1 // case - file manager for N900
2 // Copyright (C) 2010 Lukas Hrazky <lukkash@email.cz>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "fileoperator.h"
21 #include <QMessageBox>
22 #include <QVBoxLayout>
23 #include <QMaemo5InformationBox>
29 FileOperator::FileOperator(QWidget *parent) : QWidget(parent) {
30 QVBoxLayout *layout = new QVBoxLayout;
31 layout->setContentsMargins(0, 0, 0, 0);
32 layout->setSpacing(1);
33 topRow = new QHBoxLayout;
34 topRow->setContentsMargins(0, 0, 0, 0);
35 topRow->setSpacing(1);
36 layout->addLayout(topRow);
37 bottomRow = new QHBoxLayout;
38 bottomRow->setContentsMargins(0, 0, 0, 0);
39 bottomRow->setSpacing(1);
40 layout->addLayout(bottomRow);
43 qRegisterMetaType<QFileInfo>("QFileInfo");
44 qRegisterMetaType<time_t>("time_t");
46 loadOperationIcons(palette(), "delete_small", deleteIcon, inverseDeleteIcon);
47 loadOperationIcons(palette(), "copy_small", copyIcon, inverseCopyIcon);
48 loadOperationIcons(palette(), "move_small", moveIcon, inverseMoveIcon);
52 void FileOperator::deleteFiles(const QFileInfoList &files) {
53 if (checkMaxOpsNumber()) return;
56 if (files.size() == 1) {
57 title = tr("Delete file");
58 desc = tr("Are you sure you want to delete %1?")
59 .arg(shortenPath(files[0].absoluteFilePath()));
61 title = tr("Delete files");
62 desc = tr("You are about to delete %1 files. Are you sure you want to continue?").arg(files.size());
65 int confirm = QMessageBox::warning(
73 if(confirm == QMessageBox::Yes) {
74 ProgressBar *bar = new ProgressBar(deleteIcon, inverseDeleteIcon);
75 initOperation(new DeleteThread(files), bar);
80 void FileOperator::copyFiles(const QFileInfoList &files, QDir &destination) {
81 if (checkMaxOpsNumber()) return;
84 if (files.size() == 1) {
85 title = tr("Copy file");
86 desc = tr("Are you sure you want to copy %1 to %2?")
87 .arg(shortenPath(files[0].absoluteFilePath()))
88 .arg(shortenPath(destination.absolutePath()));
90 title = tr("Copy files");
91 desc = tr("You are about to copy %1 files to %2. Are you sure you want to continue?")
92 .arg(files.size()).arg(shortenPath(destination.absolutePath()));
95 int confirm = QMessageBox::warning(
103 if(confirm == QMessageBox::Yes) {
104 ProgressBar *bar = new ProgressBar(copyIcon, inverseCopyIcon);
105 bar->setBottomTexts(shortenPath(files[0].absolutePath()), shortenPath(destination.absolutePath()));
106 initOperation(new CopyThread(files, destination), bar);
111 void FileOperator::moveFiles(const QFileInfoList &files, QDir &destination) {
112 if (checkMaxOpsNumber()) return;
114 // for move we don't wanna move to the same dir
115 if (files[0].absolutePath() == destination.absolutePath()) return;
118 if (files.size() == 1) {
119 title = tr("Move file");
120 desc = tr("Are you sure you want to move %1 to %2?")
121 .arg(shortenPath(files[0].absoluteFilePath()))
122 .arg(shortenPath(destination.absolutePath()));
124 title = tr("Move files");
125 desc = tr("You are about to move %1 files to %2. Are you sure you want to continue?")
126 .arg(files.size()).arg(shortenPath(destination.absolutePath()));
129 int confirm = QMessageBox::warning(
137 if(confirm == QMessageBox::Yes) {
138 ProgressBar *bar = new ProgressBar(moveIcon, inverseMoveIcon);
139 bar->setBottomTexts(shortenPath(files[0].absolutePath()), shortenPath(destination.absolutePath()));
140 initOperation(new MoveThread(files, destination), bar);
145 void FileOperator::showErrorPrompt(OperationThread* op,
146 const QString &message,
147 const QString &fileName,
151 QAbstractButton *cancelButton = msgBox.addButton(QMessageBox::Cancel);
152 QAbstractButton *abortButton = msgBox.addButton(tr("Abort"), QMessageBox::DestructiveRole);
153 QAbstractButton *retryButton = msgBox.addButton(QMessageBox::Retry);
154 QAbstractButton *ignoreButton = msgBox.addButton(QMessageBox::Ignore);
155 QAbstractButton *ignoreAllButton = msgBox.addButton(tr("Ignore All"), QMessageBox::AcceptRole);
156 msgBox.setText(message.arg(shortenPath(fileName)));
160 if (msgBox.clickedButton() == cancelButton) {
162 op->setResponse(OperationThread::RETRY);
163 } else if (msgBox.clickedButton() == abortButton) {
164 op->setResponse(OperationThread::ABORT);
165 } else if (msgBox.clickedButton() == retryButton) {
166 op->setResponse(OperationThread::RETRY);
167 } else if (msgBox.clickedButton() == ignoreButton) {
168 op->setResponse(OperationThread::IGNORE);
169 } else if (msgBox.clickedButton() == ignoreAllButton) {
170 op->setResponse(OperationThread::IGNORE, true, err);
175 void FileOperator::showOverwritePrompt(
177 const QString &fileName,
178 const bool dirOverDir)
181 QAbstractButton *yesButton = msgBox.addButtonFirst(QDialogButtonBox::Yes);
182 QAbstractButton *yesToAllButton = msgBox.addButtonFirst(QDialogButtonBox::YesToAll);
183 QAbstractButton *noButton = msgBox.addButtonSecond(QDialogButtonBox::No);
184 QAbstractButton *noToAllButton = msgBox.addButtonSecond(QDialogButtonBox::NoToAll);
185 QAbstractButton *abortButton = msgBox.addButtonSecond(tr("Abort"), QDialogButtonBox::DestructiveRole);
186 QAbstractButton *newNameButton = msgBox.addButtonFirst(tr("New Name"), QDialogButtonBox::AcceptRole);
187 QAbstractButton *askButton = 0;
188 QAbstractButton *skipDirButton = 0;
191 msgBox.setText(tr("Directory %1 already exists. Overwrite the files inside?")
192 .arg(shortenPath(fileName)));
193 askButton = msgBox.addButtonFirst(tr("Ask"), QDialogButtonBox::AcceptRole);
194 skipDirButton = msgBox.addButtonSecond(tr("Skip"), QDialogButtonBox::NoRole);
196 msgBox.setText(tr("File %1 already exists. Overwrite?").arg(shortenPath(fileName)));
201 if (msgBox.clickedButton == 0) {
203 op->setResponse(OperationThread::NONE);
204 } else if (msgBox.clickedButton == abortButton) {
205 op->setResponse(OperationThread::ABORT);
206 } else if (msgBox.clickedButton == yesButton) {
207 op->setResponse(OperationThread::OVERWRITE);
208 } else if (msgBox.clickedButton == yesToAllButton) {
209 op->setResponse(OperationThread::OVERWRITE, true);
210 } else if (msgBox.clickedButton == noButton) {
211 op->setResponse(OperationThread::KEEP);
212 } else if (msgBox.clickedButton == noToAllButton) {
213 op->setResponse(OperationThread::KEEP, true);
214 } else if (msgBox.clickedButton == askButton) {
215 op->setResponse(OperationThread::ASK);
216 } else if (msgBox.clickedButton == newNameButton) {
217 op->setResponse(OperationThread::NONE);
218 } else if (msgBox.clickedButton == skipDirButton) {
219 op->setResponse(OperationThread::SKIP_DIR);
224 void FileOperator::showInputFilenamePrompt(OperationThread* op,
225 const QFileInfo &file,
229 QString prompt, error;
232 prompt = tr("Enter the new directory name.");
234 prompt = tr("Enter the new file name.");
237 op->newNameFromDialog = "";
238 QString text = file.fileName();
241 text = QInputDialog::getText(this, QString(), prompt + error, QLineEdit::Normal, text, &ok);
246 if (text.contains(QRegExp("[\"*/:<>?\\\\|]"))) {
247 error = "<small><br/><font color = 'red'>" +
248 tr("The name cannot contain any of the following characters: ") +
249 "\"*/:<>?\\|</font></small>";
250 } else if (ok && !text.isEmpty()) {
251 QFileInfo info(file.path() + "/" + text);
252 op->newNameFromDialog = info.absoluteFilePath();
261 void FileOperator::remove(OperationThread* op) {
263 ProgressBar *bar = get(op);
264 removeBarFromLayout(bar);
265 opList.removeAll(qMakePair(op, bar));
271 void FileOperator::togglePauseOperation(ProgressBar* bar) {
272 OperationThread *op = get(bar);
282 void FileOperator::abortOperation(ProgressBar* bar) {
283 OperationThread *op = get(bar);
285 int confirm = QMessageBox::warning(
287 tr("Abort operation"),
288 tr("Are you sure you want to abort the operation?"),
293 if(confirm == QMessageBox::Yes) {
301 void FileOperator::initOperation(OperationThread *thread, ProgressBar *bar) {
303 opList.append(qMakePair(thread, bar));
305 connect(thread, SIGNAL(showErrorPrompt(OperationThread*, const QString&, const QString&, const int)),
306 this, SLOT(showErrorPrompt(OperationThread*, const QString&, const QString&, const int)));
307 connect(thread, SIGNAL(showOverwritePrompt(OperationThread*, const QString&, bool)),
308 this, SLOT(showOverwritePrompt(OperationThread*, const QString&, bool)));
309 connect(thread, SIGNAL(showInputFilenamePrompt(OperationThread*, const QFileInfo&, bool)),
310 this, SLOT(showInputFilenamePrompt(OperationThread*, const QFileInfo&, bool)));
311 connect(thread, SIGNAL(finished(OperationThread*)),
312 this, SLOT(remove(OperationThread*)));
314 connect(thread, SIGNAL(totalSizeChanged(int)), bar, SLOT(setMaximum(int)));
315 connect(thread, SIGNAL(progressUpdate(int)), bar, SLOT(updateProgress(int)));
316 connect(thread, SIGNAL(fileNameUpdated(QString)), bar, SLOT(updateMainText(QString)));
317 connect(thread, SIGNAL(operationStarted(time_t)), bar, SLOT(setStartTime(time_t)));
318 connect(thread, SIGNAL(operationPaused()), bar, SLOT(pause()));
319 connect(thread, SIGNAL(operationResumed(time_t)), bar, SLOT(resume(time_t)));
320 connect(thread, SIGNAL(removeAfterCopy()), bar, SLOT(showRemoveNotice()));
322 connect(bar, SIGNAL(togglePauseOperation(ProgressBar*)), this, SLOT(togglePauseOperation(ProgressBar*)));
323 connect(bar, SIGNAL(abortOperation(ProgressBar*)), this, SLOT(abortOperation(ProgressBar*)));
325 thread->start(QThread::LowestPriority);
329 ProgressBar *FileOperator::get(OperationThread *op) const {
330 for (OperationList::const_iterator it = opList.begin(); it != opList.end(); ++it) {
331 if (it->first == op) return it->second;
337 OperationThread *FileOperator::get(ProgressBar *bar) const {
338 for (OperationList::const_iterator it = opList.begin(); it != opList.end(); ++it) {
339 if (it->second == bar) return it->first;
345 void FileOperator::addBarToLayout(ProgressBar *bar) {
346 switch (opList.size()) {
350 topRow->addWidget(bar);
353 topRow->addItem(bottomRow->takeAt(0));
354 bottomRow->addWidget(bar);
357 bottomRow->addItem(topRow->takeAt(2));
359 bottomRow->addWidget(bar);
364 void FileOperator::removeBarFromLayout(ProgressBar *bar) {
365 int index = topRow->indexOf(bar);
367 topRow->takeAt(index);
368 switch (opList.size()) {
370 topRow->addItem(bottomRow->takeAt(0));
372 topRow->addItem(bottomRow->takeAt(0));
376 bottomRow->removeWidget(bar);
377 switch (opList.size()) {
379 topRow->addItem(bottomRow->takeAt(0));
382 bottomRow->insertWidget(0, topRow->takeAt(2)->widget());
388 bool FileOperator::checkMaxOpsNumber() {
389 if (opList.size() == 6) {
390 QMaemo5InformationBox::information(this, tr("The maximum number of file operations is %1.").arg(6));