Commit c5f07dfc authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

* timeline toolbar: add context menu to set icon size

* project folder: allow moving
* improve project portability
parent fd09b024
......@@ -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;
......
......@@ -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);
};
......
......@@ -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"));
......
......@@ -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);
......
......@@ -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>
......@@ -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
......
......@@ -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()
......
......@@ -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);
......
......@@ -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()));
......
......@@ -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()));
}
}
......@@ -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;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment