X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmainwindow.cpp;h=3b64937db270269e57ded7e3d67bf92c0c22619c;hb=25b8bcc770a70a6c2d17f9b94b6c5b9df0c845f4;hp=f22a0e4412349016d55a043ffa039f8083b019eb;hpb=520bbaa47754e7bab9835f2434d64db904cccbd5;p=kdenlive diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f22a0e44..3b64937d 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), @@ -467,12 +472,12 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & 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("clipActionsMenu",static_cast(factory()->container("clip_actions", 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 @@ -574,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 @@ -605,33 +587,41 @@ 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"); if (KdenliveSettings::proxyparams().isEmpty() || KdenliveSettings::proxyextension().isEmpty()) { @@ -656,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(); @@ -669,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() @@ -676,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); @@ -919,7 +950,6 @@ void MainWindow::slotConnectMonitors() 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))); @@ -1248,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())); @@ -1510,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); @@ -2063,7 +2097,7 @@ void MainWindow::openLastFile() newFile(false); return; } - QAction *firstUrlAction = m_fileOpenRecent->selectableActionGroup()->actions().first(); + QAction *firstUrlAction = m_fileOpenRecent->selectableActionGroup()->actions().last(); if (firstUrlAction) firstUrlAction->trigger(); else newFile(false); } @@ -2145,7 +2179,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); @@ -2153,7 +2186,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(); @@ -2168,13 +2201,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) { @@ -2392,7 +2425,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()); @@ -2407,6 +2439,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(); } @@ -3297,12 +3330,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()) { @@ -3881,12 +3914,11 @@ void MainWindow::slotUpdateClipType(QAction *action) 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, 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) @@ -3919,24 +3951,39 @@ void MainWindow::loadClipActions() Mlt::Profile profile; Mlt::Filter *filter = Mlt::Factory::filter(profile,(char*)"videostab"); if (filter) { - delete filter; - QAction *action=actionMenu->addAction(i18n("Stabilize (vstab)")); - action->setData("videostab"); - connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction())); + 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) { - delete filter; - QAction *action=actionMenu->addAction(i18n("Stabilize (transcode)")); - action->setData("videostab2"); - connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction())); + 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())); + } } filter = Mlt::Factory::filter(profile,(char*)"motion_est"); if (filter) { - delete filter; - QAction *action=actionMenu->addAction(i18n("Automatic scene split")); - action->setData("motion_est"); - connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction())); + 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())); + } } } @@ -4049,12 +4096,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)