Ticket #6346: MythVideo.SubSeasEp.31909.diff
File MythVideo.SubSeasEp.31909.diff, 69.2 KB (added by , 15 years ago) |
---|
-
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"> -
mythvideo/theme/default-wide/video-ui.xml
467 477 </imagetype> 468 478 469 479 <textarea name="title" from="basetextarea"> 470 <area>370,12, 700,40</area>480 <area>370,12,400,40</area> 471 481 <multiline>yes</multiline> 472 482 <font>baselarge</font> 473 483 </textarea> 474 484 485 <textarea name="subtitle" from="basetextarea"> 486 <area>800,12,400,40</area> 487 <multiline>yes</multiline> 488 <font>baselarge</font> 489 </textarea> 490 475 491 <textarea name="currentvideo" from="basetextarea"> 476 492 <area>150,486,500,35</area> 477 493 <align>top,vcenter</align> … … 487 503 <font>basemedium</font> 488 504 </textarea> 489 505 506 <textarea name="s##e##" from="basetextarea"> 507 <area>1010,63,150,35</area> 508 <font>basemedium</font> 509 </textarea> 510 490 511 <textarea name="plot" from="basetextarea"> 491 512 <area>380,97,840,145</area> 492 513 <multiline>yes</multiline> … … 572 593 573 594 <window name="gallery"> 574 595 <textarea name="title" from="basetextarea"> 575 <area>70,15, 800,50</area>596 <area>70,15,420,50</area> 576 597 <cutdown>yes</cutdown> 577 598 <font>baselarge</font> 578 599 </textarea> … … 646 667 </state> 647 668 </statetype> 648 669 </buttonlist> 670 671 <textarea name="subtitle" from="basetextarea"> 672 <area>500,15,350,40</area> 673 <align>hcenter,vcenter</align> 674 <font>basemedium</font> 675 </textarea> 649 676 677 <textarea name="s##e##" from="basetextarea"> 678 <area>870,15,100,40</area> 679 <align>hcenter,vcenter</align> 680 <font>basemedium</font> 681 </textarea> 682 650 683 <textarea name="position" from="basetextarea"> 651 <area> 890,15,200,40</area>684 <area>1000,15,200,40</area> 652 685 <align>hcenter,vcenter</align> 653 686 <font>basemedium</font> 654 687 </textarea> … … 713 746 <font>baselarge</font> 714 747 </textarea> 715 748 749 <textarea name="s##e##" from="basetextarea"> 750 <area>50,380,400,30</area> 751 <font>basemedium</font> 752 </textarea> 753 754 <textarea name="subtitle" from="basetextarea"> 755 <area>50,420,400,30</area> 756 <font>basemedium</font> 757 </textarea> 758 716 759 <textarea name="director" from="basetextarea"> 717 <area>50, 367,450,30</area>760 <area>50,467,450,30</area> 718 761 </textarea> 719 762 720 763 <textarea name="year" from="basetextarea"> 721 <area>500, 367,80,30</area>764 <area>500,467,80,30</area> 722 765 <align>right</align> 723 766 </textarea> 724 767 725 768 <textarea name="plot" from="basetextarea"> 726 <area>40, 395,530,80</area>769 <area>40,495,530,80</area> 727 770 <align>left,top</align> 728 771 <multiline>yes</multiline> 729 772 <cutdown>yes</cutdown> 730 773 </textarea> 731 774 732 775 <textarea name="cast" from="basetextarea"> 733 <area>60, 480,505,70</area>776 <area>60,580,505,70</area> 734 777 <align>left,top</align> 735 778 <multiline>yes</multiline> 736 779 <cutdown>no</cutdown> 737 780 </textarea> 738 781 739 782 <textarea name="position" from="basetextarea"> 740 <area>266, 555,266,40</area>783 <area>266,655,266,40</area> 741 784 <font>basemedium</font> 742 785 <align>hcenter,vcenter</align> 743 786 </textarea> … … 843 886 <window name="edit_metadata"> 844 887 845 888 <textarea name="title" from="basetextarea"> 846 <area>10, 50,1260,50</area>889 <area>10,30,760,50</area> 847 890 <value>Edit Video Information</value> 848 891 <align>hcenter,vcenter</align> 849 892 <font>baselarge</font> … … 852 895 <!-- Labels --> 853 896 854 897 <textarea name="title_text" from="basetextarea"> 855 <area> 250,110,250,40</area>856 <value> Name:</value>898 <area>50,80,250,40</area> 899 <value>Title:</value> 857 900 <align>right,top</align> 858 901 </textarea> 859 902 903 <textarea name="subtitle_text" from="basetextarea"> 904 <area>50,138,250,40</area> 905 <value>Subtitle:</value> 906 <align>right,top</align> 907 </textarea> 908 909 <textarea name="season_text" from="basetextarea"> 910 <area>50,185,250,40</area> 911 <value>Season:</value> 912 <align>right,top</align> 913 </textarea> 914 915 <textarea name="episode_text" from="basetextarea"> 916 <area>370,185,150,40</area> 917 <value>Episode:</value> 918 <align>right,top</align> 919 </textarea> 920 860 921 <textarea name="category_text" from="title_text"> 861 <position>250,172</position> 922 <area>420,232,150,40</area> 923 <align>right</align> 862 924 <value>Category:</value> 863 925 </textarea> 864 926 865 927 <textarea name="level_text" from="title_text"> 866 <position>250,222</position> 928 <area>20,232,200,40</area> 929 <align>right</align> 867 930 <value>Parental Control:</value> 868 931 </textarea> 869 932 870 933 <textarea name="child_text" from="title_text"> 871 <position>250,267</position> 934 <area>20,277,200,40</area> 935 <align>right</align> 872 936 <value>File to Always Play Next:</value> 873 937 </textarea> 874 938 875 939 <textarea name="browse_text" from="title_text"> 876 <position>250,312</position> 940 <area>470,277,280,40</area> 941 <align>left</align> 877 942 <value>Include while Browsing:</value> 878 943 </textarea> 879 944 880 945 <textarea name="coverart_text_label" from="title_text"> 881 <position> 250,348</position>946 <position>50,328</position> 882 947 <value>Cover Art:</value> 883 948 </textarea> 884 949 885 950 <textarea name="screenshot_text_label" from="title_text"> 886 <position> 250,377</position>951 <position>50,357</position> 887 952 <value>Screenshot:</value> 888 953 </textarea> 889 954 890 955 <textarea name="banner_text_label" from="title_text"> 891 <position> 250,406</position>956 <position>50,386</position> 892 957 <value>Banner:</value> 893 958 </textarea> 894 959 895 960 <textarea name="fanart_text_label" from="title_text"> 896 <position> 250,435</position>961 <position>50,415</position> 897 962 <value>Fanart:</value> 898 963 </textarea> 899 964 900 965 <textarea name="trailer_text_label" from="title_text"> 901 <position> 250,464</position>966 <position>50,447</position> 902 967 <value>Trailer:</value> 903 968 </textarea> 904 969 905 970 <textarea name="player_text" from="title_text"> 906 <position> 250,510</position>971 <position>50,487</position> 907 972 <value>Unique Player Command:</value> 908 973 </textarea> 909 974 910 975 <!-- Widgets --> 911 976 912 977 <textedit name="title_edit" from="basetextedit"> 913 <position> 510,100</position>978 <position>310,70</position> 914 979 </textedit> 915 980 916 < buttonlist name="category_select" from="baseselector">917 <position> 510,165</position>918 </ buttonlist>981 <textedit name="subtitle_edit" from="basetextedit"> 982 <position>310,126</position> 983 </textedit> 919 984 985 <spinbox name="season" from="basespinbox"> 986 <position>310,181</position> 987 </spinbox> 988 989 <spinbox name="episode" from="basespinbox"> 990 <position>530,181</position> 991 </spinbox> 992 920 993 <buttonlist name="level_select" from="baseselector"> 921 <position> 510,215</position>994 <position>230,225</position> 922 995 </buttonlist> 923 996 997 <buttonlist name="category_select" from="baseselector"> 998 <position>580,225</position> 999 </buttonlist> 1000 924 1001 <buttonlist name="child_select" from="baseselector"> 925 <position> 510,260</position>1002 <position>230,270</position> 926 1003 </buttonlist> 927 1004 928 1005 <checkbox name="browse_check" from="basecheckbox"> 929 <position> 510,310</position>1006 <position>735,275</position> 930 1007 </checkbox> 931 1008 932 <button name="coverart_button" from="basesearchbutton"> 933 <position>510,343</position> 1009 <button name="coverart_button"> 1010 <area>310,323,32,32</area> 1011 <statetype name="buttonstate"> 1012 <state name="active"> 1013 <imagetype name="background"> 1014 <filename>blankbutton_off.png</filename> 1015 </imagetype> 1016 </state> 1017 <state name="selected" from="active"> 1018 <imagetype name="background"> 1019 <filename>blankbutton_on.png</filename> 1020 </imagetype> 1021 </state> 1022 <state name="disabled" from="active" /> 1023 <state name="pushed" from="active"> 1024 <imagetype name="background"> 1025 <filename>blankbutton_pushed.png</filename> 1026 </imagetype> 1027 </state> 1028 </statetype> 934 1029 </button> 935 1030 936 1031 <textarea name="coverart_text" from="basetextarea"> 937 <area> 550,348,250,40</area>1032 <area>350,328,250,40</area> 938 1033 <value>/path/to/the/thing.jpg</value> 939 1034 </textarea> 940 1035 941 <button name="screenshot_button" from="basesearchbutton"> 942 <position>510,372</position> 1036 <button name="screenshot_button"> 1037 <area>310,352,32,32</area> 1038 <statetype name="buttonstate"> 1039 <state name="active"> 1040 <imagetype name="background"> 1041 <filename>blankbutton_off.png</filename> 1042 </imagetype> 1043 </state> 1044 <state name="selected" from="active"> 1045 <imagetype name="background"> 1046 <filename>blankbutton_on.png</filename> 1047 </imagetype> 1048 </state> 1049 <state name="disabled" from="active" /> 1050 <state name="pushed" from="active"> 1051 <imagetype name="background"> 1052 <filename>blankbutton_pushed.png</filename> 1053 </imagetype> 1054 </state> 1055 </statetype> 943 1056 </button> 944 1057 945 1058 <textarea name="screenshot_text" from="basetextarea"> 946 <area> 550,377,250,40</area>1059 <area>350,357,250,40</area> 947 1060 <value>/path/to/the/thing.jpg</value> 948 1061 </textarea> 949 1062 950 <button name="banner_button" from="basesearchbutton"> 951 <position>510,401</position> 1063 <button name="banner_button"> 1064 <area>310,381,32,32</area> 1065 <statetype name="buttonstate"> 1066 <state name="active"> 1067 <imagetype name="background"> 1068 <filename>blankbutton_off.png</filename> 1069 </imagetype> 1070 </state> 1071 <state name="selected" from="active"> 1072 <imagetype name="background"> 1073 <filename>blankbutton_on.png</filename> 1074 </imagetype> 1075 </state> 1076 <state name="disabled" from="active" /> 1077 <state name="pushed" from="active"> 1078 <imagetype name="background"> 1079 <filename>blankbutton_pushed.png</filename> 1080 </imagetype> 1081 </state> 1082 </statetype> 952 1083 </button> 953 1084 954 1085 <textarea name="banner_text" from="basetextarea"> 955 <area> 550,406,250,40</area>1086 <area>350,386,250,40</area> 956 1087 <value>/path/to/the/thing.jpg</value> 957 1088 </textarea> 958 1089 959 <button name="fanart_button" from="basesearchbutton"> 960 <position>510,430</position> 1090 <button name="fanart_button"> 1091 <area>310,412,32,32</area> 1092 <statetype name="buttonstate"> 1093 <state name="active"> 1094 <imagetype name="background"> 1095 <filename>blankbutton_off.png</filename> 1096 </imagetype> 1097 </state> 1098 <state name="selected" from="active"> 1099 <imagetype name="background"> 1100 <filename>blankbutton_on.png</filename> 1101 </imagetype> 1102 </state> 1103 <state name="disabled" from="active" /> 1104 <state name="pushed" from="active"> 1105 <imagetype name="background"> 1106 <filename>blankbutton_pushed.png</filename> 1107 </imagetype> 1108 </state> 1109 </statetype> 961 1110 </button> 962 1111 963 1112 <textarea name="fanart_text" from="basetextarea"> 964 <area> 550,435,250,40</area>1113 <area>350,415,250,40</area> 965 1114 <value>/path/to/the/thing.jpg</value> 966 1115 </textarea> 967 1116 968 <button name="trailer_button" from="basesearchbutton"> 969 <position>510,460</position> 1117 <button name="trailer_button"> 1118 <area>310,442,32,32</area> 1119 <statetype name="buttonstate"> 1120 <state name="active"> 1121 <imagetype name="background"> 1122 <filename>blankbutton_off.png</filename> 1123 </imagetype> 1124 </state> 1125 <state name="selected" from="active"> 1126 <imagetype name="background"> 1127 <filename>blankbutton_on.png</filename> 1128 </imagetype> 1129 </state> 1130 <state name="disabled" from="active" /> 1131 <state name="pushed" from="active"> 1132 <imagetype name="background"> 1133 <filename>blankbutton_pushed.png</filename> 1134 </imagetype> 1135 </state> 1136 </statetype> 970 1137 </button> 971 1138 972 1139 <textarea name="trailer_text" from="basetextarea"> 973 <area> 550,465,250,40</area>1140 <area>350,447,250,40</area> 974 1141 <value>/path/to/the/thing.jpg</value> 975 1142 </textarea> 976 1143 1144 977 1145 <textedit name="player_edit" from="basetextedit"> 978 <position> 510,495</position>1146 <position>310,477</position> 979 1147 </textedit> 980 1148 981 1149 <button name="done_button" from="basebutton"> 982 <position> 510,565</position>1150 <position>310,537</position> 983 1151 <value>Done</value> 984 1152 </button> 985 1153 -
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, -
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 -
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(); -
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 movie 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 movie banner")); 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"); … … 782 856 VConfigPage page7(pages, false); 783 857 page7->addChild(trlr); 784 858 859 // page 8 860 VerticalConfigurationGroup *tvman = 861 new VerticalConfigurationGroup(true, false); 862 tvman->setLabel(QObject::tr("Television in MythVideo")); 863 tvman->addChild(SearchTVListingsCommand()); 864 tvman->addChild(GetTVPostersCommand()); 865 tvman->addChild(GetTVFanartCommand()); 866 tvman->addChild(GetTVBannerCommand()); 867 tvman->addChild(GetTVDataCommand()); 868 869 VConfigPage page8(pages, false); 870 page8->addChild(tvman); 871 785 872 int page_num = 1; 786 873 for (ConfigPage::PageList::const_iterator p = pages.begin(); 787 874 p != pages.end(); ++p, ++page_num) -
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; } -
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 } -
mythvideo/mythvideo/videoutils.cpp
139 142 return QString("%1 minutes").arg(length); 140 143 } 141 144 145 QString GetDisplaySeasonEpisode(int seasEp, int digits) 146 { 147 QString seasEpNum = QString::number(seasEp); 148 149 if (digits == 2 && seasEpNum.size() < 2) 150 seasEpNum.prepend("0"); 151 152 return seasEpNum; 153 } 154 142 155 QString GetDisplayBrowse(bool browse) 143 156 { 144 157 return browse ? QObject::tr("Yes") : QObject::tr("No"); -
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; -
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 .arg("mythvideo/scripts/tmdb.pl - B"));635 const QString cmd = gContext->GetSetting("MovieFanartCommandLine",808 .arg("mythvideo/scripts/tmdb.pl -F")); 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 3107 SLOT(OnFanartURL(QString, Metadata *))); 2807 3108 vfs->Run(metadata->GetInetRef(), metadata); 2808 3109 } 3110 3111 if (metadata->GetBanner().isEmpty() && 3112 (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0)) 3113 { 3114 // Obtain video banner (only for TV) 3115 VideoBannerSearch *vbs = new VideoBannerSearch(this); 3116 connect(vbs, SIGNAL(SigBannerURL(QString, Metadata *)), 3117 SLOT(OnBannerURL(QString, Metadata *))); 3118 vbs->Run(metadata->GetInetRef(), metadata); 3119 } 2809 3120 } 2810 3121 2811 3122 void VideoDialog::OnPosterURL(QString uri, Metadata *metadata) … … 2838 3149 QUrl url(uri); 2839 3150 2840 3151 QString ext = QFileInfo(url.path()).suffix(); 2841 QString dest_file = QString("%1/%2.%3").arg(fileprefix) 2842 .arg(metadata->GetInetRef()).arg(ext); 3152 QString dest_file; 3153 3154 if (metadata->GetSeason() > 0 || 3155 metadata->GetEpisode() > 0) 3156 { 3157 // Name TV downloads so that they already work with the PBB 3158 QString title = QString("%1 Season %2").arg(metadata->GetTitle()) 3159 .arg(metadata->GetSeason()); 3160 dest_file = QString("%1/%2.%3").arg(fileprefix) 3161 .arg(title).arg(ext); 3162 } 3163 else 3164 dest_file = QString("%1/%2.%3").arg(fileprefix) 3165 .arg(metadata->GetInetRef()).arg(ext); 3166 2843 3167 VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...") 2844 3168 .arg(url.toString()).arg(dest_file)); 2845 3169 … … 2932 3256 QUrl url(uri); 2933 3257 2934 3258 QString ext = QFileInfo(url.path()).suffix(); 2935 QString dest_file = QString("%1/%2.%3").arg(fileprefix) 2936 .arg(metadata->GetInetRef()).arg(ext); 3259 QString dest_file; 3260 3261 if (metadata->GetSeason() > 0 || 3262 metadata->GetEpisode() > 0) 3263 { 3264 // Name TV downloads so that they already work with the PBB 3265 QString title = QString("%1 Season %2").arg(metadata->GetTitle()) 3266 .arg(metadata->GetSeason()); 3267 dest_file = QString("%1/%2.%3").arg(fileprefix) 3268 .arg(title).arg(ext); 3269 } 3270 else 3271 dest_file = QString("%1/%2.%3").arg(fileprefix) 3272 .arg(metadata->GetInetRef()).arg(ext); 3273 2937 3274 VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...") 2938 3275 .arg(url.toString()).arg(dest_file)); 2939 3276 … … 2996 3333 UpdateItem(GetItemCurrent()); 2997 3334 } 2998 3335 3336 void VideoDialog::OnBannerURL(QString uri, Metadata *metadata) 3337 { 3338 if (metadata) 3339 { 3340 if (uri.length()) 3341 { 3342 QString fileprefix = m_d->m_banDir; 3343 3344 QDir dir; 3345 3346 // If the fanart setting hasn't been set default to 3347 // using ~/.mythtv/MythVideo/Banners 3348 if (fileprefix.length() == 0) 3349 { 3350 fileprefix = GetConfDir(); 3351 3352 dir.setPath(fileprefix); 3353 if (!dir.exists()) 3354 dir.mkdir(fileprefix); 3355 3356 fileprefix += "/MythVideo/Banners"; 3357 } 3358 3359 dir.setPath(fileprefix); 3360 if (!dir.exists()) 3361 dir.mkdir(fileprefix); 3362 3363 QUrl url(uri); 3364 3365 QString ext = QFileInfo(url.path()).suffix(); 3366 QString dest_file; 3367 3368 if (metadata->GetSeason() > 0 || 3369 metadata->GetEpisode() > 0) 3370 { 3371 // Name TV downloads so that they already work with the PBB 3372 QString title = QString("%1 Season %2").arg(metadata->GetTitle()) 3373 .arg(metadata->GetSeason()); 3374 dest_file = QString("%1/%2.%3").arg(fileprefix) 3375 .arg(title).arg(ext); 3376 } 3377 else 3378 dest_file = QString("%1/%2.%3").arg(fileprefix) 3379 .arg(metadata->GetInetRef()).arg(ext); 3380 3381 VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...") 3382 .arg(url.toString()).arg(dest_file)); 3383 3384 BannerDownloadProxy *d = 3385 BannerDownloadProxy::Create(url, dest_file, metadata); 3386 metadata->SetBanner(dest_file); 3387 3388 connect(d, SIGNAL(SigFinished(BannerDownloadErrorState, 3389 QString, Metadata *)), 3390 SLOT(OnBannerCopyFinished(BannerDownloadErrorState, 3391 QString, Metadata *))); 3392 3393 d->StartCopy(); 3394 m_d->AddBannerDownload(d); 3395 } 3396 else 3397 { 3398 metadata->SetBanner(""); 3399 OnVideoBannerSetDone(metadata); 3400 } 3401 } 3402 else 3403 OnVideoBannerSetDone(metadata); 3404 } 3405 3406 void VideoDialog::OnBannerCopyFinished(BannerDownloadErrorState error, 3407 QString errorMsg, Metadata *item) 3408 { 3409 QObject *src = sender(); 3410 if (src) 3411 m_d->RemoveBannerDownload(dynamic_cast<BannerDownloadProxy *> 3412 (src)); 3413 3414 if (error != besOK && item) 3415 item->SetBanner(""); 3416 3417 VERBOSE(VB_IMPORTANT, tr("Banner download finished: %1 %2") 3418 .arg(errorMsg).arg(error)); 3419 3420 if (error == besTimeout) 3421 { 3422 createOkDialog(tr("Banner exists for this item but could not be " 3423 "retrieved within the timeout period.\n")); 3424 } 3425 3426 OnVideoBannerSetDone(item); 3427 } 3428 3429 // This is the final call as part of a StartVideoBannerSet 3430 void VideoDialog::OnVideoBannerSetDone(Metadata *metadata) 3431 { 3432 // The metadata has a banner set 3433 if (m_busyPopup) 3434 { 3435 m_busyPopup->Close(); 3436 m_busyPopup = NULL; 3437 } 3438 3439 metadata->UpdateDatabase(); 3440 UpdateItem(GetItemCurrent()); 3441 } 3442 2999 3443 void VideoDialog::StartVideoSearchByUID(QString video_uid, Metadata *metadata) 3000 3444 { 3001 3445 // Starting the busy dialog here triggers a bizarre segfault … … 3028 3472 } 3029 3473 // set known values 3030 3474 metadata->SetTitle(data["Title"]); 3475 metadata->SetSubtitle(data["Subtitle"]); 3031 3476 metadata->SetYear(data["Year"].toInt()); 3032 3477 metadata->SetDirector(data["Director"]); 3033 3478 metadata->SetPlot(data["Plot"]); 3034 3479 metadata->SetUserRating(data["UserRating"].toFloat()); 3035 3480 metadata->SetRating(data["MovieRating"]); 3036 3481 metadata->SetLength(data["Runtime"].toInt()); 3482 metadata->SetSeason(data["Season"].toInt()); 3483 metadata->SetEpisode(data["Episode"].toInt()); 3037 3484 3038 3485 m_d->AutomaticParentalAdjustment(metadata); 3039 3486 -
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())); -
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"), -
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 -
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()); -
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);