Ticket #6346: MythVideo.SubSeasEp.080409.diff
File MythVideo.SubSeasEp.080409.diff, 116.0 KB (added by , 15 years ago) |
---|
-
mythplugins/mythbrowser/mythbrowser/main.cpp
19 19 20 20 using namespace std; 21 21 22 int handleMedia(const QString &url, const QString &, const QString &, const QString &, int, const QString &)22 int handleMedia(const QString &url, const QString &, const QString &, const QString &, const QString &, int, int, int, const QString &) 23 23 { 24 24 QStringList urls = url.split(" ", QString::SkipEmptyParts); 25 25 float zoom = gContext->GetSetting("WebBrowserZoomLevel", "1.4").toFloat(); -
mythplugins/mythvideo/theme/default/video-ui.xml
477 477 </buttonlist> 478 478 479 479 <textarea name="title" from="basetextarea"> 480 <area>40, 20,700,100</area>480 <area>40,15,700,100</area> 481 481 <multiline>yes</multiline> 482 482 <font>baseextralarge</font> 483 483 </textarea> 484 484 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 485 497 <imagetype name="coverimage"> 486 498 <area>30,90,203,311</area> 487 499 <preserveaspect>yes</preserveaspect> … … 493 505 </textarea> 494 506 495 507 <textarea name="dirlbl" from="basetextarea"> 496 <area>240,6 5,115,35</area>508 <area>240,68,115,35</area> 497 509 <value>Directed by</value> 498 510 <align>right</align> 499 511 </textarea> 500 512 501 513 <textarea name="director" from="basetextarea"> 502 <area>360,6 3,350,35</area>514 <area>360,66,350,35</area> 503 515 <font>basemedium</font> 504 516 </textarea> 505 517 … … 586 598 587 599 <window name="gallery"> 588 600 <textarea name="title" from="basetextarea"> 589 <area>70, 20,460,50</area>601 <area>70,15,460,50</area> 590 602 <cutdown>yes</cutdown> 591 603 <font>baselarge</font> 592 604 </textarea> 593 605 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 594 618 <buttonlist name="videos"> 595 619 <area>15,0,770,585</area> 596 620 <layout>grid</layout> … … 662 686 </buttonlist> 663 687 664 688 <textarea name="position" from="basetextarea"> 665 <area>530, 20,110,40</area>689 <area>530,15,110,40</area> 666 690 <align>hcenter,vcenter</align> 667 691 <font>basemedium</font> 668 692 </textarea> … … 728 752 <font>baselarge</font> 729 753 </textarea> 730 754 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 731 764 <textarea name="director" from="basetextarea"> 732 <area>50,3 67,450,30</area>765 <area>50,390,450,30</area> 733 766 </textarea> 734 767 735 768 <textarea name="year" from="basetextarea"> 736 <area>500,3 67,80,30</area>769 <area>500,390,80,30</area> 737 770 <align>right</align> 738 771 </textarea> 739 772 740 773 <textarea name="plot" from="basetextarea"> 741 <area>40, 395,530,80</area>774 <area>40,418,530,80</area> 742 775 <align>left,top</align> 743 776 <multiline>yes</multiline> 744 777 <cutdown>yes</cutdown> 745 778 </textarea> 746 779 747 780 <textarea name="cast" from="basetextarea"> 748 <area>60, 480,505,70</area>781 <area>60,503,505,50</area> 749 782 <align>left,top</align> 750 783 <multiline>yes</multiline> 751 784 <cutdown>no</cutdown> … … 867 900 <!-- Labels --> 868 901 869 902 <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> 872 905 <align>right,top</align> 873 906 </textarea> 874 907 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 875 926 <textarea name="category_text" from="title_text"> 876 <position>50,152</position> 927 <area>370,232,150,40</area> 928 <align>right</align> 877 929 <value>Category:</value> 878 930 </textarea> 879 931 880 932 <textarea name="level_text" from="title_text"> 881 <position>50,202</position> 933 <area>20,232,200,40</area> 934 <align>right</align> 882 935 <value>Parental Control:</value> 883 936 </textarea> 884 937 885 938 <textarea name="child_text" from="title_text"> 886 <position>50,247</position> 939 <area>20,277,200,40</area> 940 <align>right</align> 887 941 <value>File to Always Play Next:</value> 888 942 </textarea> 889 943 890 944 <textarea name="browse_text" from="title_text"> 891 <position>50,292</position> 945 <area>500,277,200,40</area> 946 <align>left</align> 892 947 <value>Include while Browsing:</value> 893 948 </textarea> 894 949 … … 925 980 <!-- Widgets --> 926 981 927 982 <textedit name="title_edit" from="basetextedit"> 928 <position>310, 80</position>983 <position>310,70</position> 929 984 </textedit> 930 985 931 < buttonlist name="category_select" from="baseselector">932 <position>310,1 45</position>933 </ buttonlist>986 <textedit name="subtitle_edit" from="basetextedit"> 987 <position>310,126</position> 988 </textedit> 934 989 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 935 998 <buttonlist name="level_select" from="baseselector"> 936 <position> 310,195</position>999 <position>230,225</position> 937 1000 </buttonlist> 938 1001 1002 <buttonlist name="category_select" from="baseselector"> 1003 <position>530,225</position> 1004 </buttonlist> 1005 939 1006 <buttonlist name="child_select" from="baseselector"> 940 <position> 310,240</position>1007 <position>230,270</position> 941 1008 </buttonlist> 942 1009 943 1010 <checkbox name="browse_check" from="basecheckbox"> 944 <position> 310,290</position>1011 <position>680,275</position> 945 1012 </checkbox> 946 1013 947 1014 <button name="coverart_button" from="basesearchbutton"> -
mythplugins/mythvideo/theme/default-wide/video-ui.xml
467 467 </imagetype> 468 468 469 469 <textarea name="title" from="basetextarea"> 470 <area>370,12, 700,40</area>470 <area>370,12,400,40</area> 471 471 <multiline>yes</multiline> 472 472 <font>baselarge</font> 473 473 </textarea> 474 474 475 <textarea name="subtitle" from="basetextarea"> 476 <area>800,12,400,40</area> 477 <multiline>yes</multiline> 478 <font>baselarge</font> 479 </textarea> 480 475 481 <textarea name="currentvideo" from="basetextarea"> 476 482 <area>150,486,500,35</area> 477 483 <align>top,vcenter</align> … … 487 493 <font>basemedium</font> 488 494 </textarea> 489 495 496 <textarea name="s##e##" from="basetextarea"> 497 <area>1010,63,150,35</area> 498 <font>basemedium</font> 499 </textarea> 500 490 501 <textarea name="plot" from="basetextarea"> 491 502 <area>380,97,840,145</area> 492 503 <multiline>yes</multiline> … … 572 583 573 584 <window name="gallery"> 574 585 <textarea name="title" from="basetextarea"> 575 <area>70,15, 800,50</area>586 <area>70,15,420,50</area> 576 587 <cutdown>yes</cutdown> 577 588 <font>baselarge</font> 578 589 </textarea> … … 646 657 </state> 647 658 </statetype> 648 659 </buttonlist> 660 661 <textarea name="subtitle" from="basetextarea"> 662 <area>500,15,350,40</area> 663 <align>hcenter,vcenter</align> 664 <font>basemedium</font> 665 </textarea> 649 666 667 <textarea name="s##e##" from="basetextarea"> 668 <area>870,15,100,40</area> 669 <align>hcenter,vcenter</align> 670 <font>basemedium</font> 671 </textarea> 672 650 673 <textarea name="position" from="basetextarea"> 651 <area> 890,15,200,40</area>674 <area>1000,15,200,40</area> 652 675 <align>hcenter,vcenter</align> 653 676 <font>basemedium</font> 654 677 </textarea> … … 713 736 <font>baselarge</font> 714 737 </textarea> 715 738 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> 719 743 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> 724 748 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> 731 777 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 745 778 <imagetype name="coverimage"> 746 779 <area>1000,400,225,250</area> 747 780 <preserveaspect>yes</preserveaspect> … … 843 876 <window name="edit_metadata"> 844 877 845 878 <textarea name="title" from="basetextarea"> 846 <area>10, 50,1260,50</area>879 <area>10,30,760,50</area> 847 880 <value>Edit Video Information</value> 848 881 <align>hcenter,vcenter</align> 849 882 <font>baselarge</font> … … 852 885 <!-- Labels --> 853 886 854 887 <textarea name="title_text" from="basetextarea"> 855 <area> 250,110,250,40</area>856 <value> Name:</value>888 <area>50,80,250,40</area> 889 <value>Title:</value> 857 890 <align>right,top</align> 858 891 </textarea> 859 892 893 <textarea name="subtitle_text" from="basetextarea"> 894 <area>50,138,250,40</area> 895 <value>Subtitle:</value> 896 <align>right,top</align> 897 </textarea> 898 899 <textarea name="season_text" from="basetextarea"> 900 <area>50,185,250,40</area> 901 <value>Season:</value> 902 <align>right,top</align> 903 </textarea> 904 905 <textarea name="episode_text" from="basetextarea"> 906 <area>370,185,150,40</area> 907 <value>Episode:</value> 908 <align>right,top</align> 909 </textarea> 910 860 911 <textarea name="category_text" from="title_text"> 861 <position>250,172</position> 912 <area>420,232,150,40</area> 913 <align>right</align> 862 914 <value>Category:</value> 863 915 </textarea> 864 916 865 917 <textarea name="level_text" from="title_text"> 866 <position>250,222</position> 918 <area>20,232,200,40</area> 919 <align>right</align> 867 920 <value>Parental Control:</value> 868 921 </textarea> 869 922 870 923 <textarea name="child_text" from="title_text"> 871 <position>250,267</position> 924 <area>20,277,200,40</area> 925 <align>right</align> 872 926 <value>File to Always Play Next:</value> 873 927 </textarea> 874 928 875 929 <textarea name="browse_text" from="title_text"> 876 <position>250,312</position> 930 <area>470,277,280,40</area> 931 <align>left</align> 877 932 <value>Include while Browsing:</value> 878 933 </textarea> 879 934 880 935 <textarea name="coverart_text_label" from="title_text"> 881 <position> 250,348</position>936 <position>50,328</position> 882 937 <value>Cover Art:</value> 883 938 </textarea> 884 939 885 940 <textarea name="screenshot_text_label" from="title_text"> 886 <position> 250,377</position>941 <position>50,357</position> 887 942 <value>Screenshot:</value> 888 943 </textarea> 889 944 890 945 <textarea name="banner_text_label" from="title_text"> 891 <position> 250,406</position>946 <position>50,386</position> 892 947 <value>Banner:</value> 893 948 </textarea> 894 949 895 950 <textarea name="fanart_text_label" from="title_text"> 896 <position> 250,435</position>951 <position>50,415</position> 897 952 <value>Fanart:</value> 898 953 </textarea> 899 954 900 955 <textarea name="trailer_text_label" from="title_text"> 901 <position> 250,464</position>956 <position>50,447</position> 902 957 <value>Trailer:</value> 903 958 </textarea> 904 959 905 960 <textarea name="player_text" from="title_text"> 906 <position> 250,510</position>961 <position>50,487</position> 907 962 <value>Unique Player Command:</value> 908 963 </textarea> 909 964 910 965 <!-- Widgets --> 911 966 912 967 <textedit name="title_edit" from="basetextedit"> 913 <position> 510,100</position>968 <position>310,70</position> 914 969 </textedit> 915 970 916 < buttonlist name="category_select" from="baseselector">917 <position> 510,165</position>918 </ buttonlist>971 <textedit name="subtitle_edit" from="basetextedit"> 972 <position>310,126</position> 973 </textedit> 919 974 975 <spinbox name="season" from="basespinbox"> 976 <position>310,181</position> 977 </spinbox> 978 979 <spinbox name="episode" from="basespinbox"> 980 <position>530,181</position> 981 </spinbox> 982 920 983 <buttonlist name="level_select" from="baseselector"> 921 <position> 510,215</position>984 <position>230,225</position> 922 985 </buttonlist> 923 986 987 <buttonlist name="category_select" from="baseselector"> 988 <position>580,225</position> 989 </buttonlist> 990 924 991 <buttonlist name="child_select" from="baseselector"> 925 <position> 510,260</position>992 <position>230,270</position> 926 993 </buttonlist> 927 994 928 995 <checkbox name="browse_check" from="basecheckbox"> 929 <position> 510,310</position>996 <position>735,275</position> 930 997 </checkbox> 931 998 932 <button name="coverart_button" from="basesearchbutton"> 933 <position>510,343</position> 999 <button name="coverart_button"> 1000 <area>310,323,32,32</area> 1001 <statetype name="buttonstate"> 1002 <state name="active"> 1003 <imagetype name="background"> 1004 <filename>blankbutton_off.png</filename> 1005 </imagetype> 1006 </state> 1007 <state name="selected" from="active"> 1008 <imagetype name="background"> 1009 <filename>blankbutton_on.png</filename> 1010 </imagetype> 1011 </state> 1012 <state name="disabled" from="active" /> 1013 <state name="pushed" from="active"> 1014 <imagetype name="background"> 1015 <filename>blankbutton_pushed.png</filename> 1016 </imagetype> 1017 </state> 1018 </statetype> 934 1019 </button> 935 1020 936 1021 <textarea name="coverart_text" from="basetextarea"> 937 <area> 550,348,250,40</area>1022 <area>350,328,250,40</area> 938 1023 <value>/path/to/the/thing.jpg</value> 939 1024 </textarea> 940 1025 941 <button name="screenshot_button" from="basesearchbutton"> 942 <position>510,372</position> 1026 <button name="screenshot_button"> 1027 <area>310,352,32,32</area> 1028 <statetype name="buttonstate"> 1029 <state name="active"> 1030 <imagetype name="background"> 1031 <filename>blankbutton_off.png</filename> 1032 </imagetype> 1033 </state> 1034 <state name="selected" from="active"> 1035 <imagetype name="background"> 1036 <filename>blankbutton_on.png</filename> 1037 </imagetype> 1038 </state> 1039 <state name="disabled" from="active" /> 1040 <state name="pushed" from="active"> 1041 <imagetype name="background"> 1042 <filename>blankbutton_pushed.png</filename> 1043 </imagetype> 1044 </state> 1045 </statetype> 943 1046 </button> 944 1047 945 1048 <textarea name="screenshot_text" from="basetextarea"> 946 <area> 550,377,250,40</area>1049 <area>350,357,250,40</area> 947 1050 <value>/path/to/the/thing.jpg</value> 948 1051 </textarea> 949 1052 950 <button name="banner_button" from="basesearchbutton"> 951 <position>510,401</position> 1053 <button name="banner_button"> 1054 <area>310,381,32,32</area> 1055 <statetype name="buttonstate"> 1056 <state name="active"> 1057 <imagetype name="background"> 1058 <filename>blankbutton_off.png</filename> 1059 </imagetype> 1060 </state> 1061 <state name="selected" from="active"> 1062 <imagetype name="background"> 1063 <filename>blankbutton_on.png</filename> 1064 </imagetype> 1065 </state> 1066 <state name="disabled" from="active" /> 1067 <state name="pushed" from="active"> 1068 <imagetype name="background"> 1069 <filename>blankbutton_pushed.png</filename> 1070 </imagetype> 1071 </state> 1072 </statetype> 952 1073 </button> 953 1074 954 1075 <textarea name="banner_text" from="basetextarea"> 955 <area> 550,406,250,40</area>1076 <area>350,386,250,40</area> 956 1077 <value>/path/to/the/thing.jpg</value> 957 1078 </textarea> 958 1079 959 <button name="fanart_button" from="basesearchbutton"> 960 <position>510,430</position> 1080 <button name="fanart_button"> 1081 <area>310,412,32,32</area> 1082 <statetype name="buttonstate"> 1083 <state name="active"> 1084 <imagetype name="background"> 1085 <filename>blankbutton_off.png</filename> 1086 </imagetype> 1087 </state> 1088 <state name="selected" from="active"> 1089 <imagetype name="background"> 1090 <filename>blankbutton_on.png</filename> 1091 </imagetype> 1092 </state> 1093 <state name="disabled" from="active" /> 1094 <state name="pushed" from="active"> 1095 <imagetype name="background"> 1096 <filename>blankbutton_pushed.png</filename> 1097 </imagetype> 1098 </state> 1099 </statetype> 961 1100 </button> 962 1101 963 1102 <textarea name="fanart_text" from="basetextarea"> 964 <area> 550,435,250,40</area>1103 <area>350,415,250,40</area> 965 1104 <value>/path/to/the/thing.jpg</value> 966 1105 </textarea> 967 1106 968 <button name="trailer_button" from="basesearchbutton"> 969 <position>510,460</position> 1107 <button name="trailer_button"> 1108 <area>310,442,32,32</area> 1109 <statetype name="buttonstate"> 1110 <state name="active"> 1111 <imagetype name="background"> 1112 <filename>blankbutton_off.png</filename> 1113 </imagetype> 1114 </state> 1115 <state name="selected" from="active"> 1116 <imagetype name="background"> 1117 <filename>blankbutton_on.png</filename> 1118 </imagetype> 1119 </state> 1120 <state name="disabled" from="active" /> 1121 <state name="pushed" from="active"> 1122 <imagetype name="background"> 1123 <filename>blankbutton_pushed.png</filename> 1124 </imagetype> 1125 </state> 1126 </statetype> 970 1127 </button> 971 1128 972 1129 <textarea name="trailer_text" from="basetextarea"> 973 <area> 550,465,250,40</area>1130 <area>350,447,250,40</area> 974 1131 <value>/path/to/the/thing.jpg</value> 975 1132 </textarea> 976 1133 1134 977 1135 <textedit name="player_edit" from="basetextedit"> 978 <position> 510,495</position>1136 <position>310,477</position> 979 1137 </textedit> 980 1138 981 1139 <button name="done_button" from="basebutton"> 982 <position> 510,565</position>1140 <position>310,537</position> 983 1141 <value>Done</value> 984 1142 </button> 985 1143 -
mythplugins/mythvideo/mythvideo/videodlg.h
28 28 29 29 enum CoverDownloadErrorState { esOK, esError, esTimeout }; 30 30 enum FanartDownloadErrorState { fesOK, fesError, fesTimeout }; 31 enum BannerDownloadErrorState { besOK, besError, besTimeout }; 31 32 32 33 class VideoDialog : public MythScreenType 33 34 { … … 51 52 bool Create(); 52 53 bool keyPressEvent(QKeyEvent *levent); 53 54 55 private: 56 void searchStart(); 57 58 public slots: 59 void searchComplete(QString string); 60 54 61 private slots: 55 62 void UpdatePosition(); 56 63 void UpdateText(MythUIButtonListItem *); … … 68 75 69 76 void EditMetadata(); 70 77 void VideoSearch(); 78 void TitleSubtitleSearch(); 79 void ImageOnlyDownload(); 71 80 void ManualVideoUID(); 72 81 void ManualVideoTitle(); 73 82 void ResetMetadata(); … … 93 102 94 103 // Called when the underlying data for an item changes 95 104 void OnVideoSearchListSelection(QString video_uid); 105 void OnVideoImgSearchListSelection(QString video_uid); 96 106 97 107 void OnManualVideoUID(QString video_uid); 98 108 void OnManualVideoTitle(QString title); … … 140 150 // OnVideoPosterSetDone() stop wait background 141 151 void StartVideoPosterSet(Metadata *metadata); 142 152 void StartVideoFanartSet(Metadata *metadata); 153 void StartVideoBannerSet(Metadata *metadata); 143 154 144 155 // StartVideoSearchByUID() start wait background 145 156 // OnVideoSearchByUIDDone() stop wait background … … 150 161 // OnVideoSearchByTitleDone() 151 162 void StartVideoSearchByTitle(QString video_uid, QString title, 152 163 Metadata *metadata); 164 void StartVideoSearchByTitleSubtitle(QString title, 165 QString subtitle, Metadata *metadata); 153 166 154 167 private slots: 155 168 // called during StartVideoPosterSet … … 159 172 void OnFanartURL(QString uri, Metadata *metadata); 160 173 void OnFanartCopyFinished(FanartDownloadErrorState error, QString errorMsg, 161 174 Metadata *metadata); 175 void OnBannerURL(QString uri, Metadata *metadata); 176 void OnBannerCopyFinished(BannerDownloadErrorState error, QString errorMsg, 177 Metadata *metadata); 162 178 163 179 // called during StartVideoSearchByTitle 164 180 void OnVideoSearchByTitleDone(bool normal_exit, 165 181 const SearchListResults &results, 166 182 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); 167 189 168 190 // and now the end points 169 191 170 192 // StartVideoPosterSet end 171 193 void OnVideoPosterSetDone(Metadata *metadata); 172 194 void OnVideoFanartSetDone(Metadata *metadata); 195 void OnVideoBannerSetDone(Metadata *metadata); 173 196 174 197 // StartVideoSearchByUID end 175 198 void OnVideoSearchByUIDDone(bool normal_exit, -
mythplugins/mythvideo/mythvideo/metadatalistmanager.cpp
112 112 MSqlQuery query(MSqlQuery::InitCon()); 113 113 query.setForwardOnly(true); 114 114 const QString BaseMetadataQuery( 115 "SELECT title, director, plot, rating, year, userrating," 116 "length, filename, showlevel, coverfile, inetref, childid," 117 "browse, playcommand, category, intid, trailer, screenshot," 118 "banner, fanart, host FROM videometadata"); 115 "SELECT title, director, plot, rating, year, " 116 "userrating, length, filename, showlevel, " 117 "coverfile, inetref, childid, browse, playcommand, category, " 118 "intid, trailer, screenshot, banner, fanart, " 119 "subtitle, season, episode, host FROM videometadata"); 119 120 120 121 query.prepare(BaseMetadataQuery); 121 122 -
mythplugins/mythvideo/mythvideo/metadata.cpp
89 89 public: 90 90 MetadataImp(const QString &filename, const QString &trailer, const QString &coverfile, 91 91 const QString &screenshot, const QString &banner, const QString &fanart, 92 const QString &title, int year,92 const QString &title, const QString &subtitle, int year, 93 93 const QString &inetref, const QString &director, 94 94 const QString &plot, float userrating, 95 95 const QString &rating, int length, 96 int season, int episode, 96 97 int id, ParentalLevel::Level showlevel, int categoryID, 97 98 int childID, bool browse, 98 99 const QString &playcommand, const QString &category, … … 100 101 const country_list &countries, 101 102 const cast_list &cast, 102 103 const QString &host = "") : 103 m_title(title), 104 m_title(title), m_subtitle(subtitle), 104 105 m_inetref(inetref), m_director(director), m_plot(plot), 105 106 m_rating(rating), m_playcommand(playcommand), m_category(category), 106 107 m_genres(genres), m_countries(countries), m_cast(cast), 107 108 m_filename(filename), m_trailer(trailer), m_coverfile(coverfile), 108 109 m_screenshot(screenshot), m_banner(banner), m_fanart(fanart), 109 110 m_host(host), m_categoryID(categoryID), m_childID(childID), 110 m_year(year), m_length(length), m_showlevel(showlevel), 111 m_year(year), m_length(length), m_season(season), 112 m_episode(episode), m_showlevel(showlevel), 111 113 m_browse(browse), m_id(id), m_userrating(userrating) 112 114 { 113 115 VideoCategory::GetCategory().get(m_categoryID, m_category); … … 128 130 if (this != &rhs) 129 131 { 130 132 m_title = rhs.m_title; 133 m_subtitle = rhs.m_subtitle; 131 134 m_inetref = rhs.m_inetref; 132 135 m_director = rhs.m_director; 133 136 m_plot = rhs.m_plot; … … 148 151 m_childID = rhs.m_childID; 149 152 m_year = rhs.m_year; 150 153 m_length = rhs.m_length; 154 m_season = rhs.m_season; 155 m_episode = rhs.m_episode; 151 156 m_showlevel = rhs.m_showlevel; 152 157 m_browse = rhs.m_browse; 153 158 m_id = rhs.m_id; … … 180 185 m_title = title; 181 186 } 182 187 188 const QString &getSubtitle() const { return m_subtitle; } 189 void SetSubtitle(const QString &subtitle) { m_subtitle = subtitle; } 190 183 191 const QString &GetInetRef() const { return m_inetref; } 184 192 void SetInetRef(const QString &inetRef) { m_inetref = inetRef; } 185 193 … … 249 257 int GetLength() const { return m_length; } 250 258 void SetLength(int length) { m_length = length; } 251 259 260 int GetSeason() const { return m_season; } 261 void SetSeason(int season) { m_season = season; } 262 263 int GetEpisode() const { return m_episode; } 264 void SetEpisode(int episode) { m_episode = episode; } 265 252 266 ParentalLevel::Level GetShowLevel() const { return m_showlevel; } 253 267 void SetShowLevel(ParentalLevel::Level showLevel) 254 268 { … … 289 303 290 304 private: 291 305 QString m_title; 306 QString m_subtitle; 292 307 QString m_inetref; 293 308 QString m_director; 294 309 QString m_plot; … … 310 325 int m_childID; 311 326 int m_year; 312 327 int m_length; 328 int m_season; 329 int m_episode; 313 330 ParentalLevel::Level m_showlevel; 314 331 bool m_browse; 315 332 unsigned int m_id; // videometadata.intid … … 383 400 { 384 401 MetadataImp tmp(m_filename, VIDEO_TRAILER_DEFAULT, VIDEO_COVERFILE_DEFAULT, 385 402 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, 390 410 ParentalLevel::plLowest, 0, -1, true, "", "", 391 411 Metadata::genre_list(), Metadata::country_list(), 392 412 Metadata::cast_list(), m_host); … … 484 504 m_screenshot = query.value(17).toString(); 485 505 m_banner = query.value(18).toString(); 486 506 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(); 488 511 489 512 VideoCategory::GetCategory().get(m_categoryID, m_category); 490 513 … … 501 524 void MetadataImp::saveToDatabase() 502 525 { 503 526 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); 505 530 if (m_director.isEmpty()) 506 531 m_director = VIDEO_DIRECTOR_UNKNOWN; 507 532 if (m_plot.isEmpty()) 508 533 m_plot = VIDEO_PLOT_DEFAULT; 509 534 if (m_rating.isEmpty()) 510 535 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(); 511 540 if (m_coverfile.isEmpty()) 512 541 m_coverfile = VIDEO_COVERFILE_DEFAULT; 513 542 if (m_screenshot.isEmpty()) … … 533 562 { 534 563 m_browse = gContext->GetNumSetting("VideoNewBrowsable", 1); 535 564 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)"); 543 572 } 544 573 else 545 574 { 546 query.prepare("UPDATE videometadata SET title = :TITLE, "575 query.prepare("UPDATE videometadata SET title = :TITLE, subtitle = :SUBTITLE, " 547 576 "director = :DIRECTOR, plot = :PLOT, rating= :RATING, " 548 577 "year = :YEAR, userrating = :USERRATING, " 549 "length = :LENGTH, filename = :FILENAME, trailer = :TRAILER, " 578 "length = :LENGTH, season = :SEASON, episode = :EPISODE, " 579 "filename = :FILENAME, trailer = :TRAILER, " 550 580 "showlevel = :SHOWLEVEL, coverfile = :COVERFILE, " 551 581 "screenshot = :SCREENSHOT, banner = :BANNER, fanart = :FANART, " 552 582 "inetref = :INETREF, browse = :BROWSE, host = :HOST, " … … 560 590 } 561 591 562 592 query.bindValue(":TITLE", m_title); 593 query.bindValue(":SUBTITLE", m_subtitle); 563 594 query.bindValue(":DIRECTOR", m_director); 564 595 query.bindValue(":PLOT", m_plot); 565 596 query.bindValue(":RATING", m_rating); 566 597 query.bindValue(":YEAR", m_year); 567 598 query.bindValue(":USERRATING", m_userrating); 568 599 query.bindValue(":LENGTH", m_length); 600 query.bindValue(":SEASON", m_season); 601 query.bindValue(":EPISODE", m_episode); 569 602 query.bindValue(":FILENAME", m_filename); 570 603 query.bindValue(":TRAILER", m_trailer); 571 604 query.bindValue(":SHOWLEVEL", m_showlevel); … … 793 826 } 794 827 } 795 828 796 QString Metadata::FilenameTo Title(const QString &file_name)829 QString Metadata::FilenameToMeta(const QString &file_name, int position) 797 830 { 831 // position 1 returns title, 2 returns season, 832 // 3 returns episode, 4 returns subtitle 833 798 834 QString title = file_name.right(file_name.length() - 799 835 file_name.lastIndexOf('/') - 1); 836 800 837 title.replace(QRegExp("_"), " "); 801 838 title.replace(QRegExp("%20"), " "); 839 title.replace(QRegExp("-"), " "); 802 840 title = title.left(title.lastIndexOf('.')); 803 841 title.replace(QRegExp("\\."), " "); 804 842 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 } 808 870 809 return title.trimmed();871 return QString(""); 810 872 } 811 873 812 874 namespace … … 827 889 return ret; 828 890 } 829 891 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,892 Metadata::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, 834 896 const QString &inetref, const QString &director, 835 897 const QString &plot, float userrating, 836 898 const QString &rating, int length, 899 int season, int episode, 837 900 int id, ParentalLevel::Level showlevel, int categoryID, 838 901 int childID, bool browse, 839 902 const QString &playcommand, const QString &category, … … 843 906 const QString &host) 844 907 { 845 908 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); 850 913 } 851 914 852 915 Metadata::~Metadata() … … 909 972 m_imp->SetTitle(title); 910 973 } 911 974 975 const QString &Metadata::GetSubtitle() const 976 { 977 return m_imp->getSubtitle(); 978 } 979 980 void Metadata::SetSubtitle(const QString &subtitle) 981 { 982 m_imp->SetSubtitle(subtitle); 983 } 984 912 985 int Metadata::GetYear() const 913 986 { 914 987 return m_imp->getYear(); … … 979 1052 m_imp->SetLength(length); 980 1053 } 981 1054 1055 int Metadata::GetSeason() const 1056 { 1057 return m_imp->GetSeason(); 1058 } 1059 1060 void Metadata::SetSeason(int season) 1061 { 1062 m_imp->SetSeason(season); 1063 } 1064 1065 int Metadata::GetEpisode() const 1066 { 1067 return m_imp->GetEpisode(); 1068 } 1069 1070 void Metadata::SetEpisode(int episode) 1071 { 1072 m_imp->SetEpisode(episode); 1073 } 1074 982 1075 unsigned int Metadata::GetID() const 983 1076 { 984 1077 return m_imp->GetID(); -
mythplugins/mythvideo/mythvideo/globalsettings.cpp
235 235 return gc; 236 236 } 237 237 238 HostLineEdit *SearchTVListingsCommand() 239 { 240 HostLineEdit *gc = new HostLineEdit("mythvideo.TVListCommandLine"); 241 gc->setLabel(QObject::tr("Command to search for TV shows in MythVideo")); 242 gc->setValue(GetShareDir() + "mythvideo/scripts/ttvdb.py -M"); 243 gc->setHelpText(QObject::tr("This command must be " 244 "executable by the user running MythVideo.")); 245 return gc; 246 } 247 248 HostLineEdit *GetTVPostersCommand() 249 { 250 HostLineEdit *gc = new HostLineEdit("mythvideo.TVPosterCommandLine"); 251 gc->setLabel(QObject::tr("Command to search for TV Season posters")); 252 gc->setValue(GetShareDir() + "mythvideo/scripts/ttvdb.py -mP"); 253 gc->setHelpText(QObject::tr("This command must be " 254 "executable by the user running MythVideo.")); 255 return gc; 256 } 257 258 HostLineEdit *GetTVFanartCommand() 259 { 260 HostLineEdit *gc = new HostLineEdit("mythvideo.TVFanartCommandLine"); 261 gc->setLabel(QObject::tr("Command to search for TV fanart")); 262 gc->setValue(GetShareDir() + "mythvideo/scripts/ttvdb.py -tF"); 263 gc->setHelpText(QObject::tr("This command must be " 264 "executable by the user running MythVideo.")); 265 return gc; 266 } 267 268 HostLineEdit *GetTVBannerCommand() 269 { 270 HostLineEdit *gc = new HostLineEdit("mythvideo.TVBannerCommandLine"); 271 gc->setLabel(QObject::tr("Command to search for TV banners")); 272 gc->setValue(GetShareDir() + "mythvideo/scripts/ttvdb.py -tB"); 273 gc->setHelpText(QObject::tr("This command must be " 274 "executable by the user running MythVideo.")); 275 return gc; 276 } 277 278 HostLineEdit *GetTVDataCommand() 279 { 280 HostLineEdit *gc = new HostLineEdit("mythvideo.TVDataCommandLine"); 281 gc->setLabel(QObject::tr("Command to extract data for TV Episodes")); 282 gc->setValue(GetShareDir() + "mythvideo/scripts/ttvdb.py -D"); 283 gc->setHelpText(QObject::tr("This command must be " 284 "executable by the user running MythVideo.")); 285 return gc; 286 } 287 288 HostLineEdit *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 238 298 HostLineEdit *VideoStartupDirectory() 239 299 { 240 300 HostLineEdit *gc = new HostLineEdit("VideoStartupDir"); … … 780 840 VConfigPage page7(pages, false); 781 841 page7->addChild(trlr); 782 842 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 783 857 int page_num = 1; 784 858 for (ConfigPage::PageList::const_iterator p = pages.begin(); 785 859 p != pages.end(); ++p, ++page_num) -
mythplugins/mythvideo/mythvideo/videofilter.h
54 54 kOrderByUserRatingDescending = 2, 55 55 kOrderByLength = 3, 56 56 kOrderByFilename = 4, 57 kOrderByID = 5 57 kOrderByID = 5, 58 kOrderBySeasonEp = 6 58 59 }; 59 60 60 61 int GetCategory() const { return category; } -
mythplugins/mythvideo/mythvideo/dbcheck.cpp
38 38 const QString lastMythDVDDBVersion = "1002"; 39 39 const QString lastMythVideoVersion = "1010"; 40 40 41 const QString currentDatabaseVersion = "102 3";41 const QString currentDatabaseVersion = "1024"; 42 42 43 43 const QString OldMythVideoVersionName = "VideoDBSchemaVer"; 44 44 const QString OldMythDVDVersionName = "DVDDBSchemaVer"; … … 832 832 performActualUpdate(updates, "1023", dbver, MythVideoVersionName); 833 833 } 834 834 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 } 835 846 836 847 } 837 848 } -
mythplugins/mythvideo/mythvideo/main.cpp
322 322 REG_KEY("Video","INCPARENT","Increase Parental Level","],},F11"); 323 323 REG_KEY("Video","DECPARENT","Decrease Parental Level","[,{,F10"); 324 324 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 325 329 REG_KEY("Video","HOME","Go to the first video","Home"); 326 330 REG_KEY("Video","END","Go to the last video","End"); 327 331 -
mythplugins/mythvideo/mythvideo/videoutils.cpp
139 139 return QString("%1 minutes").arg(length); 140 140 } 141 141 142 QString GetDisplaySeasonEpisode(int seasEp, int digits) 143 { 144 QString seasEpNum = QString::number(seasEp); 145 146 if (digits == 2 && seasEpNum.size() < 2) 147 seasEpNum.prepend("0"); 148 149 return seasEpNum; 150 } 151 142 152 QString GetDisplayBrowse(bool browse) 143 153 { 144 154 return browse ? QObject::tr("Yes") : QObject::tr("No"); -
mythplugins/mythvideo/mythvideo/editmetadata.h
10 10 class MythUIText; 11 11 class MythUITextEdit; 12 12 class MythUIButton; 13 class MythUISpinBox; 13 14 class MythUICheckBox; 14 15 15 16 class EditMetadataDialog : public MythScreenType … … 34 35 public slots: 35 36 void SaveAndExit(); 36 37 void SetTitle(); 38 void SetSubtitle(); 37 39 void SetCategory(MythUIButtonListItem*); 38 40 void SetPlayer(); 41 void SetSeason(); 42 void SetEpisode(); 39 43 void SetLevel(MythUIButtonListItem*); 40 44 void SetChild(MythUIButtonListItem*); 41 45 void ToggleBrowse(); … … 60 64 // 61 65 62 66 MythUITextEdit *m_titleEdit; 67 MythUITextEdit *m_subtitleEdit; 63 68 MythUITextEdit *m_playerEdit; 69 MythUISpinBox *m_seasonSpin; 70 MythUISpinBox *m_episodeSpin; 64 71 MythUIButtonList *m_categoryList; 65 72 MythUIButtonList *m_levelList; 66 73 MythUIButtonList *m_childList; -
mythplugins/mythvideo/mythvideo/videodlg.cpp
288 288 FanartDownloadErrorState m_error_state; 289 289 }; 290 290 291 class BannerDownloadProxy : public QObject 292 { 293 Q_OBJECT 294 295 signals: 296 void SigFinished(BannerDownloadErrorState reason, QString errorMsg, 297 Metadata *item); 298 public: 299 static BannerDownloadProxy *Create(const QUrl &url, const QString &dest, 300 Metadata *item) 301 { 302 return new BannerDownloadProxy(url, dest, item); 303 } 304 305 public: 306 void StartCopy() 307 { 308 m_id = m_http.get(m_url.toString(), &m_data_buffer); 309 310 m_timer.start(gContext->GetNumSetting("BannerDownloadTimeout", 30) 311 * 1000); 312 } 313 314 void Stop() 315 { 316 if (m_timer.isActive()) 317 m_timer.stop(); 318 319 VERBOSE(VB_GENERAL, tr("Banner download stopped.")); 320 m_http.abort(); 321 } 322 323 private: 324 BannerDownloadProxy(const QUrl &url, const QString &dest, 325 Metadata *item) : m_item(item), m_dest_file(dest), 326 m_id(0), m_url(url), m_error_state(besOK) 327 { 328 connect(&m_http, SIGNAL(requestFinished(int, bool)), 329 SLOT(OnFinished(int, bool))); 330 331 connect(&m_timer, SIGNAL(timeout()), SLOT(OnDownloadTimeout())); 332 m_timer.setSingleShot(true); 333 m_http.setHost(m_url.host()); 334 } 335 336 ~BannerDownloadProxy() {} 337 338 private slots: 339 void OnDownloadTimeout() 340 { 341 VERBOSE(VB_IMPORTANT, QString("Copying of '%1' timed out") 342 .arg(m_url.toString())); 343 m_error_state = besTimeout; 344 Stop(); 345 } 346 347 void OnFinished(int id, bool error) 348 { 349 QString errorMsg; 350 if (error) 351 errorMsg = m_http.errorString(); 352 353 if (id == m_id) 354 { 355 if (m_timer.isActive()) 356 m_timer.stop(); 357 358 if (!error) 359 { 360 QFile dest_file(m_dest_file); 361 if (dest_file.exists()) 362 dest_file.remove(); 363 364 if (dest_file.open(QIODevice::WriteOnly)) 365 { 366 const QByteArray &data = m_data_buffer.data(); 367 qint64 size = dest_file.write(data); 368 if (size != data.size()) 369 { 370 errorMsg = tr("Error writing data to file %1.") 371 .arg(m_dest_file); 372 m_error_state = besError; 373 } 374 } 375 else 376 { 377 errorMsg = tr("Error: file error '%1' for file %2"). 378 arg(dest_file.errorString()).arg(m_dest_file); 379 m_error_state = besError; 380 } 381 } 382 383 emit SigFinished(m_error_state, errorMsg, m_item); 384 } 385 } 386 387 private: 388 Metadata *m_item; 389 QHttp m_http; 390 QBuffer m_data_buffer; 391 QString m_dest_file; 392 int m_id; 393 QTimer m_timer; 394 QUrl m_url; 395 BannerDownloadErrorState m_error_state; 396 }; 397 291 398 /** \class ExecuteExternalCommand 292 399 * 293 400 * \brief Base class for executing an external script or other process, must … … 467 574 void Run(QString title, Metadata *item) 468 575 { 469 576 m_item = item; 577 int m_season, m_episode; 578 QString cmd; 579 m_season = m_item->GetSeason(); 580 m_episode = m_item->GetEpisode(); 470 581 471 QString def_cmd = QDir::cleanPath(QString("%1/%2") 582 if (m_season > 0 || m_episode > 0) 583 { 584 const QString def_cmd = QDir::cleanPath(QString("%1/%2") 472 585 .arg(GetShareDir()) 586 .arg("mythvideo/scripts/ttvdb.py -M")); 587 cmd = gContext->GetSetting("mythvideo.TVListCommandLine", 588 def_cmd); 589 } 590 else 591 { 592 QString def_cmd = QDir::cleanPath(QString("%1/%2") 593 .arg(GetShareDir()) 473 594 .arg("mythvideo/scripts/tmdb.pl -M")); 474 595 475 QStringcmd = gContext->GetSetting("MovieListCommandLine", def_cmd);476 477 QStringList args;478 args += title;479 StartRun(cmd, args, "Video Search");596 cmd = gContext->GetSetting("MovieListCommandLine", def_cmd); 597 } 598 QStringList args; 599 args += title; 600 StartRun(cmd, args, "Video Search"); 480 601 } 481 602 482 603 private: … … 505 626 Metadata *m_item; 506 627 }; 507 628 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 508 677 /** \class VideoUIDSearch 509 678 * 510 679 * \brief Execute the command to do video searches based on their ID. … … 525 694 void Run(QString video_uid, Metadata *item) 526 695 { 527 696 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(); 529 701 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") 531 705 .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()) 532 718 .arg("mythvideo/scripts/tmdb.pl -D")); 533 const QString cmd = gContext->GetSetting("MovieDataCommandLine",719 const QString cmd = gContext->GetSetting("MovieDataCommandLine", 534 720 def_cmd); 535 536 StartRun(cmd, QStringList(video_uid), "Video Data Query");721 StartRun(cmd, QStringList(video_uid), "Video Data Query"); 722 } 537 723 } 538 724 539 725 private: … … 570 756 void Run(QString video_uid, Metadata *item) 571 757 { 572 758 m_item = item; 759 int m_season, m_episode; 760 m_season = m_item->GetSeason(); 761 m_episode = m_item->GetEpisode(); 573 762 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 = 575 778 QDir::cleanPath(QString("%1/%2") 576 779 .arg(GetShareDir()) 577 780 .arg("mythvideo/scripts/tmdb.pl -P")); 578 const QString cmd = gContext->GetSetting("MoviePosterCommandLine",781 const QString cmd = gContext->GetSetting("MoviePosterCommandLine", 579 782 default_cmd); 580 StartRun(cmd, QStringList(video_uid), "Poster Query"); 783 784 StartRun(cmd, QStringList(video_uid), "Poster Query"); 785 } 581 786 } 582 787 583 788 private: … … 627 832 void Run(QString video_uid, Metadata *item) 628 833 { 629 834 m_item = item; 835 int m_season, m_episode; 836 m_season = m_item->GetSeason(); 837 m_episode = m_item->GetEpisode(); 630 838 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 = 632 854 QDir::cleanPath(QString("%1/%2") 633 855 .arg(GetShareDir()) 634 856 .arg("mythvideo/scripts/tmdb.pl -B")); 635 const QString cmd = gContext->GetSetting("MovieFanartCommandLine",857 const QString cmd = gContext->GetSetting("MovieFanartCommandLine", 636 858 default_cmd); 637 StartRun(cmd, QStringList(video_uid), "Fanart Query"); 859 StartRun(cmd, QStringList(video_uid), "Fanart Query"); 860 } 638 861 } 639 862 640 863 private: … … 665 888 Metadata *m_item; 666 889 }; 667 890 891 /** \class VideoBannerSearch 892 * 893 * \brief Execute external video banner command. 894 * 895 */ 896 class VideoBannerSearch : public ExecuteExternalCommand 897 { 898 Q_OBJECT 668 899 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 669 953 class ParentalLevelNotifyContainer : public QObject 670 954 { 671 955 Q_OBJECT … … 790 1074 } 791 1075 }; 792 1076 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) 795 1080 { 796 1081 QStringList search_dirs(in_dirs); 797 1082 … … 821 1106 ext != image_exts.end(); ++ext) 822 1107 { 823 1108 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); 824 1113 sfn += fntm.arg(*dir).arg(base_name).arg(*ext); 825 1114 sfn += fntm.arg(*dir).arg(video_uid).arg(*ext); 826 1115 … … 829 1118 { 830 1119 if (QFile::exists(*i)) 831 1120 { 832 poster= *i;1121 image = *i; 833 1122 return true; 834 1123 } 835 1124 } … … 946 1235 QString coverfile; 947 1236 if ((metadata->IsHostSet() 948 1237 && !metadata->GetCoverFile().startsWith("/")) 949 && (metadata->GetCoverFile() != "No Cover")) 1238 && (metadata->GetCoverFile() != "No Cover") 1239 && !metadata->GetCoverFile().isEmpty()) 950 1240 { 951 1241 coverfile = GenRemoteFileURL("Coverart", metadata->GetHost(), 952 1242 metadata->GetCoverFile()); … … 962 1252 tmp["coverfile"] = coverfile; 963 1253 964 1254 QString screenshotfile; 965 if (metadata->IsHostSet() && 966 !metadata->GetScreenshot().startsWith("/"))1255 if (metadata->IsHostSet() && !metadata->GetScreenshot().startsWith("/") 1256 && !metadata->GetScreenshot().isEmpty()) 967 1257 { 968 1258 screenshotfile = GenRemoteFileURL("Screenshots", 969 1259 metadata->GetHost(), metadata->GetScreenshot()); … … 979 1269 tmp["screenshotfile"] = screenshotfile; 980 1270 981 1271 QString bannerfile; 982 if (metadata->IsHostSet() && !metadata->GetBanner().startsWith("/")) 1272 if (metadata->IsHostSet() && !metadata->GetBanner().startsWith("/") 1273 && !metadata->GetBanner().isEmpty()) 983 1274 { 984 1275 bannerfile = GenRemoteFileURL("Banners", metadata->GetHost(), 985 1276 metadata->GetBanner()); … … 995 1286 tmp["bannerfile"] = bannerfile; 996 1287 997 1288 QString fanartfile; 998 if (metadata->IsHostSet() && !metadata->GetFanart().startsWith("/")) 1289 if (metadata->IsHostSet() && !metadata->GetFanart().startsWith("/") 1290 && !metadata->GetFanart().isEmpty()) 999 1291 { 1000 1292 fanartfile = GenRemoteFileURL("Fanart", metadata->GetHost(), 1001 1293 metadata->GetFanart()); … … 1016 1308 1017 1309 tmp["filename"] = metadata->GetFilename(); 1018 1310 tmp["title"] = metadata->GetTitle(); 1311 tmp["subtitle"] = metadata->GetSubtitle(); 1019 1312 tmp["director"] = metadata->GetDirector(); 1020 1313 tmp["plot"] = metadata->GetPlot(); 1021 1314 tmp["genres"] = GetDisplayGenres(*metadata); … … 1025 1318 tmp["length"] = GetDisplayLength(metadata->GetLength()); 1026 1319 tmp["year"] = GetDisplayYear(metadata->GetYear()); 1027 1320 tmp["userrating"] = GetDisplayUserRating(metadata->GetUserRating()); 1321 tmp["season"] = GetDisplaySeasonEpisode(metadata->GetSeason(), 1); 1322 tmp["episode"] = GetDisplaySeasonEpisode(metadata->GetEpisode(), 1); 1028 1323 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 1029 1336 tmp["userratingstate"] = 1030 1337 QString::number((int)(metadata->GetUserRating())); 1031 1338 tmp["videolevel"] = ParentalLevelToState(metadata->GetShowLevel()); … … 1075 1382 h.handleText("player"); 1076 1383 h.handleText("filename"); 1077 1384 h.handleText("title"); 1385 h.handleText("subtitle"); 1078 1386 h.handleText("director"); 1079 1387 h.handleText("plot"); 1080 1388 h.handleText("genres"); … … 1082 1390 h.handleText("cast"); 1083 1391 h.handleText("rating"); 1084 1392 h.handleText("length"); 1393 h.handleText("season"); 1394 h.handleText("s##e##"); 1395 h.handleText("##x##"); 1396 h.handleText("episode"); 1085 1397 h.handleText("year"); 1086 1398 h.handleText("userrating"); 1087 1399 … … 1254 1566 1255 1567 m_artDir = gContext->GetSetting("VideoArtworkDir"); 1256 1568 m_fanDir = gContext->GetSetting("mythvideo.fanartDir"); 1569 m_banDir = gContext->GetSetting("mythvideo.bannerDir"); 1257 1570 } 1258 1571 1259 1572 ~VideoDialogPrivate() … … 1322 1635 } 1323 1636 } 1324 1637 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 1325 1654 void StopAllRunningCoverDownloads() 1326 1655 { 1327 1656 cover_download_list tmp(m_running_downloads); … … 1336 1665 (*p)->Stop(); 1337 1666 } 1338 1667 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 } 1339 1674 1340 1675 public: 1341 1676 typedef std::set<CoverDownloadProxy *> cover_download_list; 1342 1677 cover_download_list m_running_downloads; 1343 1678 typedef std::set<FanartDownloadProxy *> fanart_download_list; 1344 1679 fanart_download_list m_running_fdownloads; 1680 typedef std::set<BannerDownloadProxy *> banner_download_list; 1681 banner_download_list m_running_bdownloads; 1345 1682 ParentalLevelNotifyContainer m_parentalLevel; 1346 1683 bool m_switchingLayout; 1347 1684 … … 1364 1701 1365 1702 QString m_artDir; 1366 1703 QString m_fanDir; 1704 QString m_banDir; 1367 1705 VideoScanner *m_scanner; 1368 1706 1369 1707 QString m_lastTreeNodePath; … … 2021 2359 if (!m_menuPopup) 2022 2360 VideoMenu(); 2023 2361 } 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(); 2024 2371 else if (action == "ESCAPE") 2025 2372 { 2026 2373 if (m_d->m_type != DLG_TREE … … 2080 2427 m_popupStack->AddScreen(okPopup); 2081 2428 } 2082 2429 2430 void 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 2452 void 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 2083 2486 bool VideoDialog::goBack() 2084 2487 { 2085 2488 bool handled = false; … … 2275 2678 2276 2679 m_menuPopup->AddButton(tr("Edit Metadata"), SLOT(EditMetadata())); 2277 2680 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())); 2278 2685 m_menuPopup->AddButton(tr("Manually Enter Video #"), 2279 2686 SLOT(ManualVideoUID())); 2280 2687 m_menuPopup->AddButton(tr("Manually Enter Video Title"), … … 2582 2989 metadata); 2583 2990 } 2584 2991 2992 void VideoDialog::TitleSubtitleSearch() 2993 { 2994 Metadata *metadata = GetMetadata(GetItemCurrent()); 2995 2996 if (metadata) 2997 StartVideoSearchByTitleSubtitle(metadata->GetTitle(), 2998 metadata->GetSubtitle(), metadata); 2999 } 3000 3001 void 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 2585 3021 void VideoDialog::ToggleBrowseable() 2586 3022 { 2587 3023 Metadata *metadata = GetMetadata(GetItemCurrent()); … … 2625 3061 } 2626 3062 } 2627 3063 3064 void 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 2628 3076 void VideoDialog::OnParentalChange(int amount) 2629 3077 { 2630 3078 Metadata *metadata = GetMetadata(GetItemCurrent()); … … 2758 3206 metadata->Reset(); 2759 3207 2760 3208 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())) 2763 3212 { 2764 3213 metadata->SetCoverFile(cover_file); 2765 3214 } 2766 3215 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 2767 3232 metadata->UpdateDatabase(); 2768 3233 2769 3234 UpdateItem(item); … … 2778 3243 //createBusyDialog(QObject::tr("Fetching poster for %1 (%2)") 2779 3244 // .arg(metadata->InetRef()) 2780 3245 // .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; 2783 3248 2784 3249 QString cover_file; 2785 3250 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())) 2788 3254 { 2789 3255 metadata->SetCoverFile(cover_file); 2790 3256 OnVideoPosterSetDone(metadata); … … 2799 3265 vps->Run(metadata->GetInetRef(), metadata); 2800 3266 } 2801 3267 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 2802 3281 if (metadata->GetFanart().isEmpty()) 2803 3282 { 2804 3283 // Obtain video fanart … … 2807 3286 SLOT(OnFanartURL(QString, Metadata *))); 2808 3287 vfs->Run(metadata->GetInetRef(), metadata); 2809 3288 } 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 } 2810 3312 } 2811 3313 2812 3314 void VideoDialog::OnPosterURL(QString uri, Metadata *metadata) … … 2839 3341 QUrl url(uri); 2840 3342 2841 3343 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 2844 3359 VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...") 2845 3360 .arg(url.toString()).arg(dest_file)); 2846 3361 … … 2933 3448 QUrl url(uri); 2934 3449 2935 3450 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 2938 3466 VERBOSE(VB_IMPORTANT, QString("Copying '%1' -> '%2'...") 2939 3467 .arg(url.toString()).arg(dest_file)); 2940 3468 … … 2997 3525 UpdateItem(GetItemCurrent()); 2998 3526 } 2999 3527 3528 void 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 3598 void 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 3622 void 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 3000 3635 void VideoDialog::StartVideoSearchByUID(QString video_uid, Metadata *metadata) 3001 3636 { 3002 3637 // Starting the busy dialog here triggers a bizarre segfault … … 3027 3662 { 3028 3663 data[(*p).section(':', 0, 0)] = (*p).section(':', 1); 3029 3664 } 3030 // set known values 3665 // Set known values, but always set Title. 3666 // Allows for partial fill. Reset Metadata for full fill. 3667 3031 3668 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"]); 3038 3670 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 3039 3688 m_d->AutomaticParentalAdjustment(metadata); 3040 3689 3041 3690 // Cast … … 3167 3816 } 3168 3817 } 3169 3818 3819 void 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 3864 void 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 3878 void 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 3170 3927 void VideoDialog::doVideoScan() 3171 3928 { 3172 3929 if (!m_d->m_scanner) -
mythplugins/mythvideo/mythvideo/videolist.cpp
826 826 for (meta_dir_node::const_entry_iterator entry = src->entries_begin(); 827 827 entry != src->entries_end(); ++entry) 828 828 { 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 } 830 850 } 831 851 } 832 852 … … 1267 1287 QString title = qfi.completeBaseName(); 1268 1288 if (m_infer_title) 1269 1289 { 1270 QString tmptitle(Metadata::FilenameTo Title(file_string));1290 QString tmptitle(Metadata::FilenameToMeta(file_string, 1)); 1271 1291 if (tmptitle.length()) 1272 1292 title = tmptitle; 1273 1293 } -
mythplugins/mythvideo/mythvideo/videoscan.cpp
267 267 VIDEO_SCREENSHOT_DEFAULT, 268 268 VIDEO_BANNER_DEFAULT, 269 269 VIDEO_FANART_DEFAULT, 270 Metadata::FilenameToTitle(p->first), 270 Metadata::FilenameToMeta(p->first, 1), 271 Metadata::FilenameToMeta(p->first, 4), 271 272 VIDEO_YEAR_DEFAULT, 272 273 VIDEO_INETREF_DEFAULT, VIDEO_DIRECTOR_DEFAULT, 273 VIDEO_PLOT_DEFAULT, 0.0, VIDEO_RATING_DEFAULT, 274 0, 0, ParentalLevel::plLowest); 274 VIDEO_PLOT_DEFAULT, 0.0, VIDEO_RATING_DEFAULT, 0, 275 Metadata::FilenameToMeta(p->first, 2).toInt(), 276 Metadata::FilenameToMeta(p->first, 3).toInt(), 277 0, ParentalLevel::plLowest); 275 278 276 279 VERBOSE(VB_GENERAL, QString("Adding : %1 : %2") 277 280 .arg(newFile.GetHost()).arg(newFile.GetFilename())); -
mythplugins/mythvideo/mythvideo/videofilter.cpp
353 353 ret = lhs_key < rhs_key; 354 354 break; 355 355 } 356 case kOrderBySeasonEp: 357 { 358 if ((lhs.GetSeason() == rhs.GetSeason()) 359 && (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 } 356 388 case kOrderByYearDescending: 357 389 { 358 390 ret = lhs.GetYear() > rhs.GetYear(); … … 649 681 // Order by 650 682 new MythUIButtonListItem(m_orderbyList, QObject::tr("Title"), 651 683 VideoFilterSettings::kOrderByTitle); 684 new MythUIButtonListItem(m_orderbyList, QObject::tr("Season/Episode"), 685 VideoFilterSettings::kOrderBySeasonEp); 652 686 new MythUIButtonListItem(m_orderbyList, QObject::tr("Year"), 653 687 VideoFilterSettings::kOrderByYearDescending); 654 688 new MythUIButtonListItem(m_orderbyList, QObject::tr("User Rating"), -
mythplugins/mythvideo/mythvideo/metadata.h
13 13 14 14 enum { VIDEO_YEAR_DEFAULT = 1895 }; 15 15 16 const QString VIDEO_SUBTITLE_DEFAULT = ""; 17 16 18 struct SortData; 17 19 18 20 class Metadata … … 44 46 45 47 public: 46 48 static SortKey GenerateDefaultSortKey(const Metadata &m, bool ignore_case); 47 static QString FilenameTo Title(const QString &file_name);49 static QString FilenameToMeta(const QString &file_name, int position); 48 50 static QString TrimTitle(const QString &title, bool ignore_case); 49 51 50 52 public: … … 55 57 const QString &banner = QString(), 56 58 const QString &fanart = QString(), 57 59 const QString &title = QString(), 60 const QString &subtitle = QString(), 58 61 int year = VIDEO_YEAR_DEFAULT, 59 62 const QString &inetref = QString(), 60 63 const QString &director = QString(), … … 62 65 float userrating = 0.0, 63 66 const QString &rating = QString(), 64 67 int length = 0, 68 int season = 0, 69 int episode = 0, 65 70 int id = 0, 66 71 ParentalLevel::Level showlevel = ParentalLevel::plLowest, 67 72 int categoryID = 0, … … 89 94 const QString &GetTitle() const; 90 95 void SetTitle(const QString& title); 91 96 97 const QString &GetSubtitle() const; 98 void SetSubtitle(const QString &subtitle); 99 92 100 int GetYear() const; 93 101 void SetYear(int year); 94 102 … … 110 118 int GetLength() const; 111 119 void SetLength(int length); 112 120 121 int GetSeason() const; 122 void SetSeason(int season); 123 124 int GetEpisode() const; 125 void SetEpisode(int episode); 126 113 127 unsigned int GetID() const; 114 128 void SetID(int id); 115 129 -
mythplugins/mythvideo/mythvideo/editmetadata.cpp
12 12 #include <mythtv/libmythui/mythuitextedit.h> 13 13 #include <mythtv/libmythui/mythuibutton.h> 14 14 #include <mythtv/libmythui/mythuicheckbox.h> 15 #include <mythtv/libmythui/mythuispinbox.h> 15 16 16 17 #include "globals.h" 17 18 #include "dbaccess.h" … … 22 23 EditMetadataDialog::EditMetadataDialog(MythScreenStack *lparent, 23 24 QString lname, Metadata *source_metadata, 24 25 const MetadataListManager &cache) : MythScreenType(lparent, lname), 25 m_origMetadata(source_metadata), m_titleEdit(0), m_playerEdit(0), 26 m_categoryList(0), m_levelList(0), m_childList(0), m_browseCheck(0), 27 m_coverartButton(0), m_coverartText(0), 26 m_origMetadata(source_metadata), m_titleEdit(0), m_subtitleEdit(0), 27 m_playerEdit(0), m_seasonSpin(0), m_episodeSpin(0), 28 m_categoryList(0), m_levelList(0), m_childList(0), 29 m_browseCheck(0), m_coverartButton(0), m_coverartText(0), 28 30 m_screenshotButton(0), m_screenshotText(0), 29 31 m_bannerButton(0), m_bannerText(0), 30 32 m_fanartButton(0), m_fanartText(0), … … 47 49 48 50 bool err = false; 49 51 UIUtilE::Assign(this, m_titleEdit, "title_edit", &err); 52 UIUtilE::Assign(this, m_subtitleEdit, "subtitle_edit", &err); 50 53 UIUtilE::Assign(this, m_playerEdit, "player_edit", &err); 51 54 55 UIUtilE::Assign(this, m_seasonSpin, "season", &err); 56 UIUtilE::Assign(this, m_episodeSpin, "episode", &err); 57 52 58 UIUtilE::Assign(this, m_coverartText, "coverart_text", &err); 53 59 UIUtilE::Assign(this, m_screenshotText, "screenshot_text", &err); 54 60 UIUtilE::Assign(this, m_bannerText, "banner_text", &err); … … 79 85 VERBOSE(VB_IMPORTANT, "Failed to build a focuslist."); 80 86 81 87 connect(m_titleEdit, SIGNAL(valueChanged()), SLOT(SetTitle())); 88 connect(m_subtitleEdit, SIGNAL(valueChanged()), SLOT(SetSubtitle())); 82 89 connect(m_playerEdit, SIGNAL(valueChanged()), SLOT(SetPlayer())); 83 90 91 connect(m_seasonSpin, SIGNAL(LosingFocus()), SLOT(SetSeason())); 92 connect(m_episodeSpin, SIGNAL(LosingFocus()), SLOT(SetEpisode())); 93 84 94 connect(m_doneButton, SIGNAL(Clicked()), SLOT(SaveAndExit())); 85 95 connect(m_coverartButton, SIGNAL(Clicked()), SLOT(FindCoverArt())); 86 96 connect(m_bannerButton, SIGNAL(Clicked()), SLOT(FindBanner())); … … 154 164 void EditMetadataDialog::fillWidgets() 155 165 { 156 166 m_titleEdit->SetText(m_workingMetadata->GetTitle()); 167 m_subtitleEdit->SetText(m_workingMetadata->GetSubtitle()); 157 168 169 m_seasonSpin->SetRange(0,100,1); 170 m_seasonSpin->SetValue(m_workingMetadata->GetSeason()); 171 m_episodeSpin->SetRange(0,999,1); 172 m_episodeSpin->SetValue(m_workingMetadata->GetEpisode()); 173 158 174 MythUIButtonListItem *button = 159 175 new MythUIButtonListItem(m_categoryList, VIDEO_CATEGORY_UNKNOWN); 160 176 const VideoCategory::entry_list &vcl = … … 312 328 m_workingMetadata->SetTitle(m_titleEdit->GetText()); 313 329 } 314 330 331 void EditMetadataDialog::SetSubtitle() 332 { 333 m_workingMetadata->SetSubtitle(m_subtitleEdit->GetText()); 334 } 335 315 336 void EditMetadataDialog::SetCategory(MythUIButtonListItem *item) 316 337 { 317 338 m_workingMetadata->SetCategoryID(item->GetData().toInt()); 318 339 } 319 340 341 void EditMetadataDialog::SetSeason() 342 { 343 m_workingMetadata->SetSeason(m_seasonSpin->GetIntValue()); 344 } 345 346 void EditMetadataDialog::SetEpisode() 347 { 348 m_workingMetadata->SetEpisode(m_episodeSpin->GetIntValue()); 349 } 350 320 351 void EditMetadataDialog::SetPlayer() 321 352 { 322 353 m_workingMetadata->SetPlayCommand(m_playerEdit->GetText()); -
mythplugins/mythvideo/mythvideo/playercommand.cpp
75 75 { 76 76 private: 77 77 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) : 80 81 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) 82 84 { 83 85 } 84 86 85 87 public: 86 88 static VideoPlayHandleMedia *Create(const QString &handler, 87 89 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) 89 93 { 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); 92 96 } 93 97 94 98 bool Play() const 95 99 { 96 100 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); 98 103 } 99 104 100 105 QString GetCommandDisplayName() const … … 112 117 QString m_mrl; 113 118 QString m_plot; 114 119 QString m_title; 120 QString m_subtitle; 115 121 QString m_director; 122 int m_season; 123 int m_episode; 116 124 int m_length; 117 125 QString m_year; 118 126 }; … … 200 208 if (play_command.length()) 201 209 { 202 210 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(), 205 214 QString::number(item->GetYear())); 206 215 } 207 216 else … … 237 246 play_command = "Internal"; 238 247 239 248 QString plot; 240 QString title = Metadata::FilenameToTitle(filename); 249 QString title = Metadata::FilenameToMeta(filename, 1); 250 QString subtitle = Metadata::FilenameToMeta(filename, 4); 241 251 QString director; 252 int season = 0; 253 int episode = 0; 242 254 int length = 0; 243 255 QString year = QString::number(VIDEO_YEAR_DEFAULT); 244 256 … … 246 258 { 247 259 plot = extraData->GetPlot(); 248 260 title = extraData->GetTitle(); 261 subtitle = extraData->GetSubtitle(); 249 262 director = extraData->GetDirector(); 263 season = extraData->GetSeason(); 264 episode = extraData->GetEpisode(); 250 265 length = extraData->GetLength(); 251 266 year = QString::number(extraData->GetYear()); 252 267 } 253 268 254 AddPlayer(play_command, filename, plot, title, director, length, year); 269 AddPlayer(play_command, filename, plot, title, subtitle, director, 270 season, episode, length, year); 255 271 } 256 272 257 273 void ClearPlayerList() … … 282 298 283 299 private: 284 300 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) 287 304 { 288 305 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)); 290 308 m_player_procs.push_back(VideoPlayMythSystem::Create(player, filename)); 291 309 } 292 310 -
mythplugins/mythvideo/mythvideo/videoutils.h
33 33 34 34 QString GetDisplayUserRating(float userrating); 35 35 QString GetDisplayLength(int length); 36 QString GetDisplaySeasonEpisode(int seasEp, int digits); 36 37 QString GetDisplayBrowse(bool browse); 37 38 QString GetDisplayYear(int year); 38 39 QString GetDisplayRating(const QString &rating); -
mythtv/themes/Terra/video-ui.xml
565 565 </imagetype> 566 566 567 567 <textarea name="title" from="basetextarea"> 568 <area>48,78, 980,35</area>568 <area>48,78,590,35</area> 569 569 <font>baselarge</font> 570 570 </textarea> 571 571 572 <textarea name="subtitle" from="basetextarea"> 573 <area>600,78,590,35</area> 574 <align>right</align> 575 <font>baselarge</font> 576 </textarea> 577 572 578 <statetype name="userratingstate" from="baserating"> 573 579 <position>1193,72</position> 574 580 </statetype> … … 583 589 <area>48,284,290,30</area> 584 590 </textarea> 585 591 592 <textarea name="##x##" from="basetextarea"> 593 <area>540,284,200,30</area> 594 <align>center</align> 595 </textarea> 596 586 597 <textarea name="director" from="basetextarea"> 587 598 <area>430,284,800,30</area> 588 599 <align>right</align> … … 885 896 <!-- Labels --> 886 897 887 898 <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> 890 901 <align>right,top</align> 891 902 </textarea> 892 903 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 893 922 <textarea name="category_text" from="title_text"> 894 <position>50,197</position> 923 <area>520,232,150,40</area> 924 <align>right</align> 895 925 <value>Category:</value> 896 926 </textarea> 897 927 898 928 <textarea name="level_text" from="title_text"> 899 <position>50,247</position> 929 <area>120,232,200,40</area> 930 <align>right</align> 900 931 <value>Parental Control:</value> 901 932 </textarea> 902 933 903 934 <textarea name="child_text" from="title_text"> 904 <position>50,292</position> 935 <area>120,277,200,40</area> 936 <align>right</align> 905 937 <value>File to Always Play Next:</value> 906 938 </textarea> 907 939 908 940 <textarea name="browse_text" from="title_text"> 909 <position>50,337</position> 941 <area>570,277,280,40</area> 942 <align>left</align> 910 943 <value>Include while Browsing:</value> 911 944 </textarea> 912 945 913 946 <textarea name="coverart_text_label" from="title_text"> 914 <position> 50,375</position>947 <position>200,328</position> 915 948 <value>Cover Art:</value> 916 949 </textarea> 917 950 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 918 966 <textarea name="trailer_text_label" from="title_text"> 919 <position> 50,405</position>967 <position>200,447</position> 920 968 <value>Trailer:</value> 921 969 </textarea> 922 970 923 971 <textarea name="player_text" from="title_text"> 924 <position> 50,445</position>972 <position>150,487</position> 925 973 <value>Unique Player Command:</value> 926 974 </textarea> 927 975 928 976 <!-- Widgets --> 929 977 930 978 <textedit name="title_edit" from="basetextedit"> 931 <position> 310,125</position>979 <position>410,70</position> 932 980 </textedit> 933 981 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> 937 985 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 938 994 <buttonlist name="level_select" from="baseselector"> 939 <position>3 10,240</position>995 <position>330,225</position> 940 996 </buttonlist> 941 997 998 <buttonlist name="category_select" from="baseselector"> 999 <position>680,225</position> 1000 </buttonlist> 1001 942 1002 <buttonlist name="child_select" from="baseselector"> 943 <position>3 10,285</position>1003 <position>330,270</position> 944 1004 </buttonlist> 945 1005 946 1006 <checkbox name="browse_check" from="basecheckbox"> 947 <position> 310,335</position>1007 <position>835,275</position> 948 1008 </checkbox> 949 1009 950 1010 <button name="coverart_button"> 951 <area> 310,370,32,32</area>1011 <area>460,323,32,32</area> 952 1012 <statetype name="buttonstate"> 953 1013 <state name="active"> 954 1014 <imagetype name="background"> … … 970 1030 </button> 971 1031 972 1032 <textarea name="coverart_text" from="basetextarea"> 973 <area> 350,375,250,40</area>1033 <area>500,328,250,40</area> 974 1034 <value>/path/to/the/thing.jpg</value> 975 1035 </textarea> 976 1036 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 977 1118 <button name="trailer_button"> 978 <area> 310,400,32,32</area>1119 <area>460,442,32,32</area> 979 1120 <statetype name="buttonstate"> 980 1121 <state name="active"> 981 1122 <imagetype name="background"> … … 997 1138 </button> 998 1139 999 1140 <textarea name="trailer_text" from="basetextarea"> 1000 <area> 350,405,250,40</area>1141 <area>500,447,250,40</area> 1001 1142 <value>/path/to/the/thing.jpg</value> 1002 1143 </textarea> 1003 1144 1145 1004 1146 <textedit name="player_edit" from="basetextedit"> 1005 <position> 310,435</position>1147 <position>410,477</position> 1006 1148 </textedit> 1007 1149 1008 1150 <button name="done_button" from="basebutton"> 1009 <position>310,505</position> 1151 <position>510,537</position> 1152 <value>Done</value> 1010 1153 </button> 1011 1154 1012 1155 </window> -
mythtv/libs/libmythui/mythmainwindow.cpp
1298 1298 1299 1299 bool MythMainWindow::HandleMedia(const QString &handler, const QString &mrl, 1300 1300 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, 1302 1304 const QString &year) 1303 1305 { 1304 1306 QString lhandler(handler); … … 1308 1310 // Let's see if we have a plugin that matches the handler name... 1309 1311 if (d->mediaPluginMap.count(lhandler)) 1310 1312 { 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); 1313 1316 return true; 1314 1317 } 1315 1318 -
mythtv/libs/libmythui/mythmainwindow.h
17 17 #define REG_JUMPEX(a, b, c, d, e) GetMythMainWindow()->RegisterJump(a, b, c, d, e) 18 18 #define REG_MEDIAPLAYER(a,b,c) GetMythMainWindow()->RegisterMediaPlugin(a, b, c) 19 19 20 typedef int (*MediaPlayCallback)(const QString &, const QString &, const QString &, const QString &, int, const QString &);20 typedef int (*MediaPlayCallback)(const QString &, const QString &, const QString &, const QString &, const QString &, int, int, int, const QString &); 21 21 22 22 class MythMainWindowPrivate; 23 23 … … 63 63 64 64 bool HandleMedia(const QString& handler, const QString& mrl, 65 65 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, 67 68 const QString& year="1895"); 68 69 69 70 void JumpTo(const QString &destination, bool pop = true); -
mythtv/programs/mythfrontend/main.cpp
672 672 } 673 673 674 674 int 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, 676 677 int lenMins, const QString &year) 677 678 { 678 679 int res = -1; … … 711 712 pginfo->pathname = QString("dvd:%1").arg(mrl); 712 713 } 713 714 714 pginfo->description = plot;715 716 715 if (director.length()) 717 pginfo-> subtitle = QString( "%1: %2" )716 pginfo->description = QString( "%1: %2. " ) 718 717 .arg(QObject::tr("Directed By")).arg(director); 719 718 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 720 735 pginfo->title = title; 721 736 722 737 if (pginfo->pathname.startsWith("dvd:"))