[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdenlive] src: * timeline toolbar: add context menu to set icon size
From:       Jean-Baptiste Mardelle <jb () kdenlive ! org>
Date:       2016-10-30 20:16:59
Message-ID: E1c0wXL-0002Aw-Jz () code ! kde ! org
[Download RAW message or body]

Git commit c5f07dfc6a9f1268b1c0b3e00dd75742a5bbd12f by Jean-Baptiste Mardelle.
Committed on 30/10/2016 at 20:11.
Pushed by mardelle into branch 'master'.

* timeline toolbar: add context menu to set icon size
* project folder: allow moving
* improve project portability

M  +61   -1    src/doc/documentchecker.cpp
M  +1    -0    src/doc/documentchecker.h
M  +41   -26   src/doc/kdenlivedoc.cpp
M  +2    -1    src/doc/kdenlivedoc.h
M  +1    -0    src/icons.qrc
M  +1    -1    src/library/librarywidget.cpp
M  +131  -13   src/mainwindow.cpp
M  +2    -0    src/mainwindow.h
M  +3    -1    src/project/dialogs/projectsettings.cpp
M  +51   -3    src/project/projectmanager.cpp
M  +7    -0    src/project/projectmanager.h

http://commits.kde.org/kdenlive/c5f07dfc6a9f1268b1c0b3e00dd75742a5bbd12f

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;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic