Ticket #6158: PBBMVExport.5.diff

File PBBMVExport.5.diff, 20.4 KB (added by robert.mcnamara@…, 12 years ago)

Lots of improvements/fixes

  • mythtv/programs/mythfrontend/playbackbox.cpp

     
    2020#include "mythdirs.h"
    2121#include "mythcontext.h"
    2222#include "mythdbcon.h"
     23#include "mythdb.h"
    2324#include "mythverbose.h"
    2425#include "programinfo.h"
    2526#include "scheduledrecording.h"
     
    4445#define LOC QString("PlaybackBox: ")
    4546#define LOC_ERR QString("PlaybackBox Error: ")
    4647
     48QString customExportFile = NULL;
     49QString customExportDir = NULL;
     50
    4751#define REC_CAN_BE_DELETED(rec) \
    4852    ((((rec)->programflags & FL_INUSEPLAYING) == 0) && \
    4953     ((((rec)->programflags & FL_INUSERECORDING) == 0) || \
     
    18151819    RemoteStopRecording(rec);
    18161820}
    18171821
     1822void PlaybackBox::mvexport(ProgramInfo *rec)
     1823{
     1824
     1825    // User Rating Adjustment
     1826    QString exportRating = QString::number((int)((rec->stars * 10.0) + 0.5));
     1827
     1828    // Stuff necessary to perform the copy command
     1829
     1830    QString copyFrom = rec->GetPlaybackURL(false, true);
     1831    QString baseMVDir = gContext->GetSetting("VideoStartupDir");
     1832    QString MVFileFormat;
     1833    QString MVDirFormat;
     1834    QString copyToDir;
     1835    QString copyToFile;
     1836    QString extension;
     1837
     1838    // Check the original extension
     1839
     1840    QRegExp rx(".*\\.(\\w+)$");
     1841    int pos = rx.indexIn(copyFrom);
     1842    if (pos > -1)
     1843    {
     1844        extension = rx.cap(1);
     1845    }
     1846    else
     1847    {
     1848        extension = "";
     1849    }
     1850
     1851    // If a custom export string is used, use it.
     1852    // Also replace %VARIABLES% with actual values.
     1853
     1854    if (customExportFile.isEmpty())
     1855    {
     1856        QString defaultDir = gContext->GetSetting("TVExportDirFormat",
     1857                              "Television/%TITLE%/");
     1858        QString defaultFile = gContext->GetSetting("TVExportFileFormat",
     1859                              "%TITLE% - %SUBTITLE%");
     1860        MVDirFormat = replaceExportVariables(rec, defaultDir);
     1861        MVFileFormat = replaceExportVariables(rec, defaultFile);
     1862    }
     1863    else
     1864    {
     1865        MVDirFormat = replaceExportVariables(rec, customExportDir);
     1866        MVFileFormat = replaceExportVariables(rec, customExportFile);
     1867    }
     1868
     1869    copyToDir = QString("%1/%2/").arg(baseMVDir).arg(MVDirFormat);
     1870    copyToFile = QString("%1/%2.%3").arg(copyToDir)
     1871                         .arg(MVFileFormat).arg(extension);
     1872
     1873
     1874    // File and Directory Definitions
     1875
     1876    QFile fromFile(copyFrom);
     1877    QDir toDir(copyToDir);
     1878    QFile toFile(copyToFile);
     1879
     1880    if (!toDir.exists())
     1881    {
     1882        // Attempt to create path to export point.
     1883        toDir.mkpath(copyToDir);
     1884        toDir.mkdir(copyToDir);
     1885        if (!toDir.exists())
     1886        {
     1887            VERBOSE(VB_IMPORTANT, QString("Unable to create directory %1! "
     1888                                          "Please ensure the preceding path "
     1889                                          "exists and is writeable.").arg(copyToDir));   
     1890            return;
     1891        }
     1892    }
     1893
     1894    // Perform the actual copy.
     1895
     1896    long long int bytesCopied = copy(toFile,fromFile);
     1897
     1898    if (bytesCopied != -1)
     1899    {
     1900        // Add File into videometadata
     1901
     1902        MSqlQuery query(MSqlQuery::InitCon());
     1903
     1904        query.prepare("INSERT INTO videometadata (title,plot,year,category,"
     1905                          "userrating,length,filename,showlevel,inetref, "
     1906                          "browse) VALUES (:TITLE, :PLOT, :YEAR, :CATEGORY, "
     1907                          ":USERRATING, :LENGTH, :FILENAME, :SHOWLEVEL, "
     1908                          ":INETREF, :BROWSE)");
     1909
     1910        query.bindValue(":TITLE", MVFileFormat);
     1911        query.bindValue(":PLOT", rec->description);
     1912        query.bindValue(":YEAR", rec->originalAirDate.toString("yyyy"));
     1913        query.bindValue(":CATEGORY", rec->category);
     1914        query.bindValue(":USERRATING", exportRating);
     1915        query.bindValue(":LENGTH", rec->lenMins);
     1916        query.bindValue(":FILENAME", copyToFile);
     1917        query.bindValue(":SHOWLEVEL", 1);
     1918        query.bindValue(":INETREF", 0);
     1919        query.bindValue(":BROWSE", 1);
     1920
     1921        if (!query.exec() || !query.isActive())
     1922        {
     1923            MythDB::DBError("video metadata update", query);
     1924            return;
     1925        }
     1926
     1927        // Move recordedmarkup for file into videometadata
     1928
     1929        MSqlQuery markup(MSqlQuery::InitCon());
     1930
     1931        markup.prepare("INSERT INTO filemarkup (filename,mark,offset,type) "
     1932                      "SELECT :FILENAME, mark, data, type from "
     1933                      "recordedmarkup where chanid=:CHANID and starttime=:STARTTIME");
     1934
     1935        markup.bindValue(":FILENAME", copyToFile);
     1936        markup.bindValue(":CHANID", rec->chanid);
     1937        markup.bindValue(":STARTTIME", rec->recstartts);
     1938
     1939        if (!markup.exec() || !markup.isActive())
     1940        {
     1941            MythDB::DBError("video metadata update", markup);
     1942            return;
     1943        }
     1944
     1945        // Copy and set preview image as screenshot
     1946        // If Banners, cover files, or fanart exist with
     1947        // seriesID as the name, use them automatically.
     1948
     1949        QString screenshotFile = getPreviewImage(rec);
     1950        QString MVScreenshotDir = gContext->GetSetting("VideoScreenshotDir");
     1951        QString MVScreenshotFile = QString("%1/%2.png").arg(MVScreenshotDir).arg(MVFileFormat);
     1952
     1953        QString MVBannerDir = gContext->GetSetting("VideoBannerDir");
     1954        QString bannerFile = testImageFiles(MVBannerDir, rec->seriesid);
     1955        if (!bannerFile.isNull())
     1956            VERBOSE(VB_IMPORTANT, QString("Found Banner File Match: %1").arg(bannerFile));
     1957
     1958        QString MVFanartDir = gContext->GetSetting("VideoFanartDir");
     1959        QString fanartFile = testImageFiles(MVFanartDir, rec->seriesid);
     1960        if (!fanartFile.isNull())
     1961            VERBOSE(VB_IMPORTANT, QString("Found Fanart File Match: %1").arg(fanartFile));
     1962
     1963        QString MVCoverDir = gContext->GetSetting("VideoArtworkDir");
     1964        QString coverFile = testImageFiles(MVCoverDir, rec->seriesid);
     1965        if (!coverFile.isNull())
     1966            VERBOSE(VB_IMPORTANT, QString("Found Cover File Match: %1").arg(coverFile));
     1967
     1968        VERBOSE(VB_IMPORTANT, QString("Copying %1 to %2").arg(screenshotFile).arg(MVScreenshotFile));
     1969
     1970        QFile fromScreenshot(screenshotFile);
     1971        QFile toScreenshot(MVScreenshotFile);
     1972
     1973        long long int screenshotBytesCopied = copy(toScreenshot,fromScreenshot);
     1974
     1975        if (screenshotBytesCopied != -1 || !bannerFile.isNull() || !fanartFile.isNull() ||
     1976            !coverFile.isNull())
     1977        {
     1978            MSqlQuery images(MSqlQuery::InitCon());
     1979
     1980            images.prepare("UPDATE videometadata set screenshot=:SCREENSHOTFILE, "
     1981                           "banner=:BANNERFILE, fanart=:FANARTFILE, coverfile=:COVERFILE "
     1982                           "where filename=:FILENAME");
     1983
     1984            images.bindValue(":SCREENSHOTFILE", MVScreenshotFile);
     1985            images.bindValue(":BANNERFILE", bannerFile);
     1986            images.bindValue(":FANARTFILE", fanartFile);
     1987            images.bindValue(":COVERFILE", coverFile);
     1988            images.bindValue(":FILENAME", copyToFile);
     1989
     1990            if (!images.exec() || !images.isActive())
     1991            {
     1992                MythDB::DBError("video metadata update", images);
     1993                 return;
     1994            }
     1995        }
     1996        else
     1997        {
     1998            VERBOSE(VB_IMPORTANT, QString("Copy succeeded, but no images "
     1999                    "were copied of found.").arg(screenshotBytesCopied));
     2000            return;
     2001        }
     2002        VERBOSE(VB_IMPORTANT, QString("Copy succeeded, %1 bytes copied.").arg(bytesCopied));
     2003    }
     2004    else
     2005    {
     2006        VERBOSE(VB_IMPORTANT, QString("Copy unsuccessful, check all permissions."));
     2007    }
     2008
     2009customExportDir.clear();
     2010customExportFile.clear();
     2011
     2012}
     2013
     2014QString PlaybackBox::testImageFiles(QString &testDirectory, QString &seriesID)
     2015{
     2016    QString testFilename = QString("%1/%2").arg(testDirectory).arg(seriesID);
     2017    QString foundFile = NULL;
     2018
     2019    QStringList test_files;
     2020    test_files.append(testFilename + ".png");
     2021    test_files.append(testFilename + ".jpg");
     2022    test_files.append(testFilename + ".gif");
     2023    for (QStringList::const_iterator tfp = test_files.begin();
     2024        tfp != test_files.end(); ++tfp)
     2025        {
     2026            if (QFile::exists(*tfp))
     2027            {
     2028                foundFile = *tfp;
     2029                break;
     2030            }
     2031        }
     2032    return foundFile;
     2033}
     2034
     2035QString PlaybackBox::replaceExportVariables(ProgramInfo *rec, QString &repString)
     2036{
     2037    if (!repString.isEmpty())
     2038    {
     2039         repString.replace(QRegExp("%FILE%"), rec->GetRecordBasename(true));
     2040         repString.replace(QRegExp("%TITLE%"), rec->title);
     2041         repString.replace(QRegExp("%SUBTITLE%"), rec->subtitle);
     2042         repString.replace(QRegExp("%DESCRIPTION%"), rec->description);
     2043         repString.replace(QRegExp("%HOSTNAME%"), rec->hostname);
     2044         repString.replace(QRegExp("%CATEGORY%"), rec->category);
     2045         repString.replace(QRegExp("%RECGROUP%"), rec->recgroup);
     2046         repString.replace(QRegExp("%PLAYGROUP%"), rec->playgroup);
     2047         repString.replace(QRegExp("%ORIGAIRYEAR%"),
     2048                         rec->originalAirDate.toString("yyyy"));
     2049         repString.replace(QRegExp("%ORIGAIRDATE%"),
     2050                         rec->originalAirDate.toString("yyyyMMdd"));
     2051         repString.replace(QRegExp("%CALLSIGN%"), rec->chansign);
     2052         repString.replace(QRegExp("%CHANNAME%"), rec->channame);
     2053         repString.replace(QRegExp("%CHANID%"), rec->chanid);
     2054         repString.replace(QRegExp("%STARTTIME%"),
     2055                         rec->recstartts.toString("yyyyMMddhhmmss"));
     2056         repString.replace(QRegExp("%ENDTIME%"),
     2057                         rec->recendts.toString("yyyyMMddhhmmss"));
     2058         repString.replace(QRegExp("%STARTTIMEISO%"),
     2059                         rec->recstartts.toString(Qt::ISODate));
     2060         repString.replace(QRegExp("%ENDTIMEISO%"),
     2061                         rec->recendts.toString(Qt::ISODate));
     2062         repString.replace(QRegExp("%PROGSTART%"),
     2063                         rec->startts.toString("yyyyMMddhhmmss"));
     2064         repString.replace(QRegExp("%PROGEND%"),
     2065                         rec->endts.toString("yyyyMMddhhmmss"));
     2066         repString.replace(QRegExp("%PROGSTARTISO%"),
     2067                         rec->startts.toString(Qt::ISODate));
     2068         repString.replace(QRegExp("%PROGENDISO%"),
     2069                         rec->endts.toString(Qt::ISODate));
     2070    }
     2071    return repString;
     2072}
     2073
    18182074bool PlaybackBox::doRemove(ProgramInfo *rec, bool forgetHistory,
    18192075                           bool forceMetadataDelete)
    18202076{
     
    18692125        showActionPopup(pginfo);
    18702126}
    18712127
     2128void PlaybackBox::showExportPopup(ProgramInfo *program)
     2129{
     2130    if (m_popupMenu)
     2131        return;
     2132
     2133    QString label = tr("Are you sure you want to export:");
     2134
     2135    m_expItem = CurrentItem();
     2136    popupString(m_expItem, label);
     2137
     2138    m_popupMenu = new MythDialogBox(label, m_popupStack, "pbbmainmenupopup");
     2139
     2140    connect(m_popupMenu, SIGNAL(Exiting()), SLOT(popupClosed()));
     2141
     2142    if (m_popupMenu->Create())
     2143        m_popupStack->AddScreen(m_popupMenu);
     2144    else
     2145    {
     2146        delete m_popupMenu;
     2147        m_popupMenu = NULL;
     2148    }
     2149
     2150    m_popupMenu->SetReturnEvent(this, "slotmenu");
     2151
     2152    m_freeSpaceNeedsUpdate = true;
     2153    QString tmpmessage;
     2154    const char *tmpslot = NULL;
     2155
     2156    if (program->IsSameProgram(*program))
     2157        {
     2158        tmpmessage = tr("Yes, Export to MythVideo");
     2159        tmpslot = SLOT(doMVExport());
     2160        m_popupMenu->AddButton(tmpmessage, tmpslot);
     2161
     2162        tmpmessage = tr("Export with custom name/location");
     2163        tmpslot = SLOT(showCustomExportEditor());
     2164        m_popupMenu->AddButton(tmpmessage, tmpslot);
     2165
     2166        tmpmessage = tr("No, I don't want to Export");
     2167        tmpslot = SLOT(noExport());
     2168        m_popupMenu->AddButton(tmpmessage, tmpslot);
     2169        }
     2170}
     2171
     2172
    18722173void PlaybackBox::showDeletePopup(ProgramInfo *program, deletePopupType types)
    18732174{
    18742175    if (m_popupMenu)
     
    22712572        else
    22722573            m_popupMenu->AddButton(tr("Preserve this episode"),
    22732574                                            SLOT(togglePreserveEpisode()));
     2575
     2576        QString MVlocation = FindPluginName("mythvideo");
     2577        if (QFile(MVlocation).exists())
     2578            m_popupMenu->AddButton(tr("Export to MythVideo"), SLOT(askMVExport()));
    22742579    }
    22752580}
    22762581
     
    26162921    stop(pginfo);
    26172922}
    26182923
     2924void PlaybackBox::doMVExport()
     2925{
     2926    ProgramInfo *pginfo = CurrentItem();
     2927    mvexport(pginfo);
     2928}
     2929
    26192930void PlaybackBox::showProgramDetails()
    26202931{
    26212932   ProgramInfo *pginfo = CurrentItem();
     
    27543065    }
    27553066}
    27563067
     3068void PlaybackBox::askMVExport(ProgramInfo *pginfo)
     3069{
     3070    if (!pginfo)
     3071        pginfo = CurrentItem();
     3072    showExportPopup(pginfo);
     3073}
     3074
    27573075void PlaybackBox::askDelete(ProgramInfo *pginfo)
    27583076{
    27593077    if (!pginfo)
     
    39854303        m_recordingList->RemoveItem(item);
    39864304}
    39874305
     4306void PlaybackBox::showCustomExportEditor()
     4307{
     4308
     4309    MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
     4310
     4311    CustomExportEdit *editExport = new CustomExportEdit(mainStack);
     4312
     4313    if (editExport->Create())
     4314    {
     4315        connect(editExport, SIGNAL(result(const QString &, const QString &)),
     4316                SLOT(startCustomExport(const QString &, const QString &)));
     4317        mainStack->AddScreen(editExport);
     4318    }
     4319    else
     4320        delete editExport;
     4321}
     4322
     4323void PlaybackBox::startCustomExport(const QString &newFile,
     4324                                    const QString &newDir)
     4325{
     4326    MythUIButtonListItem *item = m_recordingList->GetItemCurrent();
     4327
     4328    if (!item)
     4329        return;
     4330
     4331    ProgramInfo *pginfo = CurrentItem();
     4332
     4333    if (!pginfo)
     4334        return;
     4335
     4336    customExportFile = newFile;
     4337    customExportDir = newDir;
     4338
     4339    mvexport(pginfo);
     4340}
     4341
    39884342void PlaybackBox::setRecGroup(QString newRecGroup)
    39894343{
    39904344    ProgramInfo *tmpItem = CurrentItem();
     
    43554709    Close();
    43564710}
    43574711
     4712////////////////////////////////////////////////////////
     4713
     4714CustomExportEdit::CustomExportEdit(MythScreenStack *lparent)
     4715                : MythScreenType(lparent, "customexportedit")
     4716{
     4717    m_dirEdit = m_fileEdit = NULL;
     4718}
     4719
     4720bool CustomExportEdit::Create()
     4721{
     4722    if (!LoadWindowFromXML("recordings-ui.xml", "customexport", this))
     4723        return false;
     4724       
     4725    m_dirEdit = dynamic_cast<MythUITextEdit*>(GetChild("dir"));
     4726    m_fileEdit = dynamic_cast<MythUITextEdit*>(GetChild("file"));
     4727    MythUIButton *okButton = dynamic_cast<MythUIButton*>(GetChild("ok"));
     4728 
     4729    if (!m_dirEdit || !m_fileEdit || !okButton)
     4730    {
     4731        VERBOSE(VB_IMPORTANT, "Window 'customexport' is missing required "
     4732                              "elements.");
     4733        return false;
     4734    }
     4735   
     4736    m_dirEdit->SetText(gContext->GetSetting("TVExportDirFormat"));
     4737    m_fileEdit->SetText(gContext->GetSetting("TVExportFileFormat"));
     4738
     4739    connect(okButton, SIGNAL(Clicked()), SLOT(ReturnExport()));
     4740     
     4741    if (!BuildFocusList())
     4742        VERBOSE(VB_IMPORTANT, "Failed to build a focuslist.");
     4743 
     4744    return true;
     4745}
     4746
     4747void CustomExportEdit::ReturnExport()
     4748{
     4749    QString newExportDir = m_dirEdit->GetText();
     4750    QString newExportFile = m_fileEdit->GetText();
     4751
     4752    emit result(newExportFile, newExportDir);
     4753    Close();
     4754}
     4755
    43584756//////////////////////////////////////////
    43594757
    43604758HelpPopup::HelpPopup(MythScreenStack *lparent)
  • mythtv/programs/mythfrontend/playbackbox.h

     
    142142    void showRecGroupChanger();
    143143    void showPlayGroupChanger();
    144144    void showMetadataEditor();
     145    void showCustomExportEditor();
    145146    void showGroupFilter();
    146147    void showRecGroupPasswordChanger();
    147148    void showPlayFromPopup();
     
    170171
    171172    void askStop();
    172173    void doStop();
     174    void askMVExport(ProgramInfo *pginfo = NULL);
     175    void doMVExport();
    173176
    174177    void doEditScheduled();
    175178    void doAllowRerecord();
     
    200203    void setPlayGroup(QString newPlayGroup);
    201204
    202205    void saveRecMetadata(const QString &newTitle, const QString &newSubtitle);
     206    void startCustomExport(const QString &newFile, const QString &newDir);
    203207
    204208    void SetRecGroupPassword(const QString &newPasswd);
    205209
     
    260264
    261265    bool play(ProgramInfo *rec, bool inPlaylist = false);
    262266    void stop(ProgramInfo *);
     267    void mvexport(ProgramInfo *);
     268    QString testImageFiles(QString &testDirectory, QString &seriesID);
     269    QString replaceExportVariables(ProgramInfo *rec, QString &repString);
    263270    void remove(ProgramInfo *);
    264271    void showActions(ProgramInfo *);
    265272    ProgramInfo *CurrentItem(void);
     
    279286
    280287    bool doRemove(ProgramInfo *, bool forgetHistory, bool forceMetadataDelete);
    281288    void showDeletePopup(ProgramInfo *, deletePopupType);
     289    void showExportPopup(ProgramInfo *);
    282290    void showActionPopup(ProgramInfo *program);
    283291    void showFileNotFoundActionPopup(ProgramInfo *program);
    284292    void popupString(ProgramInfo *program, QString &message);
     
    376384    // Other state
    377385    /// Program currently selected for deletion
    378386    ProgramInfo *m_delItem;
     387    /// Program currently selected for export
     388    ProgramInfo *m_expItem;
    379389    /// Program currently selected during an update
    380390    ProgramInfo *m_currentItem;
    381391    /// Group currently selected
     
    516526    ProgramInfo *m_progInfo;
    517527};
    518528
     529class CustomExportEdit : public MythScreenType
     530{
     531    Q_OBJECT
     532
     533  public:
     534    CustomExportEdit(MythScreenStack *lparent);
     535
     536    bool Create(void);
     537
     538  signals:
     539    void result(const QString &, const QString &);
     540
     541  protected slots:   
     542    void ReturnExport(void);
     543 
     544  private:
     545    MythUITextEdit     *m_dirEdit;
     546    MythUITextEdit     *m_fileEdit;
     547   
     548};
     549
    519550class HelpPopup : public MythScreenType
    520551{
    521552    Q_OBJECT
  • mythplugins/mythvideo/mythvideo/globalsettings.cpp

     
    236246    return gc;
    237247}
    238248
     249HostLineEdit *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
     261HostLineEdit *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
    239272HostLineEdit *VideoArtworkDirectory()
    240273{
    241274    HostLineEdit *gc = new HostLineEdit("VideoArtworkDir");
     
    709777    vman->addChild(SearchListingsCommand());
    710778    vman->addChild(GetPostersCommand());
    711779    vman->addChild(GetDataCommand());
     780    vman->setLabel(QObject::tr("Video Export"));
     781    vman->addChild(TVExportDirectoryFormat());   
     782    vman->addChild(TVExportFileFormat()); 
    712783
    713784    VConfigPage page4(pages, false);
    714785    page4->addChild(vman);
  • mythplugins/mythvideo/mythvideo/globals.cpp

     
    2528const QString JUMP_VIDEO_TREE = "Video Listings";
    2629const QString JUMP_VIDEO_GALLERY = "Video Gallery";
    2730const QString JUMP_VIDEO_DEFAULT = "MythVideo";
     31const QString DEFAULT_TVEXPORTDIRFORMAT = "Television/%TITLE%";
     32const QString DEFAULT_TVEXPORTFILEFORMAT = "%TITLE% - %SUBTITLE%";
    2833
    2934#ifdef Q_WS_MACX
    3035const QString DEFAULT_VIDEOSTARTUP_DIR = QDir::homePath() + "/Movies";
  • mythplugins/mythvideo/mythvideo/globals.h

     
    2528extern const QString JUMP_VIDEO_DEFAULT;
    2629
    2730extern const QString DEFAULT_VIDEOSTARTUP_DIR;
     31extern const QString DEFAULT_TVEXPORTDIRFORMAT;
     32extern const QString DEFAULT_TVEXPORTFILEFORMAT;
    2833
    2934#endif // GLOBALS_H_