#include <KGuiItem>
#include <KIO/NetAccess>
#include <KTar>
-
#include <KDebug>
+#include <KApplication>
+#include <kio/directorysizejob.h>
+
#include <QTreeWidget>
#include <QtConcurrentRun>
#include "projectsettings.h"
m_copyJob(NULL),
m_name(projectName.section('.', 0, -2)),
m_doc(doc),
- m_abortArchive(false)
+ m_abortArchive(false),
+ m_extractMode(false),
+ m_extractArchive(NULL)
{
setAttribute(Qt::WA_DeleteOnClose);
setupUi(this);
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)));
+ connect(this, SIGNAL(archiveProgress(int)), this, SLOT(slotArchivingProgress(int)));
// Setup categories
QTreeWidgetItem *videos = new QTreeWidgetItem(files_list, QStringList() << i18n("Video clips"));
generateItems(others, otherUrls);
generateItems(proxies, proxyUrls);
-#if QT_VERSION >= 0x040500
allFonts.removeDuplicates();
-#endif
//TODO: fonts
parentItem->setText(0, files_list->topLevelItem(i)->text(0) + " " + i18np("(%1 item)", "(%1 items)", items));
}
}
-
+ if (m_name.isEmpty()) m_name = i18n("Untitled");
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"));
slotCheckSpace();
}
+// Constructor for extract widget
+ArchiveWidget::ArchiveWidget(const KUrl &url, QWidget * parent):
+ QDialog(parent),
+ m_extractMode(true),
+ m_extractUrl(url)
+{
+ //setAttribute(Qt::WA_DeleteOnClose);
+
+ setupUi(this);
+ connect(this, SIGNAL(extractingFinished()), this, SLOT(slotExtractingFinished()));
+ connect(this, SIGNAL(showMessage(const QString &, const QString &)), this, SLOT(slotDisplayMessage(const QString &, const QString &)));
+
+ 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()));
+ buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
+ adjustSize();
+ m_archiveThread = QtConcurrent::run(this, &ArchiveWidget::openArchiveForExtraction);
+}
+
+
ArchiveWidget::~ArchiveWidget()
{
+ if (m_extractArchive) delete m_extractArchive;
+}
+
+void ArchiveWidget::slotDisplayMessage(const QString &icon, const QString &text)
+{
+ icon_info->setPixmap(KIcon(icon).pixmap(16, 16));
+ text_info->setText(text);
+}
+
+void ArchiveWidget::openArchiveForExtraction()
+{
+ emit showMessage("system-run", i18n("Opening archive..."));
+ m_extractArchive = new KTar(m_extractUrl.path());
+ if (!m_extractArchive->isOpen() && !m_extractArchive->open( QIODevice::ReadOnly )) {
+ emit showMessage("dialog-close", i18n("Cannot open archive file:\n %1", m_extractUrl.path()));
+ groupBox->setEnabled(false);
+ return;
+ }
+
+ // Check that it is a kdenlive project archive
+ bool isProjectArchive = false;
+ QStringList files = m_extractArchive->directory()->entries();
+ for (int i = 0; i < files.count(); i++) {
+ if (files.at(i).endsWith(".kdenlive")) {
+ m_projectName = files.at(i);
+ isProjectArchive = true;
+ break;
+ }
+ }
+
+ if (!isProjectArchive) {
+ emit showMessage("dialog-close", i18n("File %1\n is not an archived Kdenlive project", m_extractUrl.path()));
+ groupBox->setEnabled(false);
+ return;
+ }
+ buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
+ emit showMessage("dialog-ok", i18n("Ready"));
}
void ArchiveWidget::done ( int r )
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;
if (freeSize > m_requestedSize) {
// everything is ok
buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
- icon_info->setPixmap(KIcon("dialog-ok").pixmap(16, 16));
- text_info->setText(i18n("Available space on drive: %1", KIO::convertSize(freeSize)));
+ slotDisplayMessage("dialog-ok", i18n("Available space on drive: %1", KIO::convertSize(freeSize)));
}
else {
buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
- icon_info->setPixmap(KIcon("dialog-close").pixmap(16, 16));
- text_info->setText(i18n("Not enough space on drive, free space: %1", KIO::convertSize(freeSize)));
+ slotDisplayMessage("dialog-close", i18n("Not enough space on drive, free space: %1", KIO::convertSize(freeSize)));
}
}
m_replacementList.clear();
m_foldersList.clear();
m_filesList.clear();
- icon_info->setPixmap(KIcon("system-run").pixmap(16, 16));
- text_info->setText(i18n("Archiving..."));
+ slotDisplayMessage("system-run", 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;
// Archiving finished
progressBar->setValue(100);
if (processProjectFile()) {
- icon_info->setPixmap(KIcon("dialog-ok").pixmap(16, 16));
- text_info->setText(i18n("Project was successfully archived."));
+ slotDisplayMessage("dialog-ok", 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"));
+ slotDisplayMessage("dialog-close", 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()));
+ slotDisplayMessage("dialog-close", i18n("There was an error while copying the files: %1", job->errorString()));
}
if (!compressed_archive->isChecked()) {
buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Archive"));
{
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) {
}
}
- // 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.firstChildElement("kdenlivedoc");
+ 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();
}
}
- 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);
- m_progressTimer->start();
return true;
}
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");
+ KTar archive(archive_url->url().path(KUrl::AddTrailingSlash) + m_name + ".tar.gz", "application/x-gzip");
archive.open( QIODevice::WriteOnly );
- kDebug()<<"ARCHIVE: "<<archive.device();
+
// Create folders
foreach(const QString &path, m_foldersList) {
archive.writeDir(path, user, group);
}
// Add files
+ int ix = 0;
QMapIterator<QString, QString> i(m_filesList);
while (i.hasNext()) {
i.next();
archive.addLocalFile(i.key(), i.value());
+ emit archiveProgress((int) 100 * ix / m_filesList.count());
+ ix++;
}
// Add project file
void ArchiveWidget::slotArchivingFinished(bool result)
{
if (result) {
- icon_info->setPixmap(KIcon("dialog-ok").pixmap(16, 16));
- text_info->setText(i18n("Project was successfully archived."));
+ slotDisplayMessage("dialog-ok", 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"));
+ slotDisplayMessage("dialog-close", i18n("There was an error processing project file"));
}
+ progressBar->setValue(100);
buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Archive"));
archive_url->setEnabled(true);
compressed_archive->setEnabled(true);
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()
+void ArchiveWidget::slotArchivingProgress(int p)
+{
+ progressBar->setValue(p);
+}
+
+void ArchiveWidget::slotStartExtracting()
+{
+ if (m_archiveThread.isRunning()) {
+ //TODO: abort extracting
+ return;
+ }
+ QFileInfo f(m_extractUrl.path());
+ m_requestedSize = f.size();
+ KIO::NetAccess::mkdir(archive_url->url().path(KUrl::RemoveTrailingSlash), this);
+ slotDisplayMessage("system-run", i18n("Extracting..."));
+ buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Abort"));
+ m_progressTimer = new QTimer;
+ m_progressTimer->setInterval(800);
+ m_progressTimer->setSingleShot(false);
+ connect(m_progressTimer, SIGNAL(timeout()), this, SLOT(slotExtractProgress()));
+ m_archiveThread = QtConcurrent::run(this, &ArchiveWidget::doExtracting);
+ m_progressTimer->start();
+}
+
+void ArchiveWidget::slotExtractProgress()
+{
+ KIO::DirectorySizeJob *job = KIO::directorySize(archive_url->url());
+ connect(job, SIGNAL(result(KJob*)), this, SLOT(slotGotProgress(KJob*)));
+}
+
+void ArchiveWidget::slotGotProgress(KJob* job)
+{
+ if (!job->error()) {
+ KIO::DirectorySizeJob *j = static_cast <KIO::DirectorySizeJob *>(job);
+ progressBar->setValue((int) 100 * j->totalSize() / m_requestedSize);
+ }
+ job->deleteLater();
+}
+
+void ArchiveWidget::doExtracting()
+{
+ m_extractArchive->directory()->copyTo(archive_url->url().path(KUrl::AddTrailingSlash));
+ m_extractArchive->close();
+ emit extractingFinished();
+}
+
+QString ArchiveWidget::extractedProjectFile()
{
- int process = 100;
+ return archive_url->url().path(KUrl::AddTrailingSlash) + m_projectName;
+}
+
+void ArchiveWidget::slotExtractingFinished()
+{
+ m_progressTimer->stop();
+ delete m_progressTimer;
+ // 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();
}