X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmainwindow.cpp;h=7990b3b6cd7da381bd0c7ad40687009866de81c9;hb=6f8f092f36ef2a23f4d4cf44f75a48f219fcecc6;hp=488975e9079595698f7b17a6e5be87f367c7a665;hpb=000c8e2337fe448a6e35896f3ef1a95dedbb39c7;p=kdenlive diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 488975e9..7990b3b6 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -81,6 +81,7 @@ #include #include #include +#include #include #include @@ -151,6 +152,9 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent m_projectListDock->setWidget(m_projectList); addDockWidget(Qt::TopDockWidgetArea, m_projectListDock); + m_shortcutRemoveFocus = new QShortcut(QKeySequence("Esc"), this); + connect(m_shortcutRemoveFocus, SIGNAL(activated()), this, SLOT(slotRemoveFocus())); + m_effectListDock = new QDockWidget(i18n("Effect List"), this); m_effectListDock->setObjectName("effect_list"); m_effectList = new EffectsListView(); @@ -172,25 +176,27 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent addDockWidget(Qt::TopDockWidgetArea, m_transitionConfigDock); KdenliveSettings::setCurrent_profile(KdenliveSettings::default_profile()); - m_fileOpenRecent = KStandardAction::openRecent(this, SLOT(openFile(const KUrl &)), - actionCollection()); + m_fileOpenRecent = KStandardAction::openRecent(this, SLOT(openFile(const KUrl &)), actionCollection()); readOptions(); + m_fileRevert = KStandardAction::revert(this, SLOT(slotRevert()), actionCollection()); + m_fileRevert->setEnabled(false); //slotDetectAudioDriver(); m_clipMonitorDock = new QDockWidget(i18n("Clip Monitor"), this); m_clipMonitorDock->setObjectName("clip_monitor"); - m_clipMonitor = new Monitor("clip", m_monitorManager, this); + m_clipMonitor = new Monitor("clip", m_monitorManager, QString(), this); m_clipMonitorDock->setWidget(m_clipMonitor); addDockWidget(Qt::TopDockWidgetArea, m_clipMonitorDock); //m_clipMonitor->stop(); m_projectMonitorDock = new QDockWidget(i18n("Project Monitor"), this); m_projectMonitorDock->setObjectName("project_monitor"); - m_projectMonitor = new Monitor("project", m_monitorManager, this); + m_projectMonitor = new Monitor("project", m_monitorManager, QString(), this); m_projectMonitorDock->setWidget(m_projectMonitor); addDockWidget(Qt::TopDockWidgetArea, m_projectMonitorDock); +#ifndef Q_WS_MAC m_recMonitorDock = new QDockWidget(i18n("Record Monitor"), this); m_recMonitorDock->setObjectName("record_monitor"); m_recMonitor = new RecMonitor("record", this); @@ -199,6 +205,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent connect(m_recMonitor, SIGNAL(addProjectClip(KUrl)), this, SLOT(slotAddProjectClip(KUrl))); connect(m_recMonitor, SIGNAL(showConfigDialog(int, int)), this, SLOT(slotPreferences(int, int))); +#endif m_undoViewDock = new QDockWidget(i18n("Undo History"), this); m_undoViewDock->setObjectName("undo_history"); @@ -223,11 +230,14 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent tabifyDockWidget(m_clipMonitorDock, m_projectMonitorDock); +#ifndef Q_WS_MAC tabifyDockWidget(m_clipMonitorDock, m_recMonitorDock); +#endif setCentralWidget(m_timelineArea); setupGUI(); + /*ScriptingPart* sp = new ScriptingPart(this, QStringList()); guiFactory()->addClient(sp);*/ @@ -352,7 +362,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent 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_effectList, SIGNAL(addEffect(QDomElement)), this, SLOT(slotAddEffect(QDomElement))); + 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); @@ -362,13 +372,12 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent // precedence, then "openlastproject", then just a plain empty file. // If opening Url fails, openlastproject will _not_ be used. if (!Url.isEmpty()) { - openFile(Url); - } else { - if (KdenliveSettings::openlastproject()) { - openLastFile(); - } - } - if (m_timelineArea->count() == 0) { + // delay loading so that the window shows up + m_startUrl = Url; + QTimer::singleShot(500, this, SLOT(openFile())); + } else if (KdenliveSettings::openlastproject()) { + QTimer::singleShot(500, this, SLOT(openLastFile())); + } else { //if (m_timelineArea->count() == 0) { newFile(false); } @@ -380,20 +389,21 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent void MainWindow::queryQuit() { - delete m_effectStack; - delete m_activeTimeline; - delete m_projectMonitor; - kDebug() << "// DEL MON 1 done"; - delete m_clipMonitor; - kDebug() << "// DEL MON 2 done"; - delete m_activeDocument; - Mlt::Factory::close(); - qApp->quit(); - /* - if (queryClose()) { - Mlt::Factory::close(); - kapp->quit(); - }*/ + if (queryClose()) { + if (m_projectMonitor) m_projectMonitor->stop(); + if (m_clipMonitor) m_clipMonitor->stop(); + delete m_effectStack; + delete m_activeTimeline; +#ifndef Q_WS_MAC + // This sometimes causes crash on exit on OS X for some reason. + delete m_projectMonitor; + delete m_clipMonitor; +#endif + delete m_activeDocument; + delete m_shortcutRemoveFocus; + Mlt::Factory::close(); + kapp->quit(); + } } //virtual @@ -402,7 +412,7 @@ bool MainWindow::queryClose() if (m_renderWidget) { int waitingJobs = m_renderWidget->waitingJobsCount(); if (waitingJobs > 0) { - switch (KMessageBox::warningYesNoCancel(this, i18n("You have %1 rendering jobs waiting in the queue.\nWhat do you want to do with these jobs?", waitingJobs), QString(), KGuiItem(i18n("Start them now")), KGuiItem(i18n("Delete them")))) { + switch (KMessageBox::warningYesNoCancel(this, i18np("You have 1 rendering job waiting in the queue.\nWhat do you want to do with this job?", "You have %1 rendering jobs waiting in the queue.\nWhat do you want to do with these jobs?", waitingJobs), QString(), KGuiItem(i18n("Start them now")), KGuiItem(i18n("Delete them")))) { case KMessageBox::Yes : // create script with waiting jobs and start it if (m_renderWidget->startWaitingRenderJobs() == false) return false; @@ -521,9 +531,12 @@ void MainWindow::readProperties(const KConfigGroup &config) void MainWindow::slotReloadEffects() { - initEffects::parseCustomEffectsFile(); + kDebug() << "START RELOAD; COUNR: " << m_customEffectsMenu->actions().count(); m_customEffectsMenu->clear(); + kDebug() << "START RELOAD; CLR: " << m_customEffectsMenu->actions().count(); + initEffects::parseCustomEffectsFile(); const QStringList effects = customEffects.effectNames(); + kDebug() << "NEW EFFS: " << effects; QAction *action; if (effects.isEmpty()) m_customEffectsMenu->setEnabled(false); else m_customEffectsMenu->setEnabled(true); @@ -597,14 +610,15 @@ void MainWindow::slotFullScreen() KToggleFullScreenAction::setFullScreen(this, actionCollection()->action("fullscreen")->isChecked()); } -void MainWindow::slotAddEffect(QDomElement effect, GenTime pos, int track) +void MainWindow::slotAddEffect(const QDomElement effect, GenTime pos, int track) { if (!m_activeDocument) return; if (effect.isNull()) { kDebug() << "--- ERROR, TRYING TO APPEND NULL EFFECT"; return; } - m_activeTimeline->projectView()->slotAddEffect(effect.cloneNode().toElement(), pos, track); + QDomElement effectToAdd = effect.cloneNode().toElement(); + m_activeTimeline->projectView()->slotAddEffect(effectToAdd, pos, track); } void MainWindow::slotRaiseMonitor(bool clipMonitor) @@ -623,9 +637,9 @@ void MainWindow::slotConnectMonitors() { m_projectList->setRenderer(m_projectMonitor->render); - connect(m_projectList, SIGNAL(receivedClipDuration(const QString &)), this, SLOT(slotUpdateClip(const QString &))); + //connect(m_projectList, SIGNAL(receivedClipDuration(const QString &)), this, SLOT(slotUpdateClip(const QString &))); connect(m_projectList, SIGNAL(showClipProperties(DocClipBase *)), this, SLOT(slotShowClipProperties(DocClipBase *))); - connect(m_projectList, SIGNAL(getFileProperties(const QDomElement &, const QString &, bool)), m_projectMonitor->render, SLOT(getFileProperties(const QDomElement &, const QString &, bool))); + connect(m_projectList, SIGNAL(getFileProperties(const QDomElement, const QString &, bool)), m_projectMonitor->render, SLOT(getFileProperties(const QDomElement, const QString &, bool))); connect(m_projectMonitor->render, SIGNAL(replyGetImage(const QString &, const QPixmap &)), m_projectList, SLOT(slotReplyGetImage(const QString &, const QPixmap &))); connect(m_projectMonitor->render, SIGNAL(replyGetFileProperties(const QString &, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &, bool)), m_projectList, SLOT(slotReplyGetFileProperties(const QString &, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &, bool))); @@ -661,6 +675,8 @@ void MainWindow::setupActions() m_timecodeFormat = new KComboBox(this); m_timecodeFormat->addItem(i18n("hh:mm:ss::ff")); m_timecodeFormat->addItem(i18n("Frames")); + if (KdenliveSettings::frametimecode()) m_timecodeFormat->setCurrentIndex(1); + connect(m_timecodeFormat, SIGNAL(activated(int)), this, SLOT(slotUpdateTimecodeFormat(int))); m_statusProgressBar = new QProgressBar(this); m_statusProgressBar->setMinimum(0); @@ -668,29 +684,26 @@ void MainWindow::setupActions() m_statusProgressBar->setMaximumWidth(150); m_statusProgressBar->setVisible(false); - QWidget *w = new QWidget; - - QHBoxLayout *layout = new QHBoxLayout; - w->setLayout(layout); - layout->setContentsMargins(5, 0, 5, 0); - QToolBar *toolbar = new QToolBar("statusToolBar", this); - - + KToolBar *toolbar = new KToolBar("statusToolBar", this, Qt::BottomToolBarArea); + toolbar->setMovable(false); m_toolGroup = new QActionGroup(this); - - QString style1 = "QToolButton {background-color: rgba(230, 230, 230, 220); border-style: inset; border:1px solid #999999;border-radius: 3px;margin: 0px 3px;padding: 0px;} QToolButton:checked { background-color: rgba(224, 224, 0, 100); border-style: inset; border:1px solid #cc6666;border-radius: 3px;}"; + statusBar()->setStyleSheet(QString("QStatusBar QLabel {font-size:%1pt;} QStatusBar::item { border: 0px; font-size:%1pt;padding:0px; }").arg(statusBar()->font().pointSize())); + QString style1 = "QToolBar { border: 0px } QToolButton {background-color: rgba(230, 230, 230, 220); border-style: inset; border:1px solid #999999;border-radius: 3px;margin: 0px 3px;padding: 0px;} QToolButton:checked { background-color: rgba(224, 224, 0, 100); border-style: inset; border:1px solid #cc6666;border-radius: 3px;}"; m_buttonSelectTool = new KAction(KIcon("kdenlive-select-tool"), i18n("Selection tool"), this); + m_buttonSelectTool->setShortcut(i18nc("Selection tool shortcut", "s")); toolbar->addAction(m_buttonSelectTool); m_buttonSelectTool->setCheckable(true); m_buttonSelectTool->setChecked(true); m_buttonRazorTool = new KAction(KIcon("edit-cut"), i18n("Razor tool"), this); + m_buttonRazorTool->setShortcut(i18nc("Razor tool shortcut", "x")); toolbar->addAction(m_buttonRazorTool); m_buttonRazorTool->setCheckable(true); m_buttonRazorTool->setChecked(false); m_buttonSpacerTool = new KAction(KIcon("kdenlive-spacer-tool"), i18n("Spacer tool"), this); + m_buttonSpacerTool->setShortcut(i18nc("Spacer tool shortcut", "m")); toolbar->addAction(m_buttonSpacerTool); m_buttonSpacerTool->setCheckable(true); m_buttonSpacerTool->setChecked(false); @@ -702,17 +715,18 @@ void MainWindow::setupActions() toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly); QWidget * actionWidget; + int max = toolbar->iconSizeDefault() + 2; actionWidget = toolbar->widgetForAction(m_buttonSelectTool); - actionWidget->setMaximumWidth(24); - actionWidget->setMinimumHeight(18); + actionWidget->setMaximumWidth(max); + actionWidget->setMaximumHeight(max - 4); actionWidget = toolbar->widgetForAction(m_buttonRazorTool); - actionWidget->setMaximumWidth(24); - actionWidget->setMinimumHeight(18); + actionWidget->setMaximumWidth(max); + actionWidget->setMaximumHeight(max - 4); actionWidget = toolbar->widgetForAction(m_buttonSpacerTool); - actionWidget->setMaximumWidth(24); - actionWidget->setMinimumHeight(18); + actionWidget->setMaximumWidth(max); + actionWidget->setMaximumHeight(max - 4); toolbar->setStyleSheet(style1); connect(m_toolGroup, SIGNAL(triggered(QAction *)), this, SLOT(slotChangeTool(QAction *))); @@ -724,8 +738,8 @@ void MainWindow::setupActions() connect(m_buttonFitZoom, SIGNAL(triggered()), this, SLOT(slotFitZoom())); actionWidget = toolbar->widgetForAction(m_buttonFitZoom); - actionWidget->setMaximumWidth(24); - actionWidget->setMinimumHeight(18); + actionWidget->setMaximumWidth(max); + actionWidget->setMaximumHeight(max - 4); m_zoomSlider = new QSlider(Qt::Horizontal, this); m_zoomSlider->setMaximum(13); @@ -733,18 +747,6 @@ void MainWindow::setupActions() m_zoomSlider->setMaximumWidth(150); m_zoomSlider->setMinimumWidth(100); - - const int contentHeight = QFontMetrics(w->font()).height() + 8; - - QString style = "QSlider::groove:horizontal { background-color: rgba(230, 230, 230, 220);border: 1px solid #999999;height: 8px;border-radius: 3px;margin-top:3px }"; - style.append("QSlider::handle:horizontal { background-color: white; border: 1px solid #999999;width: 9px;margin: -2px 0;border-radius: 3px; }"); - - m_zoomSlider->setStyleSheet(style); - - //m_zoomSlider->height() + 5; - statusBar()->setMinimumHeight(contentHeight); - - toolbar->addWidget(m_zoomSlider); m_buttonVideoThumbs = new KAction(KIcon("kdenlive-show-videothumb"), i18n("Show video thumbnails"), this); @@ -770,34 +772,32 @@ void MainWindow::setupActions() m_buttonSnap->setCheckable(true); m_buttonSnap->setChecked(KdenliveSettings::snaptopoints()); connect(m_buttonSnap, SIGNAL(triggered()), this, SLOT(slotSwitchSnap())); - layout->addWidget(toolbar); - actionWidget = toolbar->widgetForAction(m_buttonVideoThumbs); - actionWidget->setMaximumWidth(24); - actionWidget->setMinimumHeight(18); + actionWidget->setMaximumWidth(max); + actionWidget->setMaximumHeight(max - 4); actionWidget = toolbar->widgetForAction(m_buttonAudioThumbs); - actionWidget->setMaximumWidth(24); - actionWidget->setMinimumHeight(18); + actionWidget->setMaximumWidth(max); + actionWidget->setMaximumHeight(max - 4); actionWidget = toolbar->widgetForAction(m_buttonShowMarkers); - actionWidget->setMaximumWidth(24); - actionWidget->setMinimumHeight(18); + actionWidget->setMaximumWidth(max); + actionWidget->setMaximumHeight(max - 4); actionWidget = toolbar->widgetForAction(m_buttonSnap); - actionWidget->setMaximumWidth(24); - actionWidget->setMinimumHeight(18); + actionWidget->setMaximumWidth(max); + actionWidget->setMaximumHeight(max - 4); m_messageLabel = new StatusBarMessageLabel(this); m_messageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding); statusBar()->addWidget(m_messageLabel, 10); statusBar()->addWidget(m_statusProgressBar, 0); - statusBar()->addPermanentWidget(w); + statusBar()->addPermanentWidget(toolbar); statusBar()->insertPermanentFixedItem("00:00:00:00", ID_TIMELINE_POS); statusBar()->addPermanentWidget(m_timecodeFormat); - statusBar()->setMaximumHeight(statusBar()->font().pointSize() * 4); + //statusBar()->setMaximumHeight(statusBar()->font().pointSize() * 3); collection->addAction("select_tool", m_buttonSelectTool); collection->addAction("razor_tool", m_buttonRazorTool); @@ -853,6 +853,10 @@ void MainWindow::setupActions() projectRender->setShortcut(Qt::CTRL + Qt::Key_Return); connect(projectRender, SIGNAL(triggered(bool)), this, SLOT(slotRenderProject())); + KAction* projectClean = new KAction(KIcon("edit-clear"), i18n("Clean Project"), this); + collection->addAction("project_clean", projectClean); + connect(projectClean, SIGNAL(triggered(bool)), this, SLOT(slotCleanProject())); + KAction* monitorPlay = new KAction(KIcon("media-playback-start"), i18n("Play"), this); KShortcut playShortcut; playShortcut.setPrimary(Qt::Key_Space); @@ -875,7 +879,7 @@ void MainWindow::setupActions() collection->addAction("dvd_wizard", dvdWizard); connect(dvdWizard, SIGNAL(triggered(bool)), this, SLOT(slotDvdWizard())); - KAction *transcodeClip = new KAction(KIcon("edit-copy"), i18n("Transcode Clip"), this); + KAction *transcodeClip = new KAction(KIcon("edit-copy"), i18n("Transcode Clips"), this); collection->addAction("transcode_clip", transcodeClip); connect(transcodeClip, SIGNAL(triggered(bool)), this, SLOT(slotTranscodeClip())); @@ -1202,15 +1206,17 @@ void MainWindow::readOptions() KConfigGroup initialGroup(config, "version"); bool upgrade = false; if (initialGroup.exists()) { - if (initialGroup.readEntry("version", QString()).section(' ', 0, 0) != QString(version).section(' ', 0, 0)) + if (initialGroup.readEntry("version", QString()).section(' ', 0, 0) != QString(version).section(' ', 0, 0)) { upgrade = true; + } if (initialGroup.readEntry("version") == "0.7") { //Add new settings from 0.7.1 if (KdenliveSettings::defaultprojectfolder().isEmpty()) { QString path = QDir::homePath() + "/kdenlive"; - if (KStandardDirs::makeDir(path) == false) kDebug() << "/// ERROR CREATING PROJECT FOLDER: " << path; - KdenliveSettings::setDefaultprojectfolder(path); + if (KStandardDirs::makeDir(path) == false) { + kDebug() << "/// ERROR CREATING PROJECT FOLDER: " << path; + } else KdenliveSettings::setDefaultprojectfolder(path); } } @@ -1245,6 +1251,7 @@ void MainWindow::slotRunWizard() void MainWindow::newFile(bool showProjectSettings) { if (!m_timelineArea->isEnabled()) return; + m_fileRevert->setEnabled(false); QString profileName; KUrl projectFolder; QPoint projectTracks(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()); @@ -1253,7 +1260,7 @@ void MainWindow::newFile(bool showProjectSettings) profileName = KdenliveSettings::default_profile(); projectFolder = KdenliveSettings::defaultprojectfolder(); } else { - ProjectSettings *w = new ProjectSettings(projectTracks.x(), projectTracks.y(), KdenliveSettings::defaultprojectfolder(), false, this); + ProjectSettings *w = new ProjectSettings(NULL, projectTracks.x(), projectTracks.y(), KdenliveSettings::defaultprojectfolder(), false, true, this); if (w->exec() != QDialog::Accepted) return; if (!KdenliveSettings::activatetabs()) closeCurrentDocument(); KdenliveSettings::setVideothumbnails(w->enableVideoThumbs()); @@ -1294,7 +1301,7 @@ void MainWindow::activateDocument() connectDocument(currentTab, currentDoc); } -void MainWindow::closeCurrentDocument() +void MainWindow::closeCurrentDocument(bool saveChanges) { QWidget *w = m_timelineArea->currentWidget(); if (!w) return; @@ -1304,7 +1311,7 @@ void MainWindow::closeCurrentDocument() m_timelineArea->setCurrentIndex(ix); TrackView *tabToClose = (TrackView *) w; KdenliveDoc *docToClose = tabToClose->document(); - if (docToClose && docToClose->isModified()) { + if (docToClose && docToClose->isModified() && saveChanges) { switch (KMessageBox::warningYesNoCancel(this, i18n("Save changes to document?"))) { case KMessageBox::Yes : // save document here. If saving fails, return false; @@ -1359,6 +1366,7 @@ bool MainWindow::saveFileAs(const QString &outputFileName) m_timelineArea->setTabToolTip(m_timelineArea->currentIndex(), m_activeDocument->url().path()); m_activeDocument->setModified(false); m_fileOpenRecent->addUrl(KUrl(outputFileName)); + m_fileRevert->setEnabled(true); return true; } @@ -1391,6 +1399,11 @@ bool MainWindow::saveFile() void MainWindow::openFile() { + if (!m_startUrl.isEmpty()) { + openFile(m_startUrl); + m_startUrl = KUrl(); + return; + } // Check that the Kdenlive mime type is correctly installed QString mimetype = "application/x-kdenlive"; KMimeType::Ptr mime = KMimeType::mimeType(mimetype); @@ -1448,12 +1461,15 @@ void MainWindow::openFile(const KUrl &url) } } if (!KdenliveSettings::activatetabs()) closeCurrentDocument(); + m_messageLabel->setMessage(i18n("Opening file %1", url.path()), InformationMessage); + qApp->processEvents(); doOpenFile(url, NULL); } void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale) { if (!m_timelineArea->isEnabled()) return; + m_fileRevert->setEnabled(true); KdenliveDoc *doc = new KdenliveDoc(url, KdenliveSettings::defaultprojectfolder(), m_commandStack, KdenliveSettings::default_profile(), QPoint(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()), m_projectMonitor->render, this); if (stale == NULL) { stale = new KAutoSaveFile(url, doc); @@ -1611,9 +1627,13 @@ void MainWindow::slotDetectAudioDriver() void MainWindow::slotEditProjectSettings() { QPoint p = m_activeDocument->getTracksCount(); - ProjectSettings *w = new ProjectSettings(p.x(), p.y(), m_activeDocument->projectFolder().path(), true, this); + ProjectSettings *w = new ProjectSettings(m_activeDocument->clipManager(), p.x(), p.y(), m_activeDocument->projectFolder().path(), true, !m_activeDocument->isModified(), this); if (w->exec() == QDialog::Accepted) { + if (w->deleteUnused()) { + // we are going to trash the unused clips + m_projectList->trashUnusedClips(); + } QString profile = w->selectedProfile(); m_activeDocument->setProjectFolder(w->selectedFolder()); if (m_renderWidget) m_renderWidget->setDocumentPath(w->selectedFolder().path(KUrl::AddTrailingSlash)); @@ -1624,31 +1644,38 @@ void MainWindow::slotEditProjectSettings() // Deselect current effect / transition m_effectStack->slotClipItemSelected(NULL, 0); m_transitionConfig->slotTransitionItemSelected(NULL, 0, QPoint(), false); - - m_activeDocument->setProfilePath(profile); + m_clipMonitor->slotSetXml(NULL, 0); + bool updateFps = m_activeDocument->setProfilePath(profile); KdenliveSettings::setCurrent_profile(profile); KdenliveSettings::setProject_fps(m_activeDocument->fps()); setCaption(m_activeDocument->description(), m_activeDocument->isModified()); + + m_activeDocument->clipManager()->clearUnusedProducers(); m_monitorManager->resetProfiles(m_activeDocument->timecode()); + m_transitionConfig->updateProjectFormat(m_activeDocument->mltProfile(), m_activeDocument->timecode(), m_activeTimeline->tracksNumber()); m_effectStack->updateProjectFormat(m_activeDocument->mltProfile(), 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()); + //m_activeDocument->clipManager()->resetProducersList(m_projectMonitor->render->producersList()); if (dar != m_activeDocument->dar()) m_projectList->reloadClipThumbnails(); - m_activeTimeline->updateProjectFps(); + if (updateFps) m_activeTimeline->updateProjectFps(); + m_activeDocument->setModified(true); + m_commandStack->activeStack()->clear(); // We need to desactivate & reactivate monitors to get a refresh - m_monitorManager->switchMonitors(); + //m_monitorManager->switchMonitors(); } } delete w; } + void MainWindow::slotRenderProject() { if (!m_renderWidget) { QString projectfolder = m_activeDocument ? m_activeDocument->projectFolder().path(KUrl::AddTrailingSlash) : KdenliveSettings::defaultprojectfolder(); m_renderWidget = new RenderWidget(projectfolder, this); + connect(m_renderWidget, SIGNAL(shutdown()), this, SLOT(slotShutdown())); connect(m_renderWidget, SIGNAL(selectedRenderProfile(const QString &, const QString &, const QString&)), this, SLOT(slotSetDocumentRenderProfile(const QString &, const QString &, const QString&))); connect(m_renderWidget, SIGNAL(prepareRenderingData(bool, bool, const QString&)), this, SLOT(slotPrepareRendering(bool, bool, const QString&))); connect(m_renderWidget, SIGNAL(abortProcess(const QString &)), this, SIGNAL(abortRenderJob(const QString &))); @@ -1677,6 +1704,12 @@ void MainWindow::setRenderingFinished(const QString &url, int status, const QStr if (m_renderWidget) m_renderWidget->setRenderStatus(url, status, error); } +void MainWindow::slotCleanProject() +{ + if (KMessageBox::warningContinueCancel(this, i18n("This will remove all unused clips from your project."), i18n("Clean up project")) == KMessageBox::Cancel) return; + m_projectList->cleanup(); +} + void MainWindow::slotUpdateMousePosition(int pos) { if (m_activeDocument) @@ -1726,7 +1759,6 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha disconnect(m_projectList, SIGNAL(projectModified()), m_activeDocument, SLOT(setModified())); disconnect(m_projectMonitor->render, SIGNAL(refreshDocumentProducers()), m_activeDocument, SLOT(checkProjectClips())); - disconnect(m_activeDocument, SIGNAL(guidesUpdated()), this, SLOT(slotGuidesUpdated())); disconnect(m_activeDocument, SIGNAL(addProjectClip(DocClipBase *, bool)), m_projectList, SLOT(slotAddClip(DocClipBase *, bool))); disconnect(m_activeDocument, SIGNAL(resetProjectList()), m_projectList, SLOT(slotResetProjectList())); @@ -1757,6 +1789,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha disconnect(m_activeTimeline->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(activateMonitor())); disconnect(m_activeTimeline, SIGNAL(zoneMoved(int, int)), this, SLOT(slotZoneMoved(int, int))); disconnect(m_projectList, SIGNAL(loadingIsOver()), m_activeTimeline->projectView(), SLOT(slotUpdateAllThumbs())); + disconnect(m_projectList, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int))); m_effectStack->clear(); } //m_activeDocument->setRenderer(NULL); @@ -1785,6 +1818,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(m_projectMonitor, SIGNAL(zoneUpdated(QPoint)), trackView, SLOT(slotSetZone(QPoint))); connect(m_projectMonitor, SIGNAL(durationChanged(int)), trackView, SLOT(setDuration(int))); connect(m_projectMonitor->render, SIGNAL(refreshDocumentProducers()), doc, SLOT(checkProjectClips())); + connect(doc, SIGNAL(addProjectClip(DocClipBase *, bool)), m_projectList, SLOT(slotAddClip(DocClipBase *, bool))); connect(doc, SIGNAL(resetProjectList()), m_projectList, SLOT(slotResetProjectList())); connect(doc, SIGNAL(signalDeleteProjectClip(const QString &)), m_projectList, SLOT(slotDeleteClip(const QString &))); @@ -1797,6 +1831,8 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int)), m_effectStack, SLOT(slotClipItemSelected(ClipItem*, int))); + connect(trackView->projectView(), SIGNAL(updateClipMarkers(DocClipBase *)), this, SLOT(slotUpdateClipMarkers(DocClipBase*))); + connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int)), this, SLOT(slotActivateEffectStackView())); connect(trackView->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), m_transitionConfig, SLOT(slotTransitionItemSelected(Transition*, int, QPoint, bool))); connect(trackView->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), this, SLOT(slotActivateTransitionView(Transition *))); @@ -1804,6 +1840,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(m_zoomSlider, SIGNAL(valueChanged(int)), trackView, SLOT(slotChangeZoom(int))); connect(trackView->projectView(), SIGNAL(zoomIn()), this, SLOT(slotZoomIn())); connect(trackView->projectView(), SIGNAL(zoomOut()), this, SLOT(slotZoomOut())); + connect(trackView, SIGNAL(setZoom(int)), this, SLOT(slotSetZoom(int))); connect(trackView->projectView(), SIGNAL(displayMessage(const QString&, MessageType)), m_messageLabel, SLOT(setMessage(const QString&, MessageType))); connect(trackView->projectView(), SIGNAL(showClipFrame(DocClipBase *, const int)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *, const int))); @@ -1821,6 +1858,8 @@ 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(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int))); + trackView->projectView()->setContextMenu(m_timelineContextMenu, m_timelineContextClipMenu, m_timelineContextTransitionMenu, m_clipTypeGroup); m_activeTimeline = trackView; @@ -1833,7 +1872,6 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha //doc->setRenderer(m_projectMonitor->render); m_commandStack->setActiveStack(doc->commandStack()); KdenliveSettings::setProject_display_ratio(doc->dar()); - m_projectList->updateAllClips(); //doc->clipManager()->checkAudioThumbs(); //m_overView->setScene(trackView->projectScene()); @@ -1844,6 +1882,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha m_saveAction->setEnabled(doc->isModified()); m_activeDocument = doc; m_activeTimeline->updateProjectFps(); + m_activeDocument->checkProjectClips(); if (KdenliveSettings::dropbframes()) slotUpdatePreviewSettings(); // set tool to select tool @@ -1879,7 +1918,9 @@ void MainWindow::slotPreferences(int page, int option) //connect(dialog, SIGNAL(doResetProfile()), this, SLOT(slotDetectAudioDriver())); connect(dialog, SIGNAL(doResetProfile()), m_monitorManager, SLOT(slotResetProfiles())); connect(dialog, SIGNAL(updatePreviewSettings()), this, SLOT(slotUpdatePreviewSettings())); +#ifndef Q_WS_MAC connect(dialog, SIGNAL(updateCaptureFolder()), m_recMonitor, SLOT(slotUpdateCaptureFolder())); +#endif //connect(dialog, SIGNAL(updatePreviewSettings()), this, SLOT(slotUpdatePreviewSettings())); dialog->show(); if (page != -1) dialog->showPage(page, option); @@ -1958,6 +1999,12 @@ void MainWindow::slotDeleteTimelineClip() } } +void MainWindow::slotUpdateClipMarkers(DocClipBase *clip) +{ + if (m_clipMonitor->isActive()) m_clipMonitor->checkOverlay(); + m_clipMonitor->updateMarkers(clip); +} + void MainWindow::slotAddClipMarker() { DocClipBase *clip = NULL; @@ -1966,7 +2013,7 @@ void MainWindow::slotAddClipMarker() if (m_activeTimeline) { ClipItem *item = m_activeTimeline->projectView()->getActiveClipUnderCursor(); if (item) { - pos = (m_projectMonitor->position() - item->startPos() + item->cropStart()) / item->speed(); + pos = GenTime((int)((m_projectMonitor->position() - item->startPos() + item->cropStart()).frames(m_activeDocument->fps()) * item->speed() + 0.5), m_activeDocument->fps()); clip = item->baseClip(); } } @@ -1984,7 +2031,6 @@ void MainWindow::slotAddClipMarker() if (d.exec() == QDialog::Accepted) { m_activeTimeline->projectView()->slotAddClipMarker(id, d.newMarker().time(), d.newMarker().comment()); } - if (m_clipMonitor->isActive()) m_clipMonitor->checkOverlay(); } void MainWindow::slotDeleteClipMarker() @@ -2015,8 +2061,6 @@ void MainWindow::slotDeleteClipMarker() return; } m_activeTimeline->projectView()->slotDeleteClipMarker(comment, id, pos); - if (m_clipMonitor->isActive()) m_clipMonitor->checkOverlay(); - } void MainWindow::slotDeleteAllClipMarkers() @@ -2037,7 +2081,6 @@ void MainWindow::slotDeleteAllClipMarkers() return; } m_activeTimeline->projectView()->slotDeleteAllClipMarkers(clip->getId()); - if (m_clipMonitor->isActive()) m_clipMonitor->checkOverlay(); } void MainWindow::slotEditClipMarker() @@ -2076,7 +2119,6 @@ void MainWindow::slotEditClipMarker() // remove old marker m_activeTimeline->projectView()->slotAddClipMarker(id, pos, QString()); } - if (m_clipMonitor->isActive()) m_clipMonitor->checkOverlay(); } } @@ -2219,6 +2261,11 @@ void MainWindow::slotFitZoom() } } +void MainWindow::slotSetZoom(int value) +{ + m_zoomSlider->setValue(value); +} + void MainWindow::slotGotProgressInfo(const QString &message, int progress) { m_statusProgressBar->setValue(progress); @@ -2235,7 +2282,7 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip) { if (clip->clipType() == TEXT) { QString titlepath = m_activeDocument->projectFolder().path(KUrl::AddTrailingSlash) + "titles/"; - if (!clip->getProperty("xmltemplate").isEmpty()) { + if (!clip->getProperty("resource").isEmpty() && clip->getProperty("xmldata").isEmpty()) { // template text clip // Get the list of existing templates @@ -2247,7 +2294,7 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip) Ui::TemplateClip_UI dia_ui; dia_ui.setupUi(dia); int ix = -1; - const QString templatePath = clip->getProperty("xmltemplate"); + const QString templatePath = clip->getProperty("resource"); for (int i = 0; i < templateFiles.size(); ++i) { dia_ui.template_list->comboBox()->addItem(templateFiles.at(i), titlepath + templateFiles.at(i)); if (templatePath == KUrl(titlepath + templateFiles.at(i)).path()) ix = i; @@ -2259,7 +2306,6 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip) KUrl startDir(titlepath); dia_ui.template_list->fileDialog()->setUrl(startDir); dia_ui.description->setText(clip->getProperty("description")); - dia_ui.clone_clip->setChecked(true); if (dia->exec() == QDialog::Accepted) { QString textTemplate = dia_ui.template_list->comboBox()->itemData(dia_ui.template_list->comboBox()->currentIndex()).toString(); if (textTemplate.isEmpty()) textTemplate = dia_ui.template_list->comboBox()->currentText(); @@ -2268,7 +2314,7 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip) if (KUrl(textTemplate).path() != templatePath) { // The template was changed - newprops.insert("xmltemplate", textTemplate); + newprops.insert("resource", textTemplate); } if (dia_ui.description->toPlainText() != clip->getProperty("description")) { @@ -2281,11 +2327,9 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip) // template modified we need to update xmldata QString description = newprops.value("description"); if (description.isEmpty()) description = clip->getProperty("description"); - newprops.insert("xmldata", m_projectList->generateTemplateXml(newtemplate, description).toString()); - if (dia_ui.normal_clip->isChecked()) { - // Switch clip to normal clip - newprops.insert("xmltemplate", QString()); - } + else newprops.insert("templatetext", description); + //newprops.insert("xmldata", m_projectList->generateTemplateXml(newtemplate, description).toString()); + EditClipCommand *command = new EditClipCommand(m_projectList, clip->getId(), clip->properties(), newprops, true); m_activeDocument->commandStack()->push(command); } @@ -2297,13 +2341,15 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip) doc.setContent(clip->getProperty("xmldata")); dia_ui->setXml(doc); if (dia_ui->exec() == QDialog::Accepted) { - QRect rect = dia_ui->renderedRect(); QMap newprops; newprops.insert("xmldata", dia_ui->xml().toString()); - newprops.insert("out", QString::number(dia_ui->duration())); - newprops.insert("frame_size", QString::number(rect.width()) + 'x' + QString::number(rect.height())); + if (dia_ui->duration() != clip->duration().frames(m_activeDocument->fps()) - 1) { + // duration changed, we need to update duration + newprops.insert("out", QString::number(dia_ui->duration())); + } EditClipCommand *command = new EditClipCommand(m_projectList, clip->getId(), clip->properties(), newprops, true); m_activeDocument->commandStack()->push(command); + m_activeTimeline->projectView()->slotUpdateClip(clip->getId()); m_activeDocument->setModified(true); } delete dia_ui; @@ -2314,13 +2360,12 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip) ClipProperties dia(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))); if (dia.exec() == QDialog::Accepted) { - EditClipCommand *command = new EditClipCommand(m_projectList, dia.clipId(), clip->properties(), dia.properties(), true); + EditClipCommand *command = new EditClipCommand(m_projectList, clip->getId(), clip->properties(), dia.properties(), true); m_activeDocument->commandStack()->push(command); - //m_projectList->slotUpdateClipProperties(dia.clipId(), dia.properties()); if (dia.needsTimelineRefresh()) { // update clip occurences in timeline - m_activeTimeline->projectView()->slotUpdateClip(dia.clipId()); + m_activeTimeline->projectView()->slotUpdateClip(clip->getId(), dia.needsTimelineReload()); } } } @@ -2384,6 +2429,19 @@ void MainWindow::slotSetTool(PROJECTTOOL tool) { if (m_activeDocument && m_activeTimeline) { //m_activeDocument->setTool(tool); + QString message; + switch (tool) { + case SPACERTOOL: + message = i18n("Ctrl + click to use spacer on current track only"); + break; + case RAZORTOOL: + message = i18n("Click on a clip to cut it"); + break; + default: + message = i18n("Shift + click to create a selection rectangle, Ctrl + click to add an item to selection"); + break; + } + m_messageLabel->setMessage(message, InformationMessage); m_activeTimeline->projectView()->setTool(tool); } } @@ -2636,8 +2694,12 @@ void MainWindow::slotUpdateClipType(QAction *action) void MainWindow::slotDvdWizard(const QString &url, const QString &profile) { - DvdWizard *w = new DvdWizard(url, profile, this); - w->exec(); + // We must stop the monitors since we create a new on in the dvd wizard + m_clipMonitor->stop(); + m_projectMonitor->stop(); + DvdWizard w(url, profile, this); + w.exec(); + m_projectMonitor->start(); } void MainWindow::slotShowTimeline(bool show) @@ -2790,8 +2852,9 @@ void MainWindow::slotPrepareRendering(bool scriptExport, bool zoneOnly, const QS kWarning() << "////// ERROR writing DVD CHAPTER file: " << chapterFile; } else { file.write(doc.toString().toUtf8()); - if (file.error() != QFile::NoError) + if (file.error() != QFile::NoError) { kWarning() << "////// ERROR writing DVD CHAPTER file: " << chapterFile; + } file.close(); } } @@ -2800,4 +2863,37 @@ void MainWindow::slotPrepareRendering(bool scriptExport, bool zoneOnly, const QS m_renderWidget->slotExport(scriptExport, m_activeTimeline->inPoint(), m_activeTimeline->outPoint(), playlistPath, scriptPath); } +void MainWindow::slotUpdateTimecodeFormat(int ix) +{ + KdenliveSettings::setFrametimecode(ix == 1); + m_clipMonitor->updateTimecodeFormat(); + m_projectMonitor->updateTimecodeFormat(); +} + +void MainWindow::slotRemoveFocus() +{ + statusBar()->setFocus(); + statusBar()->clearFocus(); +} + +void MainWindow::slotRevert() +{ + if (KMessageBox::warningContinueCancel(this, i18n("This will delete all changes made since you last saved your project. Are you sure you want to continue?"), i18n("Revert to last saved version")) == KMessageBox::Cancel) return; + KUrl url = m_activeDocument->url(); + closeCurrentDocument(false); + doOpenFile(url, NULL); +} + + +void MainWindow::slotShutdown() +{ + if (m_activeDocument) m_activeDocument->setModified(false); + // Call shutdown + QDBusConnectionInterface* interface = QDBusConnection::sessionBus().interface(); + if (interface && interface->isServiceRegistered("org.kde.ksmserver")) { + QDBusInterface smserver("org.kde.ksmserver", "/KSMServer", "org.kde.KSMServerInterface"); + smserver.call("logout", 1, 2, 2); + } +} + #include "mainwindow.moc"