From e927a83144e3080773c54f89f3d8ec6e637d47a6 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Tue, 10 May 2011 07:47:15 +0000 Subject: [PATCH] We can now open archived projects svn path=/trunk/kdenlive/; revision=5580 --- src/archivewidget.cpp | 136 +++++++++++++++++++++++++++++++++++++++--- src/archivewidget.h | 11 ++++ src/mainwindow.cpp | 16 ++++- src/mainwindow.h | 3 +- 4 files changed, 156 insertions(+), 10 deletions(-) diff --git a/src/archivewidget.cpp b/src/archivewidget.cpp index a7830bed..2f2e373a 100644 --- a/src/archivewidget.cpp +++ b/src/archivewidget.cpp @@ -29,8 +29,9 @@ #include #include #include - #include +#include + #include #include #include "projectsettings.h" @@ -42,7 +43,8 @@ ArchiveWidget::ArchiveWidget(QString projectName, QDomDocument doc, QList entries(); + for (int i = 0; i < files.count(); i++) { + if (files.at(i).endsWith(".kdenlive")) { + m_projectName = files.at(i); + isProjectArchive = true; + break; + } + } + archive.close(); + + if (!isProjectArchive) { + KMessageBox::sorry(kapp->activeWindow(), i18n("%1 is not an archived Kdenlive project", url.path(), i18n("Cannot open file"))); + hide(); + //HACK: find a better way to terminate the dialog + QTimer::singleShot(50, this, SLOT(reject())); + return; + } + setupUi(this); + connect(this, SIGNAL(extractingFinished()), this, SLOT(slotExtractingFinished())); + + compressed_archive->setHidden(true); + project_files->setHidden(true); + files_list->setHidden(true); + label->setText(i18n("Extract to")); + setWindowTitle(i18n("Open Archived Project")); + archive_url->setUrl(KUrl(QDir::homePath())); + buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Extract")); + connect(buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(slotStartExtracting())); +} + + ArchiveWidget::~ArchiveWidget() { } @@ -191,7 +236,7 @@ void ArchiveWidget::closeEvent ( QCloseEvent * e ) bool ArchiveWidget::closeAccepted() { - if (!archive_url->isEnabled()) { + if (!m_extractMode && !archive_url->isEnabled()) { // Archiving in progress, should we stop? if (KMessageBox::warningContinueCancel(this, i18n("Archiving in progress, do you want to stop it?"), i18n("Stop Archiving"), KGuiItem(i18n("Stop Archiving"))) != KMessageBox::Continue) { return false; @@ -450,6 +495,8 @@ bool ArchiveWidget::processProjectFile() { KUrl destUrl; QTreeWidgetItem *item; + bool isArchive = compressed_archive->isChecked(); + for (int i = 0; i < files_list->topLevelItemCount(); i++) { QTreeWidgetItem *parentItem = files_list->topLevelItem(i); if (parentItem->childCount() > 0) { @@ -473,10 +520,18 @@ bool ArchiveWidget::processProjectFile() } } - // process kdenlive producers QDomElement mlt = m_doc.documentElement(); QString root = mlt.attribute("root") + "/"; - mlt.setAttribute("root", archive_url->url().path(KUrl::RemoveTrailingSlash)); + + // Adjust global settings + QString basePath; + if (isArchive) basePath = "$CURRENTPATH"; + else basePath = archive_url->url().path(KUrl::RemoveTrailingSlash); + mlt.setAttribute("root", basePath); + QDomElement project = mlt.elementsByTagName("kdenlivedoc").at(0).toElement(); + project.setAttribute("projectfolder", basePath); + + // process kdenlive producers QDomNodeList prods = mlt.elementsByTagName("kdenlive_producer"); for (int i = 0; i < prods.count(); i++) { QDomElement e = prods.item(i).toElement(); @@ -525,11 +580,22 @@ bool ArchiveWidget::processProjectFile() } } - bool isArchive = compressed_archive->isChecked(); + QString playList = m_doc.toString(); + if (isArchive) { + QString startString("\""); + startString.append(archive_url->url().path(KUrl::RemoveTrailingSlash)); + QString endString("\""); + endString.append(basePath); + playList.replace(startString, endString); + startString = ">" + archive_url->url().path(KUrl::RemoveTrailingSlash); + endString = ">" + basePath; + playList.replace(startString, endString); + } + if (isArchive) { m_temp = new KTemporaryFile; if (!m_temp->open()) KMessageBox::error(this, i18n("Cannot create temporary file")); - m_temp->write(m_doc.toString().toUtf8()); + m_temp->write(playList.toUtf8()); m_temp->close(); m_archiveThread = QtConcurrent::run(this, &ArchiveWidget::createArchive); return true; @@ -608,3 +674,59 @@ void ArchiveWidget::slotArchivingProgress(int p) { progressBar->setValue(p); } + +void ArchiveWidget::slotStartExtracting() +{ + KIO::NetAccess::mkdir(archive_url->url().path(KUrl::RemoveTrailingSlash), this); + m_archiveThread = QtConcurrent::run(this, &ArchiveWidget::doExtracting); +} + +void ArchiveWidget::doExtracting() +{ + KTar archive(m_extractUrl.path()); + archive.open( QIODevice::ReadOnly ); + archive.directory()->copyTo(archive_url->url().path(KUrl::AddTrailingSlash)); + archive.close(); + emit extractingFinished(); +} + +QString ArchiveWidget::extractedProjectFile() +{ + return archive_url->url().path(KUrl::AddTrailingSlash) + m_projectName; +} + +void ArchiveWidget::slotExtractingFinished() +{ + // Process project file + QFile file(extractedProjectFile()); + bool error = false; + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + error = true; + } + else { + QString playList = file.readAll(); + file.close(); + if (playList.isEmpty()) { + error = true; + } + else { + playList.replace("$CURRENTPATH", archive_url->url().path(KUrl::RemoveTrailingSlash)); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + kWarning() << "////// ERROR writing to file: "; + error = true; + } + else { + file.write(playList.toUtf8()); + if (file.error() != QFile::NoError) { + error = true; + } + file.close(); + } + } + } + if (error) { + KMessageBox::sorry(kapp->activeWindow(), i18n("Cannot open project file %1", extractedProjectFile()), i18n("Cannot open file")); + reject(); + } + else accept(); +} diff --git a/src/archivewidget.h b/src/archivewidget.h index 4ca08ec0..1fab3e46 100644 --- a/src/archivewidget.h +++ b/src/archivewidget.h @@ -47,7 +47,11 @@ class ArchiveWidget : public QDialog, public Ui::ArchiveWidget_UI public: ArchiveWidget(QString projectName, QDomDocument doc, QList list, QStringList luma_list, QWidget * parent = 0); + // Constructor for extracting widget + ArchiveWidget(const KUrl &url, QWidget * parent = 0); ~ArchiveWidget(); + + QString extractedProjectFile(); private slots: void slotCheckSpace(); @@ -59,6 +63,9 @@ private slots: void createArchive(); void slotArchivingProgress(int); void slotArchivingFinished(bool result); + void slotStartExtracting(); + void doExtracting(); + void slotExtractingFinished(); protected: virtual void closeEvent ( QCloseEvent * e ); @@ -75,6 +82,9 @@ private: QFuture m_archiveThread; QStringList m_foldersList; QMap m_filesList; + bool m_extractMode; + KUrl m_extractUrl; + QString m_projectName; /** @brief Generate tree widget subitems from a string list of urls. */ void generateItems(QTreeWidgetItem *parentItem, QStringList items); @@ -84,6 +94,7 @@ private: signals: void archivingFinished(bool); void archiveProgress(int); + void extractingFinished(); }; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index a6bd5c50..6307d8ba 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1908,7 +1908,7 @@ bool MainWindow::saveFileAs(const QString &outputFileName) bool MainWindow::saveFileAs() { - QString outputFile = KFileDialog::getSaveFileName(m_activeDocument->projectFolder(), getMimeType()); + QString outputFile = KFileDialog::getSaveFileName(m_activeDocument->projectFolder(), getMimeType(false)); if (outputFile.isEmpty()) { return false; } @@ -1956,6 +1956,17 @@ void MainWindow::openLastFile() void MainWindow::openFile(const KUrl &url) { + // Make sure the url is a Kdenlive project file + KMimeType::Ptr mime = KMimeType::findByUrl(url); + if (mime.data()->is("application/x-compressed-tar")) { + // Opening a compressed project file, we need to process it + kDebug()<<"Opening archive, processing"; + ArchiveWidget *ar = new ArchiveWidget(url); + if (ar->exec() == QDialog::Accepted) openFile(KUrl(ar->extractedProjectFile())); + delete ar; + return; + } + // Check if the document is already opened const int ct = m_timelineArea->count(); bool isOpened = false; @@ -4112,11 +4123,12 @@ void MainWindow::slotSwitchTitles() slotShowTitleBars(!KdenliveSettings::showtitlebars()); } -QString MainWindow::getMimeType() +QString MainWindow::getMimeType(bool open) { QString mimetype = "application/x-kdenlive"; KMimeType::Ptr mime = KMimeType::mimeType(mimetype); if (!mime) mimetype = "*.kdenlive"; + if (open) mimetype.append(" application/x-compressed-tar"); return mimetype; } diff --git a/src/mainwindow.h b/src/mainwindow.h index 6d26e393..703fc625 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -296,8 +296,9 @@ private: QPixmap createSchemePreviewIcon(const KSharedConfigPtr &config); /** @brief Checks that the Kdenlive mime type is correctly installed. + * @param open If set to true, this will return the mimetype allowed for file opening (adds .tar.gz format) * @return The mimetype */ - QString getMimeType(); + QString getMimeType(bool open = true); /** @brief Populates the "load layout" menu. */ void loadLayouts(); -- 2.39.2