Ticket #6346: MythVideo.SubSeasEp.080409.diff

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

Hopefully Final version, fixes an unreachable "else"

  • mythplugins/mythbrowser/mythbrowser/main.cpp

     
    1919
    2020using namespace std;
    2121
    22 int handleMedia(const QString &url, const QString &, const QString &, const QString &, int, const QString &)
     22int handleMedia(const QString &url, const QString &, const QString &, const QString &, const QString &, int, int, int, const QString &)
    2323{
    2424    QStringList urls = url.split(" ", QString::SkipEmptyParts);
    2525    float zoom = gContext->GetSetting("WebBrowserZoomLevel", "1.4").toFloat();
  • mythplugins/mythvideo/theme/default/video-ui.xml

     
    477477        </buttonlist>
    478478
    479479        <textarea name="title" from="basetextarea">
    480             <area>40,20,700,100</area>
     480            <area>40,15,700,100</area>
    481481            <multiline>yes</multiline>
    482482            <font>baseextralarge</font>
    483483        </textarea>
    484484
     485        <textarea name="subtitle" from="basetextarea">
     486            <area>40,45,500,100</area>
     487            <multiline>yes</multiline>
     488            <font>basemedium</font>
     489        </textarea>
     490
     491        <textarea name="##x##" from="basetextarea">
     492            <area>560,45,100,100</area>
     493            <multiline>yes</multiline>
     494            <font>basemedium</font>
     495        </textarea>
     496
    485497        <imagetype name="coverimage">
    486498            <area>30,90,203,311</area>
    487499            <preserveaspect>yes</preserveaspect>
     
    493505        </textarea>
    494506
    495507        <textarea name="dirlbl" from="basetextarea">
    496             <area>240,65,115,35</area>
     508            <area>240,68,115,35</area>
    497509            <value>Directed by</value>
    498510            <align>right</align>
    499511        </textarea>
    500512
    501513        <textarea name="director" from="basetextarea">
    502             <area>360,63,350,35</area>
     514            <area>360,66,350,35</area>
    503515            <font>basemedium</font>
    504516        </textarea>
    505517
     
    586598
    587599    <window name="gallery">
    588600        <textarea name="title" from="basetextarea">
    589             <area>70,20,460,50</area>
     601            <area>70,15,460,50</area>
    590602            <cutdown>yes</cutdown>
    591603            <font>baselarge</font>
    592604        </textarea>
    593605
     606        <textarea name="subtitle" from="basetextarea">
     607            <area>70,40,360,50</area>
     608            <cutdown>yes</cutdown>
     609            <font>basemedium</font>
     610        </textarea>
     611
     612        <textarea name="##x##" from="basetextarea">
     613            <area>440,40,70,50</area>
     614            <cutdown>yes</cutdown>
     615            <font>basemedium</font>
     616        </textarea>
     617
    594618        <buttonlist name="videos">
    595619            <area>15,0,770,585</area>
    596620            <layout>grid</layout>
     
    662686        </buttonlist>
    663687
    664688        <textarea name="position" from="basetextarea">
    665             <area>530,20,110,40</area>
     689            <area>530,15,110,40</area>
    666690            <align>hcenter,vcenter</align>
    667691            <font>basemedium</font>
    668692        </textarea>
     
    728752            <font>baselarge</font>
    729753        </textarea>
    730754
     755        <textarea name="subtitle" from="basetextarea">
     756            <area>50,360,425,30</area>
     757        </textarea>
     758
     759        <textarea name="##x##" from="basetextarea">
     760            <area>500,360,80,30</area>
     761            <align>right</align>
     762        </textarea>
     763
    731764        <textarea name="director" from="basetextarea">
    732             <area>50,367,450,30</area>
     765            <area>50,390,450,30</area>
    733766        </textarea>
    734767
    735768        <textarea name="year" from="basetextarea">
    736             <area>500,367,80,30</area>
     769            <area>500,390,80,30</area>
    737770            <align>right</align>
    738771        </textarea>
    739772
    740773        <textarea name="plot" from="basetextarea">
    741             <area>40,395,530,80</area>
     774            <area>40,418,530,80</area>
    742775            <align>left,top</align>
    743776            <multiline>yes</multiline>
    744777            <cutdown>yes</cutdown>
    745778        </textarea>
    746779
    747780        <textarea name="cast" from="basetextarea">
    748             <area>60,480,505,70</area>
     781            <area>60,503,505,50</area>
    749782            <align>left,top</align>
    750783            <multiline>yes</multiline>
    751784            <cutdown>no</cutdown>
     
    867900        <!-- Labels  -->
    868901
    869902        <textarea name="title_text" from="basetextarea">
    870             <area>50,90,250,40</area>
    871             <value>Name:</value>
     903            <area>50,80,250,40</area>
     904            <value>Title:</value>
    872905            <align>right,top</align>
    873906        </textarea>
    874907
     908        <textarea name="subtitle_text" from="basetextarea">
     909            <area>50,138,250,40</area>
     910            <value>Subtitle:</value>
     911            <align>right,top</align>
     912        </textarea>
     913
     914        <textarea name="season_text" from="basetextarea">
     915            <area>50,185,250,40</area>
     916            <value>Season:</value>
     917            <align>right,top</align>
     918        </textarea>
     919
     920        <textarea name="episode_text" from="basetextarea">
     921            <area>370,185,150,40</area>
     922            <value>Episode:</value>
     923            <align>right,top</align>
     924        </textarea>
     925
    875926        <textarea name="category_text" from="title_text">
    876             <position>50,152</position>
     927            <area>370,232,150,40</area>
     928            <align>right</align>
    877929            <value>Category:</value>
    878930        </textarea>
    879931
    880932        <textarea name="level_text" from="title_text">
    881             <position>50,202</position>
     933            <area>20,232,200,40</area>
     934            <align>right</align>
    882935            <value>Parental Control:</value>
    883936        </textarea>
    884937
    885938        <textarea name="child_text" from="title_text">
    886             <position>50,247</position>
     939            <area>20,277,200,40</area>
     940            <align>right</align>
    887941            <value>File to Always Play Next:</value>
    888942        </textarea>
    889943
    890944        <textarea name="browse_text" from="title_text">
    891             <position>50,292</position>
     945            <area>500,277,200,40</area>
     946            <align>left</align>
    892947            <value>Include while Browsing:</value>
    893948        </textarea>
    894949
     
    925980        <!-- Widgets -->
    926981
    927982        <textedit name="title_edit" from="basetextedit">
    928             <position>310,80</position>
     983            <position>310,70</position>
    929984        </textedit>
    930985
    931         <buttonlist name="category_select" from="baseselector">
    932             <position>310,145</position>
    933         </buttonlist>
     986        <textedit name="subtitle_edit" from="basetextedit">
     987            <position>310,126</position>
     988        </textedit>
    934989
     990        <spinbox name="season" from="basespinbox">
     991            <position>310,181</position>
     992        </spinbox>
     993
     994        <spinbox name="episode" from="basespinbox">
     995            <position>530,181</position>
     996        </spinbox>
     997
    935998        <buttonlist name="level_select" from="baseselector">
    936             <position>310,195</position>
     999            <position>230,225</position>
    9371000        </buttonlist>
    9381001
     1002        <buttonlist name="category_select" from="baseselector">
     1003            <position>530,225</position>
     1004        </buttonlist>
     1005
    9391006        <buttonlist name="child_select" from="baseselector">
    940             <position>310,240</position>
     1007            <position>230,270</position>
    9411008        </buttonlist>
    9421009
    9431010        <checkbox name="browse_check" from="basecheckbox">
    944             <position>310,290</position>
     1011            <position>680,275</position>
    9451012        </checkbox>
    9461013
    9471014        <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
    716         <textarea name="director" from="basetextarea">
    717             <area>50,440,720,30</area>
    718         </textarea>
     739         <textarea name="s##e##" from="basetextarea">
     740             <area>50,380,400,30</area>
     741             <font>basemedium</font>
     742         </textarea>
    719743
    720         <textarea name="year" from="basetextarea">
    721             <area>800,440,80,30</area>
    722             <align>right</align>
    723         </textarea>
     744         <textarea name="subtitle" from="basetextarea">
     745             <area>50,420,400,30</area>
     746             <font>basemedium</font>
     747         </textarea>
    724748
    725         <textarea name="plot" from="basetextarea">
    726             <area>40,474,850,80</area>
    727             <align>left,top</align>
    728             <multiline>yes</multiline>
    729             <cutdown>yes</cutdown>
    730         </textarea>
     749          <textarea name="director" from="basetextarea">
     750             <area>50,467,450,30</area>
     751          </textarea>
     752 
     753          <textarea name="year" from="basetextarea">
     754             <area>500,467,80,30</area>
     755              <align>right</align>
     756          </textarea>
     757 
     758          <textarea name="plot" from="basetextarea">
     759             <area>40,495,530,80</area>
     760              <align>left,top</align>
     761              <multiline>yes</multiline>
     762              <cutdown>yes</cutdown>
     763          </textarea>
     764 
     765          <textarea name="cast" from="basetextarea">
     766             <area>60,580,505,70</area>
     767              <align>left,top</align>
     768              <multiline>yes</multiline>
     769              <cutdown>no</cutdown>
     770          </textarea>
     771 
     772          <textarea name="position" from="basetextarea">
     773             <area>266,655,266,40</area>
     774              <font>basemedium</font>
     775              <align>hcenter,vcenter</align>
     776          </textarea>
    731777
    732         <textarea name="cast" from="basetextarea">
    733             <area>60,576,800,70</area>
    734             <align>left,top</align>
    735             <multiline>yes</multiline>
    736             <cutdown>no</cutdown>
    737         </textarea>
    738 
    739         <textarea name="position" from="basetextarea">
    740             <area>425,666,425,40</area>
    741             <font>basemedium</font>
    742             <align>hcenter,vcenter</align>
    743         </textarea>
    744 
    745778        <imagetype name="coverimage">
    746779            <area>1000,400,225,250</area>
    747780            <preserveaspect>yes</preserveaspect>
     
    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{
     
    5152    bool Create();
    5253    bool keyPressEvent(QKeyEvent *levent);
    5354
     55  private:
     56    void searchStart();
     57
     58  public slots:
     59    void searchComplete(QString string);
     60
    5461  private slots:
    5562    void UpdatePosition();
    5663    void UpdateText(MythUIButtonListItem *);
     
    6875
    6976    void EditMetadata();
    7077    void VideoSearch();
     78    void TitleSubtitleSearch();
     79    void ImageOnlyDownload();
    7180    void ManualVideoUID();
    7281    void ManualVideoTitle();
    7382    void ResetMetadata();
     
    93102
    94103    // Called when the underlying data for an item changes
    95104    void OnVideoSearchListSelection(QString video_uid);
     105    void OnVideoImgSearchListSelection(QString video_uid);
    96106
    97107    void OnManualVideoUID(QString video_uid);
    98108    void OnManualVideoTitle(QString title);
     
    140150    // OnVideoPosterSetDone() stop wait background
    141151    void StartVideoPosterSet(Metadata *metadata);
    142152    void StartVideoFanartSet(Metadata *metadata);
     153    void StartVideoBannerSet(Metadata *metadata);
    143154
    144155    // StartVideoSearchByUID() start wait background
    145156    //   OnVideoSearchByUIDDone() stop wait background
     
    150161    //   OnVideoSearchByTitleDone()
    151162    void StartVideoSearchByTitle(QString video_uid, QString title,
    152163            Metadata *metadata);
     164    void StartVideoSearchByTitleSubtitle(QString title,
     165            QString subtitle, Metadata *metadata);
    153166
    154167  private slots:
    155168    // called during StartVideoPosterSet
     
    159172    void OnFanartURL(QString uri, Metadata *metadata);
    160173    void OnFanartCopyFinished(FanartDownloadErrorState error, QString errorMsg,
    161174                              Metadata *metadata);
     175    void OnBannerURL(QString uri, Metadata *metadata);
     176    void OnBannerCopyFinished(BannerDownloadErrorState error, QString errorMsg,
     177                              Metadata *metadata);
    162178
    163179    // called during StartVideoSearchByTitle
    164180    void OnVideoSearchByTitleDone(bool normal_exit,
    165181                                  const SearchListResults &results,
    166182                                  Metadata *metadata);
     183    void OnVideoSearchByTitleSubtitleDone(bool normal_exit,
     184                                  QStringList result,
     185                                  Metadata *metadata);
     186    void OnVideoImageOnlyDone(bool normal_exit,
     187                                  const SearchListResults &results,
     188                                  Metadata *metadata);
    167189
    168190// and now the end points
    169191
    170192    // StartVideoPosterSet end
    171193    void OnVideoPosterSetDone(Metadata *metadata);
    172194    void OnVideoFanartSetDone(Metadata *metadata);
     195    void OnVideoBannerSetDone(Metadata *metadata);
    173196
    174197    // StartVideoSearchByUID end
    175198    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);
     
    793826    }
    794827}
    795828
    796 QString Metadata::FilenameToTitle(const QString &file_name)
     829QString Metadata::FilenameToMeta(const QString &file_name, int position)
    797830{
     831    // position 1 returns title, 2 returns season,
     832    //          3 returns episode, 4 returns subtitle
     833 
    798834    QString title = file_name.right(file_name.length() -
    799835                                    file_name.lastIndexOf('/') - 1);
     836
    800837    title.replace(QRegExp("_"), " ");
    801838    title.replace(QRegExp("%20"), " ");
     839    title.replace(QRegExp("-"), " ");
    802840    title = title.left(title.lastIndexOf('.'));
    803841    title.replace(QRegExp("\\."), " ");
    804842
    805     title = eatBraces(title, "[", "]");
    806     title = eatBraces(title, "(", ")");
    807     title = eatBraces(title, "{", "}");
     843    QRegExp group("^(.*[^s0-9])" // title
     844                  "(?:[s])?(\\d{1,3})(?:\\s|-)?(?:[ex])" //Season
     845                  "(?:\\s|-)?(\\d{1,3})" // Episode
     846                  "(.*)$", // subtitle
     847                  Qt::CaseInsensitive);
     848    int pos = group.indexIn(title);
     849    if (pos > -1)
     850    {
     851        QString groupResult = group.cap(0);
     852        QString title = group.cap(1);
     853        QString season = group.cap(2);
     854        QString episode = group.cap(3);
     855        QString subtitle = group.cap(4);
     856        if (position == 1 && !title.isEmpty())
     857        {
     858            title = eatBraces(title, "[", "]");
     859            title = eatBraces(title, "(", ")");
     860            title = eatBraces(title, "{", "}");
     861            return title.trimmed();
     862        }
     863        else if (position == 2)
     864            return season.trimmed();
     865        else if (position == 3)
     866            return episode.trimmed();
     867        else if (position == 4)
     868            return subtitle.trimmed();
     869    }
    808870
    809     return title.trimmed();
     871    return QString("");
    810872}
    811873
    812874namespace
     
    827889    return ret;
    828890}
    829891
    830 Metadata::Metadata(const QString &filename, const QString &trailer,
    831              const QString &coverfile, const QString &screenshot,
    832              const QString &banner, const QString &fanart,
    833              const QString &title, int year,
     892Metadata::Metadata(const QString &filename, const QString &trailer, 
     893             const QString &coverfile, const QString &screenshot, 
     894             const QString &banner, const QString &fanart, 
     895             const QString &title, const QString &subtitle, int year,
    834896             const QString &inetref, const QString &director,
    835897             const QString &plot, float userrating,
    836898             const QString &rating, int length,
     899             int season, int episode,
    837900             int id, ParentalLevel::Level showlevel, int categoryID,
    838901             int childID, bool browse,
    839902             const QString &playcommand, const QString &category,
     
    843906             const QString &host)
    844907{
    845908    m_imp = new MetadataImp(filename, trailer, coverfile, screenshot, banner,
    846                             fanart, title, year, inetref, director, plot,
    847                             userrating, rating, length, id, showlevel,
    848                             categoryID, childID, browse, playcommand, category,
    849                             genres, countries, cast, host);
     909                            fanart, title, subtitle, year, inetref, director, plot,
     910                            userrating, rating, length, season, episode, id,
     911                            showlevel, categoryID, childID, browse, playcommand,
     912                            category, genres, countries, cast, host);
    850913}
    851914
    852915Metadata::~Metadata()
     
    909972    m_imp->SetTitle(title);
    910973}
    911974
     975const QString &Metadata::GetSubtitle() const
     976{
     977    return m_imp->getSubtitle();
     978}
     979 
     980void Metadata::SetSubtitle(const QString &subtitle)
     981{
     982    m_imp->SetSubtitle(subtitle);
     983}
     984
    912985int Metadata::GetYear() const
    913986{
    914987    return m_imp->getYear();
     
    9791052    m_imp->SetLength(length);
    9801053}
    9811054
     1055int Metadata::GetSeason() const
     1056{
     1057    return m_imp->GetSeason();
     1058}
     1059
     1060void Metadata::SetSeason(int season)
     1061{
     1062    m_imp->SetSeason(season);
     1063}
     1064
     1065int Metadata::GetEpisode() const
     1066{
     1067    return m_imp->GetEpisode();
     1068}
     1069
     1070void Metadata::SetEpisode(int episode)
     1071{
     1072    m_imp->SetEpisode(episode);
     1073}
     1074
    9821075unsigned int Metadata::GetID() const
    9831076{
    9841077    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
     288HostLineEdit *GetTVTitleSubCommand()
     289{
     290    HostLineEdit *gc = new HostLineEdit("mythvideo.TVTitleSubCommandLine");
     291    gc->setLabel(QObject::tr("Command to search for TV by Title/Subtitle"));
     292    gc->setValue(GetShareDir() + "mythvideo/scripts/ttvdb.py -N");
     293    gc->setHelpText(QObject::tr("This command must be "
     294                    "executable by the user running MythVideo."));
     295    return gc;
     296}
     297
    238298HostLineEdit *VideoStartupDirectory()
    239299{
    240300    HostLineEdit *gc = new HostLineEdit("VideoStartupDir");
     
    780840    VConfigPage page7(pages, false);
    781841    page7->addChild(trlr);
    782842
     843    // page 8
     844    VerticalConfigurationGroup *tvman =
     845            new VerticalConfigurationGroup(true, false);
     846    tvman->setLabel(QObject::tr("Television in MythVideo"));
     847    tvman->addChild(SearchTVListingsCommand());
     848    tvman->addChild(GetTVPostersCommand());
     849    tvman->addChild(GetTVFanartCommand());
     850    tvman->addChild(GetTVBannerCommand());
     851    tvman->addChild(GetTVDataCommand());
     852    tvman->addChild(GetTVTitleSubCommand());
     853
     854    VConfigPage page8(pages, false);
     855    page8->addChild(tvman);
     856
    783857    int page_num = 1;
    784858    for (ConfigPage::PageList::const_iterator p = pages.begin();
    785859         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";
     
    832832            performActualUpdate(updates, "1023", dbver, MythVideoVersionName);
    833833        }
    834834
     835        if (dbver == "1023")
     836        {
     837            QStringList updates;
     838            updates += "ALTER TABLE videometadata ADD `subtitle` TEXT "
     839                       "NOT NULL AFTER `title`;";
     840            updates += "ALTER TABLE videometadata ADD `season` SMALLINT "
     841                       "UNSIGNED NOT NULL DEFAULT '0' AFTER `length`;";
     842            updates += "ALTER TABLE videometadata ADD `episode` SMALLINT "
     843                       "UNSIGNED NOT NULL DEFAULT '0' AFTER `season`;";
     844            performActualUpdate(updates, "1024", dbver, MythVideoVersionName);
     845        }
    835846
    836847    }
    837848}
  • mythplugins/mythvideo/mythvideo/main.cpp

     
    322322        REG_KEY("Video","INCPARENT","Increase Parental Level","],},F11");
    323323        REG_KEY("Video","DECPARENT","Decrease Parental Level","[,{,F10");
    324324
     325        REG_KEY("Video","INCSEARCH","Show Incremental Search Dialog","Ctrl+S");
     326        REG_KEY("Video","DOWNLOADDATA","Download metadata for current item","W");
     327        REG_KEY("Video","ITEMDETAIL","Display Item Detail Popup", "");
     328
    325329        REG_KEY("Video","HOME","Go to the first video","Home");
    326330        REG_KEY("Video","END","Go to the last video","End");
    327331
  • 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:
     
    505626        Metadata *m_item;
    506627    };
    507628
     629    /** \class VideoTitleSubtitleSearch
     630     *
     631     * \brief Executes the external command to do video title/subtitle searches.
     632     *
     633     */
     634    class VideoTitleSubtitleSearch : public ExecuteExternalCommand
     635    {
     636        Q_OBJECT
     637
     638      signals:
     639        void SigSearchResults(bool normal_exit, QStringList result,
     640                Metadata *item);
     641
     642      public:
     643        VideoTitleSubtitleSearch(QObject *oparent) :
     644            ExecuteExternalCommand(oparent), m_item(0) {}
     645
     646        void Run(QString title, QString subtitle, Metadata *item)
     647        {
     648            m_item = item;
     649            QString cmd;
     650
     651                const QString def_cmd = QDir::cleanPath(QString("%1/%2")
     652                    .arg(GetShareDir())
     653                    .arg("mythvideo/scripts/ttvdb.py -N"));
     654                cmd = gContext->GetSetting("mythvideo.TVTitleSubCommandLine",
     655                                                        def_cmd);
     656                QStringList args;
     657                args += title;
     658                args += subtitle;
     659                StartRun(cmd, args, "Video Search");
     660        }
     661
     662      private:
     663        ~VideoTitleSubtitleSearch() {}
     664
     665        void OnExecDone(bool normal_exit, QStringList out, QStringList err)
     666        {
     667            (void) err;
     668
     669            emit SigSearchResults(normal_exit, out, m_item);
     670            deleteLater();
     671        }
     672
     673      private:
     674        Metadata *m_item;
     675    };
     676
    508677    /** \class VideoUIDSearch
    509678     *
    510679     * \brief Execute the command to do video searches based on their ID.
     
    525694        void Run(QString video_uid, Metadata *item)
    526695        {
    527696            m_item = item;
    528             m_video_uid = video_uid;
     697            m_video_uid = video_uid;           
     698            int m_season, m_episode;
     699            m_season = m_item->GetSeason();
     700            m_episode = m_item->GetEpisode();
    529701
    530             const QString def_cmd = QDir::cleanPath(QString("%1/%2")
     702            if (m_season > 0 || m_episode > 0)
     703            {
     704                const QString def_cmd = QDir::cleanPath(QString("%1/%2")
    531705                    .arg(GetShareDir())
     706                    .arg("mythvideo/scripts/ttvdb.py -mD"));
     707                const QString cmd = gContext->GetSetting("mythvideo.TVDataCommandLine",
     708                                                        def_cmd);
     709                QStringList args;
     710                args << video_uid << QString::number(m_season)
     711                                  << QString::number(m_episode);
     712                StartRun(cmd, args, "Video Data Query");
     713            }
     714            else
     715            {
     716                const QString def_cmd = QDir::cleanPath(QString("%1/%2")
     717                    .arg(GetShareDir())
    532718                    .arg("mythvideo/scripts/tmdb.pl -D"));
    533             const QString cmd = gContext->GetSetting("MovieDataCommandLine",
     719                const QString cmd = gContext->GetSetting("MovieDataCommandLine",
    534720                                                        def_cmd);
    535 
    536             StartRun(cmd, QStringList(video_uid), "Video Data Query");
     721                StartRun(cmd, QStringList(video_uid), "Video Data Query");
     722            }
    537723        }
    538724
    539725      private:
     
    570756        void Run(QString video_uid, Metadata *item)
    571757        {
    572758            m_item = item;
     759            int m_season, m_episode;
     760            m_season = m_item->GetSeason();
     761            m_episode = m_item->GetEpisode();
    573762
    574             const QString default_cmd =
     763            if (m_season > 0 || m_episode > 0)
     764            {
     765                const QString def_cmd = QDir::cleanPath(QString("%1/%2")
     766                    .arg(GetShareDir())
     767                    .arg("mythvideo/scripts/ttvdb.py -mP"));
     768                const QString cmd = gContext->GetSetting("mythvideo.TVPosterCommandLine",
     769                                                        def_cmd);
     770                QStringList args;
     771                args << video_uid << QString::number(m_season)
     772                                  << QString::number(m_episode);
     773                StartRun(cmd, args, "Poster Query");
     774            }
     775            else
     776            {
     777                const QString default_cmd =
    575778                    QDir::cleanPath(QString("%1/%2")
    576779                                        .arg(GetShareDir())
    577780                                        .arg("mythvideo/scripts/tmdb.pl -P"));
    578             const QString cmd = gContext->GetSetting("MoviePosterCommandLine",
     781                const QString cmd = gContext->GetSetting("MoviePosterCommandLine",
    579782                                                        default_cmd);
    580             StartRun(cmd, QStringList(video_uid), "Poster Query");
     783
     784                StartRun(cmd, QStringList(video_uid), "Poster Query");
     785            }
    581786        }
    582787
    583788      private:
     
    627832        void Run(QString video_uid, Metadata *item)
    628833        {
    629834            m_item = item;
     835            int m_season, m_episode;
     836            m_season = m_item->GetSeason();
     837            m_episode = m_item->GetEpisode();
    630838
    631             const QString default_cmd =
     839            if (m_season > 0 || m_episode > 0)
     840            {
     841                const QString def_cmd = QDir::cleanPath(QString("%1/%2")
     842                    .arg(GetShareDir())
     843                    .arg("mythvideo/scripts/ttvdb.py -tF"));
     844                const QString cmd = gContext->GetSetting("mythvideo.TVFanartCommandLine",
     845                                                        def_cmd);
     846                QStringList args;
     847                args << video_uid << QString::number(m_season)
     848                                  << QString::number(m_episode);
     849                StartRun(cmd, args, "Fanart Query");
     850            }
     851            else
     852            {
     853                const QString default_cmd =
    632854                    QDir::cleanPath(QString("%1/%2")
    633855                                        .arg(GetShareDir())
    634856                                        .arg("mythvideo/scripts/tmdb.pl -B"));
    635             const QString cmd = gContext->GetSetting("MovieFanartCommandLine",
     857                const QString cmd = gContext->GetSetting("MovieFanartCommandLine",
    636858                                                        default_cmd);
    637             StartRun(cmd, QStringList(video_uid), "Fanart Query");
     859                StartRun(cmd, QStringList(video_uid), "Fanart Query");
     860            }
    638861        }
    639862
    640863      private:
     
    665888        Metadata *m_item;
    666889    };
    667890
     891    /** \class VideoBannerSearch
     892     *
     893     * \brief Execute external video banner command.
     894     *
     895     */
     896    class VideoBannerSearch : public ExecuteExternalCommand
     897    {
     898        Q_OBJECT
    668899
     900      signals:
     901        void SigBannerURL(QString url, Metadata *item);
     902
     903      public:
     904        VideoBannerSearch(QObject *oparent) :
     905            ExecuteExternalCommand(oparent), m_item(0) {}
     906
     907        void Run(QString video_uid, Metadata *item)
     908        {
     909            m_item = item;
     910            int m_season, m_episode;
     911            m_season = m_item->GetSeason();
     912            m_episode = m_item->GetEpisode();
     913
     914            const QString def_cmd = QDir::cleanPath(QString("%1/%2")
     915                    .arg(GetShareDir())
     916                    .arg("mythvideo/scripts/ttvdb.py -tB"));
     917            const QString cmd = gContext->GetSetting("mythvideo.TVBannerCommandLine",
     918                                                        def_cmd);
     919            QStringList args;
     920            args << video_uid << QString::number(m_season)
     921                                  << QString::number(m_episode);
     922            StartRun(cmd, args, "Banner Query");
     923        }
     924
     925      private:
     926        ~VideoBannerSearch() {}
     927
     928        void OnExecDone(bool normal_exit, QStringList out, QStringList err)
     929        {
     930            (void) err;
     931            QString url;
     932            if (normal_exit && out.size())
     933            {
     934                for (QStringList::const_iterator p = out.begin();
     935                        p != out.end(); ++p)
     936                {
     937                    if ((*p).length())
     938                    {
     939                        url = *p;
     940                        break;
     941                    }
     942                }
     943            }
     944
     945            emit SigBannerURL(url, m_item);
     946            deleteLater();
     947        }
     948
     949      private:
     950        Metadata *m_item;
     951    };
     952
    669953    class ParentalLevelNotifyContainer : public QObject
    670954    {
    671955        Q_OBJECT
     
    7901074        }
    7911075    };
    7921076
    793     bool GetLocalVideoPoster(const QString &video_uid, const QString &filename,
    794                              const QStringList &in_dirs, QString &poster)
     1077    bool GetLocalVideoImage(const QString &video_uid, const QString &filename,
     1078                             const QStringList &in_dirs, QString &image,
     1079                             QString title, int season)
    7951080    {
    7961081        QStringList search_dirs(in_dirs);
    7971082
     
    8211106                    ext != image_exts.end(); ++ext)
    8221107            {
    8231108                QStringList sfn;
     1109                if (season > 0)
     1110                    sfn += fntm.arg(*dir).arg(QString("%1 Season %2")
     1111                                 .arg(title).arg(QString::number(season)))
     1112                                 .arg(*ext);
    8241113                sfn += fntm.arg(*dir).arg(base_name).arg(*ext);
    8251114                sfn += fntm.arg(*dir).arg(video_uid).arg(*ext);
    8261115
     
    8291118                {
    8301119                    if (QFile::exists(*i))
    8311120                    {
    832                         poster = *i;
     1121                        image = *i;
    8331122                        return true;
    8341123                    }
    8351124                }
     
    9461235            QString coverfile;
    9471236            if ((metadata->IsHostSet()
    9481237                && !metadata->GetCoverFile().startsWith("/"))
    949                 && (metadata->GetCoverFile() != "No Cover"))
     1238                && (metadata->GetCoverFile() != "No Cover")
     1239                && !metadata->GetCoverFile().isEmpty())
    9501240            {
    9511241                coverfile = GenRemoteFileURL("Coverart", metadata->GetHost(),
    9521242                        metadata->GetCoverFile());
     
    9621252            tmp["coverfile"] = coverfile;
    9631253
    9641254            QString screenshotfile;
    965             if (metadata->IsHostSet() &&
    966                     !metadata->GetScreenshot().startsWith("/"))
     1255            if (metadata->IsHostSet() && !metadata->GetScreenshot().startsWith("/")
     1256                && !metadata->GetScreenshot().isEmpty())
    9671257            {
    9681258                screenshotfile = GenRemoteFileURL("Screenshots",
    9691259                        metadata->GetHost(), metadata->GetScreenshot());
     
    9791269            tmp["screenshotfile"] = screenshotfile;
    9801270
    9811271            QString bannerfile;
    982             if (metadata->IsHostSet() && !metadata->GetBanner().startsWith("/"))
     1272            if (metadata->IsHostSet() && !metadata->GetBanner().startsWith("/")
     1273                && !metadata->GetBanner().isEmpty())
    9831274            {
    9841275                bannerfile = GenRemoteFileURL("Banners", metadata->GetHost(),
    9851276                        metadata->GetBanner());
     
    9951286            tmp["bannerfile"] = bannerfile;
    9961287
    9971288            QString fanartfile;
    998             if (metadata->IsHostSet() && !metadata->GetFanart().startsWith("/"))
     1289            if (metadata->IsHostSet() && !metadata->GetFanart().startsWith("/")
     1290                && !metadata->GetFanart().isEmpty())
    9991291            {
    10001292                fanartfile = GenRemoteFileURL("Fanart", metadata->GetHost(),
    10011293                        metadata->GetFanart());
     
    10161308
    10171309            tmp["filename"] = metadata->GetFilename();
    10181310            tmp["title"] = metadata->GetTitle();
     1311            tmp["subtitle"] = metadata->GetSubtitle();
    10191312            tmp["director"] = metadata->GetDirector();
    10201313            tmp["plot"] = metadata->GetPlot();
    10211314            tmp["genres"] = GetDisplayGenres(*metadata);
     
    10251318            tmp["length"] = GetDisplayLength(metadata->GetLength());
    10261319            tmp["year"] = GetDisplayYear(metadata->GetYear());
    10271320            tmp["userrating"] = GetDisplayUserRating(metadata->GetUserRating());
     1321            tmp["season"] = GetDisplaySeasonEpisode(metadata->GetSeason(), 1);
     1322            tmp["episode"] = GetDisplaySeasonEpisode(metadata->GetEpisode(), 1);
    10281323
     1324            if (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0)
     1325            {
     1326                tmp["s##e##"] = QString("s%1e%2").arg(GetDisplaySeasonEpisode
     1327                                                     (metadata->GetSeason(), 2))
     1328                                .arg(GetDisplaySeasonEpisode(metadata->GetEpisode(), 2));
     1329                tmp["##x##"] = QString("%1x%2").arg(GetDisplaySeasonEpisode
     1330                                                     (metadata->GetSeason(), 1))           
     1331                                .arg(GetDisplaySeasonEpisode(metadata->GetEpisode(), 2));
     1332            }
     1333            else
     1334                tmp["s##e##"] = tmp["##x##"] = "";
     1335
    10291336            tmp["userratingstate"] =
    10301337                    QString::number((int)(metadata->GetUserRating()));
    10311338            tmp["videolevel"] = ParentalLevelToState(metadata->GetShowLevel());
     
    10751382        h.handleText("player");
    10761383        h.handleText("filename");
    10771384        h.handleText("title");
     1385        h.handleText("subtitle");
    10781386        h.handleText("director");
    10791387        h.handleText("plot");
    10801388        h.handleText("genres");
     
    10821390        h.handleText("cast");
    10831391        h.handleText("rating");
    10841392        h.handleText("length");
     1393        h.handleText("season");
     1394        h.handleText("s##e##");
     1395        h.handleText("##x##");
     1396        h.handleText("episode");
    10851397        h.handleText("year");
    10861398        h.handleText("userrating");
    10871399
     
    12541566
    12551567        m_artDir = gContext->GetSetting("VideoArtworkDir");
    12561568        m_fanDir = gContext->GetSetting("mythvideo.fanartDir");
     1569        m_banDir = gContext->GetSetting("mythvideo.bannerDir");
    12571570    }
    12581571
    12591572    ~VideoDialogPrivate()
     
    13221635        }
    13231636    }
    13241637
     1638    void AddBannerDownload(BannerDownloadProxy *download)
     1639    {
     1640        m_running_bdownloads.insert(download);
     1641    }
     1642
     1643    void RemoveBannerDownload(BannerDownloadProxy *download)
     1644    {
     1645        if (download)
     1646        {
     1647            banner_download_list::iterator p =
     1648                    m_running_bdownloads.find(download);
     1649            if (p != m_running_bdownloads.end())
     1650                m_running_bdownloads.erase(p);
     1651        }
     1652    }
     1653
    13251654    void StopAllRunningCoverDownloads()
    13261655    {
    13271656        cover_download_list tmp(m_running_downloads);
     
    13361665            (*p)->Stop();
    13371666    }
    13381667
     1668    void StopAllRunningBannerDownloads()
     1669    {
     1670        banner_download_list tmp(m_running_bdownloads);
     1671        for (banner_download_list::iterator p = tmp.begin(); p != tmp.end(); ++p)
     1672            (*p)->Stop();
     1673    }
    13391674
    13401675  public:
    13411676    typedef std::set<CoverDownloadProxy *> cover_download_list;
    13421677    cover_download_list m_running_downloads;
    13431678    typedef std::set<FanartDownloadProxy *> fanart_download_list;
    13441679    fanart_download_list m_running_fdownloads;
     1680    typedef std::set<BannerDownloadProxy *> banner_download_list;
     1681    banner_download_list m_running_bdownloads;
    13451682    ParentalLevelNotifyContainer m_parentalLevel;
    13461683    bool m_switchingLayout;
    13471684
     
    13641701
    13651702    QString m_artDir;
    13661703    QString m_fanDir;
     1704    QString m_banDir;
    13671705    VideoScanner *m_scanner;
    13681706
    13691707    QString m_lastTreeNodePath;
     
    20212359            if (!m_menuPopup)
    20222360                VideoMenu();
    20232361        }
     2362        else if (action == "DOWNLOADDATA")
     2363        {
     2364            if (!m_menuPopup && GetMetadata(GetItemCurrent()))
     2365                VideoSearch();
     2366        }
     2367        else if (action == "INCSEARCH")
     2368            searchStart();
     2369        else if (action == "ITEMDETAIL")
     2370            DoItemDetailShow();
    20242371        else if (action == "ESCAPE")
    20252372        {
    20262373            if (m_d->m_type != DLG_TREE
     
    20802427        m_popupStack->AddScreen(okPopup);
    20812428}
    20822429
     2430void VideoDialog::searchComplete(QString string)
     2431{
     2432    VERBOSE(VB_GENERAL | VB_EXTRA,
     2433            QString("Switching to: %1").arg(string));
     2434
     2435    if (m_d->m_type == DLG_TREE)
     2436    {
     2437        MythGenericTree *parent = m_videoButtonTree->GetCurrentNode()->getParent();
     2438        MythGenericTree *new_node = parent->getChildByName(string);
     2439        if (new_node)
     2440        {
     2441            m_videoButtonTree->SetCurrentNode(new_node);
     2442            m_videoButtonTree->SetActive(true);
     2443        }
     2444    }
     2445    else
     2446    {
     2447        m_videoButtonList->MoveToNamedPosition(string);
     2448        m_videoButtonList->SetActive(true);
     2449    }
     2450}
     2451
     2452void VideoDialog::searchStart(void)
     2453{
     2454    MythGenericTree *parent = m_d->m_currentNode->getParent();
     2455
     2456    QStringList childList;
     2457    QList<MythGenericTree*>::iterator it;
     2458    QList<MythGenericTree*> *children;
     2459    if (parent && m_d->m_type == DLG_TREE)
     2460        children = parent->getAllChildren();
     2461    else
     2462        children = m_d->m_currentNode->getAllChildren();
     2463
     2464    for (it = children->begin(); it != children->end(); ++it)
     2465    {
     2466        MythGenericTree *child = *it;
     2467        childList << child->getString();
     2468    }
     2469
     2470    MythScreenStack *popupStack =
     2471        GetMythMainWindow()->GetStack("popup stack");
     2472    MythUISearchDialog *searchDialog = new MythUISearchDialog(popupStack,
     2473        tr("Video Search"), childList, false, "");
     2474
     2475    if (searchDialog->Create())
     2476    {
     2477        connect(searchDialog, SIGNAL(haveResult(QString)),
     2478                SLOT(searchComplete(QString)));
     2479
     2480        popupStack->AddScreen(searchDialog);
     2481    }
     2482    else
     2483        delete searchDialog;
     2484}
     2485
    20832486bool VideoDialog::goBack()
    20842487{
    20852488    bool handled = false;
     
    22752678
    22762679    m_menuPopup->AddButton(tr("Edit Metadata"), SLOT(EditMetadata()));
    22772680    m_menuPopup->AddButton(tr("Download Metadata"), SLOT(VideoSearch()));
     2681    m_menuPopup->AddButton(tr("Download Images Only"),
     2682                          SLOT(ImageOnlyDownload()));
     2683    m_menuPopup->AddButton(tr("Search TV by Title/Subtitle"),
     2684                          SLOT(TitleSubtitleSearch()));
    22782685    m_menuPopup->AddButton(tr("Manually Enter Video #"),
    22792686            SLOT(ManualVideoUID()));
    22802687    m_menuPopup->AddButton(tr("Manually Enter Video Title"),
     
    25822989                                metadata);
    25832990}
    25842991
     2992void VideoDialog::TitleSubtitleSearch()
     2993{
     2994    Metadata *metadata = GetMetadata(GetItemCurrent());
     2995
     2996    if (metadata)
     2997        StartVideoSearchByTitleSubtitle(metadata->GetTitle(),
     2998                                metadata->GetSubtitle(), metadata);
     2999}
     3000
     3001void VideoDialog::ImageOnlyDownload()
     3002{
     3003    Metadata *metadata = GetMetadata(GetItemCurrent());
     3004    QString title = metadata->GetTitle();
     3005
     3006    if (metadata->GetInetRef() != VIDEO_INETREF_DEFAULT)
     3007        StartVideoPosterSet(metadata);
     3008    else
     3009    {
     3010        createBusyDialog(title);
     3011
     3012        VideoTitleSearch *vts = new VideoTitleSearch(this);
     3013        connect(vts, SIGNAL(SigSearchResults(bool, const SearchListResults &,
     3014                                Metadata *)),
     3015                SLOT(OnVideoImageOnlyDone(bool, const SearchListResults &,
     3016                                Metadata *)));
     3017        vts->Run(title, metadata);
     3018    }
     3019}
     3020
    25853021void VideoDialog::ToggleBrowseable()
    25863022{
    25873023    Metadata *metadata = GetMetadata(GetItemCurrent());
     
    26253061    }
    26263062}
    26273063
     3064void VideoDialog::OnVideoImgSearchListSelection(QString video_uid)
     3065{
     3066    Metadata *metadata = GetMetadata(GetItemCurrent());
     3067    if (metadata && !video_uid.isEmpty())
     3068    {
     3069        metadata->SetInetRef(video_uid);
     3070        metadata->UpdateDatabase();
     3071        UpdateItem(GetItemCurrent());
     3072        StartVideoPosterSet(metadata);
     3073    }
     3074}
     3075
    26283076void VideoDialog::OnParentalChange(int amount)
    26293077{
    26303078    Metadata *metadata = GetMetadata(GetItemCurrent());
     
    27583206        metadata->Reset();
    27593207
    27603208        QString cover_file;
    2761         if (GetLocalVideoPoster(metadata->GetInetRef(), metadata->GetFilename(),
    2762                         QStringList(m_d->m_artDir), cover_file))
     3209        if (GetLocalVideoImage(metadata->GetInetRef(), metadata->GetFilename(),
     3210                        QStringList(m_d->m_artDir), cover_file,
     3211                        metadata->GetTitle(), metadata->GetSeason()))
    27633212        {
    27643213            metadata->SetCoverFile(cover_file);
    27653214        }
    27663215
     3216        QString fanart_file;
     3217        if (GetLocalVideoImage(metadata->GetInetRef(), metadata->GetFilename(),
     3218                        QStringList(m_d->m_fanDir), fanart_file,
     3219                        metadata->GetTitle(), metadata->GetSeason()))
     3220        {
     3221            metadata->SetFanart(fanart_file);
     3222        }
     3223
     3224        QString banner_file;
     3225        if (GetLocalVideoImage(metadata->GetInetRef(), metadata->GetFilename(),
     3226                        QStringList(m_d->m_banDir), banner_file,
     3227                        metadata->GetTitle(), metadata->GetSeason()))
     3228        {
     3229            metadata->SetBanner(banner_file);
     3230        }
     3231
    27673232        metadata->UpdateDatabase();
    27683233
    27693234        UpdateItem(item);
     
    27783243    //createBusyDialog(QObject::tr("Fetching poster for %1 (%2)")
    27793244    //                    .arg(metadata->InetRef())
    27803245    //                    .arg(metadata->Title()));
    2781     QStringList search_dirs;
    2782     search_dirs += m_d->m_artDir;
     3246    QStringList cover_dirs;
     3247    cover_dirs += m_d->m_artDir;
    27833248
    27843249    QString cover_file;
    27853250
    2786     if (GetLocalVideoPoster(metadata->GetInetRef(), metadata->GetFilename(),
    2787                             search_dirs, cover_file))
     3251    if (GetLocalVideoImage(metadata->GetInetRef(), metadata->GetFilename(),
     3252                            cover_dirs, cover_file, metadata->GetTitle(),
     3253                            metadata->GetSeason()))
    27883254    {
    27893255        metadata->SetCoverFile(cover_file);
    27903256        OnVideoPosterSetDone(metadata);
     
    27993265        vps->Run(metadata->GetInetRef(), metadata);
    28003266    }
    28013267
     3268    QStringList fanart_dirs;
     3269    fanart_dirs += m_d->m_fanDir;
     3270
     3271    QString fanart_file;
     3272
     3273    if (GetLocalVideoImage(metadata->GetInetRef(), metadata->GetFilename(),
     3274                            fanart_dirs, fanart_file, metadata->GetTitle(),
     3275                            metadata->GetSeason()))
     3276    {
     3277        metadata->SetFanart(fanart_file);
     3278        OnVideoFanartSetDone(metadata);
     3279    }
     3280
    28023281    if (metadata->GetFanart().isEmpty())
    28033282    {
    28043283        // Obtain video fanart
     
    28073286                SLOT(OnFanartURL(QString, Metadata *)));
    28083287        vfs->Run(metadata->GetInetRef(), metadata);
    28093288    }
     3289
     3290    QStringList banner_dirs;
     3291    banner_dirs += m_d->m_banDir;
     3292       
     3293    QString banner_file;
     3294       
     3295    if (GetLocalVideoImage(metadata->GetInetRef(), metadata->GetFilename(),
     3296                            banner_dirs, banner_file, metadata->GetTitle(),
     3297                            metadata->GetSeason()))
     3298    {
     3299        metadata->SetBanner(banner_file);
     3300        OnVideoBannerSetDone(metadata);
     3301    }
     3302
     3303    if (metadata->GetBanner().isEmpty() &&
     3304       (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0))
     3305    {
     3306        // Obtain video banner (only for TV)
     3307        VideoBannerSearch *vbs = new VideoBannerSearch(this);
     3308        connect(vbs, SIGNAL(SigBannerURL(QString, Metadata *)),
     3309                SLOT(OnBannerURL(QString, Metadata *)));
     3310        vbs->Run(metadata->GetInetRef(), metadata);
     3311    }
    28103312}
    28113313
    28123314void VideoDialog::OnPosterURL(QString uri, Metadata *metadata)
     
    28393341            QUrl url(uri);
    28403342
    28413343            QString ext = QFileInfo(url.path()).suffix();
    2842             QString dest_file = QString("%1/%2.%3").arg(fileprefix)
    2843                     .arg(metadata->GetInetRef()).arg(ext);
     3344            QString dest_file;
     3345
     3346            if (metadata->GetSeason() > 0 ||
     3347                metadata->GetEpisode() > 0)
     3348            {
     3349                // Name TV downloads so that they already work with the PBB
     3350                QString title = QString("%1 Season %2").arg(metadata->GetTitle())
     3351                        .arg(metadata->GetSeason());
     3352                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3353                        .arg(title).arg(ext);
     3354            }
     3355            else
     3356                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3357                        .arg(metadata->GetInetRef()).arg(ext);
     3358
    28443359            VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...")
    28453360                    .arg(url.toString()).arg(dest_file));
    28463361
     
    29333448            QUrl url(uri);
    29343449
    29353450            QString ext = QFileInfo(url.path()).suffix();
    2936             QString dest_file = QString("%1/%2.%3").arg(fileprefix)
    2937                     .arg(metadata->GetInetRef()).arg(ext);
     3451            QString dest_file;
     3452
     3453            if (metadata->GetSeason() > 0 ||
     3454                metadata->GetEpisode() > 0)
     3455            {
     3456                // Name TV downloads so that they already work with the PBB   
     3457                QString title = QString("%1 Season %2").arg(metadata->GetTitle())
     3458                        .arg(metadata->GetSeason());
     3459                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3460                        .arg(title).arg(ext);
     3461            }
     3462            else
     3463                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3464                        .arg(metadata->GetInetRef()).arg(ext);
     3465
    29383466            VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...")
    29393467                    .arg(url.toString()).arg(dest_file));
    29403468
     
    29973525    UpdateItem(GetItemCurrent());
    29983526}
    29993527
     3528void VideoDialog::OnBannerURL(QString uri, Metadata *metadata)
     3529{
     3530    if (metadata)
     3531    {
     3532        if (uri.length())
     3533        {
     3534            QString fileprefix = m_d->m_banDir;
     3535
     3536            QDir dir;
     3537
     3538            // If the fanart setting hasn't been set default to
     3539            // using ~/.mythtv/MythVideo/Banners
     3540            if (fileprefix.length() == 0)
     3541            {
     3542                fileprefix = GetConfDir();
     3543
     3544                dir.setPath(fileprefix);
     3545                if (!dir.exists())
     3546                    dir.mkdir(fileprefix);
     3547
     3548                fileprefix += "/MythVideo/Banners";
     3549            }
     3550
     3551            dir.setPath(fileprefix);
     3552            if (!dir.exists())
     3553                dir.mkdir(fileprefix);
     3554
     3555            QUrl url(uri);
     3556
     3557            QString ext = QFileInfo(url.path()).suffix();
     3558            QString dest_file;
     3559
     3560            if (metadata->GetSeason() > 0 ||
     3561                metadata->GetEpisode() > 0)
     3562            {
     3563                // Name TV downloads so that they already work with the PBB   
     3564                QString title = QString("%1 Season %2").arg(metadata->GetTitle())
     3565                        .arg(metadata->GetSeason());
     3566                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3567                        .arg(title).arg(ext);
     3568            }
     3569            else
     3570                dest_file = QString("%1/%2.%3").arg(fileprefix)
     3571                        .arg(metadata->GetInetRef()).arg(ext);
     3572
     3573            VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...")
     3574                    .arg(url.toString()).arg(dest_file));
     3575
     3576            BannerDownloadProxy *d =
     3577                    BannerDownloadProxy::Create(url, dest_file, metadata);
     3578            metadata->SetBanner(dest_file);
     3579
     3580            connect(d, SIGNAL(SigFinished(BannerDownloadErrorState,
     3581                                          QString, Metadata *)),
     3582                    SLOT(OnBannerCopyFinished(BannerDownloadErrorState,
     3583                                              QString, Metadata *)));
     3584
     3585            d->StartCopy();
     3586            m_d->AddBannerDownload(d);
     3587        }
     3588        else
     3589        {
     3590            metadata->SetBanner("");
     3591            OnVideoBannerSetDone(metadata);
     3592        }
     3593    }
     3594    else
     3595        OnVideoBannerSetDone(metadata);
     3596}
     3597
     3598void VideoDialog::OnBannerCopyFinished(BannerDownloadErrorState error,
     3599                                       QString errorMsg, Metadata *item)
     3600{
     3601    QObject *src = sender();
     3602    if (src)
     3603        m_d->RemoveBannerDownload(dynamic_cast<BannerDownloadProxy *>
     3604                                       (src));
     3605
     3606    if (error != besOK && item)
     3607        item->SetBanner("");
     3608
     3609    VERBOSE(VB_IMPORTANT, tr("Banner download finished: %1 %2")
     3610            .arg(errorMsg).arg(error));
     3611
     3612    if (error == besTimeout)
     3613    {
     3614        createOkDialog(tr("Banner exists for this item but could not be "
     3615                            "retrieved within the timeout period.\n"));
     3616    }
     3617
     3618    OnVideoBannerSetDone(item);
     3619}
     3620
     3621// This is the final call as part of a StartVideoBannerSet
     3622void VideoDialog::OnVideoBannerSetDone(Metadata *metadata)
     3623{
     3624    // The metadata has a banner set
     3625    if (m_busyPopup)
     3626    {
     3627        m_busyPopup->Close();
     3628        m_busyPopup = NULL;
     3629    }
     3630
     3631    metadata->UpdateDatabase();
     3632    UpdateItem(GetItemCurrent());
     3633}
     3634
    30003635void VideoDialog::StartVideoSearchByUID(QString video_uid, Metadata *metadata)
    30013636{
    30023637    // Starting the busy dialog here triggers a bizarre segfault
     
    30273662        {
    30283663            data[(*p).section(':', 0, 0)] = (*p).section(':', 1);
    30293664        }
    3030         // set known values
     3665        // Set known values, but always set Title.
     3666        // Allows for partial fill.  Reset Metadata for full fill.
     3667
    30313668        metadata->SetTitle(data["Title"]);
    3032         metadata->SetYear(data["Year"].toInt());
    3033         metadata->SetDirector(data["Director"]);
    3034         metadata->SetPlot(data["Plot"]);
    3035         metadata->SetUserRating(data["UserRating"].toFloat());
    3036         metadata->SetRating(data["MovieRating"]);
    3037         metadata->SetLength(data["Runtime"].toInt());
     3669        metadata->SetSubtitle(data["Subtitle"]);       
    30383670
     3671        if (metadata->GetYear() == 1895)
     3672            metadata->SetYear(data["Year"].toInt());
     3673        if (metadata->GetDirector() == VIDEO_DIRECTOR_UNKNOWN)
     3674            metadata->SetDirector(data["Director"]);
     3675        if (metadata->GetPlot() == VIDEO_PLOT_DEFAULT)
     3676            metadata->SetPlot(data["Plot"]);
     3677        if (metadata->GetUserRating() == 0)
     3678            metadata->SetUserRating(data["UserRating"].toFloat());
     3679        if (metadata->GetRating() == VIDEO_RATING_DEFAULT)
     3680            metadata->SetRating(data["MovieRating"]);
     3681        if (metadata->GetLength() == 0)
     3682            metadata->SetLength(data["Runtime"].toInt());
     3683        if (metadata->GetSeason() == 0)
     3684            metadata->SetSeason(data["Season"].toInt());
     3685        if (metadata->GetEpisode() == 0)
     3686            metadata->SetEpisode(data["Episode"].toInt());
     3687
    30393688        m_d->AutomaticParentalAdjustment(metadata);
    30403689
    30413690        // Cast
     
    31673816    }
    31683817}
    31693818
     3819void VideoDialog::OnVideoImageOnlyDone(bool normal_exit,
     3820        const SearchListResults &results, Metadata *metadata)
     3821{
     3822    if (m_busyPopup)
     3823    {
     3824        m_busyPopup->Close();
     3825        m_busyPopup = NULL;
     3826    }
     3827
     3828    (void) normal_exit;
     3829    VERBOSE(VB_IMPORTANT,
     3830            QString("GetVideoList returned %1 possible matches")
     3831            .arg(results.size()));
     3832
     3833    if (results.size() == 1)
     3834    {
     3835        // Only one search result, fetch data.
     3836        if (results.begin().value().isEmpty())
     3837            return;
     3838        else
     3839        {
     3840            metadata->SetInetRef(results.begin().key());
     3841            metadata->UpdateDatabase();
     3842            UpdateItem(GetItemCurrent());
     3843            StartVideoPosterSet(metadata);
     3844        }
     3845    }
     3846    else if (results.size() < 1)
     3847    {
     3848        createOkDialog(tr("No matches were found."));
     3849    }
     3850    else
     3851    {
     3852        SearchResultsDialog *resultsdialog =
     3853                new SearchResultsDialog(m_popupStack, results);
     3854
     3855        if (resultsdialog->Create())
     3856            m_popupStack->AddScreen(resultsdialog);
     3857
     3858        connect(resultsdialog, SIGNAL(haveResult(QString)),
     3859                SLOT(OnVideoImgSearchListSelection(QString)),
     3860                Qt::QueuedConnection);
     3861    }
     3862}
     3863
     3864void VideoDialog::StartVideoSearchByTitleSubtitle(QString title,
     3865                                            QString subtitle, Metadata *metadata)
     3866{
     3867        createBusyDialog(title);
     3868
     3869        VideoTitleSubtitleSearch *vtss = new VideoTitleSubtitleSearch(this);
     3870
     3871        connect(vtss, SIGNAL(SigSearchResults(bool, QStringList,
     3872                                Metadata *)),
     3873                SLOT(OnVideoSearchByTitleSubtitleDone(bool, QStringList,
     3874                                Metadata *)));
     3875        vtss->Run(title, subtitle, metadata);
     3876}
     3877
     3878void VideoDialog::OnVideoSearchByTitleSubtitleDone(bool normal_exit,
     3879        QStringList result, Metadata *metadata)
     3880{
     3881    if (m_busyPopup)
     3882    {
     3883        m_busyPopup->Close();
     3884        m_busyPopup = NULL;
     3885    }
     3886
     3887    (void) normal_exit;
     3888    QString SeasEp;
     3889
     3890    if (!result.isEmpty())
     3891        SeasEp = result.takeAt(0);
     3892
     3893    if (!SeasEp.isEmpty())
     3894    {
     3895
     3896        // Stuff to parse Season and Episode here
     3897        QString season, episode = NULL;
     3898
     3899        QRegExp group("(?:[s])?(\\d{1,3})(?:\\s|-)?(?:[ex])" //Season
     3900                      "(?:\\s|-)?(\\d{1,3})", // Episode
     3901                      Qt::CaseInsensitive);
     3902
     3903        int pos = group.indexIn(SeasEp);
     3904        if (pos > -1)
     3905        {
     3906        QString groupResult = group.cap(0);
     3907        season = group.cap(1);
     3908        episode = group.cap(2);
     3909        }
     3910
     3911        VERBOSE(VB_IMPORTANT,
     3912            QString("Season and Episode found!  It was: %1")
     3913            .arg(SeasEp));
     3914
     3915        if (!season.isNull() && !episode.isNull())
     3916        {
     3917            metadata->SetSeason(season.toInt());
     3918            metadata->SetEpisode(episode.toInt());
     3919            StartVideoSearchByTitle(VIDEO_INETREF_DEFAULT,
     3920                                metadata->GetTitle(), metadata);
     3921        }
     3922    }
     3923    else
     3924        createOkDialog(tr("No matches were found."));
     3925}
     3926
    31703927void VideoDialog::doVideoScan()
    31713928{
    31723929    if (!m_d->m_scanner)
  • mythplugins/mythvideo/mythvideo/videolist.cpp

     
    826826    for (meta_dir_node::const_entry_iterator entry = src->entries_begin();
    827827         entry != src->entries_end(); ++entry)
    828828    {
    829         AddFileNode(dst, (*entry)->getData()->GetTitle(), (*entry)->getData());
     829        if (((*entry)->getData()->GetSeason() > 0) ||
     830                 ((*entry)->getData()->GetEpisode() > 0))
     831        {
     832            QString seas = QString::number((*entry)->getData()->GetSeason());
     833            QString ep = QString::number((*entry)->getData()->GetEpisode());
     834            QString tit = (*entry)->getData()->GetTitle();
     835            QString sub = (*entry)->getData()->GetSubtitle();
     836            if (ep.size() < 2)
     837                ep.prepend("0");
     838            QString TitSeasEpSub = QString("%1 %2x%3 - %4").arg(tit).arg(seas)
     839                                                           .arg(ep).arg(sub);
     840            AddFileNode(dst, TitSeasEpSub, (*entry)->getData());
     841        }
     842        else if ((*entry)->getData()->GetSubtitle().isEmpty())
     843            AddFileNode(dst, (*entry)->getData()->GetTitle(), (*entry)->getData());
     844        else
     845        {
     846            QString TitleSub = QString("%1 - %2").arg((*entry)->getData()->GetTitle())
     847                                                 .arg((*entry)->getData()->GetSubtitle());
     848            AddFileNode(dst, TitleSub, (*entry)->getData());
     849        }
    830850    }
    831851}
    832852
     
    12671287            QString title = qfi.completeBaseName();
    12681288            if (m_infer_title)
    12691289            {
    1270                 QString tmptitle(Metadata::FilenameToTitle(file_string));
     1290                QString tmptitle(Metadata::FilenameToMeta(file_string, 1));
    12711291                if (tmptitle.length())
    12721292                    title = tmptitle;
    12731293            }
  • 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

     
    7575{
    7676  private:
    7777    VideoPlayHandleMedia(const QString &handler, const QString &mrl,
    78             const QString &plot, const QString &title,
    79             const QString &director, int length, const QString &year) :
     78            const QString &plot, const QString &title, const QString &subtitle,
     79            const QString &director, int season, int episode,
     80            int length, const QString &year) :
    8081        m_handler(handler), m_mrl(mrl), m_plot(plot), m_title(title),
    81         m_director(director), m_length(length), m_year(year)
     82        m_subtitle(subtitle), m_director(director), m_season(season),
     83        m_episode(episode), m_length(length), m_year(year)
    8284    {
    8385    }
    8486
    8587  public:
    8688    static VideoPlayHandleMedia *Create(const QString &handler,
    8789            const QString &mrl, const QString &plot, const QString &title,
    88             const QString &director, int length, const QString &year)
     90            const QString &subtitle, const QString &director,
     91            int season, int episode,
     92            int length, const QString &year)
    8993    {
    90         return new VideoPlayHandleMedia(handler, mrl, plot, title,
    91                 director, length, year);
     94        return new VideoPlayHandleMedia(handler, mrl, plot, title, subtitle,
     95                director, season, episode, length, year);
    9296    }
    9397
    9498    bool Play() const
    9599    {
    96100        return gContext->GetMainWindow()->HandleMedia(m_handler, m_mrl,
    97                 m_plot, m_title, m_director, m_length, m_year);
     101                m_plot, m_title, m_subtitle, m_director, m_season,
     102                m_episode, m_length, m_year);
    98103    }
    99104
    100105    QString GetCommandDisplayName() const
     
    112117    QString m_mrl;
    113118    QString m_plot;
    114119    QString m_title;
     120    QString m_subtitle;
    115121    QString m_director;
     122    int m_season;
     123    int m_episode;
    116124    int m_length;
    117125    QString m_year;
    118126};
     
    200208            if (play_command.length())
    201209            {
    202210                AddPlayer(play_command, filename, item->GetPlot(),
    203                         item->GetTitle(), item->GetDirector(),
    204                         item->GetLength(),
     211                        item->GetTitle(), item->GetSubtitle(),
     212                        item->GetDirector(), item->GetSeason(),
     213                        item->GetEpisode(), item->GetLength(),
    205214                        QString::number(item->GetYear()));
    206215            }
    207216            else
     
    237246            play_command = "Internal";
    238247
    239248        QString plot;
    240         QString title = Metadata::FilenameToTitle(filename);
     249        QString title = Metadata::FilenameToMeta(filename, 1);
     250        QString subtitle = Metadata::FilenameToMeta(filename, 4);
    241251        QString director;
     252        int season = 0;
     253        int episode = 0;
    242254        int length = 0;
    243255        QString year = QString::number(VIDEO_YEAR_DEFAULT);
    244256
     
    246258        {
    247259            plot = extraData->GetPlot();
    248260            title = extraData->GetTitle();
     261            subtitle = extraData->GetSubtitle();
    249262            director = extraData->GetDirector();
     263            season = extraData->GetSeason();
     264            episode = extraData->GetEpisode();
    250265            length = extraData->GetLength();
    251266            year = QString::number(extraData->GetYear());
    252267        }
    253268
    254         AddPlayer(play_command, filename, plot, title, director, length, year);
     269        AddPlayer(play_command, filename, plot, title, subtitle, director,
     270                                season, episode, length, year);
    255271    }
    256272
    257273    void ClearPlayerList()
     
    282298
    283299  private:
    284300    void AddPlayer(const QString &player, const QString &filename,
    285             const QString &plot, const QString &title, const QString &director,
    286             int length, const QString &year)
     301            const QString &plot, const QString &title, const QString &subtitle,
     302            const QString &director, int season, int episode, int length,
     303            const QString &year)
    287304    {
    288305        m_player_procs.push_back(VideoPlayHandleMedia::Create(player, filename,
    289                         plot, title, director, length, year));
     306                        plot, title, subtitle, director, season, episode,
     307                        length, year));
    290308        m_player_procs.push_back(VideoPlayMythSystem::Create(player, filename));
    291309    }
    292310
  • 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>
     
    885896        <!-- Labels  -->
    886897
    887898        <textarea name="title_text" from="basetextarea">
    888             <area>50,135,250,40</area>
    889             <value>Name:</value>
     899            <area>150,80,250,40</area>
     900            <value>Title:</value>
    890901            <align>right,top</align>
    891902        </textarea>
    892903
     904        <textarea name="subtitle_text" from="basetextarea">
     905            <area>150,138,250,40</area>
     906            <value>Subtitle:</value>
     907            <align>right,top</align>
     908        </textarea>
     909
     910        <textarea name="season_text" from="basetextarea">
     911            <area>200,185,250,40</area>
     912            <value>Season:</value>
     913            <align>right,top</align>
     914        </textarea>
     915
     916        <textarea name="episode_text" from="basetextarea">
     917            <area>520,185,150,40</area>
     918            <value>Episode:</value>
     919            <align>right,top</align>
     920        </textarea>
     921
    893922        <textarea name="category_text" from="title_text">
    894             <position>50,197</position>
     923            <area>520,232,150,40</area>
     924            <align>right</align>
    895925            <value>Category:</value>
    896926        </textarea>
    897927
    898928        <textarea name="level_text" from="title_text">
    899             <position>50,247</position>
     929            <area>120,232,200,40</area>
     930            <align>right</align>
    900931            <value>Parental Control:</value>
    901932        </textarea>
    902933
    903934        <textarea name="child_text" from="title_text">
    904             <position>50,292</position>
     935            <area>120,277,200,40</area>
     936            <align>right</align>
    905937            <value>File to Always Play Next:</value>
    906938        </textarea>
    907939
    908940        <textarea name="browse_text" from="title_text">
    909             <position>50,337</position>
     941            <area>570,277,280,40</area>
     942            <align>left</align>
    910943            <value>Include while Browsing:</value>
    911944        </textarea>
    912945
    913946        <textarea name="coverart_text_label" from="title_text">
    914             <position>50,375</position>
     947            <position>200,328</position>
    915948            <value>Cover Art:</value>
    916949        </textarea>
    917950
     951        <textarea name="screenshot_text_label" from="title_text">
     952            <position>200,357</position>
     953            <value>Screenshot:</value>
     954        </textarea>
     955
     956        <textarea name="banner_text_label" from="title_text">
     957            <position>200,386</position>
     958            <value>Banner:</value>
     959        </textarea>
     960
     961        <textarea name="fanart_text_label" from="title_text">
     962            <position>200,415</position>
     963            <value>Fanart:</value>
     964        </textarea>
     965
    918966        <textarea name="trailer_text_label" from="title_text">
    919             <position>50,405</position>
     967            <position>200,447</position>
    920968            <value>Trailer:</value>
    921969        </textarea>
    922970
    923971        <textarea name="player_text" from="title_text">
    924             <position>50,445</position>
     972            <position>150,487</position>
    925973            <value>Unique Player Command:</value>
    926974        </textarea>
    927975
    928976        <!-- Widgets -->
    929977
    930978        <textedit name="title_edit" from="basetextedit">
    931             <position>310,125</position>
     979            <position>410,70</position>
    932980        </textedit>
    933981
    934         <buttonlist name="category_select" from="baseselector">
    935             <position>310,190</position>
    936         </buttonlist>
     982        <textedit name="subtitle_edit" from="basetextedit">
     983            <position>410,126</position>
     984        </textedit>
    937985
     986        <spinbox name="season" from="basespinbox">
     987            <position>460,181</position>
     988        </spinbox>
     989
     990        <spinbox name="episode" from="basespinbox">
     991            <position>680,181</position>
     992        </spinbox>
     993
    938994        <buttonlist name="level_select" from="baseselector">
    939             <position>310,240</position>
     995            <position>330,225</position>
    940996        </buttonlist>
    941997
     998        <buttonlist name="category_select" from="baseselector">
     999            <position>680,225</position>
     1000        </buttonlist>
     1001
    9421002        <buttonlist name="child_select" from="baseselector">
    943             <position>310,285</position>
     1003            <position>330,270</position>
    9441004        </buttonlist>
    9451005
    9461006        <checkbox name="browse_check" from="basecheckbox">
    947             <position>310,335</position>
     1007            <position>835,275</position>
    9481008        </checkbox>
    9491009
    9501010        <button name="coverart_button">
    951             <area>310,370,32,32</area>
     1011            <area>460,323,32,32</area>
    9521012            <statetype name="buttonstate">
    9531013                <state name="active">
    9541014                    <imagetype name="background">
     
    9701030        </button>
    9711031
    9721032        <textarea name="coverart_text" from="basetextarea">
    973             <area>350,375,250,40</area>
     1033            <area>500,328,250,40</area>
    9741034            <value>/path/to/the/thing.jpg</value>
    9751035        </textarea>
    9761036
     1037        <button name="screenshot_button">
     1038            <area>460,352,32,32</area>
     1039            <statetype name="buttonstate">
     1040                <state name="active">
     1041                    <imagetype name="background">
     1042                        <filename>blankbutton_off.png</filename>
     1043                    </imagetype>
     1044                </state>
     1045                <state name="selected" from="active">
     1046                    <imagetype name="background">
     1047                        <filename>blankbutton_on.png</filename>
     1048                    </imagetype>
     1049                </state>
     1050                <state name="disabled" from="active" />
     1051                <state name="pushed" from="active">
     1052                    <imagetype name="background">
     1053                        <filename>blankbutton_pushed.png</filename>
     1054                    </imagetype>
     1055                </state>
     1056            </statetype>
     1057        </button>
     1058
     1059        <textarea name="screenshot_text" from="basetextarea">
     1060            <area>500,357,250,40</area>
     1061            <value>/path/to/the/thing.jpg</value>
     1062        </textarea>
     1063
     1064        <button name="banner_button">
     1065            <area>460,381,32,32</area>
     1066            <statetype name="buttonstate">
     1067                <state name="active">
     1068                    <imagetype name="background">
     1069                        <filename>blankbutton_off.png</filename>
     1070                    </imagetype>
     1071                </state>
     1072                <state name="selected" from="active">
     1073                    <imagetype name="background">
     1074                        <filename>blankbutton_on.png</filename>
     1075                    </imagetype>
     1076                </state>
     1077                <state name="disabled" from="active" />
     1078                <state name="pushed" from="active">
     1079                    <imagetype name="background">
     1080                        <filename>blankbutton_pushed.png</filename>
     1081                    </imagetype>
     1082                </state>
     1083            </statetype>
     1084        </button>
     1085
     1086        <textarea name="banner_text" from="basetextarea">
     1087            <area>500,386,250,40</area>
     1088            <value>/path/to/the/thing.jpg</value>
     1089        </textarea>
     1090
     1091        <button name="fanart_button">
     1092            <area>460,412,32,32</area>
     1093            <statetype name="buttonstate">
     1094                <state name="active">
     1095                    <imagetype name="background">
     1096                        <filename>blankbutton_off.png</filename>
     1097                    </imagetype>
     1098                </state>
     1099                <state name="selected" from="active">
     1100                    <imagetype name="background">
     1101                        <filename>blankbutton_on.png</filename>
     1102                    </imagetype>
     1103                </state>
     1104                <state name="disabled" from="active" />
     1105                <state name="pushed" from="active">
     1106                    <imagetype name="background">
     1107                        <filename>blankbutton_pushed.png</filename>
     1108                    </imagetype>
     1109                </state>
     1110            </statetype>
     1111        </button>
     1112
     1113        <textarea name="fanart_text" from="basetextarea">
     1114            <area>500,415,250,40</area>
     1115            <value>/path/to/the/thing.jpg</value>
     1116        </textarea>
     1117
    9771118        <button name="trailer_button">
    978             <area>310,400,32,32</area>
     1119            <area>460,442,32,32</area>
    9791120            <statetype name="buttonstate">
    9801121                <state name="active">
    9811122                    <imagetype name="background">
     
    9971138        </button>
    9981139
    9991140        <textarea name="trailer_text" from="basetextarea">
    1000             <area>350,405,250,40</area>
     1141            <area>500,447,250,40</area>
    10011142            <value>/path/to/the/thing.jpg</value>
    10021143        </textarea>
    10031144
     1145
    10041146        <textedit name="player_edit" from="basetextedit">
    1005             <position>310,435</position>
     1147            <position>410,477</position>
    10061148        </textedit>
    10071149
    10081150        <button name="done_button" from="basebutton">
    1009             <position>310,505</position>
     1151            <position>510,537</position>
     1152            <value>Done</value>
    10101153        </button>
    10111154
    10121155    </window>
  • mythtv/libs/libmythui/mythmainwindow.cpp

     
    12981298
    12991299bool MythMainWindow::HandleMedia(const QString &handler, const QString &mrl,
    13001300                                 const QString &plot, const QString &title,
    1301                                  const QString &director, int lenMins,
     1301                                 const QString &subtitle,
     1302                                 const QString &director, int season,
     1303                                 int episode, int lenMins,
    13021304                                 const QString &year)
    13031305{
    13041306    QString lhandler(handler);
     
    13081310    // Let's see if we have a plugin that matches the handler name...
    13091311    if (d->mediaPluginMap.count(lhandler))
    13101312    {
    1311         d->mediaPluginMap[lhandler].playFn(mrl, plot, title,
    1312                                           director, lenMins, year);
     1313        d->mediaPluginMap[lhandler].playFn(mrl, plot, title, subtitle,
     1314                                          director, season, episode, lenMins,
     1315                                          year);
    13131316        return true;
    13141317    }
    13151318
  • mythtv/libs/libmythui/mythmainwindow.h

     
    1717#define REG_JUMPEX(a, b, c, d, e) GetMythMainWindow()->RegisterJump(a, b, c, d, e)
    1818#define REG_MEDIAPLAYER(a,b,c) GetMythMainWindow()->RegisterMediaPlugin(a, b, c)
    1919
    20 typedef int (*MediaPlayCallback)(const QString &, const QString &, const QString &, const QString &, int, const QString &);
     20typedef int (*MediaPlayCallback)(const QString &, const QString &, const QString &, const QString &, const QString &, int, int, int, const QString &);
    2121
    2222class MythMainWindowPrivate;
    2323
     
    6363
    6464    bool HandleMedia(const QString& handler, const QString& mrl,
    6565                     const QString& plot="", const QString& title="",
    66                      const QString& director="", int lenMins=120,
     66                     const QString& subtitle="", const QString& director="",
     67                     int season=0, int episode=0, int lenMins=120,
    6768                     const QString& year="1895");
    6869
    6970    void JumpTo(const QString &destination, bool pop = true);
  • mythtv/programs/mythfrontend/main.cpp

     
    672672}
    673673
    674674int internal_play_media(const QString &mrl, const QString &plot,
    675                         const QString &title, const QString &director,
     675                        const QString &title, const QString &subtitle,
     676                        const QString &director, int season, int episode,
    676677                        int lenMins, const QString &year)
    677678{
    678679    int res = -1;
     
    711712        pginfo->pathname = QString("dvd:%1").arg(mrl);
    712713    }
    713714
    714     pginfo->description = plot;
    715 
    716715    if (director.length())
    717         pginfo->subtitle = QString( "%1: %2" )
     716        pginfo->description = QString( "%1: %2.  " )
    718717                           .arg(QObject::tr("Directed By")).arg(director);
    719718
     719    pginfo->description += plot;
     720
     721    if (subtitle.length())
     722        pginfo->subtitle = subtitle;
     723
     724    if ((season > 0) || (episode > 0))
     725    {
     726        QString seas, ep;
     727        seas = QString::number(season);
     728        ep = QString::number(episode);
     729        if (ep.size() < 2)
     730            ep.prepend("0");
     731        QString SeasEpTitle =  QString("%1x%2").arg(seas).arg(ep);
     732        pginfo->chanstr = SeasEpTitle;
     733    }
     734
    720735    pginfo->title = title;
    721736
    722737    if (pginfo->pathname.startsWith("dvd:"))