diff options
-rw-r--r-- | filesystemwidget.cpp | 136 | ||||
-rw-r--r-- | filesystemwidget.h | 12 | ||||
-rw-r--r-- | shemov.cpp | 37 | ||||
-rw-r--r-- | shemov.h | 2 |
4 files changed, 123 insertions, 64 deletions
diff --git a/filesystemwidget.cpp b/filesystemwidget.cpp index 33c6be5..f5dd632 100644 --- a/filesystemwidget.cpp +++ b/filesystemwidget.cpp @@ -24,6 +24,10 @@ #include <QFile> #include <QTextStream> #include <QSqlQuery> +#include <QClipboard> +#include <QMimeData> +#include <QUrl> +#include <QList> #include "filesystemwidget.h" #include "filesystemdirproxy.h" @@ -35,7 +39,7 @@ #include "pictureviewer.h" #include "smglobals.h" -FilesystemWidget::FilesystemWidget(QWidget *parent) : QWidget(parent) { +FilesystemWidget::FilesystemWidget(QWidget *parent) : QWidget(parent), mClipboardMode(None) { mModel = new FileSystemModel; mModel->setRootPath("/"); mModel->setFilter(QDir::AllEntries | QDir::NoDot); @@ -234,66 +238,49 @@ void FilesystemWidget::deleteFiles(){ emit statusbarMessage(message); } -void FilesystemWidget::copyFiles(){ +void FilesystemWidget::toClipboard(int clipmode){ + mClipboardMode = clipmode; + QClipboard *clip = qApp->clipboard(); QModelIndexList selected = mFileView->selectionModel()->selectedRows(); + clip->clear(); + mModel->clearClipboardList(); if(selected.isEmpty()){ - emit statusbarMessage(tr("No files selected!")); return; } - QSortFilterProxyModel *proxy = static_cast<QSortFilterProxyModel*>(mFileView->model()); - QModelIndex rootIndex = proxy->mapToSource(mFileView->rootIndex()); - QFileInfo root = mModel->fileInfo(rootIndex); - QString message = QString(tr("Really copy %1 files to %2?")).arg(selected.count()).arg(root.absoluteFilePath()); - int retval = QMessageBox::question(this, tr("Question"), message, QMessageBox::Yes | QMessageBox::No); - if(retval == QMessageBox::Yes){ - int files(0), dirs(0), failed(0); - foreach(QModelIndex idx, selected){ - QModelIndex real = proxy->mapToSource(idx); - QFileInfo info = mModel->fileInfo(real); - if(info.isDir()){ - ++dirs; - copyRecursive(info, root.absoluteFilePath()); - }else{ - QString newFile = QString("%1/%2").arg(root.absoluteFilePath()).arg(info.fileName()); - if(QFile::copy(info.absoluteFilePath(), newFile)){ - ++files; - }else{ - ++failed; - } - } + QList<QUrl> files; + foreach(QModelIndex idx, selected){ + if(idx.data(QFileSystemModel::FileNameRole).toString() == ".."){ + continue; } - QString message = QString(tr("Successfully copied %1 files and %2 directories, %3 errors")).arg(files).arg(dirs).arg(failed); - statusbarMessage(message); - mFileView->selectionModel()->clearSelection(); + files << QUrl::fromLocalFile(idx.data(QFileSystemModel::FilePathRole).toString()); + mModel->markForClipboard(mFileProxy->mapToSource(idx)); } + QMimeData *mimeData = new QMimeData; + mimeData->setUrls(files); + clip->setMimeData(mimeData); } -void FilesystemWidget::moveFiles(){ - QModelIndexList selected = mFileView->selectionModel()->selectedRows(); - if(selected.isEmpty()){ - emit statusbarMessage(tr("No files selected!")); +void FilesystemWidget::fromClipboard(){ + QClipboard *clip = qApp->clipboard(); + const QMimeData *mimeData = clip->mimeData(); + if(!mimeData->hasUrls()){ return; } - QSortFilterProxyModel *proxy = static_cast<QSortFilterProxyModel*>(mFileView->model()); - QModelIndex rootIndex = proxy->mapToSource(mFileView->rootIndex()); - QFileInfo root = mModel->fileInfo(rootIndex); - QString message = QString(tr("Really move %1 file(s) to %2?")).arg(selected.count()).arg(root.absoluteFilePath()); - int retval = QMessageBox::question(this, tr("Question"), message, QMessageBox::Yes | QMessageBox::No); - if(retval == QMessageBox::Yes){ - int success(0), failed(0); - foreach(QModelIndex cur, selected){ - QModelIndex real = proxy->mapToSource(cur); - QFileInfo info = mModel->fileInfo(real); - QString dest = QString("%1/%2").arg(root.absoluteFilePath()).arg(info.fileName()); - if(QFile::rename(info.absoluteFilePath(), dest)){ - ++success; - }else{ - ++failed; - } - } - QString message = QString(tr("Successfully moved %1 file(s), %2 errors")).arg(success).arg(failed); - emit statusbarMessage(message); - mFileView->selectionModel()->clearSelection(); + QStringList files; + foreach(QUrl url, mimeData->urls()){ + files << url.toLocalFile(); + } + const QString destDir = selectedDir(); + QFileInfo destDirFi(destDir); + if(!destDirFi.isDir()){ + return; + } + if(mClipboardMode == Copy){ + mModel->clearClipboardList(); + copyFiles(files, destDir); + }else if(mClipboardMode == Cut){ + mModel->clearClipboardList(); + moveFiles(files, destDir); } } @@ -478,6 +465,26 @@ void FilesystemWidget::deleteRecursive(const QFileInfo &start){ } } +void FilesystemWidget::copyFiles(const QStringList &files, const QString &dest){ + foreach(const QString file, files){ + QFileInfo fi(file); + if(fi.isDir()){ + copyRecursive(fi, dest); + }else if(fi.isFile()){ + const QString destFile = QString("%1/%2").arg(dest).arg(fi.fileName()); + QFile::copy(fi.absoluteFilePath(), destFile); + } + } +} + +void FilesystemWidget::moveFiles(const QStringList &files, const QString &dest){ + foreach(const QString file, files){ + QFileInfo fi(file); + const QString destFile = QString("%1/%2").arg(dest).arg(fi.fileName()); + QFile::rename(file, destFile); + } +} + QPair<QString, QStringList> FilesystemWidget::programData(const QString &prefix, const QString &preferred){ QSettings s; QString section = QString("programs_%1").arg(prefix); @@ -521,6 +528,14 @@ void FilesystemWidget::copyRecursive(const QFileInfo &start, const QString &dest } } +const QString FilesystemWidget::selectedDir(){ + const QModelIndexList selected = mDirView->selectionModel()->selectedRows(); + if(!selected.isEmpty()){ + return selected.at(0).data(QFileSystemModel::FilePathRole).toString(); + } + return QString(); +} + void FilesystemWidget::dirExpanded(const QModelIndex &idx){ QModelIndex real = mDirProxy->mapToSource(idx); if(real.isValid()){ @@ -587,6 +602,9 @@ QVariant FileSystemModel::data(const QModelIndex &index, int role) const{ if(mSeen.keys().contains(path)){ return QBrush(Qt::red); } + if(mClipEntries.contains(index)){ + return QBrush(Qt::darkBlue); + } } return QFileSystemModel::data(index, role); } @@ -610,6 +628,22 @@ void FileSystemModel::markAsSeen(const QString &path, bool seen){ } } +void FileSystemModel::markForClipboard(const QPersistentModelIndex &idx){ + if(idx.isValid()){ + if(!mClipEntries.contains(idx)){ + mClipEntries << idx; + } + } +} + +void FileSystemModel::clearClipboardList(){ + QList<QPersistentModelIndex> tmp(mClipEntries); + mClipEntries.clear(); + foreach(QPersistentModelIndex ent, tmp){ + emit dataChanged(ent, ent); + } +} + void FileSystemModel::cleanup(){ QStringList toRemove; foreach(QString p, mSeen.keys()){ diff --git a/filesystemwidget.h b/filesystemwidget.h index ee0b9b3..b54fdad 100644 --- a/filesystemwidget.h +++ b/filesystemwidget.h @@ -32,6 +32,7 @@ class QSqlQuery; class FilesystemWidget : public QWidget { Q_OBJECT public: + enum ClipboardMode { Copy, Cut, None }; FilesystemWidget(QWidget *parent = 0); ~FilesystemWidget() {} FileView *fileView() { return mFileView; } @@ -54,8 +55,8 @@ class FilesystemWidget : public QWidget { void parentDir(); void goBack(); void deleteFiles(); - void copyFiles(); - void moveFiles(); + void toClipboard(int clipmode); + void fromClipboard(); void renameFile(); void renameCover(const QString &infix); void setTemplate(); @@ -73,7 +74,10 @@ class FilesystemWidget : public QWidget { private: void setWindowTitle(const QString &dir); void deleteRecursive(const QFileInfo &start); + void copyFiles(const QStringList &files, const QString &dest); + void moveFiles(const QStringList &files, const QString &dest); void copyRecursive(const QFileInfo &start, const QString &destdir); + const QString selectedDir(); QPair<QString, QStringList> programData(const QString &prefix, const QString &preferred); QStringList selectedFiles(); QStringList mExpandedDirs; @@ -88,6 +92,7 @@ class FilesystemWidget : public QWidget { qint64 mSize; PictureViewer *mPicViewer; QString mLastDir; + int mClipboardMode; }; class FileSystemModel : public QFileSystemModel { @@ -100,6 +105,8 @@ class FileSystemModel : public QFileSystemModel { public slots: void markAsSeen(const QString &path, bool seen); + void markForClipboard(const QPersistentModelIndex &idx); + void clearClipboardList(); private: void cleanup(); @@ -107,6 +114,7 @@ class FileSystemModel : public QFileSystemModel { QSqlDatabase mDb; QSqlQuery *mDeleteFromSeenQuery; QSqlQuery *mMarkAsSeenQuery; + QList<QPersistentModelIndex> mClipEntries; }; #endif @@ -332,12 +332,19 @@ void SheMov::createActions(){ mDeleteFilesA = new QAction(tr("Delete selected..."), this); mDeleteFilesA->setShortcut(tr("CTRL+d")); connect(mDeleteFilesA, SIGNAL(triggered()), mFSWidget, SLOT(deleteFiles())); - mCopyA = new QAction(tr("Copy file(s)..."), this); - mCopyA->setShortcut(tr("CTRL+v")); - connect(mCopyA, SIGNAL(triggered()), mFSWidget, SLOT(copyFiles())); - mMoveA = new QAction(tr("Move file(s)..."), this); - mMoveA->setShortcut(tr("CTRL+m")); - connect(mMoveA, SIGNAL(triggered()), mFSWidget, SLOT(moveFiles())); + QSignalMapper *copyCutMapper = new QSignalMapper(this); + mCopyA = new QAction(tr("Copy"), this); + mCopyA->setShortcut(tr("CTRL+c")); + copyCutMapper->setMapping(mCopyA, FilesystemWidget::Copy); + connect(mCopyA, SIGNAL(triggered()), copyCutMapper, SLOT(map())); + mCutA = new QAction(tr("Cut"), this); + mCutA->setShortcut(tr("CTRL+x")); + copyCutMapper->setMapping(mCutA, FilesystemWidget::Cut); + connect(mCutA, SIGNAL(triggered()), copyCutMapper, SLOT(map())); + connect(copyCutMapper, SIGNAL(mapped(int)), mFSWidget, SLOT(toClipboard(int))); + mPasteA = new QAction(tr("Paste"), this); + mPasteA->setShortcut(tr("Ctrl+v")); + connect(mPasteA, SIGNAL(triggered()), mFSWidget, SLOT(fromClipboard())); mRenameA = new QAction(tr("Rename..."), this); mRenameA->setShortcut(tr("CTRL+r")); connect(mRenameA, SIGNAL(triggered()), mFSWidget, SLOT(renameFile())); @@ -380,7 +387,6 @@ void SheMov::createActions(){ mRenameMapper->setMapping(mRenameCoverBA, tr("back")); mRenameCoverBA->setData("RenameMenu"); mRenameCoverCA = new QAction(tr("Rename to cover"), this); - mRenameCoverCA->setShortcut(tr("CTRL+c")); connect(mRenameCoverCA, SIGNAL(triggered()), mRenameMapper, SLOT(map())); mRenameMapper->setMapping(mRenameCoverCA, tr("cover")); mRenameCoverCA->setData("RenameMenu"); @@ -549,17 +555,22 @@ void SheMov::createMenus(){ mEditFSMenu->addAction(mDeleteFilesA); mEditFSMenu->addSeparator(); mEditFSMenu->addAction(mCopyA); - mEditFSMenu->addAction(mMoveA); + mEditFSMenu->addAction(mCutA); + mEditFSMenu->addAction(mPasteA); mEditFSMenu->addAction(mRenameA); mRenameMenu = new QMenu(tr("&Rename..."), this); mRenameMenu->addAction(mTemplateA); mRenameMenu->addAction(mRenameCoverFA); mRenameMenu->addAction(mRenameCoverBA); mRenameMenu->addAction(mRenameCoverCA); - mRenameMenuA = new QAction(tr("&Rename"), this); + mRenameMenuA = new QAction(tr("&Rename to"), this); mRenameMenuA->setMenu(mRenameMenu); mEditFSMenu->addAction(mRenameMenuA); mEditFSMenu->addSeparator(); + mEditFSMenu->addAction(mCopyA); + mEditFSMenu->addAction(mCutA); + mEditFSMenu->addAction(mPasteA); + mEditFSMenu->addSeparator(); mEditFSMenu->addAction(mMountDvdA); mEditFSMenu->addSeparator(); mEditFSMenu->addAction(mMarkA); @@ -636,9 +647,13 @@ void SheMov::createMenus(){ mFSWidget->fileView()->addAction(mCreateFolderA); mFSWidget->fileView()->addAction(mDeleteFilesA); mFSWidget->fileView()->addAction(mRenameA); - mFSWidget->fileView()->addAction(mCopyA); - mFSWidget->fileView()->addAction(mMoveA); mFSWidget->fileView()->addAction(mRenameMenuA); + QAction *sep16 = new QAction(this); + sep16->setSeparator(true); + mFSWidget->fileView()->addAction(sep16); + mFSWidget->fileView()->addAction(mCopyA); + mFSWidget->fileView()->addAction(mCutA); + mFSWidget->fileView()->addAction(mPasteA); QAction *sep10 = new QAction(this); sep10->setSeparator(true); mFSWidget->fileView()->addAction(sep10); @@ -75,6 +75,8 @@ class SheMov : public QMainWindow { QAction *mDeleteFilesA; QAction *mRefreshA; QAction *mCopyA; + QAction *mCutA; + QAction *mPasteA; QAction *mMoveA; QAction *mRenameA; QAction *mCdupA; |