]> git.sesse.net Git - kdenlive/commitdiff
Archive compressed project (in progress)
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Mon, 9 May 2011 22:36:42 +0000 (22:36 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Mon, 9 May 2011 22:36:42 +0000 (22:36 +0000)
svn path=/trunk/kdenlive/; revision=5578

src/archivewidget.cpp
src/archivewidget.h
src/mainwindow.cpp
src/widgets/archivewidget_ui.ui

index 16a8243c1db43613d8384053178836963817411d..7e3c60dd4549f5215e44a76e8b39924d67535266 100644 (file)
 #include <KMessageBox>
 #include <KGuiItem>
 #include <KIO/NetAccess>
+#include <KTar>
 
 #include <KDebug>
 #include <QTreeWidget>
+#include <QtConcurrentRun>
 #include "projectsettings.h"
 
 
-ArchiveWidget::ArchiveWidget(QDomDocument doc, QList <DocClipBase*> list, QStringList luma_list, QWidget * parent) :
+ArchiveWidget::ArchiveWidget(QString projectName, QDomDocument doc, QList <DocClipBase*> list, QStringList luma_list, QWidget * parent) :
         QDialog(parent),
         m_requestedSize(0),
         m_copyJob(NULL),
-        m_doc(doc)
+        m_name(projectName.section('.', 0, -2)),
+        m_doc(doc),
+        m_abortArchive(false)
 {
     setAttribute(Qt::WA_DeleteOnClose);
     setupUi(this);
     setWindowTitle(i18n("Archive Project"));
     archive_url->setUrl(KUrl(QDir::homePath()));
     connect(archive_url, SIGNAL(textChanged (const QString &)), this, SLOT(slotCheckSpace()));
+    connect(this, SIGNAL(archivingFinished(bool)), this, SLOT(slotArchivingFinished(bool)));
 
     // Setup categories
     QTreeWidgetItem *videos = new QTreeWidgetItem(files_list, QStringList() << i18n("Video clips"));
@@ -156,7 +161,8 @@ ArchiveWidget::ArchiveWidget(QDomDocument doc, QList <DocClipBase*> list, QStrin
             parentItem->setText(0, files_list->topLevelItem(i)->text(0) + " " + i18np("(%1 item)", "(%1 items)", items));
         }
     }
-    
+
+    compressed_archive->setText(compressed_archive->text() + " (" + m_name + ".tar.gz)");
     project_files->setText(i18np("%1 file to archive, requires %2", "%1 files to archive, requires %2", total, KIO::convertSize(m_requestedSize)));
     buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Archive"));
     connect(buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(slotStartArchiving()));
@@ -282,32 +288,49 @@ void ArchiveWidget::slotCheckSpace()
 
 bool ArchiveWidget::slotStartArchiving(bool firstPass)
 {
-    if (firstPass && m_copyJob) {
+    if (firstPass && (m_copyJob || m_archiveThread.isRunning())) {
         // archiving in progress, abort
-        m_copyJob->kill(KJob::EmitResult);
+        if (m_copyJob) m_copyJob->kill(KJob::EmitResult);
+        m_abortArchive = true;
         return true;
     }
+    bool isArchive = compressed_archive->isChecked();
     if (!firstPass) m_copyJob = NULL;
     else {
         //starting archiving
+        m_abortArchive = false;
         m_duplicateFiles.clear();
         m_replacementList.clear();
+        m_foldersList.clear();
+        m_filesList.clear();
+        icon_info->setPixmap(KIcon("system-run").pixmap(16, 16));
+        text_info->setText(i18n("Archiving..."));
+        repaint();
         archive_url->setEnabled(false);
+        compressed_archive->setEnabled(false);
+        m_progressTimer = new QTimer(this);
+        connect(m_progressTimer, SIGNAL(timeout()), this, SLOT(updateProgress()));
+        m_progressTimer->setSingleShot(false);
+        m_progressTimer->setInterval(700);
     }
     KUrl::List files;
     KUrl destUrl;
+    QString destPath;
     QTreeWidgetItem *parentItem;
     bool isSlideshow = false;
     for (int i = 0; i < files_list->topLevelItemCount(); i++) {
         parentItem = files_list->topLevelItem(i);
         if (parentItem->childCount() > 0 && !parentItem->isDisabled()) {
             if (parentItem->data(0, Qt::UserRole).toString() == "slideshows") {
-                KIO::NetAccess::mkdir(KUrl(archive_url->url().path(KUrl::AddTrailingSlash) + "slideshows"), this);
+                KUrl slideFolder(archive_url->url().path(KUrl::AddTrailingSlash) + "slideshows");
+                if (isArchive) m_foldersList.append("slideshows");
+                else KIO::NetAccess::mkdir(slideFolder, this);
                 isSlideshow = true;
             }
             files_list->setCurrentItem(parentItem);
             if (!isSlideshow) parentItem->setDisabled(true);
-            destUrl = KUrl(archive_url->url().path(KUrl::AddTrailingSlash) + parentItem->data(0, Qt::UserRole).toString());
+            destPath = parentItem->data(0, Qt::UserRole).toString() + "/";
+            destUrl = KUrl(archive_url->url().path(KUrl::AddTrailingSlash) + destPath);
             QTreeWidgetItem *item;
             for (int j = 0; j < parentItem->childCount(); j++) {
                 item = parentItem->child(j);
@@ -316,7 +339,8 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass)
                     if (item->isDisabled()) {
                         continue;
                     }
-                    destUrl = KUrl(destUrl.path(KUrl::AddTrailingSlash) + item->data(0, Qt::UserRole).toString() + "/");
+                    destPath.append(item->data(0, Qt::UserRole).toString() + "/");
+                    destUrl = KUrl(archive_url->url().path(KUrl::AddTrailingSlash) + destPath);
                     QStringList srcFiles = item->data(0, Qt::UserRole + 1).toStringList();
                     for (int k = 0; k < srcFiles.count(); k++) {
                         files << KUrl(srcFiles.at(k));
@@ -334,14 +358,17 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass)
                 else {
                     // We must rename the destination file, since another file with same name exists
                     //TODO: monitor progress
-                    m_duplicateFiles.insert(KUrl(item->text(0)), KUrl(destUrl.path(KUrl::AddTrailingSlash) + item->data(0, Qt::UserRole).toString()));
+                    if (isArchive) {
+                        m_filesList.insert(item->text(0), destPath + item->data(0, Qt::UserRole).toString());
+                    }
+                    else m_duplicateFiles.insert(KUrl(item->text(0)), KUrl(destUrl.path(KUrl::AddTrailingSlash) + item->data(0, Qt::UserRole).toString()));
                 }
             }
             break;
         }
     }
 
-    if (destUrl.isEmpty()) {
+    if (destPath.isEmpty()) {
         if (m_duplicateFiles.isEmpty()) return false;        
         QMapIterator<KUrl, KUrl> i(m_duplicateFiles);
         if (i.hasNext()) {
@@ -356,12 +383,22 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass)
         return true;
     }
 
-    if (files.isEmpty()) slotStartArchiving(false);
-    KIO::NetAccess::mkdir(destUrl, this);
-    m_copyJob = KIO::copy (files, destUrl, KIO::HideProgressInfo);
-    connect(m_copyJob, SIGNAL(result(KJob *)), this, SLOT(slotArchivingFinished(KJob *)));
-    connect(m_copyJob, SIGNAL(processedSize(KJob *, qulonglong)), this, SLOT(slotArchivingProgress(KJob *, qulonglong)));
-
+    if (isArchive) {
+        m_foldersList.append(destPath);
+        for (int i = 0; i < files.count(); i++) {
+            m_filesList.insert(files.at(i).path(), destPath + files.at(i).fileName());
+        }
+        slotArchivingFinished();
+    }
+    else if (files.isEmpty()) {
+        slotStartArchiving(false);
+    }
+    else {
+        KIO::NetAccess::mkdir(destUrl, this);
+        m_copyJob = KIO::copy (files, destUrl, KIO::HideProgressInfo);
+        connect(m_copyJob, SIGNAL(result(KJob *)), this, SLOT(slotArchivingFinished(KJob *)));
+        connect(m_copyJob, SIGNAL(processedSize(KJob *, qulonglong)), this, SLOT(slotArchivingProgress(KJob *, qulonglong)));
+    }
     if (firstPass) {
         progressBar->setValue(0);
         buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Abort"));
@@ -371,12 +408,12 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass)
 
 void ArchiveWidget::slotArchivingFinished(KJob *job)
 {
-    if (job->error() == 0) {
+    if (job == NULL || job->error() == 0) {
         if (slotStartArchiving(false)) {
             // We still have files to archive
             return;
         }
-        else {
+        else if (!compressed_archive->isChecked()) {
             // Archiving finished
             progressBar->setValue(100);
             if (processProjectFile()) {
@@ -387,20 +424,22 @@ void ArchiveWidget::slotArchivingFinished(KJob *job)
                 icon_info->setPixmap(KIcon("dialog-close").pixmap(16, 16));
                 text_info->setText(i18n("There was an error processing project file"));
             }
-        }
+        } else processProjectFile();
     }
     else {
         m_copyJob = NULL;
         icon_info->setPixmap(KIcon("dialog-close").pixmap(16, 16));
         text_info->setText(i18n("There was an error while copying the files: %1", job->errorString()));
     }
-    buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Archive"));
-    archive_url->setEnabled(true);
-    for (int i = 0; i < files_list->topLevelItemCount(); i++) {
-        files_list->topLevelItem(i)->setDisabled(false);
-        for (int j = 0; j < files_list->topLevelItem(i)->childCount(); j++)
-            files_list->topLevelItem(i)->child(j)->setDisabled(false);
-        
+    if (!compressed_archive->isChecked()) {
+        buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Archive"));
+        archive_url->setEnabled(true);
+        compressed_archive->setEnabled(true);
+        for (int i = 0; i < files_list->topLevelItemCount(); i++) {
+            files_list->topLevelItem(i)->setDisabled(false);
+            for (int j = 0; j < files_list->topLevelItem(i)->childCount(); j++)
+                files_list->topLevelItem(i)->child(j)->setDisabled(false);        
+        }
     }
 }
 
@@ -433,7 +472,6 @@ bool ArchiveWidget::processProjectFile()
                     dest.addPath(item->data(0, Qt::UserRole).toString());
                 }
                 m_replacementList.insert(src, dest);
-                kDebug()<<"___ PROCESS ITEM :"<<src << "="<<dest;
             }
         }
     }
@@ -490,7 +528,18 @@ bool ArchiveWidget::processProjectFile()
         }
     }
 
-    QString path = archive_url->url().path(KUrl::AddTrailingSlash) + "project.kdenlive";
+    bool isArchive = compressed_archive->isChecked();
+    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->close();
+        m_archiveThread = QtConcurrent::run(this, &ArchiveWidget::createArchive);
+        m_progressTimer->start();
+        return true;
+    }
+    
+    QString path = archive_url->url().path(KUrl::AddTrailingSlash) + m_name + ".kdenlive";
     QFile file(path);
     if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
         kWarning() << "//////  ERROR writing to file: " << path;
@@ -508,3 +557,55 @@ bool ArchiveWidget::processProjectFile()
     return true;
 }
 
+void ArchiveWidget::createArchive()
+{
+    QFileInfo dirInfo(archive_url->url().path());
+    QString user = dirInfo.owner();
+    QString group = dirInfo.group();
+    KTar archive(archive_url->url().path(KUrl::AddTrailingSlash) + m_name + ".tar.gz");
+    archive.open( QIODevice::WriteOnly );
+    kDebug()<<"ARCHIVE: "<<archive.device();
+    // Create folders
+    foreach(const QString &path, m_foldersList) {
+        archive.writeDir(path, user, group);
+    }
+
+    // Add files
+    QMapIterator<QString, QString> i(m_filesList);
+    while (i.hasNext()) {
+        i.next();
+        archive.addLocalFile(i.key(), i.value());
+    }
+
+    // Add project file
+    archive.addLocalFile(m_temp->fileName(), m_name + ".kdenlive");
+    bool result = archive.close();
+    delete m_temp;
+    emit archivingFinished(result);
+}
+
+void ArchiveWidget::slotArchivingFinished(bool result)
+{
+    if (result) {
+        icon_info->setPixmap(KIcon("dialog-ok").pixmap(16, 16));
+        text_info->setText(i18n("Project was successfully archived."));
+    }
+    else {
+        icon_info->setPixmap(KIcon("dialog-close").pixmap(16, 16));
+        text_info->setText(i18n("There was an error processing project file"));
+    }
+    buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Archive"));
+    archive_url->setEnabled(true);
+    compressed_archive->setEnabled(true);
+    for (int i = 0; i < files_list->topLevelItemCount(); i++) {
+        files_list->topLevelItem(i)->setDisabled(false);
+        for (int j = 0; j < files_list->topLevelItem(i)->childCount(); j++)
+            files_list->topLevelItem(i)->child(j)->setDisabled(false);
+    }
+    m_progressTimer->stop();
+}
+
+void ArchiveWidget::updateProgress()
+{
+    int process = 100;
+}
index 32acc74a9cdb717e412f15a9de88aab347f583b8..90b64d67929453d05d98164778732b52f8fcfda8 100644 (file)
@@ -31,6 +31,7 @@
 #include <QList>
 #include <KIO/Job>
 #include <KIO/CopyJob>
+#include <KTemporaryFile>
 
 class KJob;
 
@@ -45,16 +46,19 @@ class ArchiveWidget : public QDialog, public Ui::ArchiveWidget_UI
     Q_OBJECT
 
 public:
-    ArchiveWidget(QDomDocument doc, QList <DocClipBase*> list, QStringList luma_list, QWidget * parent = 0);
+    ArchiveWidget(QString projectName, QDomDocument doc, QList <DocClipBase*> list, QStringList luma_list, QWidget * parent = 0);
     ~ArchiveWidget();
     
 private slots:
     void slotCheckSpace();
     bool slotStartArchiving(bool firstPass = true);
-    void slotArchivingFinished(KJob *job);
+    void slotArchivingFinished(KJob *job = NULL);
     void slotArchivingProgress(KJob *, qulonglong);
     virtual void done ( int r );
     bool closeAccepted();
+    void createArchive();
+    void updateProgress();
+    void slotArchivingFinished(bool result);
 
 protected:
     virtual void closeEvent ( QCloseEvent * e );
@@ -64,7 +68,14 @@ private:
     KIO::CopyJob *m_copyJob;
     QMap <KUrl, KUrl> m_duplicateFiles;
     QMap <KUrl, KUrl> m_replacementList;
+    QString m_name;
     QDomDocument m_doc;
+    KTemporaryFile *m_temp;
+    bool m_abortArchive;
+    QFuture<void> m_archiveThread;
+    QStringList m_foldersList;
+    QMap <QString, QString> m_filesList;
+    QTimer *m_progressTimer;
 
     /** @brief Generate tree widget subitems from a string list of urls. */
     void generateItems(QTreeWidgetItem *parentItem, QStringList items);
@@ -72,6 +83,7 @@ private:
     bool processProjectFile();
 
 signals:
+    void archivingFinished(bool);
 
 };
 
index 3b4db23e9734878376f6d07340edbec8f18f5593..a6bd5c50d0fc8f407afacc8b78e64fd62f7741ec 100644 (file)
@@ -4253,7 +4253,7 @@ void MainWindow::slotArchiveProject()
 {
     QList <DocClipBase*> list = m_projectList->documentClipList();
     QDomDocument doc = m_activeDocument->xmlSceneList(m_projectMonitor->sceneList(), m_projectList->expandedFolders());
-    ArchiveWidget *d = new ArchiveWidget(doc, list, m_activeTimeline->projectView()->extractTransitionsLumas(), this);
+    ArchiveWidget *d = new ArchiveWidget(m_activeDocument->url().fileName(), doc, list, m_activeTimeline->projectView()->extractTransitionsLumas(), this);
     d->exec();
 }
 
index 1eee924418f98e934d0295c8591acc78b31ca7a3..46a48a0eb68f3bb4d62c2879cb5ecd4e6eec548f 100644 (file)
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>320</width>
-    <height>220</height>
+    <width>263</width>
+    <height>210</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -32,7 +32,7 @@
      </item>
     </layout>
    </item>
-   <item row="1" column="0" colspan="2">
+   <item row="2" column="0" colspan="2">
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <widget class="QLabel" name="icon_info">
      </item>
     </layout>
    </item>
-   <item row="2" column="0" colspan="2">
+   <item row="3" column="0" colspan="2">
     <widget class="QLabel" name="project_files">
      <property name="text">
       <string/>
      </property>
     </widget>
    </item>
-   <item row="4" column="0">
+   <item row="5" column="0">
     <widget class="QProgressBar" name="progressBar">
      <property name="value">
       <number>0</number>
      </property>
     </widget>
    </item>
-   <item row="4" column="1">
+   <item row="5" column="1">
     <widget class="QDialogButtonBox" name="buttonBox">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
@@ -80,7 +80,7 @@
      </property>
     </widget>
    </item>
-   <item row="3" column="0" colspan="2">
+   <item row="4" column="0" colspan="2">
     <widget class="QTreeWidget" name="files_list">
      <property name="alternatingRowColors">
       <bool>true</bool>
      </column>
     </widget>
    </item>
+   <item row="1" column="0" colspan="2">
+    <widget class="QCheckBox" name="compressed_archive">
+     <property name="text">
+      <string>Compressed archive</string>
+     </property>
+    </widget>
+   </item>
   </layout>
  </widget>
  <customwidgets>