X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmainwindow.cpp;h=65a39cd5dec2f76dcf5d85281a341cbaed4a0bc2;hb=11a4d09164d3e0d7dcbe5891cb5ccc8c50c89e17;hp=01d8daf12eedc7778f36f1fa361f06c00afc3107;hpb=5b7a383d5285d0214ecc32d98d56af9c0e744212;p=kdenlive diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 01d8daf1..65a39cd5 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -61,6 +61,7 @@ #include "colorscopes/histogram.h" #include "audiospectrum.h" #include "spectrogram.h" +#include "archivewidget.h" #include #include @@ -215,7 +216,10 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & 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 ...")); @@ -426,7 +430,6 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & setupGUI(); - // Find QDockWidget tab bars and show / hide widget title bars on right click QList tabs = findChildren(); for (int i = 0; i < tabs.count(); i++) { @@ -447,7 +450,6 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & loadPlugins(); loadTranscoders(); - //kDebug() << factory() << " " << factory()->container("video_effects_menu", this); m_projectMonitor->setupMenu(static_cast(factory()->container("monitor_go", this)), m_playZone, m_loopZone, NULL, m_loopClip); m_clipMonitor->setupMenu(static_cast(factory()->container("monitor_go", this)), m_playZone, m_loopZone, static_cast(factory()->container("marker_menu", this))); @@ -505,13 +507,14 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & QMenu *m = static_cast(factory()->container("video_effects_menu", this)); - m = m_effectsMenu; + m->addActions(m_effectsMenu->actions()); m_transitionsMenu = new QMenu(i18n("Add Transition"), this); for (int i = 0; i < transitions.count(); ++i) m_transitionsMenu->addAction(m_transitions[i]); + connect(m, SIGNAL(triggered(QAction *)), this, SLOT(slotAddVideoEffect(QAction *))); connect(m_effectsMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotAddVideoEffect(QAction *))); connect(m_transitionsMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotAddTransition(QAction *))); @@ -616,6 +619,7 @@ MainWindow::~MainWindow() delete m_projectMonitor; delete m_clipMonitor; delete m_shortcutRemoveFocus; + delete[] m_transitions; Mlt::Factory::close(); } @@ -844,7 +848,7 @@ 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(removeInvalidProxy(const QString &)), m_projectList, SLOT(slotRemoveInvalidProxy(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))); @@ -1203,6 +1207,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); @@ -1899,7 +1908,7 @@ bool MainWindow::saveFileAs(const QString &outputFileName) 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 +1956,17 @@ 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; + } + // Check if the document is already opened const int ct = m_timelineArea->count(); bool isOpened = false; @@ -2192,7 +2212,7 @@ void MainWindow::slotEditProjectSettings() m_activeDocument->setDocumentProperty("proxyparams", w->proxyParams()); if (m_activeDocument->clipManager()->clipsCount() > 0 && KMessageBox::questionYesNo(this, i18n("You have changed the proxy parameters. Do you want to recreate all proxy clips for this project?")) == KMessageBox::Yes) { //TODO: rebuild all proxies - //m_activeDocument->rebuildAllProxies(); + //m_projectList->rebuildProxies(); } } if (m_activeDocument->getDocumentProperty("proxyextension") != w->proxyExtension()) { @@ -2375,9 +2395,9 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha 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)), m_effectStack, SLOT(slotClipItemSelected(ClipItem*, int))); - disconnect(m_activeTimeline->projectView(), SIGNAL(clipItemSelected(ClipItem*, int)), this, SLOT(slotActivateEffectStackView())); - disconnect(m_activeTimeline->projectView(), SIGNAL(clipItemSelected(ClipItem*, int)), m_projectMonitor, SLOT(slotSetSelectedClip(ClipItem*))); + 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*))); disconnect(m_activeTimeline->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), m_transitionConfig, SLOT(slotTransitionItemSelected(Transition*, int, QPoint, bool))); disconnect(m_activeTimeline->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), this, SLOT(slotActivateTransitionView(Transition *))); disconnect(m_activeTimeline->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), m_projectMonitor, SLOT(slotSetSelectedClip(Transition*))); @@ -2456,12 +2476,12 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(doc, SIGNAL(guidesUpdated()), this, SLOT(slotGuidesUpdated())); connect(m_notesWidget, SIGNAL(textChanged()), doc, SLOT(setModified())); - connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int)), m_effectStack, SLOT(slotClipItemSelected(ClipItem*, int))); + connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), m_effectStack, SLOT(slotClipItemSelected(ClipItem*, int))); connect(trackView->projectView(), SIGNAL(updateClipMarkers(DocClipBase *)), this, SLOT(slotUpdateClipMarkers(DocClipBase*))); connect(trackView, SIGNAL(showTrackEffects(int, TrackInfo)), m_effectStack, SLOT(slotTrackItemSelected(int, TrackInfo))); connect(trackView, SIGNAL(showTrackEffects(int, TrackInfo)), this, SLOT(slotActivateEffectStackView())); - connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int)), this, SLOT(slotActivateEffectStackView())); + connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), this, SLOT(slotActivateEffectStackView(ClipItem*, int, bool))); 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 *))); m_zoomSlider->setValue(doc->zoom().x()); @@ -2473,7 +2493,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(trackView->projectView(), SIGNAL(showClipFrame(DocClipBase *, QPoint, const int)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *, QPoint, const int))); connect(trackView->projectView(), SIGNAL(playMonitor()), m_projectMonitor, SLOT(slotPlay())); - connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int)), m_projectMonitor, SLOT(slotSetSelectedClip(ClipItem*))); + connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), m_projectMonitor, SLOT(slotSetSelectedClip(ClipItem*))); connect(trackView->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), m_projectMonitor, SLOT(slotSetSelectedClip(Transition*))); connect(m_effectStack, SIGNAL(updateEffect(ClipItem*, int, QDomElement, QDomElement, int)), trackView->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, int, QDomElement, QDomElement, int))); @@ -2989,23 +3009,6 @@ void MainWindow::slotAddVideoEffect(QAction *result) else m_messageLabel->setMessage(i18n("Cannot find effect %1 / %2").arg(info.at(0)).arg(info.at(1)), ErrorMessage); } -void MainWindow::slotAddAudioEffect(QAction *result) -{ - if (!result) return; - QStringList info = result->data().toStringList(); - if (info.isEmpty()) return; - QDomElement effect = audioEffects.getEffectByTag(info.at(1), info.at(2)); - slotAddEffect(effect); -} - -void MainWindow::slotAddCustomEffect(QAction *result) -{ - if (!result) return; - QStringList info = result->data().toStringList(); - if (info.isEmpty()) return; - QDomElement effect = customEffects.getEffectByTag(info.at(1), info.at(2)); - slotAddEffect(effect); -} void MainWindow::slotZoomIn() { @@ -3219,9 +3222,13 @@ void MainWindow::customEvent(QEvent* e) if (e->type() == QEvent::User) m_messageLabel->setMessage(static_cast (e)->message(), MltError); } -void MainWindow::slotActivateEffectStackView() +void MainWindow::slotActivateEffectStackView(ClipItem* item, int ix, bool raise) { - m_effectStack->raiseWindow(m_effectStackDock); + Q_UNUSED(item) + Q_UNUSED(ix) + + if (raise) + m_effectStack->raiseWindow(m_effectStackDock); } void MainWindow::slotActivateTransitionView(Transition *t) @@ -3828,14 +3835,57 @@ void MainWindow::slotPrepareRendering(bool scriptExport, bool zoneOnly, const QS // 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(); - QMapIterator i(proxies); + + + 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.startsWith("/") && !producerResource.isEmpty() ){ + producerResource=root+"/"+producerResource; + } + if (producerResource.contains('?')) { + suffix = "?" + producerResource.section('?', 1); + producerResource = producerResource.section('?', 0, 0); + } + else suffix.clear(); + if (!producerResource.isEmpty()) { + if (proxies.contains(producerResource)) { + EffectsList::setProperty(e, "resource", proxies.value(producerResource) + suffix); + // We need to delete the "aspect_ratio" property because proxy clips + // 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"); + } + } + } + + /*QMapIterator i(proxies); while (i.hasNext()) { i.next(); // Replace all keys with their values (proxy path with original path) - playlistContent.replace(i.key(), i.value()); - } + QString key = i.key(); + playlistContent.replace(key, i.value()); + if (!root.isEmpty() && key.startsWith(root)) { + // in case the resource path in MLT playlist is relative + key.remove(0, root.count() + 1); + playlistContent.replace(key, i.value()); + } + }*/ + playlistContent = doc.toString(); } // Do save scenelist @@ -3908,12 +3958,51 @@ void MainWindow::slotChangePalette(QAction *action, const QString &themename) else theme = action->data().toString(); KdenliveSettings::setColortheme(theme); // Make palette for all widgets. - QPalette plt; + QPalette plt = kapp->palette(); if (theme.isEmpty()) { plt = QApplication::desktop()->palette(); } else { KSharedConfigPtr config = KSharedConfig::openConfig(theme); - 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 + KColorScheme schemeTooltip(QPalette::Active, KColorScheme::Tooltip, config); + + for ( int i = 0; i < 3 ; i++ ) { + QPalette::ColorGroup state = states[i]; + KColorScheme schemeView(state, KColorScheme::View, config); + KColorScheme schemeWindow(state, KColorScheme::Window, config); + KColorScheme schemeButton(state, KColorScheme::Button, config); + KColorScheme schemeSelection(state, KColorScheme::Selection, config); + + plt.setBrush( state, QPalette::WindowText, schemeWindow.foreground() ); + plt.setBrush( state, QPalette::Window, schemeWindow.background() ); + plt.setBrush( state, QPalette::Base, schemeView.background() ); + plt.setBrush( state, QPalette::Text, schemeView.foreground() ); + plt.setBrush( state, QPalette::Button, schemeButton.background() ); + plt.setBrush( state, QPalette::ButtonText, schemeButton.foreground() ); + plt.setBrush( state, QPalette::Highlight, schemeSelection.background() ); + plt.setBrush( state, QPalette::HighlightedText, schemeSelection.foreground() ); + plt.setBrush( state, QPalette::ToolTipBase, schemeTooltip.background() ); + plt.setBrush( state, QPalette::ToolTipText, schemeTooltip.foreground() ); + + plt.setColor( state, QPalette::Light, schemeWindow.shade( KColorScheme::LightShade ) ); + plt.setColor( state, QPalette::Midlight, schemeWindow.shade( KColorScheme::MidlightShade ) ); + plt.setColor( state, QPalette::Mid, schemeWindow.shade( KColorScheme::MidShade ) ); + plt.setColor( state, QPalette::Dark, schemeWindow.shade( KColorScheme::DarkShade ) ); + plt.setColor( state, QPalette::Shadow, schemeWindow.shade( KColorScheme::ShadowShade ) ); + + plt.setBrush( state, QPalette::AlternateBase, schemeView.background( KColorScheme::AlternateBackground) ); + plt.setBrush( state, QPalette::Link, schemeView.foreground( KColorScheme::LinkText ) ); + plt.setBrush( state, QPalette::LinkVisited, schemeView.foreground( KColorScheme::VisitedText ) ); + } +#endif } kapp->setPalette(plt); @@ -4037,11 +4126,12 @@ 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 (open) mimetype.append(" application/x-compressed-tar"); return mimetype; } @@ -4167,6 +4257,22 @@ 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(); +} + + #include "mainwindow.moc" #ifdef DEBUG_MAINW