X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Farchivewidget.cpp;h=ef31b85bd32faba2b44cad160cc3c367a7a79792;hb=7f1da508760806124e9ef3c270e838ab0b347e20;hp=1641e6d3765193361be5d07af53ca0324a060658;hpb=86e749b3719d01c440202540c3d3bb19a2b9bfee;p=kdenlive diff --git a/src/archivewidget.cpp b/src/archivewidget.cpp index 1641e6d3..ef31b85b 100644 --- a/src/archivewidget.cpp +++ b/src/archivewidget.cpp @@ -32,6 +32,9 @@ #include #include #include +#if KDE_IS_VERSION(4,7,0) +#include +#endif #include #include @@ -46,7 +49,8 @@ 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,54 +104,79 @@ 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++) { 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 @@ -166,13 +200,13 @@ ArchiveWidget::ArchiveWidget(QString projectName, QDomDocument doc, QList 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")); connect(buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(slotStartArchiving())); buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); - + slotCheckSpace(); } @@ -183,32 +217,13 @@ ArchiveWidget::ArchiveWidget(const KUrl &url, QWidget * parent): m_extractUrl(url) { //setAttribute(Qt::WA_DeleteOnClose); - m_extractArchive = new KTar(url.path()); - m_extractArchive->open( QIODevice::ReadOnly ); - - // 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) { - KMessageBox::sorry(kapp->activeWindow(), i18n("%1 is not an archived Kdenlive project", url.path(), i18n("Cannot open file"))); - m_extractArchive->close(); - 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())); + connect(this, SIGNAL(showMessage(const QString &, const QString &)), this, SLOT(slotDisplayMessage(const QString &, const QString &))); compressed_archive->setHidden(true); + proxy_only->setHidden(true); project_files->setHidden(true); files_list->setHidden(true); label->setText(i18n("Extract to")); @@ -216,6 +231,9 @@ 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(true); + adjustSize(); + m_archiveThread = QtConcurrent::run(this, &ArchiveWidget::openArchiveForExtraction); } @@ -224,6 +242,55 @@ 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::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...")); + 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 ) { if (closeAccepted()) QDialog::done(r); @@ -274,11 +341,14 @@ void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QStringList items dir.setNameFilters(filters); QFileInfoList resultList = dir.entryInfoList(QDir::Files); QStringList slideImages; + qint64 totalSize = 0; for (int i = 0; i < resultList.count(); i++) { - m_requestedSize += resultList.at(i).size(); + 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) @@ -291,13 +361,16 @@ void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, QStringList items QStringList slideImages; QString directory = dir.absolutePath(); if (!directory.endsWith('/')) directory.append('/'); + qint64 totalSize = 0; 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)) { @@ -312,26 +385,119 @@ 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; } } } +void ArchiveWidget::generateItems(QTreeWidgetItem *parentItem, 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; + 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; + 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; + qint64 totalSize = 0; + QString directory = dir.absolutePath(); + if (!directory.endsWith('/')) directory.append('/'); + 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; + } + ++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); - 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))); } } @@ -352,10 +518,10 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass) 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); + proxy_only->setEnabled(false); compressed_archive->setEnabled(false); } KUrl::List files; @@ -363,28 +529,36 @@ bool ArchiveWidget::slotStartArchiving(bool firstPass) QString destPath; QTreeWidgetItem *parentItem; bool isSlideshow = false; + 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); + 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++) { @@ -409,10 +583,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 + if (isArchive) slotArchivingFinished(NULL, true); + return true; + } + if (destPath.isEmpty()) { if (m_duplicateFiles.isEmpty()) return false; QMapIterator i(m_duplicateFiles); @@ -451,10 +632,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; } @@ -462,23 +643,21 @@ void ArchiveWidget::slotArchivingFinished(KJob *job) // Archiving finished progressBar->setValue(100); if (processProjectFile()) { - icon_info->setPixmap(KIcon("dialog-ok").pixmap(16, 16)); - text_info->setText(i18n("Project was successfully archived.")); + slotJobResult(true, 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")); + slotJobResult(false, 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())); + 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++) { files_list->topLevelItem(i)->setDisabled(false); @@ -531,7 +710,7 @@ bool ArchiveWidget::processProjectFile() if (isArchive) basePath = "$CURRENTPATH"; else basePath = archive_url->url().path(KUrl::RemoveTrailingSlash); mlt.setAttribute("root", basePath); - QDomElement project = mlt.elementsByTagName("kdenlivedoc").at(0).toElement(); + QDomElement project = mlt.firstChildElement("kdenlivedoc"); project.setAttribute("projectfolder", basePath); // process kdenlive producers @@ -655,16 +834,16 @@ void ArchiveWidget::createArchive() void ArchiveWidget::slotArchivingFinished(bool result) { if (result) { - icon_info->setPixmap(KIcon("dialog-ok").pixmap(16, 16)); - text_info->setText(i18n("Project was successfully archived.")); + slotJobResult(true, i18n("Project was successfully archived.")); + buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); } else { - icon_info->setPixmap(KIcon("dialog-close").pixmap(16, 16)); - text_info->setText(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++) { files_list->topLevelItem(i)->setDisabled(false); @@ -687,8 +866,7 @@ void ArchiveWidget::slotStartExtracting() QFileInfo f(m_extractUrl.path()); m_requestedSize = f.size(); KIO::NetAccess::mkdir(archive_url->url().path(KUrl::RemoveTrailingSlash), this); - icon_info->setPixmap(KIcon("system-run").pixmap(16, 16)); - text_info->setText(i18n("Extracting...")); + slotDisplayMessage("system-run", i18n("Extracting...")); buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Abort")); m_progressTimer = new QTimer; m_progressTimer->setInterval(800); @@ -762,3 +940,74 @@ 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(); +} +