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 <QHBoxLayout>
28 FileOperator::FileOperator(QWidget *parent) : QWidget(parent) {
29 QHBoxLayout *layout = new QHBoxLayout;
30 layout->setContentsMargins(0, 0, 0, 0);
31 layout->setSpacing(1);
34 qRegisterMetaType<QFileInfo>("QFileInfo");
35 qRegisterMetaType<time_t>("time_t");
37 loadOperationIcons(palette(), "delete_small", deleteIcon, inverseDeleteIcon);
38 loadOperationIcons(palette(), "copy_small", copyIcon, inverseCopyIcon);
39 loadOperationIcons(palette(), "move_small", moveIcon, inverseMoveIcon);
43 void FileOperator::deleteFiles(const QFileInfoList &files) {
45 if (files.size() == 1) {
46 title = tr("Delete file");
47 desc = tr("Are you sure you want to delete %1?")
48 .arg(shortenPath(files[0].absoluteFilePath()));
50 title = tr("Delete files");
51 desc = tr("You are about to delete %1 files. Are you sure you want to continue?").arg(files.size());
54 int confirm = QMessageBox::warning(
62 if(confirm == QMessageBox::Yes) {
63 ProgressBar *bar = new ProgressBar(deleteIcon, inverseDeleteIcon);
64 initOperation(new DeleteThread(files), bar);
69 void FileOperator::copyFiles(const QFileInfoList &files, QDir &destination) {
71 if (files.size() == 1) {
72 title = tr("Copy file");
73 desc = tr("Are you sure you want to copy %1 to %2?")
74 .arg(shortenPath(files[0].absoluteFilePath()))
75 .arg(shortenPath(destination.absolutePath()));
77 title = tr("Copy files");
78 desc = tr("You are about to copy %1 files to %2. Are you sure you want to continue?")
79 .arg(files.size()).arg(shortenPath(destination.absolutePath()));
82 int confirm = QMessageBox::warning(
90 if(confirm == QMessageBox::Yes) {
91 ProgressBar *bar = new ProgressBar(copyIcon, inverseCopyIcon);
92 bar->setBottomTexts(shortenPath(files[0].absolutePath()), shortenPath(destination.absolutePath()));
93 initOperation(new CopyThread(files, destination), bar);
98 void FileOperator::moveFiles(const QFileInfoList &files, QDir &destination) {
99 // for move we don't wanna move to the same dir
100 if (files[0].absolutePath() == destination.absolutePath()) return;
103 if (files.size() == 1) {
104 title = tr("Move file");
105 desc = tr("Are you sure you want to move %1 to %2?")
106 .arg(shortenPath(files[0].absoluteFilePath()))
107 .arg(shortenPath(destination.absolutePath()));
109 title = tr("Move files");
110 desc = tr("You are about to move %1 files to %2. Are you sure you want to continue?")
111 .arg(files.size()).arg(shortenPath(destination.absolutePath()));
114 int confirm = QMessageBox::warning(
122 if(confirm == QMessageBox::Yes) {
123 ProgressBar *bar = new ProgressBar(moveIcon, inverseMoveIcon);
124 bar->setBottomTexts(shortenPath(files[0].absolutePath()), shortenPath(destination.absolutePath()));
125 initOperation(new MoveThread(files, destination), bar);
130 void FileOperator::showErrorPrompt(OperationThread* op,
131 const QString &message,
132 const QString &fileName,
136 QAbstractButton *cancelButton = msgBox.addButton(QMessageBox::Cancel);
137 QAbstractButton *abortButton = msgBox.addButton(tr("Abort"), QMessageBox::DestructiveRole);
138 QAbstractButton *retryButton = msgBox.addButton(QMessageBox::Retry);
139 QAbstractButton *ignoreButton = msgBox.addButton(QMessageBox::Ignore);
140 QAbstractButton *ignoreAllButton = msgBox.addButton(tr("Ignore All"), QMessageBox::AcceptRole);
141 msgBox.setText(message.arg(shortenPath(fileName)));
145 if (msgBox.clickedButton() == cancelButton) {
147 op->setResponse(OperationThread::RETRY);
148 } else if (msgBox.clickedButton() == abortButton) {
149 op->setResponse(OperationThread::ABORT);
150 } else if (msgBox.clickedButton() == retryButton) {
151 op->setResponse(OperationThread::RETRY);
152 } else if (msgBox.clickedButton() == ignoreButton) {
153 op->setResponse(OperationThread::IGNORE);
154 } else if (msgBox.clickedButton() == ignoreAllButton) {
155 op->setResponse(OperationThread::IGNORE, true, err);
160 void FileOperator::showOverwritePrompt(
162 const QString &fileName,
163 const bool dirOverDir)
166 QAbstractButton *yesButton = msgBox.addButtonFirst(QDialogButtonBox::Yes);
167 QAbstractButton *yesToAllButton = msgBox.addButtonFirst(QDialogButtonBox::YesToAll);
168 QAbstractButton *noButton = msgBox.addButtonSecond(QDialogButtonBox::No);
169 QAbstractButton *noToAllButton = msgBox.addButtonSecond(QDialogButtonBox::NoToAll);
170 QAbstractButton *abortButton = msgBox.addButtonSecond(tr("Abort"), QDialogButtonBox::DestructiveRole);
171 QAbstractButton *newNameButton = msgBox.addButtonFirst(tr("New Name"), QDialogButtonBox::AcceptRole);
172 QAbstractButton *askButton = 0;
173 QAbstractButton *skipDirButton = 0;
176 msgBox.setText(tr("Directory %1 already exists. Overwrite the files inside?")
177 .arg(shortenPath(fileName)));
178 askButton = msgBox.addButtonFirst(tr("Ask"), QDialogButtonBox::AcceptRole);
179 skipDirButton = msgBox.addButtonSecond(tr("Skip"), QDialogButtonBox::NoRole);
181 msgBox.setText(tr("File %1 already exists. Overwrite?").arg(shortenPath(fileName)));
186 if (msgBox.clickedButton == 0) {
188 op->setResponse(OperationThread::NONE);
189 } else if (msgBox.clickedButton == abortButton) {
190 op->setResponse(OperationThread::ABORT);
191 } else if (msgBox.clickedButton == yesButton) {
192 op->setResponse(OperationThread::OVERWRITE);
193 } else if (msgBox.clickedButton == yesToAllButton) {
194 op->setResponse(OperationThread::OVERWRITE, true);
195 } else if (msgBox.clickedButton == noButton) {
196 op->setResponse(OperationThread::KEEP);
197 } else if (msgBox.clickedButton == noToAllButton) {
198 op->setResponse(OperationThread::KEEP, true);
199 } else if (msgBox.clickedButton == askButton) {
200 op->setResponse(OperationThread::ASK);
201 } else if (msgBox.clickedButton == newNameButton) {
202 op->setResponse(OperationThread::NONE);
203 } else if (msgBox.clickedButton == skipDirButton) {
204 op->setResponse(OperationThread::SKIP_DIR);
209 void FileOperator::showInputFilenamePrompt(OperationThread* op,
210 const QFileInfo &file,
214 QString prompt, error;
217 prompt = tr("Enter the new directory name.");
219 prompt = tr("Enter the new file name.");
222 op->newNameFromDialog = "";
223 QString text = file.fileName();
226 text = QInputDialog::getText(this, QString(), prompt + error, QLineEdit::Normal, text, &ok);
231 if (text.contains(QRegExp("[\"*/:<>?\\\\|]"))) {
232 error = "<small><br/><font color = 'red'>" +
233 tr("The name cannot contain any of the following characters: ") +
234 "\"*/:<>?\\|</font></small>";
235 } else if (ok && !text.isEmpty()) {
236 QFileInfo info(file.path() + "/" + text);
237 op->newNameFromDialog = info.absoluteFilePath();
246 void FileOperator::remove(OperationThread* op) {
248 ProgressBar *bar = get(op);
249 layout()->removeWidget(bar);
250 opList.removeAll(qMakePair(op, bar));
256 void FileOperator::togglePauseOperation(ProgressBar* bar) {
257 OperationThread *op = get(bar);
267 void FileOperator::abortOperation(ProgressBar* bar) {
268 OperationThread *op = get(bar);
270 int confirm = QMessageBox::warning(
272 tr("Abort operation"),
273 tr("Are you sure you want to abort the operation?"),
278 if(confirm == QMessageBox::Yes) {
286 void FileOperator::initOperation(OperationThread *thread, ProgressBar *bar) {
287 opList.append(qMakePair(thread, bar));
289 connect(thread, SIGNAL(showErrorPrompt(OperationThread*, const QString&, const QString&, const int)),
290 this, SLOT(showErrorPrompt(OperationThread*, const QString&, const QString&, const int)));
291 connect(thread, SIGNAL(showOverwritePrompt(OperationThread*, const QString&, bool)),
292 this, SLOT(showOverwritePrompt(OperationThread*, const QString&, bool)));
293 connect(thread, SIGNAL(showInputFilenamePrompt(OperationThread*, const QFileInfo&, bool)),
294 this, SLOT(showInputFilenamePrompt(OperationThread*, const QFileInfo&, bool)));
295 connect(thread, SIGNAL(finished(OperationThread*)),
296 this, SLOT(remove(OperationThread*)));
298 connect(thread, SIGNAL(totalSizeChanged(int)), bar, SLOT(setMaximum(int)));
299 connect(thread, SIGNAL(progressUpdate(int)), bar, SLOT(updateProgress(int)));
300 connect(thread, SIGNAL(fileNameUpdated(QString)), bar, SLOT(updateMainText(QString)));
301 connect(thread, SIGNAL(operationStarted(time_t)), bar, SLOT(setStartTime(time_t)));
302 connect(thread, SIGNAL(operationPaused()), bar, SLOT(pause()));
303 connect(thread, SIGNAL(operationResumed(time_t)), bar, SLOT(resume(time_t)));
304 connect(thread, SIGNAL(removeAfterCopy()), bar, SLOT(showRemoveNotice()));
306 connect(bar, SIGNAL(togglePauseOperation(ProgressBar*)), this, SLOT(togglePauseOperation(ProgressBar*)));
307 connect(bar, SIGNAL(abortOperation(ProgressBar*)), this, SLOT(abortOperation(ProgressBar*)));
309 layout()->addWidget(bar);
310 thread->start(QThread::LowestPriority);
314 ProgressBar *FileOperator::get(OperationThread *op) const {
315 for (OperationList::const_iterator it = opList.begin(); it != opList.end(); ++it) {
316 if (it->first == op) return it->second;
322 OperationThread *FileOperator::get(ProgressBar *bar) const {
323 for (OperationList::const_iterator it = opList.begin(); it != opList.end(); ++it) {
324 if (it->second == bar) return it->first;