--- /dev/null
+case
+Makefile
+.build
--- /dev/null
+######################################################################
+# Automatically generated by qmake (2.01a) Mon Jul 12 22:30:42 2010
+######################################################################
+
+TEMPLATE = app
+TARGET =
+DEPENDPATH += . src
+INCLUDEPATH += . src
+
+# added manually!
+CONFIG += link_pkgconfig
+PKGCONFIG += dbus-1 gnome-vfs-2.0
+LIBS += -lhildonmime -ldbus-1
+OBJECTS_DIR=.build
+MOC_DIR=.build
+
+# Input
+HEADERS += src/addressbar.h \
+ src/button.h \
+ src/case.h \
+ src/filelist.h \
+ src/fileoperator.h \
+ src/pane.h
+SOURCES += src/addressbar.cpp \
+ src/button.cpp \
+ src/case.cpp \
+ src/filelist.cpp \
+ src/fileoperator.cpp \
+ src/main.cpp \
+ src/pane.cpp
--- /dev/null
+// case - file manager for N900
+// Copyright (C) 2010 Lukas Hrazky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+#include "addressbar.h"
+
+
+AddressBar::AddressBar(QWidget *parent) : QLineEdit(parent) {
+ setMaximumHeight(60);
+ setContentsMargins(-4, -4, -4, -4);
+
+ connect(this, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
+}
+
+
+void AddressBar::mousePressEvent(QMouseEvent *event) {
+ emit mousePressed();
+ QLineEdit::mousePressEvent(event);
+}
+
+
+void AddressBar::returnPressed() {
+ emit pathEntered(text());
+}
--- /dev/null
+// case - file manager for N900
+// Copyright (C) 2010 Lukas Hrazky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+#ifndef ADDRESSBAR_H
+#define ADDRESSBAR_H
+
+#include <QLineEdit>
+
+
+class AddressBar : public QLineEdit {
+ Q_OBJECT;
+
+signals:
+ void mousePressed();
+ void pathEntered(QString path);
+
+public:
+ explicit AddressBar(QWidget *parent = 0);
+
+protected:
+ void mousePressEvent(QMouseEvent *event);
+
+protected slots:
+ void returnPressed();
+};
+
+#endif // ADDRESSBAR_H
--- /dev/null
+// case - file manager for N900
+// Copyright (C) 2010 Lukas Hrazky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+#include "button.h"
+
+
+Button::Button(QWidget *parent, const int maxWidth, const int maxHeight) : QPushButton(parent) {
+ setMaximumWidth(maxWidth);
+ setMaximumHeight(maxHeight);
+}
+
+Button::Button(const QString &text, QWidget *parent, const int maxWidth, const int maxHeight) :
+ QPushButton(text, parent)
+{
+ setMaximumWidth(maxWidth);
+ setMaximumHeight(maxHeight);
+}
+
+Button::Button(const QIcon &icon, const QString &text, QWidget *parent, const int maxWidth, const int maxHeight) :
+ QPushButton(icon, text, parent)
+{
+ setMaximumWidth(maxWidth);
+ setMaximumHeight(maxHeight);
+}
--- /dev/null
+// case - file manager for N900
+// Copyright (C) 2010 Lukas Hrazky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+#ifndef BUTTON_H
+#define BUTTON_H
+
+#include <QPushButton>
+
+
+class Button : public QPushButton {
+ Q_OBJECT
+
+public:
+ explicit Button(QWidget *parent = 0, int maxWidth = 70, int maxHeight = 70);
+ explicit Button(const QString &text, QWidget *parent = 0, const int maxWidth = 70, const int maxHeight = 70);
+ explicit Button(const QIcon &icon, const QString &text, QWidget *parent = 0, const int maxWidth = 70, const int maxHeight = 70);
+};
+
+#endif // BUTTON_H
--- /dev/null
+// case - file manager for N900
+// Copyright (C) 2010 Lukas Hrazky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+#include "case.h"
+
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+
+
+Case::Case(QWidget *parent) :
+ QMainWindow(parent),
+ leftPane(new Pane(this)),
+ rightPane(new Pane(this)),
+ activePane(leftPane),
+ inactivePane(rightPane),
+ cloneBtn(new Button(">>", 0, 60, 70)),
+ moveBtn(new Button("mv>", 0, 60, 70)),
+ copyBtn(new Button("cp>", 0, 60, 70)),
+ delBtn(new Button("rm", 0, 60, 70)),
+ swapBtn(new Button("<>", 0, 60, 70)),
+ fileOperator(new FileOperator(this))
+{
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+
+ QHBoxLayout *paneLayout = new QHBoxLayout;
+ paneLayout->setContentsMargins(0, 0, 0, 0);
+ paneLayout->setSpacing(1);
+
+ QWidget *central = new QWidget;
+ setCentralWidget(central);
+ central->setLayout(layout);
+ layout->addLayout(paneLayout);
+
+ paneLayout->addWidget(leftPane);
+ leftPane->toggleActive();
+
+ QVBoxLayout *middleButtons = new QVBoxLayout;
+ paneLayout->addLayout(middleButtons);
+ middleButtons->setSpacing(10);
+ middleButtons->setContentsMargins(0, 0, 0, 0);
+
+ cloneBtn->setContentsMargins(0, 0, 0, 0);
+
+ middleButtons->addWidget(cloneBtn);
+ middleButtons->addWidget(moveBtn);
+ middleButtons->addWidget(copyBtn);
+ middleButtons->addWidget(delBtn);
+ middleButtons->addWidget(swapBtn);
+
+ paneLayout->addWidget(rightPane);
+
+ layout->addWidget(fileOperator);
+
+ connect(this, SIGNAL(activePaneSwitched()), leftPane, SLOT(toggleActive()));
+ connect(this, SIGNAL(activePaneSwitched()), rightPane, SLOT(toggleActive()));
+
+ connect(cloneBtn, SIGNAL(pressed()), this, SLOT(clonePane()));
+ connect(delBtn, SIGNAL(pressed()), this, SLOT(deleteFiles()));
+ connect(copyBtn, SIGNAL(pressed()), this, SLOT(copyFiles()));
+ connect(moveBtn, SIGNAL(pressed()), this, SLOT(moveFiles()));
+ connect(swapBtn, SIGNAL(pressed()), this, SLOT(swapPanes()));
+}
+
+
+void Case::switchActivePane() {
+ Pane *tmpPane = activePane;
+ activePane = inactivePane;
+ inactivePane = tmpPane;
+
+ if (leftPane == activePane) {
+ cloneBtn->setText(">>");
+ moveBtn->setText("mv>");
+ copyBtn->setText("cp>");
+ } else {
+ cloneBtn->setText("<<");
+ moveBtn->setText("<mv");
+ copyBtn->setText("<cp");
+ }
+
+ emit activePaneSwitched();
+}
+
+
+void Case::deleteFiles() {
+ if (activePane->selection().size()) {
+ fileOperator->deleteFiles(activePane->selection());
+ }
+}
+
+
+void Case::copyFiles() {
+ if (activePane->selection().size()) {
+ QDir dest = inactivePane->path();
+ fileOperator->copyFiles(activePane->selection(), dest);
+ }
+}
+
+
+void Case::moveFiles() {
+ if (activePane->selection().size()) {
+ QDir dest = inactivePane->path();
+ fileOperator->moveFiles(activePane->selection(), dest);
+ }
+}
+
+
+void Case::clonePane() {
+ inactivePane->changePath(activePane->path());
+}
+
+
+void Case::swapPanes() {
+ QString tmpPath = activePane->path();
+ activePane->changePath(inactivePane->path());
+ inactivePane->changePath(tmpPath);
+}
--- /dev/null
+// case - file manager for N900
+// Copyright (C) 2010 Lukas Hrazky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+#ifndef CASE_H
+#define CASE_H
+
+#include "pane.h"
+#include "fileoperator.h"
+#include "button.h"
+
+#include <QMainWindow>
+#include <QEvent>
+
+
+class Case : public QMainWindow {
+ Q_OBJECT
+
+signals:
+ void activePaneSwitched();
+
+public:
+ Case(QWidget *parent = 0);
+
+public slots:
+ void switchActivePane();
+
+private:
+ Pane *leftPane, *rightPane, *activePane, *inactivePane;
+ Button *cloneBtn, *moveBtn, *copyBtn, *delBtn, *swapBtn;
+ FileOperator *fileOperator;
+
+private slots:
+ void deleteFiles();
+ void copyFiles();
+ void moveFiles();
+ void clonePane();
+ void swapPanes();
+};
+
+#endif // CASE_H
--- /dev/null
+// case - file manager for N900
+// Copyright (C) 2010 Lukas Hrazky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+#include "filelist.h"
+
+#include <QProcess>
+#include <QUrl>
+
+#include <hildon-mime.h>
+#include <dbus/dbus.h>
+
+
+FileList::FileList(QWidget *parent) :
+ QListView(parent),
+ fileSystemModel(new QFileSystemModel)
+{
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ //setSelectionMode(QAbstractItemView::SingleSelection);
+ setSelectionMode(QAbstractItemView::MultiSelection);
+
+ setModel(fileSystemModel);
+
+ fileSystemModel->setFilter(fileSystemModel->filter() | QDir::System);
+ setRootIndex(fileSystemModel->setRootPath(QDir::homePath()));
+
+ connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(activateItem(QModelIndex)));
+}
+
+
+const QFileInfoList FileList::selection() const {
+ QFileInfoList files;
+ QModelIndexList l = selectionModel()->selectedIndexes();
+ for (int i = 0; i < l.size(); ++i) {
+ files.append(fileSystemModel->fileInfo(l[i]));
+ }
+ return files;
+}
+
+
+const QString FileList::path() const {
+ return fileSystemModel->rootPath();
+}
+
+
+bool FileList::changePath(QString path) {
+ QDir dir(fileSystemModel->rootPath());
+ if (dir.cd(path)) {
+ setRootIndex(fileSystemModel->setRootPath(dir.absolutePath()));
+ clearSelection();
+ emit pathChanged(fileSystemModel->rootPath());
+ return true;
+ }
+
+ return false;
+}
+
+
+bool FileList::goUp() {
+ return changePath("..");
+}
+
+
+void FileList::activateItem(QModelIndex index) {
+ const QFileInfo &file = fileSystemModel->fileInfo(index);
+
+ if(file.isDir()) {
+ changePath(file.absoluteFilePath());
+ } else if(file.isExecutable()) {
+ QProcess::startDetached(file.absoluteFilePath());
+ } else {
+ // TODO: find better solution for this, maybe get fixed in Qt
+ DBusConnection* conn;
+ conn = dbus_bus_get(DBUS_BUS_SESSION, 0);
+ hildon_mime_open_file(conn, QUrl::fromLocalFile(file.absoluteFilePath()).toEncoded().constData());
+
+ // Not working with maemo5. Uses hildon_uri_open function from
+ // libhildonmime which should work, but all files opened in browser.
+ //QDesktopServices::openUrl(QUrl::fromLocalFile(file.absoluteFilePath()));
+ }
+}
+
+
+void FileList::mousePressEvent(QMouseEvent *event) {
+ emit mousePressed();
+ QListView::mousePressEvent(event);
+}
--- /dev/null
+// case - file manager for N900
+// Copyright (C) 2010 Lukas Hrazky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+#ifndef FILELIST_H
+#define FILELIST_H
+
+#include <QListView>
+#include <QFileInfoList>
+#include <QFileSystemModel>
+
+
+class FileList : public QListView {
+ Q_OBJECT;
+
+signals:
+ void mousePressed();
+ void pathChanged(QString path);
+
+public:
+ explicit FileList(QWidget *parent = 0);
+
+ const QFileInfoList selection() const;
+ const QString path() const;
+
+public slots:
+ bool changePath(QString path);
+ bool goUp();
+
+protected:
+ QFileSystemModel *fileSystemModel;
+
+ void mousePressEvent(QMouseEvent *event);
+
+private slots:
+ void activateItem(QModelIndex index);
+};
+
+#endif // FILELIST_H
--- /dev/null
+// case - file manager for N900
+// Copyright (C) 2010 Lukas Hrazky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+#include "fileoperator.h"
+
+#include <QtGui>
+#include <QDir>
+#include <QMessageBox>
+#include <QHBoxLayout>
+#include <QChar>
+
+#include <math.h>
+#include <errno.h>
+#include <iostream>
+
+
+#define SHOW_ERROR_PROMPT(promptString) \
+ response = FileOperator::NONE; \
+ if (ignoreAll[errno]) { \
+ response = FileOperator::IGNORE; \
+ } else { \
+ char buf[255]; \
+ char *realBuf = strerror_r(errno, buf, 255); \
+ emit showErrorPrompt(this, promptString + ". " + realBuf + ".", errno); \
+ waitCond.wait(&mutex); \
+ }
+
+
+#define ERROR_PROMPT(operation, promptString) \
+{ \
+ response = FileOperator::NONE; \
+ while (!abort && operation) { \
+ SHOW_ERROR_PROMPT(promptString) \
+ if (response == FileOperator::IGNORE) { \
+ break; \
+ } \
+ } \
+}
+
+
+#define ERROR_PROMPT_XP(operation, promptString, onIgnore, quitCmd) \
+{ \
+ ERROR_PROMPT(operation, promptString) \
+ if (abort || response == FileOperator::IGNORE) { \
+ if (!abort) onIgnore; \
+ quitCmd; \
+ } \
+}
+
+
+#define OVERWRITE_PROMPT(file, newFile) \
+{ \
+ response = FileOperator::NONE; \
+ \
+ if (newFile.exists()) { \
+ if (overwriteAll != FileOperator::NONE) { \
+ response = overwriteAll; \
+ } else { \
+ bool dirOverDir = false; \
+ if (newFile.isDir() && file.isDir()) dirOverDir = true; \
+ emit showOverwritePrompt(this, newFile.absoluteFilePath(), dirOverDir); \
+ waitCond.wait(&mutex); \
+ } \
+ } \
+}
+
+
+FileOperator::FileOperator(QWidget *parent) : QWidget(parent) {
+ QHBoxLayout *layout = new QHBoxLayout;
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ setLayout(layout);
+}
+
+
+void FileOperator::deleteFiles(const QFileInfoList &files) {
+ QString title, desc;
+ if (files.size() == 1) {
+ title = tr("Delete file");
+ desc = tr("Are you sure you want to delete %1?").arg(files[0].absoluteFilePath());
+ } else {
+ title = tr("Delete files");
+ desc = tr("You are about to delete %1 files. Are you sure you want to continue?").arg(files.size());
+ }
+
+ int confirm = QMessageBox::warning(
+ 0,
+ title,
+ desc,
+ QMessageBox::Yes,
+ QMessageBox::No
+ );
+
+ if(confirm == QMessageBox::Yes) {
+ caterNewThread(new DeleteThread(files));
+ }
+}
+
+
+void FileOperator::copyFiles(const QFileInfoList &files, QDir &destination) {
+ QString title, desc;
+ if (files.size() == 1) {
+ title = tr("Copy file");
+ desc = tr("Are you sure you want to copy %1 to %2?").arg(files[0].absoluteFilePath())
+ .arg(destination.absolutePath());
+ } else {
+ title = tr("Copy files");
+ desc = tr("You are about to copy %1 files to %2. Are you sure you want to continue?")
+ .arg(files.size()).arg(destination.absolutePath());
+ }
+
+ int confirm = QMessageBox::warning(
+ 0,
+ title,
+ desc,
+ QMessageBox::Yes,
+ QMessageBox::No
+ );
+
+ if(confirm == QMessageBox::Yes) {
+ caterNewThread(new CopyThread(files, destination));
+ }
+}
+
+
+void FileOperator::moveFiles(const QFileInfoList &files, QDir &destination) {
+ // for move we don't wanna move to the same dir
+ if (files[0].absolutePath() == destination.absolutePath()) return;
+
+ QString title, desc;
+ if (files.size() == 1) {
+ title = tr("Move file");
+ desc = tr("Are you sure you want to move %1 to %2?").arg(files[0].absoluteFilePath())
+ .arg(destination.absolutePath());
+ } else {
+ title = tr("Move files");
+ desc = tr("You are about to move %1 files to %2. Are you sure you want to continue?")
+ .arg(files.size()).arg(destination.absolutePath());
+ }
+
+ int confirm = QMessageBox::warning(
+ 0,
+ title,
+ desc,
+ QMessageBox::Yes,
+ QMessageBox::No
+ );
+
+ if(confirm == QMessageBox::Yes) {
+ caterNewThread(new MoveThread(files, destination));
+ }
+}
+
+
+void FileOperator::showErrorPrompt(FileManipulatorThread* manipulator, const QString &message, const int err) {
+ QMessageBox msgBox;
+ msgBox.addButton(QMessageBox::Cancel);
+ QAbstractButton *abortButton = msgBox.addButton(tr("Abort"), QMessageBox::DestructiveRole);
+ QAbstractButton *retryButton = msgBox.addButton(QMessageBox::Retry);
+ QAbstractButton *ignoreButton = msgBox.addButton(QMessageBox::Ignore);
+ QAbstractButton *ignoreAllButton = msgBox.addButton(tr("Ignore All"), QMessageBox::AcceptRole);
+ msgBox.setText(message);
+
+ msgBox.exec();
+
+ if (msgBox.clickedButton() == abortButton) {
+ manipulator->setResponse(ABORT);
+ } else if (msgBox.clickedButton() == retryButton) {
+ manipulator->setResponse(RETRY);
+ } else if (msgBox.clickedButton() == ignoreButton) {
+ manipulator->setResponse(IGNORE);
+ } else if (msgBox.clickedButton() == ignoreAllButton) {
+ manipulator->setResponse(IGNORE, true, err);
+ }
+}
+
+
+void FileOperator::showOverwritePrompt(
+ FileManipulatorThread* manipulator,
+ const QString &fileName,
+ const bool dirOverDir)
+{
+ QMessageBox msgBox;
+ msgBox.addButton(QMessageBox::Cancel);
+ QAbstractButton *yesButton = msgBox.addButton(QMessageBox::Yes);
+ QAbstractButton *yesToAllButton = msgBox.addButton(QMessageBox::YesToAll);
+ QAbstractButton *noButton = msgBox.addButton(QMessageBox::No);
+ QAbstractButton *noToAllButton = msgBox.addButton(QMessageBox::NoToAll);
+ QAbstractButton *abortButton = msgBox.addButton(tr("Abort"), QMessageBox::DestructiveRole);
+ QAbstractButton *askButton = 0;
+
+ if (dirOverDir) {
+ msgBox.setText(tr("Directory %1 already exists. Overwrite the files inside?").arg(fileName));
+ askButton = msgBox.addButton(tr("Ask"), QMessageBox::AcceptRole);
+ } else {
+ msgBox.setText(tr("File %1 already exists. Overwrite?").arg(fileName));
+ }
+
+ msgBox.exec();
+
+ if (msgBox.clickedButton() == abortButton) {
+ manipulator->setResponse(ABORT);
+ } else if (msgBox.clickedButton() == yesButton) {
+ manipulator->setResponse(OVERWRITE);
+ } else if (msgBox.clickedButton() == yesToAllButton) {
+ manipulator->setResponse(OVERWRITE, true);
+ } else if (msgBox.clickedButton() == noButton) {
+ manipulator->setResponse(KEEP);
+ } else if (msgBox.clickedButton() == noToAllButton) {
+ manipulator->setResponse(KEEP, true);
+ } else if (msgBox.clickedButton() == askButton) {
+ manipulator->setResponse(NONE, true);
+ }
+}
+
+
+void FileOperator::remove(FileManipulatorThread* manipulator) {
+ layout()->removeWidget(manipulator->widget);
+ manipulatorList.removeAll(manipulator);
+ delete manipulator;
+}
+
+
+void FileOperator::setBarSize(FileManipulatorThread* manipulator, unsigned int size) {
+ manipulator->widget->setMinimum(0);
+ manipulator->widget->setMaximum(size);
+}
+
+
+void FileOperator::updateProgress(FileManipulatorThread* manipulator, int value) {
+ if (manipulator->widget->value() + value > manipulator->widget->maximum()) {
+ std::cout << "WARNING, EXCEEDING MAXIMUM BY " << value << std::endl;
+ }
+ manipulator->widget->setValue(manipulator->widget->value() + value);
+}
+
+
+void FileOperator::caterNewThread(FileManipulatorThread *thread) {
+ manipulatorList.append(thread);
+
+ connect(thread, SIGNAL(showErrorPrompt(FileManipulatorThread*, const QString&, const int)),
+ this, SLOT(showErrorPrompt(FileManipulatorThread*, const QString&, const int)));
+ connect(thread, SIGNAL(showOverwritePrompt(FileManipulatorThread*, const QString&, bool)),
+ this, SLOT(showOverwritePrompt(FileManipulatorThread*, const QString&, bool)));
+ connect(thread, SIGNAL(finished(FileManipulatorThread*)),
+ this, SLOT(remove(FileManipulatorThread*)));
+ connect(thread, SIGNAL(setBarSize(FileManipulatorThread*, unsigned int)),
+ this, SLOT(setBarSize(FileManipulatorThread*, unsigned int)));
+ connect(thread, SIGNAL(updateProgress(FileManipulatorThread*, int)),
+ this, SLOT(updateProgress(FileManipulatorThread*, int)));
+
+ thread->widget->setValue(0);
+
+ layout()->addWidget(thread->widget);
+ thread->start();
+}
+
+
+FileManipulatorThread::FileManipulatorThread(const QFileInfoList files, QDir dest) :
+ widget(new QProgressBar()),
+ files(files),
+ dest(dest),
+ response(FileOperator::NONE),
+ overwriteAll(FileOperator::NONE),
+ abort(false),
+ barSize(0),
+ barValue(0),
+ fileSize(0),
+ fileValue(0)
+{
+ memset(ignoreAll, false, sizeof(ignoreAll));
+ //widget->setStyle(new QPlastiqueStyle);
+}
+
+
+void FileManipulatorThread::setResponse(
+ const FileOperator::Response response,
+ const bool applyToAll,
+ const int err)
+{
+ mutex.lock();
+
+ this->response = response;
+
+ if (applyToAll) {
+ if (response == FileOperator::KEEP
+ || response == FileOperator::OVERWRITE
+ || response == FileOperator::NONE)
+ {
+ overwriteAll = response;
+ }
+
+ if (response == FileOperator::IGNORE) {
+ ignoreAll[err] = true;
+ }
+ }
+
+ if (response == FileOperator::ABORT) abort = true;
+
+ mutex.unlock();
+ waitCond.wakeAll();
+}
+
+
+void FileManipulatorThread::processFiles(const QFileInfoList &files) {
+ for (QFileInfoList::const_iterator it = files.begin(); it != files.end(); ++it) {
+ perform(*it);
+ if (abort) break;
+ }
+}
+
+
+bool FileManipulatorThread::remove(QString &fileName, const bool ignoreDirNotEmpty) {
+ return remove(QFileInfo(fileName), ignoreDirNotEmpty);
+}
+
+
+bool FileManipulatorThread::remove(const QFileInfoList &files, const bool ignoreDirNotEmpty) {
+ bool res = true;
+ for (QFileInfoList::const_iterator it = files.begin(); it != files.end(); ++it) {
+ if (!remove(*it, ignoreDirNotEmpty)) res = false;
+ if (abort) break;
+ }
+ return res;
+}
+
+
+bool FileManipulatorThread::remove(const QFileInfo &file, const bool ignoreDirNotEmpty) {
+ QString path = file.absoluteFilePath();
+ QFSFileEngine engine(path);
+
+ if (file.isDir()) {
+ QFileInfoList list = listDirFiles(path);
+
+ if (ignoreDirNotEmpty && list.size()) return true;
+
+ if (!remove(list, ignoreDirNotEmpty)) return false;
+
+ ERROR_PROMPT(!engine.rmdir(path, false),
+ tr("Error deleting directory %1.").arg(path))
+ } else {
+ ERROR_PROMPT(!engine.remove(),
+ tr("Error deleting file %1.").arg(path))
+ }
+
+ if (abort || response == FileOperator::IGNORE) return false;
+ return true;
+}
+
+
+void FileManipulatorThread::copy(const QFileInfo &file, const bool removeAfterCopy) {
+ std::cout << (removeAfterCopy ? "MOVING " : "COPYING ") << file.absoluteFilePath().toStdString()
+ << " to " << dest.absolutePath().toStdString() << std::endl;
+
+ QString path(file.absoluteFilePath());
+ QString newPath(dest.absolutePath() + "/" + file.fileName());
+ QFSFileEngine engine(path);
+ QFSFileEngine newEngine(newPath);
+ QFileInfo newFile(newPath);
+
+ updateFile(path);
+
+ // hack to prevent asking about the same file if we already asked in the rename(...) function
+ if (overwriteAll == FileOperator::DONT_ASK_ONCE) {
+ overwriteAll = FileOperator::NONE;
+ } else {
+ OVERWRITE_PROMPT(file, newFile)
+ }
+
+ if (abort) return;
+
+ // this loop is here only to allow easily breaking out to the end (and remove the source file/dir)
+ while (1) {
+ if (response == FileOperator::KEEP) {
+ updateProgress(fileSizeMap[path]);
+ break;
+ }
+
+ FileOperator::Response overwriteResponse = response;
+
+ if (file.isDir()) {
+ if (newFile.exists() && !newFile.isDir()) {
+ if(!remove(newPath)) {
+ updateProgress(fileSizeMap[path]);
+ break;
+ }
+ newFile = QFileInfo(newPath);
+ }
+
+ if (!newFile.exists()) {
+ ERROR_PROMPT_XP(!engine.mkdir(newPath, false),
+ tr("Error creating directory %1.").arg(newPath),
+ updateProgress(fileSizeMap[path]),
+ break)
+ }
+
+ updateProgress(1);
+
+ QDir destBackup = dest;
+ dest = newPath;
+
+ FileOperator::Response tmpResp = overwriteAll;
+ overwriteAll = overwriteResponse;
+
+ processFiles(listDirFiles(path));
+
+ overwriteAll = tmpResp;
+
+ ERROR_PROMPT(!newEngine.setPermissions(file.permissions()),
+ tr("Error setting permissions for directory %1.").arg(newPath))
+
+ if (abort) return;
+
+ dest = destBackup;
+ } else {
+ ERROR_PROMPT_XP(engine.isSequential(),
+ tr("Cannot copy sequential file %1.").arg(path),
+ updateProgress(fileSizeMap[path]),
+ break)
+
+ if (newFile.exists() && newFile.isDir()) {
+ ERROR_PROMPT_XP(!remove(newPath),
+ tr("Cannot replace directory %1 due to previous errors.").arg(newPath),
+ updateProgress(fileSizeMap[path]),
+ break)
+ }
+
+ ERROR_PROMPT_XP(!engine.open(QIODevice::ReadOnly),
+ tr("Error reading file %1.").arg(path),
+ updateProgress(fileSizeMap[path]),
+ break)
+
+ bool ignore = false;
+ while (!abort && !ignore) {
+ engine.seek(0);
+
+ ERROR_PROMPT(!newEngine.open(QIODevice::WriteOnly | QIODevice::Truncate),
+ tr("Error writing file %1.").arg(newPath))
+
+ if (abort || response == FileOperator::IGNORE) {
+ if (response == FileOperator::IGNORE) {
+ updateProgress(fileSizeMap[path] - fileValue);
+ ignore = true;
+ }
+ break;
+ }
+
+ bool error = false;
+ char block[4096];
+ qint64 bytes;
+ while ((bytes = engine.read(block, sizeof(block))) > 0) {
+ if (bytes == -1 || bytes != newEngine.write(block, bytes)) {
+ if (bytes == -1) {
+ SHOW_ERROR_PROMPT(tr("Error while reading from file %1.").arg(path));
+ } else {
+ SHOW_ERROR_PROMPT(tr("Error while writing to file %1.").arg(newPath));
+ }
+
+ if (!abort) {
+ if (response == FileOperator::IGNORE) {
+ updateProgress(fileSizeMap[path] - fileValue);
+ ignore = true;
+ } else {
+ updateProgress(-fileValue);
+ }
+ }
+ error = true;
+ break;
+ }
+
+ updateProgress(1);
+ }
+
+ if (!error) break;
+ }
+
+ engine.close();
+ newEngine.close();
+
+ if (abort || ignore) {
+ newEngine.remove();
+ } else {
+ ERROR_PROMPT(!newEngine.setPermissions(file.permissions()),
+ tr("Error setting permissions for file %1.").arg(newPath))
+ }
+ }
+
+ break;
+ }
+
+ if (removeAfterCopy && !abort) remove(path, true);
+}
+
+
+unsigned int FileManipulatorThread::countFiles(const QFileInfoList &files) {
+ unsigned int res = 0;
+
+ for (QFileInfoList::const_iterator it = files.begin(); it != files.end(); ++it) {
+ unsigned int size = 1;
+
+ if (it->isDir()) {
+ size += countFiles(listDirFiles(it->absoluteFilePath()));
+ }
+
+ res += size;
+ fileSizeMap[it->absoluteFilePath()] = size;
+ }
+
+ return res;
+}
+
+
+unsigned int FileManipulatorThread::calculateFileSize(const QFileInfoList &files) {
+ unsigned int res = 0;
+
+ for (QFileInfoList::const_iterator it = files.begin(); it != files.end(); ++it) {
+ unsigned int size = 1;
+
+ if (it->isDir()) {
+ size += calculateFileSize(listDirFiles(it->absoluteFilePath()));
+ } else {
+ size = ceil(static_cast<float>(it->size()) / 4096);
+ }
+
+ res += size;
+ fileSizeMap[it->absoluteFilePath()] = size;
+ }
+
+ return res;
+}
+
+
+QFileInfoList FileManipulatorThread::listDirFiles(const QString &dirPath) {
+ QDir dir = dirPath;
+ return dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::System | QDir::Hidden);
+}
+
+
+void FileManipulatorThread::setBarSize(unsigned int size) {
+ barSize = size;
+ emit setBarSize(this, size);
+}
+
+
+void FileManipulatorThread::updateProgress(int value) {
+ barValue += value;
+ fileValue += value;
+ emit updateProgress(this, value);
+}
+
+
+void FileManipulatorThread::updateFile(const QString &fileName) {
+ fileValue = 0;
+ emit updateFile(this, fileName);
+}
+
+
+void DeleteThread::run() {
+ mutex.lock();
+
+ setBarSize(countFiles(files));
+
+ processFiles(files);
+
+ sleep(0.5);
+ emit finished(this);
+}
+
+
+void DeleteThread::perform(const QFileInfo &file) {
+ std::cout << "DELETING " << file.absoluteFilePath().toStdString() << std::endl;
+
+ QString path = file.absoluteFilePath();
+ QFSFileEngine engine(path);
+
+ if (file.isDir()) {
+ processFiles(listDirFiles(path));
+
+ if (!listDirFiles(path).size()) {
+ ERROR_PROMPT(!engine.rmdir(path, false),
+ tr("Error deleting directory %1.").arg(path))
+ }
+ } else {
+ ERROR_PROMPT(!engine.remove(),
+ tr("Error deleting file %1.").arg(path))
+ }
+
+ if (!abort) updateProgress(1);
+}
+
+
+void CopyThread::run() {
+ mutex.lock();
+
+ setBarSize(calculateFileSize(files));
+
+ processFiles(files);
+
+ sleep(0.5);
+ emit finished(this);
+}
+
+
+void CopyThread::perform(const QFileInfo &file) {
+ copy(file, false);
+}
+
+
+void MoveThread::run() {
+ mutex.lock();
+
+ rename(files, dest);
+
+ sleep(0.5);
+ emit finished(this);
+}
+
+
+void MoveThread::rename(const QFileInfoList &files, const QDir &dest) {
+ setBarSize(barSize + files.size());
+
+ for (int i = 0; i < files.size(); ++i) {
+ QString path = files[i].absoluteFilePath();
+ QFSFileEngine engine(path);
+ QString newPath = dest.absolutePath() + "/" + files[i].fileName();
+
+ updateFile(path);
+
+ OVERWRITE_PROMPT(files[i], QFileInfo(newPath))
+
+ if (response == FileOperator::KEEP) {
+ remove(path);
+ if (abort) break;
+ updateProgress(1);
+ continue;
+ }
+
+ while (!abort && !engine.rename(newPath)) {
+ // source and target are on different partitions
+ // this should happen on the first file, unless some are skipped by overwrite prompt
+ // we calculate the actual file sizes, because from now on copy & remove takes over
+ if (errno == EXDEV) {
+ setBarSize(barValue + calculateFileSize(files));
+
+ FileOperator::Response tmpResp = overwriteAll;
+ overwriteAll = response;
+ // hack: we already checked the first file we are sending to processFiles(...)
+ // so we don't want to ask about this one again
+ if (overwriteAll == FileOperator::NONE) overwriteAll = FileOperator::DONT_ASK_ONCE;
+
+ processFiles(files.mid(i));
+
+ overwriteAll = tmpResp;
+
+ // just to quit the loops, we are done
+ abort = true;
+ // the target is nonempty dir. lets call this recursively and rename the contents one by one
+ } else if (errno == ENOTEMPTY || errno == EEXIST) {
+ FileOperator::Response tmpResp = overwriteAll;
+ overwriteAll = response;
+
+ rename(listDirFiles(path), QDir(newPath));
+ if (abort) break;
+
+ overwriteAll = tmpResp;
+
+ ERROR_PROMPT(!engine.rmdir(path, false), tr("Error deleting directory %1.").arg(path))
+
+ break;
+ // source and target are nonmatching types(file and dir)
+ // remove the target and let it loop once again
+ } else if (errno == ENOTDIR || errno == EISDIR) {
+ if (!remove(newPath)) break;
+ } else {
+ SHOW_ERROR_PROMPT(tr("Error moving %1.").arg(path))
+
+ if (response == FileOperator::IGNORE) {
+ break;
+ }
+ }
+ }
+
+ if (abort) break;
+ updateProgress(1);
+ }
+}
+
+
+void MoveThread::perform(const QFileInfo &file) {
+ copy(file, true);
+}
--- /dev/null
+// case - file manager for N900
+// Copyright (C) 2010 Lukas Hrazky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+#ifndef FILEOPERATOR_H
+#define FILEOPERATOR_H
+
+#include <QWidget>
+#include <QProgressBar>
+#include <QFileInfo>
+#include <QThread>
+#include <QMutex>
+#include <QWaitCondition>
+#include <QDir>
+#include <QMap>
+
+
+class FileManipulatorThread;
+
+
+class FileOperator : public QWidget {
+ Q_OBJECT
+
+public:
+ // DONT_ASK_ONCE is a hackish way to avoid asking twice to overwrite the same directory when moving
+ enum Response{NONE, ABORT, RETRY, IGNORE, KEEP, OVERWRITE, DONT_ASK_ONCE};
+
+ FileOperator(QWidget *parent = 0);
+
+ void deleteFiles(const QFileInfoList &files);
+ void copyFiles(const QFileInfoList &files, QDir &destination);
+ void moveFiles(const QFileInfoList &files, QDir &destination);
+
+public slots:
+ void showErrorPrompt(FileManipulatorThread* manipulator, const QString &message, const int err);
+ void showOverwritePrompt(FileManipulatorThread* manipulator, const QString &fileName, const bool dirOverDir);
+ void remove(FileManipulatorThread* manipulator);
+ void setBarSize(FileManipulatorThread* manipulator, unsigned int size);
+ void updateProgress(FileManipulatorThread* manipulator, int value);
+
+protected:
+ void caterNewThread(FileManipulatorThread *thread);
+
+ QList<FileManipulatorThread*> manipulatorList;
+};
+
+
+class FileManipulatorThread : public QThread {
+ Q_OBJECT
+
+public:
+ explicit FileManipulatorThread(const QFileInfoList files, QDir dest = QDir());
+ void setResponse(const FileOperator::Response response, const bool appyToAll = false, const int err = 0);
+
+ QProgressBar *widget;
+
+protected:
+ void processFiles(const QFileInfoList &files);
+ virtual void perform(const QFileInfo &file) = 0;
+
+ bool remove(QString &filename, const bool ignoreDirNotEmpty = false);
+ bool remove(const QFileInfoList &files, const bool ignoreDirNotEmpty = false);
+ bool remove(const QFileInfo &file, const bool ignoreDirNotEmpty = false);
+
+ void copy(const QFileInfo &file, const bool removeAfterCopy);
+
+ unsigned int countFiles(const QFileInfoList &files);
+ unsigned int calculateFileSize(const QFileInfoList &files);
+
+ QFileInfoList listDirFiles(const QString &dirPath);
+
+ void setBarSize(unsigned int size);
+ void updateProgress(int value);
+ void updateFile(const QString &fileName);
+
+ const QFileInfoList files;
+ QDir dest;
+
+ FileOperator::Response response;
+ FileOperator::Response overwriteAll;
+ bool abort;
+ bool ignoreAll[256];
+
+ QMap<QString, qint64> fileSizeMap;
+
+ QMutex mutex;
+ QWaitCondition waitCond;
+
+ unsigned int barSize, barValue, fileSize, fileValue;
+
+signals:
+ void showErrorPrompt(FileManipulatorThread*, const QString&, const int);
+ void showOverwritePrompt(FileManipulatorThread*, const QString&, const bool);
+ void finished(FileManipulatorThread*);
+ void setBarSize(FileManipulatorThread*, unsigned int);
+ void updateProgress(FileManipulatorThread*, int);
+ void updateFile(FileManipulatorThread*, const QString&);
+};
+
+
+class DeleteThread : public FileManipulatorThread {
+ Q_OBJECT
+
+public:
+ explicit DeleteThread(const QFileInfoList &files) : FileManipulatorThread(files) {}
+
+protected:
+ void run();
+ virtual void perform(const QFileInfo &file);
+};
+
+
+class CopyThread : public FileManipulatorThread {
+ Q_OBJECT
+
+public:
+ explicit CopyThread(const QFileInfoList &files, QDir &dest) : FileManipulatorThread(files, dest) {}
+
+protected:
+ void run();
+ virtual void perform(const QFileInfo &file);
+};
+
+
+class MoveThread : public FileManipulatorThread {
+ Q_OBJECT
+
+public:
+ explicit MoveThread(const QFileInfoList &files, QDir &dest) : FileManipulatorThread(files, dest) {}
+
+protected:
+ void run();
+ virtual void perform(const QFileInfo &file);
+ void rename(const QFileInfoList &files, const QDir &dest);
+};
+
+
+#endif // FILEOPERATOR_H
--- /dev/null
+// case - file manager for N900
+// Copyright (C) 2010 Lukas Hrazky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+#include <QApplication>
+
+#include "case.h"
+
+
+int main(int argc, char* argv[]) {
+ QApplication app(argc, argv);
+ Case theCase;
+
+ theCase.show();
+ return app.exec();
+}
--- /dev/null
+// case - file manager for N900
+// Copyright (C) 2010 Lukas Hrazky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+#include "pane.h"
+
+#include <QHeaderView>
+#include <QVBoxLayout>
+#include <QMessageBox>
+#include <QInputDialog>
+#include <QDesktopServices>
+#include <QUrl>
+#include <QProcess>
+#include <QPainter>
+
+
+Pane::Pane(QWidget *theCase, QWidget *parent) :
+ QWidget(parent),
+ theCase(theCase),
+ active(false),
+ location(new AddressBar),
+ up(new Button("^", 0, 70, 60)),
+ fileList(new FileList)
+{
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setContentsMargins(3, 3, 3, 3);
+ layout->setSpacing(0);
+ setLayout(layout);
+
+ QHBoxLayout *topLine = new QHBoxLayout;
+
+ location->setText(fileList->path());
+ layout->setSpacing(0);
+
+ topLine->addWidget(location);
+ topLine->addWidget(up);
+ layout->addLayout(topLine);
+ layout->addWidget(fileList);
+
+ connect(location, SIGNAL(pathEntered(QString)), fileList, SLOT(changePath(QString)));
+ connect(up, SIGNAL(pressed()), fileList, SLOT(goUp()));
+ connect(fileList, SIGNAL(pathChanged(QString)), location, SLOT(setText(QString)));
+
+ activationConnect();
+}
+
+
+void Pane::paintEvent(QPaintEvent *) {
+ if (active) {
+ QPainter painter(this);
+ painter.setPen(palette().color(QPalette::Highlight));
+ QRect g = this->geometry();
+ g.moveTo(1, 1);
+ g.setWidth(g.width() - 3);
+ g.setHeight(g.height() - 3);
+ painter.drawRect(g);
+ }
+}
+
+
+void Pane::activationConnect() {
+ connect(up, SIGNAL(clicked()), theCase, SLOT(switchActivePane()));
+ connect(location, SIGNAL(mousePressed()), theCase, SLOT(switchActivePane()));
+ connect(fileList, SIGNAL(mousePressed()), theCase, SLOT(switchActivePane()));
+}
+
+
+void Pane::activationDisconnect() {
+ disconnect(up, SIGNAL(clicked()), theCase, SLOT(switchActivePane()));
+ disconnect(location, SIGNAL(mousePressed()), theCase, SLOT(switchActivePane()));
+ disconnect(fileList, SIGNAL(mousePressed()), theCase, SLOT(switchActivePane()));
+}
+
+
+void Pane::toggleActive() {
+ active = !active;
+ if (active) activationDisconnect(); else activationConnect();
+ update();
+}
+
+
+const QFileInfoList Pane::selection() const {
+ return fileList->selection();
+}
+
+
+bool Pane::changePath(QString path) {
+ location->setText(path);
+ return fileList->changePath(path);
+}
+
+
+const QString Pane::path() const {
+ return fileList->path();
+}
--- /dev/null
+// case - file manager for N900
+// Copyright (C) 2010 Lukas Hrazky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+#ifndef PANE_H
+#define PANE_H
+
+#include <QFileInfoList>
+#include <QDir>
+
+#include "button.h"
+#include "filelist.h"
+#include "addressbar.h"
+
+
+class Pane : public QWidget {
+ Q_OBJECT
+
+public:
+ explicit Pane(QWidget *theCase, QWidget *parent = 0);
+
+ const QString path() const;
+ const QFileInfoList selection() const;
+
+public slots:
+ bool changePath(QString path);
+ void toggleActive();
+
+protected:
+ void paintEvent(QPaintEvent *);
+
+ void activationConnect();
+ void activationDisconnect();
+
+private:
+ QWidget *theCase;
+
+ bool active;
+
+ AddressBar *location;
+ Button *up;
+ FileList *fileList;
+};
+
+#endif // PANE_H