summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Mardelle <jb@kdenlive.org>2016-10-30 20:11:09 (GMT)
committerJean-Baptiste Mardelle <jb@kdenlive.org>2016-10-30 20:11:09 (GMT)
commitc5f07dfc6a9f1268b1c0b3e00dd75742a5bbd12f (patch)
tree7160e589e5526d2e932da27b60a8822697062d68
parentfd09b024794d5670befb63c9a8723b19edb5ebc2 (diff)
* timeline toolbar: add context menu to set icon size
* project folder: allow moving * improve project portability
-rw-r--r--src/doc/documentchecker.cpp62
-rw-r--r--src/doc/documentchecker.h1
-rw-r--r--src/doc/kdenlivedoc.cpp67
-rw-r--r--src/doc/kdenlivedoc.h3
-rw-r--r--src/icons.qrc1
-rw-r--r--src/library/librarywidget.cpp2
-rw-r--r--src/mainwindow.cpp144
-rw-r--r--src/mainwindow.h2
-rw-r--r--src/project/dialogs/projectsettings.cpp4
-rw-r--r--src/project/projectmanager.cpp54
-rw-r--r--src/project/projectmanager.h7
11 files changed, 301 insertions, 46 deletions
diff --git a/src/doc/documentchecker.cpp b/src/doc/documentchecker.cpp
index 8b8098c..00b12f0 100644
--- a/src/doc/documentchecker.cpp
+++ b/src/doc/documentchecker.cpp
@@ -81,6 +81,26 @@ bool DocumentChecker::hasErrorInClips()
}
root = QDir::cleanPath(root) + QDir::separator();
}
+ // Check if strorage folder for temp files exists
+ QString storageFolder;
+ QDomNodeList playlists = m_doc.elementsByTagName(QStringLiteral("playlist"));
+ for (int i = 0; i < playlists.count(); ++i) {
+ if (playlists.at(i).toElement().attribute(QStringLiteral("id")) == QStringLiteral("main bin")) {
+ QString documentid = EffectsList::property(playlists.at(i).toElement(), QStringLiteral("kdenlive:docproperties.documentid"));
+ storageFolder = EffectsList::property(playlists.at(i).toElement(), QStringLiteral("kdenlive:docproperties.storagefolder"));
+ if (!storageFolder.isEmpty() && !!storageFolder.startsWith(QStringLiteral("/"))) {
+ storageFolder.prepend(root);
+ }
+ if (!storageFolder.isEmpty() && !QFile::exists(storageFolder) && QFile::exists(m_url.adjusted(QUrl::RemoveFilename).path() + QStringLiteral("/") + documentid)) {
+ storageFolder = m_url.adjusted(QUrl::RemoveFilename).path();
+ qDebug()<<"* * *Switching storage folder: "<<storageFolder;
+ EffectsList::setProperty(playlists.at(i).toElement(), QStringLiteral("kdenlive:docproperties.storagefolder"), storageFolder + QStringLiteral("/") + documentid);
+ m_doc.documentElement().setAttribute(QStringLiteral("modified"), QStringLiteral("1"));
+ }
+ break;
+ }
+ }
+
QDomNodeList documentProducers = m_doc.elementsByTagName(QStringLiteral("producer"));
QDomElement profile = baseElement.firstChildElement(QStringLiteral("profile"));
bool hdProfile = true;
@@ -140,7 +160,18 @@ bool DocumentChecker::hasErrorInClips()
}
if (!QFile::exists(proxy)) {
// Missing clip found
- missingProxies.append(e);
+ // Check if proxy exists in current storage folder
+ bool fixed = false;
+ if (!storageFolder.isEmpty()) {
+ QDir dir(storageFolder + QStringLiteral("/proxy/"));
+ if (dir.exists(QFileInfo(proxy).fileName())) {
+ QString updatedPath = dir.absoluteFilePath(QFileInfo(proxy).fileName());
+ fixProxyClip(e.attribute(QStringLiteral("id")), EffectsList::property(e, QStringLiteral("kdenlive:proxy")), updatedPath, documentProducers);
+ fixed = true;
+ }
+ }
+ if (!fixed)
+ missingProxies.append(e);
}
QString original = EffectsList::property(e, QStringLiteral("kdenlive:originalurl"));
if (!original.startsWith(QLatin1String("/"))) {
@@ -703,6 +734,35 @@ void DocumentChecker::acceptDialog()
//QDialog::accept();
}
+void DocumentChecker::fixProxyClip(const QString &id, const QString oldUrl, const QString newUrl, QDomNodeList producers)
+{
+ QDomElement e, property;
+ QDomNodeList properties;
+ for (int i = 0; i < producers.count(); ++i) {
+ e = producers.item(i).toElement();
+ QString sourceId = e.attribute(QStringLiteral("id"));
+ QString parentId = sourceId.section('_', 0, 0);
+ if (parentId.startsWith(QLatin1String("slowmotion"))) {
+ parentId = parentId.section(':', 1, 1);
+ }
+ if (parentId == id) {
+ // Fix clip
+ QString resource = EffectsList::property(e, QStringLiteral("resource"));
+ // TODO: Slowmmotion clips
+ if (resource.contains(QRegExp("\\?[0-9]+\\.[0-9]+(&amp;strobe=[0-9]+)?$"))) {
+ //fixedResource.append('?' + resource.section('?', -1));
+ }
+ if (resource == oldUrl) {
+ EffectsList::setProperty(e, QStringLiteral("resource"), newUrl);
+ }
+ if (sourceId == id) {
+ // Only set originalurl on master producer
+ EffectsList::setProperty(e, QStringLiteral("kdenlive:proxy"), newUrl);
+ }
+ }
+ }
+}
+
void DocumentChecker::fixSourceClipItem(QTreeWidgetItem *child, QDomNodeList producers)
{
QDomElement e, property;
diff --git a/src/doc/documentchecker.h b/src/doc/documentchecker.h
index f27449e..5c09739 100644
--- a/src/doc/documentchecker.h
+++ b/src/doc/documentchecker.h
@@ -78,6 +78,7 @@ private:
void fixClipItem(QTreeWidgetItem *child, QDomNodeList producers, QDomNodeList trans);
void fixSourceClipItem(QTreeWidgetItem *child, QDomNodeList producers);
+ void fixProxyClip(const QString &id, const QString oldUrl, const QString newUrl, QDomNodeList producers);
};
diff --git a/src/doc/kdenlivedoc.cpp b/src/doc/kdenlivedoc.cpp
index 5ad59bb..b2d825d 100644
--- a/src/doc/kdenlivedoc.cpp
+++ b/src/doc/kdenlivedoc.cpp
@@ -138,7 +138,6 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, const QString &projectFolder, QUndoGro
m_documentProperties[QStringLiteral("proxyminsize")] = QString::number(KdenliveSettings::proxyminsize());
m_documentProperties[QStringLiteral("generateimageproxy")] = QString::number((int) KdenliveSettings::generateimageproxy());
m_documentProperties[QStringLiteral("proxyimageminsize")] = QString::number(KdenliveSettings::proxyimageminsize());
- m_documentProperties[QStringLiteral("documentid")] = QString::number(QDateTime::currentMSecsSinceEpoch());
// Load properties
QMapIterator<QString, QString> i(properties);
@@ -739,7 +738,7 @@ void KdenliveDoc::setProjectFolder(QUrl url)
dir.mkpath(dir.absolutePath());
}
dir.mkdir(QStringLiteral("titles"));
- if (KMessageBox::questionYesNo(QApplication::activeWindow(), i18n("You have changed the project folder. Do you want to copy the cached data from %1 to the new folder %2?", m_projectFolder, url.path())) == KMessageBox::Yes) moveProjectData(url);
+ /*if (KMessageBox::questionYesNo(QApplication::activeWindow(), i18n("You have changed the project folder. Do you want to copy the cached data from %1 to the new folder %2?", m_projectFolder, url.path())) == KMessageBox::Yes) moveProjectData(url);*/
m_projectFolder = url.path();
updateProjectFolderPlacesEntry();
@@ -754,31 +753,31 @@ void KdenliveDoc::moveProjectData(const QUrl &url)
if (clip->clipType() == Text) {
// the image for title clip must be moved
QUrl oldUrl = clip->clipUrl();
- QUrl newUrl = QUrl::fromLocalFile(url.toLocalFile() + QDir::separator() + "titles/" + oldUrl.fileName());
- KIO::Job *job = KIO::copy(oldUrl, newUrl);
- if (job->exec()) clip->setProperty(QStringLiteral("resource"), newUrl.path());
- }
- /*
- QString hash = clip->getClipHash();
- QUrl oldVideoThumbUrl = QUrl::fromLocalFile(m_projectFolder.path() + QDir::separator() + "thumbs/" + hash + ".png");
- if (QFile::exists(oldVideoThumbUrl.path())) {
- cacheUrls << oldVideoThumbUrl;
+ if (!oldUrl.isEmpty()) {
+ QUrl newUrl = QUrl::fromLocalFile(url.toLocalFile() + QStringLiteral("/titles/") + oldUrl.fileName());
+ KIO::Job *job = KIO::copy(oldUrl, newUrl);
+ if (job->exec()) clip->setProperty(QStringLiteral("resource"), newUrl.path());
+ }
+ continue;
}
- QUrl oldAudioThumbUrl = QUrl::fromLocalFile(m_projectFolder.path() + QDir::separator() + "thumbs/" + hash + ".thumb");
- if (QFile::exists(oldAudioThumbUrl.path())) {
- cacheUrls << oldAudioThumbUrl;
+ QString proxy = clip->property(QStringLiteral("kdenlive:proxy"));
+ if (proxy.length() > 2 && QFile::exists(proxy)) {
+ QUrl pUrl = QUrl::fromLocalFile(proxy);
+ if (!cacheUrls.contains(pUrl)) {
+ cacheUrls << pUrl;
+ }
}
- QUrl oldVideoProxyUrl = QUrl::fromLocalFile(m_projectFolder.path() + QDir::separator() + "proxy/" + hash + '.' + KdenliveSettings::proxyextension());
- if (QFile::exists(oldVideoProxyUrl.path())) {
- cacheUrls << oldVideoProxyUrl;
+ }
+ if (!cacheUrls.isEmpty()) {
+ QDir proxyDir(url.path() + "/proxy/");
+ if (proxyDir.mkpath(QStringLiteral("."))) {
+ KIO::CopyJob *job = KIO::move(cacheUrls, QUrl::fromLocalFile(proxyDir.absolutePath()));
+ KJobWidgets::setWindow(job, QApplication::activeWindow());
+ if (job->exec() > 0) {
+ KMessageBox::sorry(QApplication::activeWindow(), i18n("Moving proxy clips failed: %1", job->errorText()));
+ }
}
- */
}
- /*if (!cacheUrls.isEmpty()) {
- KIO::Job *job = KIO::copy(cacheUrls, QUrl::fromLocalFile(url.path() + QDir::separator() + "thumbs/"));
- KJobWidgets::setWindow(job, QApplication::activeWindow());
- job->exec();
- }*/
}
const QString &KdenliveDoc::profilePath() const
@@ -1382,7 +1381,7 @@ QMap <QString, QString> KdenliveDoc::documentProperties()
{
m_documentProperties.insert(QStringLiteral("version"), QString::number(DOCUMENTVERSION));
m_documentProperties.insert(QStringLiteral("kdenliveversion"), QStringLiteral(KDENLIVE_VERSION));
- m_documentProperties.insert(QStringLiteral("storagefolder"), m_projectFolder);
+ m_documentProperties.insert(QStringLiteral("storagefolder"), m_projectFolder + QStringLiteral("/") + m_documentProperties.value(QStringLiteral("documentid")));
m_documentProperties.insert(QStringLiteral("profile"), profilePath());
m_documentProperties.insert(QStringLiteral("position"), QString::number(m_render->seekPosition().frames(m_render->fps())));
return m_documentProperties;
@@ -1391,6 +1390,11 @@ QMap <QString, QString> KdenliveDoc::documentProperties()
void KdenliveDoc::loadDocumentProperties()
{
QDomNodeList list = m_document.elementsByTagName(QStringLiteral("playlist"));
+ QDomElement baseElement = m_document.documentElement();
+ QString root = baseElement.attribute(QStringLiteral("root"));
+ if (!root.isEmpty()) {
+ root = QDir::cleanPath(root) + QDir::separator();
+ }
if (!list.isEmpty()) {
QDomElement pl = list.at(0).toElement();
if (pl.isNull()) return;
@@ -1402,7 +1406,16 @@ void KdenliveDoc::loadDocumentProperties()
name = e.attribute(QStringLiteral("name"));
if (name.startsWith(QLatin1String("kdenlive:docproperties."))) {
name = name.section(QStringLiteral("."), 1);
- m_documentProperties.insert(name, e.firstChild().nodeValue());
+ if (name == QStringLiteral("storagefolder")) {
+ // Make sure we have an absolute path
+ QString value = e.firstChild().nodeValue();
+ if (!value.startsWith(QStringLiteral("/"))) {
+ value.prepend(root);
+ }
+ m_documentProperties.insert(name, value);
+ } else {
+ m_documentProperties.insert(name, e.firstChild().nodeValue());
+ }
} else if (name.startsWith(QLatin1String("kdenlive:docmetadata."))) {
name = name.section(QStringLiteral("."), 1);
m_documentMetadata.insert(name, e.firstChild().nodeValue());
@@ -1411,7 +1424,9 @@ void KdenliveDoc::loadDocumentProperties()
}
QString path = m_documentProperties.value(QStringLiteral("storagefolder"));
if (!path.isEmpty()) {
- m_projectFolder = path;
+ QDir dir(path);
+ dir.cdUp();
+ m_projectFolder = dir.absolutePath();
}
QString profile = m_documentProperties.value(QStringLiteral("profile"));
diff --git a/src/doc/kdenlivedoc.h b/src/doc/kdenlivedoc.h
index bde4065..8210332 100644
--- a/src/doc/kdenlivedoc.h
+++ b/src/doc/kdenlivedoc.h
@@ -173,6 +173,8 @@ public:
QStringList getProxyHashList();
/** @brief Returns true if advanced compositing is available */
static int compositingMode();
+ /** @brief Move project data files to new url */
+ void moveProjectData(const QUrl &url);
private:
QUrl m_url;
@@ -202,7 +204,6 @@ private:
QMap <QString, QString> m_documentMetadata;
QString searchFileRecursively(const QDir &dir, const QString &matchSize, const QString &matchHash) const;
- void moveProjectData(const QUrl &url);
/** @brief Creates a new project. */
QDomDocument createEmptyDocument(int videotracks, int audiotracks);
diff --git a/src/icons.qrc b/src/icons.qrc
index e0c69f6..e04c4b6 100644
--- a/src/icons.qrc
+++ b/src/icons.qrc
@@ -26,6 +26,7 @@
<file alias="linear.svg">../data/pics/breeze-light/lt_linear.svg</file>
<file alias="discrete.svg">../data/pics/breeze-light/lt_discrete.svg</file>
<file alias="smooth.svg">../data/pics/breeze-light/lt_smooth.svg</file>
+ <file alias="project-defaults.svg">../data/pics/breeze-light/lt_project-defaults.svg</file>
<file alias="kdenlive.png">../data/icons/48-apps-kdenlive.png</file>
</qresource>
</RCC>
diff --git a/src/library/librarywidget.cpp b/src/library/librarywidget.cpp
index 392e8b1..ed27d58 100644
--- a/src/library/librarywidget.cpp
+++ b/src/library/librarywidget.cpp
@@ -408,7 +408,7 @@ void LibraryWidget::slotMoveData(QList <QUrl> urls, QString dest)
if (!url.path().startsWith(m_directory.absolutePath())) {
// Dropped an external file, attempt to copy it to library
KIO::FileCopyJob *copyJob = KIO::file_copy(url, QUrl::fromLocalFile(dir.absoluteFilePath(url.fileName())));
- connect(copyJob, SIGNAL(finished(KJob *)), this, SLOT(slotDownloadFinished(KJob *)));
+ connect(copyJob, SIGNAL(result(KJob *)), this, SLOT(slotDownloadFinished(KJob *)));
connect(copyJob, SIGNAL(percent(KJob *, unsigned long)), this, SLOT(slotDownloadProgress(KJob *, unsigned long)));
} else {
// Internal drag/drop
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 54738bc..db31b1f 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -252,13 +252,17 @@ MainWindow::MainWindow(const QString &MltPath, const QUrl &Url, const QString &
setDockOptions(dockOptions() | QMainWindow::GroupedDragging);
#endif
setTabPosition(Qt::AllDockWidgetAreas, (QTabWidget::TabPosition) KdenliveSettings::tabposition());
- m_timelineToolBar = toolBar("timelineToolBar"); //KToolBar("timelineToolBar", this);
+ m_timelineToolBar = toolBar(QStringLiteral("timelineToolBar"));
m_timelineToolBarContainer = new QWidget(this);
QVBoxLayout *ctnLay = new QVBoxLayout;
ctnLay->setSpacing(0);
ctnLay->setContentsMargins(0, 0, 0, 0);
m_timelineToolBarContainer->setLayout(ctnLay);
ctnLay->addWidget(m_timelineToolBar);
+ KSharedConfigPtr config = KSharedConfig::openConfig();
+ KConfigGroup mainConfig(config, QStringLiteral("MainWindow"));
+ KConfigGroup tbGroup(&mainConfig, QStringLiteral("Toolbar timelineToolBar"));
+ m_timelineToolBar->applySettings(tbGroup);
QFrame *fr = new QFrame(this);
fr->setFrameShape(QFrame::HLine);
fr->setMaximumHeight(1);
@@ -561,7 +565,7 @@ MainWindow::MainWindow(const QString &MltPath, const QUrl &Url, const QString &
m_timelineToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
// TODO: let user select timeline toolbar toolbutton style
- //connect(toolBar(), &QToolBar::toolButtonStyleChanged, m_timelineToolBar, &QToolBar::setToolButtonStyle);
+ //connect(toolBar(), &QToolBar::iconSizeChanged, m_timelineToolBar, &QToolBar::setToolButtonStyle);
m_timelineToolBar->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_timelineToolBar, &QWidget::customContextMenuRequested, this, &MainWindow::showTimelineToolbarMenu);
@@ -1642,19 +1646,9 @@ void MainWindow::slotEditProjectSettings()
if (w->exec() == QDialog::Accepted) {
QString profile = w->selectedProfile();
- project->setProjectFolder(w->selectedFolder());
+ //project->setProjectFolder(w->selectedFolder());
pCore->projectManager()->currentTimeline()->updatePreviewSettings(w->selectedPreview());
bool modified = false;
- if (w->storageFolder() != project->projectFolder()) {
- if (w->storageFolder().isEmpty() && project->projectFolder() == QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) {
- // Ok, we continue to use system folders
- } else {
- // Project folder changed:
- if (KMessageBox::warningContinueCancel(this, i18n("This will move all temporary files from <b>%1</b> to <b>%2</b>", project->projectFolder(), w->storageFolder().isEmpty() ? QStandardPaths::writableLocation(QStandardPaths::CacheLocation) : w->storageFolder())) == KMessageBox::Continue) {
- // Proceeed with move
- }
- }
- }
if (m_recMonitor) {
m_recMonitor->slotUpdateCaptureFolder(project->projectFolder() + QDir::separator());
}
@@ -1705,6 +1699,40 @@ void MainWindow::slotEditProjectSettings()
if (w->metadata() != project->metadata()) {
project->setMetadata(w->metadata());
}
+ QString newProjectFolder = w->storageFolder();
+ if (newProjectFolder.isEmpty()) {
+ newProjectFolder = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
+ }
+ if (newProjectFolder != project->projectFolder()) {
+ KMessageBox::ButtonCode answer;
+ // Project folder changed:
+ if (project->isModified()) {
+ answer = KMessageBox::warningContinueCancel(this, i18n("The current project has not been saved. This will first save the project, then move all temporary files from <b>%1</b> to <b>%2</b>, and the project file will be reloaded", project->projectFolder(), newProjectFolder));
+ if (answer == KMessageBox::Continue) {
+ pCore->projectManager()->saveFile();
+ }
+ } else {
+ answer = KMessageBox::warningContinueCancel(this, i18n("This will move all temporary files from <b>%1</b> to <b>%2</b>, the project file will then be reloaded", project->projectFolder(), newProjectFolder));
+ }
+ if (answer == KMessageBox::Continue) {
+ // Proceeed with move
+ QString documentId = QDir::cleanPath(project->getDocumentProperty(QStringLiteral("documentid")));
+ bool ok;
+ documentId.toLong(&ok);
+ if (!ok || documentId.isEmpty()) {
+ KMessageBox::sorry(this, i18n("Cannot perform operation, invalid document id: %1", documentId));
+ } else {
+ QDir newDir(newProjectFolder);
+ QDir oldDir(project->projectFolder());
+ if (newDir.exists(documentId)) {
+ KMessageBox::sorry(this, i18n("Cannot perform operation, target directory already exists: %1", newDir.absoluteFilePath(documentId)));
+ } else {
+ // Proceed with the move
+ pCore->projectManager()->moveDataFolder(oldDir.absoluteFilePath(documentId), newDir.absolutePath());
+ }
+ }
+ }
+ }
if (modified) project->setModified();
}
delete w;
@@ -3822,7 +3850,97 @@ void MainWindow::showTimelineToolbarMenu(const QPoint &pos)
{
QMenu menu;
menu.addAction(actionCollection()->action(KStandardAction::name(KStandardAction::ConfigureToolbars)));
+ QMenu *contextSize = new QMenu(i18n("Icon Size"));
+ menu.addMenu(contextSize);
+ QActionGroup *sizeGroup = new QActionGroup(contextSize);
+ int currentSize = m_timelineToolBar->iconSize().width();
+ QAction *a = new QAction(i18nc("@item:inmenu Icon size", "Default"), contextSize);
+ a->setData(m_timelineToolBar->iconSizeDefault());
+ a->setCheckable(true);
+ if (m_timelineToolBar->iconSizeDefault() == currentSize) {
+ a->setChecked(true);
+ }
+ a->setActionGroup(sizeGroup);
+ contextSize->addAction(a);
+ KIconTheme *theme = KIconLoader::global()->theme();
+ QList<int> avSizes;
+ if (theme) {
+ avSizes = theme->querySizes(KIconLoader::Toolbar);
+ }
+
+ qSort(avSizes);
+
+ if (avSizes.count() < 10) {
+ // Fixed or threshold type icons
+ Q_FOREACH (int it, avSizes) {
+ QString text;
+ if (it < 19) {
+ text = i18n("Small (%1x%2)", it, it);
+ } else if (it < 25) {
+ text = i18n("Medium (%1x%2)", it, it);
+ } else if (it < 35) {
+ text = i18n("Large (%1x%2)", it, it);
+ } else {
+ text = i18n("Huge (%1x%2)", it, it);
+ }
+
+ // save the size in the contextIconSizes map
+ QAction *a = new QAction(text, contextSize);
+ a->setData(it);
+ a->setCheckable(true);
+ a->setActionGroup(sizeGroup);
+ if (it == currentSize) {
+ a->setChecked(true);
+ }
+ contextSize->addAction(a);
+ }
+ } else {
+ // Scalable icons.
+ const int progression[] = { 16, 22, 32, 48, 64, 96, 128, 192, 256 };
+
+ for (uint i = 0; i < 9; i++) {
+ Q_FOREACH (int it, avSizes) {
+ if (it >= progression[ i ]) {
+ QString text;
+ if (it < 19) {
+ text = i18n("Small (%1x%2)", it, it);
+ } else if (it < 25) {
+ text = i18n("Medium (%1x%2)", it, it);
+ } else if (it < 35) {
+ text = i18n("Large (%1x%2)", it, it);
+ } else {
+ text = i18n("Huge (%1x%2)", it, it);
+ }
+
+ // save the size in the contextIconSizes map
+ QAction *a = new QAction(text, contextSize);
+ a->setData(it);
+ a->setCheckable(true);
+ a->setActionGroup(sizeGroup);
+ if (it == currentSize) {
+ a->setChecked(true);
+ }
+ contextSize->addAction(a);
+ break;
+ }
+ }
+ }
+ }
+ connect(contextSize, &QMenu::triggered, this, &MainWindow::setTimelineToolbarIconSize);
menu.exec(m_timelineToolBar->mapToGlobal(pos));
+ contextSize->deleteLater();
+}
+
+void MainWindow::setTimelineToolbarIconSize(QAction *a)
+{
+ if (!a)
+ return;
+ int size = a->data().toInt();
+ m_timelineToolBar->setIconDimensions(size);
+ KSharedConfigPtr config = KSharedConfig::openConfig();
+ KConfigGroup mainConfig(config, QStringLiteral("MainWindow"));
+ KConfigGroup tbGroup(&mainConfig, QStringLiteral("Toolbar timelineToolBar"));
+ m_timelineToolBar->saveSettings(tbGroup);
}
void MainWindow::slotManageCache()
diff --git a/src/mainwindow.h b/src/mainwindow.h
index fa89edb..1fea110 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -476,6 +476,8 @@ private slots:
/** @brief Cycle through the different timeline trim modes. */
void slotSwitchTrimMode();
void setTrimMode(const QString mode);
+ /** @brief Set timeline toolbar icon size. */
+ void setTimelineToolbarIconSize(QAction *a);
signals:
Q_SCRIPTABLE void abortRenderJob(const QString &url);
diff --git a/src/project/dialogs/projectsettings.cpp b/src/project/dialogs/projectsettings.cpp
index 30fac17..f0c6721 100644
--- a/src/project/dialogs/projectsettings.cpp
+++ b/src/project/dialogs/projectsettings.cpp
@@ -96,7 +96,9 @@ ProjectSettings::ProjectSettings(KdenliveDoc *doc, QMap <QString, QString> metad
QString storageFolder = doc->getDocumentProperty(QStringLiteral("storagefolder"));
if (!storageFolder.isEmpty()) {
custom_folder->setChecked(true);
- project_folder->setUrl(QUrl::fromLocalFile(storageFolder));
+ QDir dir(storageFolder);
+ dir.cdUp();
+ project_folder->setUrl(QUrl::fromLocalFile(dir.absolutePath()));
} else {
xdg_folder->setChecked(true);
project_folder->setUrl(QUrl::fromLocalFile(KdenliveSettings::defaultprojectfolder()));
diff --git a/src/project/projectmanager.cpp b/src/project/projectmanager.cpp
index f112874..3fffbf9 100644
--- a/src/project/projectmanager.cpp
+++ b/src/project/projectmanager.cpp
@@ -29,13 +29,14 @@ the Free Software Foundation, either version 3 of the License, or
#include <KActionCollection>
#include <KRecentDirs>
-#include <QAction>
+#include <KJob>
#include <KMessageBox>
#include <klocalizedstring.h>
#include <QProgressDialog>
#include <QCryptographicHash>
#include <QFileDialog>
+#include <QAction>
#include <QDebug>
#include <QMimeDatabase>
#include <QMimeType>
@@ -136,13 +137,15 @@ void ProjectManager::newFile(bool showProjectSettings, bool force)
QMap <QString, QString> documentMetadata;
QPoint projectTracks(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks());
pCore->monitorManager()->resetDisplay();
+ QString documentId = QString::number(QDateTime::currentMSecsSinceEpoch());
+ documentProperties.insert(QStringLiteral("documentid"), documentId);
if (!showProjectSettings) {
if (!closeCurrentDocument()) {
return;
}
if (KdenliveSettings::customprojectfolder()) {
projectFolder = KdenliveSettings::defaultprojectfolder();
- documentProperties.insert(QStringLiteral("storagefolder"), projectFolder);
+ documentProperties.insert(QStringLiteral("storagefolder"), projectFolder + QStringLiteral("/") + documentId);
}
} else {
QPointer<ProjectSettings> w = new ProjectSettings(NULL, QMap <QString, QString> (), QStringList(), projectTracks.x(), projectTracks.y(), KdenliveSettings::defaultprojectfolder(), false, true, pCore->window());
@@ -177,7 +180,7 @@ void ProjectManager::newFile(bool showProjectSettings, bool force)
}
documentProperties.insert(QStringLiteral("proxyimageminsize"), QString::number(w->proxyImageMinSize()));
if (!projectFolder.isEmpty()) {
- documentProperties.insert(QStringLiteral("storagefolder"), projectFolder);
+ documentProperties.insert(QStringLiteral("storagefolder"), projectFolder + QStringLiteral("/") + documentId);
}
documentMetadata = w->metadata();
delete w;
@@ -274,6 +277,13 @@ bool ProjectManager::saveFileAs(const QString &outputFileName)
prepareSave();
QString saveFolder = QFileInfo(outputFileName).absolutePath();
QString scene = projectSceneList(saveFolder);
+ if (!m_replacementPattern.isEmpty()) {
+ QMapIterator<QString, QString> i(m_replacementPattern);
+ while (i.hasNext()) {
+ i.next();
+ scene.replace(i.key(), i.value());
+ }
+ }
if (m_project->saveSceneList(outputFileName, scene) == false) {
return false;
}
@@ -785,3 +795,41 @@ void ProjectManager::saveZone(QStringList info, QDir dir)
{
pCore->bin()->saveZone(info, dir);
}
+
+void ProjectManager::moveDataFolder(const QString &src, const QString &dest)
+{
+ // Move tmp folder (thumbnails, timeline preview)
+ KIO::CopyJob *copyJob = KIO::move(QUrl::fromLocalFile(src),QUrl::fromLocalFile(dest));
+ connect(copyJob, SIGNAL(result(KJob *)), this, SLOT(slotMoveFinished(KJob *)));
+ connect(copyJob, SIGNAL(percent(KJob *, unsigned long)), this, SLOT(slotMoveProgress(KJob *, unsigned long)));
+ // Move proxies
+ m_project->moveProjectData(QUrl::fromLocalFile(dest));
+}
+
+void ProjectManager::slotMoveProgress(KJob *, unsigned long progress)
+{
+ pCore->window()->slotGotProgressInfo(i18n("Moving project folder"), progress, ProcessingJobMessage);
+}
+
+void ProjectManager::slotMoveFinished(KJob *job)
+{
+ if (job->error() == 0) {
+ pCore->window()->slotGotProgressInfo(QString(), 100, InformationMessage);
+ KIO::CopyJob *copyJob = static_cast<KIO::CopyJob *> (job);
+ QString newFolder = copyJob->destUrl().path();
+ // Check if project folder is inside document folder, in which case, paths will be relative
+ QDir projectDir(m_project->url().toString(QUrl::RemoveFilename | QUrl::RemoveScheme));
+ QDir srcDir(m_project->projectFolder());
+ if (srcDir.absolutePath().startsWith(projectDir.absolutePath())) {
+ m_replacementPattern.insert(QStringLiteral(">proxy/"), QStringLiteral(">") + newFolder + QStringLiteral("/proxy/"));
+ } else {
+ m_replacementPattern.insert(m_project->projectFolder() + QStringLiteral("/proxy/"), newFolder + QStringLiteral("/proxy/"));
+ }
+ m_project->setProjectFolder(QUrl::fromLocalFile(newFolder));
+ saveFile();
+ m_replacementPattern.clear();
+ slotRevert();
+ } else {
+ KMessageBox::sorry(pCore->window(), i18n("Error moving project folder: %1", job->errorText()));
+ }
+}
diff --git a/src/project/projectmanager.h b/src/project/projectmanager.h
index 93d9c4d..c6ed651 100644
--- a/src/project/projectmanager.h
+++ b/src/project/projectmanager.h
@@ -28,6 +28,7 @@ class QAction;
class QUrl;
class QProgressDialog;
class KAutoSaveFile;
+class KJob;
/**
* @class ProjectManager
@@ -63,6 +64,8 @@ public:
/** @brief returns a default hd profile depending on timezone*/
static QString getDefaultProjectFormat();
void saveZone(QStringList info, QDir dir);
+ /** @brief Move the current project's data folder */
+ void moveDataFolder(const QString &src, const QString &dest);
public slots:
void newFile(bool showProjectSettings = true, bool force = false);
@@ -122,6 +125,9 @@ private slots:
void slotOpenBackup(const QUrl &url = QUrl());
/** @brief Start autosaving the document. */
void slotAutoSave();
+ /** @brief Report progress of folder move operation. */
+ void slotMoveProgress(KJob *, unsigned long progress);
+ void slotMoveFinished(KJob *job);
signals:
void docOpened(KdenliveDoc *document);
@@ -141,6 +147,7 @@ private:
QTimer m_autoSaveTimer;
QUrl m_startUrl;
QString m_loadClipsOnOpen;
+ QMap <QString, QString> m_replacementPattern;
QAction *m_fileRevert;
KRecentFilesAction *m_recentFilesAction;