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

* First steps towards using custom project folder to store tmp data (wip)

* First steps towards "portable" projects (using relative paths)
parent aa925129
......@@ -934,7 +934,7 @@ ProjectFolder *Bin::rootFolder()
return m_rootFolder;
}
QUrl Bin::projectFolder() const
QString Bin::projectFolder() const
{
return m_doc->projectFolder();
}
......@@ -3003,7 +3003,7 @@ void Bin::slotLoadClipMarkers(const QString &id)
}
cbox->setCurrentIndex(KdenliveSettings::default_marker_type());
//TODO KF5 how to add custom cbox to Qfiledialog
QPointer<QFileDialog> fd = new QFileDialog(this, i18n("Load Clip Markers"), m_doc->projectFolder().path());
QPointer<QFileDialog> fd = new QFileDialog(this, i18n("Load Clip Markers"), m_doc->projectFolder());
fd->setMimeTypeFilters(QStringList()<<QStringLiteral("text/plain"));
fd->setFileMode(QFileDialog::ExistingFile);
if (fd->exec() != QDialog::Accepted) return;
......@@ -3085,7 +3085,7 @@ void Bin::slotSaveClipMarkers(const QString &id)
}
cbox->setCurrentIndex(0);
//TODO KF5 how to add custom cbox to Qfiledialog
QPointer<QFileDialog> fd = new QFileDialog(this, i18n("Save Clip Markers"), m_doc->projectFolder().path());
QPointer<QFileDialog> fd = new QFileDialog(this, i18n("Save Clip Markers"), m_doc->projectFolder());
fd->setMimeTypeFilters(QStringList() << QStringLiteral("text/plain"));
fd->setFileMode(QFileDialog::AnyFile);
fd->setAcceptMode(QFileDialog::AcceptSave);
......@@ -3160,8 +3160,9 @@ void Bin::slotGetCurrentProjectImage(bool request)
void Bin::showTitleWidget(ProjectClip *clip)
{
QString path = clip->getProducerProperty(QStringLiteral("resource"));
QString titlepath = m_doc->projectFolder().path() + QDir::separator() + "titles/";
TitleWidget dia_ui(QUrl(), m_doc->timecode(), titlepath, pCore->monitorManager()->projectMonitor()->render, pCore->window());
QDir titleFolder(m_doc->projectFolder() + QStringLiteral("/titles"));
titleFolder.mkpath(QStringLiteral("."));
TitleWidget dia_ui(QUrl(), m_doc->timecode(), titleFolder.absolutePath(), pCore->monitorManager()->projectMonitor()->render, pCore->window());
connect(&dia_ui, SIGNAL(requestBackgroundFrame(bool)), pCore->monitorManager()->projectMonitor(), SLOT(slotGetCurrentImage(bool)));
QDomDocument doc;
QString xmldata = clip->getProducerProperty(QStringLiteral("xmldata"));
......
......@@ -496,7 +496,7 @@ public:
/** @brief An effect setting was changed, update stack if displayed. */
void updateMasterEffect(ClipController *ctl);
/** @brief Returns current project's folder for storing items. */
QUrl projectFolder() const;
QString projectFolder() const;
/** @brief Display a message about an operation in status bar. */
void emitMessage(const QString &, int, MessageType);
void rebuildMenu();
......
......@@ -263,10 +263,9 @@ void ClipCreationDialog::createSlideshowClip(KdenliveDoc *doc, QStringList group
void ClipCreationDialog::createTitleClip(KdenliveDoc *doc, QStringList groupInfo, QString templatePath, Bin *bin)
{
// Make sure the titles folder exists
QDir dir(doc->projectFolder().path());
dir.mkdir(QStringLiteral("titles"));
dir.cd(QStringLiteral("titles"));
QPointer<TitleWidget> dia_ui = new TitleWidget(QUrl::fromLocalFile(templatePath), doc->timecode(), dir.path(), doc->renderer(), bin);
QDir dir(doc->projectFolder() + QStringLiteral("/titles"));
dir.mkpath(QStringLiteral("."));
QPointer<TitleWidget> dia_ui = new TitleWidget(QUrl::fromLocalFile(templatePath), doc->timecode(), dir.absolutePath(), doc->renderer(), bin);
QObject::connect(dia_ui, SIGNAL(requestBackgroundFrame(bool)), bin, SLOT(slotGetCurrentProjectImage(bool)));
if (dia_ui->exec() == QDialog::Accepted) {
// Ready, create clip xml
......@@ -298,7 +297,7 @@ void ClipCreationDialog::createTitleClip(KdenliveDoc *doc, QStringList groupInfo
void ClipCreationDialog::createTitleTemplateClip(KdenliveDoc *doc, QStringList groupInfo, Bin *bin)
{
QPointer<TitleTemplateDialog> dia = new TitleTemplateDialog(doc->projectFolder().path(), QApplication::activeWindow());
QPointer<TitleTemplateDialog> dia = new TitleTemplateDialog(doc->projectFolder(), QApplication::activeWindow());
if (dia->exec() == QDialog::Accepted) {
QString textTemplate = dia->selectedTemplate();
......@@ -456,7 +455,7 @@ void ClipCreationDialog::createClipsCommand(KdenliveDoc *doc, const QList<QUrl>
for (int i = 0; i < items.count() ; ++i) {
QDomElement content = items.item(i).toElement();
if (content.hasAttribute(QStringLiteral("base64"))) {
QString titlesFolder = doc->projectFolder().path() + QDir::separator() + "titles/";
QString titlesFolder = doc->projectFolder()+ QStringLiteral("/titles/");
QString path = TitleDocument::extractBase64Image(titlesFolder, content.attribute(QStringLiteral("base64")));
if (!path.isEmpty()) {
content.setAttribute(QStringLiteral("url"), path);
......
......@@ -83,6 +83,8 @@ KdenliveSettingsDialog::KdenliveSettingsDialog(const QMap<QString, QString>& map
m_page8->setIcon(KoIconUtils::themedIcon(QStringLiteral("project-defaults")));
connect(m_configProject.kcfg_generateproxy, SIGNAL(toggled(bool)), m_configProject.kcfg_proxyminsize, SLOT(setEnabled(bool)));
m_configProject.kcfg_proxyminsize->setEnabled(KdenliveSettings::generateproxy());
m_configProject.projecturl->setMode(KFile::Directory);
m_configProject.projecturl->setUrl(QUrl::fromLocalFile(KdenliveSettings::defaultprojectfolder()));
connect(m_configProject.kcfg_generateimageproxy, SIGNAL(toggled(bool)), m_configProject.kcfg_proxyimageminsize, SLOT(setEnabled(bool)));
m_configProject.kcfg_proxyimageminsize->setEnabled(KdenliveSettings::generateimageproxy());
......@@ -103,8 +105,6 @@ KdenliveSettingsDialog::KdenliveSettingsDialog(const QMap<QString, QString>& map
m_configEnv.kcfg_mltthreads->setMaximum(maxThreads > 2 ? maxThreads : 8);
m_configEnv.tmppathurl->setMode(KFile::Directory);
m_configEnv.tmppathurl->lineEdit()->setObjectName(QStringLiteral("kcfg_currenttmpfolder"));
m_configEnv.projecturl->setMode(KFile::Directory);
m_configEnv.projecturl->lineEdit()->setObjectName(QStringLiteral("kcfg_defaultprojectfolder"));
m_configEnv.capturefolderurl->setMode(KFile::Directory);
m_configEnv.capturefolderurl->lineEdit()->setObjectName(QStringLiteral("kcfg_capturefolder"));
m_configEnv.capturefolderurl->setEnabled(!KdenliveSettings::capturetoprojectfolder());
......@@ -707,6 +707,10 @@ void KdenliveSettingsDialog::updateSettings()
updateCapturePath = true;
}
if (m_configProject.projecturl->url().path() != KdenliveSettings::defaultprojectfolder()) {
KdenliveSettings::setDefaultprojectfolder(m_configProject.projecturl->url().path());
}
if (m_configEnv.capturefolderurl->url().path() != KdenliveSettings::capturefolder()) {
KdenliveSettings::setCapturefolder(m_configEnv.capturefolderurl->url().path());
updateCapturePath = true;
......
......@@ -68,10 +68,21 @@ bool DocumentChecker::hasErrorInClips()
QDomElement e;
QString resource;
int max;
QString root = m_doc.documentElement().attribute(QStringLiteral("root"));
if (!root.isEmpty()) root = QDir::cleanPath(root) + QDir::separator();
QDomElement baseElement = m_doc.documentElement();
QString root = baseElement.attribute(QStringLiteral("root"));
if (!root.isEmpty()) {
QDir dir(root);
if (!dir.exists()) {
// Looks like project was moved, try recovering root from current project url
m_rootReplacement.first = root;
root = m_url.adjusted(QUrl::RemoveFilename).path();
baseElement.setAttribute(QStringLiteral("root"), root);
m_rootReplacement.second = root;
}
root = QDir::cleanPath(root) + QDir::separator();
}
QDomNodeList documentProducers = m_doc.elementsByTagName(QStringLiteral("producer"));
QDomElement profile = m_doc.documentElement().firstChildElement(QStringLiteral("profile"));
QDomElement profile = baseElement.firstChildElement(QStringLiteral("profile"));
bool hdProfile = true;
if (!profile.isNull()) {
if (profile.attribute(QStringLiteral("width")).toInt() < 1000) {
......@@ -270,24 +281,44 @@ bool DocumentChecker::hasErrorInClips()
QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.treeWidget, QStringList() << clipType);
item->setData(0, statusRole, CLIPMISSING);
item->setData(0, clipTypeRole, type);
item->setData(0, idRole, e.attribute(QStringLiteral("id")));
item->setToolTip(0, i18n("Missing item"));
if (status == TITLE_IMAGE_ELEMENT) {
item->setIcon(0, KoIconUtils::themedIcon("dialog-warning"));
item->setToolTip(1, e.attribute("name"));
item->setText(1, e.attribute("resource"));
QString imageResource = e.attribute("resource");
item->setData(0, typeRole, status);
item->setData(0, typeOriginalResource, e.attribute("resource"));
if (!m_rootReplacement.first.isEmpty()) {
if (imageResource.startsWith(m_rootReplacement.first)) {
imageResource.replace(m_rootReplacement.first, m_rootReplacement.second);
if (QFile::exists(imageResource)) {
item->setData(0, statusRole, CLIPOK);
item->setToolTip(0, i18n("Relocated item"));
}
}
}
item->setText(1, imageResource);
} else {
item->setIcon(0, KoIconUtils::themedIcon("dialog-close"));
if (!resource.startsWith("/")) {
resource.prepend(root);
}
item->setText(1, resource);
item->setData(0, hashRole, EffectsList::property(e, QStringLiteral("kdenlive:file_hash")));
item->setData(0, sizeRole, EffectsList::property(e, QStringLiteral("kdenlive:file_size")));
if (!m_rootReplacement.first.isEmpty()) {
if (resource.startsWith(m_rootReplacement.first)) {
resource.replace(m_rootReplacement.first, m_rootReplacement.second);
if (QFile::exists(resource)) {
item->setData(0, statusRole, CLIPOK);
item->setToolTip(0, i18n("Relocated item"));
}
}
}
item->setText(1, resource);
}
item->setData(0, clipTypeRole, type);
item->setData(0, idRole, e.attribute(QStringLiteral("id")));
item->setToolTip(0, i18n("Missing item"));
}
foreach(const QString font, m_missingFonts) {
......
......@@ -64,6 +64,7 @@ private:
QDomDocument m_doc;
Ui::MissingClips_UI m_ui;
QDialog *m_dialog;
QPair <QString, QString>m_rootReplacement;
QString searchPathRecursively(const QDir &dir, const QString &fileName, ClipType type = Unknown) const;
QString searchFileRecursively(const QDir &dir, const QString &matchSize, const QString &matchHash, const QString &fileName) const;
void checkStatus();
......
......@@ -85,7 +85,7 @@ void DocUndoStack::push(QUndoCommand *cmd)
const double DOCUMENTVERSION = 0.95;
KdenliveDoc::KdenliveDoc(const QUrl &url, const QUrl &projectFolder, QUndoGroup *undoGroup, const QString &profileName, const QMap <QString, QString>& properties, const QMap <QString, QString>& metadata, const QPoint &tracks, Render *render, NotesPlugin *notes, bool *openBackup, MainWindow *parent) :
KdenliveDoc::KdenliveDoc(const QUrl &url, const QString &projectFolder, QUndoGroup *undoGroup, const QString &profileName, const QMap <QString, QString>& properties, const QMap <QString, QString>& metadata, const QPoint &tracks, Render *render, NotesPlugin *notes, bool *openBackup, MainWindow *parent) :
QObject(parent),
m_autosave(NULL),
m_url(url),
......@@ -153,7 +153,6 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, const QUrl &projectFolder, QUndoGroup
j.next();
m_documentMetadata[j.key()] = j.value();
}
if (QLocale().decimalPoint() != QLocale::system().decimalPoint()) {
setlocale(LC_NUMERIC, "");
QLocale systemLocale = QLocale::system();
......@@ -257,7 +256,6 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, const QUrl &projectFolder, QUndoGroup
}
}
}
initCacheDirs();
// Something went wrong, or a new file was requested: create a new project
if (!success) {
......@@ -267,28 +265,22 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, const QUrl &projectFolder, QUndoGroup
updateProjectProfile(false);
}
// Ask to create the project directory if it does not exist
QFileInfo checkProjectFolder(m_projectFolder.toString(QUrl::RemoveFilename | QUrl::RemoveScheme));
if (!QFile::exists(m_projectFolder.path()) && checkProjectFolder.isWritable()) {
int create = KMessageBox::questionYesNo(parent, i18n("Project directory %1 does not exist. Create it?", m_projectFolder.path()));
if (create == KMessageBox::Yes) {
QDir projectDir(m_projectFolder.path());
bool ok = projectDir.mkpath(m_projectFolder.path());
if (!ok) {
KMessageBox::sorry(parent, i18n("The directory %1, could not be created.\nPlease make sure you have the required permissions.", m_projectFolder.path()));
if (!m_projectFolder.isEmpty()) {
// Ask to create the project directory if it does not exist
QDir folder(m_projectFolder);
if (!folder.mkpath(QStringLiteral("."))) {
// Project folder is not writable
m_projectFolder = m_url.toString(QUrl::RemoveFilename | QUrl::RemoveScheme);
folder.setPath(m_projectFolder);
if (folder.exists()) {
KMessageBox::sorry(parent, i18n("The project directory %1, could not be created.\nPlease make sure you have the required permissions.\nDefaulting to system folders", m_projectFolder));
} else {
KMessageBox::information(parent, i18n("Document project folder is invalid, using system default folders"));
}
m_projectFolder.clear();
}
}
// Make sure the project folder is usable
if (m_projectFolder.isEmpty() || !QFile::exists(m_projectFolder.path())) {
KMessageBox::information(parent, i18n("Document project folder is invalid, setting it to the default one: %1", KdenliveSettings::defaultprojectfolder()));
m_projectFolder = QUrl::fromLocalFile(KdenliveSettings::defaultprojectfolder());
}
// Make sure that the necessary folders exist
QDir dir(m_projectFolder.path());
dir.mkdir(QStringLiteral("titles"));
initCacheDirs();
updateProjectFolderPlacesEntry();
}
......@@ -307,10 +299,9 @@ KdenliveDoc::~KdenliveDoc()
bool ok;
documentId.toLong(&ok);
if (ok && !documentId.isEmpty()) {
QString kdenliveCacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
QDir cacheDir(kdenliveCacheDir + "/" + documentId);
if (cacheDir.exists() && cacheDir.dirName() == documentId) {
cacheDir.removeRecursively();
QDir baseCache = getCacheDir(CacheBase, &ok);
if (baseCache.dirName() == documentId && baseCache.entryList(QDir::Files).count() == 0) {
baseCache.removeRecursively();
}
}
}
......@@ -573,7 +564,7 @@ void KdenliveDoc::slotAutoSave()
qDebug() << "ERROR; CANNOT CREATE AUTOSAVE FILE";
}
//qDebug() << "// AUTOSAVE FILE: " << m_autosave->fileName();
QDomDocument sceneList = xmlSceneList(m_render->sceneList());
QDomDocument sceneList = xmlSceneList(m_render->sceneList(m_url.adjusted(QUrl::RemoveFilename).path()));
if (sceneList.isNull()) {
//Make sure we don't save if scenelist is corrupted
KMessageBox::error(QApplication::activeWindow(), i18n("Cannot write to file %1, scene list is corrupted.", m_autosave->fileName()));
......@@ -731,23 +722,25 @@ QString KdenliveDoc::groupsXml() const
return m_clipManager->groupsXml();
}
QUrl KdenliveDoc::projectFolder() const
QString KdenliveDoc::projectFolder() const
{
//if (m_projectFolder.isEmpty()) return QUrl(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "//projects/");
if (m_projectFolder.isEmpty()) {
return QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
}
return m_projectFolder;
}
void KdenliveDoc::setProjectFolder(QUrl url)
{
if (url == m_projectFolder) return;
if (url == QUrl::fromLocalFile(m_projectFolder)) return;
setModified(true);
QDir dir(url.toLocalFile());
if (!dir.exists()) {
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.path(), url.path())) == KMessageBox::Yes) moveProjectData(url);
m_projectFolder = 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();
}
......@@ -974,7 +967,7 @@ ClipController *KdenliveDoc::getClipController(const QString &clipId)
void KdenliveDoc::slotCreateTextTemplateClip(const QString &group, const QString &groupId, QUrl path)
{
QString titlesFolder = QDir::cleanPath(projectFolder().path() + QDir::separator() + "titles/");
QString titlesFolder = QDir::cleanPath(m_projectFolder + "/titles/");
if (path.isEmpty()) {
QPointer<QFileDialog> d = new QFileDialog(QApplication::activeWindow(), i18n("Enter Template Path"), titlesFolder);
d->setMimeTypeFilters(QStringList() << QStringLiteral("application/x-kdenlivetitle"));
......@@ -1076,7 +1069,7 @@ void KdenliveDoc::updateProjectFolderPlacesEntry()
KBookmark bookmark = root.first();
QString kdenliveName = QCoreApplication::applicationName();
QUrl documentLocation = m_projectFolder;
QUrl documentLocation = QUrl::fromLocalFile(m_projectFolder);
bool exists = false;
......@@ -1389,7 +1382,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("projectfolder"), m_projectFolder.path());
m_documentProperties.insert(QStringLiteral("storagefolder"), m_projectFolder);
m_documentProperties.insert(QStringLiteral("profile"), profilePath());
m_documentProperties.insert(QStringLiteral("position"), QString::number(m_render->seekPosition().frames(m_render->fps())));
return m_documentProperties;
......@@ -1416,12 +1409,11 @@ void KdenliveDoc::loadDocumentProperties()
}
}
}
QString path = m_documentProperties.value(QStringLiteral("projectfolder"));
if (!path.startsWith('/')) {
QDir dir = QDir::home();
path = dir.absoluteFilePath(path);
QString path = m_documentProperties.value(QStringLiteral("storagefolder"));
if (!path.isEmpty()) {
m_projectFolder = path;
}
m_projectFolder = QUrl::fromLocalFile(path);
QString profile = m_documentProperties.value(QStringLiteral("profile"));
if (!profile.isEmpty())
m_profile = ProfilesDialog::getVideoProfile(profile);
......@@ -1647,9 +1639,14 @@ void KdenliveDoc::saveMltPlaylist(const QString fileName)
void KdenliveDoc::initCacheDirs()
{
bool ok = false;
QString kdenliveCacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
QString kdenliveCacheDir;
QString documentId = QDir::cleanPath(getDocumentProperty(QStringLiteral("documentid")));
documentId.toLong(&ok);
if (m_projectFolder.isEmpty()) {
kdenliveCacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
} else {
kdenliveCacheDir = m_projectFolder;
}
if (!ok || documentId.isEmpty() || kdenliveCacheDir.isEmpty()) {
return;
}
......@@ -1665,14 +1662,21 @@ void KdenliveDoc::initCacheDirs()
QDir KdenliveDoc::getCacheDir(CacheType type, bool *ok) const
{
QString kdenliveCacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
QString basePath;
QString kdenliveCacheDir;
QString documentId = QDir::cleanPath(getDocumentProperty(QStringLiteral("documentid")));
documentId.toLong(ok);
if (!*ok || documentId.isEmpty() || kdenliveCacheDir.isEmpty()) {
*ok = false;
return QDir(kdenliveCacheDir);
if (m_projectFolder.isEmpty()) {
kdenliveCacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
if (!*ok || documentId.isEmpty() || kdenliveCacheDir.isEmpty()) {
*ok = false;
return QDir(kdenliveCacheDir);
}
} else {
// Use specified folder to store all files
kdenliveCacheDir = m_projectFolder;
}
QString basePath = kdenliveCacheDir + "/" + documentId;
basePath = kdenliveCacheDir + QStringLiteral("/") + documentId;
switch (type) {
case CacheRoot:
basePath = kdenliveCacheDir;
......
......@@ -75,7 +75,7 @@ class KdenliveDoc: public QObject
Q_OBJECT
public:
KdenliveDoc(const QUrl &url, const QUrl &projectFolder, QUndoGroup *undoGroup, const QString &profileName, const QMap <QString, QString>& properties, const QMap <QString, QString>& metadata, const QPoint &tracks, Render *render, NotesPlugin *notes, bool *openBackup, MainWindow *parent = 0);
KdenliveDoc(const QUrl &url, const QString &projectFolder, QUndoGroup *undoGroup, const QString &profileName, const QMap <QString, QString>& properties, const QMap <QString, QString>& metadata, const QPoint &tracks, Render *render, NotesPlugin *notes, bool *openBackup, MainWindow *parent = 0);
~KdenliveDoc();
QDomNodeList producersList();
double fps() const;
......@@ -109,7 +109,7 @@ public:
bool isModified() const;
/** @brief Returns the project folder, used to store project files. */
QUrl projectFolder() const;
QString projectFolder() const;
void setZoom(int horizontal, int vertical);
QPoint zoom() const;
double dar() const;
......@@ -196,7 +196,7 @@ private:
bool m_modified;
/** @brief The project folder, used to store project files (titles, effects...). */
QUrl m_projectFolder;
QString m_projectFolder;
QList <int> m_undoChunks;
QMap <QString, QString> m_documentProperties;
QMap <QString, QString> m_documentMetadata;
......
......@@ -181,13 +181,6 @@ bool initEffects::parseEffectFiles(Mlt::Repository* repository, const QString &l
consumersList << consumers->get_name(i);
delete consumers;
movit = true;
// Seems like with latest changes, SDL works fine with movit
/*if (consumersList.contains(QStringLiteral("rtaudio"))) {
// enable movit GPU effects / display. Currently, Movit crashes with sdl_audio,
// So enable only when rtaudio is available
movit = true;
}
else KdenliveSettings::setGpu_accel(false);*/
}
else KdenliveSettings::setGpu_accel(false);
......
......@@ -381,7 +381,12 @@
<entry name="defaultprojectfolder" type="Path">
<label>Default folder for project files.</label>
<default>$HOME/kdenlive</default>
<default></default>
</entry>
<entry name="customprojectfolder" type="Bool">
<label>Don't use default XDG folders to store project files.</label>
<default>false</default>
</entry>
<entry name="capturetoprojectfolder" type="Bool">
......
......@@ -1573,13 +1573,9 @@ bool MainWindow::readOptions()
pCore->projectManager()->recentFilesAction()->loadEntries(KConfigGroup(config, "Recent Files"));
if (KdenliveSettings::defaultprojectfolder().isEmpty()) {
QDir dir(QDir::homePath());
if (!dir.mkdir(QStringLiteral("kdenlive"))) {
qDebug() << "/// ERROR CREATING PROJECT FOLDER: ";
} else {
dir.cd("kdenlive");
KdenliveSettings::setDefaultprojectfolder(dir.absolutePath());
}
QDir dir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
dir.mkpath(QStringLiteral("."));
KdenliveSettings::setDefaultprojectfolder(dir.absolutePath());
}
if (KdenliveSettings::trackheight() == 0) {
QFontMetrics metrics(font());
......@@ -1605,6 +1601,13 @@ bool MainWindow::readOptions()
delete w;
::exit(1);
}
} else if (!KdenliveSettings::ffmpegpath().isEmpty() && !QFile::exists(KdenliveSettings::ffmpegpath())) {
// Invalid entry for FFmpeg, check system
QPointer<Wizard> w = new Wizard(true);
if (w->exec() == QDialog::Accepted && w->isOk()) {
w->adjustSettings();
}
delete w;
}
initialGroup.writeEntry("version", version);
return firstRun;
......@@ -1632,7 +1635,7 @@ void MainWindow::slotEditProjectSettings()
KdenliveDoc *project = pCore->projectManager()->current();
QPoint p = pCore->projectManager()->currentTimeline()->getTracksCount();
QPointer<ProjectSettings> w = new ProjectSettings(project, project->metadata(), pCore->projectManager()->currentTimeline()->projectView()->extractTransitionsLumas(), p.x(), p.y(), project->projectFolder().path(), true, !project->isModified(), this);
QPointer<ProjectSettings> w = new ProjectSettings(project, project->metadata(), pCore->projectManager()->currentTimeline()->projectView()->extractTransitionsLumas(), p.x(), p.y(), project->projectFolder(), true, !project->isModified(), this);
connect(w, SIGNAL(disableProxies()), this, SLOT(slotDisableProxies()));
connect(w, SIGNAL(disablePreview()), pCore->projectManager()->currentTimeline(), SLOT(invalidateRange()));
connect(w, SIGNAL(refreshProfiles()), this, SLOT(slotRefreshProfiles()));
......@@ -1642,11 +1645,21 @@ void MainWindow::slotEditProjectSettings()
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().path() + QDir::separator());
m_recMonitor->slotUpdateCaptureFolder(project->projectFolder() + QDir::separator());
}
if (m_renderWidget) {
m_renderWidget->setDocumentPath(project->projectFolder().path() + QDir::separator());
m_renderWidget->setDocumentPath(project->projectFolder() + QDir::separator());
}
if (KdenliveSettings::videothumbnails() != w->enableVideoThumbs()) {
slotSwitchVideoThumbs();
......@@ -1716,7 +1729,7 @@ void MainWindow::slotRenderProject()
KdenliveDoc *project = pCore->projectManager()->current();
if (!m_renderWidget) {
QString projectfolder = project ? project->projectFolder().path() + QDir::separator() : KdenliveSettings::defaultprojectfolder();
QString projectfolder = project ? project->projectFolder() + QDir::separator() : KdenliveSettings::defaultprojectfolder();
MltVideoProfile profile;
if (project) {
profile = project->mltProfile();
......@@ -1728,7 +1741,7 @@ void MainWindow::slotRenderProject()
connect(m_renderWidget, SIGNAL(openDvdWizard(QString)), this, SLOT(slotDvdWizard(QString)));
m_renderWidget->setProfile(project->mltProfile());
m_renderWidget->setGuides(pCore->projectManager()->currentTimeline()->projectView()->guidesData(), project->projectDuration());
m_renderWidget->setDocumentPath(project->projectFolder().path() + QDir::separator());
m_renderWidget->setDocumentPath(project->projectFolder() + QDir::separator());
m_renderWidget->setRenderProfile(project->getRenderProperties());
}
if (m_compositeAction->currentAction())
......@@ -1932,7 +1945,7 @@ void MainWindow::connectDocument()
slotCheckRenderStatus();
m_renderWidget->setProfile(project->mltProfile());
m_renderWidget->setGuides(pCore->projectManager()->currentTimeline()->projectView()->guidesData(), project->projectDuration());
m_renderWidget->setDocumentPath(project->projectFolder().path() + QDir::separator());
m_renderWidget->setDocumentPath(project->projectFolder() + QDir::separator());
m_renderWidget->setRenderProfile(project->getRenderProperties());
}
m_zoomSlider->setValue(project->zoom().x());
......@@ -1947,7 +1960,7 @@ void MainWindow::connectDocument()
pCore->monitorManager()->setDocument(project);
trackView->updateProfile(1.0);
if (m_recMonitor) {
m_recMonitor->slotUpdateCaptureFolder(project->projectFolder().path() + QDir::separator());
m_recMonitor->slotUpdateCaptureFolder(project->projectFolder() + QDir::separator());
}
//Update the mouse position display so it will display in DF/NDF format by default based on the project setting.
slotUpdateMousePosition(0);
......@@ -2061,7 +2074,7 @@ void MainWindow::slotUpdateCaptureFolder()
{
if (m_recMonitor) {
if (pCore->projectManager()->current())
m_recMonitor->slotUpdateCaptureFolder(pCore->projectManager()->current()->projectFolder().path() + QDir::separator());
m_recMonitor->slotUpdateCaptureFolder(pCore->projectManager()->current()->projectFolder() + QDir::separator());
else
m_recMonitor->slotUpdateCaptureFolder(KdenliveSettings::defaultprojectfolder());
}
......@@ -2948,8 +2961,7 @@ void MainWindow::slotGetNewTitleStuff()
{
if (getNewStuff(QStringLiteral("kdenlive_titles.knsrc")) > 0) {
// get project title path
QString titlePath = pCore->projectManager()->current()->projectFolder().path();
titlePath.append(QStringLiteral("/titles/"));
QString titlePath = pCore->projectManager()->current()->projectFolder() + QStringLiteral("/titles/");
TitleWidget::refreshTitleTemplates(titlePath);
}
}
......@@ -3273,7 +3285,7 @@ void MainWindow::slotPrepareRendering(bool scriptExport, bool zoneOnly, const QS
playlistPath = temp.fileName();
}
QString playlistContent = pCore->projectManager()->projectSceneList();
QString playlistContent = pCore->projectManager()->projectSceneList(project->url().adjusted(QUrl::RemoveFilename).path());
if (!chapterFile.isEmpty()) {
int in = 0;
int out;
......@@ -3581,7 +3593,7 @@ void MainWindow::slotMonitorRequestRenderFrame(bool request)
void MainWindow::slotOpenStopmotion()
{
if (m_stopmotion == NULL) {
m_stopmotion = new StopmotionWidget(pCore->monitorManager(), pCore->projectManager()->current()->projectFolder(), m_stopmotion_actions->actions(), this);
//m_stopmotion = new StopmotionWidget(pCore->monitorManager(), pCore->projectManager()->current()->projectFolder(), m_stopmotion_actions->actions(), this);