X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmainwindow.cpp;h=c3efd3dabd70eab4dd1ee5422be529f0b67f5c73;hb=2553030e55b9872509b433d0eb12b546fa33f7e3;hp=4013073ffabe9b3b7f3d7a447ca936b8536f13a0;hpb=d99246be40d1c8a275a21af1775e595d209d040d;p=kdenlive diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4013073f..c3efd3da 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -61,6 +61,8 @@ #include "colorscopes/histogram.h" #include "audiospectrum.h" #include "spectrogram.h" +#include "archivewidget.h" +#include "databackup/backupwidget.h" #include #include @@ -138,6 +140,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & KXmlGuiWindow(parent), m_activeDocument(NULL), m_activeTimeline(NULL), + m_recMonitor(NULL), m_renderWidget(NULL), #ifndef NO_JOGSHUTTLE m_jogProcess(NULL), @@ -151,8 +154,6 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & new MainWindowAdaptor(this); QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.registerObject("/MainWindow", this); - - setlocale(LC_NUMERIC, "POSIX"); if (!KdenliveSettings::colortheme().isEmpty()) slotChangePalette(NULL, KdenliveSettings::colortheme()); setFont(KGlobalSettings::toolBarFont()); parseProfiles(MltPath); @@ -198,7 +199,8 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & m_clipMonitorDock->setObjectName("clip_monitor"); m_clipMonitor = new Monitor("clip", m_monitorManager, QString(), m_timelineArea); m_clipMonitorDock->setWidget(m_clipMonitor); - + connect(m_projectList, SIGNAL(clipSelected(DocClipBase *, QPoint)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *, QPoint))); + m_projectMonitorDock = new QDockWidget(i18n("Project Monitor"), this); m_projectMonitorDock->setObjectName("project_monitor"); m_projectMonitor = new Monitor("project", m_monitorManager, QString()); @@ -207,15 +209,19 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & #ifndef Q_WS_MAC m_recMonitorDock = new QDockWidget(i18n("Record Monitor"), this); m_recMonitorDock->setObjectName("record_monitor"); - m_recMonitor = new RecMonitor("record"); + m_recMonitor = new RecMonitor("record", m_monitorManager); m_recMonitorDock->setWidget(m_recMonitor); connect(m_recMonitor, SIGNAL(addProjectClip(KUrl)), this, SLOT(slotAddProjectClip(KUrl))); connect(m_recMonitor, SIGNAL(showConfigDialog(int, int)), this, SLOT(slotPreferences(int, int))); #endif + m_monitorManager->initMonitors(m_clipMonitor, m_projectMonitor, m_recMonitor); m_notesDock = new QDockWidget(i18n("Project Notes"), this); m_notesDock->setObjectName("notes_widget"); - m_notesWidget = new KTextEdit(); + m_notesWidget = new NotesWidget(); + connect(m_notesWidget, SIGNAL(insertNotesTimecode()), this, SLOT(slotInsertNotesTimecode())); + connect(m_notesWidget, SIGNAL(seekProject(int)), m_projectMonitor->render, SLOT(seekToFrame(int))); + m_notesWidget->setTabChangesFocus(true); #if KDE_IS_VERSION(4,4,0) m_notesWidget->setClickMessage(i18n("Enter your project notes here ...")); @@ -241,7 +247,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & m_effectListDock->setWidget(m_effectList); addDockWidget(Qt::TopDockWidgetArea, m_effectListDock); - m_vectorscope = new Vectorscope(m_projectMonitor, m_clipMonitor); + m_vectorscope = new Vectorscope(m_monitorManager); m_vectorscopeDock = new QDockWidget(i18n("Vectorscope"), this); m_vectorscopeDock->setObjectName(m_vectorscope->widgetName()); m_vectorscopeDock->setWidget(m_vectorscope); @@ -251,7 +257,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & connect(m_vectorscope, SIGNAL(requestAutoRefresh(bool)), this, SLOT(slotUpdateGfxScopeFrameRequest())); m_gfxScopesList.append(m_vectorscopeDock); - m_waveform = new Waveform(m_projectMonitor, m_clipMonitor); + m_waveform = new Waveform(m_monitorManager); m_waveformDock = new QDockWidget(i18n("Waveform"), this); m_waveformDock->setObjectName(m_waveform->widgetName()); m_waveformDock->setWidget(m_waveform); @@ -261,7 +267,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & connect(m_waveform, SIGNAL(requestAutoRefresh(bool)), this, SLOT(slotUpdateGfxScopeFrameRequest())); m_gfxScopesList.append(m_waveformDock); - m_RGBParade = new RGBParade(m_projectMonitor, m_clipMonitor); + m_RGBParade = new RGBParade(m_monitorManager); m_RGBParadeDock = new QDockWidget(i18n("RGB Parade"), this); m_RGBParadeDock->setObjectName(m_RGBParade->widgetName()); m_RGBParadeDock->setWidget(m_RGBParade); @@ -271,7 +277,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & connect(m_RGBParade, SIGNAL(requestAutoRefresh(bool)), this, SLOT(slotUpdateGfxScopeFrameRequest())); m_gfxScopesList.append(m_RGBParadeDock); - m_histogram = new Histogram(m_projectMonitor, m_clipMonitor); + m_histogram = new Histogram(m_monitorManager); m_histogramDock = new QDockWidget(i18n("Histogram"), this); m_histogramDock->setObjectName(m_histogram->widgetName()); m_histogramDock->setWidget(m_histogram); @@ -351,6 +357,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & setupActions(); + connect(m_commandStack, SIGNAL(cleanChanged(bool)), m_saveAction, SLOT(setDisabled(bool))); // Close non-general docks for the initial layout @@ -557,12 +564,12 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & connect(m_projectMonitorDock, SIGNAL(visibilityChanged(bool)), m_projectMonitor, SLOT(refreshMonitor(bool))); connect(m_clipMonitorDock, SIGNAL(visibilityChanged(bool)), m_clipMonitor, SLOT(refreshMonitor(bool))); //connect(m_monitorManager, SIGNAL(connectMonitors()), this, SLOT(slotConnectMonitors())); - connect(m_monitorManager, SIGNAL(raiseClipMonitor(bool)), this, SLOT(slotRaiseMonitor(bool))); + connect(m_monitorManager, SIGNAL(raiseMonitor(AbstractMonitor *)), this, SLOT(slotRaiseMonitor(AbstractMonitor *))); connect(m_monitorManager, SIGNAL(checkColorScopes()), this, SLOT(slotUpdateColorScopes())); + connect(m_monitorManager, SIGNAL(clearScopes()), this, SLOT(slotClearColorScopes())); connect(m_effectList, SIGNAL(addEffect(const QDomElement)), this, SLOT(slotAddEffect(const QDomElement))); connect(m_effectList, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects())); - m_monitorManager->initMonitors(m_clipMonitor, m_projectMonitor); slotConnectMonitors(); // Open or create a file. Command line argument passed in Url has @@ -820,10 +827,10 @@ void MainWindow::slotAddEffect(const QDomElement effect) else m_activeTimeline->projectView()->slotAddEffect(effectToAdd, GenTime(), -1); } -void MainWindow::slotRaiseMonitor(bool clipMonitor) +void MainWindow::slotRaiseMonitor(AbstractMonitor *monitor) { - if (clipMonitor) m_clipMonitorDock->raise(); - else m_projectMonitorDock->raise(); + if (monitor == m_clipMonitor) m_clipMonitorDock->raise(); + else if (monitor == m_projectMonitor) m_projectMonitorDock->raise(); } void MainWindow::slotUpdateClip(const QString &id) @@ -844,6 +851,8 @@ void MainWindow::slotConnectMonitors() connect(m_projectMonitor->render, SIGNAL(replyGetFileProperties(const QString &, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &, bool, bool)), m_projectList, SLOT(slotReplyGetFileProperties(const QString &, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &, bool, bool))); connect(m_projectMonitor->render, SIGNAL(removeInvalidClip(const QString &, bool)), m_projectList, SLOT(slotRemoveInvalidClip(const QString &, bool))); + + connect(m_projectMonitor->render, SIGNAL(blockClipMonitor(const QString)), this, SLOT(slotBlockClipMonitor(const QString))); connect(m_projectMonitor->render, SIGNAL(removeInvalidProxy(const QString &, bool)), m_projectList, SLOT(slotRemoveInvalidProxy(const QString &, bool))); connect(m_clipMonitor, SIGNAL(refreshClipThumbnail(const QString &, bool)), m_projectList, SLOT(slotRefreshClipThumbnail(const QString &, bool))); @@ -853,8 +862,8 @@ void MainWindow::slotConnectMonitors() connect(m_projectMonitor, SIGNAL(requestFrameForAnalysis(bool)), this, SLOT(slotMonitorRequestRenderFrame(bool))); - connect(m_clipMonitor, SIGNAL(saveZone(Render *, QPoint)), this, SLOT(slotSaveZone(Render *, QPoint))); - connect(m_projectMonitor, SIGNAL(saveZone(Render *, QPoint)), this, SLOT(slotSaveZone(Render *, QPoint))); + connect(m_clipMonitor, SIGNAL(saveZone(Render *, QPoint, DocClipBase *)), this, SLOT(slotSaveZone(Render *, QPoint, DocClipBase *))); + connect(m_projectMonitor, SIGNAL(saveZone(Render *, QPoint, DocClipBase *)), this, SLOT(slotSaveZone(Render *, QPoint, DocClipBase *))); } void MainWindow::slotAdjustClipMonitor() @@ -1155,6 +1164,10 @@ void MainWindow::setupActions() collection.addAction("project_settings", projectAction); connect(projectAction, SIGNAL(triggered(bool)), this, SLOT(slotEditProjectSettings())); + KAction* backupAction = new KAction(KIcon("edit-undo"), i18n("Open Backup File"), this); + collection.addAction("open_backup", backupAction); + connect(backupAction, SIGNAL(triggered(bool)), this, SLOT(slotOpenBackupDialog())); + KAction* projectRender = new KAction(KIcon("media-record"), i18n("Render"), this); collection.addAction("project_render", projectRender); projectRender->setShortcut(Qt::CTRL + Qt::Key_Return); @@ -1203,6 +1216,11 @@ void MainWindow::setupActions() collection.addAction("transcode_clip", transcodeClip); connect(transcodeClip, SIGNAL(triggered(bool)), this, SLOT(slotTranscodeClip())); + KAction *archiveProject = new KAction(KIcon("file-save"), i18n("Archive Project"), this); + collection.addAction("archive_project", archiveProject); + connect(archiveProject, SIGNAL(triggered(bool)), this, SLOT(slotArchiveProject())); + + KAction *markIn = collection.addAction("mark_in"); markIn->setText(i18n("Set Zone In")); markIn->setShortcut(Qt::Key_I); @@ -1495,15 +1513,6 @@ void MainWindow::setupActions() showTitleBar->setChecked(KdenliveSettings::showtitlebars()); slotShowTitleBars(KdenliveSettings::showtitlebars()); - - //const QByteArray state = layoutGroup.readEntry("layout1", QByteArray()); - - /*QAction *maxCurrent = new KAction(i18n("Maximize Current Widget"), this); - collection.addAction("maximize_current", maxCurrent); - maxCurrent->setCheckable(true); - maxCurrent->setChecked(false); - connect(maxCurrent, SIGNAL(triggered(bool)), this, SLOT(slotMaximizeCurrent(bool)));*/ - m_closeAction = KStandardAction::close(this, SLOT(closeCurrentDocument()), collection); KStandardAction::quit(this, SLOT(close()), collection); KStandardAction::open(this, SLOT(openFile()), collection); @@ -1580,6 +1589,13 @@ void MainWindow::setupActions() connect(reloadClip , SIGNAL(triggered()), m_projectList, SLOT(slotReloadClip())); reloadClip->setEnabled(false); + QAction *proxyClip = new KAction(i18n("Proxy Clip"), this); + collection.addAction("proxy_clip", proxyClip); + proxyClip->setData("proxy_clip"); + proxyClip->setCheckable(true); + proxyClip->setChecked(false); + connect(proxyClip, SIGNAL(toggled(bool)), m_projectList, SLOT(slotProxyCurrentItem(bool))); + QAction *stopMotion = new KAction(KIcon("image-x-generic"), i18n("Stop Motion Capture"), this); collection.addAction("stopmotion", stopMotion); connect(stopMotion , SIGNAL(triggered()), this, SLOT(slotOpenStopmotion())); @@ -1593,6 +1609,7 @@ void MainWindow::setupActions() addClips->addAction(addFolderButton); addClips->addAction(reloadClip); + addClips->addAction(proxyClip); addClips->addAction(clipProperties); addClips->addAction(openClip); addClips->addAction(deleteClip); @@ -1614,8 +1631,6 @@ void MainWindow::setupActions() } //m_effectsActionCollection->readSettings(); - //connect(collection, SIGNAL( clearStatusText() ), - //statusBar(), SLOT( clear() ) ); } void MainWindow::slotDisplayActionMessage(QAction *a) @@ -1664,9 +1679,7 @@ void MainWindow::slotLoadLayout(QAction *action) if (layoutId.isEmpty()) return; KSharedConfigPtr config = KGlobal::config(); KConfigGroup layouts(config, "Layouts"); - //QByteArray geom = QByteArray::fromBase64(layouts.readEntry(layoutId).toAscii()); QByteArray state = QByteArray::fromBase64(layouts.readEntry(layoutId).toAscii()); - //restoreGeometry(geom); restoreState(state); } @@ -1792,8 +1805,8 @@ void MainWindow::newFile(bool showProjectSettings, bool force) } m_timelineArea->setEnabled(true); m_projectList->setEnabled(true); - - KdenliveDoc *doc = new KdenliveDoc(KUrl(), projectFolder, m_commandStack, profileName, documentProperties, projectTracks, m_projectMonitor->render, m_notesWidget, this); + bool openBackup; + KdenliveDoc *doc = new KdenliveDoc(KUrl(), projectFolder, m_commandStack, profileName, documentProperties, projectTracks, m_projectMonitor->render, m_notesWidget, &openBackup, this); doc->m_autosave = new KAutoSaveFile(KUrl(), doc); bool ok; TrackView *trackView = new TrackView(doc, &ok, this); @@ -1894,12 +1907,13 @@ bool MainWindow::saveFileAs(const QString &outputFileName) m_activeDocument->setModified(false); m_fileOpenRecent->addUrl(KUrl(outputFileName)); m_fileRevert->setEnabled(true); + m_undoView->stack()->setClean(); return true; } bool MainWindow::saveFileAs() { - QString outputFile = KFileDialog::getSaveFileName(m_activeDocument->projectFolder(), getMimeType()); + QString outputFile = KFileDialog::getSaveFileName(m_activeDocument->projectFolder(), getMimeType(false)); if (outputFile.isEmpty()) { return false; } @@ -1947,6 +1961,22 @@ void MainWindow::openLastFile() void MainWindow::openFile(const KUrl &url) { + // Make sure the url is a Kdenlive project file + KMimeType::Ptr mime = KMimeType::findByUrl(url); + if (mime.data()->is("application/x-compressed-tar")) { + // Opening a compressed project file, we need to process it + kDebug()<<"Opening archive, processing"; + ArchiveWidget *ar = new ArchiveWidget(url); + if (ar->exec() == QDialog::Accepted) openFile(KUrl(ar->extractedProjectFile())); + delete ar; + return; + } + if (!url.fileName().endsWith(".kdenlive")) { + // This is not a Kdenlive project file, abort loading + KMessageBox::sorry(this, i18n("File %1 is not a Kdenlive project file", url.path())); + return; + } + // Check if the document is already opened const int ct = m_timelineArea->count(); bool isOpened = false; @@ -1998,7 +2028,8 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale) delete m_stopmotion; m_stopmotion = NULL; } - + + m_timer.start(); KProgressDialog progressDialog(this, i18n("Loading project"), i18n("Loading project")); progressDialog.setAllowCancel(false); progressDialog.progressBar()->setMaximum(4); @@ -2006,7 +2037,8 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale) progressDialog.progressBar()->setValue(0); qApp->processEvents(); - KdenliveDoc *doc = new KdenliveDoc(url, KdenliveSettings::defaultprojectfolder(), m_commandStack, KdenliveSettings::default_profile(), QMap (), QPoint(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()), m_projectMonitor->render, m_notesWidget, this, &progressDialog); + bool openBackup; + KdenliveDoc *doc = new KdenliveDoc(url, KdenliveSettings::defaultprojectfolder(), m_commandStack, KdenliveSettings::default_profile(), QMap (), QPoint(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()), m_projectMonitor->render, m_notesWidget, &openBackup, this, &progressDialog); progressDialog.progressBar()->setValue(1); progressDialog.progressBar()->setMaximum(4); @@ -2053,6 +2085,7 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale) m_clipMonitor->refreshMonitor(true); progressDialog.progressBar()->setValue(4); + if (openBackup) slotOpenBackupDialog(url); } void MainWindow::recoverFiles(QList staleFiles) @@ -2176,6 +2209,7 @@ void MainWindow::slotEditProjectSettings() { QPoint p = m_activeDocument->getTracksCount(); ProjectSettings *w = new ProjectSettings(m_projectList, m_activeTimeline->projectView()->extractTransitionsLumas(), p.x(), p.y(), m_activeDocument->projectFolder().path(), true, !m_activeDocument->isModified(), this); + connect(w, SIGNAL(disableProxies()), this, SLOT(slotDisableProxies())); if (w->exec() == QDialog::Accepted) { QString profile = w->selectedProfile(); @@ -2224,10 +2258,15 @@ void MainWindow::slotEditProjectSettings() delete w; } -void MainWindow::slotUpdateProjectProfile(const QString &profile) +void MainWindow::slotDisableProxies() { - double dar = m_activeDocument->dar(); + m_activeDocument->setDocumentProperty("enableproxy", QString::number((int) false)); + m_activeDocument->setModified(); + slotUpdateProxySettings(); +} +void MainWindow::slotUpdateProjectProfile(const QString &profile) +{ // Recreate the stopmotion widget if profile changes if (m_stopmotion) { delete m_stopmotion; @@ -2250,8 +2289,6 @@ void MainWindow::slotUpdateProjectProfile(const QString &profile) m_projectList->updateProjectFormat(m_activeDocument->timecode()); if (m_renderWidget) m_renderWidget->setProfile(m_activeDocument->mltProfile()); m_timelineArea->setTabText(m_timelineArea->currentIndex(), m_activeDocument->description()); - //m_activeDocument->clipManager()->resetProducersList(m_projectMonitor->render->producersList()); - if (dar != m_activeDocument->dar()) m_projectList->reloadClipThumbnails(); if (updateFps) m_activeTimeline->updateProjectFps(); m_activeDocument->setModified(true); m_commandStack->activeStack()->clear(); @@ -2366,7 +2403,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha disconnect(m_projectList, SIGNAL(projectModified()), m_activeDocument, SLOT(setModified())); disconnect(m_projectList, SIGNAL(updateProfile(const QString &)), this, SLOT(slotUpdateProjectProfile(const QString &))); - disconnect(m_projectMonitor->render, SIGNAL(refreshDocumentProducers()), m_activeDocument, SLOT(checkProjectClips())); + disconnect(m_projectMonitor->render, SIGNAL(refreshDocumentProducers(bool, bool)), m_activeDocument, SLOT(checkProjectClips(bool, bool))); disconnect(m_activeDocument, SIGNAL(guidesUpdated()), this, SLOT(slotGuidesUpdated())); disconnect(m_activeDocument, SIGNAL(addProjectClip(DocClipBase *, bool)), m_projectList, SLOT(slotAddClip(DocClipBase *, bool))); @@ -2374,7 +2411,6 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha disconnect(m_activeDocument, SIGNAL(signalDeleteProjectClip(const QString &)), this, SLOT(slotDeleteClip(const QString &))); disconnect(m_activeDocument, SIGNAL(updateClipDisplay(const QString &)), m_projectList, SLOT(slotUpdateClip(const QString &))); disconnect(m_activeDocument, SIGNAL(selectLastAddedClip(const QString &)), m_projectList, SLOT(slotSelectClip(const QString &))); - disconnect(m_activeDocument, SIGNAL(deleteTimelineClip(const QString &)), m_activeTimeline, SLOT(slotDeleteClip(const QString &))); disconnect(m_activeTimeline->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), m_effectStack, SLOT(slotClipItemSelected(ClipItem*, int))); disconnect(m_activeTimeline->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), this, SLOT(slotActivateEffectStackView(ClipItem*, int, bool))); disconnect(m_activeTimeline->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), m_projectMonitor, SLOT(slotSetSelectedClip(ClipItem*))); @@ -2408,7 +2444,6 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha m_effectStack->clear(); } //m_activeDocument->setRenderer(NULL); - disconnect(m_projectList, SIGNAL(clipSelected(DocClipBase *)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *))); disconnect(m_projectList, SIGNAL(refreshClip(const QString &, bool)), m_monitorManager, SLOT(slotRefreshCurrentMonitor())); m_clipMonitor->stop(); } @@ -2418,7 +2453,6 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha m_projectList->setDocument(doc); m_transitionConfig->updateProjectFormat(doc->mltProfile(), doc->timecode(), doc->tracksList()); m_effectStack->updateProjectFormat(doc->mltProfile(), doc->timecode()); - connect(m_projectList, SIGNAL(clipSelected(DocClipBase *, QPoint)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *, QPoint))); connect(m_projectList, SIGNAL(refreshClip(const QString &, bool)), m_monitorManager, SLOT(slotRefreshCurrentMonitor())); connect(m_projectList, SIGNAL(refreshClip(const QString &, bool)), trackView->projectView(), SLOT(slotRefreshThumbs(const QString &, bool))); connect(m_projectList, SIGNAL(clipNeedsReload(const QString&, bool)), trackView->projectView(), SLOT(slotUpdateClip(const QString &, bool))); @@ -2430,7 +2464,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(m_projectList, SIGNAL(findInTimeline(const QString&)), this, SLOT(slotClipInTimeline(const QString&))); - connect(trackView, SIGNAL(cursorMoved()), m_projectMonitor, SLOT(activateMonitor())); + //connect(trackView, SIGNAL(cursorMoved()), m_projectMonitor, SLOT(activateMonitor())); connect(trackView, SIGNAL(insertTrack(int)), this, SLOT(slotInsertTrack(int))); connect(trackView, SIGNAL(deleteTrack(int)), this, SLOT(slotDeleteTrack(int))); connect(trackView, SIGNAL(configTrack(int)), this, SLOT(slotConfigTrack(int))); @@ -2443,7 +2477,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(m_projectMonitor, SIGNAL(zoneUpdated(QPoint)), doc, SLOT(setModified())); connect(m_clipMonitor, SIGNAL(zoneUpdated(QPoint)), doc, SLOT(setModified())); connect(m_projectMonitor, SIGNAL(durationChanged(int)), trackView, SLOT(setDuration(int))); - connect(m_projectMonitor->render, SIGNAL(refreshDocumentProducers()), doc, SLOT(checkProjectClips())); + connect(m_projectMonitor->render, SIGNAL(refreshDocumentProducers(bool, bool)), doc, SLOT(checkProjectClips(bool, bool))); connect(doc, SIGNAL(addProjectClip(DocClipBase *, bool)), m_projectList, SLOT(slotAddClip(DocClipBase *, bool))); connect(doc, SIGNAL(resetProjectList()), m_projectList, SLOT(slotResetProjectList())); @@ -2451,9 +2485,10 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(doc, SIGNAL(updateClipDisplay(const QString &)), m_projectList, SLOT(slotUpdateClip(const QString &))); connect(doc, SIGNAL(selectLastAddedClip(const QString &)), m_projectList, SLOT(slotSelectClip(const QString &))); - connect(doc, SIGNAL(deleteTimelineClip(const QString &)), trackView, SLOT(slotDeleteClip(const QString &))); connect(doc, SIGNAL(docModified(bool)), this, SLOT(slotUpdateDocumentState(bool))); connect(doc, SIGNAL(guidesUpdated()), this, SLOT(slotGuidesUpdated())); + connect(doc, SIGNAL(saveTimelinePreview(const QString)), trackView, SLOT(slotSaveTimelinePreview(const QString))); + connect(m_notesWidget, SIGNAL(textChanged()), doc, SLOT(setModified())); connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), m_effectStack, SLOT(slotClipItemSelected(ClipItem*, int))); @@ -2491,6 +2526,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(trackView->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(activateMonitor())); connect(trackView, SIGNAL(zoneMoved(int, int)), this, SLOT(slotZoneMoved(int, int))); connect(m_projectList, SIGNAL(loadingIsOver()), trackView->projectView(), SLOT(slotUpdateAllThumbs())); + connect(m_projectList, SIGNAL(loadingIsOver()), this, SLOT(slotElapsedTime())); connect(m_projectList, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int))); connect(m_projectList, SIGNAL(updateRenderStatus()), this, SLOT(slotCheckRenderStatus())); @@ -3154,6 +3190,7 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip) // any type of clip but a title ClipProperties *dia = new ClipProperties(clip, m_activeDocument->timecode(), m_activeDocument->fps(), this); connect(dia, SIGNAL(addMarker(const QString &, GenTime, QString)), m_activeTimeline->projectView(), SLOT(slotAddClipMarker(const QString &, GenTime, QString))); + connect(dia, SIGNAL(deleteProxy(const QString)), m_projectList, SLOT(slotDeleteProxy(const QString))); connect(dia, SIGNAL(applyNewClipProperties(const QString, QMap , QMap , bool, bool)), this, SLOT(slotApplyNewClipProperties(const QString, QMap , QMap , bool, bool))); dia->show(); } @@ -3499,7 +3536,7 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event) } -void MainWindow::slotSaveZone(Render *render, QPoint zone) +void MainWindow::slotSaveZone(Render *render, QPoint zone, DocClipBase *baseClip, KUrl path) { KDialog *dialog = new KDialog(this); dialog->setCaption("Save clip zone"); @@ -3510,9 +3547,15 @@ void MainWindow::slotSaveZone(Render *render, QPoint zone) QVBoxLayout *vbox = new QVBoxLayout(widget); QLabel *label1 = new QLabel(i18n("Save clip zone as:"), this); - QString path = m_activeDocument->projectFolder().path(KUrl::AddTrailingSlash); - path.append("untitled.mlt"); - KUrlRequester *url = new KUrlRequester(KUrl(path), this); + if (path.isEmpty()) { + QString tmppath = m_activeDocument->projectFolder().path(KUrl::AddTrailingSlash); + if (baseClip == NULL) tmppath.append("untitled.mlt"); + else { + tmppath.append((baseClip->name().isEmpty() ? baseClip->fileURL().fileName() : baseClip->name()) + "-" + QString::number(zone.x()).rightJustified(4, '0') + ".mlt"); + } + path = KUrl(tmppath); + } + KUrlRequester *url = new KUrlRequester(path, this); url->setFilter("video/mlt-playlist"); QLabel *label2 = new QLabel(i18n("Description:"), this); KLineEdit *edit = new KLineEdit(this); @@ -3520,27 +3563,54 @@ void MainWindow::slotSaveZone(Render *render, QPoint zone) vbox->addWidget(url); vbox->addWidget(label2); vbox->addWidget(edit); - if (dialog->exec() == QDialog::Accepted) - render->saveZone(url->url(), edit->text(), zone); + if (dialog->exec() == QDialog::Accepted) { + if (QFile::exists(url->url().path())) { + if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", url->url().path())) == KMessageBox::No) { + slotSaveZone(render, zone, baseClip, url->url()); + return; + } + } + if (baseClip && !baseClip->fileURL().isEmpty()) { + // create zone from clip url, so that we don't have problems with proxy clips + QProcess p; +#if QT_VERSION >= 0x040600 + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + env.remove("MLT_PROFILE"); + p.setProcessEnvironment(env); +#else + QStringList env = QProcess::systemEnvironment(); + env << "MLT_PROFILE='\0'"; + p.setEnvironment(env); +#endif + p.start(KdenliveSettings::rendererpath(), QStringList() << baseClip->fileURL().path() << "in=" + QString::number(zone.x()) << "out=" + QString::number(zone.y()) << "-consumer" << "xml:" + url->url().path()); + if (!p.waitForStarted(3000)) { + KMessageBox::sorry(this, i18n("Cannot start MLT's renderer:\n%1", KdenliveSettings::rendererpath())); + } + else if (!p.waitForFinished(5000)) { + KMessageBox::sorry(this, i18n("Timeout while creating xml output")); + } + } + else render->saveZone(url->url(), edit->text(), zone); + } } void MainWindow::slotSetInPoint() { - if (m_clipMonitor->isActive()) + if (m_clipMonitor->isActive()) { m_clipMonitor->slotSetZoneStart(); - else + } else { m_projectMonitor->slotSetZoneStart(); - //else m_activeTimeline->projectView()->setInPoint(); + } } void MainWindow::slotSetOutPoint() { - if (m_clipMonitor->isActive()) + if (m_clipMonitor->isActive()) { m_clipMonitor->slotSetZoneEnd(); - else + } else { m_projectMonitor->slotSetZoneEnd(); - // else m_activeTimeline->projectView()->setOutPoint(); + } } void MainWindow::slotResizeItemStart() @@ -3651,21 +3721,15 @@ void MainWindow::slotShowTimeline(bool show) } } -void MainWindow::slotMaximizeCurrent(bool /*show*/) +void MainWindow::slotMaximizeCurrent(bool) { //TODO: is there a way to maximize current widget? - //if (show == true) - { - m_timelineState = saveState(); - QWidget *par = focusWidget()->parentWidget(); - while (par->parentWidget() && par->parentWidget() != this) - par = par->parentWidget(); - kDebug() << "CURRENT WIDGET: " << par->objectName(); - } - /*else { - //centralWidget()->setHidden(false); - //restoreState(m_timelineState); - }*/ + + m_timelineState = saveState(); + QWidget *par = focusWidget()->parentWidget(); + while (par->parentWidget() && par->parentWidget() != this) + par = par->parentWidget(); + kDebug() << "CURRENT WIDGET: " << par->objectName(); } void MainWindow::loadTranscoders() @@ -3812,24 +3876,40 @@ void MainWindow::slotPrepareRendering(bool scriptExport, bool zoneOnly, const QS if (m_renderWidget->automaticAudioExport()) { exportAudio = m_activeTimeline->checkProjectAudio(); } else exportAudio = m_renderWidget->selectedAudioExport(); + + // Set playlist audio volume to 100% + QDomDocument doc; + doc.setContent(playlistContent); + QDomElement tractor = doc.documentElement().firstChildElement("tractor"); + if (!tractor.isNull()) { + QDomNodeList props = tractor.elementsByTagName("property"); + for (int i = 0; i < props.count(); i++) { + if (props.at(i).toElement().attribute("name") == "meta.volume") { + props.at(i).firstChild().setNodeValue("1"); + break; + } + } + } // Do we want proxy rendering if (m_projectList->useProxy() && !m_renderWidget->proxyRendering()) { - QDomDocument doc; - doc.setContent(playlistContent); QString root = doc.documentElement().attribute("root"); // replace proxy clips with originals QMap proxies = m_projectList->getProxies(); - QDomNodeList producers = doc.elementsByTagName("producer"); QString producerResource; QString suffix; for (uint n = 0; n < producers.length(); n++) { QDomElement e = producers.item(n).toElement(); producerResource = EffectsList::property(e, "resource"); + if (producerResource.isEmpty()) continue; + if (!producerResource.startsWith("/")) { + producerResource.prepend(root + "/"); + } if (producerResource.contains('?')) { + // slowmotion producer suffix = "?" + producerResource.section('?', 1); producerResource = producerResource.section('?', 0, 0); } @@ -3841,12 +3921,6 @@ void MainWindow::slotPrepareRendering(bool scriptExport, bool zoneOnly, const QS // sometimes have different ratio than original clips EffectsList::removeProperty(e, "aspect_ratio"); } - else if (!root.isEmpty() && producerResource.startsWith(root) && proxies.contains(producerResource.remove(0, root.count() + 1))) { - EffectsList::setProperty(e, "resource", proxies.value(producerResource.remove(0, root.count() + 1)) + suffix); - // We need to delete the "aspect_ratio" property because proxy clips - // sometimes have different ratio than original clips - EffectsList::removeProperty(e, "aspect_ratio"); - } } } @@ -3862,8 +3936,8 @@ void MainWindow::slotPrepareRendering(bool scriptExport, bool zoneOnly, const QS playlistContent.replace(key, i.value()); } }*/ - playlistContent = doc.toString(); } + playlistContent = doc.toString(); // Do save scenelist QFile file(playlistPath); @@ -3940,11 +4014,12 @@ void MainWindow::slotChangePalette(QAction *action, const QString &themename) plt = QApplication::desktop()->palette(); } else { KSharedConfigPtr config = KSharedConfig::openConfig(theme); - - // Since there currently is a bug (or feature change) in KGlobalSettings::createApplicationPalette, we need - // to do the palette loading stuff ourselves... - //plt = KGlobalSettings::createApplicationPalette(config); - + +#if KDE_IS_VERSION(4,6,3) + plt = KGlobalSettings::createNewApplicationPalette(config); +#else + // Since there was a bug in createApplicationPalette in KDE < 4.6.3 we need + // to do the palette loading stuff ourselves. (https://bugs.kde.org/show_bug.cgi?id=263497) QPalette::ColorGroup states[3] = { QPalette::Active, QPalette::Inactive, QPalette::Disabled }; // TT thinks tooltips shouldn't use active, so we use our active colors for all states @@ -3978,7 +4053,9 @@ void MainWindow::slotChangePalette(QAction *action, const QString &themename) plt.setBrush( state, QPalette::Link, schemeView.foreground( KColorScheme::LinkText ) ); plt.setBrush( state, QPalette::LinkVisited, schemeView.foreground( KColorScheme::VisitedText ) ); } +#endif } + kapp->setPalette(plt); const QObjectList children = statusBar()->children(); @@ -4100,11 +4177,15 @@ void MainWindow::slotSwitchTitles() slotShowTitleBars(!KdenliveSettings::showtitlebars()); } -QString MainWindow::getMimeType() +QString MainWindow::getMimeType(bool open) { QString mimetype = "application/x-kdenlive"; KMimeType::Ptr mime = KMimeType::mimeType(mimetype); - if (!mime) mimetype = "*.kdenlive"; + if (!mime) { + mimetype = "*.kdenlive"; + if (open) mimetype.append(" *.tar.gz"); + } + else if (open) mimetype.append(" application/x-compressed-tar"); return mimetype; } @@ -4151,9 +4232,13 @@ void MainWindow::slotDoUpdateGfxScopeFrameRequest() m_projectMonitor->render->sendFrameForAnalysis = false; } m_clipMonitor->render->sendFrameForAnalysis = false; + if (m_recMonitor) + m_recMonitor->analyseFrames(false); } else { m_projectMonitor->render->sendFrameForAnalysis = true; m_clipMonitor->render->sendFrameForAnalysis = true; + if (m_recMonitor) + m_recMonitor->analyseFrames(true); } } @@ -4187,28 +4272,35 @@ void MainWindow::slotDoUpdateAudioScopeFrameRequest() void MainWindow::slotUpdateColorScopes() { bool request = false; + kDebug()<<"// UPDATE SCOPES"; for (int i = 0; i < m_gfxScopesList.count(); i++) { // Check if we need the renderer to send a new frame for update if (!m_gfxScopesList.at(i)->widget()->visibleRegion().isEmpty() && !(static_cast(m_gfxScopesList.at(i)->widget())->autoRefreshEnabled())) request = true; - static_cast(m_gfxScopesList.at(i)->widget())->slotActiveMonitorChanged(m_clipMonitor->isActive()); + static_cast(m_gfxScopesList.at(i)->widget())->slotActiveMonitorChanged(); } - if (request) { - if (m_clipMonitor->isActive()) m_clipMonitor->render->sendFrameUpdate(); - else m_projectMonitor->render->sendFrameUpdate(); + if (request && m_monitorManager->activeRenderer()) { + m_monitorManager->activeRenderer()->sendFrameUpdate(); + } +} + +void MainWindow::slotClearColorScopes() +{ + for (int i = 0; i < m_gfxScopesList.count(); i++) { + static_cast(m_gfxScopesList.at(i)->widget())->slotClearMonitor(); } } void MainWindow::slotOpenStopmotion() { if (m_stopmotion == NULL) { - m_stopmotion = new StopmotionWidget(m_activeDocument->projectFolder(), m_stopmotion_actions->actions(), this); + m_stopmotion = new StopmotionWidget(m_monitorManager, m_activeDocument->projectFolder(), m_stopmotion_actions->actions(), this); connect(m_stopmotion, SIGNAL(addOrUpdateSequence(const QString)), m_projectList, SLOT(slotAddOrUpdateSequence(const QString))); - for (int i = 0; i < m_gfxScopesList.count(); i++) { + //for (int i = 0; i < m_gfxScopesList.count(); i++) { // Check if we need the renderer to send a new frame for update /*if (!m_scopesList.at(i)->widget()->visibleRegion().isEmpty() && !(static_cast(m_scopesList.at(i)->widget())->autoRefreshEnabled())) request = true;*/ - connect(m_stopmotion, SIGNAL(gotFrame(QImage)), static_cast(m_gfxScopesList.at(i)->widget()), SLOT(slotRenderZoneUpdated(QImage))); + //connect(m_stopmotion, SIGNAL(gotFrame(QImage)), static_cast(m_gfxScopesList.at(i)->widget()), SLOT(slotRenderZoneUpdated(QImage))); //static_cast(m_scopesList.at(i)->widget())->slotMonitorCapture(); - } + //} } m_stopmotion->show(); } @@ -4230,6 +4322,63 @@ void MainWindow::slotUpdateProxySettings() m_projectList->updateProxyConfig(); } +void MainWindow::slotInsertNotesTimecode() +{ + int frames = m_projectMonitor->render->seekPosition().frames(m_activeDocument->fps()); + QString position = m_activeDocument->timecode().getTimecodeFromFrames(frames); + m_notesWidget->insertHtml("" + position + " "); +} + +void MainWindow::slotArchiveProject() +{ + QList list = m_projectList->documentClipList(); + QDomDocument doc = m_activeDocument->xmlSceneList(m_projectMonitor->sceneList(), m_projectList->expandedFolders()); + ArchiveWidget *d = new ArchiveWidget(m_activeDocument->url().fileName(), doc, list, m_activeTimeline->projectView()->extractTransitionsLumas(), this); + d->exec(); +} + + +void MainWindow::slotOpenBackupDialog(const KUrl url) +{ + KUrl projectFile; + KUrl projectFolder; + QString projectId; + kDebug()<<"// BACKUP URL: "<projectFolder(); + projectFile = m_activeDocument->url(); + projectId = m_activeDocument->getDocumentProperty("documentid"); + } + + BackupWidget *dia = new BackupWidget(projectFile, projectFolder, projectId, this); + if (dia->exec() == QDialog::Accepted) { + QString requestedBackup = dia->selectedFile(); + m_activeDocument->backupLastSavedVersion(projectFile.path()); + closeCurrentDocument(false); + doOpenFile(KUrl(requestedBackup), NULL); + m_activeDocument->setUrl(projectFile); + m_activeDocument->setModified(true); + setCaption(m_activeDocument->description()); + } + delete dia; +} + +void MainWindow::slotBlockClipMonitor(const QString id) +{ + if (m_clipMonitor->activeClip() && m_clipMonitor->activeClip()->getId() == id) m_clipMonitor->slotSetXml(NULL); +} + + +void MainWindow::slotElapsedTime() +{ + kDebug()<<"-----------------------------------------\n"<<"Time elapsed: "<