Ticket #6346: MythVideo.SubSeasEp.32809.diff
File MythVideo.SubSeasEp.32809.diff, 71.5 KB (added by , 15 years ago) |
---|
-
mythplugins/mythvideo/theme/default/video-ui.xml
867 867 <!-- Labels --> 868 868 869 869 <textarea name="title_text" from="basetextarea"> 870 <area>50, 90,250,40</area>871 <value> Name:</value>870 <area>50,80,250,40</area> 871 <value>Title:</value> 872 872 <align>right,top</align> 873 873 </textarea> 874 874 875 <textarea name="subtitle_text" from="basetextarea"> 876 <area>50,138,250,40</area> 877 <value>Subtitle:</value> 878 <align>right,top</align> 879 </textarea> 880 881 <textarea name="season_text" from="basetextarea"> 882 <area>50,185,250,40</area> 883 <value>Season:</value> 884 <align>right,top</align> 885 </textarea> 886 887 <textarea name="episode_text" from="basetextarea"> 888 <area>370,185,150,40</area> 889 <value>Episode:</value> 890 <align>right,top</align> 891 </textarea> 892 875 893 <textarea name="category_text" from="title_text"> 876 <position>50,152</position> 894 <area>370,232,150,40</area> 895 <align>right</align> 877 896 <value>Category:</value> 878 897 </textarea> 879 898 880 899 <textarea name="level_text" from="title_text"> 881 <position>50,202</position> 900 <area>20,232,200,40</area> 901 <align>right</align> 882 902 <value>Parental Control:</value> 883 903 </textarea> 884 904 885 905 <textarea name="child_text" from="title_text"> 886 <position>50,247</position> 906 <area>20,277,200,40</area> 907 <align>right</align> 887 908 <value>File to Always Play Next:</value> 888 909 </textarea> 889 910 890 911 <textarea name="browse_text" from="title_text"> 891 <position>50,292</position> 912 <area>500,277,200,40</area> 913 <align>left</align> 892 914 <value>Include while Browsing:</value> 893 915 </textarea> 894 916 … … 925 947 <!-- Widgets --> 926 948 927 949 <textedit name="title_edit" from="basetextedit"> 928 <position>310, 80</position>950 <position>310,70</position> 929 951 </textedit> 930 952 931 < buttonlist name="category_select" from="baseselector">932 <position>310,1 45</position>933 </ buttonlist>953 <textedit name="subtitle_edit" from="basetextedit"> 954 <position>310,126</position> 955 </textedit> 934 956 957 <spinbox name="season" from="basespinbox"> 958 <position>310,181</position> 959 </spinbox> 960 961 <spinbox name="episode" from="basespinbox"> 962 <position>530,181</position> 963 </spinbox> 964 935 965 <buttonlist name="level_select" from="baseselector"> 936 <position> 310,195</position>966 <position>230,225</position> 937 967 </buttonlist> 938 968 969 <buttonlist name="category_select" from="baseselector"> 970 <position>530,225</position> 971 </buttonlist> 972 939 973 <buttonlist name="child_select" from="baseselector"> 940 <position> 310,240</position>974 <position>230,270</position> 941 975 </buttonlist> 942 976 943 977 <checkbox name="browse_check" from="basecheckbox"> 944 <position> 310,290</position>978 <position>680,275</position> 945 979 </checkbox> 946 980 947 981 <button name="coverart_button" from="basesearchbutton"> -
mythplugins/mythvideo/theme/default-wide/video-ui.xml
467 467 </imagetype> 468 468 469 469 <textarea name="title" from="basetextarea"> 470 <area>370,12, 700,40</area>470 <area>370,12,400,40</area> 471 471 <multiline>yes</multiline> 472 472 <font>baselarge</font> 473 473 </textarea> 474 474 475 <textarea name="subtitle" from="basetextarea"> 476 <area>800,12,400,40</area> 477 <multiline>yes</multiline> 478 <font>baselarge</font> 479 </textarea> 480 475 481 <textarea name="currentvideo" from="basetextarea"> 476 482 <area>150,486,500,35</area> 477 483 <align>top,vcenter</align> … … 487 493 <font>basemedium</font> 488 494 </textarea> 489 495 496 <textarea name="s##e##" from="basetextarea"> 497 <area>1010,63,150,35</area> 498 <font>basemedium</font> 499 </textarea> 500 490 501 <textarea name="plot" from="basetextarea"> 491 502 <area>380,97,840,145</area> 492 503 <multiline>yes</multiline> … … 572 583 573 584 <window name="gallery"> 574 585 <textarea name="title" from="basetextarea"> 575 <area>70,15, 800,50</area>586 <area>70,15,420,50</area> 576 587 <cutdown>yes</cutdown> 577 588 <font>baselarge</font> 578 589 </textarea> … … 646 657 </state> 647 658 </statetype> 648 659 </buttonlist> 660 661 <textarea name="subtitle" from="basetextarea"> 662 <area>500,15,350,40</area> 663 <align>hcenter,vcenter</align> 664 <font>basemedium</font> 665 </textarea> 649 666 667 <textarea name="s##e##" from="basetextarea"> 668 <area>870,15,100,40</area> 669 <align>hcenter,vcenter</align> 670 <font>basemedium</font> 671 </textarea> 672 650 673 <textarea name="position" from="basetextarea"> 651 <area> 890,15,200,40</area>674 <area>1000,15,200,40</area> 652 675 <align>hcenter,vcenter</align> 653 676 <font>basemedium</font> 654 677 </textarea> … … 713 736 <font>baselarge</font> 714 737 </textarea> 715 738 739 <textarea name="s##e##" from="basetextarea"> 740 <area>50,380,400,30</area> 741 <font>basemedium</font> 742 </textarea> 743 744 <textarea name="subtitle" from="basetextarea"> 745 <area>50,420,400,30</area> 746 <font>basemedium</font> 747 </textarea> 748 716 749 <textarea name="director" from="basetextarea"> 717 <area>50, 367,450,30</area>750 <area>50,467,450,30</area> 718 751 </textarea> 719 752 720 753 <textarea name="year" from="basetextarea"> 721 <area>500, 367,80,30</area>754 <area>500,467,80,30</area> 722 755 <align>right</align> 723 756 </textarea> 724 757 725 758 <textarea name="plot" from="basetextarea"> 726 <area>40, 395,530,80</area>759 <area>40,495,530,80</area> 727 760 <align>left,top</align> 728 761 <multiline>yes</multiline> 729 762 <cutdown>yes</cutdown> 730 763 </textarea> 731 764 732 765 <textarea name="cast" from="basetextarea"> 733 <area>60, 480,505,70</area>766 <area>60,580,505,70</area> 734 767 <align>left,top</align> 735 768 <multiline>yes</multiline> 736 769 <cutdown>no</cutdown> 737 770 </textarea> 738 771 739 772 <textarea name="position" from="basetextarea"> 740 <area>266, 555,266,40</area>773 <area>266,655,266,40</area> 741 774 <font>basemedium</font> 742 775 <align>hcenter,vcenter</align> 743 776 </textarea> … … 843 876 <window name="edit_metadata"> 844 877 845 878 <textarea name="title" from="basetextarea"> 846 <area>10, 50,1260,50</area>879 <area>10,30,760,50</area> 847 880 <value>Edit Video Information</value> 848 881 <align>hcenter,vcenter</align> 849 882 <font>baselarge</font> … … 852 885 <!-- Labels --> 853 886 854 887 <textarea name="title_text" from="basetextarea"> 855 <area> 250,110,250,40</area>856 <value> Name:</value>888 <area>50,80,250,40</area> 889 <value>Title:</value> 857 890 <align>right,top</align> 858 891 </textarea> 859 892 893 <textarea name="subtitle_text" from="basetextarea"> 894 <area>50,138,250,40</area> 895 <value>Subtitle:</value> 896 <align>right,top</align> 897 </textarea> 898 899 <textarea name="season_text" from="basetextarea"> 900 <area>50,185,250,40</area> 901 <value>Season:</value> 902 <align>right,top</align> 903 </textarea> 904 905 <textarea name="episode_text" from="basetextarea"> 906 <area>370,185,150,40</area> 907 <value>Episode:</value> 908 <align>right,top</align> 909 </textarea> 910 860 911 <textarea name="category_text" from="title_text"> 861 <position>250,172</position> 912 <area>420,232,150,40</area> 913 <align>right</align> 862 914 <value>Category:</value> 863 915 </textarea> 864 916 865 917 <textarea name="level_text" from="title_text"> 866 <position>250,222</position> 918 <area>20,232,200,40</area> 919 <align>right</align> 867 920 <value>Parental Control:</value> 868 921 </textarea> 869 922 870 923 <textarea name="child_text" from="title_text"> 871 <position>250,267</position> 924 <area>20,277,200,40</area> 925 <align>right</align> 872 926 <value>File to Always Play Next:</value> 873 927 </textarea> 874 928 875 929 <textarea name="browse_text" from="title_text"> 876 <position>250,312</position> 930 <area>470,277,280,40</area> 931 <align>left</align> 877 932 <value>Include while Browsing:</value> 878 933 </textarea> 879 934 880 935 <textarea name="coverart_text_label" from="title_text"> 881 <position> 250,348</position>936 <position>50,328</position> 882 937 <value>Cover Art:</value> 883 938 </textarea> 884 939 885 940 <textarea name="screenshot_text_label" from="title_text"> 886 <position> 250,377</position>941 <position>50,357</position> 887 942 <value>Screenshot:</value> 888 943 </textarea> 889 944 890 945 <textarea name="banner_text_label" from="title_text"> 891 <position> 250,406</position>946 <position>50,386</position> 892 947 <value>Banner:</value> 893 948 </textarea> 894 949 895 950 <textarea name="fanart_text_label" from="title_text"> 896 <position> 250,435</position>951 <position>50,415</position> 897 952 <value>Fanart:</value> 898 953 </textarea> 899 954 900 955 <textarea name="trailer_text_label" from="title_text"> 901 <position> 250,464</position>956 <position>50,447</position> 902 957 <value>Trailer:</value> 903 958 </textarea> 904 959 905 960 <textarea name="player_text" from="title_text"> 906 <position> 250,510</position>961 <position>50,487</position> 907 962 <value>Unique Player Command:</value> 908 963 </textarea> 909 964 910 965 <!-- Widgets --> 911 966 912 967 <textedit name="title_edit" from="basetextedit"> 913 <position> 510,100</position>968 <position>310,70</position> 914 969 </textedit> 915 970 916 < buttonlist name="category_select" from="baseselector">917 <position> 510,165</position>918 </ buttonlist>971 <textedit name="subtitle_edit" from="basetextedit"> 972 <position>310,126</position> 973 </textedit> 919 974 975 <spinbox name="season" from="basespinbox"> 976 <position>310,181</position> 977 </spinbox> 978 979 <spinbox name="episode" from="basespinbox"> 980 <position>530,181</position> 981 </spinbox> 982 920 983 <buttonlist name="level_select" from="baseselector"> 921 <position> 510,215</position>984 <position>230,225</position> 922 985 </buttonlist> 923 986 987 <buttonlist name="category_select" from="baseselector"> 988 <position>580,225</position> 989 </buttonlist> 990 924 991 <buttonlist name="child_select" from="baseselector"> 925 <position> 510,260</position>992 <position>230,270</position> 926 993 </buttonlist> 927 994 928 995 <checkbox name="browse_check" from="basecheckbox"> 929 <position> 510,310</position>996 <position>735,275</position> 930 997 </checkbox> 931 998 932 <button name="coverart_button" from="basesearchbutton"> 933 <position>510,343</position> 999 <button name="coverart_button"> 1000 <area>310,323,32,32</area> 1001 <statetype name="buttonstate"> 1002 <state name="active"> 1003 <imagetype name="background"> 1004 <filename>blankbutton_off.png</filename> 1005 </imagetype> 1006 </state> 1007 <state name="selected" from="active"> 1008 <imagetype name="background"> 1009 <filename>blankbutton_on.png</filename> 1010 </imagetype> 1011 </state> 1012 <state name="disabled" from="active" /> 1013 <state name="pushed" from="active"> 1014 <imagetype name="background"> 1015 <filename>blankbutton_pushed.png</filename> 1016 </imagetype> 1017 </state> 1018 </statetype> 934 1019 </button> 935 1020 936 1021 <textarea name="coverart_text" from="basetextarea"> 937 <area> 550,348,250,40</area>1022 <area>350,328,250,40</area> 938 1023 <value>/path/to/the/thing.jpg</value> 939 1024 </textarea> 940 1025 941 <button name="screenshot_button" from="basesearchbutton"> 942 <position>510,372</position> 1026 <button name="screenshot_button"> 1027 <area>310,352,32,32</area> 1028 <statetype name="buttonstate"> 1029 <state name="active"> 1030 <imagetype name="background"> 1031 <filename>blankbutton_off.png</filename> 1032 </imagetype> 1033 </state> 1034 <state name="selected" from="active"> 1035 <imagetype name="background"> 1036 <filename>blankbutton_on.png</filename> 1037 </imagetype> 1038 </state> 1039 <state name="disabled" from="active" /> 1040 <state name="pushed" from="active"> 1041 <imagetype name="background"> 1042 <filename>blankbutton_pushed.png</filename> 1043 </imagetype> 1044 </state> 1045 </statetype> 943 1046 </button> 944 1047 945 1048 <textarea name="screenshot_text" from="basetextarea"> 946 <area> 550,377,250,40</area>1049 <area>350,357,250,40</area> 947 1050 <value>/path/to/the/thing.jpg</value> 948 1051 </textarea> 949 1052 950 <button name="banner_button" from="basesearchbutton"> 951 <position>510,401</position> 1053 <button name="banner_button"> 1054 <area>310,381,32,32</area> 1055 <statetype name="buttonstate"> 1056 <state name="active"> 1057 <imagetype name="background"> 1058 <filename>blankbutton_off.png</filename> 1059 </imagetype> 1060 </state> 1061 <state name="selected" from="active"> 1062 <imagetype name="background"> 1063 <filename>blankbutton_on.png</filename> 1064 </imagetype> 1065 </state> 1066 <state name="disabled" from="active" /> 1067 <state name="pushed" from="active"> 1068 <imagetype name="background"> 1069 <filename>blankbutton_pushed.png</filename> 1070 </imagetype> 1071 </state> 1072 </statetype> 952 1073 </button> 953 1074 954 1075 <textarea name="banner_text" from="basetextarea"> 955 <area> 550,406,250,40</area>1076 <area>350,386,250,40</area> 956 1077 <value>/path/to/the/thing.jpg</value> 957 1078 </textarea> 958 1079 959 <button name="fanart_button" from="basesearchbutton"> 960 <position>510,430</position> 1080 <button name="fanart_button"> 1081 <area>310,412,32,32</area> 1082 <statetype name="buttonstate"> 1083 <state name="active"> 1084 <imagetype name="background"> 1085 <filename>blankbutton_off.png</filename> 1086 </imagetype> 1087 </state> 1088 <state name="selected" from="active"> 1089 <imagetype name="background"> 1090 <filename>blankbutton_on.png</filename> 1091 </imagetype> 1092 </state> 1093 <state name="disabled" from="active" /> 1094 <state name="pushed" from="active"> 1095 <imagetype name="background"> 1096 <filename>blankbutton_pushed.png</filename> 1097 </imagetype> 1098 </state> 1099 </statetype> 961 1100 </button> 962 1101 963 1102 <textarea name="fanart_text" from="basetextarea"> 964 <area> 550,435,250,40</area>1103 <area>350,415,250,40</area> 965 1104 <value>/path/to/the/thing.jpg</value> 966 1105 </textarea> 967 1106 968 <button name="trailer_button" from="basesearchbutton"> 969 <position>510,460</position> 1107 <button name="trailer_button"> 1108 <area>310,442,32,32</area> 1109 <statetype name="buttonstate"> 1110 <state name="active"> 1111 <imagetype name="background"> 1112 <filename>blankbutton_off.png</filename> 1113 </imagetype> 1114 </state> 1115 <state name="selected" from="active"> 1116 <imagetype name="background"> 1117 <filename>blankbutton_on.png</filename> 1118 </imagetype> 1119 </state> 1120 <state name="disabled" from="active" /> 1121 <state name="pushed" from="active"> 1122 <imagetype name="background"> 1123 <filename>blankbutton_pushed.png</filename> 1124 </imagetype> 1125 </state> 1126 </statetype> 970 1127 </button> 971 1128 972 1129 <textarea name="trailer_text" from="basetextarea"> 973 <area> 550,465,250,40</area>1130 <area>350,447,250,40</area> 974 1131 <value>/path/to/the/thing.jpg</value> 975 1132 </textarea> 976 1133 1134 977 1135 <textedit name="player_edit" from="basetextedit"> 978 <position> 510,495</position>1136 <position>310,477</position> 979 1137 </textedit> 980 1138 981 1139 <button name="done_button" from="basebutton"> 982 <position> 510,565</position>1140 <position>310,537</position> 983 1141 <value>Done</value> 984 1142 </button> 985 1143 -
mythplugins/mythvideo/mythvideo/videodlg.h
28 28 29 29 enum CoverDownloadErrorState { esOK, esError, esTimeout }; 30 30 enum FanartDownloadErrorState { fesOK, fesError, fesTimeout }; 31 enum BannerDownloadErrorState { besOK, besError, besTimeout }; 31 32 32 33 class VideoDialog : public MythScreenType 33 34 { … … 140 141 // OnVideoPosterSetDone() stop wait background 141 142 void StartVideoPosterSet(Metadata *metadata); 142 143 void StartVideoFanartSet(Metadata *metadata); 144 void StartVideoBannerSet(Metadata *metadata); 143 145 144 146 // StartVideoSearchByUID() start wait background 145 147 // OnVideoSearchByUIDDone() stop wait background … … 159 161 void OnFanartURL(QString uri, Metadata *metadata); 160 162 void OnFanartCopyFinished(FanartDownloadErrorState error, QString errorMsg, 161 163 Metadata *metadata); 164 void OnBannerURL(QString uri, Metadata *metadata); 165 void OnBannerCopyFinished(BannerDownloadErrorState error, QString errorMsg, 166 Metadata *metadata); 162 167 163 168 // called during StartVideoSearchByTitle 164 169 void OnVideoSearchByTitleDone(bool normal_exit, … … 170 175 // StartVideoPosterSet end 171 176 void OnVideoPosterSetDone(Metadata *metadata); 172 177 void OnVideoFanartSetDone(Metadata *metadata); 178 void OnVideoBannerSetDone(Metadata *metadata); 173 179 174 180 // StartVideoSearchByUID end 175 181 void OnVideoSearchByUIDDone(bool normal_exit, -
mythplugins/mythvideo/mythvideo/metadatalistmanager.cpp
112 112 MSqlQuery query(MSqlQuery::InitCon()); 113 113 query.setForwardOnly(true); 114 114 const QString BaseMetadataQuery( 115 "SELECT title, director, plot, rating, year, userrating," 116 "length, filename, showlevel, coverfile, inetref, childid," 117 "browse, playcommand, category, intid, trailer, screenshot," 118 "banner, fanart, host FROM videometadata"); 115 "SELECT title, director, plot, rating, year, " 116 "userrating, length, filename, showlevel, " 117 "coverfile, inetref, childid, browse, playcommand, category, " 118 "intid, trailer, screenshot, banner, fanart, " 119 "subtitle, season, episode, host FROM videometadata"); 119 120 120 121 query.prepare(BaseMetadataQuery); 121 122 -
mythplugins/mythvideo/mythvideo/metadata.cpp
89 89 public: 90 90 MetadataImp(const QString &filename, const QString &trailer, const QString &coverfile, 91 91 const QString &screenshot, const QString &banner, const QString &fanart, 92 const QString &title, int year,92 const QString &title, const QString &subtitle, int year, 93 93 const QString &inetref, const QString &director, 94 94 const QString &plot, float userrating, 95 95 const QString &rating, int length, 96 unsigned int season, unsigned int episode, 96 97 int id, ParentalLevel::Level showlevel, int categoryID, 97 98 int childID, bool browse, 98 99 const QString &playcommand, const QString &category, … … 100 101 const country_list &countries, 101 102 const cast_list &cast, 102 103 const QString &host = "") : 103 m_title(title), 104 m_title(title), m_subtitle(subtitle), 104 105 m_inetref(inetref), m_director(director), m_plot(plot), 105 106 m_rating(rating), m_playcommand(playcommand), m_category(category), 106 107 m_genres(genres), m_countries(countries), m_cast(cast), 107 108 m_filename(filename), m_trailer(trailer), m_coverfile(coverfile), 108 109 m_screenshot(screenshot), m_banner(banner), m_fanart(fanart), 109 110 m_host(host), m_categoryID(categoryID), m_childID(childID), 110 m_year(year), m_length(length), m_showlevel(showlevel), 111 m_year(year), m_length(length), m_season(season), 112 m_episode(episode), m_showlevel(showlevel), 111 113 m_browse(browse), m_id(id), m_userrating(userrating) 112 114 { 113 115 VideoCategory::GetCategory().get(m_categoryID, m_category); … … 128 130 if (this != &rhs) 129 131 { 130 132 m_title = rhs.m_title; 133 m_subtitle = rhs.m_subtitle; 131 134 m_inetref = rhs.m_inetref; 132 135 m_director = rhs.m_director; 133 136 m_plot = rhs.m_plot; … … 148 151 m_childID = rhs.m_childID; 149 152 m_year = rhs.m_year; 150 153 m_length = rhs.m_length; 154 m_season = rhs.m_season; 155 m_episode = rhs.m_episode; 151 156 m_showlevel = rhs.m_showlevel; 152 157 m_browse = rhs.m_browse; 153 158 m_id = rhs.m_id; … … 180 185 m_title = title; 181 186 } 182 187 188 const QString &getSubtitle() const { return m_subtitle; } 189 void SetSubtitle(const QString &subtitle) { m_subtitle = subtitle; } 190 183 191 const QString &GetInetRef() const { return m_inetref; } 184 192 void SetInetRef(const QString &inetRef) { m_inetref = inetRef; } 185 193 … … 249 257 int GetLength() const { return m_length; } 250 258 void SetLength(int length) { m_length = length; } 251 259 260 int GetSeason() const { return m_season; } 261 void SetSeason(int season) { m_season = season; } 262 263 int GetEpisode() const { return m_episode; } 264 void SetEpisode(int episode) { m_episode = episode; } 265 252 266 ParentalLevel::Level GetShowLevel() const { return m_showlevel; } 253 267 void SetShowLevel(ParentalLevel::Level showLevel) 254 268 { … … 289 303 290 304 private: 291 305 QString m_title; 306 QString m_subtitle; 292 307 QString m_inetref; 293 308 QString m_director; 294 309 QString m_plot; … … 310 325 int m_childID; 311 326 int m_year; 312 327 int m_length; 328 int m_season; 329 int m_episode; 313 330 ParentalLevel::Level m_showlevel; 314 331 bool m_browse; 315 332 unsigned int m_id; // videometadata.intid … … 384 401 MetadataImp tmp(m_filename, VIDEO_TRAILER_DEFAULT, VIDEO_COVERFILE_DEFAULT, 385 402 VIDEO_SCREENSHOT_DEFAULT, VIDEO_BANNER_DEFAULT, 386 403 VIDEO_FANART_DEFAULT, Metadata::FilenameToTitle(m_filename), 387 VIDEO_ YEAR_DEFAULT, VIDEO_INETREF_DEFAULT,404 VIDEO_SUBTITLE_DEFAULT, VIDEO_YEAR_DEFAULT, VIDEO_INETREF_DEFAULT, 388 405 VIDEO_DIRECTOR_DEFAULT, VIDEO_PLOT_DEFAULT, 0.0, 389 VIDEO_RATING_DEFAULT, 0, m_id, 406 VIDEO_RATING_DEFAULT, 0, 407 Metadata::FilenameToSeasonEpisode(m_filename, 1), 408 Metadata::FilenameToSeasonEpisode(m_filename, 2), m_id, 390 409 ParentalLevel::plLowest, 0, -1, true, "", "", 391 410 Metadata::genre_list(), Metadata::country_list(), 392 411 Metadata::cast_list(), m_host); … … 484 503 m_screenshot = query.value(17).toString(); 485 504 m_banner = query.value(18).toString(); 486 505 m_fanart = query.value(19).toString(); 487 m_host = query.value(20).toString(); 506 m_subtitle = query.value(20).toString(); 507 m_season = query.value(21).toInt(); 508 m_episode = query.value(22).toInt(); 509 m_host = query.value(23).toString(); 488 510 489 511 VideoCategory::GetCategory().get(m_categoryID, m_category); 490 512 … … 502 524 { 503 525 if (m_title.isEmpty()) 504 526 m_title = Metadata::FilenameToTitle(m_filename); 527 if (m_subtitle.isEmpty()) 528 m_subtitle = VIDEO_SUBTITLE_DEFAULT; 505 529 if (m_director.isEmpty()) 506 530 m_director = VIDEO_DIRECTOR_UNKNOWN; 507 531 if (m_plot.isEmpty()) 508 532 m_plot = VIDEO_PLOT_DEFAULT; 509 533 if (m_rating.isEmpty()) 510 534 m_rating = VIDEO_RATING_DEFAULT; 535 if (m_season == 0) 536 m_season = Metadata::FilenameToSeasonEpisode(m_filename, 1); 537 if (m_episode == 0) 538 m_episode = Metadata::FilenameToSeasonEpisode(m_filename, 2); 511 539 if (m_coverfile.isEmpty()) 512 540 m_coverfile = VIDEO_COVERFILE_DEFAULT; 513 541 if (m_screenshot.isEmpty()) … … 533 561 { 534 562 m_browse = gContext->GetNumSetting("VideoNewBrowsable", 1); 535 563 536 query.prepare("INSERT INTO videometadata (title, director,plot,"537 "rating,year,userrating,length, filename,showlevel,"538 " coverfile,inetref,browse,trailer,screenshot,banner,"539 "fanart,host) VALUES (:TITLE, : DIRECTOR, :PLOT, :RATING, "540 ": YEAR, :USERRATING, :LENGTH, :FILENAME, :SHOWLEVEL, "541 ": COVERFILE, :INETREF, :BROWSE, :TRAILER, :SCREENSHOT, "542 ": BANNER, :FANART, :HOST)");564 query.prepare("INSERT INTO videometadata (title,subtitle,director,plot," 565 "rating,year,userrating,length,season,episode,filename," 566 "showlevel,coverfile,inetref,browse,trailer,screenshot,banner," 567 "fanart,host) VALUES (:TITLE, :SUBTITLE, :DIRECTOR, :PLOT, " 568 ":RATING, :YEAR, :USERRATING, :LENGTH, :SEASON, :EPISODE, " 569 ":FILENAME, :SHOWLEVEL, :COVERFILE, :INETREF, :BROWSE, " 570 ":TRAILER, :SCREENSHOT, :BANNER, :FANART, :HOST)"); 543 571 } 544 572 else 545 573 { 546 query.prepare("UPDATE videometadata SET title = :TITLE, "574 query.prepare("UPDATE videometadata SET title = :TITLE, subtitle = :SUBTITLE, " 547 575 "director = :DIRECTOR, plot = :PLOT, rating= :RATING, " 548 576 "year = :YEAR, userrating = :USERRATING, " 549 "length = :LENGTH, filename = :FILENAME, trailer = :TRAILER, " 577 "length = :LENGTH, season = :SEASON, episode = :EPISODE, " 578 "filename = :FILENAME, trailer = :TRAILER, " 550 579 "showlevel = :SHOWLEVEL, coverfile = :COVERFILE, " 551 580 "screenshot = :SCREENSHOT, banner = :BANNER, fanart = :FANART, " 552 581 "inetref = :INETREF, browse = :BROWSE, host = :HOST, " … … 560 589 } 561 590 562 591 query.bindValue(":TITLE", m_title); 592 query.bindValue(":SUBTITLE", m_subtitle); 563 593 query.bindValue(":DIRECTOR", m_director); 564 594 query.bindValue(":PLOT", m_plot); 565 595 query.bindValue(":RATING", m_rating); 566 596 query.bindValue(":YEAR", m_year); 567 597 query.bindValue(":USERRATING", m_userrating); 568 598 query.bindValue(":LENGTH", m_length); 599 query.bindValue(":SEASON", m_season); 600 query.bindValue(":EPISODE", m_episode); 569 601 query.bindValue(":FILENAME", m_filename); 570 602 query.bindValue(":TRAILER", m_trailer); 571 603 query.bindValue(":SHOWLEVEL", m_showlevel); … … 811 843 return title.trimmed(); 812 844 } 813 845 846 unsigned int Metadata::FilenameToSeasonEpisode(const QString &file_name, 847 int position) 848 { 849 // position 1 returns season, 2 returns episode 850 851 QString title = file_name.right(file_name.length() - 852 file_name.lastIndexOf('/') - 1); 853 QRegExp group("(\\d{1,3})(?:\\s|-|_|\\.)?(?:[ex])" //Season 854 "(?:\\s|-|_|\\.)?(\\d{1,3})", // Episode 855 Qt::CaseInsensitive); 856 int pos = group.indexIn(title); 857 if (pos > -1) 858 { 859 QString groupResult = group.cap(0); 860 QString season = group.cap(1); 861 QString episode = group.cap(2); 862 if (position == 1) 863 return season.toInt(); 864 else if (position == 2) 865 return episode.toInt(); 866 } 867 return 0; 868 } 869 814 870 namespace 815 871 { 816 872 const QRegExp &getTitleTrim(bool ignore_case) … … 829 885 return ret; 830 886 } 831 887 832 Metadata::Metadata(const QString &filename, const QString &trailer, 833 const QString &coverfile, const QString &screenshot, 834 const QString &banner, const QString &fanart, 835 const QString &title, int year,888 Metadata::Metadata(const QString &filename, const QString &trailer, 889 const QString &coverfile, const QString &screenshot, 890 const QString &banner, const QString &fanart, 891 const QString &title, const QString &subtitle, int year, 836 892 const QString &inetref, const QString &director, 837 893 const QString &plot, float userrating, 838 894 const QString &rating, int length, 895 int season, int episode, 839 896 int id, ParentalLevel::Level showlevel, int categoryID, 840 897 int childID, bool browse, 841 898 const QString &playcommand, const QString &category, … … 845 902 const QString &host) 846 903 { 847 904 m_imp = new MetadataImp(filename, trailer, coverfile, screenshot, banner, 848 fanart, title, year, inetref, director, plot,849 userrating, rating, length, id, showlevel,850 categoryID, childID, browse, playcommand, category,851 genres, countries, cast, host);905 fanart, title, subtitle, year, inetref, director, plot, 906 userrating, rating, length, season, episode, id, 907 showlevel, categoryID, childID, browse, playcommand, 908 category, genres, countries, cast, host); 852 909 } 853 910 854 911 Metadata::~Metadata() … … 911 968 m_imp->SetTitle(title); 912 969 } 913 970 971 const QString &Metadata::GetSubtitle() const 972 { 973 return m_imp->getSubtitle(); 974 } 975 976 void Metadata::SetSubtitle(const QString &subtitle) 977 { 978 m_imp->SetSubtitle(subtitle); 979 } 980 914 981 int Metadata::GetYear() const 915 982 { 916 983 return m_imp->getYear(); … … 981 1048 m_imp->SetLength(length); 982 1049 } 983 1050 1051 int Metadata::GetSeason() const 1052 { 1053 return m_imp->GetSeason(); 1054 } 1055 1056 void Metadata::SetSeason(int season) 1057 { 1058 m_imp->SetSeason(season); 1059 } 1060 1061 int Metadata::GetEpisode() const 1062 { 1063 return m_imp->GetEpisode(); 1064 } 1065 1066 void Metadata::SetEpisode(int episode) 1067 { 1068 m_imp->SetEpisode(episode); 1069 } 1070 984 1071 unsigned int Metadata::GetID() const 985 1072 { 986 1073 return m_imp->GetID(); -
mythplugins/mythvideo/mythvideo/globalsettings.cpp
235 235 return gc; 236 236 } 237 237 238 HostLineEdit *SearchTVListingsCommand() 239 { 240 HostLineEdit *gc = new HostLineEdit("mythvideo.TVListCommandLine"); 241 gc->setLabel(QObject::tr("Command to search for TV shows in MythVideo")); 242 gc->setValue(GetShareDir() + "mythvideo/scripts/ttvdb.py -M"); 243 gc->setHelpText(QObject::tr("This command must be " 244 "executable by the user running MythVideo.")); 245 return gc; 246 } 247 248 HostLineEdit *GetTVPostersCommand() 249 { 250 HostLineEdit *gc = new HostLineEdit("mythvideo.TVPosterCommandLine"); 251 gc->setLabel(QObject::tr("Command to search for TV Season posters")); 252 gc->setValue(GetShareDir() + "mythvideo/scripts/ttvdb.py -mP"); 253 gc->setHelpText(QObject::tr("This command must be " 254 "executable by the user running MythVideo.")); 255 return gc; 256 } 257 258 HostLineEdit *GetTVFanartCommand() 259 { 260 HostLineEdit *gc = new HostLineEdit("mythvideo.TVFanartCommandLine"); 261 gc->setLabel(QObject::tr("Command to search for TV fanart")); 262 gc->setValue(GetShareDir() + "mythvideo/scripts/ttvdb.py -tF"); 263 gc->setHelpText(QObject::tr("This command must be " 264 "executable by the user running MythVideo.")); 265 return gc; 266 } 267 268 HostLineEdit *GetTVBannerCommand() 269 { 270 HostLineEdit *gc = new HostLineEdit("mythvideo.TVBannerCommandLine"); 271 gc->setLabel(QObject::tr("Command to search for TV banners")); 272 gc->setValue(GetShareDir() + "mythvideo/scripts/ttvdb.py -tB"); 273 gc->setHelpText(QObject::tr("This command must be " 274 "executable by the user running MythVideo.")); 275 return gc; 276 } 277 278 HostLineEdit *GetTVDataCommand() 279 { 280 HostLineEdit *gc = new HostLineEdit("mythvideo.TVDataCommandLine"); 281 gc->setLabel(QObject::tr("Command to extract data for TV Episodes")); 282 gc->setValue(GetShareDir() + "mythvideo/scripts/ttvdb.py -D"); 283 gc->setHelpText(QObject::tr("This command must be " 284 "executable by the user running MythVideo.")); 285 return gc; 286 } 287 238 288 HostLineEdit *VideoStartupDirectory() 239 289 { 240 290 HostLineEdit *gc = new HostLineEdit("VideoStartupDir"); … … 776 826 VConfigPage page7(pages, false); 777 827 page7->addChild(trlr); 778 828 829 // page 8 830 VerticalConfigurationGroup *tvman = 831 new VerticalConfigurationGroup(true, false); 832 tvman->setLabel(QObject::tr("Television in MythVideo")); 833 tvman->addChild(SearchTVListingsCommand()); 834 tvman->addChild(GetTVPostersCommand()); 835 tvman->addChild(GetTVFanartCommand()); 836 tvman->addChild(GetTVBannerCommand()); 837 tvman->addChild(GetTVDataCommand()); 838 839 VConfigPage page8(pages, false); 840 page8->addChild(tvman); 841 779 842 int page_num = 1; 780 843 for (ConfigPage::PageList::const_iterator p = pages.begin(); 781 844 p != pages.end(); ++p, ++page_num) -
mythplugins/mythvideo/mythvideo/videofilter.h
54 54 kOrderByUserRatingDescending = 2, 55 55 kOrderByLength = 3, 56 56 kOrderByFilename = 4, 57 kOrderByID = 5 57 kOrderByID = 5, 58 kOrderBySeasonEp = 6 58 59 }; 59 60 60 61 int GetCategory() const { return category; } -
mythplugins/mythvideo/mythvideo/dbcheck.cpp
38 38 const QString lastMythDVDDBVersion = "1002"; 39 39 const QString lastMythVideoVersion = "1010"; 40 40 41 const QString currentDatabaseVersion = "102 3";41 const QString currentDatabaseVersion = "1024"; 42 42 43 43 const QString OldMythVideoVersionName = "VideoDBSchemaVer"; 44 44 const QString OldMythDVDVersionName = "DVDDBSchemaVer"; … … 834 834 performActualUpdate(updates, "1023", dbver, MythVideoVersionName); 835 835 } 836 836 837 if (dbver == "1023") 838 { 839 QStringList updates; 840 updates += "ALTER TABLE videometadata ADD `subtitle` TEXT " 841 "NOT NULL AFTER `title`;"; 842 updates += "ALTER TABLE videometadata ADD `season` SMALLINT " 843 "UNSIGNED NOT NULL DEFAULT '0' AFTER `length`;"; 844 updates += "ALTER TABLE videometadata ADD `episode` SMALLINT " 845 "UNSIGNED NOT NULL DEFAULT '0' AFTER `season`;"; 846 performActualUpdate(updates, "1024", dbver, MythVideoVersionName); 847 } 837 848 838 849 } 839 850 } -
mythplugins/mythvideo/mythvideo/videoutils.cpp
139 139 return QString("%1 minutes").arg(length); 140 140 } 141 141 142 QString GetDisplaySeasonEpisode(int seasEp, int digits) 143 { 144 QString seasEpNum = QString::number(seasEp); 145 146 if (digits == 2 && seasEpNum.size() < 2) 147 seasEpNum.prepend("0"); 148 149 return seasEpNum; 150 } 151 142 152 QString GetDisplayBrowse(bool browse) 143 153 { 144 154 return browse ? QObject::tr("Yes") : QObject::tr("No"); -
mythplugins/mythvideo/mythvideo/editmetadata.h
10 10 class MythUIText; 11 11 class MythUITextEdit; 12 12 class MythUIButton; 13 class MythUISpinBox; 13 14 class MythUICheckBox; 14 15 15 16 class EditMetadataDialog : public MythScreenType … … 34 35 public slots: 35 36 void SaveAndExit(); 36 37 void SetTitle(); 38 void SetSubtitle(); 37 39 void SetCategory(MythUIButtonListItem*); 38 40 void SetPlayer(); 41 void SetSeason(); 42 void SetEpisode(); 39 43 void SetLevel(MythUIButtonListItem*); 40 44 void SetChild(MythUIButtonListItem*); 41 45 void ToggleBrowse(); … … 60 64 // 61 65 62 66 MythUITextEdit *m_titleEdit; 67 MythUITextEdit *m_subtitleEdit; 63 68 MythUITextEdit *m_playerEdit; 69 MythUISpinBox *m_seasonSpin; 70 MythUISpinBox *m_episodeSpin; 64 71 MythUIButtonList *m_categoryList; 65 72 MythUIButtonList *m_levelList; 66 73 MythUIButtonList *m_childList; -
mythplugins/mythvideo/mythvideo/videodlg.cpp
288 288 FanartDownloadErrorState m_error_state; 289 289 }; 290 290 291 class BannerDownloadProxy : public QObject 292 { 293 Q_OBJECT 294 295 signals: 296 void SigFinished(BannerDownloadErrorState reason, QString errorMsg, 297 Metadata *item); 298 public: 299 static BannerDownloadProxy *Create(const QUrl &url, const QString &dest, 300 Metadata *item) 301 { 302 return new BannerDownloadProxy(url, dest, item); 303 } 304 305 public: 306 void StartCopy() 307 { 308 m_id = m_http.get(m_url.toString(), &m_data_buffer); 309 310 m_timer.start(gContext->GetNumSetting("BannerDownloadTimeout", 30) 311 * 1000); 312 } 313 314 void Stop() 315 { 316 if (m_timer.isActive()) 317 m_timer.stop(); 318 319 VERBOSE(VB_GENERAL, tr("Banner download stopped.")); 320 m_http.abort(); 321 } 322 323 private: 324 BannerDownloadProxy(const QUrl &url, const QString &dest, 325 Metadata *item) : m_item(item), m_dest_file(dest), 326 m_id(0), m_url(url), m_error_state(besOK) 327 { 328 connect(&m_http, SIGNAL(requestFinished(int, bool)), 329 SLOT(OnFinished(int, bool))); 330 331 connect(&m_timer, SIGNAL(timeout()), SLOT(OnDownloadTimeout())); 332 m_timer.setSingleShot(true); 333 m_http.setHost(m_url.host()); 334 } 335 336 ~BannerDownloadProxy() {} 337 338 private slots: 339 void OnDownloadTimeout() 340 { 341 VERBOSE(VB_IMPORTANT, QString("Copying of '%1' timed out") 342 .arg(m_url.toString())); 343 m_error_state = besTimeout; 344 Stop(); 345 } 346 347 void OnFinished(int id, bool error) 348 { 349 QString errorMsg; 350 if (error) 351 errorMsg = m_http.errorString(); 352 353 if (id == m_id) 354 { 355 if (m_timer.isActive()) 356 m_timer.stop(); 357 358 if (!error) 359 { 360 QFile dest_file(m_dest_file); 361 if (dest_file.exists()) 362 dest_file.remove(); 363 364 if (dest_file.open(QIODevice::WriteOnly)) 365 { 366 const QByteArray &data = m_data_buffer.data(); 367 qint64 size = dest_file.write(data); 368 if (size != data.size()) 369 { 370 errorMsg = tr("Error writing data to file %1.") 371 .arg(m_dest_file); 372 m_error_state = besError; 373 } 374 } 375 else 376 { 377 errorMsg = tr("Error: file error '%1' for file %2"). 378 arg(dest_file.errorString()).arg(m_dest_file); 379 m_error_state = besError; 380 } 381 } 382 383 emit SigFinished(m_error_state, errorMsg, m_item); 384 } 385 } 386 387 private: 388 Metadata *m_item; 389 QHttp m_http; 390 QBuffer m_data_buffer; 391 QString m_dest_file; 392 int m_id; 393 QTimer m_timer; 394 QUrl m_url; 395 BannerDownloadErrorState m_error_state; 396 }; 397 291 398 /** \class ExecuteExternalCommand 292 399 * 293 400 * \brief Base class for executing an external script or other process, must … … 467 574 void Run(QString title, Metadata *item) 468 575 { 469 576 m_item = item; 577 int m_season, m_episode; 578 QString cmd; 579 m_season = m_item->GetSeason(); 580 m_episode = m_item->GetEpisode(); 470 581 471 QString def_cmd = QDir::cleanPath(QString("%1/%2") 582 if (m_season > 0 || m_episode > 0) 583 { 584 const QString def_cmd = QDir::cleanPath(QString("%1/%2") 472 585 .arg(GetShareDir()) 586 .arg("mythvideo/scripts/ttvdb.py -M")); 587 cmd = gContext->GetSetting("mythvideo.TVListCommandLine", 588 def_cmd); 589 } 590 else 591 { 592 QString def_cmd = QDir::cleanPath(QString("%1/%2") 593 .arg(GetShareDir()) 473 594 .arg("mythvideo/scripts/tmdb.pl -M")); 474 595 475 QStringcmd = gContext->GetSetting("MovieListCommandLine", def_cmd);476 477 QStringList args;478 args += title;479 StartRun(cmd, args, "Video Search");596 cmd = gContext->GetSetting("MovieListCommandLine", def_cmd); 597 } 598 QStringList args; 599 args += title; 600 StartRun(cmd, args, "Video Search"); 480 601 } 481 602 482 603 private: … … 525 646 void Run(QString video_uid, Metadata *item) 526 647 { 527 648 m_item = item; 528 m_video_uid = video_uid; 649 m_video_uid = video_uid; 650 int m_season, m_episode; 651 m_season = m_item->GetSeason(); 652 m_episode = m_item->GetEpisode(); 529 653 530 const QString def_cmd = QDir::cleanPath(QString("%1/%2") 654 if (m_season > 0 || m_episode > 0) 655 { 656 const QString def_cmd = QDir::cleanPath(QString("%1/%2") 531 657 .arg(GetShareDir()) 658 .arg("mythvideo/scripts/ttvdb.py -mD")); 659 const QString cmd = gContext->GetSetting("mythvideo.TVDataCommandLine", 660 def_cmd); 661 QStringList args; 662 args << video_uid << QString::number(m_season) 663 << QString::number(m_episode); 664 StartRun(cmd, args, "Video Data Query"); 665 } 666 else 667 { 668 const QString def_cmd = QDir::cleanPath(QString("%1/%2") 669 .arg(GetShareDir()) 532 670 .arg("mythvideo/scripts/tmdb.pl -D")); 533 const QString cmd = gContext->GetSetting("MovieDataCommandLine",671 const QString cmd = gContext->GetSetting("MovieDataCommandLine", 534 672 def_cmd); 535 536 StartRun(cmd, QStringList(video_uid), "Video Data Query");673 StartRun(cmd, QStringList(video_uid), "Video Data Query"); 674 } 537 675 } 538 676 539 677 private: … … 570 708 void Run(QString video_uid, Metadata *item) 571 709 { 572 710 m_item = item; 711 int m_season, m_episode; 712 m_season = m_item->GetSeason(); 713 m_episode = m_item->GetEpisode(); 573 714 574 const QString default_cmd = 715 if (m_season > 0 || m_episode > 0) 716 { 717 const QString def_cmd = QDir::cleanPath(QString("%1/%2") 718 .arg(GetShareDir()) 719 .arg("mythvideo/scripts/ttvdb.py -mP")); 720 const QString cmd = gContext->GetSetting("mythvideo.TVPosterCommandLine", 721 def_cmd); 722 QStringList args; 723 args << video_uid << QString::number(m_season) 724 << QString::number(m_episode); 725 StartRun(cmd, args, "Poster Query"); 726 } 727 else 728 { 729 const QString default_cmd = 575 730 QDir::cleanPath(QString("%1/%2") 576 731 .arg(GetShareDir()) 577 732 .arg("mythvideo/scripts/tmdb.pl -P")); 578 const QString cmd = gContext->GetSetting("MoviePosterCommandLine",733 const QString cmd = gContext->GetSetting("MoviePosterCommandLine", 579 734 default_cmd); 580 StartRun(cmd, QStringList(video_uid), "Poster Query"); 735 736 StartRun(cmd, QStringList(video_uid), "Poster Query"); 737 } 581 738 } 582 739 583 740 private: … … 627 784 void Run(QString video_uid, Metadata *item) 628 785 { 629 786 m_item = item; 787 int m_season, m_episode; 788 m_season = m_item->GetSeason(); 789 m_episode = m_item->GetEpisode(); 630 790 631 const QString default_cmd = 791 if (m_season > 0 || m_episode > 0) 792 { 793 const QString def_cmd = QDir::cleanPath(QString("%1/%2") 794 .arg(GetShareDir()) 795 .arg("mythvideo/scripts/ttvdb.py -tF")); 796 const QString cmd = gContext->GetSetting("mythvideo.TVFanartCommandLine", 797 def_cmd); 798 QStringList args; 799 args << video_uid << QString::number(m_season) 800 << QString::number(m_episode); 801 StartRun(cmd, args, "Fanart Query"); 802 } 803 else 804 { 805 const QString default_cmd = 632 806 QDir::cleanPath(QString("%1/%2") 633 807 .arg(GetShareDir()) 634 808 .arg("mythvideo/scripts/tmdb.pl -B")); 635 const QString cmd = gContext->GetSetting("MovieFanartCommandLine",809 const QString cmd = gContext->GetSetting("MovieFanartCommandLine", 636 810 default_cmd); 637 StartRun(cmd, QStringList(video_uid), "Fanart Query"); 811 StartRun(cmd, QStringList(video_uid), "Fanart Query"); 812 } 638 813 } 639 814 640 815 private: … … 665 840 Metadata *m_item; 666 841 }; 667 842 843 /** \class VideoBannerSearch 844 * 845 * \brief Execute external video banner command. 846 * 847 */ 848 class VideoBannerSearch : public ExecuteExternalCommand 849 { 850 Q_OBJECT 668 851 852 signals: 853 void SigBannerURL(QString url, Metadata *item); 854 855 public: 856 VideoBannerSearch(QObject *oparent) : 857 ExecuteExternalCommand(oparent), m_item(0) {} 858 859 void Run(QString video_uid, Metadata *item) 860 { 861 m_item = item; 862 int m_season, m_episode; 863 m_season = m_item->GetSeason(); 864 m_episode = m_item->GetEpisode(); 865 866 const QString def_cmd = QDir::cleanPath(QString("%1/%2") 867 .arg(GetShareDir()) 868 .arg("mythvideo/scripts/ttvdb.py -tB")); 869 const QString cmd = gContext->GetSetting("mythvideo.TVBannerCommandLine", 870 def_cmd); 871 QStringList args; 872 args << video_uid << QString::number(m_season) 873 << QString::number(m_episode); 874 StartRun(cmd, args, "Banner Query"); 875 } 876 877 private: 878 ~VideoBannerSearch() {} 879 880 void OnExecDone(bool normal_exit, QStringList out, QStringList err) 881 { 882 (void) err; 883 QString url; 884 if (normal_exit && out.size()) 885 { 886 for (QStringList::const_iterator p = out.begin(); 887 p != out.end(); ++p) 888 { 889 if ((*p).length()) 890 { 891 url = *p; 892 break; 893 } 894 } 895 } 896 897 emit SigBannerURL(url, m_item); 898 deleteLater(); 899 } 900 901 private: 902 Metadata *m_item; 903 }; 904 669 905 class ParentalLevelNotifyContainer : public QObject 670 906 { 671 907 Q_OBJECT … … 1016 1252 1017 1253 tmp["filename"] = metadata->GetFilename(); 1018 1254 tmp["title"] = metadata->GetTitle(); 1255 tmp["subtitle"] = metadata->GetSubtitle(); 1019 1256 tmp["director"] = metadata->GetDirector(); 1020 1257 tmp["plot"] = metadata->GetPlot(); 1021 1258 tmp["genres"] = GetDisplayGenres(*metadata); … … 1025 1262 tmp["length"] = GetDisplayLength(metadata->GetLength()); 1026 1263 tmp["year"] = GetDisplayYear(metadata->GetYear()); 1027 1264 tmp["userrating"] = GetDisplayUserRating(metadata->GetUserRating()); 1265 tmp["season"] = GetDisplaySeasonEpisode(metadata->GetSeason(), 1); 1266 tmp["episode"] = GetDisplaySeasonEpisode(metadata->GetEpisode(), 1); 1028 1267 1268 if (metadata->GetSeason() > 0 || metadata->GetEpisode() >= 0) 1269 { 1270 tmp["s##e##"] = QString("s%1e%2").arg(GetDisplaySeasonEpisode 1271 (metadata->GetSeason(), 2)) 1272 .arg(GetDisplaySeasonEpisode(metadata->GetEpisode(), 2)); 1273 tmp["##x##"] = QString("%1x%2").arg(GetDisplaySeasonEpisode 1274 (metadata->GetSeason(), 1)) 1275 .arg(GetDisplaySeasonEpisode(metadata->GetEpisode(), 2)); 1276 } 1277 else 1278 tmp["s##e##"] = tmp["##x##"] = ""; 1279 1029 1280 tmp["userratingstate"] = 1030 1281 QString::number((int)(metadata->GetUserRating())); 1031 1282 tmp["videolevel"] = ParentalLevelToState(metadata->GetShowLevel()); … … 1075 1326 h.handleText("player"); 1076 1327 h.handleText("filename"); 1077 1328 h.handleText("title"); 1329 h.handleText("subtitle"); 1078 1330 h.handleText("director"); 1079 1331 h.handleText("plot"); 1080 1332 h.handleText("genres"); … … 1082 1334 h.handleText("cast"); 1083 1335 h.handleText("rating"); 1084 1336 h.handleText("length"); 1337 h.handleText("season"); 1338 h.handleText("s##e##"); 1339 h.handleText("##x##"); 1340 h.handleText("episode"); 1085 1341 h.handleText("year"); 1086 1342 h.handleText("userrating"); 1087 1343 … … 1254 1510 1255 1511 m_artDir = gContext->GetSetting("VideoArtworkDir"); 1256 1512 m_fanDir = gContext->GetSetting("mythvideo.fanartDir"); 1513 m_banDir = gContext->GetSetting("mythvideo.bannerDir"); 1257 1514 } 1258 1515 1259 1516 ~VideoDialogPrivate() … … 1322 1579 } 1323 1580 } 1324 1581 1582 void AddBannerDownload(BannerDownloadProxy *download) 1583 { 1584 m_running_bdownloads.insert(download); 1585 } 1586 1587 void RemoveBannerDownload(BannerDownloadProxy *download) 1588 { 1589 if (download) 1590 { 1591 banner_download_list::iterator p = 1592 m_running_bdownloads.find(download); 1593 if (p != m_running_bdownloads.end()) 1594 m_running_bdownloads.erase(p); 1595 } 1596 } 1597 1325 1598 void StopAllRunningCoverDownloads() 1326 1599 { 1327 1600 cover_download_list tmp(m_running_downloads); … … 1336 1609 (*p)->Stop(); 1337 1610 } 1338 1611 1612 void StopAllRunningBannerDownloads() 1613 { 1614 banner_download_list tmp(m_running_bdownloads); 1615 for (banner_download_list::iterator p = tmp.begin(); p != tmp.end(); ++p) 1616 (*p)->Stop(); 1617 } 1339 1618 1340 1619 public: 1341 1620 typedef std::set<CoverDownloadProxy *> cover_download_list; 1342 1621 cover_download_list m_running_downloads; 1343 1622 typedef std::set<FanartDownloadProxy *> fanart_download_list; 1344 1623 fanart_download_list m_running_fdownloads; 1624 typedef std::set<BannerDownloadProxy *> banner_download_list; 1625 banner_download_list m_running_bdownloads; 1345 1626 ParentalLevelNotifyContainer m_parentalLevel; 1346 1627 bool m_switchingLayout; 1347 1628 … … 1364 1645 1365 1646 QString m_artDir; 1366 1647 QString m_fanDir; 1648 QString m_banDir; 1367 1649 VideoScanner *m_scanner; 1368 1650 1369 1651 QString m_lastTreeNodePath; … … 2806 3088 SLOT(OnFanartURL(QString, Metadata *))); 2807 3089 vfs->Run(metadata->GetInetRef(), metadata); 2808 3090 } 3091 3092 if (metadata->GetBanner().isEmpty() && 3093 (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0)) 3094 { 3095 // Obtain video banner (only for TV) 3096 VideoBannerSearch *vbs = new VideoBannerSearch(this); 3097 connect(vbs, SIGNAL(SigBannerURL(QString, Metadata *)), 3098 SLOT(OnBannerURL(QString, Metadata *))); 3099 vbs->Run(metadata->GetInetRef(), metadata); 3100 } 2809 3101 } 2810 3102 2811 3103 void VideoDialog::OnPosterURL(QString uri, Metadata *metadata) … … 2838 3130 QUrl url(uri); 2839 3131 2840 3132 QString ext = QFileInfo(url.path()).suffix(); 2841 QString dest_file = QString("%1/%2.%3").arg(fileprefix) 2842 .arg(metadata->GetInetRef()).arg(ext); 3133 QString dest_file; 3134 3135 if (metadata->GetSeason() > 0 || 3136 metadata->GetEpisode() > 0) 3137 { 3138 // Name TV downloads so that they already work with the PBB 3139 QString title = QString("%1 Season %2").arg(metadata->GetTitle()) 3140 .arg(metadata->GetSeason()); 3141 dest_file = QString("%1/%2.%3").arg(fileprefix) 3142 .arg(title).arg(ext); 3143 } 3144 else 3145 dest_file = QString("%1/%2.%3").arg(fileprefix) 3146 .arg(metadata->GetInetRef()).arg(ext); 3147 2843 3148 VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...") 2844 3149 .arg(url.toString()).arg(dest_file)); 2845 3150 … … 2932 3237 QUrl url(uri); 2933 3238 2934 3239 QString ext = QFileInfo(url.path()).suffix(); 2935 QString dest_file = QString("%1/%2.%3").arg(fileprefix) 2936 .arg(metadata->GetInetRef()).arg(ext); 3240 QString dest_file; 3241 3242 if (metadata->GetSeason() > 0 || 3243 metadata->GetEpisode() > 0) 3244 { 3245 // Name TV downloads so that they already work with the PBB 3246 QString title = QString("%1 Season %2").arg(metadata->GetTitle()) 3247 .arg(metadata->GetSeason()); 3248 dest_file = QString("%1/%2.%3").arg(fileprefix) 3249 .arg(title).arg(ext); 3250 } 3251 else 3252 dest_file = QString("%1/%2.%3").arg(fileprefix) 3253 .arg(metadata->GetInetRef()).arg(ext); 3254 2937 3255 VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...") 2938 3256 .arg(url.toString()).arg(dest_file)); 2939 3257 … … 2996 3314 UpdateItem(GetItemCurrent()); 2997 3315 } 2998 3316 3317 void VideoDialog::OnBannerURL(QString uri, Metadata *metadata) 3318 { 3319 if (metadata) 3320 { 3321 if (uri.length()) 3322 { 3323 QString fileprefix = m_d->m_banDir; 3324 3325 QDir dir; 3326 3327 // If the fanart setting hasn't been set default to 3328 // using ~/.mythtv/MythVideo/Banners 3329 if (fileprefix.length() == 0) 3330 { 3331 fileprefix = GetConfDir(); 3332 3333 dir.setPath(fileprefix); 3334 if (!dir.exists()) 3335 dir.mkdir(fileprefix); 3336 3337 fileprefix += "/MythVideo/Banners"; 3338 } 3339 3340 dir.setPath(fileprefix); 3341 if (!dir.exists()) 3342 dir.mkdir(fileprefix); 3343 3344 QUrl url(uri); 3345 3346 QString ext = QFileInfo(url.path()).suffix(); 3347 QString dest_file; 3348 3349 if (metadata->GetSeason() > 0 || 3350 metadata->GetEpisode() > 0) 3351 { 3352 // Name TV downloads so that they already work with the PBB 3353 QString title = QString("%1 Season %2").arg(metadata->GetTitle()) 3354 .arg(metadata->GetSeason()); 3355 dest_file = QString("%1/%2.%3").arg(fileprefix) 3356 .arg(title).arg(ext); 3357 } 3358 else 3359 dest_file = QString("%1/%2.%3").arg(fileprefix) 3360 .arg(metadata->GetInetRef()).arg(ext); 3361 3362 VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...") 3363 .arg(url.toString()).arg(dest_file)); 3364 3365 BannerDownloadProxy *d = 3366 BannerDownloadProxy::Create(url, dest_file, metadata); 3367 metadata->SetBanner(dest_file); 3368 3369 connect(d, SIGNAL(SigFinished(BannerDownloadErrorState, 3370 QString, Metadata *)), 3371 SLOT(OnBannerCopyFinished(BannerDownloadErrorState, 3372 QString, Metadata *))); 3373 3374 d->StartCopy(); 3375 m_d->AddBannerDownload(d); 3376 } 3377 else 3378 { 3379 metadata->SetBanner(""); 3380 OnVideoBannerSetDone(metadata); 3381 } 3382 } 3383 else 3384 OnVideoBannerSetDone(metadata); 3385 } 3386 3387 void VideoDialog::OnBannerCopyFinished(BannerDownloadErrorState error, 3388 QString errorMsg, Metadata *item) 3389 { 3390 QObject *src = sender(); 3391 if (src) 3392 m_d->RemoveBannerDownload(dynamic_cast<BannerDownloadProxy *> 3393 (src)); 3394 3395 if (error != besOK && item) 3396 item->SetBanner(""); 3397 3398 VERBOSE(VB_IMPORTANT, tr("Banner download finished: %1 %2") 3399 .arg(errorMsg).arg(error)); 3400 3401 if (error == besTimeout) 3402 { 3403 createOkDialog(tr("Banner exists for this item but could not be " 3404 "retrieved within the timeout period.\n")); 3405 } 3406 3407 OnVideoBannerSetDone(item); 3408 } 3409 3410 // This is the final call as part of a StartVideoBannerSet 3411 void VideoDialog::OnVideoBannerSetDone(Metadata *metadata) 3412 { 3413 // The metadata has a banner set 3414 if (m_busyPopup) 3415 { 3416 m_busyPopup->Close(); 3417 m_busyPopup = NULL; 3418 } 3419 3420 metadata->UpdateDatabase(); 3421 UpdateItem(GetItemCurrent()); 3422 } 3423 2999 3424 void VideoDialog::StartVideoSearchByUID(QString video_uid, Metadata *metadata) 3000 3425 { 3001 3426 // Starting the busy dialog here triggers a bizarre segfault … … 3028 3453 } 3029 3454 // set known values 3030 3455 metadata->SetTitle(data["Title"]); 3456 metadata->SetSubtitle(data["Subtitle"]); 3031 3457 metadata->SetYear(data["Year"].toInt()); 3032 3458 metadata->SetDirector(data["Director"]); 3033 3459 metadata->SetPlot(data["Plot"]); 3034 3460 metadata->SetUserRating(data["UserRating"].toFloat()); 3035 3461 metadata->SetRating(data["MovieRating"]); 3036 3462 metadata->SetLength(data["Runtime"].toInt()); 3463 metadata->SetSeason(data["Season"].toInt()); 3464 metadata->SetEpisode(data["Episode"].toInt()); 3037 3465 3038 3466 m_d->AutomaticParentalAdjustment(metadata); 3039 3467 -
mythplugins/mythvideo/mythvideo/videoscan.cpp
268 268 VIDEO_BANNER_DEFAULT, 269 269 VIDEO_FANART_DEFAULT, 270 270 Metadata::FilenameToTitle(p->first), 271 VIDEO_SUBTITLE_DEFAULT, 271 272 VIDEO_YEAR_DEFAULT, 272 273 VIDEO_INETREF_DEFAULT, VIDEO_DIRECTOR_DEFAULT, 273 VIDEO_PLOT_DEFAULT, 0.0, VIDEO_RATING_DEFAULT, 274 0, 0, ParentalLevel::plLowest); 274 VIDEO_PLOT_DEFAULT, 0.0, VIDEO_RATING_DEFAULT, 0, 275 Metadata::FilenameToSeasonEpisode(p->first, 1), 276 Metadata::FilenameToSeasonEpisode(p->first, 2), 277 0, ParentalLevel::plLowest); 275 278 276 279 VERBOSE(VB_GENERAL, QString("Adding : %1 : %2") 277 280 .arg(newFile.GetHost()).arg(newFile.GetFilename())); -
mythplugins/mythvideo/mythvideo/videofilter.cpp
353 353 ret = lhs_key < rhs_key; 354 354 break; 355 355 } 356 case kOrderBySeasonEp: 357 { 358 if (lhs.GetSeason() == rhs.GetSeason()) 359 ret = lhs.GetEpisode() < rhs.GetEpisode(); 360 else 361 ret = lhs.GetSeason() < rhs.GetSeason(); 362 break; 363 } 356 364 case kOrderByYearDescending: 357 365 { 358 366 ret = lhs.GetYear() > rhs.GetYear(); … … 649 657 // Order by 650 658 new MythUIButtonListItem(m_orderbyList, QObject::tr("Title"), 651 659 VideoFilterSettings::kOrderByTitle); 660 new MythUIButtonListItem(m_orderbyList, QObject::tr("Season/Episode"), 661 VideoFilterSettings::kOrderBySeasonEp); 652 662 new MythUIButtonListItem(m_orderbyList, QObject::tr("Year"), 653 663 VideoFilterSettings::kOrderByYearDescending); 654 664 new MythUIButtonListItem(m_orderbyList, QObject::tr("User Rating"), -
mythplugins/mythvideo/mythvideo/metadata.h
13 13 14 14 enum { VIDEO_YEAR_DEFAULT = 1895 }; 15 15 16 const QString VIDEO_SUBTITLE_DEFAULT = ""; 17 16 18 struct SortData; 17 19 18 20 class Metadata … … 45 47 public: 46 48 static SortKey GenerateDefaultSortKey(const Metadata &m, bool ignore_case); 47 49 static QString FilenameToTitle(const QString &file_name); 50 static unsigned int FilenameToSeasonEpisode(const QString &file_name, 51 int position); 48 52 static QString TrimTitle(const QString &title, bool ignore_case); 49 53 50 54 public: … … 55 59 const QString &banner = QString(), 56 60 const QString &fanart = QString(), 57 61 const QString &title = QString(), 62 const QString &subtitle = QString(), 58 63 int year = VIDEO_YEAR_DEFAULT, 59 64 const QString &inetref = QString(), 60 65 const QString &director = QString(), … … 62 67 float userrating = 0.0, 63 68 const QString &rating = QString(), 64 69 int length = 0, 70 int season = 0, 71 int episode = 0, 65 72 int id = 0, 66 73 ParentalLevel::Level showlevel = ParentalLevel::plLowest, 67 74 int categoryID = 0, … … 89 96 const QString &GetTitle() const; 90 97 void SetTitle(const QString& title); 91 98 99 const QString &GetSubtitle() const; 100 void SetSubtitle(const QString &subtitle); 101 92 102 int GetYear() const; 93 103 void SetYear(int year); 94 104 … … 110 120 int GetLength() const; 111 121 void SetLength(int length); 112 122 123 int GetSeason() const; 124 void SetSeason(int season); 125 126 int GetEpisode() const; 127 void SetEpisode(int episode); 128 113 129 unsigned int GetID() const; 114 130 void SetID(int id); 115 131 -
mythplugins/mythvideo/mythvideo/editmetadata.cpp
12 12 #include <mythtv/libmythui/mythuitextedit.h> 13 13 #include <mythtv/libmythui/mythuibutton.h> 14 14 #include <mythtv/libmythui/mythuicheckbox.h> 15 #include <mythtv/libmythui/mythuispinbox.h> 15 16 16 17 #include "globals.h" 17 18 #include "dbaccess.h" … … 22 23 EditMetadataDialog::EditMetadataDialog(MythScreenStack *lparent, 23 24 QString lname, Metadata *source_metadata, 24 25 const MetadataListManager &cache) : MythScreenType(lparent, lname), 25 m_origMetadata(source_metadata), m_titleEdit(0), m_playerEdit(0), 26 m_categoryList(0), m_levelList(0), m_childList(0), m_browseCheck(0), 27 m_coverartButton(0), m_coverartText(0), 26 m_origMetadata(source_metadata), m_titleEdit(0), m_subtitleEdit(0), 27 m_playerEdit(0), m_seasonSpin(0), m_episodeSpin(0), 28 m_categoryList(0), m_levelList(0), m_childList(0), 29 m_browseCheck(0), m_coverartButton(0), m_coverartText(0), 28 30 m_screenshotButton(0), m_screenshotText(0), 29 31 m_bannerButton(0), m_bannerText(0), 30 32 m_fanartButton(0), m_fanartText(0), … … 47 49 48 50 bool err = false; 49 51 UIUtilE::Assign(this, m_titleEdit, "title_edit", &err); 52 UIUtilE::Assign(this, m_subtitleEdit, "subtitle_edit", &err); 50 53 UIUtilE::Assign(this, m_playerEdit, "player_edit", &err); 51 54 55 UIUtilE::Assign(this, m_seasonSpin, "season", &err); 56 UIUtilE::Assign(this, m_episodeSpin, "episode", &err); 57 52 58 UIUtilE::Assign(this, m_coverartText, "coverart_text", &err); 53 59 UIUtilE::Assign(this, m_screenshotText, "screenshot_text", &err); 54 60 UIUtilE::Assign(this, m_bannerText, "banner_text", &err); … … 79 85 VERBOSE(VB_IMPORTANT, "Failed to build a focuslist."); 80 86 81 87 connect(m_titleEdit, SIGNAL(valueChanged()), SLOT(SetTitle())); 88 connect(m_subtitleEdit, SIGNAL(valueChanged()), SLOT(SetSubtitle())); 82 89 connect(m_playerEdit, SIGNAL(valueChanged()), SLOT(SetPlayer())); 83 90 91 connect(m_seasonSpin, SIGNAL(LosingFocus()), SLOT(SetSeason())); 92 connect(m_episodeSpin, SIGNAL(LosingFocus()), SLOT(SetEpisode())); 93 84 94 connect(m_doneButton, SIGNAL(Clicked()), SLOT(SaveAndExit())); 85 95 connect(m_coverartButton, SIGNAL(Clicked()), SLOT(FindCoverArt())); 86 96 connect(m_bannerButton, SIGNAL(Clicked()), SLOT(FindBanner())); … … 154 164 void EditMetadataDialog::fillWidgets() 155 165 { 156 166 m_titleEdit->SetText(m_workingMetadata->GetTitle()); 167 m_subtitleEdit->SetText(m_workingMetadata->GetSubtitle()); 157 168 169 m_seasonSpin->SetRange(0,100,1); 170 m_seasonSpin->SetValue(m_workingMetadata->GetSeason()); 171 m_episodeSpin->SetRange(0,999,1); 172 m_episodeSpin->SetValue(m_workingMetadata->GetEpisode()); 173 158 174 MythUIButtonListItem *button = 159 175 new MythUIButtonListItem(m_categoryList, VIDEO_CATEGORY_UNKNOWN); 160 176 const VideoCategory::entry_list &vcl = … … 312 328 m_workingMetadata->SetTitle(m_titleEdit->GetText()); 313 329 } 314 330 331 void EditMetadataDialog::SetSubtitle() 332 { 333 m_workingMetadata->SetSubtitle(m_subtitleEdit->GetText()); 334 } 335 315 336 void EditMetadataDialog::SetCategory(MythUIButtonListItem *item) 316 337 { 317 338 m_workingMetadata->SetCategoryID(item->GetData().toInt()); 318 339 } 319 340 341 void EditMetadataDialog::SetSeason() 342 { 343 m_workingMetadata->SetSeason(m_seasonSpin->GetIntValue()); 344 } 345 346 void EditMetadataDialog::SetEpisode() 347 { 348 m_workingMetadata->SetEpisode(m_episodeSpin->GetIntValue()); 349 } 350 320 351 void EditMetadataDialog::SetPlayer() 321 352 { 322 353 m_workingMetadata->SetPlayCommand(m_playerEdit->GetText()); -
mythplugins/mythvideo/mythvideo/videoutils.h
33 33 34 34 QString GetDisplayUserRating(float userrating); 35 35 QString GetDisplayLength(int length); 36 QString GetDisplaySeasonEpisode(int seasEp, int digits); 36 37 QString GetDisplayBrowse(bool browse); 37 38 QString GetDisplayYear(int year); 38 39 QString GetDisplayRating(const QString &rating); -
mythtv/themes/Terra/video-ui.xml
565 565 </imagetype> 566 566 567 567 <textarea name="title" from="basetextarea"> 568 <area>48,78, 980,35</area>568 <area>48,78,590,35</area> 569 569 <font>baselarge</font> 570 570 </textarea> 571 571 572 <textarea name="subtitle" from="basetextarea"> 573 <area>600,78,590,35</area> 574 <align>right</align> 575 <font>baselarge</font> 576 </textarea> 577 572 578 <statetype name="userratingstate" from="baserating"> 573 579 <position>1193,72</position> 574 580 </statetype> … … 583 589 <area>48,284,290,30</area> 584 590 </textarea> 585 591 592 <textarea name="##x##" from="basetextarea"> 593 <area>540,284,200,30</area> 594 <align>center</align> 595 </textarea> 596 586 597 <textarea name="director" from="basetextarea"> 587 598 <area>430,284,800,30</area> 588 599 <align>right</align> … … 604 615 <font>baselarge</font> 605 616 </textarea> 606 617 618 <imagetype name="fanart"> 619 <area>0,0,1280,720</area> 620 <filename /> 621 </imagetype> 622 607 623 <buttonlist name="videos"> 608 624 <area>12,0,1260,785</area> 609 625 <layout>grid</layout> … … 730 746 <value>Videos - Tree</value> 731 747 </textarea> 732 748 749 <imagetype name="fanart"> 750 <area>0,0,1280,720</area> 751 <filename /> 752 </imagetype> 753 733 754 <textarea name="breadcrumbs" from="basetextarea"> 734 755 <area>50,20,700,40</area> 735 756 <font>basemedium</font>