win32.cpp \
thumbnailview.cpp \
thumbnaildelegate.cpp \
- thumbnailworker.cpp
+ thumbnailworker.cpp \
+ folderview_private.cpp
HEADERS += mainwindow.h \
renamesingledialog.h \
abstractrenamedialog.h \
thumbnailview.h \
thumbnaildelegate.h \
- thumbnailworker.h
+ thumbnailworker.h \
+ folderview_private.h \
+ operationworker.h
FORMS += mainwindow.ui \
renamesingledialog.ui \
Gefu is an Experimental File Utility.
+ * 内蔵ビューアでのファイル読み込みを別スレッド化
+ * 内蔵テキストビューアの自分描画
+ * バイナリエディタ
+
#### 2014/09/16 Ver 0.24
* ツールバーの表示/非表示を切り替えられるようにしました。
* ドラッグ検出のピクセル閾値を小さくしました。
* フォルダビューのコンテキストメニューを変更しました。
* フィルタラベルもフォルダビューと同じ文字色・背景色に変更しました。
* サムネイル生成スレッドの優先度を調整しました。
- * 不具合修正
+ * 不具合修正
* 単画面モードで検索ボックスが表示されなかったのを修正。
* メニューの活性・非活性の整合性を修正。
* サムネイルモードで拡大が行われていたのを修正。
#include "abstractworker.h"\r
\r
-AbstractWorker::AbstractWorker(QObject *parent) :\r
- QObject(parent),\r
- m_Mutex(),\r
- m_stopRequested(false)\r
+#include <QThread>\r
+\r
+AbstractWorker::AbstractWorker() :\r
+ QObject(),\r
+ m_mutex(),\r
+ m_abort(false),\r
+ m_thread(new QThread())\r
{\r
+ connect(m_thread, SIGNAL(started()), this, SLOT(run()));\r
+ connect(this, SIGNAL(finished()), m_thread, SLOT(quit()));\r
+ connect(this, SIGNAL(finished()), this, SLOT(deleteLater()));\r
+ connect(m_thread, SIGNAL(finished()), m_thread, SLOT(deleteLater()));\r
}\r
\r
-void AbstractWorker::requestStop() {\r
- QMutexLocker lock(&m_Mutex);\r
- m_stopRequested = true;\r
+void AbstractWorker::abort()\r
+{\r
+ QMutexLocker lock(&m_mutex);\r
+ m_abort = true;\r
}\r
\r
-bool AbstractWorker::isStopRequested() {\r
- QMutexLocker lock(&m_Mutex);\r
- return m_stopRequested;\r
+void AbstractWorker::start()\r
+{\r
+ this->moveToThread(m_thread);\r
+ m_thread->start();\r
}\r
+\r
+bool AbstractWorker::isAborted()\r
+{\r
+ QMutexLocker lock(&m_mutex);\r
+ return m_abort;\r
+}\r
+\r
#ifndef ABSTRACTWORKER_H\r
#define ABSTRACTWORKER_H\r
\r
-#include <QLabel>\r
-#include <QMutex>\r
#include <QObject>\r
\r
class AbstractWorker : public QObject\r
{\r
Q_OBJECT\r
public:\r
- explicit AbstractWorker(QObject *parent = 0);\r
+ explicit AbstractWorker();\r
\r
- void requestStop();\r
+ void abort();\r
+ void start();\r
\r
protected:\r
- bool isStopRequested();\r
+ QMutex m_mutex;\r
+\r
+ bool isAborted();\r
\r
signals:\r
- void canceled();\r
- void error(const QString &msg);\r
- void finished();\r
- void information(const QString &msg);\r
- void operation(const QString &msg);\r
- void success(const QString &msg);\r
+ void finished(bool abort = false);\r
\r
public slots:\r
- virtual void operate() = 0;\r
+ virtual void run() = 0;\r
\r
private:\r
- QMutex m_Mutex;\r
- bool m_stopRequested;\r
+ bool m_abort;\r
+ QThread* m_thread;\r
};\r
\r
#endif // ABSTRACTWORKER_H\r
#include <QDateTime>\r
#include <QThread>\r
\r
-CopyMoveWorker::CopyMoveWorker(QObject *parent) :\r
- AbstractWorker(parent),\r
- m_CopyList(NULL),\r
+const int SLEEP_TIME = 1;\r
+\r
+CopyMoveWorker::CopyMoveWorker() :\r
+ OperationWorker(),\r
+ m_CopyList(),\r
m_tgtDir(),\r
m_CopyMap(),\r
m_AskingMutex(),\r
{\r
}\r
\r
-void CopyMoveWorker::operate()\r
+void CopyMoveWorker::Listup(const QString &srcPath, const QString &tgtPath)\r
{\r
- if (m_Move) {\r
- emit information(tr("移動準備中..."));\r
+ if (isAborted()) {\r
+ return;\r
}\r
- else {\r
- emit information(tr("コピー準備中..."));\r
+ this->thread()->msleep(SLEEP_TIME);\r
+\r
+ QFileInfo info(srcPath);\r
+ QDir tgtDir(tgtPath);\r
+\r
+ m_CopyMap.insert(srcPath, tgtDir.absoluteFilePath(info.fileName()));\r
+ if (!info.isDir()) {\r
+ return;\r
+ }\r
+\r
+ QDir srcDir(srcPath);\r
+ QFileInfoList list = srcDir.entryInfoList(QDir::NoDotAndDotDot |\r
+ QDir::System |\r
+ QDir::Hidden |\r
+ QDir::AllDirs |\r
+ QDir::Files,\r
+ QDir::DirsFirst);\r
+ foreach (QFileInfo info2, list) {\r
+ Listup(info2.absoluteFilePath(),\r
+ tgtDir.absoluteFilePath(info.fileName()));\r
}\r
+}\r
\r
- foreach (const QFileInfo &info, *m_CopyList) {\r
- if (isStopRequested()) {\r
- emit canceled();\r
+///////////////////////////////////////////////////////////////////////////////\r
+/// \brief CopyMoveWorker::run\r
+///\r
+void CopyMoveWorker::run()\r
+{\r
+ foreach (const QString &path, m_CopyList) {\r
+ if (isAborted()) {\r
+ emit finished(true);\r
return;\r
}\r
- Listup(info.absoluteFilePath(), m_tgtDir);\r
+ Listup(path, m_tgtDir);\r
}\r
\r
bool ret;\r
int skipCount = 0;\r
int errorCount = 0;\r
int errDelCount = 0;\r
+ const QString operation = (m_Move) ? tr("移動:%1 -> %2") :\r
+ tr("コピー:%1 -> %2");\r
QString msg;\r
QString copyMethod;\r
QString alias;\r
StringMap::iterator it;\r
for (it = m_CopyMap.begin(); it != m_CopyMap.end(); it++) {\r
- if (isStopRequested()) {\r
- emit canceled();\r
+ this->thread()->msleep(SLEEP_TIME);\r
+ if (isAborted()) {\r
+ emit finished(true);\r
return;\r
}\r
QFileInfo srcInfo(it.key());\r
QFileInfo tgtInfo(it.value());\r
\r
- emit operation((m_Move ? tr("移動") : tr("コピー:"))\r
- + srcInfo.absoluteFilePath()\r
- + tr(" -> ")\r
- + tgtInfo.absoluteFilePath());\r
+ emit progress(operation\r
+ .arg(srcInfo.absoluteFilePath())\r
+ .arg(tgtInfo.absoluteFilePath()));\r
\r
if (srcInfo.isDir()) {\r
if (tgtInfo.exists()) {\r
}\r
\r
// キャンセルされた?\r
- if (isStopRequested()) {\r
+ if (isAborted()) {\r
msg = tr("%1個のファイルをコピーしました。").arg(successCount);\r
if (skipCount > 0) {\r
msg += tr("%1個のファイルをスキップしました。").arg(skipCount);\r
if (errorCount > 0) {\r
msg += tr("%1個のファイルをコピーできませんでした。").arg(errorCount);\r
}\r
- emit information(msg);\r
- emit canceled();\r
+ emit progress(msg);\r
+ emit finished(true);\r
return;\r
}\r
\r
break;\r
}\r
}\r
- emit operation(tr("=>") + tgtInfo.fileName() + tr("にリネーム"));\r
+ emit progress(tr("=> %1 にリネーム").arg(tgtInfo.fileName()));\r
}\r
else if (copyMethod == "rbSkip") {\r
emit success(tr("スキップ"));\r
}\r
else if (copyMethod == "rbRename") {\r
tgtInfo.setFile(tgtInfo.absolutePath(), alias);\r
- emit operation(tr("=>") + tgtInfo.fileName() + tr("にリネーム"));\r
+ emit progress(tr("=> %1 にリネーム").arg(tgtInfo.fileName()));\r
}\r
else {\r
qDebug() << "Unknown method : " << copyMethod;\r
emit finished();\r
}\r
\r
-void CopyMoveWorker::Listup(const QString &srcPath, const QString &tgtPath)\r
+QString CopyMoveWorker::initialText() const\r
{\r
- if (isStopRequested()) {\r
- return;\r
+ if (m_Move) {\r
+ return tr("移動準備中...");\r
}\r
-\r
- QFileInfo info(srcPath);\r
- QDir tgtDir(tgtPath);\r
-\r
- m_CopyMap.insert(srcPath, tgtDir.absoluteFilePath(info.fileName()));\r
- qDebug() << srcPath << " -> " << tgtDir.absoluteFilePath(info.fileName());\r
- if (info.isDir()) {\r
- QDir srcDir(srcPath);\r
- foreach (QFileInfo info2, srcDir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) {\r
- Listup(info2.absoluteFilePath(),\r
- tgtDir.absoluteFilePath(info.fileName()));\r
- }\r
+ else {\r
+ return tr("コピー準備中...");\r
}\r
}\r
#ifndef COPYWORKER_H\r
#define COPYWORKER_H\r
\r
-#include "abstractworker.h"\r
+#include "operationworker.h"\r
#include "global.h"\r
\r
#include <QFileInfo>\r
\r
-class CopyMoveWorker : public AbstractWorker\r
+class CopyMoveWorker : public OperationWorker\r
{\r
Q_OBJECT\r
public:\r
- explicit CopyMoveWorker(QObject *parent = 0);\r
+ explicit CopyMoveWorker();\r
\r
- void setCopyList(const QFileInfoList *list) {\r
+ void setCopyList(const QStringList &list) {\r
m_CopyList = list;\r
}\r
void setTargetDir(const QString &path) {\r
const QString &srcPath, const QString &tgtPath);\r
\r
public slots:\r
- void operate();\r
\r
private:\r
- const QFileInfoList *m_CopyList;\r
+ QStringList m_CopyList;\r
QString m_tgtDir;\r
StringMap m_CopyMap;\r
QMutex m_AskingMutex;\r
}\r
\r
void Listup(const QString &srcPath, const QString &tgtPath);\r
+\r
+ // AbstractWorker interface\r
+public slots:\r
+ void run();\r
+\r
+ // OperationWorker interface\r
+public:\r
+ QString initialText() const;\r
};\r
\r
#endif // COPYWORKER_H\r
#include "deleteworker.h"\r
+\r
#include <QFileInfo>\r
#include <QDir>\r
#include <QDebug>\r
+#include <QThread>\r
+\r
+const int SLEEP_TIME = 1;\r
\r
-DeleteWorker::DeleteWorker(QObject *parent) :\r
- AbstractWorker(parent),\r
- m_DeleteList(NULL),\r
+DeleteWorker::DeleteWorker() :\r
+ OperationWorker(),\r
+ m_DeleteList(),\r
m_Targets()\r
{\r
}\r
\r
-void DeleteWorker::operate()\r
+void DeleteWorker::Listup(const QString &path)\r
{\r
- emit information(tr("削除準備中..."));\r
+ if (isAborted()) {\r
+ return;\r
+ }\r
+ this->thread()->msleep(SLEEP_TIME);\r
+\r
+ if (QFileInfo(path).isDir()) {\r
+ QDir dir(path);\r
+ QFileInfoList list = dir.entryInfoList(QDir::NoDotAndDotDot |\r
+ QDir::System |\r
+ QDir::Hidden |\r
+ QDir::AllDirs |\r
+ QDir::Files,\r
+ QDir::DirsFirst);\r
+ foreach (const QFileInfo &info, list) {\r
+ Listup(info.absoluteFilePath());\r
+ }\r
+ }\r
+\r
+ m_Targets << path;\r
+}\r
\r
- foreach (const QFileInfo &info, *m_DeleteList) {\r
- if (isStopRequested()) {\r
- emit canceled();\r
+\r
+void DeleteWorker::run()\r
+{\r
+ foreach (const QFileInfo &info, m_DeleteList) {\r
+ if (isAborted()) {\r
+ emit finished(true);\r
return;\r
}\r
Listup(info.absoluteFilePath());\r
int errorCount = 0;\r
QString msg;\r
foreach (const QString &path, m_Targets) {\r
- if (isStopRequested()) {\r
- emit canceled();\r
+ this->thread()->msleep(SLEEP_TIME);\r
+ if (isAborted()) {\r
+ emit finished(true);\r
return;\r
}\r
\r
- emit operation(tr("削除:") + path);\r
+ emit progress(tr("削除:%1").arg(path));\r
\r
QFileInfo info(path);\r
if (info.isDir()) {\r
emit finished();\r
}\r
\r
-void DeleteWorker::Listup(const QString &path)\r
+QString DeleteWorker::initialText() const\r
{\r
- if (isStopRequested()) {\r
- return;\r
- }\r
-\r
- if (QFileInfo(path).isDir()) {\r
- QDir dir(path);\r
- QFileInfoList list = dir.entryInfoList(QDir::NoDotAndDotDot |\r
- QDir::System |\r
- QDir::Hidden |\r
- QDir::AllDirs |\r
- QDir::Files,\r
- QDir::DirsFirst);\r
- foreach (const QFileInfo &info, list) {\r
- Listup(info.absoluteFilePath());\r
- }\r
- }\r
-\r
- m_Targets << path;\r
+ return tr("削除準備中...");\r
}\r
#ifndef DELETEWORKER_H\r
#define DELETEWORKER_H\r
\r
-#include "abstractworker.h"\r
+#include "operationworker.h"\r
\r
#include <QFileInfoList>\r
+#include <QStringList>\r
\r
-class DeleteWorker : public AbstractWorker\r
+class DeleteWorker : public OperationWorker\r
{\r
Q_OBJECT\r
public:\r
- explicit DeleteWorker(QObject *parent = 0);\r
+ explicit DeleteWorker();\r
\r
- void setDeleteList(const QFileInfoList *list) {\r
+ void setDeleteList(const QFileInfoList &list) {\r
m_DeleteList = list;\r
}\r
\r
-public slots:\r
- void operate();\r
-\r
private:\r
- const QFileInfoList *m_DeleteList;\r
- QStringList m_Targets;\r
+ QFileInfoList m_DeleteList;\r
+ QStringList m_Targets;\r
\r
void Listup(const QString &path);\r
+\r
+ // AbstractWorker interface\r
+public slots:\r
+ void run();\r
+\r
+ // OperationWorker interface\r
+public:\r
+ QString initialText() const;\r
};\r
\r
#endif // DELETEWORKER_H\r
m_font()\r
{\r
// サムネイル生成用スレッドを初期化する\r
- QThread *thread = new QThread();\r
m_worker = new ThumbnailWorker();\r
- m_worker->moveToThread(thread);\r
connect(m_worker, SIGNAL(resultReady(QString,QPixmap)), this, SLOT(thumbnail_Ready(QString,QPixmap)));\r
- connect(m_worker, SIGNAL(finished()), thread, SLOT(quit()));\r
- connect(thread, SIGNAL(started()), m_worker, SLOT(doWork()));\r
- thread->start();\r
+ m_worker->start();\r
\r
connect(&m_fsWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(fsWatcher_directoryChanged(QString)));\r
}\r
///\r
FolderModel::~FolderModel()\r
{\r
- m_worker->finish();\r
- m_worker->thread()->quit();\r
- m_worker->thread()->wait();\r
+ m_worker->abort();\r
}\r
\r
///////////////////////////////////////////////////////////////////////////////\r
///\r
void FolderModel::thumbnail_Ready(const QString &path, const QPixmap &pixmap)\r
{\r
+ qDebug() << "FolderModel::thumbnail_Ready()" << path;\r
QFileInfo fi(path);\r
if (fi.absolutePath() == m_dir.absolutePath()) {\r
m_pixmapCacheMutex.lock();\r
-#include "folderpanel.h"
#include "mainwindow.h"
#include "preferences.h"
#include "folderview.h"
#include <QApplication>
#include <QDebug>
-#include <QDrag>
#include <QHeaderView>
-#include <QMouseEvent>
-#include <QMimeData>
///////////////////////////////////////////////////////////////////////////////
/// \brief FolderView::FolderView
FolderView::FolderView(QWidget *parent) :
QTableView(parent),
AbstractView(),
- m_dragStartPos(),
- m_dragging(false),
- m_saveRow(0),
- m_savePath(),
- m_saveName()
+ m_p(this)
{
- setDragEnabled(true);
- setAcceptDrops(true);
- setDropIndicatorShown(true);
- setContextMenuPolicy(Qt::DefaultContextMenu);
}
///////////////////////////////////////////////////////////////////////////////
qDebug() << "FolderView::initialize()";
connect(this, SIGNAL(doubleClicked(QModelIndex)), w, SLOT(onOpen(QModelIndex)));
+ connect(&m_p, SIGNAL(copyItems(QStringList,QString)), w, SLOT(copyItems(QStringList,QString)));
+ connect(&m_p, SIGNAL(moveItems(QStringList,QString)), w, SLOT(moveItems(QStringList,QString)));
installEventFilter(w);
+ viewport()->installEventFilter(&m_p);
viewport()->installEventFilter(w);
}
-///////////////////////////////////////////////////////////////////////////////
-/// \brief FolderView::selectedItems
-/// \return
-///
-QFileInfoList FolderView::selectedItems() const
-{
- QFileInfoList list = folderModel()->markedItems();
- if (list.isEmpty()) {
- list << folderModel()->fileInfo(currentIndex());
- }
-
- return list;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// \brief FolderView::model_PreReset
-///
-/// モデルリセット前の処理
-///
-void FolderView::model_PreReset()
-{
- qDebug() << "FolderView::model_PreReset()";
-
- // 現在行と名前を保存しておく
- if (model() && currentIndex().isValid()) {
- m_saveRow = currentIndex().row();
- m_saveName = folderModel()->fileName(currentIndex());
- m_savePath = folderModel()->rootPath();
- }
- else {
- m_saveRow = 0;
- m_saveName = QString::null;
- m_savePath = QString::null;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// \brief FolderView::model_PostReset
-///
-/// モデルリセット後の処理
-///
-void FolderView::model_PostReset()
-{
- qDebug() << "FolderView::model_PostReset()";
-
- // フォルダが変わった場合は先頭行を選択する
- if (m_savePath != folderModel()->rootPath()) {
- setCurrentIndex(model()->index(0, 0));
- return;
- }
-
- // 保存した名前と同名アイテムが見つかれば、再選択する
- for (int row = 0; row < model()->rowCount(); row++) {
- QModelIndex index = model()->index(row, 0);
- if (folderModel()->fileName(index) == m_saveName) {
- setCurrentIndex(index);
- return;
- }
- }
-
- // 同名アイテムが見つからなければ、行を維持する
- if (m_saveRow >= model()->rowCount()) {
- m_saveRow = model()->rowCount() - 1;
- }
- setCurrentIndex(model()->index(m_saveRow, 1));
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// \brief FolderView::mousePressEvent
-/// \param event
-///
-void FolderView::mousePressEvent(QMouseEvent *event)
-{
- m_dragStartPos = QPoint();
- if ((event->buttons() & Qt::LeftButton) ||
- (event->buttons() & Qt::RightButton))
- {
- QModelIndex index = indexAt(event->pos());
- if (index.isValid() && folderModel()->fileName(index) != "..") {
- m_dragStartPos = event->pos();
- }
- }
-
- QTableView::mousePressEvent(event);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// \brief FolderView::mouseMoveEvent
-/// \param event
-///
-void FolderView::mouseMoveEvent(QMouseEvent *event)
-{
- if (!(event->buttons() & Qt::LeftButton) &&
- !(event->buttons() & Qt::RightButton))
- {
- QTableView::mouseMoveEvent(event);
- return;
- }
- if (m_dragStartPos.isNull() ||
- (event->pos() - m_dragStartPos).manhattanLength() < 5)
- {
- QTableView::mouseMoveEvent(event);
- return;
- }
-
- QFileInfoList list = selectedItems();
- if (list.size() == 1 && list[0].fileName() == "..") {
- QTableView::mouseMoveEvent(event);
- return;
- }
-
- QList<QUrl> urls;
- foreach (const QFileInfo &info, list) {
- urls << QUrl::fromLocalFile(info.absoluteFilePath());
- }
-
- QDrag *drag = new QDrag(this);
- QMimeData *mimeData = new QMimeData;
- mimeData->setUrls(urls);
- drag->setMimeData(mimeData);
-
- m_dragging = true;
- drag->exec(Qt::CopyAction);
- m_dragging = false;
- m_dragStartPos = QPoint();
-}
-
-void FolderView::dragEnterEvent(QDragEnterEvent *event)
-{
- qDebug() << "FolderView::dragEnterEvent()";
-
- if (event->mimeData()->hasUrls()) {
- event->acceptProposedAction();
- return;
- }
-
- QTableView::dragEnterEvent(event);
-}
-
void FolderView::setModel(QAbstractItemModel *model)
{
if (this->model()) {
QTableView::setModel(model);
if (this->model()) {
- connect(this->model(), SIGNAL(modelAboutToBeReset()), this, SLOT(model_PreReset()));
- connect(this->model(), SIGNAL(modelReset()), this, SLOT(model_PostReset()));
+ connect(this->model(), SIGNAL(modelAboutToBeReset()), &m_p, SLOT(model_PreReset()));
+ connect(this->model(), SIGNAL(modelReset()), &m_p, SLOT(model_PostReset()));
// 列の幅を設定する
horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
#define FOLDERVIEW_H
#include "abstractview.h"
+#include "folderview_private.h"
#include "foldermodel.h"
#include <QTableView>
class FolderView : public QTableView, public AbstractView
{
Q_OBJECT
- Q_PROPERTY(bool dragging MEMBER m_dragging READ isDragging())
public:
explicit FolderView(QWidget *parent = 0);
void initialize(MainWindow *w);
- bool isDragging();
FolderModel* folderModel() const;
- QFileInfoList selectedItems() const;
private:
- QPoint m_dragStartPos;
- bool m_dragging;
- int m_saveRow;
- QString m_savePath;
- QString m_saveName;
+ FolderView_Private m_p;
signals:
private slots:
- void model_PreReset();
- void model_PostReset();
-
- // QWidget interface
-protected:
- void mousePressEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void dragEnterEvent(QDragEnterEvent *event);
// QAbstractItemView interface
public:
void scaleDown();
};
-inline bool FolderView::isDragging()
-{
- return m_dragging;
-}
-
inline FolderModel *FolderView::folderModel() const
{
return static_cast<FolderModel*>(model());
--- /dev/null
+#include "foldermodel.h"
+#include "folderview_private.h"
+
+#include <QDebug>
+#include <QDrag>
+#include <QDragEnterEvent>
+#include <QEvent>
+#include <QMenu>
+#include <QMimeData>
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief FolderView_Private::FolderView_Private
+/// \param parent 親オブジェクト
+///
+/// コンストラクタ
+///
+FolderView_Private::FolderView_Private(QAbstractItemView *parent) :
+ QObject(parent),
+ m_view(parent),
+ m_dragStartPos(),
+ m_dragging(false),
+ m_saveRow(0),
+ m_savePath(),
+ m_saveName()
+{
+ m_view->setDragEnabled(true);
+ m_view->setAcceptDrops(true);
+ m_view->setDropIndicatorShown(true);
+ m_view->setContextMenuPolicy(Qt::DefaultContextMenu);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief FolderView_Private::onDragEnter
+/// \param obj イベントが発生したオブジェクト
+/// \param e ドラッグエンターイベントオブジェクト
+/// \return 処理した場合はtrueを返します。
+///
+bool FolderView_Private::onDragEnter(QObject *obj, QDragEnterEvent *e)
+{
+ Q_UNUSED(obj);
+
+ if (e->mimeData()->hasUrls()) {
+ e->acceptProposedAction();
+ return true;
+ }
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief FolderView_Private::onDrop
+/// \param obj イベントが発生したオブジェクト
+/// \param e ドロップイベントオブジェクト
+/// \return 処理した場合はtrueを返します。
+///
+bool FolderView_Private::onDrop(QObject *obj, QDropEvent *e)
+{
+ Q_UNUSED(obj);
+
+ if (m_dragging) {
+ // 自分自身へのドロップなら何もしない
+ return true;
+ }
+
+ QStringList list;
+ foreach (const QUrl &url, e->mimeData()->urls()) {
+ QString path = QFileInfo(url.toLocalFile()).canonicalFilePath();
+ if (!path.isEmpty()) {
+ list << path;
+ }
+ else {
+ qDebug() << "drop path is empty." << url;
+ }
+ }
+
+ if (list.isEmpty()) {
+ // ローカルファイルのドロップでなければ何もしない
+ return true;
+ }
+
+ e->acceptProposedAction();
+
+ QMenu menu(m_view);
+ QAction *actCopy = menu.addAction(tr("コピー"));
+ QAction *actMove = menu.addAction(tr("移動"));
+ menu.addSeparator();
+ menu.addAction(tr("キャンセル"));
+
+ QAction *selected = menu.exec(m_view->mapToGlobal(e->pos()));
+ FolderModel *model = static_cast<FolderModel*>(m_view->model());
+ if (selected == actMove) {
+ emit moveItems(list, model->rootPath());
+ }
+ else if (selected == actCopy) {
+ emit copyItems(list, model->rootPath());
+ }
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief FolderView_Private::onMouseMove
+/// \param obj イベントが発生したオブジェクト
+/// \param e マウスイベントオブジェクト
+/// \return 処理した場合はtrueを返します。
+///
+bool FolderView_Private::onMouseMove(QObject *obj, QMouseEvent *e)
+{
+ Q_UNUSED(obj);
+
+ if (!(e->buttons() & Qt::LeftButton) && !(e->buttons() & Qt::RightButton))
+ {
+ return false;
+ }
+
+ if (m_dragStartPos.isNull() ||
+ (e->pos() - m_dragStartPos).manhattanLength() < 5)
+ {
+ return false;
+ }
+
+ FolderModel *model = static_cast<FolderModel*>(m_view->model());
+ QFileInfoList list = model->markedItems();
+ if (list.isEmpty()) {
+ list << model->fileInfo(m_view->currentIndex());
+ }
+ if (list.size() == 1 && list[0].fileName() == "..") {
+ return false;
+ }
+
+ QList<QUrl> urls;
+ foreach (const QFileInfo &info, list) {
+ urls << QUrl::fromLocalFile(info.absoluteFilePath());
+ }
+
+ QDrag *drag = new QDrag(this);
+ QMimeData *mimeData = new QMimeData;
+ mimeData->setUrls(urls);
+ drag->setMimeData(mimeData);
+
+ m_dragging = true;
+ drag->exec(Qt::CopyAction);
+ m_dragging = false;
+ m_dragStartPos = QPoint();
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief FolderView_Private::onMousePress
+/// \param obj イベントが発生したオブジェクト
+/// \param e マウスイベントオブジェクト
+/// \return 処理した場合はtrueを返します。
+///
+bool FolderView_Private::onMousePress(QObject *obj, QMouseEvent *e)
+{
+ Q_UNUSED(obj);
+
+ m_dragStartPos = QPoint();
+ if ((e->buttons() & Qt::LeftButton) || (e->buttons() & Qt::RightButton))
+ {
+ FolderModel *model = static_cast<FolderModel*>(m_view->model());
+ QModelIndex index = m_view->indexAt(e->pos());
+ if (index.isValid() && model->fileName(index) != "..") {
+ m_dragStartPos = e->pos();
+ }
+ }
+
+ // 本来のイベント処理も行う
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief FolderView_Private::model_PostReset
+///
+/// モデルリセット後の処理
+///
+void FolderView_Private::model_PostReset()
+{
+ FolderModel *model = static_cast<FolderModel*>(m_view->model());
+
+ // フォルダが変わった場合は先頭行を選択する
+ if (m_savePath != model->rootPath()) {
+ m_view->setCurrentIndex(model->index(0, 0));
+ return;
+ }
+
+ // 保存した名前と同名アイテムが見つかれば、再選択する
+ for (int row = 0; row < model->rowCount(); row++) {
+ QModelIndex index = model->index(row, 0);
+ if (model->fileName(index) == m_saveName) {
+ m_view->setCurrentIndex(index);
+ return;
+ }
+ }
+
+ // 同名アイテムが見つからなければ、行を維持する
+ if (m_saveRow >= model->rowCount()) {
+ m_saveRow = model->rowCount() - 1;
+ }
+ m_view->setCurrentIndex(model->index(m_saveRow, 1));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief FolderView_Private::model_PreReset
+///
+/// モデルリセット前の処理
+///
+void FolderView_Private::model_PreReset()
+{
+ // 現在行と名前を保存しておく
+ if (m_view->model() && m_view->currentIndex().isValid()) {
+ FolderModel *model = static_cast<FolderModel*>(m_view->model());
+ m_saveRow = m_view->currentIndex().row();
+ m_saveName = model->fileName(m_view->currentIndex());
+ m_savePath = model->rootPath();
+ }
+ else {
+ m_saveRow = 0;
+ m_saveName = QString::null;
+ m_savePath = QString::null;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief FolderView_Private::eventFilter
+/// \param obj イベントが発生したオブジェクト
+/// \param e イベントオブジェクト
+/// \return 処理した場合はtrueを返します。
+///
+bool FolderView_Private::eventFilter(QObject *obj, QEvent *e)
+{
+ if (e->type() == QEvent::MouseButtonPress) {
+ return onMousePress(obj, static_cast<QMouseEvent*>(e));
+ }
+ else if (e->type() == QEvent::MouseMove) {
+ return onMouseMove(obj, static_cast<QMouseEvent*>(e));
+ }
+ else if (e->type() == QEvent::DragEnter) {
+ return onDragEnter(obj, static_cast<QDragEnterEvent*>(e));
+ }
+ else if (e->type() == QEvent::Drop) {
+ return onDrop(obj, static_cast<QDropEvent*>(e));
+ }
+
+ return false;
+}
--- /dev/null
+#ifndef FOLDERVIEW_PRIVATE_H
+#define FOLDERVIEW_PRIVATE_H
+
+#include <QObject>
+#include <QAbstractItemView>
+
+class FolderView_Private : public QObject
+{
+ Q_OBJECT
+public:
+ explicit FolderView_Private(QAbstractItemView *parent = 0);
+
+private:
+ QAbstractItemView* m_view;
+ QPoint m_dragStartPos;
+ bool m_dragging;
+ int m_saveRow;
+ QString m_savePath;
+ QString m_saveName;
+
+ bool onDragEnter(QObject *obj, QDragEnterEvent *e);
+ bool onDrop(QObject *obj, QDropEvent *e);
+ bool onMouseMove(QObject *obj, QMouseEvent *e);
+ bool onMousePress(QObject *obj, QMouseEvent *e);
+
+signals:
+ void copyItems(const QStringList &list, const QString &tgtDir);
+ void moveItems(const QStringList &list, const QString &tgtDir);
+
+public slots:
+ void model_PostReset();
+ void model_PreReset();
+
+ // QObject interface
+public:
+ bool eventFilter(QObject *obj, QEvent *e);
+};
+
+#endif // FOLDERVIEW_PRIVATE_H
{\r
qDebug() << "MainWindow::onMove";\r
\r
- QFileInfoList list = selectedItems();\r
+ QStringList list;\r
+ foreach (const QFileInfo &fi, selectedItems()) {\r
+ list << fi.absoluteFilePath();\r
+ }\r
if (list.isEmpty()) {\r
return;\r
}\r
this, tr("フォルダを選択"), activeModel()->rootPath());\r
if (!path.isEmpty()) {\r
activeModel()->setRootPath(path);\r
-// updateActions();\r
}\r
}\r
\r
{\r
m_overwriteDialog.setFileInfo(srcPath, tgtPath);\r
if (m_overwriteDialog.exec() == QDialog::Rejected) {\r
- worker->requestStop();\r
+ worker->abort();\r
}\r
}\r
*copyMethod = m_overwriteDialog.copyMethod();\r
///\r
/// アイテムをコピーします。\r
///\r
-void MainWindow::copyItems(const QFileInfoList &list, const QString &tgtDir)\r
+void MainWindow::copyItems(const QStringList &list, const QString &tgtDir)\r
{\r
qDebug() << "MainWindow::copyItems()" << tgtDir;\r
\r
CopyMoveWorker *worker = new CopyMoveWorker();\r
connect(worker, SIGNAL(askOverWrite(QString*,QString*,QString,QString)),\r
this, SLOT(askOverWrite(QString*,QString*,QString,QString)));\r
- worker->setCopyList(&list);\r
+ worker->setCopyList(list);\r
worker->setTargetDir(tgtDir);\r
worker->setMoveMode(false);\r
\r
///\r
/// アイテムを移動します。\r
///\r
-void MainWindow::moveItems(const QFileInfoList &list, const QString &tgtDir)\r
+void MainWindow::moveItems(const QStringList &list, const QString &tgtDir)\r
{\r
qDebug() << "MainWindow::moveItems()" << tgtDir;\r
\r
CopyMoveWorker *worker = new CopyMoveWorker();\r
connect(worker, SIGNAL(askOverWrite(QString*,QString*,QString,QString)),\r
this, SLOT(askOverWrite(QString*,QString*,QString,QString)));\r
- worker->setCopyList(&list);\r
+ worker->setCopyList(list);\r
worker->setTargetDir(tgtDir);\r
worker->setMoveMode(true);\r
\r
}\r
\r
QAction *selected = menu.exec(e->globalPos());\r
- if (selected == ui->action_ScaleDown ||\r
- selected == ui->action_ScaleUp)\r
- {\r
+ if (selected == ui->action_ScaleDown || selected == ui->action_ScaleUp) {\r
ui->image_FitToWindow->blockSignals(true);\r
ui->image_FitToWindow->setChecked(false);\r
ui->image_FitToWindow->blockSignals(false);\r
}\r
\r
///////////////////////////////////////////////////////////////////////////////\r
-/// \brief MainWindow::onDropEvent\r
-/// \param obj イベントが発生したオブジェクト\r
-/// \param e ドロップイベントオブジェクト\r
-/// \return 処理した場合はtrue, 処理しなかった場合はfalseを返します。\r
-///\r
-bool MainWindow::onDropEvent(QObject *obj, QDropEvent *e)\r
-{\r
- qDebug() << "MainWindow::onDropEvent()";\r
-\r
- if (obj->parent()->objectName() == "folderView" ||\r
- obj->parent()->objectName() == "thumbnailView")\r
- {\r
- QAbstractItemView *v = static_cast<QAbstractItemView*>(obj->parent());\r
- if (v->property("dragging").toBool()) {\r
- // 自分自身へのドロップなら何もしない\r
- return true;\r
- }\r
-\r
- QFileInfoList list;\r
- foreach (const QUrl &url, e->mimeData()->urls()) {\r
- QString path = QFileInfo(url.toLocalFile()).canonicalFilePath();\r
- if (!path.isEmpty()) {\r
- list << path;\r
- }\r
- else {\r
- qDebug() << "drop path is empty." << url;\r
- }\r
- }\r
-\r
- if (list.isEmpty()) {\r
- // ローカルファイルのドロップでなければ何もしない\r
- return true;\r
- }\r
-\r
- e->acceptProposedAction();\r
-\r
- QMenu menu(this);\r
- QAction *actCopy = menu.addAction(tr("コピー"));\r
- QAction *actMove = menu.addAction(tr("移動"));\r
- menu.addSeparator();\r
- menu.addAction(tr("キャンセル"));\r
-\r
- QAction *selected = menu.exec(v->mapToGlobal(e->pos()));\r
- FolderModel *m = static_cast<FolderModel*>(v->model());\r
- if (selected == actMove) {\r
- moveItems(list, m->rootPath());\r
- }\r
- else if (selected == actCopy) {\r
- copyItems(list, m->rootPath());\r
- }\r
- return true;\r
- }\r
- else {\r
- qDebug() << obj->parent()->objectName();\r
- }\r
-\r
- return true;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////////\r
/// \brief MainWindow::onKeyPressEvent\r
/// \param obj イベントが発生したオブジェクト\r
/// \param e キーイベントオブジェクト\r
{\r
qDebug() << "MainWindow::onCopy";\r
\r
- QFileInfoList list = selectedItems();\r
+ QStringList list;\r
+ foreach (const QFileInfo &fi, selectedItems()) {\r
+ list << fi.absoluteFilePath();\r
+ }\r
if (list.isEmpty()) {\r
return;\r
}\r
}\r
\r
DeleteWorker *worker = new DeleteWorker();\r
- worker->setDeleteList(&list);\r
+ worker->setDeleteList(list);\r
\r
OperationDialog opDlg(this);\r
opDlg.setWindowTitle(tr("削除"));\r
// コンテキストメニューイベントの処理\r
return onContextMenuEvent(watched, static_cast<QContextMenuEvent*>(e));\r
\r
- case QEvent::Drop:\r
- qDebug() << "QEvent::Drop";\r
- // ドロップイベントの処理\r
- return onDropEvent(watched, static_cast<QDropEvent*>(e));\r
-\r
default:\r
break;\r
}\r
public slots:\r
void askOverWrite(QString *copyMethod, QString *alias,\r
const QString &srcPath, const QString &tgtPath);\r
+ void copyItems(const QStringList &list, const QString &tgtDir);\r
+ void moveItems(const QStringList &list, const QString &tgtDir);\r
void onAddBookmark();\r
void onOpen(const QModelIndex &index = QModelIndex());\r
void view_copyAvailable(bool yes);\r
\r
FolderModel* activeModel() const;\r
Panel* activePanel() const;\r
- void copyItems(const QFileInfoList &list, const QString &tgtDir);\r
QAbstractItemView* focusItemView() const;\r
FolderModel* inactiveModel() const;\r
Panel* inactivePanel() const;\r
void initActions();\r
void initBookmarkMenu();\r
- void moveItems(const QFileInfoList &list, const QString &tgtDir);\r
bool onContextMenuEvent(QObject *obj, QContextMenuEvent *e);\r
- bool onDropEvent(QObject *obj, QDropEvent *e);\r
+// bool onDropEvent(QObject *obj, QDropEvent *e);\r
bool onKeyPressEvent(QObject *obj, QKeyEvent *e);\r
QFileInfoList selectedItems() const;\r
void sendEventOther(QEvent *event);\r
m_Error(false)\r
{\r
ui->setupUi(this);\r
+ ui->textEdit->setVisible(false);\r
resize(parent->width() * 0.8, height());\r
}\r
\r
return ui->chkAutoClose->isChecked();\r
}\r
\r
-void OperationDialog::showEvent(QShowEvent *)\r
-{\r
- ui->textEdit->setVisible(false);\r
-\r
- QThread *thread = new QThread();\r
- m_worker->moveToThread(thread);\r
- connect(m_worker, SIGNAL(information(QString)), ui->label, SLOT(setText(QString)));\r
- connect(thread, SIGNAL(started()), m_worker, SLOT(operate()));\r
- connect(m_worker, SIGNAL(finished()), thread, SLOT(quit()));\r
-\r
- connect(thread, SIGNAL(finished()), m_worker, SLOT(deleteLater()));\r
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));\r
-\r
- connect(m_worker, SIGNAL(operation(QString)), this, SLOT(onOperation(QString)));\r
- connect(m_worker, SIGNAL(success(QString)), this, SLOT(onSuccess(QString)));\r
- connect(m_worker, SIGNAL(error(QString)), this, SLOT(onError(QString)));\r
- connect(m_worker, SIGNAL(finished()), this, SLOT(onFinished()));\r
- connect(m_worker, SIGNAL(canceled()), this, SLOT(onCanceled()));\r
-\r
- thread->start();\r
-}\r
-\r
-void OperationDialog::onOperation(const QString &msg)\r
+void OperationDialog::onProgress(const QString &msg)\r
{\r
ui->textEdit->append(msg + " ... ");\r
}\r
ui->textEdit->append("<font color='red'><strong>" + msg + "</strong></font>");\r
}\r
\r
-void OperationDialog::onFinished()\r
+void OperationDialog::onFinished(bool abort)\r
{\r
ui->progressBar->setMaximum(1);\r
ui->progressBar->setValue(1);\r
ui->btnCloseCancel->setText(tr("閉じる"));\r
\r
ui->textEdit->append("");\r
- ui->textEdit->append(tr("完了"));\r
- if (!m_Error && ui->chkAutoClose->checkState() == Qt::Checked) {\r
- QDialog::accept();\r
+ if (abort) {\r
+ ui->textEdit->append(tr("操作は途中でキャンセルされました。"));\r
+ }\r
+ else {\r
+ ui->textEdit->append(tr("完了"));\r
+ if (!m_Error && ui->chkAutoClose->checkState() == Qt::Checked) {\r
+ QDialog::accept();\r
+ }\r
}\r
-}\r
-\r
-void OperationDialog::onCanceled()\r
-{\r
- ui->progressBar->setMaximum(1);\r
- ui->progressBar->setValue(1);\r
- ui->btnCloseCancel->setText(tr("閉じる"));\r
-\r
- ui->textEdit->append("");\r
- ui->textEdit->append(tr("操作は途中でキャンセルされました。"));\r
}\r
\r
void OperationDialog::on_btnCloseCancel_clicked()\r
QDialog::accept();\r
}\r
else {\r
- m_worker->requestStop();\r
+ m_worker->abort();\r
}\r
}\r
\r
ui->btnShowDetail->setText(tr("詳細を隠す"));\r
}\r
}\r
+\r
+int OperationDialog::exec()\r
+{\r
+ connect(m_worker, SIGNAL(finished(bool)), this, SLOT(onFinished(bool)));\r
+ connect(m_worker, SIGNAL(error(QString)), this, SLOT(onError(QString)));\r
+ connect(m_worker, SIGNAL(progress(QString)), this, SLOT(onProgress(QString)));\r
+ connect(m_worker, SIGNAL(success(QString)), this, SLOT(onSuccess(QString)));\r
+ connect(m_worker, SIGNAL(information(QString)), ui->label, SLOT(setText(QString)));\r
+\r
+ ui->label->setText(m_worker->initialText());\r
+ m_worker->start();\r
+ return QDialog::exec();\r
+}\r
#ifndef OPERATIONDIALOG_H\r
#define OPERATIONDIALOG_H\r
\r
-#include "abstractworker.h"\r
+#include "operationworker.h"\r
\r
#include <QDialog>\r
\r
explicit OperationDialog(QWidget *parent = 0);\r
~OperationDialog();\r
\r
- void setWorker(AbstractWorker *worker) {\r
+ void setWorker(OperationWorker *worker) {\r
m_worker = worker;\r
}\r
void setAutoClose(bool yes);\r
bool autoClose() const;\r
\r
-protected:\r
- void showEvent(QShowEvent *);\r
-\r
private:\r
Ui::OperationDialog *ui;\r
\r
- AbstractWorker* m_worker;\r
- bool m_Error;\r
+ OperationWorker* m_worker;\r
+ bool m_Error;\r
\r
private slots:\r
- void onOperation(const QString &msg);\r
+ void onProgress(const QString &msg);\r
void onSuccess(const QString &msg);\r
void onError(const QString &msg);\r
- void onFinished();\r
- void onCanceled();\r
+ void onFinished(bool abort);\r
void on_btnCloseCancel_clicked();\r
void on_btnShowDetail_clicked();\r
+\r
+ // QDialog interface\r
+public slots:\r
+ int exec();\r
};\r
\r
#endif // OPERATIONDIALOG_H\r
--- /dev/null
+#ifndef OPERATIONWORKER_H
+#define OPERATIONWORKER_H
+
+#include "abstractworker.h"
+
+class OperationWorker : public AbstractWorker
+{
+ Q_OBJECT
+public:
+ explicit OperationWorker() :
+ AbstractWorker()
+ {
+ }
+
+ virtual QString initialText() const = 0;
+
+signals:
+ void information(const QString &msg);
+ void error(const QString &msg);
+ void progress(const QString &msg);
+ void success(const QString &msg);
+
+public slots:
+
+};
+
+#endif // OPERATIONWORKER_H
#include "renameworker.h"\r
+\r
#include <QFile>\r
#include <QFileInfo>\r
+#include <QThread>\r
+\r
+const int SLEEP_TIME = 1;\r
\r
-RenameWorker::RenameWorker(QObject *parent) :\r
- AbstractWorker(parent),\r
+RenameWorker::RenameWorker() :\r
+ OperationWorker(),\r
m_RenameMap(NULL)\r
{\r
}\r
\r
-void RenameWorker::operate()\r
+void RenameWorker::run()\r
{\r
- emit information(tr("名前を変更しています..."));\r
StringMap::const_iterator it;\r
bool ret;\r
int successCount = 0;\r
int errorCount = 0;\r
QString msg;\r
for (it = m_RenameMap->begin(); it != m_RenameMap->end(); it++) {\r
- if (isStopRequested()) {\r
- emit canceled();\r
+ this->thread()->msleep(SLEEP_TIME);\r
+ if (isAborted()) {\r
+ emit finished(true);\r
return;\r
}\r
\r
- emit operation(tr("名前変更:")\r
- + QFileInfo(it.key()).fileName()\r
- + tr(" -> ")\r
- + QFileInfo(it.value()).fileName());\r
+ emit progress(tr("名前変更:%1 -> %2")\r
+ .arg(QFileInfo(it.key()).fileName())\r
+ .arg(QFileInfo(it.value()).fileName()));\r
ret = QFile::rename(it.key(), it.value());\r
if (ret) {\r
successCount++;\r
\r
emit finished();\r
}\r
+\r
+QString RenameWorker::initialText() const\r
+{\r
+ return tr("名前を変更しています...");\r
+}\r
#ifndef RENAMEWORKER_H\r
#define RENAMEWORKER_H\r
\r
-#include "abstractworker.h"\r
+#include "operationworker.h"\r
#include "global.h"\r
\r
-class RenameWorker : public AbstractWorker\r
+class RenameWorker : public OperationWorker\r
{\r
Q_OBJECT\r
public:\r
- explicit RenameWorker(QObject *parent = 0);\r
+ explicit RenameWorker();\r
\r
void setRenameMap(const StringMap *map) {\r
m_RenameMap = map;\r
}\r
\r
-public slots:\r
- void operate();\r
-\r
private:\r
const StringMap *m_RenameMap;\r
+\r
+ // AbstractWorker interface\r
+public slots:\r
+ void run();\r
+\r
+ // OperationWorker interface\r
+public:\r
+ QString initialText() const;\r
};\r
\r
#endif // RENAMEWORKER_H\r
}
// アイコンまたは画像
- QSize size(option.rect.size());
- size -= padding;
+ QSize size(option.rect.size() - padding);
QPixmap pixmap = model->pixmap(index, size);
painter->drawPixmap(padding.width() + option.rect.left() + (size.width() - pixmap.width()) / 2,
option.rect.top() + (size.height() - pixmap.height()) / 2,
pixmap);
-
}
QSize ThumbnailDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
/// コンストラクタ
///
ThumbnailView::ThumbnailView(QWidget *parent) :
- QListView(parent)
+ QListView(parent),
+ m_p(this)
{
setItemDelegate(new ThumbnailDelegate(this));
setSpacing(12);
- setDragEnabled(true);
- setAcceptDrops(true);
- setDropIndicatorShown(true);
- setContextMenuPolicy(Qt::DefaultContextMenu);
}
///////////////////////////////////////////////////////////////////////////////
qDebug() << "ThumbnailView::initialize()";
connect(this, SIGNAL(doubleClicked(QModelIndex)), w, SLOT(onOpen(QModelIndex)));
+ connect(&m_p, SIGNAL(copyItems(QStringList,QString)), w, SLOT(copyItems(QStringList,QString)));
+ connect(&m_p, SIGNAL(moveItems(QStringList,QString)), w, SLOT(moveItems(QStringList,QString)));
installEventFilter(w);
+ viewport()->installEventFilter(&m_p);
viewport()->installEventFilter(w);
}
-///////////////////////////////////////////////////////////////////////////////
-/// \brief ThumbnailView::selectedItems
-/// \return
-///
-QFileInfoList ThumbnailView::selectedItems() const
-{
- QFileInfoList list = folderModel()->markedItems();
- if (list.isEmpty()) {
- list << folderModel()->fileInfo(currentIndex());
- }
-
- return list;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// \brief ThumbnailView::model_PreReset
-///
-/// モデルリセット前の処理
-///
-void ThumbnailView::model_PreReset()
-{
- qDebug() << "ThumbnailView::model_PreReset()";
-
- // 現在行と名前を保存しておく
- if (model() && currentIndex().isValid()) {
- m_saveRow = currentIndex().row();
- m_saveName = folderModel()->fileName(currentIndex());
- m_savePath = folderModel()->rootPath();
- }
- else {
- m_saveRow = 0;
- m_saveName = QString::null;
- m_savePath = QString::null;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// \brief ThumbnailView::model_PostReset
-///
-/// モデルリセット後の処理
-///
-void ThumbnailView::model_PostReset()
-{
- qDebug() << "ThumbnailView::model_PostReset()";
-
- // フォルダが変わった場合は先頭行を選択する
- if (m_savePath != folderModel()->rootPath()) {
- setCurrentIndex(model()->index(0, 0));
- return;
- }
-
- // 保存した名前と同名アイテムが見つかれば、再選択する
- for (int row = 0; row < model()->rowCount(); row++) {
- QModelIndex index = model()->index(row, 0);
- if (folderModel()->fileName(index) == m_saveName) {
- setCurrentIndex(index);
- return;
- }
- }
-
- // 同名アイテムが見つからなければ、行を維持する
- if (m_saveRow >= model()->rowCount()) {
- m_saveRow = model()->rowCount() - 1;
- }
- setCurrentIndex(model()->index(m_saveRow, 1));
-
-}
void ThumbnailView::scaleDown()
{
QListView::setModel(model);
if (this->model()) {
- connect(this->model(), SIGNAL(modelAboutToBeReset()), this, SLOT(model_PreReset()));
- connect(this->model(), SIGNAL(modelReset()), this, SLOT(model_PostReset()));
- }
-}
-
-
-void ThumbnailView::mousePressEvent(QMouseEvent *event)
-{
- m_dragStartPos = QPoint();
- if ((event->buttons() & Qt::LeftButton) ||
- (event->buttons() & Qt::RightButton))
- {
- QModelIndex index = indexAt(event->pos());
- if (index.isValid() && folderModel()->fileName(index) != "..") {
- m_dragStartPos = event->pos();
- }
- }
-
- QListView::mousePressEvent(event);
-}
-
-void ThumbnailView::mouseMoveEvent(QMouseEvent *event)
-{
- if (!(event->buttons() & Qt::LeftButton) &&
- !(event->buttons() & Qt::RightButton))
- {
- QListView::mouseMoveEvent(event);
- return;
- }
- if (m_dragStartPos.isNull() ||
- (event->pos() - m_dragStartPos).manhattanLength() < qApp->startDragDistance())
- {
- QListView::mouseMoveEvent(event);
- return;
+ connect(this->model(), SIGNAL(modelAboutToBeReset()), &m_p, SLOT(model_PreReset()));
+ connect(this->model(), SIGNAL(modelReset()), &m_p, SLOT(model_PostReset()));
}
-
- QFileInfoList list = selectedItems();
- if (list.size() == 1 && list[0].fileName() == "..") {
- QListView::mouseMoveEvent(event);
- return;
- }
-
- QList<QUrl> urls;
- foreach (const QFileInfo &info, list) {
- urls << QUrl::fromLocalFile(info.absoluteFilePath());
- }
-
- QDrag *drag = new QDrag(this);
- QMimeData *mimeData = new QMimeData;
- mimeData->setUrls(urls);
- drag->setMimeData(mimeData);
-
- m_dragging = true;
- drag->exec(Qt::CopyAction);
- m_dragging = false;
- m_dragStartPos = QPoint();
-
-}
-
-void ThumbnailView::dragEnterEvent(QDragEnterEvent *event)
-{
- if (event->mimeData()->hasUrls()) {
- event->acceptProposedAction();
- return;
- }
-
- QListView::dragEnterEvent(event);
}
void ThumbnailView::setVisible(bool visible)
#define THUMBNAILVIEW_H
#include "abstractview.h"
+#include "folderview_private.h"
#include "foldermodel.h"
#include <QListView>
class ThumbnailView : public QListView, public AbstractView
{
Q_OBJECT
- Q_PROPERTY(bool dragging MEMBER m_dragging READ isDragging())
public:
explicit ThumbnailView(QWidget *parent = 0);
void initialize(MainWindow *w);
- bool isDragging();
FolderModel* folderModel() const;
- QFileInfoList selectedItems() const;
private:
- QPoint m_dragStartPos;
- bool m_dragging;
- int m_saveRow;
- QString m_savePath;
- QString m_saveName;
+ FolderView_Private m_p;
signals:
private slots:
- void model_PreReset();
- void model_PostReset();
// AbstractView interface
public:
void setModel(QAbstractItemModel *model);
// QWidget interface
-protected:
- void mousePressEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void dragEnterEvent(QDragEnterEvent *event);
-
- // QWidget interface
public slots:
void setVisible(bool visible);
};
-inline bool ThumbnailView::isDragging()
-{
- return m_dragging;
-}
-
inline FolderModel *ThumbnailView::folderModel() const
{
return static_cast<FolderModel*>(model());
#include <QTimer>
#include <QThread>
-ThumbnailWorker::ThumbnailWorker(QObject *parent) :
- QObject(parent),
- m_mutex(),
- m_pathList(),
- m_loop(true)
+ThumbnailWorker::ThumbnailWorker() :
+ AbstractWorker(),
+ m_pathList()
{
}
void ThumbnailWorker::addPath(const QString &path)
{
+ qDebug() << "ThumbnailWorker::addPath()" << path;
QMutexLocker locker(&m_mutex);
m_pathList << path;
}
m_pathList.clear();
}
-void ThumbnailWorker::finish()
-{
- QMutexLocker locker(&m_mutex);
- m_loop = false;
- qDebug() << "ThumbnailWorker::finish()";
-}
-
QString ThumbnailWorker::getPath()
{
QMutexLocker locker(&m_mutex);
if (m_pathList.isEmpty()) {
return QString();
}
+ qDebug() << "ThumbnailWorker::getPath()";
return m_pathList.takeFirst();
}
-bool ThumbnailWorker::loop()
+void ThumbnailWorker::run()
{
- QMutexLocker locker(&m_mutex);
- return m_loop;
-}
+ qDebug() << "ThumbnailWorker::run() enter.";
-void ThumbnailWorker::doWork()
-{
- while (loop()) {
+ while (!isAborted()) {
QString path = getPath();
if (!path.isEmpty()) {
QPixmap pixmap(path);
emit resultReady(path, pixmap);
}
}
- QThread::msleep(100);
+ this->thread()->msleep(100);
}
emit finished();
- qDebug() << "ThumbnailWorker::doWork() finished.";
+ qDebug() << "ThumbnailWorker::run() finished.";
}
#ifndef THUMBNAILWORKER_H
#define THUMBNAILWORKER_H
-#include <QObject>
-#include <QMutex>
+#include "abstractworker.h"
+
#include <QSize>
#include <QPixmap>
-class ThumbnailWorker : public QObject
+class ThumbnailWorker : public AbstractWorker
{
Q_OBJECT
public:
- explicit ThumbnailWorker(QObject *parent = 0);
+ explicit ThumbnailWorker();
void addPath(const QString &path);
void clearPath();
- void finish();
private:
- QMutex m_mutex;
QStringList m_pathList;
- bool m_loop;
QString getPath();
- bool loop();
signals:
- void finished();
void resultReady(const QString &path, const QPixmap &pixmap);
+ // AbstractWorker interface
public slots:
- void doWork();
+ void run();
};
#endif // THUMBNAILWORKER_H