X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Farchivewidget.cpp;h=a645172e5a9efe19f83a28dc7423d5a5f6d353c4;hb=c3302003093710ee247ad84c0fe2ef3c579d417f;hp=363781df6423abef52f85f0cde8c52e71ce24da4;hpb=9c8485b112894071602a863693b4e2dbc2baeca0;p=kdenlive diff --git a/src/archivewidget.cpp b/src/archivewidget.cpp index 363781df..a645172e 100644 --- a/src/archivewidget.cpp +++ b/src/archivewidget.cpp @@ -32,29 +32,36 @@ #include #include #include +#if KDE_IS_VERSION(4,7,0) +#include +#endif #include #include #include "projectsettings.h" -ArchiveWidget::ArchiveWidget(QString projectName, QDomDocument doc, QList list, QStringList luma_list, QWidget * parent) : - QDialog(parent), - m_requestedSize(0), - m_copyJob(NULL), - m_name(projectName.section('.', 0, -2)), - m_doc(doc), - m_abortArchive(false), - m_extractMode(false), - m_extractArchive(NULL) +ArchiveWidget::ArchiveWidget(const QString &projectName, const QDomDocument &doc, const QList &list, const QStringList &luma_list, QWidget * parent) : + QDialog(parent) + , m_requestedSize(0) + , m_copyJob(NULL) + , m_name(projectName.section('.', 0, -2)) + , m_doc(doc) + , m_temp(NULL) + , m_abortArchive(false) + , m_extractMode(false) + , m_progressTimer(NULL) + , m_extractArchive(NULL) + , m_missingClips(0) { 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(archive_url, SIGNAL(textChanged(QString)), this, SLOT(slotCheckSpace())); connect(this, SIGNAL(archivingFinished(bool)), this, SLOT(slotArchivingFinished(bool))); connect(this, SIGNAL(archiveProgress(int)), this, SLOT(slotArchivingProgress(int))); + connect(proxy_only, SIGNAL(stateChanged(int)), this, SLOT(slotProxyOnly(int))); // Setup categories QTreeWidgetItem *videos = new QTreeWidgetItem(files_list, QStringList() << i18n("Video clips")); @@ -77,6 +84,10 @@ ArchiveWidget::ArchiveWidget(QString projectName, QDomDocument doc, QList setIcon(0, KIcon("text-plain")); texts->setData(0, Qt::UserRole, "texts"); texts->setExpanded(false); + QTreeWidgetItem *playlists = new QTreeWidgetItem(files_list, QStringList() << i18n("Playlist clips")); + playlists->setIcon(0, KIcon("video-mlt-playlist")); + playlists->setData(0, Qt::UserRole, "playlist"); + playlists->setExpanded(false); QTreeWidgetItem *others = new QTreeWidgetItem(files_list, QStringList() << i18n("Other clips")); others->setIcon(0, KIcon("unknown")); others->setData(0, Qt::UserRole, "others"); @@ -95,60 +106,85 @@ ArchiveWidget::ArchiveWidget(QString projectName, QDomDocument doc, QList slideUrls; + QMap audioUrls; + QMap videoUrls; + QMap imageUrls; + QMap playlistUrls; + QMap proxyUrls; - for (int i = 0; i < list.count(); i++) { + for (int i = 0; i < list.count(); ++i) { DocClipBase *clip = list.at(i); CLIPTYPE t = clip->clipType(); + QString id = clip->getId(); if (t == SLIDESHOW) { KUrl slideUrl = clip->fileURL(); //TODO: Slideshow files - slideUrls << slideUrl.path(); + slideUrls.insert(id, slideUrl.path()); } - else if (t == IMAGE) imageUrls << clip->fileURL().path(); + else if (t == IMAGE) imageUrls.insert(id, clip->fileURL().path()); else if (t == TEXT) { QStringList imagefiles = TitleWidget::extractImageList(clip->getProperty("xmldata")); QStringList fonts = TitleWidget::extractFontList(clip->getProperty("xmldata")); - imageUrls << imagefiles; + extraImageUrls << imagefiles; allFonts << fonts; } else if (t == PLAYLIST) { + playlistUrls.insert(id, clip->fileURL().path()); QStringList files = ProjectSettings::extractPlaylistUrls(clip->fileURL().path()); otherUrls << files; } else if (!clip->fileURL().isEmpty()) { - if (t == AUDIO) audioUrls << clip->fileURL().path(); + if (t == AUDIO) audioUrls.insert(id, clip->fileURL().path()); else { - videoUrls << clip->fileURL().path(); + videoUrls.insert(id, clip->fileURL().path()); // Check if we have a proxy QString proxy = clip->getProperty("proxy"); - if (!proxy.isEmpty() && proxy != "-" && QFile::exists(proxy)) proxyUrls << proxy; + if (!proxy.isEmpty() && proxy != "-" && QFile::exists(proxy)) proxyUrls.insert(id, proxy); } } } + generateItems(images, extraImageUrls); generateItems(sounds, audioUrls); generateItems(videos, videoUrls); generateItems(images, imageUrls); generateItems(slideshows, slideUrls); + generateItems(playlists, playlistUrls); generateItems(others, otherUrls); generateItems(proxies, proxyUrls); -#if QT_VERSION >= 0x040500 allFonts.removeDuplicates(); + +#if KDE_IS_VERSION(4,7,0) + m_infoMessage = new KMessageWidget(this); + QVBoxLayout *s = static_cast (layout()); + s->insertWidget(5, m_infoMessage); + m_infoMessage->setCloseButtonVisible(false); + m_infoMessage->setWordWrap(true); + m_infoMessage->hide(); #endif + + // missing clips, warn user + if (m_missingClips > 0) { + QString infoText = i18np("You have %1 missing clip in your project.", "You have %1 missing clips in your project.", m_missingClips); +#if KDE_IS_VERSION(4,7,0) + m_infoMessage->setMessageType(KMessageWidget::Warning); + m_infoMessage->setText(infoText); + m_infoMessage->animatedShow(); +#else + KMessageBox::sorry(this, infoText); +#endif + } //TODO: fonts // Hide unused categories, add item count int total = 0; - for (int i = 0; i < files_list->topLevelItemCount(); i++) { + for (int i = 0; i < files_list->topLevelItemCount(); ++i) { QTreeWidgetItem *parentItem = files_list->topLevelItem(i); int items = parentItem->childCount(); if (items == 0) { @@ -163,7 +199,7 @@ ArchiveWidget::ArchiveWidget(QString projectName, QDomDocument doc, QList setText(0, files_list->topLevelItem(i)->text(0) + " " + i18np("(%1 item)", "(%1 items)", items)); + parentItem->setText(0, files_list->topLevelItem(i)->text(0) + ' ' + i18np("(%1 item)", "(%1 items)", items)); } } if (m_name.isEmpty()) m_name = i18n("Untitled"); @@ -185,10 +221,15 @@ ArchiveWidget::ArchiveWidget(const KUrl &url, QWidget * parent): //setAttribute(Qt::WA_DeleteOnClose); setupUi(this); + m_progressTimer = new QTimer; + m_progressTimer->setInterval(800); + m_progressTimer->setSingleShot(false); + connect(m_progressTimer, SIGNAL(timeout()), this, SLOT(slotExtractProgress())); connect(this, SIGNAL(extractingFinished()), this, SLOT(slotExtractingFinished())); - connect(this, SIGNAL(showMessage(const QString &, const QString &)), this, SLOT(slotDisplayMessage(const QString &, const QString &))); + connect(this, SIGNAL(showMessage(QString,QString)), this, SLOT(slotDisplayMessage(QString,QString))); compressed_archive->setHidden(true); + proxy_only->setHidden(true); project_files->setHidden(true); files_list->setHidden(true); label->setText(i18n("Extract to")); @@ -196,7 +237,7 @@ ArchiveWidget::ArchiveWidget(const KUrl &url, QWidget * parent): 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); + buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true); adjustSize(); m_archiveThread = QtConcurrent::run(this, &ArchiveWidget::openArchiveForExtraction); } @@ -204,15 +245,29 @@ ArchiveWidget::ArchiveWidget(const KUrl &url, QWidget * parent): ArchiveWidget::~ArchiveWidget() { - if (m_extractArchive) delete m_extractArchive; + delete m_extractArchive; + delete m_progressTimer; } void ArchiveWidget::slotDisplayMessage(const QString &icon, const QString &text) -{ +{ icon_info->setPixmap(KIcon(icon).pixmap(16, 16)); text_info->setText(text); } +void ArchiveWidget::slotJobResult(bool success, const QString &text) +{ +#if KDE_IS_VERSION(4,7,0) + m_infoMessage->setMessageType(success ? KMessageWidget::Positive : KMessageWidget::Warning); + m_infoMessage->setText(text); + m_infoMessage->animatedShow(); +#else + if (success) icon_info->setPixmap(KIcon("dialog-ok").pixmap(16, 16)); + else icon_info->setPixmap(KIcon("dialog-close").pixmap(16, 16)); + text_info->setText(text); +#endif +} + void ArchiveWidget::openArchiveForExtraction() { emit showMessage("system-run", i18n("Opening archive...")); @@ -226,7 +281,7 @@ void ArchiveWidget::openArchiveForExtraction() // 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++) { + for (int i = 0; i < files.count(); ++i) { if (files.at(i).endsWith(".kdenlive")) { m_projectName = files.at(i); isProjectArchive = true; @@ -237,6 +292,7 @@ void ArchiveWidget::openArchiveForExtraction() if (!isProjectArchive) { emit showMessage("dialog-close", i18n("File %1\n is not an archived Kdenlive project", m_extractUrl.path())); groupBox->setEnabled(false); + buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); return; } buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true); @@ -269,7 +325,7 @@ bool ArchiveWidget::closeAccepted() } -void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QStringList items) +void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, const QStringList& items) { QStringList filesList; QString fileName; @@ -287,17 +343,104 @@ void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QStringList items if (slideUrl.fileName().startsWith(".all.")) { // mimetype slideshow (for example *.png) QStringList filters; - QString extension; // TODO: improve jpeg image detection with extension like jpeg, requires change in MLT image producers filters << "*." + slideUrl.fileName().section('.', -1); dir.setNameFilters(filters); QFileInfoList resultList = dir.entryInfoList(QDir::Files); QStringList slideImages; - for (int i = 0; i < resultList.count(); i++) { - m_requestedSize += resultList.at(i).size(); + qint64 totalSize = 0; + for (int i = 0; i < resultList.count(); ++i) { + totalSize += resultList.at(i).size(); + slideImages << resultList.at(i).absoluteFilePath(); + } + item->setData(0, Qt::UserRole + 1, slideImages); + item->setData(0, Qt::UserRole + 3, totalSize); + m_requestedSize += totalSize; + } + else { + // pattern url (like clip%.3d.png) + QStringList result = dir.entryList(QDir::Files); + QString filter = slideUrl.fileName(); + QString ext = filter.section('.', -1); + filter = filter.section('%', 0, -2); + QString regexp = '^' + filter + "\\d+\\." + ext + '$'; + QRegExp rx(regexp); + QStringList slideImages; + QString directory = dir.absolutePath(); + if (!directory.endsWith('/')) directory.append('/'); + qint64 totalSize = 0; + foreach(const QString & path, result) { + if (rx.exactMatch(path)) { + totalSize += QFileInfo(directory + path).size(); + slideImages << directory + path; + } + } + item->setData(0, Qt::UserRole + 1, slideImages); + item->setData(0, Qt::UserRole + 3, totalSize); + m_requestedSize += totalSize; + } + } + else if (filesList.contains(fileName)) { + // we have 2 files with same name + int ix = 0; + QString newFileName = fileName.section('.', 0, -2) + '_' + QString::number(ix) + '.' + fileName.section('.', -1); + while (filesList.contains(newFileName)) { + ix ++; + newFileName = fileName.section('.', 0, -2) + '_' + QString::number(ix) + '.' + fileName.section('.', -1); + } + fileName = newFileName; + item->setData(0, Qt::UserRole, fileName); + } + if (!isSlideshow) { + qint64 fileSize = QFileInfo(file).size(); + if (fileSize <= 0) { + item->setIcon(0, KIcon("edit-delete")); + m_missingClips++; + } + else { + m_requestedSize += fileSize; + item->setData(0, Qt::UserRole + 3, fileSize); + } + filesList << fileName; + } + } +} + +void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, const QMap & items) +{ + QStringList filesList; + QString fileName; + int ix = 0; + bool isSlideshow = parentItem->data(0, Qt::UserRole).toString() == "slideshows"; + QMap::const_iterator it = items.constBegin(); + while (it != items.constEnd()) { + QString file = it.value(); + QTreeWidgetItem *item = new QTreeWidgetItem(parentItem, QStringList() << file); + // Store the clip's id + item->setData(0, Qt::UserRole + 2, it.key()); + fileName = KUrl(file).fileName(); + if (isSlideshow) { + // we store each slideshow in a separate subdirectory + item->setData(0, Qt::UserRole, ix); + ix++; + KUrl slideUrl(file); + QDir dir(slideUrl.directory(KUrl::AppendTrailingSlash)); + if (slideUrl.fileName().startsWith(".all.")) { + // mimetype slideshow (for example *.png) + QStringList filters; + // TODO: improve jpeg image detection with extension like jpeg, requires change in MLT image producers + filters << "*." + slideUrl.fileName().section('.', -1); + dir.setNameFilters(filters); + QFileInfoList resultList = dir.entryInfoList(QDir::Files); + QStringList slideImages; + qint64 totalSize = 0; + for (int i = 0; i < resultList.count(); ++i) { + totalSize += resultList.at(i).size(); slideImages << resultList.at(i).absoluteFilePath(); } item->setData(0, Qt::UserRole + 1, slideImages); + item->setData(0, Qt::UserRole + 3, totalSize); + m_requestedSize += totalSize; } else { // pattern url (like clip%.3d.png) @@ -305,24 +448,27 @@ void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QStringList items QString filter = slideUrl.fileName(); QString ext = filter.section('.', -1); filter = filter.section('%', 0, -2); - QString regexp = "^" + filter + "\\d+\\." + ext + "$"; + QString regexp = '^' + filter + "\\d+\\." + ext + '$'; QRegExp rx(regexp); QStringList slideImages; + qint64 totalSize = 0; QString directory = dir.absolutePath(); if (!directory.endsWith('/')) directory.append('/'); foreach(const QString & path, result) { if (rx.exactMatch(path)) { - m_requestedSize += QFileInfo(directory + path).size(); + totalSize += QFileInfo(directory + path).size(); slideImages << directory + path; } } item->setData(0, Qt::UserRole + 1, slideImages); + item->setData(0, Qt::UserRole + 3, totalSize); + m_requestedSize += totalSize; } } else if (filesList.contains(fileName)) { // we have 2 files with same name int ix = 0; - QString newFileName = fileName.section('.', 0, -2) + "_" + QString::number(ix) + "." + fileName.section('.', -1); + QString newFileName = fileName.section('.', 0, -2) + '_' + QString::number(ix) + '.' + fileName.section('.', -1); while (filesList.contains(newFileName)) { ix ++; newFileName = fileName.section('.', 0, -2) + "_" + QString::number(ix) + "." + fileName.section('.', -1); @@ -331,16 +477,25 @@ void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QStringList items item->setData(0, Qt::UserRole, fileName); } if (!isSlideshow) { - m_requestedSize += QFileInfo(file).size(); + qint64 fileSize = QFileInfo(file).size(); + if (fileSize <= 0) { + item->setIcon(0, KIcon("edit-delete")); + m_missingClips++; + } + else { + m_requestedSize += fileSize; + item->setData(0, Qt::UserRole + 3, fileSize); + } filesList << fileName; } + ++it; } } void ArchiveWidget::slotCheckSpace() { KDiskFreeSpaceInfo inf = KDiskFreeSpaceInfo::freeSpaceInfo( archive_url->url().path()); - KIO::filesize_t freeSize = inf.available();; + KIO::filesize_t freeSize = inf.available(); if (freeSize > m_requestedSize) { // everything is ok buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true); @@ -372,6 +527,7 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass) slotDisplayMessage("system-run", i18n("Archiving...")); repaint(); archive_url->setEnabled(false); + proxy_only->setEnabled(false); compressed_archive->setEnabled(false); } KUrl::List files; @@ -379,28 +535,35 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass) QString destPath; QTreeWidgetItem *parentItem; bool isSlideshow = false; - for (int i = 0; i < files_list->topLevelItemCount(); i++) { + int items = 0; + + // We parse all files going into one folder, then start the copy job + for (int i = 0; i < files_list->topLevelItemCount(); ++i) { parentItem = files_list->topLevelItem(i); - if (parentItem->childCount() > 0 && !parentItem->isDisabled()) { + if (parentItem->isDisabled()) { + parentItem->setExpanded(false); + continue; + } + if (parentItem->childCount() > 0) { if (parentItem->data(0, Qt::UserRole).toString() == "slideshows") { KUrl slideFolder(archive_url->url().path(KUrl::AddTrailingSlash) + "slideshows"); if (isArchive) m_foldersList.append("slideshows"); else KIO::NetAccess::mkdir(slideFolder, this); isSlideshow = true; } + else isSlideshow = false; files_list->setCurrentItem(parentItem); - if (!isSlideshow) parentItem->setDisabled(true); - destPath = parentItem->data(0, Qt::UserRole).toString() + "/"; + parentItem->setExpanded(true); + 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); + if (item->isDisabled()) continue; // Special case: slideshows + items++; if (isSlideshow) { - if (item->isDisabled()) { - continue; - } - destPath.append(item->data(0, Qt::UserRole).toString() + "/"); + destPath += 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++) { @@ -425,10 +588,17 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass) else m_duplicateFiles.insert(KUrl(item->text(0)), KUrl(destUrl.path(KUrl::AddTrailingSlash) + item->data(0, Qt::UserRole).toString())); } } + if (!isSlideshow) parentItem->setDisabled(true); break; } } + if (items == 0) { + // No clips to archive + slotArchivingFinished(NULL, true); + return true; + } + if (destPath.isEmpty()) { if (m_duplicateFiles.isEmpty()) return false; QMapIterator i(m_duplicateFiles); @@ -438,15 +608,15 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass) KUrl startJobDst = i.value(); m_duplicateFiles.remove(startJobSrc); KIO::CopyJob *job = KIO::copyAs(startJobSrc, startJobDst, KIO::HideProgressInfo); - connect(job, SIGNAL(result(KJob *)), this, SLOT(slotArchivingFinished(KJob *))); - connect(job, SIGNAL(processedSize(KJob *, qulonglong)), this, SLOT(slotArchivingProgress(KJob *, qulonglong))); + connect(job, SIGNAL(result(KJob*)), this, SLOT(slotArchivingFinished(KJob*))); + connect(job, SIGNAL(processedSize(KJob*,qulonglong)), this, SLOT(slotArchivingProgress(KJob*,qulonglong))); } return true; } if (isArchive) { m_foldersList.append(destPath); - for (int i = 0; i < files.count(); i++) { + for (int i = 0; i < files.count(); ++i) { m_filesList.insert(files.at(i).path(), destPath + files.at(i).fileName()); } slotArchivingFinished(); @@ -457,8 +627,8 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass) 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))); + 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); @@ -467,10 +637,10 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass) return true; } -void ArchiveWidget::slotArchivingFinished(KJob *job) +void ArchiveWidget::slotArchivingFinished(KJob *job, bool finished) { if (job == NULL || job->error() == 0) { - if (slotStartArchiving(false)) { + if (!finished && slotStartArchiving(false)) { // We still have files to archive return; } @@ -478,22 +648,23 @@ void ArchiveWidget::slotArchivingFinished(KJob *job) // Archiving finished progressBar->setValue(100); if (processProjectFile()) { - slotDisplayMessage("dialog-ok", i18n("Project was successfully archived.")); + slotJobResult(true, i18n("Project was successfully archived.")); } else { - slotDisplayMessage("dialog-close", i18n("There was an error processing project file")); + slotJobResult(false, i18n("There was an error processing project file")); } } else processProjectFile(); } else { m_copyJob = NULL; - slotDisplayMessage("dialog-close", i18n("There was an error while copying the files: %1", job->errorString())); + slotJobResult(false, i18n("There was an error while copying the files: %1", job->errorString())); } if (!compressed_archive->isChecked()) { buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Archive")); archive_url->setEnabled(true); + proxy_only->setEnabled(true); compressed_archive->setEnabled(true); - for (int i = 0; i < files_list->topLevelItemCount(); i++) { + 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); @@ -513,7 +684,7 @@ bool ArchiveWidget::processProjectFile() QTreeWidgetItem *item; bool isArchive = compressed_archive->isChecked(); - for (int i = 0; i < files_list->topLevelItemCount(); i++) { + for (int i = 0; i < files_list->topLevelItemCount(); ++i) { QTreeWidgetItem *parentItem = files_list->topLevelItem(i); if (parentItem->childCount() > 0) { destUrl = KUrl(archive_url->url().path(KUrl::AddTrailingSlash) + parentItem->data(0, Qt::UserRole).toString()); @@ -523,7 +694,7 @@ bool ArchiveWidget::processProjectFile() KUrl src(item->text(0)); KUrl dest = destUrl; if (isSlideshow) { - dest = KUrl(destUrl.path(KUrl::AddTrailingSlash) + item->data(0, Qt::UserRole).toString() + "/" + src.fileName()); + dest = KUrl(destUrl.path(KUrl::AddTrailingSlash) + item->data(0, Qt::UserRole).toString() + '/' + src.fileName()); } else if (item->data(0, Qt::UserRole).isNull()) { dest.addPath(src.fileName()); @@ -537,7 +708,7 @@ bool ArchiveWidget::processProjectFile() } QDomElement mlt = m_doc.documentElement(); - QString root = mlt.attribute("root") + "/"; + QString root = mlt.attribute("root") + '/'; // Adjust global settings QString basePath; @@ -549,7 +720,7 @@ bool ArchiveWidget::processProjectFile() // process kdenlive producers QDomNodeList prods = mlt.elementsByTagName("kdenlive_producer"); - for (int i = 0; i < prods.count(); i++) { + for (int i = 0; i < prods.count(); ++i) { QDomElement e = prods.item(i).toElement(); if (e.isNull()) continue; if (e.hasAttribute("resource")) { @@ -566,7 +737,7 @@ bool ArchiveWidget::processProjectFile() // process mlt producers prods = mlt.elementsByTagName("producer"); - for (int i = 0; i < prods.count(); i++) { + for (int i = 0; i < prods.count(); ++i) { QDomElement e = prods.item(i).toElement(); if (e.isNull()) continue; QString src = EffectsList::property(e, "resource"); @@ -581,7 +752,7 @@ bool ArchiveWidget::processProjectFile() // process mlt transitions (for luma files) prods = mlt.elementsByTagName("transition"); QString attribute; - for (int i = 0; i < prods.count(); i++) { + for (int i = 0; i < prods.count(); ++i) { QDomElement e = prods.item(i).toElement(); if (e.isNull()) continue; attribute = "resource"; @@ -603,8 +774,8 @@ bool ArchiveWidget::processProjectFile() QString endString("\""); endString.append(basePath); playList.replace(startString, endString); - startString = ">" + archive_url->url().path(KUrl::RemoveTrailingSlash); - endString = ">" + basePath; + startString = '>' + archive_url->url().path(KUrl::RemoveTrailingSlash); + endString = '>' + basePath; playList.replace(startString, endString); } @@ -659,25 +830,31 @@ void ArchiveWidget::createArchive() } // Add project file - archive.addLocalFile(m_temp->fileName(), m_name + ".kdenlive"); - bool result = archive.close(); - delete m_temp; + bool result = false; + if (m_temp) { + archive.addLocalFile(m_temp->fileName(), m_name + ".kdenlive"); + result = archive.close(); + delete m_temp; + m_temp = 0; + } emit archivingFinished(result); } void ArchiveWidget::slotArchivingFinished(bool result) { if (result) { - slotDisplayMessage("dialog-ok", i18n("Project was successfully archived.")); + slotJobResult(true, i18n("Project was successfully archived.")); + buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); } else { - slotDisplayMessage("dialog-close", i18n("There was an error processing project file")); + slotJobResult(false, i18n("There was an error processing project file")); } progressBar->setValue(100); buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Archive")); archive_url->setEnabled(true); + proxy_only->setEnabled(true); compressed_archive->setEnabled(true); - for (int i = 0; i < files_list->topLevelItemCount(); i++) { + 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); @@ -700,10 +877,6 @@ void ArchiveWidget::slotStartExtracting() 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(); } @@ -730,7 +903,7 @@ void ArchiveWidget::doExtracting() emit extractingFinished(); } -QString ArchiveWidget::extractedProjectFile() +QString ArchiveWidget::extractedProjectFile() const { return archive_url->url().path(KUrl::AddTrailingSlash) + m_projectName; } @@ -738,7 +911,6 @@ QString ArchiveWidget::extractedProjectFile() void ArchiveWidget::slotExtractingFinished() { m_progressTimer->stop(); - delete m_progressTimer; // Process project file QFile file(extractedProjectFile()); bool error = false; @@ -746,7 +918,7 @@ void ArchiveWidget::slotExtractingFinished() error = true; } else { - QString playList = file.readAll(); + QString playList = QString::fromUtf8(file.readAll()); file.close(); if (playList.isEmpty()) { error = true; @@ -772,3 +944,76 @@ void ArchiveWidget::slotExtractingFinished() } else accept(); } + +void ArchiveWidget::slotProxyOnly(int onlyProxy) +{ + m_requestedSize = 0; + if (onlyProxy == Qt::Checked) { + // Archive proxy clips + QStringList proxyIdList; + QTreeWidgetItem *parentItem = NULL; + + // Build list of existing proxy ids + for (int i = 0; i < files_list->topLevelItemCount(); ++i) { + parentItem = files_list->topLevelItem(i); + if (parentItem->data(0, Qt::UserRole).toString() == "proxy") break; + } + if (!parentItem) return; + int items = parentItem->childCount(); + for (int j = 0; j < items; j++) { + proxyIdList << parentItem->child(j)->data(0, Qt::UserRole + 2).toString(); + } + + // Parse all items to disable original clips for existing proxies + for (int i = 0; i < proxyIdList.count(); ++i) { + QString id = proxyIdList.at(i); + if (id.isEmpty()) continue; + for (int j = 0; j < files_list->topLevelItemCount(); j++) { + parentItem = files_list->topLevelItem(j); + if (parentItem->data(0, Qt::UserRole).toString() == "proxy") continue; + items = parentItem->childCount(); + for (int k = 0; k < items; k++) { + if (parentItem->child(k)->data(0, Qt::UserRole + 2).toString() == id) { + // This item has a proxy, do not archive it + parentItem->child(k)->setFlags(Qt::ItemIsSelectable); + break; + } + } + } + } + } + else { + // Archive all clips + for (int i = 0; i < files_list->topLevelItemCount(); ++i) { + QTreeWidgetItem *parentItem = files_list->topLevelItem(i); + int items = parentItem->childCount(); + for (int j = 0; j < items; j++) { + parentItem->child(j)->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + } + } + } + + // Calculate requested size + int total = 0; + for (int i = 0; i < files_list->topLevelItemCount(); ++i) { + QTreeWidgetItem *parentItem = files_list->topLevelItem(i); + int items = parentItem->childCount(); + int itemsCount = 0; + bool isSlideshow = parentItem->data(0, Qt::UserRole).toString() == "slideshows"; + + for (int j = 0; j < items; j++) { + if (!parentItem->child(j)->isDisabled()) { + m_requestedSize += parentItem->child(j)->data(0, Qt::UserRole + 3).toInt(); + if (isSlideshow) total += parentItem->child(j)->data(0, Qt::UserRole + 1).toStringList().count(); + else total ++; + itemsCount ++; + } + } + parentItem->setText(0, parentItem->text(0).section('(', 0, 0) + i18np("(%1 item)", "(%1 items)", itemsCount)); + } + project_files->setText(i18np("%1 file to archive, requires %2", "%1 files to archive, requires %2", total, KIO::convertSize(m_requestedSize))); + slotCheckSpace(); +} + + +#include "archivewidget.moc"