#include "renderer.h"
#include "jogshuttle.h"
#include "clipproperties.h"
+#include "wizard.h"
-#define ID_STATUS_MSG 1
-#define ID_EDITMODE_MSG 2
-#define ID_TIMELINE_MSG 3
-#define ID_TIMELINE_BUTTONS 5
-#define ID_TIMELINE_POS 6
-#define ID_TIMELINE_FORMAT 7
+static const int ID_STATUS_MSG = 1;
+static const int ID_EDITMODE_MSG = 2;
+static const int ID_TIMELINE_MSG = 3;
+static const int ID_TIMELINE_BUTTONS = 5;
+static const int ID_TIMELINE_POS = 6;
+static const int ID_TIMELINE_FORMAT = 7;
namespace Mlt {
class Producer;
: KXmlGuiWindow(parent),
m_activeDocument(NULL), m_activeTimeline(NULL), m_renderWidget(NULL), m_jogProcess(NULL), m_findActivated(false), m_initialized(false) {
setlocale(LC_NUMERIC, "POSIX");
- parseProfiles();
setFont(KGlobalSettings::toolBarFont());
+ parseProfiles();
m_commandStack = new QUndoGroup;
m_timelineArea = new KTabWidget(this);
m_timelineArea->setTabReorderingEnabled(true);
transitionConfigDock->setWidget(transitionConfig);
addDockWidget(Qt::TopDockWidgetArea, transitionConfigDock);
+ KdenliveSettings::setCurrent_profile(KdenliveSettings::default_profile());
+ m_fileOpenRecent = KStandardAction::openRecent(this, SLOT(openFile(const KUrl &)),
+ actionCollection());
+ readOptions();
clipMonitorDock = new QDockWidget(i18n("Clip Monitor"), this);
clipMonitorDock->setObjectName("clip_monitor");
tabifyDockWidget(projectListDock, effectStackDock);
tabifyDockWidget(projectListDock, transitionConfigDock);
//tabifyDockWidget(projectListDock, undoViewDock);
- projectListDock->raise();
+
tabifyDockWidget(clipMonitorDock, projectMonitorDock);
tabifyDockWidget(clipMonitorDock, recMonitorDock);
m_timelineContextMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Paste)));
m_timelineContextClipMenu->addAction(actionCollection()->action("delete_timeline_clip"));
+ m_timelineContextClipMenu->addAction(actionCollection()->action("change_clip_speed"));
m_timelineContextClipMenu->addAction(actionCollection()->action("cut_timeline_clip"));
m_timelineContextClipMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Copy)));
m_timelineContextClipMenu->addAction(actionCollection()->action("paste_effects"));
if (KdenliveSettings::openlastproject()) {
openLastFile();
- } else newFile();
+ } else {
+ /*QList<KAutoSaveFile *> staleFiles = KAutoSaveFile::allStaleFiles();
+ if (!staleFiles.isEmpty()) {
+ if (KMessageBox::questionYesNo(this, i18n("Auto-saved files exist. Do you want to recover them now?"), i18n("File Recovery"), KGuiItem(i18n("Recover")), KGuiItem(i18n("Don't recover"))) == KMessageBox::Yes) {
+ recoverFiles(staleFiles);
+ }
+ else newFile();
+ }
+ else*/
+ newFile();
+ }
activateShuttleDevice();
+ projectListDock->raise();
}
void MainWindow::queryQuit() {
else projectMonitorDock->raise();
}
-void MainWindow::slotSetClipDuration(int id, int duration) {
+void MainWindow::slotSetClipDuration(const QString &id, int duration) {
if (!m_activeDocument) return;
m_activeDocument->setProducerDuration(id, duration);
}
void MainWindow::slotConnectMonitors() {
m_projectList->setRenderer(m_clipMonitor->render);
- connect(m_projectList, SIGNAL(receivedClipDuration(int, int)), this, SLOT(slotSetClipDuration(int, int)));
+ connect(m_projectList, SIGNAL(receivedClipDuration(const QString &, int)), this, SLOT(slotSetClipDuration(const QString &, int)));
connect(m_projectList, SIGNAL(showClipProperties(DocClipBase *)), this, SLOT(slotShowClipProperties(DocClipBase *)));
- connect(m_projectList, SIGNAL(getFileProperties(const QDomElement &, int)), m_clipMonitor->render, SLOT(getFileProperties(const QDomElement &, int)));
- connect(m_clipMonitor->render, SIGNAL(replyGetImage(int, int, const QPixmap &, int, int)), m_projectList, SLOT(slotReplyGetImage(int, int, const QPixmap &, int, int)));
- connect(m_clipMonitor->render, SIGNAL(replyGetFileProperties(int, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &)), m_projectList, SLOT(slotReplyGetFileProperties(int, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &)));
+ connect(m_projectList, SIGNAL(getFileProperties(const QDomElement &, const QString &)), m_clipMonitor->render, SLOT(getFileProperties(const QDomElement &, const QString &)));
+ connect(m_clipMonitor->render, SIGNAL(replyGetImage(const QString &, int, const QPixmap &, int, int)), m_projectList, SLOT(slotReplyGetImage(const QString &, int, const QPixmap &, int, int)));
+ connect(m_clipMonitor->render, SIGNAL(replyGetFileProperties(const QString &, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &)), m_projectList, SLOT(slotReplyGetFileProperties(const QString &, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &)));
+
+ connect(m_clipMonitor->render, SIGNAL(removeInvalidClip(const QString &)), m_projectList, SLOT(slotRemoveInvalidClip(const QString &)));
- connect(m_clipMonitor->render, SIGNAL(removeInvalidClip(int)), m_projectList, SLOT(slotRemoveInvalidClip(int)));
+ connect(m_clipMonitor, SIGNAL(refreshClipThumbnail(const QString &)), m_projectList, SLOT(slotRefreshClipThumbnail(const QString &)));
- connect(m_clipMonitor, SIGNAL(refreshClipThumbnail(int)), m_projectList, SLOT(slotRefreshClipThumbnail(int)));
+ connect(m_clipMonitor, SIGNAL(adjustMonitorSize()), this, SLOT(slotAdjustClipMonitor()));
+ connect(m_projectMonitor, SIGNAL(adjustMonitorSize()), this, SLOT(slotAdjustProjectMonitor()));
+}
+
+void MainWindow::slotAdjustClipMonitor() {
+ clipMonitorDock->updateGeometry();
+ clipMonitorDock->adjustSize();
+ m_clipMonitor->resetSize();
+}
+
+void MainWindow::slotAdjustProjectMonitor() {
+ projectMonitorDock->updateGeometry();
+ projectMonitorDock->adjustSize();
+ m_projectMonitor->resetSize();
}
void MainWindow::setupActions() {
actionCollection()->addAction("delete_timeline_clip", deleteTimelineClip);
connect(deleteTimelineClip, SIGNAL(triggered(bool)), this, SLOT(slotDeleteTimelineClip()));
+ KAction* editTimelineClipSpeed = new KAction(KIcon("edit-delete"), i18n("Change Clip Speed"), this);
+ actionCollection()->addAction("change_clip_speed", editTimelineClipSpeed);
+ connect(editTimelineClipSpeed, SIGNAL(triggered(bool)), this, SLOT(slotChangeClipSpeed()));
+
KAction* cutTimelineClip = new KAction(KIcon("edit-cut"), i18n("Cut Clip"), this);
cutTimelineClip->setShortcut(Qt::SHIFT + Qt::Key_R);
actionCollection()->addAction("cut_timeline_clip", cutTimelineClip);
KStandardAction::open(this, SLOT(openFile()),
actionCollection());
- m_fileOpenRecent = KStandardAction::openRecent(this, SLOT(openFile(const KUrl &)),
- actionCollection());
-
KStandardAction::save(this, SLOT(saveFile()),
actionCollection());
KStandardAction::paste(this, SLOT(slotPaste()),
actionCollection());
- KStandardAction::undo(this, SLOT(undo()),
- actionCollection());
+ KAction *undo = KStandardAction::undo(m_commandStack, SLOT(undo()),
+ actionCollection());
+ undo->setEnabled(false);
+ connect(m_commandStack, SIGNAL(canUndoChanged(bool)), undo, SLOT(setEnabled(bool)));
- KStandardAction::redo(this, SLOT(redo()),
- actionCollection());
+ KAction *redo = KStandardAction::redo(m_commandStack, SLOT(redo()),
+ actionCollection());
+ redo->setEnabled(false);
+ connect(m_commandStack, SIGNAL(canRedoChanged(bool)), redo, SLOT(setEnabled(bool)));
KStandardAction::fullScreen(this, SLOT(slotFullScreen()), this, actionCollection());
this, SLOT(slotDisplayActionMessage(QAction*)));
//connect(actionCollection(), SIGNAL( clearStatusText() ),
//statusBar(), SLOT( clear() ) );
-
- readOptions();
-}
-
-void MainWindow::undo() {
- m_commandStack->undo();
-}
-
-void MainWindow::redo() {
- m_commandStack->redo();
}
void MainWindow::slotDisplayActionMessage(QAction *a) {
void MainWindow::readOptions() {
KSharedConfigPtr config = KGlobal::config();
m_fileOpenRecent->loadEntries(KConfigGroup(config, "Recent Files"));
+ KConfigGroup initialGroup(config, "version");
+ if (!initialGroup.exists()) {
+ // this is our first run, show Wizard
+ Wizard *w = new Wizard(this);
+ if (w->exec() == QDialog::Accepted) {
+ w->adjustSettings();
+ initialGroup.writeEntry("version", "0.7");
+ }
+ delete w;
+ }
}
void MainWindow::newFile() {
projectFolder = w->selectedFolder();
delete w;
}
- MltVideoProfile prof;
- if (!profileName.isEmpty()) prof = ProfilesDialog::getVideoProfile(profileName);
- else prof = ProfilesDialog::getVideoProfile("dv_pal");
- if (prof.width == 0) prof = ProfilesDialog::getVideoProfile("dv_pal");
- KdenliveDoc *doc = new KdenliveDoc(KUrl(), projectFolder, prof, m_commandStack, this);
+ KdenliveDoc *doc = new KdenliveDoc(KUrl(), projectFolder, m_commandStack, profileName, this);
+ doc->m_autosave = new KAutoSaveFile(KUrl(), doc);
TrackView *trackView = new TrackView(doc, this);
- m_timelineArea->addTab(trackView, KIcon("kdenlive"), i18n("Untitled") + " / " + prof.description);
+ m_timelineArea->addTab(trackView, KIcon("kdenlive"), doc->description());
if (m_timelineArea->count() == 1) {
connectDocumentInfo(doc);
connectDocument(trackView, doc);
void MainWindow::saveFileAs(const QString &outputFileName) {
m_projectMonitor->saveSceneList(outputFileName, m_activeDocument->documentInfoXml());
m_activeDocument->setUrl(KUrl(outputFileName));
+ if (m_activeDocument->m_autosave == NULL) {
+ m_activeDocument->m_autosave = new KAutoSaveFile(KUrl(outputFileName), this);
+ } else m_activeDocument->m_autosave->setManagedFile(KUrl(outputFileName));
setCaption(m_activeDocument->description());
m_timelineArea->setTabText(m_timelineArea->currentIndex(), m_activeDocument->description());
m_timelineArea->setTabToolTip(m_timelineArea->currentIndex(), m_activeDocument->url().path());
saveFileAs();
} else {
saveFileAs(m_activeDocument->url().path());
+ m_activeDocument->m_autosave->resize(0);
}
}
void MainWindow::openLastFile() {
KSharedConfigPtr config = KGlobal::config();
- QString Lastproject = config->group("Recent Files").readPathEntry("File1", QString());
- openFile(KUrl(Lastproject));
+ KUrl::List urls = m_fileOpenRecent->urls();
+ if (urls.isEmpty()) newFile();
+ else openFile(urls.last());
}
void MainWindow::openFile(const KUrl &url) {
// Check for backup file
- bool recovery = false;
- QString directory = url.directory();
- QString fileName = url.fileName();
- KUrl recoveryUrl;
- recoveryUrl.setDirectory(directory);
- recoveryUrl.setFileName("~" + fileName);
- if (KIO::NetAccess::exists(recoveryUrl, KIO::NetAccess::SourceSide, this)) {
- KFileItem bkup(KFileItem::Unknown, KFileItem::Unknown, recoveryUrl, true);
- KFileItem src(KFileItem::Unknown, KFileItem::Unknown, url, true);
- if (bkup.time(KFileItem::ModificationTime) > src.time(KFileItem::ModificationTime)) {
- // Backup file is more recent than source file, ask user for recovery
- if (KMessageBox::questionYesNo(this, i18n("A newer recovery file exists for <b>%1</b>\nOpen recovery file ?", url.fileName())) == KMessageBox::Yes) recovery = true;
+
+ QList<KAutoSaveFile *> staleFiles = KAutoSaveFile::staleFiles(url);
+ if (!staleFiles.isEmpty()) {
+ if (KMessageBox::questionYesNo(this,
+ i18n("Auto-saved files exist. Do you want to recover them now?"),
+ i18n("File Recovery"),
+ KGuiItem(i18n("Recover")), KGuiItem(i18n("Don't recover"))) == KMessageBox::Yes) {
+ recoverFiles(staleFiles);
+ return;
+ } else {
+ // remove the stale files
+ foreach(KAutoSaveFile *stale, staleFiles) {
+ stale->open(QIODevice::ReadWrite);
+ delete stale;
+ }
}
}
+ doOpenFile(url, NULL);
+}
- //TODO: get video profile from url before opening it
- MltVideoProfile prof = ProfilesDialog::getVideoProfile(KdenliveSettings::default_profile());
- if (prof.width == 0) prof = ProfilesDialog::getVideoProfile("dv_pal");
+void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale) {
KdenliveDoc *doc;
- if (recovery) {
- doc = new KdenliveDoc(recoveryUrl, KUrl(), prof, m_commandStack, this);
- doc->setUrl(url);
+ doc = new KdenliveDoc(url, KUrl(), m_commandStack, QString(), this);
+ if (stale == NULL) {
+ stale = new KAutoSaveFile(url, doc);
+ doc->m_autosave = stale;
+ } else {
+ doc->m_autosave = stale;
+ doc->setUrl(stale->managedFile());
doc->setModified(true);
- } else doc = new KdenliveDoc(url, KUrl(), prof, m_commandStack, this);
+ stale->setParent(doc);
+ }
connectDocumentInfo(doc);
TrackView *trackView = new TrackView(doc, this);
m_timelineArea->setCurrentIndex(m_timelineArea->addTab(trackView, KIcon("kdenlive"), doc->description()));
if (m_timelineArea->count() > 1) m_timelineArea->setTabBarHidden(false);
slotGotProgressInfo(QString(), -1);
m_projectMonitor->refreshMonitor(true);
- //connectDocument(trackView, doc);
+}
+
+void MainWindow::recoverFiles(QList<KAutoSaveFile *> staleFiles) {
+ foreach(KAutoSaveFile *stale, staleFiles) {
+ /*if (!stale->open(QIODevice::QIODevice::ReadOnly)) {
+ // show an error message; we could not steal the lockfile
+ // maybe another application got to the file before us?
+ delete stale;
+ continue;
+ }*/
+ kDebug() << "// OPENING RECOVERY: " << stale->fileName() << "\nMANAGED: " << stale->managedFile().path();
+ // the stalefiles also contain ".lock" files so we must ignore them... bug in KAutoSaveFile ?
+ if (!stale->fileName().endsWith(".lock")) doOpenFile(KUrl(stale->fileName()), stale);
+ else KIO::NetAccess::del(KUrl(stale->fileName()), this);
+ }
}
if (w->exec() == QDialog::Accepted) {
QString profile = w->selectedProfile();
m_activeDocument->setProfilePath(profile);
- m_monitorManager->resetProfiles(profile);
+ KdenliveSettings::setCurrent_profile(profile);
+ KdenliveSettings::setProject_fps(m_activeDocument->fps());
setCaption(m_activeDocument->description());
- KdenliveSettings::setCurrent_profile(m_activeDocument->profilePath());
+ m_monitorManager->resetProfiles(m_activeDocument->timecode());
if (m_renderWidget) m_renderWidget->setDocumentStandard(m_activeDocument->getDocumentStandard());
- m_monitorManager->setTimecode(m_activeDocument->timecode());
m_timelineArea->setTabText(m_timelineArea->currentIndex(), m_activeDocument->description());
// We need to desactivate & reactivate monitors to get a refresh
disconnect(m_projectMonitor, SIGNAL(renderPosition(int)), m_activeTimeline, SLOT(moveCursorPos(int)));
disconnect(m_projectMonitor, SIGNAL(durationChanged(int)), m_activeTimeline, SLOT(setDuration(int)));
disconnect(m_activeDocument, SIGNAL(addProjectClip(DocClipBase *)), m_projectList, SLOT(slotAddClip(DocClipBase *)));
- disconnect(m_activeDocument, SIGNAL(addProjectFolder(const QString, int, bool, bool)), m_projectList, SLOT(slotAddFolder(const QString, int, bool, bool)));
- disconnect(m_activeDocument, SIGNAL(signalDeleteProjectClip(int)), m_projectList, SLOT(slotDeleteClip(int)));
- disconnect(m_activeDocument, SIGNAL(updateClipDisplay(int)), m_projectList, SLOT(slotUpdateClip(int)));
- disconnect(m_activeDocument, SIGNAL(refreshClipThumbnail(int)), m_projectList, SLOT(slotRefreshClipThumbnail(int)));
- disconnect(m_activeDocument, SIGNAL(deletTimelineClip(int)), m_activeTimeline, SLOT(slotDeleteClip(int)));
+ disconnect(m_activeDocument, SIGNAL(addProjectFolder(const QString, const QString &, bool, bool)), m_projectList, SLOT(slotAddFolder(const QString, const QString &, bool, bool)));
+ disconnect(m_activeDocument, SIGNAL(signalDeleteProjectClip(const QString &)), m_projectList, SLOT(slotDeleteClip(const QString &)));
+ disconnect(m_activeDocument, SIGNAL(updateClipDisplay(const QString &)), m_projectList, SLOT(slotUpdateClip(const QString &)));
+ disconnect(m_activeDocument, SIGNAL(refreshClipThumbnail(const QString &)), m_projectList, SLOT(slotRefreshClipThumbnail(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, SIGNAL(clipItemSelected(ClipItem*)), effectStack, SLOT(slotClipItemSelected(ClipItem*)));
disconnect(m_activeTimeline, SIGNAL(clipItemSelected(ClipItem*)), this, SLOT(slotActivateEffectStackView()));
disconnect(m_activeTimeline, SIGNAL(transitionItemSelected(Transition*)), transitionConfig, SLOT(slotTransitionItemSelected(Transition*)));
disconnect(m_projectList, SIGNAL(clipSelected(DocClipBase *)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *)));
m_clipMonitor->stop();
}
+ KdenliveSettings::setCurrent_profile(doc->profilePath());
KdenliveSettings::setProject_fps(doc->fps());
- m_monitorManager->resetProfiles(doc->profilePath());
+ m_monitorManager->resetProfiles(doc->timecode());
m_projectList->setDocument(doc);
connect(m_projectList, SIGNAL(clipSelected(DocClipBase *)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *)));
connect(trackView, SIGNAL(cursorMoved()), m_projectMonitor, SLOT(activateMonitor()));
connect(m_projectMonitor, SIGNAL(renderPosition(int)), trackView, SLOT(moveCursorPos(int)));
connect(m_projectMonitor, SIGNAL(durationChanged(int)), trackView, SLOT(setDuration(int)));
connect(doc, SIGNAL(addProjectClip(DocClipBase *)), m_projectList, SLOT(slotAddClip(DocClipBase *)));
- connect(doc, SIGNAL(addProjectFolder(const QString, int, bool, bool)), m_projectList, SLOT(slotAddFolder(const QString, int, bool, bool)));
- connect(doc, SIGNAL(signalDeleteProjectClip(int)), m_projectList, SLOT(slotDeleteClip(int)));
- connect(doc, SIGNAL(updateClipDisplay(int)), m_projectList, SLOT(slotUpdateClip(int)));
- connect(doc, SIGNAL(refreshClipThumbnail(int)), m_projectList, SLOT(slotRefreshClipThumbnail(int)));
+ connect(doc, SIGNAL(addProjectFolder(const QString, const QString &, bool, bool)), m_projectList, SLOT(slotAddFolder(const QString, const QString &, bool, bool)));
+ connect(doc, SIGNAL(signalDeleteProjectClip(const QString &)), m_projectList, SLOT(slotDeleteClip(const QString &)));
+ connect(doc, SIGNAL(updateClipDisplay(const QString &)), m_projectList, SLOT(slotUpdateClip(const QString &)));
+ connect(doc, SIGNAL(refreshClipThumbnail(const QString &)), m_projectList, SLOT(slotRefreshClipThumbnail(const QString &)));
+ connect(doc, SIGNAL(selectLastAddedClip(const QString &)), m_projectList, SLOT(slotSelectClip(const QString &)));
- connect(doc, SIGNAL(deletTimelineClip(int)), trackView, SLOT(slotDeleteClip(int)));
+ connect(doc, SIGNAL(deleteTimelineClip(const QString &)), trackView, SLOT(slotDeleteClip(const QString &)));
connect(doc, SIGNAL(docModified(bool)), this, SLOT(slotUpdateDocumentState(bool)));
connect(trackView->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(activateMonitor()));
trackView->projectView()->setContextMenu(m_timelineContextMenu, m_timelineContextClipMenu, m_timelineContextTransitionMenu);
m_activeTimeline = trackView;
- KdenliveSettings::setCurrent_profile(doc->profilePath());
if (m_renderWidget) m_renderWidget->setDocumentStandard(doc->getDocumentStandard());
- m_monitorManager->setTimecode(doc->timecode());
doc->setRenderer(m_projectMonitor->render);
m_commandStack->setActiveStack(doc->commandStack());
-
+ KdenliveSettings::setProject_display_ratio(doc->dar());
doc->updateAllProjectClips();
if (m_commandStack->isClean()) kDebug() << "//////////// UNDO STACK IS CLEAN";
// create it :
KdenliveSettingsDialog* dialog = new KdenliveSettingsDialog(this);
connect(dialog, SIGNAL(settingsChanged(const QString&)), this, SLOT(updateConfiguration()));
+ connect(dialog, SIGNAL(doResetProfile()), m_monitorManager, SLOT(slotResetProfiles()));
dialog->show();
if (page != -1) dialog->showPage(page, option);
}
}
}
+void MainWindow::slotChangeClipSpeed() {
+ if (m_activeTimeline) {
+ m_activeTimeline->projectView()->changeClipSpeed();
+ }
+}
+
void MainWindow::slotAddClipMarker() {
if (m_activeTimeline) {
m_activeTimeline->projectView()->slotAddClipMarker();
return;
}
ClipProperties dia(clip, m_activeDocument->timecode(), m_activeDocument->fps(), this);
- connect(&dia, SIGNAL(addMarker(int, GenTime, QString)), m_activeTimeline->projectView(), SLOT(slotAddClipMarker(int, GenTime, QString)));
+ connect(&dia, SIGNAL(addMarker(const QString &, GenTime, QString)), m_activeTimeline->projectView(), SLOT(slotAddClipMarker(const QString &, GenTime, QString)));
if (dia.exec() == QDialog::Accepted) {
m_projectList->slotUpdateClipProperties(dia.clipId(), dia.properties());
if (dia.needsTimelineRefresh()) {