X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmainwindow.cpp;h=f6fd491a8e2e8e2888e8313324c2257c4ef42cb4;hb=a41bc84cad7d706f246fab2837bae42a328a0b93;hp=ad1cf6e886cf29a2fb428feefa8460e63e9820a7;hpb=f555964fc8fd3452f2aa6d8217d20e2aa4013334;p=kdenlive diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ad1cf6e8..f6fd491a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -142,6 +142,11 @@ EffectsList MainWindow::transitions; QMap MainWindow::m_lumacache; +static bool sortByNames(const QPair &a, const QPair &b) +{ + return a.first < b.first; +} + MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & clipsToLoad, QWidget *parent) : KXmlGuiWindow(parent), m_activeDocument(NULL), @@ -158,7 +163,8 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & m_jogShuttle(NULL), #endif m_findActivated(false), - m_stopmotion(NULL) + m_stopmotion(NULL), + m_mainClip(NULL) { qRegisterMetaType > (); qRegisterMetaType ("stringMap"); @@ -233,9 +239,9 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & // Connect the project list connect(m_projectList, SIGNAL(clipSelected(DocClipBase *, QPoint, bool)), m_clipMonitor, SLOT(slotSetClipProducer(DocClipBase *, QPoint, bool))); - connect(m_projectList, SIGNAL(raiseClipMonitor()), m_clipMonitor, SLOT(slotActivateMonitor())); + connect(m_projectList, SIGNAL(raiseClipMonitor(bool)), m_clipMonitor, SLOT(slotActivateMonitor(bool))); 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(displayMessage(const QString&, int, MessageType)), this, SLOT(slotGotProgressInfo(const QString&, int, MessageType))); connect(m_projectList, SIGNAL(updateRenderStatus()), this, SLOT(slotCheckRenderStatus())); connect(m_projectList, SIGNAL(clipNeedsReload(const QString&)),this, SLOT(slotUpdateClip(const QString &))); connect(m_projectList, SIGNAL(updateProfile(const QString &)), this, SLOT(slotUpdateProjectProfile(const QString &))); @@ -279,7 +285,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & m_effectStack = new EffectStackView2(m_projectMonitor); m_effectStackDock->setWidget(m_effectStack); addDockWidget(Qt::TopDockWidgetArea, m_effectStackDock); - connect(m_effectStack, SIGNAL(startFilterJob(ItemInfo, const QString&,const QString&,const QString&,const QString&,const QString&,const QString&,const QString&)), m_projectList, SLOT(slotStartFilterJob(ItemInfo, const QString&,const QString&,const QString&,const QString&,const QString&,const QString&,const QString&))); + connect(m_effectStack, SIGNAL(startFilterJob(ItemInfo, const QString&,const QString&,const QString&,const QString&,const QString&,const QMap &)), m_projectList, SLOT(slotStartFilterJob(ItemInfo, const QString&,const QString&,const QString&,const QString&,const QString&,const QMap &))); m_transitionConfigDock = new QDockWidget(i18n("Transition"), this); m_transitionConfigDock->setObjectName("transition"); @@ -459,19 +465,19 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & loadPlugins(); loadTranscoders(); - loadStabilize(); + loadClipActions(); 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))); QMenu *clipInTimeline = static_cast(factory()->container("clip_in_timeline", this)); clipInTimeline->setIcon(KIcon("go-jump")); - QHash menus; - menus.insert("addMenu",static_cast(factory()->container("generators", this))); - menus.insert("extractAudioMenu",static_cast(factory()->container("extract_audio", this))); - menus.insert("transcodeMenu",static_cast(factory()->container("transcoders", this))); - menus.insert("stabilizeMenu",static_cast(factory()->container("stabilize", this))); - menus.insert("inTimelineMenu",clipInTimeline); + QHash menus; + menus.insert("addMenu",static_cast(factory()->container("generators", this))); + menus.insert("extractAudioMenu",static_cast(factory()->container("extract_audio", this))); + menus.insert("transcodeMenu",static_cast(factory()->container("transcoders", this))); + menus.insert("clipActionsMenu",static_cast(factory()->container("clip_actions", this))); + menus.insert("inTimelineMenu",clipInTimeline); m_projectList->setupGeneratorMenu(menus); // build themes menus @@ -573,29 +579,6 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & slotConnectMonitors(); - // Open or create a file. Command line argument passed in Url has - // precedence, then "openlastproject", then just a plain empty file. - // If opening Url fails, openlastproject will _not_ be used. - if (!Url.isEmpty()) { - // 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); - } - - if (!clipsToLoad.isEmpty() && m_activeDocument) { - QStringList list = clipsToLoad.split(','); - QList urls; - foreach(const QString &path, list) { - kDebug() << QDir::current().absoluteFilePath(path); - urls << QUrl::fromLocalFile(QDir::current().absoluteFilePath(path)); - } - m_projectList->slotAddClip(urls); - } - #ifdef USE_JOGSHUTTLE activateShuttleDevice(); #endif @@ -604,35 +587,43 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & actionCollection()->addAssociatedWidget(m_clipMonitor->container()); actionCollection()->addAssociatedWidget(m_projectMonitor->container()); - QMap viewActions; + QList > viewActions; + QPair pair; KAction *showTimeline = new KAction(i18n("Timeline"), this); showTimeline->setCheckable(true); showTimeline->setChecked(true); connect(showTimeline, SIGNAL(triggered(bool)), this, SLOT(slotShowTimeline(bool))); - viewActions.insert(showTimeline->text(), showTimeline); + + KMenu *viewMenu = static_cast(factory()->container("dockwindows", this)); + pair.first = showTimeline->text(); + pair.second = showTimeline; + viewActions.append(pair); QList docks = findChildren(); for (int i = 0; i < docks.count(); i++) { QDockWidget* dock = docks.at(i); + QAction * a = dock->toggleViewAction(); + if (!a) continue; KAction* dockInformations = new KAction(this); - dockInformations->setText(dock->windowTitle()); + dockInformations->setText(a->text()); dockInformations->setCheckable(true); dockInformations->setChecked(!dock->isHidden()); - connect(dockInformations,SIGNAL(toggled(bool)), dock, SLOT(setVisible(bool))); - viewActions.insert(dockInformations->text(), dockInformations); - } - - - KMenu *viewMenu = static_cast(factory()->container("dockwindows", this)); - //const QList viewActions = createPopupMenu()->actions(); - QMap::const_iterator i = viewActions.constBegin(); - while (i != viewActions.constEnd()) { - viewMenu->addAction(guiActions->addAction(i.key(), i.value())); - ++i; + // HACK: since QActions cannot be used in KActionCategory to allow shortcut, we create a duplicate KAction of the dock QAction and link them + connect(a,SIGNAL(toggled(bool)), dockInformations, SLOT(setChecked(bool))); + connect(dockInformations,SIGNAL(triggered(bool)), a, SLOT(trigger())); + pair.first = dockInformations->text(); + pair.second = dockInformations; + viewActions.append(pair); } + // Sort dock view action by name + qSort(viewActions.begin(), viewActions.end(), sortByNames); + // Populate view menu + for (int i = 0; i < viewActions.count(); i++) + viewMenu->addAction(guiActions->addAction(viewActions.at(i).first, viewActions.at(i).second)); + // Populate encoding profiles - KConfig conf("encodingprofiles.rc", KConfig::FullConfig, "appdata"); + KConfig conf("encodingprofiles.rc", KConfig::CascadeConfig, "appdata"); if (KdenliveSettings::proxyparams().isEmpty() || KdenliveSettings::proxyextension().isEmpty()) { KConfigGroup group(&conf, "proxy"); QMap< QString, QString > values = group.entryMap(); @@ -655,6 +646,17 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & KdenliveSettings::setV4l_extension(data.section(';', 1, 1)); } } + if (KdenliveSettings::grab_parameters().isEmpty() || KdenliveSettings::grab_extension().isEmpty()) { + KConfigGroup group(&conf, "screengrab"); + QMap< QString, QString > values = group.entryMap(); + QMapIterator i(values); + if (i.hasNext()) { + i.next(); + QString data = i.value(); + KdenliveSettings::setGrab_parameters(data.section(';', 0, 0)); + KdenliveSettings::setGrab_extension(data.section(';', 1, 1)); + } + } if (KdenliveSettings::decklink_parameters().isEmpty() || KdenliveSettings::decklink_extension().isEmpty()) { KConfigGroup group(&conf, "decklink"); QMap< QString, QString > values = group.entryMap(); @@ -668,6 +670,30 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & } connect (KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), this, SLOT(slotChangePalette())); + + // Open or create a file. Command line argument passed in Url has + // precedence, then "openlastproject", then just a plain empty file. + // If opening Url fails, openlastproject will _not_ be used. + if (!Url.isEmpty()) { + // 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); + } + + if (!clipsToLoad.isEmpty() && m_activeDocument) { + QStringList list = clipsToLoad.split(','); + QList urls; + foreach(const QString &path, list) { + kDebug() << QDir::current().absoluteFilePath(path); + urls << QUrl::fromLocalFile(QDir::current().absoluteFilePath(path)); + } + m_projectList->slotAddClip(urls); + } + } MainWindow::~MainWindow() @@ -675,6 +701,12 @@ MainWindow::~MainWindow() if (m_stopmotion) { delete m_stopmotion; } + +#ifdef USE_JOGSHUTTLE + if (m_jogProcess) + delete m_jogProcess; +#endif + m_effectStack->slotClipItemSelected(NULL); m_transitionConfig->slotTransitionItemSelected(NULL, 0, QPoint(), false); @@ -812,7 +844,7 @@ void MainWindow::generateClip() QAction *action = qobject_cast(sender()); ClipGenerator *iGenerator = qobject_cast(action->parent()); - KUrl clipUrl = iGenerator->generatedClip(action->data().toString(), m_activeDocument->projectFolder(), + KUrl clipUrl = iGenerator->generatedClip(KdenliveSettings::rendererpath(), action->data().toString(), m_activeDocument->projectFolder(), QStringList(), QStringList(), m_activeDocument->fps(), m_activeDocument->width(), m_activeDocument->height()); if (!clipUrl.isEmpty()) { m_projectList->slotAddClip(QList () << clipUrl); @@ -911,13 +943,13 @@ void MainWindow::slotUpdateClip(const QString &id) void MainWindow::slotConnectMonitors() { m_projectList->setRenderer(m_projectMonitor->render); + connect(m_projectList, SIGNAL(pauseMonitor()), m_monitorManager, SLOT(slotPause())); connect(m_projectList, SIGNAL(deleteProjectClips(QStringList, QMap)), this, SLOT(slotDeleteProjectClips(QStringList, QMap))); connect(m_projectList, SIGNAL(showClipProperties(DocClipBase *)), this, SLOT(slotShowClipProperties(DocClipBase *))); connect(m_projectList, SIGNAL(showClipProperties(QList , QMap)), this, SLOT(slotShowClipProperties(QList , QMap))); connect(m_projectMonitor->render, SIGNAL(replyGetImage(const QString &, const QString &, int, int)), m_projectList, SLOT(slotReplyGetImage(const QString &, const QString &, int, int))); connect(m_projectMonitor->render, SIGNAL(replyGetImage(const QString &, const QImage &)), m_projectList, SLOT(slotReplyGetImage(const QString &, const QImage &))); - kDebug()<<" - - - - - -\n CONNECTED REPLY"; connect(m_projectMonitor->render, SIGNAL(replyGetFileProperties(const QString &, Mlt::Producer*, const stringMap &, const stringMap &, bool)), m_projectList, SLOT(slotReplyGetFileProperties(const QString &, Mlt::Producer*, const stringMap &, const stringMap &, bool))); connect(m_projectMonitor->render, SIGNAL(removeInvalidClip(const QString &, bool)), m_projectList, SLOT(slotRemoveInvalidClip(const QString &, bool))); @@ -1246,14 +1278,12 @@ void MainWindow::setupActions() connect(projectAdjust, SIGNAL(triggered(bool)), m_projectList, SLOT(adjustProjectProfileToItem())); KAction* monitorPlay = new KAction(KIcon("media-playback-start"), i18n("Play"), this); - KShortcut playShortcut; - playShortcut.setPrimary(Qt::Key_Space); - playShortcut.setAlternate(Qt::Key_K); - monitorPlay->setShortcut(playShortcut); + monitorPlay->setShortcut(Qt::Key_Space); collection.addAction("monitor_play", monitorPlay); connect(monitorPlay, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotPlay())); KAction* monitorPause = new KAction(KIcon("media-playback-stop"), i18n("Pause"), this); + monitorPause->setShortcut(Qt::Key_K); collection.addAction("monitor_pause", monitorPause); connect(monitorPause, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotPause())); @@ -1400,6 +1430,11 @@ void MainWindow::setupActions() collection.addAction("delete_timeline_clip", deleteItem); connect(deleteItem, SIGNAL(triggered(bool)), this, SLOT(slotDeleteItem())); + KAction* alignPlayhead = new KAction(i18n("Align Playhead to Mouse Position"), this); + alignPlayhead->setShortcut(Qt::Key_P); + collection.addAction("align_playhead", alignPlayhead); + connect(alignPlayhead, SIGNAL(triggered(bool)), this, SLOT(slotAlignPlayheadToMousePos())); + /*KAction* editTimelineClipSpeed = new KAction(i18n("Change Clip Speed"), this); collection.addAction("change_clip_speed", editTimelineClipSpeed); editTimelineClipSpeed->setData("change_speed"); @@ -1503,14 +1538,20 @@ void MainWindow::setupActions() KAction* splitAudio = new KAction(KIcon("document-new"), i18n("Split Audio"), this); collection.addAction("split_audio", splitAudio); + // "A+V" as data means this action should only be available for clips with audio AND video + splitAudio->setData("A+V"); connect(splitAudio, SIGNAL(triggered(bool)), this, SLOT(slotSplitAudio())); KAction* setAudioAlignReference = new KAction(i18n("Set Audio Reference"), this); collection.addAction("set_audio_align_ref", setAudioAlignReference); + // "A" as data means this action should only be available for clips with audio + setAudioAlignReference->setData("A"); connect(setAudioAlignReference, SIGNAL(triggered()), this, SLOT(slotSetAudioAlignReference())); KAction* alignAudio = new KAction(i18n("Align Audio to Reference"), this); collection.addAction("align_audio", alignAudio); + // "A" as data means this action should only be available for clips with audio + alignAudio->setData("A"); connect(alignAudio, SIGNAL(triggered()), this, SLOT(slotAlignAudio())); KAction* audioOnly = new KAction(KIcon("document-new"), i18n("Audio Only"), this); @@ -1829,7 +1870,7 @@ void MainWindow::readOptions() } } - + if (KdenliveSettings::ffmpegpath().isEmpty() || KdenliveSettings::ffplaypath().isEmpty()) upgrade = true; if (!initialGroup.exists() || upgrade) { // this is our first run, show Wizard QPointer w = new Wizard(upgrade, this); @@ -1960,6 +2001,7 @@ bool MainWindow::closeCurrentDocument(bool saveChanges) break; } } + slotTimelineClipSelected(NULL, false); m_clipMonitor->slotSetClipProducer(NULL); m_projectList->slotResetProjectList(); m_timelineArea->removeTab(m_timelineArea->indexOf(w)); @@ -1970,6 +2012,7 @@ bool MainWindow::closeCurrentDocument(bool saveChanges) if (docToClose == m_activeDocument) { delete m_activeDocument; m_activeDocument = NULL; + m_monitorManager->setDocument(m_activeDocument); m_effectStack->clear(); m_transitionConfig->slotTransitionItemSelected(NULL, 0, QPoint(), false); } else { @@ -2050,11 +2093,14 @@ void MainWindow::openFile() void MainWindow::openLastFile() { - KSharedConfigPtr config = KGlobal::config(); - KUrl::List urls = m_fileOpenRecent->urls(); - //WARNING: this is buggy, we get a random url, not the last one. Bug in KRecentFileAction? - if (urls.isEmpty()) newFile(false); - else openFile(urls.last()); + if (m_fileOpenRecent->selectableActionGroup()->actions().isEmpty()) { + // No files in history + newFile(false); + return; + } + QAction *firstUrlAction = m_fileOpenRecent->selectableActionGroup()->actions().last(); + if (firstUrlAction) firstUrlAction->trigger(); + else newFile(false); } void MainWindow::openFile(const KUrl &url) @@ -2065,13 +2111,23 @@ void MainWindow::openFile(const KUrl &url) // Opening a compressed project file, we need to process it kDebug()<<"Opening archive, processing"; QPointer ar = new ArchiveWidget(url); - if (ar->exec() == QDialog::Accepted) openFile(KUrl(ar->extractedProjectFile())); + if (ar->exec() == QDialog::Accepted) { + openFile(KUrl(ar->extractedProjectFile())); + } + else if (!m_startUrl.isEmpty()) { + // we tried to open an invalid file from command line, init new project + newFile(false); + } 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())); + if (!m_startUrl.isEmpty()) { + // we tried to open an invalid file from command line, init new project + newFile(false); + } return; } @@ -2134,7 +2190,6 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale) progressDialog.progressBar()->setMaximum(4); progressDialog.show(); progressDialog.progressBar()->setValue(0); - qApp->processEvents(); bool openBackup; KdenliveDoc *doc = new KdenliveDoc(stale ? KUrl(stale->fileName()) : url, KdenliveSettings::defaultprojectfolder(), m_commandStack, KdenliveSettings::default_profile(), QMap (), QMap (), QPoint(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()), m_projectMonitor->render, m_notesWidget, &openBackup, this, &progressDialog); @@ -2142,7 +2197,7 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale) progressDialog.progressBar()->setValue(1); progressDialog.progressBar()->setMaximum(4); progressDialog.setLabelText(i18n("Loading project")); - qApp->processEvents(); + progressDialog.repaint(); if (stale == NULL) { QByteArray hash = QCryptographicHash::hash(url.encodedPath(), QCryptographicHash::Md5).toHex(); @@ -2157,13 +2212,13 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale) connectDocumentInfo(doc); progressDialog.progressBar()->setValue(2); - qApp->processEvents(); + progressDialog.repaint(); bool ok; TrackView *trackView = new TrackView(doc, m_tracksActionCollection->actions(), &ok, this); connectDocument(trackView, doc); progressDialog.progressBar()->setValue(3); - qApp->processEvents(); + progressDialog.repaint(); m_timelineArea->setCurrentIndex(m_timelineArea->addTab(trackView, KIcon("kdenlive"), doc->description())); if (!ok) { @@ -2176,7 +2231,6 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale) } m_timelineArea->setTabToolTip(m_timelineArea->currentIndex(), doc->url().path()); trackView->setDuration(trackView->duration()); - trackView->projectView()->initCursorPos(m_projectMonitor->render->seekPosition().frames(doc->fps())); if (m_timelineArea->count() > 1) m_timelineArea->setTabBarHidden(false); slotGotProgressInfo(QString(), -1); @@ -2382,7 +2436,6 @@ void MainWindow::slotUpdateProjectProfile(const QString &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_activeDocument->tracksList()); @@ -2397,6 +2450,7 @@ void MainWindow::slotUpdateProjectProfile(const QString &profile) m_commandStack->activeStack()->clear(); //Update the mouse position display so it will display in DF/NDF format by default based on the project setting. slotUpdateMousePosition(0); + m_projectList->slotReloadClip(); // We need to desactivate & reactivate monitors to get a refresh //m_monitorManager->switchMonitors(); } @@ -2413,7 +2467,7 @@ void MainWindow::slotRenderProject() connect(m_renderWidget, SIGNAL(selectedRenderProfile(QMap )), this, SLOT(slotSetDocumentRenderProfile(QMap ))); 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 &))); - connect(m_renderWidget, SIGNAL(openDvdWizard(const QString &, const QString &)), this, SLOT(slotDvdWizard(const QString &, const QString &))); + connect(m_renderWidget, SIGNAL(openDvdWizard(const QString &)), this, SLOT(slotDvdWizard(const QString &))); if (m_activeDocument) { m_renderWidget->setProfile(m_activeDocument->mltProfile()); m_renderWidget->setGuides(m_activeDocument->guidesXml(), m_activeDocument->projectDuration()); @@ -2521,7 +2575,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha disconnect(m_activeTimeline->projectView(), SIGNAL(playMonitor()), m_projectMonitor, SLOT(slotPlay())); disconnect(m_activeTimeline->projectView(), SIGNAL(displayMessage(const QString&, MessageType)), m_messageLabel, SLOT(setMessage(const QString&, MessageType))); disconnect(m_activeTimeline->projectView(), SIGNAL(showClipFrame(DocClipBase *, QPoint, bool, const int)), m_clipMonitor, SLOT(slotSetClipProducer(DocClipBase *, QPoint, bool, const int))); - disconnect(m_projectList, SIGNAL(gotFilterJobResults(const QString &, int, int, const QString &, stringMap)), m_activeTimeline->projectView(), SLOT(slotGotFilterJobResults(const QString &, int, int, const QString &, stringMap))); + disconnect(m_projectList, SIGNAL(gotFilterJobResults(const QString &, int, int, stringMap,stringMap)), m_activeTimeline->projectView(), SLOT(slotGotFilterJobResults(const QString &, int, int, stringMap, stringMap))); disconnect(m_activeTimeline, SIGNAL(cursorMoved()), m_projectMonitor, SLOT(slotActivateMonitor())); disconnect(m_activeTimeline, SIGNAL(configTrack(int)), this, SLOT(slotConfigTrack(int))); @@ -2536,10 +2590,13 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha disconnect(m_effectStack, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int))); disconnect(m_transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), m_activeTimeline->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement))); disconnect(m_transitionConfig, SIGNAL(seekTimeline(int)), m_activeTimeline->projectView() , SLOT(setCursorPos(int))); + disconnect(m_transitionConfig, SIGNAL(importClipKeyframes(GRAPHICSRECTITEM)), m_activeTimeline->projectView() , SLOT(slotImportClipKeyframes(GRAPHICSRECTITEM))); + disconnect(m_activeTimeline->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(slotActivateMonitor())); 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(refreshClip(const QString &)), m_activeTimeline->projectView(), SLOT(slotRefreshThumbs(const QString &))); + disconnect(m_projectList, SIGNAL(addMarkers(const QString &, QList )), m_activeTimeline->projectView(), SLOT(slotAddClipMarker(const QString &, QList ))); m_effectStack->clear(); } //m_activeDocument->setRenderer(NULL); @@ -2561,6 +2618,9 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(trackView, SIGNAL(updateTracksInfo()), this, SLOT(slotUpdateTrackInfo())); connect(trackView, SIGNAL(mousePosition(int)), this, SLOT(slotUpdateMousePosition(int))); connect(trackView->projectView(), SIGNAL(forceClipProcessing(const QString &)), m_projectList, SLOT(slotForceProcessing(const QString &))); + + connect(trackView->projectView(), SIGNAL(importKeyframes(GRAPHICSRECTITEM, const QString&, int)), this, SLOT(slotProcessImportKeyframes(GRAPHICSRECTITEM, const QString&, int))); + connect(m_projectMonitor, SIGNAL(renderPosition(int)), trackView, SLOT(moveCursorPos(int))); connect(m_projectMonitor, SIGNAL(zoneUpdated(QPoint)), trackView, SLOT(slotSetZone(QPoint))); connect(m_projectMonitor, SIGNAL(zoneUpdated(QPoint)), doc, SLOT(setModified())); @@ -2597,7 +2657,9 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(trackView->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), m_projectMonitor, SLOT(slotSetSelectedClip(Transition*))); - connect(m_projectList, SIGNAL(gotFilterJobResults(const QString &, int, int, const QString &, stringMap)), trackView->projectView(), SLOT(slotGotFilterJobResults(const QString &, int, int, const QString &, stringMap))); + connect(m_projectList, SIGNAL(gotFilterJobResults(const QString &, int, int, stringMap,stringMap)), trackView->projectView(), SLOT(slotGotFilterJobResults(const QString &, int, int, stringMap,stringMap))); + + connect(m_projectList, SIGNAL(addMarkers(const QString &, QList )), trackView->projectView(), SLOT(slotAddClipMarker(const QString &, QList ))); // Effect stack signals connect(m_effectStack, SIGNAL(updateEffect(ClipItem*, int, QDomElement, QDomElement, int,bool)), trackView->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, int, QDomElement, QDomElement, int,bool))); @@ -2606,13 +2668,16 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(m_effectStack, SIGNAL(addEffect(ClipItem*, QDomElement)), trackView->projectView(), SLOT(slotAddEffect(ClipItem*, QDomElement))); connect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, QList , bool)), trackView->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, QList , bool))); connect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, QList , int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, QList , int))); + connect(m_effectStack, SIGNAL(refreshEffectStack(ClipItem*)), trackView->projectView(), SLOT(slotRefreshEffects(ClipItem*))); - connect(m_effectStack, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(seekCursorPos(int))); + connect(m_effectStack, SIGNAL(seekTimeline(int)), trackView->projectView(), SLOT(seekCursorPos(int))); + connect(m_effectStack, SIGNAL(importClipKeyframes(GRAPHICSRECTITEM)), trackView->projectView(), SLOT(slotImportClipKeyframes(GRAPHICSRECTITEM))); connect(m_effectStack, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects())); connect(m_effectStack, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int))); // Transition config signals connect(m_transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement))); + connect(m_transitionConfig, SIGNAL(importClipKeyframes(GRAPHICSRECTITEM)), trackView->projectView() , SLOT(slotImportClipKeyframes(GRAPHICSRECTITEM))); connect(m_transitionConfig, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(seekCursorPos(int))); connect(trackView->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(slotActivateMonitor())); @@ -2640,6 +2705,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha m_saveAction->setEnabled(doc->isModified()); m_normalEditTool->setChecked(true); m_activeDocument = doc; + m_monitorManager->setDocument(m_activeDocument); m_activeTimeline->updateProjectFps(); m_activeDocument->checkProjectClips(); #ifndef Q_WS_MAC @@ -2647,7 +2713,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha #endif //Update the mouse position display so it will display in DF/NDF format by default based on the project setting. slotUpdateMousePosition(0); - m_monitorManager->activateMonitor(Kdenlive::clipMonitor); + m_monitorManager->activateMonitor(Kdenlive::clipMonitor, true); // set tool to select tool m_buttonSelectTool->setChecked(true); } @@ -2733,7 +2799,7 @@ void MainWindow::updateConfiguration() // Update list of transcoding profiles loadTranscoders(); - loadStabilize(); + loadClipActions(); #ifdef USE_JOGSHUTTLE activateShuttleDevice(); #endif @@ -2833,11 +2899,14 @@ void MainWindow::slotAddClipMarker() return; } QString id = clip->getId(); - CommentedTime marker(pos, i18n("Marker")); + CommentedTime marker(pos, i18n("Marker"), KdenliveSettings::default_marker_type()); QPointer d = new MarkerDialog(clip, marker, m_activeDocument->timecode(), i18n("Add Marker"), this); - if (d->exec() == QDialog::Accepted) - m_activeTimeline->projectView()->slotAddClipMarker(id, d->newMarker().time(), d->newMarker().comment()); + if (d->exec() == QDialog::Accepted) { + m_activeTimeline->projectView()->slotAddClipMarker(id, QList () << d->newMarker()); + QString hash = clip->getClipHash(); + if (!hash.isEmpty()) m_activeDocument->cacheImage(hash + '#' + QString::number(d->newMarker().time().frames(m_activeDocument->fps())), d->markerImage()); + } delete d; } @@ -2913,20 +2982,22 @@ void MainWindow::slotEditClipMarker() } QString id = clip->getId(); - QString oldcomment = clip->markerComment(pos); - if (oldcomment.isEmpty()) { + CommentedTime oldMarker = clip->markerAt(pos); + if (oldMarker == CommentedTime()) { m_messageLabel->setMessage(i18n("No marker found at cursor time"), ErrorMessage); return; } - CommentedTime marker(pos, oldcomment); - QPointer d = new MarkerDialog(clip, marker, + QPointer d = new MarkerDialog(clip, oldMarker, m_activeDocument->timecode(), i18n("Edit Marker"), this); if (d->exec() == QDialog::Accepted) { - m_activeTimeline->projectView()->slotAddClipMarker(id, d->newMarker().time(), d->newMarker().comment()); + m_activeTimeline->projectView()->slotAddClipMarker(id, QList () <newMarker()); + QString hash = clip->getClipHash(); + if (!hash.isEmpty()) m_activeDocument->cacheImage(hash + '#' + QString::number(d->newMarker().time().frames(m_activeDocument->fps())), d->markerImage()); if (d->newMarker().time() != pos) { // remove old marker - m_activeTimeline->projectView()->slotAddClipMarker(id, pos, QString()); + oldMarker.setMarkerType(-1); + m_activeTimeline->projectView()->slotAddClipMarker(id, QList () <setMessage(i18n("Cannot find clip to add marker"), ErrorMessage); return; } - - m_activeTimeline->projectView()->slotAddClipMarker(clip->getId(), pos, m_activeDocument->timecode().getDisplayTimecode(pos, false)); + //TODO: allow user to set default marker category + CommentedTime marker(pos, m_activeDocument->timecode().getDisplayTimecode(pos, false), KdenliveSettings::default_marker_type()); + m_activeTimeline->projectView()->slotAddClipMarker(clip->getId(), QList () <projectView()->slotAddGuide(false); } @@ -2972,7 +3044,7 @@ void MainWindow::slotRemoveSpace() void MainWindow::slotInsertTrack(int ix) { - m_projectMonitor->slotActivateMonitor(); + m_monitorManager->activateMonitor(Kdenlive::projectMonitor); if (m_activeTimeline) { if (ix == -1) ix = m_activeTimeline->projectView()->selectedTrack(); m_activeTimeline->projectView()->slotInsertTrack(ix); @@ -2983,7 +3055,7 @@ void MainWindow::slotInsertTrack(int ix) void MainWindow::slotDeleteTrack(int ix) { - m_projectMonitor->slotActivateMonitor(); + m_monitorManager->activateMonitor(Kdenlive::projectMonitor); if (m_activeTimeline) { if (ix == -1) ix = m_activeTimeline->projectView()->selectedTrack(); m_activeTimeline->projectView()->slotDeleteTrack(ix); @@ -2994,7 +3066,7 @@ void MainWindow::slotDeleteTrack(int ix) void MainWindow::slotConfigTrack(int ix) { - m_projectMonitor->slotActivateMonitor(); + m_monitorManager->activateMonitor(Kdenlive::projectMonitor); if (m_activeTimeline) m_activeTimeline->projectView()->slotConfigTracks(ix); if (m_activeDocument) @@ -3003,7 +3075,7 @@ void MainWindow::slotConfigTrack(int ix) void MainWindow::slotSelectTrack() { - m_projectMonitor->slotActivateMonitor(); + m_monitorManager->activateMonitor(Kdenlive::projectMonitor); if (m_activeTimeline) { m_activeTimeline->projectView()->slotSelectClipsInTrack(); } @@ -3011,7 +3083,7 @@ void MainWindow::slotSelectTrack() void MainWindow::slotSelectAllTracks() { - m_projectMonitor->slotActivateMonitor(); + m_monitorManager->activateMonitor(Kdenlive::projectMonitor); if (m_activeTimeline) m_activeTimeline->projectView()->slotSelectAllClips(); } @@ -3102,16 +3174,17 @@ void MainWindow::slotEditItemDuration() m_activeTimeline->projectView()->editItemDuration(); } -void MainWindow::slotAddProjectClip(KUrl url, const QString &comment) +void MainWindow::slotAddProjectClip(KUrl url, stringMap data) { - if (m_activeDocument) - m_activeDocument->slotAddClipFile(url, QString(), QString(), comment); + if (m_activeDocument) { + m_activeDocument->slotAddClipFile(url, data); + } } void MainWindow::slotAddProjectClipList(KUrl::List urls) { if (m_activeDocument) - m_activeDocument->slotAddClipList(urls, QString()); + m_activeDocument->slotAddClipList(urls); } void MainWindow::slotAddTransition(QAction *result) @@ -3196,19 +3269,13 @@ void MainWindow::slotUpdateZoomSliderToolTip(int zoomlevel) m_zoomSlider->setToolTip(i18n("Zoom Level: %1/13", (13 - zoomlevel))); } -void MainWindow::slotGotProgressInfo(const QString &message, int progress) +void MainWindow::slotGotProgressInfo(const QString &message, int progress, MessageType type) { - m_statusProgressBar->setValue(progress); + if (type == DefaultMessage) m_statusProgressBar->setValue(progress); + m_messageLabel->setMessage(message, type); if (progress >= 0) { - if (!message.isEmpty()) - m_messageLabel->setMessage(message, InformationMessage);//statusLabel->setText(message); - m_statusProgressBar->setVisible(true); - } else if (progress == -2) { - if (!message.isEmpty()) - m_messageLabel->setMessage(message, ErrorMessage); - m_statusProgressBar->setVisible(false); + if (type == DefaultMessage) m_statusProgressBar->setVisible(true); } else { - m_messageLabel->setMessage(QString(), DefaultMessage); m_statusProgressBar->setVisible(false); } } @@ -3280,12 +3347,12 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip) if (dia_ui->exec() == QDialog::Accepted) { QMap newprops; newprops.insert("xmldata", dia_ui->xml().toString()); - if (dia_ui->outPoint() != clip->duration().frames(m_activeDocument->fps())) { + if (dia_ui->duration() != clip->duration().frames(m_activeDocument->fps())) { // duration changed, we need to update duration - newprops.insert("out", QString::number(dia_ui->outPoint())); + newprops.insert("out", QString::number(dia_ui->duration() - 1)); int currentLength = QString(clip->producerProperty("length")).toInt(); - if (currentLength <= dia_ui->outPoint()) - newprops.insert("length", QString::number(dia_ui->outPoint() + 1)); + if (currentLength <= dia_ui->duration()) + newprops.insert("length", QString::number(dia_ui->duration())); else newprops.insert("length", clip->producerProperty("length")); } if (!path.isEmpty()) { @@ -3305,10 +3372,34 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip) //m_activeDocument->editTextClip(clip->getProperty("xml"), clip->getId()); return; } + + // Check if we already have a properties dialog opened for that clip + QList list = findChildren(); + for (int i = 0; i < list.size(); ++i) { + if (list.at(i)->clipId() == clip->getId()) { + // We have one dialog, show it + list.at(i)->raise(); + return; + } + } // 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))); + + if (clip->clipType() == AV || clip->clipType() == VIDEO || clip->clipType() == PLAYLIST || clip->clipType() == SLIDESHOW) { + // request clip thumbnails + connect(m_activeDocument->clipManager(), SIGNAL(gotClipPropertyThumbnail(const QString&,QImage)), dia, SLOT(slotGotThumbnail(const QString&,QImage))); + connect(dia, SIGNAL(requestThumb(const QString, QList )), m_activeDocument->clipManager(), SLOT(slotRequestThumbs(QString,QList))); + m_activeDocument->clipManager()->slotRequestThumbs(QString('?' + clip->getId()), QList() << clip->getClipThumbFrame()); + } + + connect(dia, SIGNAL(addMarkers(const QString &, QList )), m_activeTimeline->projectView(), SLOT(slotAddClipMarker(const QString &, QList ))); + connect(dia, SIGNAL(editAnalysis(QString,QString,QString)), m_activeTimeline->projectView(), SLOT(slotAddClipExtraData(QString,QString,QString))); + connect(m_activeTimeline->projectView(), SIGNAL(updateClipMarkers(DocClipBase *)), dia, SLOT(slotFillMarkersList(DocClipBase *))); + connect(m_activeTimeline->projectView(), SIGNAL(updateClipExtraData(DocClipBase *)), dia, SLOT(slotUpdateAnalysisData(DocClipBase *))); + connect(m_projectList, SIGNAL(updateAnalysisData(DocClipBase *)), dia, SLOT(slotUpdateAnalysisData(DocClipBase *))); + connect(dia, SIGNAL(loadMarkers(const QString &)), m_activeTimeline->projectView(), SLOT(slotLoadClipMarkers(const QString &))); + connect(dia, SIGNAL(saveMarkers(const QString &)), m_activeTimeline->projectView(), SLOT(slotSaveClipMarkers(const 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(); @@ -3363,6 +3454,11 @@ void MainWindow::customEvent(QEvent* e) void MainWindow::slotTimelineClipSelected(ClipItem* item, bool raise) { + if (item != m_mainClip) { + if (m_mainClip) m_mainClip->setMainSelectedClip(false); + if (item) item->setMainSelectedClip(true); + m_mainClip = item; + } m_effectStack->slotClipItemSelected(item); m_projectMonitor->slotSetSelectedClip(item); if (raise) @@ -3574,12 +3670,13 @@ void MainWindow::slotClipInTimeline(const QString &clipId) void MainWindow::slotClipInProjectTree() { if (m_activeTimeline) { - const QStringList &clipIds = m_activeTimeline->projectView()->selectedClips(); + QStringList clipIds; + if (m_mainClip) clipIds << m_mainClip->clipProducer(); + else clipIds = m_activeTimeline->projectView()->selectedClips(); if (clipIds.isEmpty()) return; m_projectListDock->raise(); - for (int i = 0; i < clipIds.count(); i++) - m_projectList->selectItemById(clipIds.at(i)); + m_projectList->selectItemById(clipIds.at(0)); if (m_projectMonitor->isActive()) slotSwitchMonitors(); } @@ -3843,15 +3940,14 @@ void MainWindow::slotUpdateClipType(QAction *action) } } -void MainWindow::slotDvdWizard(const QString &url, const QString &profile) +void MainWindow::slotDvdWizard(const QString &url) { // We must stop the monitors since we create a new on in the dvd wizard - m_clipMonitor->stop(); - m_projectMonitor->stop(); - QPointer w = new DvdWizard(url, profile, this); + m_monitorManager->activateMonitor(Kdenlive::dvdMonitor); + QPointer w = new DvdWizard(m_monitorManager, url, this); w->exec(); - m_projectMonitor->start(); delete w; + m_monitorManager->activateMonitor(Kdenlive::clipMonitor); } void MainWindow::slotShowTimeline(bool show) @@ -3876,25 +3972,50 @@ void MainWindow::slotMaximizeCurrent(bool) kDebug() << "CURRENT WIDGET: " << par->objectName(); } -void MainWindow::loadStabilize() +void MainWindow::loadClipActions() { - QMenu* stabMenu= static_cast(factory()->container("stabilize", this)); - if (stabMenu){ - stabMenu->clear(); + QMenu* actionMenu= static_cast(factory()->container("clip_actions", this)); + if (actionMenu){ + actionMenu->clear(); Mlt::Profile profile; - if (Mlt::Factory::filter(profile,(char*)"videostab")){ - QAction *action=stabMenu->addAction("Videostab (vstab)"); - action->setData("videostab"); - connect(action,SIGNAL(triggered()), this, SLOT(slotStabilize())); + Mlt::Filter *filter = Mlt::Factory::filter(profile,(char*)"videostab"); + if (filter) { + if (!filter->is_valid()) { + delete filter; + } + else { + delete filter; + QAction *action=actionMenu->addAction(i18n("Stabilize (vstab)")); + action->setData("videostab"); + connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction())); + } + } + filter = Mlt::Factory::filter(profile,(char*)"videostab2"); + if (filter) { + if (!filter->is_valid()) { + delete filter; + } + else { + delete filter; + QAction *action=actionMenu->addAction(i18n("Stabilize (transcode)")); + action->setData("videostab2"); + connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction())); + } } - if (Mlt::Factory::filter(profile,(char*)"videostab2")){ - QAction *action=stabMenu->addAction("Videostab (transcode)"); - action->setData("videostab2"); - connect(action,SIGNAL(triggered()), this, SLOT(slotStabilize())); + filter = Mlt::Factory::filter(profile,(char*)"motion_est"); + if (filter) { + if (!filter->is_valid()) { + delete filter; + } + else { + delete filter; + QAction *action=actionMenu->addAction(i18n("Automatic scene split")); + action->setData("motion_est"); + connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction())); + } } } - } void MainWindow::loadTranscoders() @@ -3905,7 +4026,7 @@ void MainWindow::loadTranscoders() QMenu *extractAudioMenu = static_cast(factory()->container("extract_audio", this)); extractAudioMenu->clear(); - KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc"); + KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc", KConfig::CascadeConfig); KConfigGroup transConfig(config, "Transcoding"); // read the entries QMap< QString, QString > profiles = transConfig.entryMap(); @@ -3927,7 +4048,7 @@ void MainWindow::loadTranscoders() } } -void MainWindow::slotStabilize() +void MainWindow::slotStartClipAction() { QString condition,filtername; QStringList ids; @@ -3938,22 +4059,6 @@ void MainWindow::slotStabilize() filtername=action->data().toString(); } m_projectList->startClipFilterJob(filtername, condition); - /* - if (ids.isEmpty()) { - m_messageLabel->setMessage(i18n("No clip to transcode"), ErrorMessage); - return; - } - QString destination; - ProjectItem *item = m_projectList->getClipById(ids.at(0)); - if (ids.count() == 1) { - - } - ClipStabilize *d = new ClipStabilize(destination, ids.count(), filtername); - //connect(d, SIGNAL(addClip(KUrl)), this, SLOT(slotAddProjectClip(KUrl))); - if (d->exec() == QDialog::Accepted) { - m_projectList->slotStabilizeClipJob(ids, d->autoAddClip(), d->params(), d->desc()); - } - delete d;*/ } void MainWindow::slotTranscode(KUrl::List urls) @@ -3974,7 +4079,7 @@ void MainWindow::slotTranscode(KUrl::List urls) m_messageLabel->setMessage(i18n("No clip to transcode"), ErrorMessage); return; } - ClipTranscode *d = new ClipTranscode(urls, params, desc); + ClipTranscode *d = new ClipTranscode(urls, params, QStringList(), desc); connect(d, SIGNAL(addClip(KUrl)), this, SLOT(slotAddProjectClip(KUrl))); d->show(); } @@ -4004,12 +4109,17 @@ void MainWindow::slotPrepareRendering(bool scriptExport, bool zoneOnly, const QS QString scriptPath; QString playlistPath; if (scriptExport) { - bool ok; QString scriptsFolder = m_activeDocument->projectFolder().path(KUrl::AddTrailingSlash) + "scripts/"; - QString path = m_renderWidget->getFreeScriptName(); - scriptPath = QInputDialog::getText(this, i18n("Create Render Script"), i18n("Script name (will be saved in: %1)", scriptsFolder), QLineEdit::Normal, KUrl(path).fileName(), &ok); - if (!ok || scriptPath.isEmpty()) return; - scriptPath.prepend(scriptsFolder); + QString path = m_renderWidget->getFreeScriptName(m_activeDocument->url()); + QPointer getUrl = new KUrlRequesterDialog(path, i18n("Create Render Script"), this); + getUrl->fileDialog()->setMode(KFile::File); + getUrl->fileDialog()->setOperationMode(KFileDialog::Saving); + if (getUrl->exec() == QDialog::Rejected) { + delete getUrl; + return; + } + scriptPath = getUrl->selectedUrl().path(); + delete getUrl; QFile f(scriptPath); if (f.exists()) { if (KMessageBox::warningYesNo(this, i18n("Script file already exists. Do you want to overwrite it?")) != KMessageBox::Yes) @@ -4058,7 +4168,7 @@ void MainWindow::slotPrepareRendering(bool scriptExport, bool zoneOnly, const QS // Always insert a guide in pos 0 QDomElement chapter = doc.createElement("chapter"); chapters.insertBefore(chapter, QDomNode()); - chapter.setAttribute("title", i18n("Start")); + chapter.setAttribute("title", i18nc("the first in a list of chapters", "Start")); chapter.setAttribute("time", "0"); } // save chapters file @@ -4496,7 +4606,7 @@ void MainWindow::slotDownloadResources() if (m_activeDocument) currentFolder = m_activeDocument->projectFolder().path(); else currentFolder = KdenliveSettings::defaultprojectfolder(); ResourceWidget *d = new ResourceWidget(currentFolder); - connect(d, SIGNAL(addClip(KUrl, const QString &)), this, SLOT(slotAddProjectClip(KUrl, const QString &))); + connect(d, SIGNAL(addClip(KUrl,stringMap)), this, SLOT(slotAddProjectClip(KUrl,stringMap))); d->show(); } @@ -4529,6 +4639,26 @@ void MainWindow::slotSaveTimelineClip() } } +void MainWindow::slotProcessImportKeyframes(GRAPHICSRECTITEM type, const QString& data, int maximum) +{ + if (type == AVWIDGET) { + // This data should be sent to the effect stack + m_effectStack->setKeyframes(data, maximum); + } + else if (type == TRANSITIONWIDGET) { + // This data should be sent to the transition stack + m_transitionConfig->setKeyframes(data, maximum); + } + else { + // Error + } +} + +void MainWindow::slotAlignPlayheadToMousePos() +{ + m_monitorManager->activateMonitor(Kdenlive::projectMonitor); + m_activeTimeline->projectView()->slotAlignPlayheadToMousePos(); +} #include "mainwindow.moc"