• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeutils API Reference
  • KDE Home
  • Contact Us
 

ark

  • sources
  • kde-4.14
  • kdeutils
  • ark
  • app
batchextract.cpp
Go to the documentation of this file.
1 /*
2  * ark -- archiver for the KDE project
3  *
4  * Copyright (C) 2008 Harald Hvaal <haraldhv@stud.ntnu.no>
5  * Copyright (C) 2009-2010 Raphael Kubo da Costa <rakuco@FreeBSD.org>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "batchextract.h"
30 
31 #include "kerfuffle/archive.h"
32 #include "kerfuffle/extractiondialog.h"
33 #include "kerfuffle/jobs.h"
34 #include "kerfuffle/queries.h"
35 
36 #include <KDebug>
37 #include <KGlobal>
38 #include <KLocale>
39 #include <KMessageBox>
40 #include <KRun>
41 #include <KIO/RenameDialog>
42 #include <kwidgetjobtracker.h>
43 
44 #include <QDir>
45 #include <QFileInfo>
46 #include <QTimer>
47 #include <QWeakPointer>
48 
49 BatchExtract::BatchExtract()
50  : KCompositeJob(0),
51  m_autoSubfolder(false),
52  m_preservePaths(true),
53  m_openDestinationAfterExtraction(false)
54 {
55  setCapabilities(KJob::Killable);
56 
57  connect(this, SIGNAL(result(KJob*)), SLOT(showFailedFiles()));
58 }
59 
60 BatchExtract::~BatchExtract()
61 {
62  if (!m_inputs.isEmpty()) {
63  KIO::getJobTracker()->unregisterJob(this);
64  }
65 }
66 
67 void BatchExtract::addExtraction(Kerfuffle::Archive* archive)
68 {
69  QString destination = destinationFolder();
70 
71  if ((autoSubfolder()) && (!archive->isSingleFolderArchive())) {
72  const QDir d(destination);
73  QString subfolderName = archive->subfolderName();
74 
75  if (d.exists(subfolderName)) {
76  subfolderName = KIO::RenameDialog::suggestName(destination, subfolderName);
77  }
78 
79  d.mkdir(subfolderName);
80 
81  destination += QLatin1Char( '/' ) + subfolderName;
82  }
83 
84  Kerfuffle::ExtractionOptions options;
85  options[QLatin1String( "PreservePaths" )] = preservePaths();
86 
87  Kerfuffle::ExtractJob *job = archive->copyFiles(QVariantList(), destination, options);
88 
89  kDebug() << QString(QLatin1String( "Registering job from archive %1, to %2, preservePaths %3" )).arg(archive->fileName()).arg(destination).arg(preservePaths());
90 
91  addSubjob(job);
92 
93  m_fileNames[job] = qMakePair(archive->fileName(), destination);
94 
95  connect(job, SIGNAL(percent(KJob*,ulong)),
96  this, SLOT(forwardProgress(KJob*,ulong)));
97  connect(job, SIGNAL(userQuery(Kerfuffle::Query*)),
98  this, SLOT(slotUserQuery(Kerfuffle::Query*)));
99 }
100 
101 void BatchExtract::slotUserQuery(Kerfuffle::Query *query)
102 {
103  query->execute();
104 }
105 
106 bool BatchExtract::autoSubfolder() const
107 {
108  return m_autoSubfolder;
109 }
110 
111 void BatchExtract::setAutoSubfolder(bool value)
112 {
113  m_autoSubfolder = value;
114 }
115 
116 void BatchExtract::start()
117 {
118  QTimer::singleShot(0, this, SLOT(slotStartJob()));
119 }
120 
121 void BatchExtract::slotStartJob()
122 {
123  // If none of the archives could be loaded, there is no subjob to run
124  if (m_inputs.isEmpty()) {
125  emitResult();
126  return;
127  }
128 
129  foreach(Kerfuffle::Archive *archive, m_inputs) {
130  addExtraction(archive);
131  }
132 
133  KIO::getJobTracker()->registerJob(this);
134 
135  emit description(this,
136  i18n("Extracting file..."),
137  qMakePair(i18n("Source archive"), m_fileNames.value(subjobs().at(0)).first),
138  qMakePair(i18n("Destination"), m_fileNames.value(subjobs().at(0)).second)
139  );
140 
141  m_initialJobCount = subjobs().size();
142 
143  kDebug() << "Starting first job";
144 
145  subjobs().at(0)->start();
146 }
147 
148 void BatchExtract::showFailedFiles()
149 {
150  if (!m_failedFiles.isEmpty()) {
151  KMessageBox::informationList(0, i18n("The following files could not be extracted:"), m_failedFiles);
152  }
153 }
154 
155 void BatchExtract::slotResult(KJob *job)
156 {
157  kDebug();
158 
159  // TODO: The user must be informed about which file caused the error, and that the other files
160  // in the queue will not be extracted.
161  if (job->error()) {
162  kDebug() << "There was en error, " << job->errorText();
163 
164  setErrorText(job->errorText());
165  setError(job->error());
166 
167  removeSubjob(job);
168 
169  KMessageBox::error(NULL, job->errorText().isEmpty() ?
170  i18n("There was an error during extraction.") : job->errorText()
171  );
172 
173  emitResult();
174 
175  return;
176  } else {
177  removeSubjob(job);
178  }
179 
180  if (!hasSubjobs()) {
181  if (openDestinationAfterExtraction()) {
182  KUrl destination(destinationFolder());
183  destination.cleanPath();
184  KRun::runUrl(destination, QLatin1String( "inode/directory" ), 0);
185  }
186 
187  kDebug() << "Finished, emitting the result";
188  emitResult();
189  } else {
190  kDebug() << "Starting the next job";
191  emit description(this,
192  i18n("Extracting file..."),
193  qMakePair(i18n("Source archive"), m_fileNames.value(subjobs().at(0)).first),
194  qMakePair(i18n("Destination"), m_fileNames.value(subjobs().at(0)).second)
195  );
196  subjobs().at(0)->start();
197  }
198 }
199 
200 void BatchExtract::forwardProgress(KJob *job, unsigned long percent)
201 {
202  Q_UNUSED(job)
203  int jobPart = 100 / m_initialJobCount;
204  setPercent(jobPart *(m_initialJobCount - subjobs().size()) + percent / m_initialJobCount);
205 }
206 
207 bool BatchExtract::addInput(const KUrl& url)
208 {
209  Kerfuffle::Archive *archive = Kerfuffle::Archive::create(url.pathOrUrl(), this);
210 
211  if ((archive == NULL) || (!QFileInfo(url.pathOrUrl()).exists())) {
212  m_failedFiles.append(url.fileName());
213  return false;
214  }
215 
216  m_inputs.append(archive);
217 
218  return true;
219 }
220 
221 bool BatchExtract::openDestinationAfterExtraction() const
222 {
223  return m_openDestinationAfterExtraction;
224 }
225 
226 bool BatchExtract::preservePaths() const
227 {
228  return m_preservePaths;
229 }
230 
231 QString BatchExtract::destinationFolder() const
232 {
233  if (m_destinationFolder.isEmpty()) {
234  return QDir::currentPath();
235  } else {
236  return m_destinationFolder;
237  }
238 }
239 
240 void BatchExtract::setDestinationFolder(const QString& folder)
241 {
242  if (QFileInfo(folder).isDir()) {
243  m_destinationFolder = folder;
244  }
245 }
246 
247 void BatchExtract::setOpenDestinationAfterExtraction(bool value)
248 {
249  m_openDestinationAfterExtraction = value;
250 }
251 
252 void BatchExtract::setPreservePaths(bool value)
253 {
254  m_preservePaths = value;
255 }
256 
257 bool BatchExtract::showExtractDialog()
258 {
259  QWeakPointer<Kerfuffle::ExtractionDialog> dialog =
260  new Kerfuffle::ExtractionDialog;
261 
262  if (m_inputs.size() > 1) {
263  dialog.data()->batchModeOption();
264  }
265 
266  dialog.data()->setAutoSubfolder(autoSubfolder());
267  dialog.data()->setCurrentUrl(destinationFolder());
268  dialog.data()->setPreservePaths(preservePaths());
269 
270  if (m_inputs.size() == 1) {
271  if (m_inputs.at(0)->isSingleFolderArchive()) {
272  dialog.data()->setSingleFolderArchive(true);
273  }
274  dialog.data()->setSubfolder(m_inputs.at(0)->subfolderName());
275  }
276 
277  if (!dialog.data()->exec()) {
278  delete dialog.data();
279  return false;
280  }
281 
282  setAutoSubfolder(dialog.data()->autoSubfolders());
283  setDestinationFolder(dialog.data()->destinationDirectory().pathOrUrl());
284  setOpenDestinationAfterExtraction(dialog.data()->openDestinationAfterExtraction());
285  setPreservePaths(dialog.data()->preservePaths());
286 
287  delete dialog.data();
288 
289  return true;
290 }
291 
292 #include <batchextract.moc>
BatchExtract::~BatchExtract
virtual ~BatchExtract()
Destroys a BatchExtract object.
Definition: batchextract.cpp:60
BatchExtract::setOpenDestinationAfterExtraction
void setOpenDestinationAfterExtraction(bool value)
Whether to open the destination folder after all archives are extracted.
Definition: batchextract.cpp:247
Kerfuffle::Query
Definition: queries.h:44
Kerfuffle::Archive::subfolderName
QString subfolderName()
Definition: archive.cpp:268
QList::at
const T & at(int i) const
BatchExtract::addExtraction
void addExtraction(Kerfuffle::Archive *archive)
Creates an ExtractJob for the given archive and puts it on the queue.
Definition: batchextract.cpp:67
BatchExtract::addInput
bool addInput(const KUrl &url)
Adds a file to the list of files that will be extracted.
Definition: batchextract.cpp:207
Kerfuffle::ExtractionDialog
Definition: extractiondialog.h:40
QWeakPointer::data
T * data() const
archive.h
queries.h
QDir::currentPath
QString currentPath()
BatchExtract::setAutoSubfolder
void setAutoSubfolder(bool value)
Set whether a folder should be created when necessary so the archive is extracted to it...
Definition: batchextract.cpp:111
Kerfuffle::Archive::create
KJob * create()
Definition: archive.cpp:145
BatchExtract::BatchExtract
BatchExtract()
Creates a new BatchExtract object.
Definition: batchextract.cpp:49
QList::size
int size() const
QDir::exists
bool exists() const
QList::append
void append(const T &value)
Kerfuffle::Archive::isSingleFolderArchive
bool isSingleFolderArchive()
Definition: archive.cpp:256
QHash
BatchExtract::destinationFolder
QString destinationFolder() const
Returns the destination directory where the archives will be extracted to.
Definition: batchextract.cpp:231
BatchExtract::preservePaths
bool preservePaths() const
Whether all files should be extracted to the same directory, even if they're in different directories...
Definition: batchextract.cpp:226
QList::isEmpty
bool isEmpty() const
QString::isEmpty
bool isEmpty() const
QString
Kerfuffle::Archive::fileName
QString fileName() const
Definition: archive.cpp:194
Kerfuffle::Archive
Definition: archive.h:88
extractiondialog.h
QFileInfo
BatchExtract::openDestinationAfterExtraction
bool openDestinationAfterExtraction() const
Returns whether the destination folder should be open after all archives are extracted.
Definition: batchextract.cpp:221
batchextract.h
QLatin1Char
Kerfuffle::ExtractJob
Definition: jobs.h:118
BatchExtract::setPreservePaths
void setPreservePaths(bool value)
Sets whether paths should be preserved during extraction.
Definition: batchextract.cpp:252
QDir
jobs.h
QLatin1String
QDir::mkdir
bool mkdir(const QString &dirName) const
Kerfuffle::Archive::copyFiles
ExtractJob * copyFiles(const QList< QVariant > &files, const QString &destinationDir, ExtractionOptions options=ExtractionOptions())
Definition: archive.cpp:183
BatchExtract::start
void start()
A wrapper that calls slotStartJob() when the event loop has started.
Definition: batchextract.cpp:116
BatchExtract::setDestinationFolder
void setDestinationFolder(const QString &folder)
Sets the directory the archives will be extracted to.
Definition: batchextract.cpp:240
BatchExtract::autoSubfolder
bool autoSubfolder() const
Whether to automatically create a folder inside the destination directory if the archive has more tha...
Definition: batchextract.cpp:106
QWeakPointer
BatchExtract::showExtractDialog
bool showExtractDialog()
Shows the extract options dialog before extracting the files.
Definition: batchextract.cpp:257
BatchExtract
This class schedules the extraction of all given compressed archives.
Definition: batchextract.h:54
KCompositeJob
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
Kerfuffle::Query::execute
virtual void execute()=0
Execute the response.
KJob
QMap::value
const T value(const Key &key) const
QTimer::singleShot
singleShot
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:42:37 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

ark

Skip menu "ark"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdeutils API Reference

Skip menu "kdeutils API Reference"
  • ark
  • filelight
  • kcalc
  • kcharselect
  • kdf
  • kfloppy
  • kgpg
  • ktimer
  • kwallet
  • sweeper

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal