Ticket #6346: MythVideo.SubSeasEp.33109.diff

File MythVideo.SubSeasEp.33109.diff, 79.3 KB (added by robert.mcnamara@…, 15 years ago)

Exorcise random hunks from another patch, sigh

  • mythplugins/mythvideo/theme/default/video-ui.xml

     
    867867        <!-- Labels  -->
    868868
    869869        <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>
    872872            <align>right,top</align>
    873873        </textarea>
    874874
     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
    875893        <textarea name="category_text" from="title_text">
    876             <position>50,152</position>
     894            <area>370,232,150,40</area>
     895            <align>right</align>
    877896            <value>Category:</value>
    878897        </textarea>
    879898
    880899        <textarea name="level_text" from="title_text">
    881             <position>50,202</position>
     900            <area>20,232,200,40</area>
     901            <align>right</align>
    882902            <value>Parental Control:</value>
    883903        </textarea>
    884904
    885905        <textarea name="child_text" from="title_text">
    886             <position>50,247</position>
     906            <area>20,277,200,40</area>
     907            <align>right</align>
    887908            <value>File to Always Play Next:</value>
    888909        </textarea>
    889910
    890911        <textarea name="browse_text" from="title_text">
    891             <position>50,292</position>
     912            <area>500,277,200,40</area>
     913            <align>left</align>
    892914            <value>Include while Browsing:</value>
    893915        </textarea>
    894916
     
    925947        <!-- Widgets -->
    926948
    927949        <textedit name="title_edit" from="basetextedit">
    928             <position>310,80</position>
     950            <position>310,70</position>
    929951        </textedit>
    930952
    931         <buttonlist name="category_select" from="baseselector">
    932             <position>310,145</position>
    933         </buttonlist>
     953        <textedit name="subtitle_edit" from="basetextedit">
     954            <position>310,126</position>
     955        </textedit>
    934956
     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
    935965        <buttonlist name="level_select" from="baseselector">
    936             <position>310,195</position>
     966            <position>230,225</position>
    937967        </buttonlist>
    938968
     969        <buttonlist name="category_select" from="baseselector">
     970            <position>530,225</position>
     971        </buttonlist>
     972
    939973        <buttonlist name="child_select" from="baseselector">
    940             <position>310,240</position>
     974            <position>230,270</position>
    941975        </buttonlist>
    942976
    943977        <checkbox name="browse_check" from="basecheckbox">
    944             <position>310,290</position>
     978            <position>680,275</position>
    945979        </checkbox>
    946980
    947981        <button name="coverart_button" from="basesearchbutton">
  • mythplugins/mythvideo/theme/default-wide/video-ui.xml

     
    467467        </imagetype>
    468468
    469469        <textarea name="title" from="basetextarea">
    470             <area>370,12,700,40</area>
     470            <area>370,12,400,40</area>
    471471            <multiline>yes</multiline>
    472472            <font>baselarge</font>
    473473        </textarea>
    474474
     475        <textarea name="subtitle" from="basetextarea">
     476            <area>800,12,400,40</area>
     477            <multiline>yes</multiline>
     478            <font>baselarge</font>
     479        </textarea>
     480
    475481        <textarea name="currentvideo" from="basetextarea">
    476482            <area>150,486,500,35</area>
    477483            <align>top,vcenter</align>
     
    487493            <font>basemedium</font>
    488494        </textarea>
    489495
     496        <textarea name="s##e##" from="basetextarea">
     497            <area>1010,63,150,35</area>
     498            <font>basemedium</font>
     499        </textarea>
     500
    490501        <textarea name="plot" from="basetextarea">
    491502            <area>380,97,840,145</area>
    492503            <multiline>yes</multiline>
     
    572583
    573584    <window name="gallery">
    574585        <textarea name="title" from="basetextarea">
    575             <area>70,15,800,50</area>
     586            <area>70,15,420,50</area>
    576587            <cutdown>yes</cutdown>
    577588            <font>baselarge</font>
    578589        </textarea>
     
    646657                </state>
    647658            </statetype>
    648659        </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>
    649666
     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
    650673        <textarea name="position" from="basetextarea">
    651             <area>890,15,200,40</area>
     674            <area>1000,15,200,40</area>
    652675            <align>hcenter,vcenter</align>
    653676            <font>basemedium</font>
    654677        </textarea>
     
    713736            <font>baselarge</font>
    714737        </textarea>
    715738
     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
    716749        <textarea name="director" from="basetextarea">
    717             <area>50,367,450,30</area>
     750            <area>50,467,450,30</area>
    718751        </textarea>
    719752
    720753        <textarea name="year" from="basetextarea">
    721             <area>500,367,80,30</area>
     754            <area>500,467,80,30</area>
    722755            <align>right</align>
    723756        </textarea>
    724757
    725758        <textarea name="plot" from="basetextarea">
    726             <area>40,395,530,80</area>
     759            <area>40,495,530,80</area>
    727760            <align>left,top</align>
    728761            <multiline>yes</multiline>
    729762            <cutdown>yes</cutdown>
    730763        </textarea>
    731764
    732765        <textarea name="cast" from="basetextarea">
    733             <area>60,480,505,70</area>
     766            <area>60,580,505,70</area>
    734767            <align>left,top</align>
    735768            <multiline>yes</multiline>
    736769            <cutdown>no</cutdown>
    737770        </textarea>
    738771
    739772        <textarea name="position" from="basetextarea">
    740             <area>266,555,266,40</area>
     773            <area>266,655,266,40</area>
    741774            <font>basemedium</font>
    742775            <align>hcenter,vcenter</align>
    743776        </textarea>
     
    843876    <window name="edit_metadata">
    844877
    845878        <textarea name="title" from="basetextarea">
    846             <area>10,50,1260,50</area>
     879            <area>10,30,760,50</area>
    847880            <value>Edit Video Information</value>
    848881            <align>hcenter,vcenter</align>
    849882            <font>baselarge</font>
     
    852885        <!-- Labels  -->
    853886
    854887        <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>
    857890            <align>right,top</align>
    858891        </textarea>
    859892
     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
    860911        <textarea name="category_text" from="title_text">
    861             <position>250,172</position>
     912            <area>420,232,150,40</area>
     913            <align>right</align>
    862914            <value>Category:</value>
    863915        </textarea>
    864916
    865917        <textarea name="level_text" from="title_text">
    866             <position>250,222</position>
     918            <area>20,232,200,40</area>
     919            <align>right</align>
    867920            <value>Parental Control:</value>
    868921        </textarea>
    869922
    870923        <textarea name="child_text" from="title_text">
    871             <position>250,267</position>
     924            <area>20,277,200,40</area>
     925            <align>right</align>
    872926            <value>File to Always Play Next:</value>
    873927        </textarea>
    874928
    875929        <textarea name="browse_text" from="title_text">
    876             <position>250,312</position>
     930            <area>470,277,280,40</area>
     931            <align>left</align>
    877932            <value>Include while Browsing:</value>
    878933        </textarea>
    879934
    880935        <textarea name="coverart_text_label" from="title_text">
    881             <position>250,348</position>
     936            <position>50,328</position>
    882937            <value>Cover Art:</value>
    883938        </textarea>
    884939
    885940        <textarea name="screenshot_text_label" from="title_text">
    886             <position>250,377</position>
     941            <position>50,357</position>
    887942            <value>Screenshot:</value>
    888943        </textarea>
    889944
    890945        <textarea name="banner_text_label" from="title_text">
    891             <position>250,406</position>
     946            <position>50,386</position>
    892947            <value>Banner:</value>
    893948        </textarea>
    894949
    895950        <textarea name="fanart_text_label" from="title_text">
    896             <position>250,435</position>
     951            <position>50,415</position>
    897952            <value>Fanart:</value>
    898953        </textarea>
    899954
    900955        <textarea name="trailer_text_label" from="title_text">
    901             <position>250,464</position>
     956            <position>50,447</position>
    902957            <value>Trailer:</value>
    903958        </textarea>
    904959
    905960        <textarea name="player_text" from="title_text">
    906             <position>250,510</position>
     961            <position>50,487</position>
    907962            <value>Unique Player Command:</value>
    908963        </textarea>
    909964
    910965        <!-- Widgets -->
    911966
    912967        <textedit name="title_edit" from="basetextedit">
    913             <position>510,100</position>
     968            <position>310,70</position>
    914969        </textedit>
    915970
    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>
    919974
     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
    920983        <buttonlist name="level_select" from="baseselector">
    921             <position>510,215</position>
     984            <position>230,225</position>
    922985        </buttonlist>
    923986
     987        <buttonlist name="category_select" from="baseselector">
     988            <position>580,225</position>
     989        </buttonlist>
     990
    924991        <buttonlist name="child_select" from="baseselector">
    925             <position>510,260</position>
     992            <position>230,270</position>
    926993        </buttonlist>
    927994
    928995        <checkbox name="browse_check" from="basecheckbox">
    929             <position>510,310</position>
     996            <position>735,275</position>
    930997        </checkbox>
    931998
    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>
    9341019        </button>
    9351020
    9361021        <textarea name="coverart_text" from="basetextarea">
    937             <area>550,348,250,40</area>
     1022            <area>350,328,250,40</area>
    9381023            <value>/path/to/the/thing.jpg</value>
    9391024        </textarea>
    9401025
    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>
    9431046        </button>
    9441047
    9451048        <textarea name="screenshot_text" from="basetextarea">
    946             <area>550,377,250,40</area>
     1049            <area>350,357,250,40</area>
    9471050            <value>/path/to/the/thing.jpg</value>
    9481051        </textarea>
    9491052
    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>
    9521073        </button>
    9531074
    9541075        <textarea name="banner_text" from="basetextarea">
    955             <area>550,406,250,40</area>
     1076            <area>350,386,250,40</area>
    9561077            <value>/path/to/the/thing.jpg</value>
    9571078        </textarea>
    9581079
    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>
    9611100        </button>
    9621101
    9631102        <textarea name="fanart_text" from="basetextarea">
    964             <area>550,435,250,40</area>
     1103            <area>350,415,250,40</area>
    9651104            <value>/path/to/the/thing.jpg</value>
    9661105        </textarea>
    9671106
    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>
    9701127        </button>
    9711128
    9721129        <textarea name="trailer_text" from="basetextarea">
    973             <area>550,465,250,40</area>
     1130            <area>350,447,250,40</area>
    9741131            <value>/path/to/the/thing.jpg</value>
    9751132        </textarea>
    9761133
     1134
    9771135        <textedit name="player_edit" from="basetextedit">
    978             <position>510,495</position>
     1136            <position>310,477</position>
    9791137        </textedit>
    9801138
    9811139        <button name="done_button" from="basebutton">
    982             <position>510,565</position>
     1140            <position>310,537</position>
    9831141            <value>Done</value>
    9841142        </button>
    9851143
  • mythplugins/mythvideo/mythvideo/videodlg.h

     
    2828
    2929enum CoverDownloadErrorState { esOK, esError, esTimeout };
    3030enum FanartDownloadErrorState { fesOK, fesError, fesTimeout };
     31enum BannerDownloadErrorState { besOK, besError, besTimeout };
    3132
    3233class VideoDialog : public MythScreenType
    3334{
     
    140141    // OnVideoPosterSetDone() stop wait background
    141142    void StartVideoPosterSet(Metadata *metadata);
    142143    void StartVideoFanartSet(Metadata *metadata);
     144    void StartVideoBannerSet(Metadata *metadata);
    143145
    144146    // StartVideoSearchByUID() start wait background
    145147    //   OnVideoSearchByUIDDone() stop wait background
     
    159161    void OnFanartURL(QString uri, Metadata *metadata);
    160162    void OnFanartCopyFinished(FanartDownloadErrorState error, QString errorMsg,
    161163                              Metadata *metadata);
     164    void OnBannerURL(QString uri, Metadata *metadata);
     165    void OnBannerCopyFinished(BannerDownloadErrorState error, QString errorMsg,
     166                              Metadata *metadata);
    162167
    163168    // called during StartVideoSearchByTitle
    164169    void OnVideoSearchByTitleDone(bool normal_exit,
     
    170175    // StartVideoPosterSet end
    171176    void OnVideoPosterSetDone(Metadata *metadata);
    172177    void OnVideoFanartSetDone(Metadata *metadata);
     178    void OnVideoBannerSetDone(Metadata *metadata);
    173179
    174180    // StartVideoSearchByUID end
    175181    void OnVideoSearchByUIDDone(bool normal_exit,
  • mythplugins/mythvideo/mythvideo/metadatalistmanager.cpp

     
    112112    MSqlQuery query(MSqlQuery::InitCon());
    113113    query.setForwardOnly(true);
    114114    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");
    119120
    120121    query.prepare(BaseMetadataQuery);
    121122
  • mythplugins/mythvideo/mythvideo/metadata.cpp

     
    8989  public:
    9090    MetadataImp(const QString &filename, const QString &trailer, const QString &coverfile,
    9191             const QString &screenshot, const QString &banner, const QString &fanart,
    92              const QString &title, int year,
     92             const QString &title, const QString &subtitle, int year,
    9393             const QString &inetref, const QString &director,
    9494             const QString &plot, float userrating,
    9595             const QString &rating, int length,
     96             int season, int episode,
    9697             int id, ParentalLevel::Level showlevel, int categoryID,
    9798             int childID, bool browse,
    9899             const QString &playcommand, const QString &category,
     
    100101             const country_list &countries,
    101102             const cast_list &cast,
    102103             const QString &host = "") :
    103         m_title(title),
     104        m_title(title), m_subtitle(subtitle),
    104105        m_inetref(inetref), m_director(director), m_plot(plot),
    105106        m_rating(rating), m_playcommand(playcommand), m_category(category),
    106107        m_genres(genres), m_countries(countries), m_cast(cast),
    107108        m_filename(filename), m_trailer(trailer), m_coverfile(coverfile),
    108109        m_screenshot(screenshot), m_banner(banner), m_fanart(fanart),
    109110        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),
    111113        m_browse(browse), m_id(id), m_userrating(userrating)
    112114    {
    113115        VideoCategory::GetCategory().get(m_categoryID, m_category);
     
    128130        if (this != &rhs)
    129131        {
    130132            m_title = rhs.m_title;
     133            m_subtitle = rhs.m_subtitle;
    131134            m_inetref = rhs.m_inetref;
    132135            m_director = rhs.m_director;
    133136            m_plot = rhs.m_plot;
     
    148151            m_childID = rhs.m_childID;
    149152            m_year = rhs.m_year;
    150153            m_length = rhs.m_length;
     154            m_season = rhs.m_season;
     155            m_episode = rhs.m_episode;
    151156            m_showlevel = rhs.m_showlevel;
    152157            m_browse = rhs.m_browse;
    153158            m_id = rhs.m_id;
     
    180185        m_title = title;
    181186    }
    182187
     188    const QString &getSubtitle() const { return m_subtitle; }
     189    void SetSubtitle(const QString &subtitle) { m_subtitle = subtitle; }
     190
    183191    const QString &GetInetRef() const { return m_inetref; }
    184192    void SetInetRef(const QString &inetRef) { m_inetref = inetRef; }
    185193
     
    249257    int GetLength() const { return m_length; }
    250258    void SetLength(int length) { m_length = length; }
    251259
     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
    252266    ParentalLevel::Level GetShowLevel() const { return m_showlevel; }
    253267    void SetShowLevel(ParentalLevel::Level showLevel)
    254268    {
     
    289303
    290304  private:
    291305    QString m_title;
     306    QString m_subtitle;
    292307    QString m_inetref;
    293308    QString m_director;
    294309    QString m_plot;
     
    310325    int m_childID;
    311326    int m_year;
    312327    int m_length;
     328    int m_season;
     329    int m_episode;
    313330    ParentalLevel::Level m_showlevel;
    314331    bool m_browse;
    315332    unsigned int m_id;  // videometadata.intid
     
    383400{
    384401    MetadataImp tmp(m_filename, VIDEO_TRAILER_DEFAULT, VIDEO_COVERFILE_DEFAULT,
    385402                    VIDEO_SCREENSHOT_DEFAULT, VIDEO_BANNER_DEFAULT,
    386                     VIDEO_FANART_DEFAULT, Metadata::FilenameToTitle(m_filename),
    387                     VIDEO_YEAR_DEFAULT, VIDEO_INETREF_DEFAULT,
    388                     VIDEO_DIRECTOR_DEFAULT, VIDEO_PLOT_DEFAULT, 0.0,
    389                     VIDEO_RATING_DEFAULT, 0, m_id,
     403                    VIDEO_FANART_DEFAULT, Metadata::FilenameToMeta(m_filename, 1),
     404                    Metadata::FilenameToMeta(m_filename, 4), VIDEO_YEAR_DEFAULT,
     405                    VIDEO_INETREF_DEFAULT, VIDEO_DIRECTOR_DEFAULT,
     406                    VIDEO_PLOT_DEFAULT, 0.0,
     407                    VIDEO_RATING_DEFAULT, 0,
     408                    Metadata::FilenameToMeta(m_filename, 2).toInt(),
     409                    Metadata::FilenameToMeta(m_filename, 3).toInt(), m_id,
    390410                    ParentalLevel::plLowest, 0, -1, true, "", "",
    391411                    Metadata::genre_list(), Metadata::country_list(),
    392412                    Metadata::cast_list(), m_host);
     
    484504    m_screenshot = query.value(17).toString();
    485505    m_banner = query.value(18).toString();
    486506    m_fanart = query.value(19).toString();
    487     m_host = query.value(20).toString();
     507    m_subtitle = query.value(20).toString();
     508    m_season = query.value(21).toInt();
     509    m_episode = query.value(22).toInt();
     510    m_host = query.value(23).toString();
    488511
    489512    VideoCategory::GetCategory().get(m_categoryID, m_category);
    490513
     
    501524void MetadataImp::saveToDatabase()
    502525{
    503526    if (m_title.isEmpty())
    504         m_title = Metadata::FilenameToTitle(m_filename);
     527        m_title = Metadata::FilenameToMeta(m_filename, 1);
     528    if (m_subtitle.isEmpty())
     529        m_subtitle = Metadata::FilenameToMeta(m_filename, 4);
    505530    if (m_director.isEmpty())
    506531        m_director = VIDEO_DIRECTOR_UNKNOWN;
    507532    if (m_plot.isEmpty())
    508533        m_plot = VIDEO_PLOT_DEFAULT;
    509534    if (m_rating.isEmpty())
    510535        m_rating = VIDEO_RATING_DEFAULT;
     536    if (m_season == 0)
     537        m_season = Metadata::FilenameToMeta(m_filename, 2).toInt();
     538    if (m_episode == 0)
     539        m_episode = Metadata::FilenameToMeta(m_filename, 3).toInt();
    511540    if (m_coverfile.isEmpty())
    512541        m_coverfile = VIDEO_COVERFILE_DEFAULT;
    513542    if (m_screenshot.isEmpty())
     
    533562    {
    534563        m_browse = gContext->GetNumSetting("VideoNewBrowsable", 1);
    535564
    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)");
     565        query.prepare("INSERT INTO videometadata (title,subtitle,director,plot,"
     566                      "rating,year,userrating,length,season,episode,filename,"
     567                      "showlevel,coverfile,inetref,browse,trailer,screenshot,banner,"
     568                      "fanart,host) VALUES (:TITLE, :SUBTITLE, :DIRECTOR, :PLOT, "
     569                      ":RATING, :YEAR, :USERRATING, :LENGTH, :SEASON, :EPISODE, "
     570                      ":FILENAME, :SHOWLEVEL, :COVERFILE, :INETREF, :BROWSE, "
     571                      ":TRAILER, :SCREENSHOT, :BANNER, :FANART, :HOST)");
    543572    }
    544573    else
    545574    {
    546         query.prepare("UPDATE videometadata SET title = :TITLE, "
     575        query.prepare("UPDATE videometadata SET title = :TITLE, subtitle = :SUBTITLE, "
    547576                      "director = :DIRECTOR, plot = :PLOT, rating= :RATING, "
    548577                      "year = :YEAR, userrating = :USERRATING, "
    549                       "length = :LENGTH, filename = :FILENAME, trailer = :TRAILER, "
     578                      "length = :LENGTH, season = :SEASON, episode = :EPISODE, "
     579                      "filename = :FILENAME, trailer = :TRAILER, "
    550580                      "showlevel = :SHOWLEVEL, coverfile = :COVERFILE, "
    551581                      "screenshot = :SCREENSHOT, banner = :BANNER, fanart = :FANART, "
    552582                      "inetref = :INETREF, browse = :BROWSE, host = :HOST, "
     
    560590    }
    561591
    562592    query.bindValue(":TITLE", m_title);
     593    query.bindValue(":SUBTITLE", m_subtitle);
    563594    query.bindValue(":DIRECTOR", m_director);
    564595    query.bindValue(":PLOT", m_plot);
    565596    query.bindValue(":RATING", m_rating);
    566597    query.bindValue(":YEAR", m_year);
    567598    query.bindValue(":USERRATING", m_userrating);
    568599    query.bindValue(":LENGTH", m_length);
     600    query.bindValue(":SEASON", m_season);
     601    query.bindValue(":EPISODE", m_episode);
    569602    query.bindValue(":FILENAME", m_filename);
    570603    query.bindValue(":TRAILER", m_trailer);
    571604    query.bindValue(":SHOWLEVEL", m_showlevel);
     
    795828    }
    796829}
    797830
    798 QString Metadata::FilenameToTitle(const QString &file_name)
     831QString Metadata::FilenameToMeta(const QString &file_name, int position)
    799832{
     833    // position 1 returns title, 2 returns season,
     834    //          3 returns episode, 4 returns subtitle
     835 
    800836    QString title = file_name.right(file_name.length() -
    801837                                    file_name.lastIndexOf('/') - 1);
     838
    802839    title.replace(QRegExp("_"), " ");
    803840    title.replace(QRegExp("%20"), " ");
     841    title.replace(QRegExp("-"), " ");
    804842    title = title.left(title.lastIndexOf('.'));
    805843    title.replace(QRegExp("\\."), " ");
    806844
     
    808846    title = eatBraces(title, "(", ")");
    809847    title = eatBraces(title, "{", "}");
    810848
    811     return title.trimmed();
     849    QRegExp group("^(.*[^s0-9])" // title
     850                  "(?:[s])?(\\d{1,3})(?:\\s|-)?(?:[ex])" //Season
     851                  "(?:\\s|-)?(\\d{1,3})" // Episode
     852                  "(.*)$", // subtitle
     853                  Qt::CaseInsensitive);
     854    int pos = group.indexIn(title);
     855    if (pos > -1)
     856    {
     857        QString groupResult = group.cap(0);
     858        QString title = group.cap(1);
     859        QString season = group.cap(2);
     860        QString episode = group.cap(3);
     861        QString subtitle = group.cap(4);
     862        if (position == 1 && !title.isEmpty())
     863            return title.trimmed();
     864        else if (position == 2)
     865            return season.trimmed();
     866        else if (position == 3)
     867            return episode.trimmed();
     868        else if (position == 4)
     869            return subtitle.trimmed();
     870    }
     871    else if (position == 1)
     872        return title;
     873    else if (position == 2 || position == 3)
     874        return QString("0");
     875
     876    return QString("");
    812877}
    813878
    814879namespace
     
    829894    return ret;
    830895}
    831896
    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,
     897Metadata::Metadata(const QString &filename, const QString &trailer, 
     898             const QString &coverfile, const QString &screenshot, 
     899             const QString &banner, const QString &fanart, 
     900             const QString &title, const QString &subtitle, int year,
    836901             const QString &inetref, const QString &director,
    837902             const QString &plot, float userrating,
    838903             const QString &rating, int length,
     904             int season, int episode,
    839905             int id, ParentalLevel::Level showlevel, int categoryID,
    840906             int childID, bool browse,
    841907             const QString &playcommand, const QString &category,
     
    845911             const QString &host)
    846912{
    847913    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);
     914                            fanart, title, subtitle, year, inetref, director, plot,
     915                            userrating, rating, length, season, episode, id,
     916                            showlevel, categoryID, childID, browse, playcommand,
     917                            category, genres, countries, cast, host);
    852918}
    853919
    854920Metadata::~Metadata()
     
    911977    m_imp->SetTitle(title);
    912978}
    913979
     980const QString &Metadata::GetSubtitle() const
     981{
     982    return m_imp->getSubtitle();
     983}
     984 
     985void Metadata::SetSubtitle(const QString &subtitle)
     986{
     987    m_imp->SetSubtitle(subtitle);
     988}
     989
    914990int Metadata::GetYear() const
    915991{
    916992    return m_imp->getYear();
     
    9811057    m_imp->SetLength(length);
    9821058}
    9831059
     1060int Metadata::GetSeason() const
     1061{
     1062    return m_imp->GetSeason();
     1063}
     1064
     1065void Metadata::SetSeason(int season)
     1066{
     1067    m_imp->SetSeason(season);
     1068}
     1069
     1070int Metadata::GetEpisode() const
     1071{
     1072    return m_imp->GetEpisode();
     1073}
     1074
     1075void Metadata::SetEpisode(int episode)
     1076{
     1077    m_imp->SetEpisode(episode);
     1078}
     1079
    9841080unsigned int Metadata::GetID() const
    9851081{
    9861082    return m_imp->GetID();
  • mythplugins/mythvideo/mythvideo/globalsettings.cpp

     
    235235    return gc;
    236236}
    237237
     238HostLineEdit *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
     248HostLineEdit *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
     258HostLineEdit *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
     268HostLineEdit *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
     278HostLineEdit *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
    238288HostLineEdit *VideoStartupDirectory()
    239289{
    240290    HostLineEdit *gc = new HostLineEdit("VideoStartupDir");
     
    776826    VConfigPage page7(pages, false);
    777827    page7->addChild(trlr);
    778828
     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
    779842    int page_num = 1;
    780843    for (ConfigPage::PageList::const_iterator p = pages.begin();
    781844         p != pages.end(); ++p, ++page_num)
  • mythplugins/mythvideo/mythvideo/videofilter.h

     
    5454        kOrderByUserRatingDescending = 2,
    5555        kOrderByLength = 3,
    5656        kOrderByFilename = 4,
    57         kOrderByID = 5
     57        kOrderByID = 5,
     58        kOrderBySeasonEp = 6
    5859    };
    5960
    6061    int GetCategory() const { return category; }
  • mythplugins/mythvideo/mythvideo/dbcheck.cpp

     
    3838    const QString lastMythDVDDBVersion = "1002";
    3939    const QString lastMythVideoVersion = "1010";
    4040
    41     const QString currentDatabaseVersion = "1023";
     41    const QString currentDatabaseVersion = "1024";
    4242
    4343    const QString OldMythVideoVersionName = "VideoDBSchemaVer";
    4444    const QString OldMythDVDVersionName = "DVDDBSchemaVer";
     
    834834            performActualUpdate(updates, "1023", dbver, MythVideoVersionName);
    835835        }
    836836
     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        }
    837848
    838849    }
    839850}
  • mythplugins/mythvideo/mythvideo/videoutils.cpp

     
    139139    return QString("%1 minutes").arg(length);
    140140}
    141141
     142QString 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
    142152QString GetDisplayBrowse(bool browse)
    143153{
    144154    return browse ? QObject::tr("Yes") : QObject::tr("No");
  • mythplugins/mythvideo/mythvideo/editmetadata.h

     
    1010class MythUIText;
    1111class MythUITextEdit;
    1212class MythUIButton;
     13class MythUISpinBox;
    1314class MythUICheckBox;
    1415
    1516class EditMetadataDialog : public MythScreenType
     
    3435  public slots:
    3536    void SaveAndExit();
    3637    void SetTitle();
     38    void SetSubtitle();
    3739    void SetCategory(MythUIButtonListItem*);
    3840    void SetPlayer();
     41    void SetSeason();
     42    void SetEpisode();
    3943    void SetLevel(MythUIButtonListItem*);
    4044    void SetChild(MythUIButtonListItem*);
    4145    void ToggleBrowse();
     
    6064    //
    6165
    6266    MythUITextEdit      *m_titleEdit;
     67    MythUITextEdit      *m_subtitleEdit;
    6368    MythUITextEdit      *m_playerEdit;
     69    MythUISpinBox       *m_seasonSpin;
     70    MythUISpinBox       *m_episodeSpin;
    6471    MythUIButtonList      *m_categoryList;
    6572    MythUIButtonList      *m_levelList;
    6673    MythUIButtonList      *m_childList;
  • mythplugins/mythvideo/mythvideo/videodlg.cpp

     
    288288        FanartDownloadErrorState m_error_state;
    289289    };
    290290
     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
    291398    /** \class ExecuteExternalCommand
    292399     *
    293400     * \brief Base class for executing an external script or other process, must
     
    467574        void Run(QString title, Metadata *item)
    468575        {
    469576            m_item = item;
     577            int m_season, m_episode;
     578            QString cmd;
     579            m_season = m_item->GetSeason();
     580            m_episode = m_item->GetEpisode();
    470581
    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")
    472585                    .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())
    473594                    .arg("mythvideo/scripts/tmdb.pl -M"));
    474595
    475             QString cmd = 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");
    480601        }
    481602
    482603      private:
     
    525646        void Run(QString video_uid, Metadata *item)
    526647        {
    527648            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();
    529653
    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")
    531657                    .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())
    532670                    .arg("mythvideo/scripts/tmdb.pl -D"));
    533             const QString cmd = gContext->GetSetting("MovieDataCommandLine",
     671                const QString cmd = gContext->GetSetting("MovieDataCommandLine",
    534672                                                        def_cmd);
    535 
    536             StartRun(cmd, QStringList(video_uid), "Video Data Query");
     673                StartRun(cmd, QStringList(video_uid), "Video Data Query");
     674            }
    537675        }
    538676
    539677      private:
     
    570708        void Run(QString video_uid, Metadata *item)
    571709        {
    572710            m_item = item;
     711            int m_season, m_episode;
     712            m_season = m_item->GetSeason();
     713            m_episode = m_item->GetEpisode();
    573714
    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 =
    575730                    QDir::cleanPath(QString("%1/%2")
    576731                                        .arg(GetShareDir())
    577732                                        .arg("mythvideo/scripts/tmdb.pl -P"));
    578             const QString cmd = gContext->GetSetting("MoviePosterCommandLine",
     733                const QString cmd = gContext->GetSetting("MoviePosterCommandLine",
    579734                                                        default_cmd);
    580             StartRun(cmd, QStringList(video_uid), "Poster Query");
     735
     736                StartRun(cmd, QStringList(video_uid), "Poster Query");
     737            }
    581738        }
    582739
    583740      private:
     
    627784        void Run(QString video_uid, Metadata *item)
    628785        {
    629786            m_item = item;
     787            int m_season, m_episode;
     788            m_season = m_item->GetSeason();
     789            m_episode = m_item->GetEpisode();
    630790
    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 =
    632806                    QDir::cleanPath(QString("%1/%2")
    633807                                        .arg(GetShareDir())
    634808                                        .arg("mythvideo/scripts/tmdb.pl -B"));
    635             const QString cmd = gContext->GetSetting("MovieFanartCommandLine",
     809                const QString cmd = gContext->GetSetting("MovieFanartCommandLine",
    636810                                                        default_cmd);
    637             StartRun(cmd, QStringList(video_uid), "Fanart Query");
     811                StartRun(cmd, QStringList(video_uid), "Fanart Query");
     812            }
    638813        }
    639814
    640815      private:
     
    665840        Metadata *m_item;
    666841    };
    667842
     843    /** \class VideoBannerSearch
     844     *
     845     * \brief Execute external video banner command.
     846     *
     847     */
     848    class VideoBannerSearch : public ExecuteExternalCommand
     849    {
     850        Q_OBJECT
    668851
     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
    669905    class ParentalLevelNotifyContainer : public QObject
    670906    {
    671907        Q_OBJECT
     
    7901026        }
    7911027    };
    7921028
    793     bool GetLocalVideoPoster(const QString &video_uid, const QString &filename,
    794                              const QStringList &in_dirs, QString &poster)
     1029    bool GetLocalVideoImage(const QString &video_uid, const QString &filename,
     1030                             const QStringList &in_dirs, QString &image,
     1031                             QString title, int season)
    7951032    {
    7961033        QStringList search_dirs(in_dirs);
    7971034
     
    8211058                    ext != image_exts.end(); ++ext)
    8221059            {
    8231060                QStringList sfn;
     1061                if (season > 0)
     1062                    sfn += fntm.arg(*dir).arg(QString("%1 Season %2")
     1063                                 .arg(title).arg(QString::number(season)))
     1064                                 .arg(*ext);
    8241065                sfn += fntm.arg(*dir).arg(base_name).arg(*ext);
    8251066                sfn += fntm.arg(*dir).arg(video_uid).arg(*ext);
    8261067
     
    8291070                {
    8301071                    if (QFile::exists(*i))
    8311072                    {
    832                         poster = *i;
     1073                        image = *i;
    8331074                        return true;
    8341075                    }
    8351076                }
     
    10161257
    10171258            tmp["filename"] = metadata->GetFilename();
    10181259            tmp["title"] = metadata->GetTitle();
     1260            tmp["subtitle"] = metadata->GetSubtitle();
    10191261            tmp["director"] = metadata->GetDirector();
    10201262            tmp["plot"] = metadata->GetPlot();
    10211263            tmp["genres"] = GetDisplayGenres(*metadata);
     
    10251267            tmp["length"] = GetDisplayLength(metadata->GetLength());
    10261268            tmp["year"] = GetDisplayYear(metadata->GetYear());
    10271269            tmp["userrating"] = GetDisplayUserRating(metadata->GetUserRating());
     1270            tmp["season"] = GetDisplaySeasonEpisode(metadata->GetSeason(), 1);
     1271            tmp["episode"] = GetDisplaySeasonEpisode(metadata->GetEpisode(), 1);
    10281272
     1273            if (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0)
     1274            {
     1275                tmp["s##e##"] = QString("s%1e%2").arg(GetDisplaySeasonEpisode
     1276                                                     (metadata->GetSeason(), 2))
     1277                                .arg(GetDisplaySeasonEpisode(metadata->GetEpisode(), 2));
     1278                tmp["##x##"] = QString("%1x%2").arg(GetDisplaySeasonEpisode
     1279                                                     (metadata->GetSeason(), 1))           
     1280                                .arg(GetDisplaySeasonEpisode(metadata->GetEpisode(), 2));
     1281            }
     1282            else
     1283                tmp["s##e##"] = tmp["##x##"] = "";
     1284
    10291285            tmp["userratingstate"] =
    10301286                    QString::number((int)(metadata->GetUserRating()));
    10311287            tmp["videolevel"] = ParentalLevelToState(metadata->GetShowLevel());
     
    10751331        h.handleText("player");
    10761332        h.handleText("filename");
    10771333        h.handleText("title");
     1334        h.handleText("subtitle");
    10781335        h.handleText("director");
    10791336        h.handleText("plot");
    10801337        h.handleText("genres");
     
    10821339        h.handleText("cast");
    10831340        h.handleText("rating");
    10841341        h.handleText("length");
     1342        h.handleText("season");
     1343        h.handleText("s##e##");
     1344        h.handleText("##x##");
     1345        h.handleText("episode");
    10851346        h.handleText("year");
    10861347        h.handleText("userrating");
    10871348
     
    12541515
    12551516        m_artDir = gContext->GetSetting("VideoArtworkDir");
    12561517        m_fanDir = gContext->GetSetting("mythvideo.fanartDir");
     1518        m_banDir = gContext->GetSetting("mythvideo.bannerDir");
    12571519    }
    12581520
    12591521    ~VideoDialogPrivate()
     
    13221584        }
    13231585    }
    13241586
     1587    void AddBannerDownload(BannerDownloadProxy *download)
     1588    {
     1589        m_running_bdownloads.insert(download);
     1590    }
     1591
     1592    void RemoveBannerDownload(BannerDownloadProxy *download)
     1593    {
     1594        if (download)
     1595        {
     1596            banner_download_list::iterator p =
     1597                    m_running_bdownloads.find(download);
     1598            if (p != m_running_bdownloads.end())
     1599                m_running_bdownloads.erase(p);
     1600        }
     1601    }
     1602
    13251603    void StopAllRunningCoverDownloads()
    13261604    {
    13271605        cover_download_list tmp(m_running_downloads);
     
    13361614            (*p)->Stop();
    13371615    }
    13381616
     1617    void StopAllRunningBannerDownloads()
     1618    {
     1619        banner_download_list tmp(m_running_bdownloads);
     1620        for (banner_download_list::iterator p = tmp.begin(); p != tmp.end(); ++p)
     1621            (*p)->Stop();
     1622    }
    13391623
    13401624  public:
    13411625    typedef std::set<CoverDownloadProxy *> cover_download_list;
    13421626    cover_download_list m_running_downloads;
    13431627    typedef std::set<FanartDownloadProxy *> fanart_download_list;
    13441628    fanart_download_list m_running_fdownloads;
     1629    typedef std::set<BannerDownloadProxy *> banner_download_list;
     1630    banner_download_list m_running_bdownloads;
    13451631    ParentalLevelNotifyContainer m_parentalLevel;
    13461632    bool m_switchingLayout;
    13471633
     
    13641650
    13651651    QString m_artDir;
    13661652    QString m_fanDir;
     1653    QString m_banDir;
    13671654    VideoScanner *m_scanner;
    13681655
    13691656    QString m_lastTreeNodePath;
     
    27573063        metadata->Reset();
    27583064
    27593065        QString cover_file;
    2760         if (GetLocalVideoPoster(metadata->GetInetRef(), metadata->GetFilename(),
    2761                         QStringList(m_d->m_artDir), cover_file))
     3066        if (GetLocalVideoImage(metadata->GetInetRef(), metadata->GetFilename(),
     3067                        QStringList(m_d->m_artDir), cover_file,
     3068                        metadata->GetTitle(), metadata->GetSeason()))
    27623069        {
    27633070            metadata->SetCoverFile(cover_file);
    27643071        }
    27653072
     3073        QString fanart_file;
     3074        if (GetLocalVideoImage(metadata->GetInetRef(), metadata->GetFilename(),
     3075                        QStringList(m_d->m_fanDir), fanart_file,
     3076                        metadata->GetTitle(), metadata->GetSeason()))
     3077        {
     3078            metadata->SetFanart(fanart_file);
     3079        }
     3080
     3081        QString banner_file;
     3082        if (GetLocalVideoImage(metadata->GetInetRef(), metadata->GetFilename(),
     3083                        QStringList(m_d->m_banDir), banner_file,
     3084                        metadata->GetTitle(), metadata->GetSeason()))
     3085        {
     3086            metadata->SetBanner(banner_file);
     3087        }
     3088
    27663089        metadata->UpdateDatabase();
    27673090
    27683091        UpdateItem(item);
     
    27773100    //createBusyDialog(QObject::tr("Fetching poster for %1 (%2)")
    27783101    //                    .arg(metadata->InetRef())
    27793102    //                    .arg(metadata->Title()));
    2780     QStringList search_dirs;
    2781     search_dirs += m_d->m_artDir;
     3103    QStringList cover_dirs;
     3104    cover_dirs += m_d->m_artDir;
    27823105
    27833106    QString cover_file;
    27843107
    2785     if (GetLocalVideoPoster(metadata->GetInetRef(), metadata->GetFilename(),
    2786                             search_dirs, cover_file))
     3108    if (GetLocalVideoImage(metadata->GetInetRef(), metadata->GetFilename(),
     3109                            cover_dirs, cover_file, metadata->GetTitle(),
     3110                            metadata->GetSeason()))
    27873111    {
    27883112        metadata->SetCoverFile(cover_file);
    27893113        OnVideoPosterSetDone(metadata);
     
    27983122        vps->Run(metadata->GetInetRef(), metadata);
    27993123    }
    28003124
     3125    QStringList fanart_dirs;
     3126    fanart_dirs += m_d->m_fanDir;
     3127
     3128    QString fanart_file;
     3129
     3130    if (GetLocalVideoImage(metadata->GetInetRef(), metadata->GetFilename(),
     3131                            fanart_dirs, fanart_file, metadata->GetTitle(),
     3132                            metadata->GetSeason()))
     3133    {
     3134        metadata->SetFanart(fanart_file);
     3135        OnVideoFanartSetDone(metadata);
     3136    }
     3137
    28013138    if (metadata->GetFanart().isEmpty())
    28023139    {
    28033140        // Obtain video fanart
     
    28063143                SLOT(OnFanartURL(QString, Metadata *)));
    28073144        vfs->Run(metadata->GetInetRef(), metadata);
    28083145    }
     3146
     3147    QStringList banner_dirs;
     3148    banner_dirs += m_d->m_banDir;
     3149       
     3150    QString banner_file;
     3151       
     3152    if (GetLocalVideoImage(metadata->GetInetRef(), metadata->GetFilename(),
     3153                            banner_dirs, banner_file, metadata->GetTitle(),
     3154                            metadata->GetSeason()))
     3155    {
     3156        metadata->SetBanner(banner_file);
     3157        OnVideoBannerSetDone(metadata);
     3158    }
     3159
     3160    if (metadata->GetBanner().isEmpty() &&
     3161       (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0))
     3162    {
     3163        // Obtain video banner (only for TV)
     3164        VideoBannerSearch *vbs = new VideoBannerSearch(this);
     3165        connect(vbs, SIGNAL(SigBannerURL(QString, Metadata *)),
     3166                SLOT(OnBannerURL(QString, Metadata *)));
     3167        vbs->Run(metadata->GetInetRef(), metadata);
     3168    }
    28093169}
    28103170
    28113171void VideoDialog::OnPosterURL(QString uri, Metadata *metadata)
     
    28383198            QUrl url(uri);
    28393199
    28403200            QString ext = QFileInfo(url.path()).suffix();
    2841             QString dest_file = QString("%1/%2.%3").arg(fileprefix)
    2842                     .arg(metadata->GetInetRef()).arg(ext);
     3201            QString dest_file;
     3202
     3203            if (metadata->GetSeason() > 0 ||
     3204                metadata->GetEpisode() > 0)
     3205            {
     3206                // Name TV downloads so that they already work with the PBB
     3207                QString title = QString("%1 Season %2").arg(metadata->GetTitle())
     3208                        .arg(metadata->GetSeason());
     3209                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3210                        .arg(title).arg(ext);
     3211            }
     3212            else
     3213                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3214                        .arg(metadata->GetInetRef()).arg(ext);
     3215
    28433216            VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...")
    28443217                    .arg(url.toString()).arg(dest_file));
    28453218
     
    29323305            QUrl url(uri);
    29333306
    29343307            QString ext = QFileInfo(url.path()).suffix();
    2935             QString dest_file = QString("%1/%2.%3").arg(fileprefix)
    2936                     .arg(metadata->GetInetRef()).arg(ext);
     3308            QString dest_file;
     3309
     3310            if (metadata->GetSeason() > 0 ||
     3311                metadata->GetEpisode() > 0)
     3312            {
     3313                // Name TV downloads so that they already work with the PBB   
     3314                QString title = QString("%1 Season %2").arg(metadata->GetTitle())
     3315                        .arg(metadata->GetSeason());
     3316                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3317                        .arg(title).arg(ext);
     3318            }
     3319            else
     3320                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3321                        .arg(metadata->GetInetRef()).arg(ext);
     3322
    29373323            VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...")
    29383324                    .arg(url.toString()).arg(dest_file));
    29393325
     
    29963382    UpdateItem(GetItemCurrent());
    29973383}
    29983384
     3385void VideoDialog::OnBannerURL(QString uri, Metadata *metadata)
     3386{
     3387    if (metadata)
     3388    {
     3389        if (uri.length())
     3390        {
     3391            QString fileprefix = m_d->m_banDir;
     3392
     3393            QDir dir;
     3394
     3395            // If the fanart setting hasn't been set default to
     3396            // using ~/.mythtv/MythVideo/Banners
     3397            if (fileprefix.length() == 0)
     3398            {
     3399                fileprefix = GetConfDir();
     3400
     3401                dir.setPath(fileprefix);
     3402                if (!dir.exists())
     3403                    dir.mkdir(fileprefix);
     3404
     3405                fileprefix += "/MythVideo/Banners";
     3406            }
     3407
     3408            dir.setPath(fileprefix);
     3409            if (!dir.exists())
     3410                dir.mkdir(fileprefix);
     3411
     3412            QUrl url(uri);
     3413
     3414            QString ext = QFileInfo(url.path()).suffix();
     3415            QString dest_file;
     3416
     3417            if (metadata->GetSeason() > 0 ||
     3418                metadata->GetEpisode() > 0)
     3419            {
     3420                // Name TV downloads so that they already work with the PBB   
     3421                QString title = QString("%1 Season %2").arg(metadata->GetTitle())
     3422                        .arg(metadata->GetSeason());
     3423                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3424                        .arg(title).arg(ext);
     3425            }
     3426            else
     3427                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3428                        .arg(metadata->GetInetRef()).arg(ext);
     3429
     3430            VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...")
     3431                    .arg(url.toString()).arg(dest_file));
     3432
     3433            BannerDownloadProxy *d =
     3434                    BannerDownloadProxy::Create(url, dest_file, metadata);
     3435            metadata->SetBanner(dest_file);
     3436
     3437            connect(d, SIGNAL(SigFinished(BannerDownloadErrorState,
     3438                                          QString, Metadata *)),
     3439                    SLOT(OnBannerCopyFinished(BannerDownloadErrorState,
     3440                                              QString, Metadata *)));
     3441
     3442            d->StartCopy();
     3443            m_d->AddBannerDownload(d);
     3444        }
     3445        else
     3446        {
     3447            metadata->SetBanner("");
     3448            OnVideoBannerSetDone(metadata);
     3449        }
     3450    }
     3451    else
     3452        OnVideoBannerSetDone(metadata);
     3453}
     3454
     3455void VideoDialog::OnBannerCopyFinished(BannerDownloadErrorState error,
     3456                                       QString errorMsg, Metadata *item)
     3457{
     3458    QObject *src = sender();
     3459    if (src)
     3460        m_d->RemoveBannerDownload(dynamic_cast<BannerDownloadProxy *>
     3461                                       (src));
     3462
     3463    if (error != besOK && item)
     3464        item->SetBanner("");
     3465
     3466    VERBOSE(VB_IMPORTANT, tr("Banner download finished: %1 %2")
     3467            .arg(errorMsg).arg(error));
     3468
     3469    if (error == besTimeout)
     3470    {
     3471        createOkDialog(tr("Banner exists for this item but could not be "
     3472                            "retrieved within the timeout period.\n"));
     3473    }
     3474
     3475    OnVideoBannerSetDone(item);
     3476}
     3477
     3478// This is the final call as part of a StartVideoBannerSet
     3479void VideoDialog::OnVideoBannerSetDone(Metadata *metadata)
     3480{
     3481    // The metadata has a banner set
     3482    if (m_busyPopup)
     3483    {
     3484        m_busyPopup->Close();
     3485        m_busyPopup = NULL;
     3486    }
     3487
     3488    metadata->UpdateDatabase();
     3489    UpdateItem(GetItemCurrent());
     3490}
     3491
    29993492void VideoDialog::StartVideoSearchByUID(QString video_uid, Metadata *metadata)
    30003493{
    30013494    // Starting the busy dialog here triggers a bizarre segfault
     
    30283521        }
    30293522        // set known values
    30303523        metadata->SetTitle(data["Title"]);
     3524        metadata->SetSubtitle(data["Subtitle"]);
    30313525        metadata->SetYear(data["Year"].toInt());
    30323526        metadata->SetDirector(data["Director"]);
    30333527        metadata->SetPlot(data["Plot"]);
    30343528        metadata->SetUserRating(data["UserRating"].toFloat());
    30353529        metadata->SetRating(data["MovieRating"]);
    30363530        metadata->SetLength(data["Runtime"].toInt());
     3531        metadata->SetSeason(data["Season"].toInt());
     3532        metadata->SetEpisode(data["Episode"].toInt());
    30373533
    30383534        m_d->AutomaticParentalAdjustment(metadata);
    30393535
  • mythplugins/mythvideo/mythvideo/videolist.cpp

     
    12671267            QString title = qfi.completeBaseName();
    12681268            if (m_infer_title)
    12691269            {
    1270                 QString tmptitle(Metadata::FilenameToTitle(file_string));
     1270                QString tmptitle(Metadata::FilenameToMeta(file_string, 1));
    12711271                if (tmptitle.length())
    12721272                    title = tmptitle;
    12731273            }
  • mythplugins/mythvideo/mythvideo/videoscan.cpp

     
    267267                                 VIDEO_SCREENSHOT_DEFAULT,
    268268                                 VIDEO_BANNER_DEFAULT,
    269269                                 VIDEO_FANART_DEFAULT,
    270                                  Metadata::FilenameToTitle(p->first),
     270                                 Metadata::FilenameToMeta(p->first, 1),
     271                                 Metadata::FilenameToMeta(p->first, 4),
    271272                                 VIDEO_YEAR_DEFAULT,
    272273                                 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::FilenameToMeta(p->first, 2).toInt(),
     276                                 Metadata::FilenameToMeta(p->first, 3).toInt(),
     277                                 0, ParentalLevel::plLowest);
    275278
    276279                VERBOSE(VB_GENERAL, QString("Adding : %1 : %2")
    277280                        .arg(newFile.GetHost()).arg(newFile.GetFilename()));
  • mythplugins/mythvideo/mythvideo/videofilter.cpp

     
    353353            ret = lhs_key < rhs_key;
    354354            break;
    355355        }
     356        case kOrderBySeasonEp:
     357        {
     358            if ((lhs.GetSeason() == rhs.GetSeason())
     359                && (lhs.GetEpisode() == rhs.GetEpisode())
     360                && (lhs.GetSeason() == 0)
     361                && (rhs.GetSeason() == 0)
     362                && (lhs.GetEpisode() == 0)
     363                && (rhs.GetEpisode() == 0))
     364            {
     365                Metadata::SortKey lhs_key;
     366                Metadata::SortKey rhs_key;
     367                if (lhs.HasSortKey() && rhs.HasSortKey())
     368                {
     369                    lhs_key = lhs.GetSortKey();
     370                    rhs_key = rhs.GetSortKey();
     371                }
     372                else
     373                {
     374                    lhs_key = Metadata::GenerateDefaultSortKey(lhs,
     375                                                               sort_ignores_case);
     376                    rhs_key = Metadata::GenerateDefaultSortKey(rhs,
     377                                                               sort_ignores_case);
     378                }
     379                ret = lhs_key < rhs_key;
     380            }
     381            else if (lhs.GetSeason() == rhs.GetSeason()
     382                     && lhs.GetTitle() == rhs.GetTitle())
     383                ret = lhs.GetEpisode() < rhs.GetEpisode();
     384            else
     385                ret = lhs.GetSeason() < rhs.GetSeason();
     386            break;
     387        }
    356388        case kOrderByYearDescending:
    357389        {
    358390            ret = lhs.GetYear() > rhs.GetYear();
     
    649681    // Order by
    650682    new MythUIButtonListItem(m_orderbyList, QObject::tr("Title"),
    651683                           VideoFilterSettings::kOrderByTitle);
     684    new MythUIButtonListItem(m_orderbyList, QObject::tr("Season/Episode"),
     685                           VideoFilterSettings::kOrderBySeasonEp);
    652686    new MythUIButtonListItem(m_orderbyList, QObject::tr("Year"),
    653687                           VideoFilterSettings::kOrderByYearDescending);
    654688    new MythUIButtonListItem(m_orderbyList, QObject::tr("User Rating"),
  • mythplugins/mythvideo/mythvideo/metadata.h

     
    1313
    1414enum { VIDEO_YEAR_DEFAULT = 1895 };
    1515
     16const QString VIDEO_SUBTITLE_DEFAULT = "";
     17
    1618struct SortData;
    1719
    1820class Metadata
     
    4446
    4547  public:
    4648    static SortKey GenerateDefaultSortKey(const Metadata &m, bool ignore_case);
    47     static QString FilenameToTitle(const QString &file_name);
     49    static QString FilenameToMeta(const QString &file_name, int position);
    4850    static QString TrimTitle(const QString &title, bool ignore_case);
    4951
    5052  public:
     
    5557             const QString &banner = QString(),
    5658             const QString &fanart = QString(),
    5759             const QString &title = QString(),
     60             const QString &subtitle = QString(),
    5861             int year = VIDEO_YEAR_DEFAULT,
    5962             const QString &inetref = QString(),
    6063             const QString &director = QString(),
     
    6265             float userrating = 0.0,
    6366             const QString &rating = QString(),
    6467             int length = 0,
     68             int season = 0,
     69             int episode = 0,
    6570             int id = 0,
    6671             ParentalLevel::Level showlevel = ParentalLevel::plLowest,
    6772             int categoryID = 0,
     
    8994    const QString &GetTitle() const;
    9095    void SetTitle(const QString& title);
    9196
     97    const QString &GetSubtitle() const;
     98    void SetSubtitle(const QString &subtitle);
     99
    92100    int GetYear() const;
    93101    void SetYear(int year);
    94102
     
    110118    int GetLength() const;
    111119    void SetLength(int length);
    112120
     121    int GetSeason() const;
     122    void SetSeason(int season);
     123
     124    int GetEpisode() const;
     125    void SetEpisode(int episode);
     126
    113127    unsigned int GetID() const;
    114128    void SetID(int id);
    115129
  • mythplugins/mythvideo/mythvideo/editmetadata.cpp

     
    1212#include <mythtv/libmythui/mythuitextedit.h>
    1313#include <mythtv/libmythui/mythuibutton.h>
    1414#include <mythtv/libmythui/mythuicheckbox.h>
     15#include <mythtv/libmythui/mythuispinbox.h>
    1516
    1617#include "globals.h"
    1718#include "dbaccess.h"
     
    2223EditMetadataDialog::EditMetadataDialog(MythScreenStack *lparent,
    2324        QString lname, Metadata *source_metadata,
    2425        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),
    2830    m_screenshotButton(0), m_screenshotText(0),
    2931    m_bannerButton(0), m_bannerText(0),
    3032    m_fanartButton(0), m_fanartText(0),
     
    4749
    4850    bool err = false;
    4951    UIUtilE::Assign(this, m_titleEdit, "title_edit", &err);
     52    UIUtilE::Assign(this, m_subtitleEdit, "subtitle_edit", &err);
    5053    UIUtilE::Assign(this, m_playerEdit, "player_edit", &err);
    5154
     55    UIUtilE::Assign(this, m_seasonSpin, "season", &err);
     56    UIUtilE::Assign(this, m_episodeSpin, "episode", &err);
     57
    5258    UIUtilE::Assign(this, m_coverartText, "coverart_text", &err);
    5359    UIUtilE::Assign(this, m_screenshotText, "screenshot_text", &err);
    5460    UIUtilE::Assign(this, m_bannerText, "banner_text", &err);
     
    7985        VERBOSE(VB_IMPORTANT, "Failed to build a focuslist.");
    8086
    8187    connect(m_titleEdit, SIGNAL(valueChanged()), SLOT(SetTitle()));
     88    connect(m_subtitleEdit, SIGNAL(valueChanged()), SLOT(SetSubtitle()));
    8289    connect(m_playerEdit, SIGNAL(valueChanged()), SLOT(SetPlayer()));
    8390
     91    connect(m_seasonSpin, SIGNAL(LosingFocus()), SLOT(SetSeason()));
     92    connect(m_episodeSpin, SIGNAL(LosingFocus()), SLOT(SetEpisode()));
     93
    8494    connect(m_doneButton, SIGNAL(Clicked()), SLOT(SaveAndExit()));
    8595    connect(m_coverartButton, SIGNAL(Clicked()), SLOT(FindCoverArt()));
    8696    connect(m_bannerButton, SIGNAL(Clicked()), SLOT(FindBanner()));
     
    154164void EditMetadataDialog::fillWidgets()
    155165{
    156166    m_titleEdit->SetText(m_workingMetadata->GetTitle());
     167    m_subtitleEdit->SetText(m_workingMetadata->GetSubtitle());
    157168
     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
    158174    MythUIButtonListItem *button =
    159175        new MythUIButtonListItem(m_categoryList, VIDEO_CATEGORY_UNKNOWN);
    160176    const VideoCategory::entry_list &vcl =
     
    312328    m_workingMetadata->SetTitle(m_titleEdit->GetText());
    313329}
    314330
     331void EditMetadataDialog::SetSubtitle()
     332{
     333    m_workingMetadata->SetSubtitle(m_subtitleEdit->GetText());
     334}
     335
    315336void EditMetadataDialog::SetCategory(MythUIButtonListItem *item)
    316337{
    317338    m_workingMetadata->SetCategoryID(item->GetData().toInt());
    318339}
    319340
     341void EditMetadataDialog::SetSeason()
     342{
     343    m_workingMetadata->SetSeason(m_seasonSpin->GetIntValue());
     344}
     345
     346void EditMetadataDialog::SetEpisode()
     347{
     348    m_workingMetadata->SetEpisode(m_episodeSpin->GetIntValue());
     349}
     350
    320351void EditMetadataDialog::SetPlayer()
    321352{
    322353    m_workingMetadata->SetPlayCommand(m_playerEdit->GetText());
  • mythplugins/mythvideo/mythvideo/playercommand.cpp

     
    237237            play_command = "Internal";
    238238
    239239        QString plot;
    240         QString title = Metadata::FilenameToTitle(filename);
     240        QString title = Metadata::FilenameToMeta(filename, 1);
    241241        QString director;
    242242        int length = 0;
    243243        QString year = QString::number(VIDEO_YEAR_DEFAULT);
  • mythplugins/mythvideo/mythvideo/videoutils.h

     
    3333
    3434QString GetDisplayUserRating(float userrating);
    3535QString GetDisplayLength(int length);
     36QString GetDisplaySeasonEpisode(int seasEp, int digits);
    3637QString GetDisplayBrowse(bool browse);
    3738QString GetDisplayYear(int year);
    3839QString GetDisplayRating(const QString &rating);
  • mythtv/themes/Terra/video-ui.xml

     
    506506            <value>Video Browser</value>
    507507        </textarea>
    508508
     509        <imagetype name="fanart">
     510            <area>0,0,1280,720</area>
     511            <filename />
     512        </imagetype>
     513
    509514        <imagetype name="browserbackground">
    510515            <position>0,345</position>
    511516            <filename>video/browserlistbackground.png</filename>
     
    565570        </imagetype>
    566571
    567572        <textarea name="title" from="basetextarea">
    568             <area>48,78,980,35</area>
     573            <area>48,78,590,35</area>
    569574            <font>baselarge</font>
    570575        </textarea>
    571576
     577        <textarea name="subtitle" from="basetextarea">
     578            <area>600,78,590,35</area>
     579            <align>right</align>
     580            <font>baselarge</font>
     581        </textarea>
     582
    572583        <statetype name="userratingstate" from="baserating">
    573584            <position>1193,72</position>
    574585        </statetype>
     
    583594            <area>48,284,290,30</area>
    584595        </textarea>
    585596
     597        <textarea name="##x##" from="basetextarea">
     598            <area>540,284,200,30</area>
     599            <align>center</align>
     600        </textarea>
     601
    586602        <textarea name="director" from="basetextarea">
    587603            <area>430,284,800,30</area>
    588604            <align>right</align>
     
    604620            <font>baselarge</font>
    605621        </textarea>
    606622
     623        <imagetype name="fanart">
     624            <area>0,0,1280,720</area>
     625            <filename />
     626        </imagetype>
     627
    607628        <buttonlist name="videos">
    608629            <area>12,0,1260,785</area>
    609630            <layout>grid</layout>
     
    730751            <value>Videos - Tree</value>
    731752        </textarea>
    732753
     754        <imagetype name="fanart">
     755            <area>0,0,1280,720</area>
     756            <filename />
     757        </imagetype>
     758
    733759        <textarea name="breadcrumbs" from="basetextarea">
    734760            <area>50,20,700,40</area>
    735761            <font>basemedium</font>