Ticket #6158: PBBMVExport.4.diff
File PBBMVExport.4.diff, 19.3 KB (added by , 17 years ago) |
---|
-
mythtv/programs/mythfrontend/playbackbox.cpp
20 20 #include "mythdirs.h" 21 21 #include "mythcontext.h" 22 22 #include "mythdbcon.h" 23 #include "mythdb.h" 23 24 #include "mythverbose.h" 24 25 #include "programinfo.h" 25 26 #include "scheduledrecording.h" … … 42 43 #define LOC QString("PlaybackBox: ") 43 44 #define LOC_ERR QString("PlaybackBox Error: ") 44 45 46 QString customExportFile = NULL; 47 QString customExportDir = NULL; 48 45 49 #define REC_CAN_BE_DELETED(rec) \ 46 50 ((((rec)->programflags & FL_INUSEPLAYING) == 0) && \ 47 51 ((((rec)->programflags & FL_INUSERECORDING) == 0) || \ … … 1813 1817 RemoteStopRecording(rec); 1814 1818 } 1815 1819 1820 void PlaybackBox::mvexport(ProgramInfo *rec) 1821 { 1822 1823 // User Rating Adjustment 1824 QString exportRating = QString::number((int)((rec->stars * 10.0) + 0.5)); 1825 1826 // Stuff necessary to perform the copy command 1827 1828 QString copyFrom = rec->GetPlaybackURL(false, true); 1829 QString baseMVDir = gContext->GetSetting("VideoStartupDir"); 1830 QString MVFileFormat; 1831 QString MVDirFormat; 1832 QString copyToDir; 1833 QString copyToFile; 1834 QString extension; 1835 1836 // Check the original extension 1837 1838 QRegExp rx(".*\\.(\\w+)$"); 1839 int pos = rx.indexIn(copyFrom); 1840 if (pos > -1) 1841 { 1842 extension = rx.cap(1); 1843 } 1844 else 1845 { 1846 extension = ""; 1847 } 1848 1849 // If a custom export string is used, use it 1850 1851 if (customExportFile.isEmpty()) 1852 { 1853 MVDirFormat = gContext->GetSetting("TVExportDirFormat", 1854 "Television/%TITLE%/"); 1855 MVFileFormat = gContext->GetSetting("TVExportFileFormat", 1856 "%TITLE% - %SUBTITLE%"); 1857 } 1858 else 1859 { 1860 MVDirFormat = customExportDir; 1861 MVFileFormat = customExportFile; 1862 } 1863 1864 // Replace Variables with actual values 1865 1866 if (!MVDirFormat.isEmpty()) 1867 { 1868 MVDirFormat.replace(QRegExp("%FILE%"), rec->GetRecordBasename(true)); 1869 MVDirFormat.replace(QRegExp("%TITLE%"), rec->title); 1870 MVDirFormat.replace(QRegExp("%SUBTITLE%"), rec->subtitle); 1871 MVDirFormat.replace(QRegExp("%DESCRIPTION%"), rec->description); 1872 MVDirFormat.replace(QRegExp("%HOSTNAME%"), rec->hostname); 1873 MVDirFormat.replace(QRegExp("%CATEGORY%"), rec->category); 1874 MVDirFormat.replace(QRegExp("%RECGROUP%"), rec->recgroup); 1875 MVDirFormat.replace(QRegExp("%PLAYGROUP%"), rec->playgroup); 1876 MVDirFormat.replace(QRegExp("%CHANID%"), rec->chanid); 1877 MVDirFormat.replace(QRegExp("%STARTTIME%"), 1878 rec->recstartts.toString("yyyyMMddhhmmss")); 1879 MVDirFormat.replace(QRegExp("%ENDTIME%"), 1880 rec->recendts.toString("yyyyMMddhhmmss")); 1881 MVDirFormat.replace(QRegExp("%STARTTIMEISO%"), 1882 rec->recstartts.toString(Qt::ISODate)); 1883 MVDirFormat.replace(QRegExp("%ENDTIMEISO%"), 1884 rec->recendts.toString(Qt::ISODate)); 1885 MVDirFormat.replace(QRegExp("%PROGSTART%"), 1886 rec->startts.toString("yyyyMMddhhmmss")); 1887 MVDirFormat.replace(QRegExp("%PROGEND%"), 1888 rec->endts.toString("yyyyMMddhhmmss")); 1889 MVDirFormat.replace(QRegExp("%PROGSTARTISO%"), 1890 rec->startts.toString(Qt::ISODate)); 1891 MVDirFormat.replace(QRegExp("%PROGENDISO%"), 1892 rec->endts.toString(Qt::ISODate)); 1893 } 1894 if (!MVFileFormat.isEmpty()) 1895 { 1896 MVFileFormat.replace(QRegExp("%FILE%"), rec->GetRecordBasename(true)); 1897 MVFileFormat.replace(QRegExp("%TITLE%"), rec->title); 1898 MVFileFormat.replace(QRegExp("%SUBTITLE%"), rec->subtitle); 1899 MVFileFormat.replace(QRegExp("%DESCRIPTION%"), rec->description); 1900 MVFileFormat.replace(QRegExp("%HOSTNAME%"), rec->hostname); 1901 MVFileFormat.replace(QRegExp("%CATEGORY%"), rec->category); 1902 MVFileFormat.replace(QRegExp("%RECGROUP%"), rec->recgroup); 1903 MVFileFormat.replace(QRegExp("%PLAYGROUP%"), rec->playgroup); 1904 MVFileFormat.replace(QRegExp("%CHANID%"), rec->chanid); 1905 MVFileFormat.replace(QRegExp("%STARTTIME%"), 1906 rec->recstartts.toString("yyyyMMddhhmmss")); 1907 MVFileFormat.replace(QRegExp("%ENDTIME%"), 1908 rec->recendts.toString("yyyyMMddhhmmss")); 1909 MVFileFormat.replace(QRegExp("%STARTTIMEISO%"), 1910 rec->recstartts.toString(Qt::ISODate)); 1911 MVFileFormat.replace(QRegExp("%ENDTIMEISO%"), 1912 rec->recendts.toString(Qt::ISODate)); 1913 MVFileFormat.replace(QRegExp("%PROGSTART%"), 1914 rec->startts.toString("yyyyMMddhhmmss")); 1915 MVFileFormat.replace(QRegExp("%PROGEND%"), 1916 rec->endts.toString("yyyyMMddhhmmss")); 1917 MVFileFormat.replace(QRegExp("%PROGSTARTISO%"), 1918 rec->startts.toString(Qt::ISODate)); 1919 MVFileFormat.replace(QRegExp("%PROGENDISO%"), 1920 rec->endts.toString(Qt::ISODate)); 1921 } 1922 1923 copyToDir = QString("%1/%2/").arg(baseMVDir).arg(MVDirFormat); 1924 copyToFile = QString("%1/%2.%3").arg(copyToDir) 1925 .arg(MVFileFormat).arg(extension); 1926 1927 1928 // File and Directory Definitions 1929 1930 QFile fromFile(copyFrom); 1931 QDir toDir(copyToDir); 1932 QFile toFile(copyToFile); 1933 1934 if (!toDir.exists()) 1935 { 1936 // Attempt to create path to export point. 1937 toDir.mkpath(copyToDir); 1938 toDir.mkdir(copyToDir); 1939 if (!toDir.exists()) 1940 { 1941 VERBOSE(VB_IMPORTANT, QString("Unable to create directory %1! " 1942 "Please ensure the preceding path " 1943 "exists and is writeable.").arg(copyToDir)); 1944 return; 1945 } 1946 } 1947 1948 long long int bytesCopied = copy(toFile,fromFile); 1949 1950 if (bytesCopied != -1) 1951 { 1952 // Add File into videometadata 1953 1954 MSqlQuery query(MSqlQuery::InitCon()); 1955 1956 query.prepare("INSERT INTO videometadata (title,plot,year,category," 1957 "userrating,length,filename,showlevel,inetref, " 1958 "browse) VALUES (:TITLE, :PLOT, :YEAR, :CATEGORY, " 1959 ":USERRATING, :LENGTH, :FILENAME, :SHOWLEVEL, " 1960 ":INETREF, :BROWSE)"); 1961 1962 query.bindValue(":TITLE", MVFileFormat); 1963 query.bindValue(":PLOT", rec->description); 1964 query.bindValue(":YEAR", rec->originalAirDate.toString("yyyy")); 1965 query.bindValue(":CATEGORY", rec->category); 1966 query.bindValue(":USERRATING", exportRating); 1967 query.bindValue(":LENGTH", rec->lenMins); 1968 query.bindValue(":FILENAME", copyToFile); 1969 query.bindValue(":SHOWLEVEL", 1); 1970 query.bindValue(":INETREF", 0); 1971 query.bindValue(":BROWSE", 1); 1972 1973 if (!query.exec() || !query.isActive()) 1974 { 1975 MythDB::DBError("video metadata update", query); 1976 return; 1977 } 1978 1979 // Move recordedmarkup for file into videometadata 1980 1981 MSqlQuery markup(MSqlQuery::InitCon()); 1982 1983 markup.prepare("INSERT INTO filemarkup (filename,mark,offset,type) " 1984 "SELECT :FILENAME, mark, data, type from " 1985 "recordedmarkup where chanid=:CHANID and starttime=:STARTTIME"); 1986 1987 markup.bindValue(":FILENAME", copyToFile); 1988 markup.bindValue(":CHANID", rec->chanid); 1989 markup.bindValue(":STARTTIME", rec->recstartts); 1990 1991 if (!markup.exec() || !markup.isActive()) 1992 { 1993 MythDB::DBError("video metadata update", markup); 1994 return; 1995 } 1996 1997 // Copy and set preview image as coverfile 1998 1999 QString imagefile = NULL; 2000 imagefile = getPreviewImage(rec); 2001 QString MVScreenshotDir = gContext->GetSetting("VideoScreenshotDir"); 2002 QString MVimagefile = QString("%1/%2.png").arg(MVScreenshotDir).arg(MVFileFormat); 2003 2004 VERBOSE(VB_IMPORTANT, QString("Copying %1 to %2").arg(imagefile).arg(MVimagefile)); 2005 2006 QFile fromPoster(imagefile); 2007 QFile toPoster(MVimagefile); 2008 2009 long long int posterBytesCopied = copy(toPoster,fromPoster); 2010 2011 if (posterBytesCopied != -1) 2012 { 2013 MSqlQuery poster(MSqlQuery::InitCon()); 2014 2015 poster.prepare("UPDATE videometadata set screenshot=:COVERFILE " 2016 "where filename=:FILENAME"); 2017 2018 poster.bindValue(":COVERFILE", MVimagefile); 2019 poster.bindValue(":FILENAME", copyToFile); 2020 2021 if (!poster.exec() || !poster.isActive()) 2022 { 2023 MythDB::DBError("video metadata update", poster); 2024 return; 2025 } 2026 } 2027 else 2028 { 2029 VERBOSE(VB_IMPORTANT, QString("Copy succeeded, but image copy failed.").arg(posterBytesCopied)); 2030 return; 2031 } 2032 VERBOSE(VB_IMPORTANT, QString("Copy succeeded, %1 bytes copied.").arg(bytesCopied)); 2033 } 2034 else 2035 { 2036 VERBOSE(VB_IMPORTANT, QString("Copy unsuccessful, check all permissions.")); 2037 } 2038 2039 customExportDir.clear(); 2040 customExportFile.clear(); 2041 2042 } 2043 1816 2044 bool PlaybackBox::doRemove(ProgramInfo *rec, bool forgetHistory, 1817 2045 bool forceMetadataDelete) 1818 2046 { … … 1867 2095 showActionPopup(pginfo); 1868 2096 } 1869 2097 2098 void PlaybackBox::showExportPopup(ProgramInfo *program) 2099 { 2100 if (m_popupMenu) 2101 return; 2102 2103 QString label = tr("Are you sure you want to export:"); 2104 2105 m_expItem = CurrentItem(); 2106 popupString(m_expItem, label); 2107 2108 m_popupMenu = new MythDialogBox(label, m_popupStack, "pbbmainmenupopup"); 2109 2110 connect(m_popupMenu, SIGNAL(Exiting()), SLOT(popupClosed())); 2111 2112 if (m_popupMenu->Create()) 2113 m_popupStack->AddScreen(m_popupMenu); 2114 else 2115 { 2116 delete m_popupMenu; 2117 m_popupMenu = NULL; 2118 } 2119 2120 m_popupMenu->SetReturnEvent(this, "slotmenu"); 2121 2122 m_freeSpaceNeedsUpdate = true; 2123 QString tmpmessage; 2124 const char *tmpslot = NULL; 2125 2126 if (program->IsSameProgram(*program)) 2127 { 2128 tmpmessage = tr("Yes, Export to MythVideo"); 2129 tmpslot = SLOT(doMVExport()); 2130 m_popupMenu->AddButton(tmpmessage, tmpslot); 2131 2132 tmpmessage = tr("Export with custom name/location"); 2133 tmpslot = SLOT(showCustomExportEditor()); 2134 m_popupMenu->AddButton(tmpmessage, tmpslot); 2135 2136 tmpmessage = tr("No, I don't want to Export"); 2137 tmpslot = SLOT(noExport()); 2138 m_popupMenu->AddButton(tmpmessage, tmpslot); 2139 } 2140 } 2141 2142 1870 2143 void PlaybackBox::showDeletePopup(ProgramInfo *program, deletePopupType types) 1871 2144 { 1872 2145 if (m_popupMenu) … … 2518 2791 true); 2519 2792 m_popupMenu->AddButton(tr("Job Options"), SLOT(showJobPopup()), true); 2520 2793 2794 QString MVlocation = FindPluginName("mythvideo"); 2795 if (QFile(MVlocation).exists()) 2796 m_popupMenu->AddButton(tr("Export to MythVideo"), SLOT(askMVExport())); 2797 2521 2798 if (!(m_player && m_player->IsSameProgram(0, pginfo))) 2522 2799 { 2523 2800 if (pginfo->recgroup == "Deleted") … … 2614 2891 stop(pginfo); 2615 2892 } 2616 2893 2894 void PlaybackBox::doMVExport() 2895 { 2896 ProgramInfo *pginfo = CurrentItem(); 2897 mvexport(pginfo); 2898 } 2899 2617 2900 void PlaybackBox::showProgramDetails() 2618 2901 { 2619 2902 ProgramInfo *pginfo = CurrentItem(); … … 2752 3035 } 2753 3036 } 2754 3037 3038 void PlaybackBox::askMVExport(ProgramInfo *pginfo) 3039 { 3040 if (!pginfo) 3041 pginfo = CurrentItem(); 3042 showExportPopup(pginfo); 3043 } 3044 2755 3045 void PlaybackBox::askDelete(ProgramInfo *pginfo) 2756 3046 { 2757 3047 if (!pginfo) … … 3983 4273 m_recordingList->RemoveItem(item); 3984 4274 } 3985 4275 4276 void PlaybackBox::showCustomExportEditor() 4277 { 4278 4279 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); 4280 4281 CustomExportEdit *editExport = new CustomExportEdit(mainStack); 4282 4283 if (editExport->Create()) 4284 { 4285 connect(editExport, SIGNAL(result(const QString &, const QString &)), 4286 SLOT(startCustomExport(const QString &, const QString &))); 4287 mainStack->AddScreen(editExport); 4288 } 4289 else 4290 delete editExport; 4291 } 4292 4293 void PlaybackBox::startCustomExport(const QString &newFile, 4294 const QString &newDir) 4295 { 4296 MythUIButtonListItem *item = m_recordingList->GetItemCurrent(); 4297 4298 if (!item) 4299 return; 4300 4301 ProgramInfo *pginfo = CurrentItem(); 4302 4303 if (!pginfo) 4304 return; 4305 4306 customExportFile = newFile; 4307 customExportDir = newDir; 4308 4309 mvexport(pginfo); 4310 } 4311 3986 4312 void PlaybackBox::setRecGroup(QString newRecGroup) 3987 4313 { 3988 4314 ProgramInfo *tmpItem = CurrentItem(); … … 4353 4679 Close(); 4354 4680 } 4355 4681 4682 //////////////////////////////////////////////////////// 4683 4684 CustomExportEdit::CustomExportEdit(MythScreenStack *lparent) 4685 : MythScreenType(lparent, "customexportedit") 4686 { 4687 m_dirEdit = m_fileEdit = NULL; 4688 } 4689 4690 bool CustomExportEdit::Create() 4691 { 4692 if (!LoadWindowFromXML("recordings-ui.xml", "customexport", this)) 4693 return false; 4694 4695 m_dirEdit = dynamic_cast<MythUITextEdit*>(GetChild("dir")); 4696 m_fileEdit = dynamic_cast<MythUITextEdit*>(GetChild("file")); 4697 MythUIButton *okButton = dynamic_cast<MythUIButton*>(GetChild("ok")); 4698 4699 if (!m_dirEdit || !m_fileEdit || !okButton) 4700 { 4701 VERBOSE(VB_IMPORTANT, "Window 'customexport' is missing required " 4702 "elements."); 4703 return false; 4704 } 4705 4706 m_dirEdit->SetText(gContext->GetSetting("TVExportDirFormat")); 4707 m_fileEdit->SetText(gContext->GetSetting("TVExportFileFormat")); 4708 4709 connect(okButton, SIGNAL(Clicked()), SLOT(ReturnExport())); 4710 4711 if (!BuildFocusList()) 4712 VERBOSE(VB_IMPORTANT, "Failed to build a focuslist."); 4713 4714 return true; 4715 } 4716 4717 void CustomExportEdit::ReturnExport() 4718 { 4719 QString newExportDir = m_dirEdit->GetText(); 4720 QString newExportFile = m_fileEdit->GetText(); 4721 4722 emit result(newExportFile, newExportDir); 4723 Close(); 4724 } 4725 4356 4726 ////////////////////////////////////////// 4357 4727 4358 4728 HelpPopup::HelpPopup(MythScreenStack *lparent) -
mythtv/programs/mythfrontend/playbackbox.h
142 142 void showRecGroupChanger(); 143 143 void showPlayGroupChanger(); 144 144 void showMetadataEditor(); 145 void showCustomExportEditor(); 145 146 void showGroupFilter(); 146 147 void showRecGroupPasswordChanger(); 147 148 void showPlayFromPopup(); … … 170 171 171 172 void askStop(); 172 173 void doStop(); 174 void askMVExport(ProgramInfo *pginfo = NULL); 175 void doMVExport(); 173 176 174 177 void doEditScheduled(); 175 178 void doAllowRerecord(); … … 200 203 void setPlayGroup(QString newPlayGroup); 201 204 202 205 void saveRecMetadata(const QString &newTitle, const QString &newSubtitle); 206 void startCustomExport(const QString &newFile, const QString &newDir); 203 207 204 208 void SetRecGroupPassword(const QString &newPasswd); 205 209 … … 260 264 261 265 bool play(ProgramInfo *rec, bool inPlaylist = false); 262 266 void stop(ProgramInfo *); 267 void mvexport(ProgramInfo *); 263 268 void remove(ProgramInfo *); 264 269 void showActions(ProgramInfo *); 265 270 ProgramInfo *CurrentItem(void); … … 279 284 280 285 bool doRemove(ProgramInfo *, bool forgetHistory, bool forceMetadataDelete); 281 286 void showDeletePopup(ProgramInfo *, deletePopupType); 287 void showExportPopup(ProgramInfo *); 282 288 void showActionPopup(ProgramInfo *program); 283 289 void showFileNotFoundActionPopup(ProgramInfo *program); 284 290 void popupString(ProgramInfo *program, QString &message); … … 376 382 // Other state 377 383 /// Program currently selected for deletion 378 384 ProgramInfo *m_delItem; 385 /// Program currently selected for export 386 ProgramInfo *m_expItem; 379 387 /// Program currently selected during an update 380 388 ProgramInfo *m_currentItem; 381 389 /// Group currently selected … … 516 524 ProgramInfo *m_progInfo; 517 525 }; 518 526 527 class CustomExportEdit : public MythScreenType 528 { 529 Q_OBJECT 530 531 public: 532 CustomExportEdit(MythScreenStack *lparent); 533 534 bool Create(void); 535 536 signals: 537 void result(const QString &, const QString &); 538 539 protected slots: 540 void ReturnExport(void); 541 542 private: 543 MythUITextEdit *m_dirEdit; 544 MythUITextEdit *m_fileEdit; 545 546 }; 547 519 548 class HelpPopup : public MythScreenType 520 549 { 521 550 Q_OBJECT -
mythplugins/mythvideo/mythvideo/globalsettings.cpp
236 246 return gc; 237 247 } 238 248 249 HostLineEdit *TVExportDirectoryFormat() 250 { 251 HostLineEdit *gc = new HostLineEdit("TVExportDirFormat"); 252 gc->setLabel(QObject::tr("TV Export Directory Format")); 253 gc->setValue(DEFAULT_TVEXPORTDIRFORMAT); 254 gc->setHelpText(QObject::tr("Directory format for recording export " 255 "to MythVideo, using user job style variables. Directory " 256 "is off of base MythVideo directory. Example: " 257 "Television/%CATEGORY%/%TITLE%")); 258 return gc; 259 } 260 261 HostLineEdit *TVExportFileFormat() 262 { 263 HostLineEdit *gc = new HostLineEdit("TVExportFileFormat"); 264 gc->setLabel(QObject::tr("TV Export File Format")); 265 gc->setValue(DEFAULT_TVEXPORTFILEFORMAT); 266 gc->setHelpText(QObject::tr("File format for recording export " 267 "to MythVideo, using user job style variables. Example: " 268 "%TITLE% - %SUBTITLE% (%STARTTIMEISO%)")); 269 return gc; 270 } 271 239 272 HostLineEdit *VideoArtworkDirectory() 240 273 { 241 274 HostLineEdit *gc = new HostLineEdit("VideoArtworkDir"); … … 683 748 page1->addChild(VideoStartupDirectory()); 684 749 page1->addChild(VideoArtworkDirectory()); 685 750 page1->addChild(VideoDefaultView()); 751 page1->addChild(TVExportDirectoryFormat()); 752 page1->addChild(TVExportFileFormat()); 686 753 687 754 VConfigPage page2(pages, false); 688 755 page2->addChild(VideoListUnknownFiletypes()); -
mythplugins/mythvideo/mythvideo/globals.cpp
25 28 const QString JUMP_VIDEO_TREE = "Video Listings"; 26 29 const QString JUMP_VIDEO_GALLERY = "Video Gallery"; 27 30 const QString JUMP_VIDEO_DEFAULT = "MythVideo"; 31 const QString DEFAULT_TVEXPORTDIRFORMAT = "Television/%TITLE%"; 32 const QString DEFAULT_TVEXPORTFILEFORMAT = "%TITLE% - %SUBTITLE%"; 28 33 29 34 #ifdef Q_WS_MACX 30 35 const QString DEFAULT_VIDEOSTARTUP_DIR = QDir::homePath() + "/Movies"; -
mythplugins/mythvideo/mythvideo/globals.h
25 28 extern const QString JUMP_VIDEO_DEFAULT; 26 29 27 30 extern const QString DEFAULT_VIDEOSTARTUP_DIR; 31 extern const QString DEFAULT_TVEXPORTDIRFORMAT; 32 extern const QString DEFAULT_TVEXPORTFILEFORMAT; 28 33 29 34 #endif // GLOBALS_H_