Ticket #6346: MythVideo.SubSeasEp.32809.diff

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

Various small fixes, theme and UI mostly

  • 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             unsigned int season, unsigned 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
     
    384401    MetadataImp tmp(m_filename, VIDEO_TRAILER_DEFAULT, VIDEO_COVERFILE_DEFAULT,
    385402                    VIDEO_SCREENSHOT_DEFAULT, VIDEO_BANNER_DEFAULT,
    386403                    VIDEO_FANART_DEFAULT, Metadata::FilenameToTitle(m_filename),
    387                     VIDEO_YEAR_DEFAULT, VIDEO_INETREF_DEFAULT,
     404                    VIDEO_SUBTITLE_DEFAULT, VIDEO_YEAR_DEFAULT, VIDEO_INETREF_DEFAULT,
    388405                    VIDEO_DIRECTOR_DEFAULT, VIDEO_PLOT_DEFAULT, 0.0,
    389                     VIDEO_RATING_DEFAULT, 0, m_id,
     406                    VIDEO_RATING_DEFAULT, 0,
     407                    Metadata::FilenameToSeasonEpisode(m_filename, 1),
     408                    Metadata::FilenameToSeasonEpisode(m_filename, 2), m_id,
    390409                    ParentalLevel::plLowest, 0, -1, true, "", "",
    391410                    Metadata::genre_list(), Metadata::country_list(),
    392411                    Metadata::cast_list(), m_host);
     
    484503    m_screenshot = query.value(17).toString();
    485504    m_banner = query.value(18).toString();
    486505    m_fanart = query.value(19).toString();
    487     m_host = query.value(20).toString();
     506    m_subtitle = query.value(20).toString();
     507    m_season = query.value(21).toInt();
     508    m_episode = query.value(22).toInt();
     509    m_host = query.value(23).toString();
    488510
    489511    VideoCategory::GetCategory().get(m_categoryID, m_category);
    490512
     
    502524{
    503525    if (m_title.isEmpty())
    504526        m_title = Metadata::FilenameToTitle(m_filename);
     527    if (m_subtitle.isEmpty())
     528        m_subtitle = VIDEO_SUBTITLE_DEFAULT;
    505529    if (m_director.isEmpty())
    506530        m_director = VIDEO_DIRECTOR_UNKNOWN;
    507531    if (m_plot.isEmpty())
    508532        m_plot = VIDEO_PLOT_DEFAULT;
    509533    if (m_rating.isEmpty())
    510534        m_rating = VIDEO_RATING_DEFAULT;
     535    if (m_season == 0)
     536        m_season = Metadata::FilenameToSeasonEpisode(m_filename, 1);
     537    if (m_episode == 0)
     538        m_episode = Metadata::FilenameToSeasonEpisode(m_filename, 2);
    511539    if (m_coverfile.isEmpty())
    512540        m_coverfile = VIDEO_COVERFILE_DEFAULT;
    513541    if (m_screenshot.isEmpty())
     
    533561    {
    534562        m_browse = gContext->GetNumSetting("VideoNewBrowsable", 1);
    535563
    536         query.prepare("INSERT INTO videometadata (title,director,plot,"
    537                       "rating,year,userrating,length,filename,showlevel,"
    538                       "coverfile,inetref,browse,trailer,screenshot,banner,"
    539                       "fanart,host) VALUES (:TITLE, :DIRECTOR, :PLOT, :RATING, "
    540                       ":YEAR, :USERRATING, :LENGTH, :FILENAME, :SHOWLEVEL, "
    541                       ":COVERFILE, :INETREF, :BROWSE, :TRAILER, :SCREENSHOT, "
    542                       ":BANNER, :FANART, :HOST)");
     564        query.prepare("INSERT INTO videometadata (title,subtitle,director,plot,"
     565                      "rating,year,userrating,length,season,episode,filename,"
     566                      "showlevel,coverfile,inetref,browse,trailer,screenshot,banner,"
     567                      "fanart,host) VALUES (:TITLE, :SUBTITLE, :DIRECTOR, :PLOT, "
     568                      ":RATING, :YEAR, :USERRATING, :LENGTH, :SEASON, :EPISODE, "
     569                      ":FILENAME, :SHOWLEVEL, :COVERFILE, :INETREF, :BROWSE, "
     570                      ":TRAILER, :SCREENSHOT, :BANNER, :FANART, :HOST)");
    543571    }
    544572    else
    545573    {
    546         query.prepare("UPDATE videometadata SET title = :TITLE, "
     574        query.prepare("UPDATE videometadata SET title = :TITLE, subtitle = :SUBTITLE, "
    547575                      "director = :DIRECTOR, plot = :PLOT, rating= :RATING, "
    548576                      "year = :YEAR, userrating = :USERRATING, "
    549                       "length = :LENGTH, filename = :FILENAME, trailer = :TRAILER, "
     577                      "length = :LENGTH, season = :SEASON, episode = :EPISODE, "
     578                      "filename = :FILENAME, trailer = :TRAILER, "
    550579                      "showlevel = :SHOWLEVEL, coverfile = :COVERFILE, "
    551580                      "screenshot = :SCREENSHOT, banner = :BANNER, fanart = :FANART, "
    552581                      "inetref = :INETREF, browse = :BROWSE, host = :HOST, "
     
    560589    }
    561590
    562591    query.bindValue(":TITLE", m_title);
     592    query.bindValue(":SUBTITLE", m_subtitle);
    563593    query.bindValue(":DIRECTOR", m_director);
    564594    query.bindValue(":PLOT", m_plot);
    565595    query.bindValue(":RATING", m_rating);
    566596    query.bindValue(":YEAR", m_year);
    567597    query.bindValue(":USERRATING", m_userrating);
    568598    query.bindValue(":LENGTH", m_length);
     599    query.bindValue(":SEASON", m_season);
     600    query.bindValue(":EPISODE", m_episode);
    569601    query.bindValue(":FILENAME", m_filename);
    570602    query.bindValue(":TRAILER", m_trailer);
    571603    query.bindValue(":SHOWLEVEL", m_showlevel);
     
    811843    return title.trimmed();
    812844}
    813845
     846unsigned int Metadata::FilenameToSeasonEpisode(const QString &file_name,
     847                                    int position)
     848{
     849    // position 1 returns season, 2 returns episode
     850
     851    QString title = file_name.right(file_name.length() -
     852                                    file_name.lastIndexOf('/') - 1);
     853    QRegExp group("(\\d{1,3})(?:\\s|-|_|\\.)?(?:[ex])" //Season
     854                  "(?:\\s|-|_|\\.)?(\\d{1,3})", // Episode
     855                  Qt::CaseInsensitive);
     856    int pos = group.indexIn(title);
     857    if (pos > -1)
     858    {
     859        QString groupResult = group.cap(0);
     860        QString season = group.cap(1);
     861        QString episode = group.cap(2);
     862        if (position == 1)
     863            return season.toInt();
     864        else if (position == 2)
     865            return episode.toInt();
     866    }
     867    return 0;
     868}
     869
    814870namespace
    815871{
    816872    const QRegExp &getTitleTrim(bool ignore_case)
     
    829885    return ret;
    830886}
    831887
    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,
     888Metadata::Metadata(const QString &filename, const QString &trailer, 
     889             const QString &coverfile, const QString &screenshot, 
     890             const QString &banner, const QString &fanart, 
     891             const QString &title, const QString &subtitle, int year,
    836892             const QString &inetref, const QString &director,
    837893             const QString &plot, float userrating,
    838894             const QString &rating, int length,
     895             int season, int episode,
    839896             int id, ParentalLevel::Level showlevel, int categoryID,
    840897             int childID, bool browse,
    841898             const QString &playcommand, const QString &category,
     
    845902             const QString &host)
    846903{
    847904    m_imp = new MetadataImp(filename, trailer, coverfile, screenshot, banner,
    848                             fanart, title, year, inetref, director, plot,
    849                             userrating, rating, length, id, showlevel,
    850                             categoryID, childID, browse, playcommand, category,
    851                             genres, countries, cast, host);
     905                            fanart, title, subtitle, year, inetref, director, plot,
     906                            userrating, rating, length, season, episode, id,
     907                            showlevel, categoryID, childID, browse, playcommand,
     908                            category, genres, countries, cast, host);
    852909}
    853910
    854911Metadata::~Metadata()
     
    911968    m_imp->SetTitle(title);
    912969}
    913970
     971const QString &Metadata::GetSubtitle() const
     972{
     973    return m_imp->getSubtitle();
     974}
     975 
     976void Metadata::SetSubtitle(const QString &subtitle)
     977{
     978    m_imp->SetSubtitle(subtitle);
     979}
     980
    914981int Metadata::GetYear() const
    915982{
    916983    return m_imp->getYear();
     
    9811048    m_imp->SetLength(length);
    9821049}
    9831050
     1051int Metadata::GetSeason() const
     1052{
     1053    return m_imp->GetSeason();
     1054}
     1055
     1056void Metadata::SetSeason(int season)
     1057{
     1058    m_imp->SetSeason(season);
     1059}
     1060
     1061int Metadata::GetEpisode() const
     1062{
     1063    return m_imp->GetEpisode();
     1064}
     1065
     1066void Metadata::SetEpisode(int episode)
     1067{
     1068    m_imp->SetEpisode(episode);
     1069}
     1070
    9841071unsigned int Metadata::GetID() const
    9851072{
    9861073    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
     
    10161252
    10171253            tmp["filename"] = metadata->GetFilename();
    10181254            tmp["title"] = metadata->GetTitle();
     1255            tmp["subtitle"] = metadata->GetSubtitle();
    10191256            tmp["director"] = metadata->GetDirector();
    10201257            tmp["plot"] = metadata->GetPlot();
    10211258            tmp["genres"] = GetDisplayGenres(*metadata);
     
    10251262            tmp["length"] = GetDisplayLength(metadata->GetLength());
    10261263            tmp["year"] = GetDisplayYear(metadata->GetYear());
    10271264            tmp["userrating"] = GetDisplayUserRating(metadata->GetUserRating());
     1265            tmp["season"] = GetDisplaySeasonEpisode(metadata->GetSeason(), 1);
     1266            tmp["episode"] = GetDisplaySeasonEpisode(metadata->GetEpisode(), 1);
    10281267
     1268            if (metadata->GetSeason() > 0 || metadata->GetEpisode() >= 0)
     1269            {
     1270                tmp["s##e##"] = QString("s%1e%2").arg(GetDisplaySeasonEpisode
     1271                                                     (metadata->GetSeason(), 2))
     1272                                .arg(GetDisplaySeasonEpisode(metadata->GetEpisode(), 2));
     1273                tmp["##x##"] = QString("%1x%2").arg(GetDisplaySeasonEpisode
     1274                                                     (metadata->GetSeason(), 1))           
     1275                                .arg(GetDisplaySeasonEpisode(metadata->GetEpisode(), 2));
     1276            }
     1277            else
     1278                tmp["s##e##"] = tmp["##x##"] = "";
     1279
    10291280            tmp["userratingstate"] =
    10301281                    QString::number((int)(metadata->GetUserRating()));
    10311282            tmp["videolevel"] = ParentalLevelToState(metadata->GetShowLevel());
     
    10751326        h.handleText("player");
    10761327        h.handleText("filename");
    10771328        h.handleText("title");
     1329        h.handleText("subtitle");
    10781330        h.handleText("director");
    10791331        h.handleText("plot");
    10801332        h.handleText("genres");
     
    10821334        h.handleText("cast");
    10831335        h.handleText("rating");
    10841336        h.handleText("length");
     1337        h.handleText("season");
     1338        h.handleText("s##e##");
     1339        h.handleText("##x##");
     1340        h.handleText("episode");
    10851341        h.handleText("year");
    10861342        h.handleText("userrating");
    10871343
     
    12541510
    12551511        m_artDir = gContext->GetSetting("VideoArtworkDir");
    12561512        m_fanDir = gContext->GetSetting("mythvideo.fanartDir");
     1513        m_banDir = gContext->GetSetting("mythvideo.bannerDir");
    12571514    }
    12581515
    12591516    ~VideoDialogPrivate()
     
    13221579        }
    13231580    }
    13241581
     1582    void AddBannerDownload(BannerDownloadProxy *download)
     1583    {
     1584        m_running_bdownloads.insert(download);
     1585    }
     1586
     1587    void RemoveBannerDownload(BannerDownloadProxy *download)
     1588    {
     1589        if (download)
     1590        {
     1591            banner_download_list::iterator p =
     1592                    m_running_bdownloads.find(download);
     1593            if (p != m_running_bdownloads.end())
     1594                m_running_bdownloads.erase(p);
     1595        }
     1596    }
     1597
    13251598    void StopAllRunningCoverDownloads()
    13261599    {
    13271600        cover_download_list tmp(m_running_downloads);
     
    13361609            (*p)->Stop();
    13371610    }
    13381611
     1612    void StopAllRunningBannerDownloads()
     1613    {
     1614        banner_download_list tmp(m_running_bdownloads);
     1615        for (banner_download_list::iterator p = tmp.begin(); p != tmp.end(); ++p)
     1616            (*p)->Stop();
     1617    }
    13391618
    13401619  public:
    13411620    typedef std::set<CoverDownloadProxy *> cover_download_list;
    13421621    cover_download_list m_running_downloads;
    13431622    typedef std::set<FanartDownloadProxy *> fanart_download_list;
    13441623    fanart_download_list m_running_fdownloads;
     1624    typedef std::set<BannerDownloadProxy *> banner_download_list;
     1625    banner_download_list m_running_bdownloads;
    13451626    ParentalLevelNotifyContainer m_parentalLevel;
    13461627    bool m_switchingLayout;
    13471628
     
    13641645
    13651646    QString m_artDir;
    13661647    QString m_fanDir;
     1648    QString m_banDir;
    13671649    VideoScanner *m_scanner;
    13681650
    13691651    QString m_lastTreeNodePath;
     
    28063088                SLOT(OnFanartURL(QString, Metadata *)));
    28073089        vfs->Run(metadata->GetInetRef(), metadata);
    28083090    }
     3091
     3092    if (metadata->GetBanner().isEmpty() &&
     3093       (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0))
     3094    {
     3095        // Obtain video banner (only for TV)
     3096        VideoBannerSearch *vbs = new VideoBannerSearch(this);
     3097        connect(vbs, SIGNAL(SigBannerURL(QString, Metadata *)),
     3098                SLOT(OnBannerURL(QString, Metadata *)));
     3099        vbs->Run(metadata->GetInetRef(), metadata);
     3100    }
    28093101}
    28103102
    28113103void VideoDialog::OnPosterURL(QString uri, Metadata *metadata)
     
    28383130            QUrl url(uri);
    28393131
    28403132            QString ext = QFileInfo(url.path()).suffix();
    2841             QString dest_file = QString("%1/%2.%3").arg(fileprefix)
    2842                     .arg(metadata->GetInetRef()).arg(ext);
     3133            QString dest_file;
     3134
     3135            if (metadata->GetSeason() > 0 ||
     3136                metadata->GetEpisode() > 0)
     3137            {
     3138                // Name TV downloads so that they already work with the PBB
     3139                QString title = QString("%1 Season %2").arg(metadata->GetTitle())
     3140                        .arg(metadata->GetSeason());
     3141                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3142                        .arg(title).arg(ext);
     3143            }
     3144            else
     3145                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3146                        .arg(metadata->GetInetRef()).arg(ext);
     3147
    28433148            VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...")
    28443149                    .arg(url.toString()).arg(dest_file));
    28453150
     
    29323237            QUrl url(uri);
    29333238
    29343239            QString ext = QFileInfo(url.path()).suffix();
    2935             QString dest_file = QString("%1/%2.%3").arg(fileprefix)
    2936                     .arg(metadata->GetInetRef()).arg(ext);
     3240            QString dest_file;
     3241
     3242            if (metadata->GetSeason() > 0 ||
     3243                metadata->GetEpisode() > 0)
     3244            {
     3245                // Name TV downloads so that they already work with the PBB   
     3246                QString title = QString("%1 Season %2").arg(metadata->GetTitle())
     3247                        .arg(metadata->GetSeason());
     3248                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3249                        .arg(title).arg(ext);
     3250            }
     3251            else
     3252                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3253                        .arg(metadata->GetInetRef()).arg(ext);
     3254
    29373255            VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...")
    29383256                    .arg(url.toString()).arg(dest_file));
    29393257
     
    29963314    UpdateItem(GetItemCurrent());
    29973315}
    29983316
     3317void VideoDialog::OnBannerURL(QString uri, Metadata *metadata)
     3318{
     3319    if (metadata)
     3320    {
     3321        if (uri.length())
     3322        {
     3323            QString fileprefix = m_d->m_banDir;
     3324
     3325            QDir dir;
     3326
     3327            // If the fanart setting hasn't been set default to
     3328            // using ~/.mythtv/MythVideo/Banners
     3329            if (fileprefix.length() == 0)
     3330            {
     3331                fileprefix = GetConfDir();
     3332
     3333                dir.setPath(fileprefix);
     3334                if (!dir.exists())
     3335                    dir.mkdir(fileprefix);
     3336
     3337                fileprefix += "/MythVideo/Banners";
     3338            }
     3339
     3340            dir.setPath(fileprefix);
     3341            if (!dir.exists())
     3342                dir.mkdir(fileprefix);
     3343
     3344            QUrl url(uri);
     3345
     3346            QString ext = QFileInfo(url.path()).suffix();
     3347            QString dest_file;
     3348
     3349            if (metadata->GetSeason() > 0 ||
     3350                metadata->GetEpisode() > 0)
     3351            {
     3352                // Name TV downloads so that they already work with the PBB   
     3353                QString title = QString("%1 Season %2").arg(metadata->GetTitle())
     3354                        .arg(metadata->GetSeason());
     3355                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3356                        .arg(title).arg(ext);
     3357            }
     3358            else
     3359                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3360                        .arg(metadata->GetInetRef()).arg(ext);
     3361
     3362            VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...")
     3363                    .arg(url.toString()).arg(dest_file));
     3364
     3365            BannerDownloadProxy *d =
     3366                    BannerDownloadProxy::Create(url, dest_file, metadata);
     3367            metadata->SetBanner(dest_file);
     3368
     3369            connect(d, SIGNAL(SigFinished(BannerDownloadErrorState,
     3370                                          QString, Metadata *)),
     3371                    SLOT(OnBannerCopyFinished(BannerDownloadErrorState,
     3372                                              QString, Metadata *)));
     3373
     3374            d->StartCopy();
     3375            m_d->AddBannerDownload(d);
     3376        }
     3377        else
     3378        {
     3379            metadata->SetBanner("");
     3380            OnVideoBannerSetDone(metadata);
     3381        }
     3382    }
     3383    else
     3384        OnVideoBannerSetDone(metadata);
     3385}
     3386
     3387void VideoDialog::OnBannerCopyFinished(BannerDownloadErrorState error,
     3388                                       QString errorMsg, Metadata *item)
     3389{
     3390    QObject *src = sender();
     3391    if (src)
     3392        m_d->RemoveBannerDownload(dynamic_cast<BannerDownloadProxy *>
     3393                                       (src));
     3394
     3395    if (error != besOK && item)
     3396        item->SetBanner("");
     3397
     3398    VERBOSE(VB_IMPORTANT, tr("Banner download finished: %1 %2")
     3399            .arg(errorMsg).arg(error));
     3400
     3401    if (error == besTimeout)
     3402    {
     3403        createOkDialog(tr("Banner exists for this item but could not be "
     3404                            "retrieved within the timeout period.\n"));
     3405    }
     3406
     3407    OnVideoBannerSetDone(item);
     3408}
     3409
     3410// This is the final call as part of a StartVideoBannerSet
     3411void VideoDialog::OnVideoBannerSetDone(Metadata *metadata)
     3412{
     3413    // The metadata has a banner set
     3414    if (m_busyPopup)
     3415    {
     3416        m_busyPopup->Close();
     3417        m_busyPopup = NULL;
     3418    }
     3419
     3420    metadata->UpdateDatabase();
     3421    UpdateItem(GetItemCurrent());
     3422}
     3423
    29993424void VideoDialog::StartVideoSearchByUID(QString video_uid, Metadata *metadata)
    30003425{
    30013426    // Starting the busy dialog here triggers a bizarre segfault
     
    30283453        }
    30293454        // set known values
    30303455        metadata->SetTitle(data["Title"]);
     3456        metadata->SetSubtitle(data["Subtitle"]);
    30313457        metadata->SetYear(data["Year"].toInt());
    30323458        metadata->SetDirector(data["Director"]);
    30333459        metadata->SetPlot(data["Plot"]);
    30343460        metadata->SetUserRating(data["UserRating"].toFloat());
    30353461        metadata->SetRating(data["MovieRating"]);
    30363462        metadata->SetLength(data["Runtime"].toInt());
     3463        metadata->SetSeason(data["Season"].toInt());
     3464        metadata->SetEpisode(data["Episode"].toInt());
    30373465
    30383466        m_d->AutomaticParentalAdjustment(metadata);
    30393467
  • mythplugins/mythvideo/mythvideo/videoscan.cpp

     
    268268                                 VIDEO_BANNER_DEFAULT,
    269269                                 VIDEO_FANART_DEFAULT,
    270270                                 Metadata::FilenameToTitle(p->first),
     271                                 VIDEO_SUBTITLE_DEFAULT,
    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::FilenameToSeasonEpisode(p->first, 1),
     276                                 Metadata::FilenameToSeasonEpisode(p->first, 2),
     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                ret = lhs.GetEpisode() < rhs.GetEpisode();
     360            else
     361                ret = lhs.GetSeason() < rhs.GetSeason();
     362            break;
     363        }
    356364        case kOrderByYearDescending:
    357365        {
    358366            ret = lhs.GetYear() > rhs.GetYear();
     
    649657    // Order by
    650658    new MythUIButtonListItem(m_orderbyList, QObject::tr("Title"),
    651659                           VideoFilterSettings::kOrderByTitle);
     660    new MythUIButtonListItem(m_orderbyList, QObject::tr("Season/Episode"),
     661                           VideoFilterSettings::kOrderBySeasonEp);
    652662    new MythUIButtonListItem(m_orderbyList, QObject::tr("Year"),
    653663                           VideoFilterSettings::kOrderByYearDescending);
    654664    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
     
    4547  public:
    4648    static SortKey GenerateDefaultSortKey(const Metadata &m, bool ignore_case);
    4749    static QString FilenameToTitle(const QString &file_name);
     50    static unsigned int FilenameToSeasonEpisode(const QString &file_name,
     51                            int position);
    4852    static QString TrimTitle(const QString &title, bool ignore_case);
    4953
    5054  public:
     
    5559             const QString &banner = QString(),
    5660             const QString &fanart = QString(),
    5761             const QString &title = QString(),
     62             const QString &subtitle = QString(),
    5863             int year = VIDEO_YEAR_DEFAULT,
    5964             const QString &inetref = QString(),
    6065             const QString &director = QString(),
     
    6267             float userrating = 0.0,
    6368             const QString &rating = QString(),
    6469             int length = 0,
     70             int season = 0,
     71             int episode = 0,
    6572             int id = 0,
    6673             ParentalLevel::Level showlevel = ParentalLevel::plLowest,
    6774             int categoryID = 0,
     
    8996    const QString &GetTitle() const;
    9097    void SetTitle(const QString& title);
    9198
     99    const QString &GetSubtitle() const;
     100    void SetSubtitle(const QString &subtitle);
     101
    92102    int GetYear() const;
    93103    void SetYear(int year);
    94104
     
    110120    int GetLength() const;
    111121    void SetLength(int length);
    112122
     123    int GetSeason() const;
     124    void SetSeason(int season);
     125
     126    int GetEpisode() const;
     127    void SetEpisode(int episode);
     128
    113129    unsigned int GetID() const;
    114130    void SetID(int id);
    115131
  • 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/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

     
    565565        </imagetype>
    566566
    567567        <textarea name="title" from="basetextarea">
    568             <area>48,78,980,35</area>
     568            <area>48,78,590,35</area>
    569569            <font>baselarge</font>
    570570        </textarea>
    571571
     572        <textarea name="subtitle" from="basetextarea">
     573            <area>600,78,590,35</area>
     574            <align>right</align>
     575            <font>baselarge</font>
     576        </textarea>
     577
    572578        <statetype name="userratingstate" from="baserating">
    573579            <position>1193,72</position>
    574580        </statetype>
     
    583589            <area>48,284,290,30</area>
    584590        </textarea>
    585591
     592        <textarea name="##x##" from="basetextarea">
     593            <area>540,284,200,30</area>
     594            <align>center</align>
     595        </textarea>
     596
    586597        <textarea name="director" from="basetextarea">
    587598            <area>430,284,800,30</area>
    588599            <align>right</align>
     
    604615            <font>baselarge</font>
    605616        </textarea>
    606617
     618        <imagetype name="fanart">
     619            <area>0,0,1280,720</area>
     620            <filename />
     621        </imagetype>
     622
    607623        <buttonlist name="videos">
    608624            <area>12,0,1260,785</area>
    609625            <layout>grid</layout>
     
    730746            <value>Videos - Tree</value>
    731747        </textarea>
    732748
     749        <imagetype name="fanart">
     750            <area>0,0,1280,720</area>
     751            <filename />
     752        </imagetype>
     753
    733754        <textarea name="breadcrumbs" from="basetextarea">
    734755            <area>50,20,700,40</area>
    735756            <font>basemedium</font>