From 06da03204020e69eceb894e51b0b75759acae699 Mon Sep 17 00:00:00 2001 From: Masayuki Satoh Date: Sun, 14 Sep 2014 18:09:46 +0900 Subject: [PATCH] =?utf8?q?=E3=82=B5=E3=83=A0=E3=83=8D=E3=82=A4=E3=83=AB?= =?utf8?q?=E3=83=A2=E3=83=BC=E3=83=89=E3=81=AE=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Gefu.pro | 37 +- README.md | 7 + ReadMe.txt | 9 +- abstractrenamedialog.h | 39 + abstractview.h | 13 + anyview.cpp | 132 --- anyview.h | 46 - bookmarkdialog.cpp | 26 +- colorsamplemodel.cpp | 70 -- colorsamplemodel.h | 45 - common.h | 87 -- copymoveworker.h | 3 +- filetablemodel.cpp | 350 ------ filetablemodel.h | 71 -- foldermodel.cpp | 529 +++++++++ foldermodel.h | 209 ++++ folderpanel.cpp | 372 ++++--- folderpanel.h | 44 +- folderpanel.ui | 37 +- folderview.cpp | 520 ++------- folderview.h | 97 +- global.cpp | 22 + global.h | 16 + history.cpp | 36 - history.h | 34 - historydialog.cpp | 89 +- historydialog.h | 30 +- historydialog.ui | 39 +- images/Picture.png | Bin 1994 -> 0 bytes images/Pictures.png | Bin 0 -> 26452 bytes images/windows_fullscreen.png | Bin 0 -> 7232 bytes installer-full.nsi | 4 +- installer.nsi | 4 +- irenamedialog.cpp | 11 - irenamedialog.h | 28 - keybind.txt | 8 +- main.cpp | 208 ---- mainwindow.cpp | 2391 ++++++++++++++++++++++++++--------------- mainwindow.h | 212 ++-- mainwindow.ui | 468 +++++--- operationdialog.cpp | 1 - overwritedialog.cpp | 8 +- panel.cpp | 173 +++ panel.h | 34 + anyview.ui => panel.ui | 36 +- preferencedialog.cpp | 820 ++++++-------- preferencedialog.h | 28 +- preferencedialog.ui | 2249 +++++++++++++++----------------------- preferences.cpp | 340 ++++++ preferences.h | 103 ++ renamemultidialog.cpp | 4 +- renamemultidialog.h | 4 +- renamesingledialog.cpp | 4 +- renamesingledialog.h | 4 +- renameworker.h | 2 +- resource.qrc | 3 +- searchbox.cpp | 63 -- searchbox.h | 28 - simpleimageview.cpp | 290 ++--- simpleimageview.h | 54 +- simpletextview.cpp | 234 +--- simpletextview.h | 52 +- sortdialog.cpp | 101 +- sortdialog.h | 5 +- thumbnaildelegate.cpp | 90 ++ thumbnaildelegate.h | 27 + thumbnailview.cpp | 61 ++ thumbnailview.h | 34 + win32.cpp | 22 + win32.h | 11 + 70 files changed, 5708 insertions(+), 5520 deletions(-) create mode 100644 abstractrenamedialog.h create mode 100644 abstractview.h delete mode 100644 anyview.cpp delete mode 100644 anyview.h delete mode 100644 colorsamplemodel.cpp delete mode 100644 colorsamplemodel.h delete mode 100644 common.h delete mode 100644 filetablemodel.cpp delete mode 100644 filetablemodel.h create mode 100644 foldermodel.cpp create mode 100644 foldermodel.h create mode 100644 global.cpp create mode 100644 global.h delete mode 100644 history.cpp delete mode 100644 history.h delete mode 100644 images/Picture.png create mode 100644 images/Pictures.png create mode 100644 images/windows_fullscreen.png delete mode 100644 irenamedialog.cpp delete mode 100644 irenamedialog.h create mode 100644 panel.cpp create mode 100644 panel.h rename anyview.ui => panel.ui (70%) create mode 100644 preferences.cpp create mode 100644 preferences.h delete mode 100644 searchbox.cpp delete mode 100644 searchbox.h create mode 100644 thumbnaildelegate.cpp create mode 100644 thumbnaildelegate.h create mode 100644 thumbnailview.cpp create mode 100644 thumbnailview.h create mode 100644 win32.cpp create mode 100644 win32.h diff --git a/Gefu.pro b/Gefu.pro index 04149f9..4476cbb 100644 --- a/Gefu.pro +++ b/Gefu.pro @@ -18,51 +18,54 @@ SOURCES += main.cpp\ renamesingledialog.cpp \ renamemultidialog.cpp \ operationdialog.cpp \ - irenamedialog.cpp \ renameworker.cpp \ deleteworker.cpp \ overwritedialog.cpp \ copymoveworker.cpp \ sortdialog.cpp \ - filetablemodel.cpp \ - history.cpp \ historydialog.cpp \ preferencedialog.cpp \ - colorsamplemodel.cpp \ simpletextview.cpp \ - searchbox.cpp \ folderview.cpp \ - anyview.cpp \ folderpanel.cpp \ bookmarkdialog.cpp \ simpleimageview.cpp \ - abstractworker.cpp + abstractworker.cpp \ + foldermodel.cpp \ + panel.cpp \ + preferences.cpp \ + global.cpp \ + win32.cpp \ + thumbnailview.cpp \ + thumbnaildelegate.cpp HEADERS += mainwindow.h \ renamesingledialog.h \ renamemultidialog.h \ operationdialog.h \ - common.h \ - irenamedialog.h \ renameworker.h \ deleteworker.h \ overwritedialog.h \ copymoveworker.h \ sortdialog.h \ - filetablemodel.h \ - history.h \ historydialog.h \ preferencedialog.h \ - colorsamplemodel.h \ simpletextview.h \ - searchbox.h \ folderview.h \ version.h \ - anyview.h \ folderpanel.h \ bookmarkdialog.h \ simpleimageview.h \ - abstractworker.h + abstractworker.h \ + foldermodel.h \ + panel.h \ + preferences.h \ + global.h \ + win32.h \ + abstractview.h \ + abstractrenamedialog.h \ + thumbnailview.h \ + thumbnaildelegate.h FORMS += mainwindow.ui \ renamesingledialog.ui \ @@ -72,9 +75,9 @@ FORMS += mainwindow.ui \ sortdialog.ui \ historydialog.ui \ preferencedialog.ui \ - anyview.ui \ folderpanel.ui \ - bookmarkdialog.ui + bookmarkdialog.ui \ + panel.ui RESOURCES += \ resource.qrc diff --git a/README.md b/README.md index e3addcf..996dc97 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,13 @@ Gefu Gefu is an Experimental File Utility. +#### Ver0.21 + * 設定ダイアログを刷新。 + * iniファイルのパスも変更したため、設定が初期化されます。 + * 画像ビューアの画質を向上。 + * アイコンを変更。 + * フォルダビューの列ヘッダーを削除。 + #### 2014/08/31 Ver0.20 * ウィンドウ自体が非アクティブになったとき、両パネルとも暗くなっていたのを修正。 * ドロップ時、コピー・移動・キャンセルのポップアップメニューを出すようにした。 diff --git a/ReadMe.txt b/ReadMe.txt index ea10fbc..e9d99c0 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -1,6 +1,6 @@ =============================================================================== Gefu(げふぅ) - Gefu is an Experimental File Utility - - Version 0.20 + Version 0.21 =============================================================================== 2014/08/31 @miyabi_satoh @@ -88,9 +88,10 @@ - 配布・転載を行う場合は @miyabi_satoh までご連絡ください。 特に利益を生じる無断配布・無断転載は固く禁じます。 - メニューおよびツールバーのアイコンには、以下を使用しています - - Tango Icon Library http://tango.freedesktop.org/Tango_Icon_Library - - Utilities-file-archiver.png http://chakraos.org/wiki/index.php?title=File:Utilities-file-archiver.png - - Cats Icons 2 http://www.softicons.com/system-icons/cats-icons-2-by-mcdo-design + - Cats Icons 2 http://www.softicons.com/system-icons/cats-icons-2-by-mcdo-design + - NuoveXT Icons by Saki http://www.iconarchive.com/show/nuoveXT-icons-by-saki.html + - 32x32 Free Design Icons http://www.small-icons.com/packs/32x32-free-design-icons.htm + ◇ 連絡先 ◇ Web: https://sourceforge.jp/projects/gefu/ diff --git a/abstractrenamedialog.h b/abstractrenamedialog.h new file mode 100644 index 0000000..ffcd71e --- /dev/null +++ b/abstractrenamedialog.h @@ -0,0 +1,39 @@ +#ifndef ABSTRACTRENAMEDIALOG_H +#define ABSTRACTRENAMEDIALOG_H + +#include "global.h" + +#include +#include + +class AbstractRenameDialog : public QDialog +{ + Q_OBJECT +public: + explicit AbstractRenameDialog(QWidget *parent = 0) : + QDialog(parent) + { + } + + const StringMap& renameMap() const + { + return m_RenameMap; + } + + void setWorkingDirectory(const QString &path) + { + m_dir.setPath(path); + } + + virtual void setNames(const QFileInfoList &names) = 0; + +signals: + +public slots: + +protected: + QDir m_dir; + StringMap m_RenameMap; +}; + +#endif // ABSTRACTRENAMEDIALOG_H diff --git a/abstractview.h b/abstractview.h new file mode 100644 index 0000000..56f13c7 --- /dev/null +++ b/abstractview.h @@ -0,0 +1,13 @@ +#ifndef ABSTRACTVIEW_H +#define ABSTRACTVIEW_H + +class AbstractView +{ +public: + AbstractView() {} + + virtual void scaleUp() = 0; + virtual void scaleDown() = 0; +}; + +#endif // ABSTRACTVIEW_H diff --git a/anyview.cpp b/anyview.cpp deleted file mode 100644 index 24dc82f..0000000 --- a/anyview.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include "common.h" -#include "folderview.h" -#include "anyview.h" -#include "ui_anyview.h" - -#include -#include - -AnyView::AnyView(QWidget *parent) : - QWidget(parent), - ui(new Ui::AnyView) -{ - ui->setupUi(this); - - // 初期状態では全て非表示 - ui->folderPanel->setVisible(false); - ui->graphicsView->setVisible(false); - ui->textView->setVisible(false); -} - -AnyView::~AnyView() -{ - delete ui; -} - -void AnyView::changeView(int viewType) -{ - qDebug() << "AnyView::changeView();" << viewType; - - // 一度すべてを非表示にする - ui->folderPanel->setVisible(false); - ui->graphicsView->setVisible(false); - ui->textView->setVisible(false); - - QWidget *w; - switch (viewType) { - case AnyView::ViewFolder: w = ui->folderPanel; break; - case AnyView::ViewImage: w = ui->graphicsView; break; - case AnyView::ViewText: w = ui->textView; break; - default: Q_ASSERT(false); w = NULL; break; - } - - this->setVisible(true); - w->setVisible(true); -} - -bool AnyView::setViewItem(const QFileInfo &info) -{ - // フォルダ - if (info.isDir()) { - changeView(ViewFolder); - ui->folderPanel->folderView()->setPath(info.absoluteFilePath(), true); - return true; - } - - // 画像ファイル - changeView(ViewImage); - if (ui->graphicsView->setSource(info.absoluteFilePath())) { - return true; - } - - QSettings settings; - bool isBinary = false; - if (!settings.value(IniKey_ViewerForceOpen).toBool()) { - QStringList list = settings.value(IniKey_ViewerIgnoreExt).toString().split(","); - foreach (const QString &ext, list) { - if (ext.toLower() == info.suffix().toLower()) { - isBinary = true; - break; - } - } - } - - if (!isBinary) { - changeView(ViewText); - QFile file(info.absoluteFilePath()); - if (file.open(QIODevice::ReadOnly)) { - ui->textView->setSource(file.readAll()); - file.close(); - return true; - } - } - - changeView(ViewText); - ui->textView->setSource(""); - return false; -} - -FolderPanel *AnyView::folderPanel() const -{ - return ui->folderPanel; -} - -SimpleImageView *AnyView::imageView() const -{ - return ui->graphicsView; -} - -SimpleTextView *AnyView::textView() const -{ - return ui->textView; -} - -QWidget *AnyView::visibleView() const -{ - if (ui->folderPanel->isVisible()) { - return ui->folderPanel->folderView(); - } - if (ui->graphicsView->isVisible()) { - return ui->graphicsView; - } - if (ui->textView->isVisible()) { - return ui->textView; - } - return NULL; -} - -void AnyView::focusInEvent(QFocusEvent *) -{ - qDebug() << "AnyView::focusInEvent();"; - - if (ui->folderPanel->isVisible()) { - ui->folderPanel->folderView()->setFocus(); - } - else if (ui->graphicsView->isVisible()) { - ui->graphicsView->setFocus(); - } - else { - Q_ASSERT(ui->textView->isVisible()); - ui->textView->setFocus(); - } -} diff --git a/anyview.h b/anyview.h deleted file mode 100644 index 2926016..0000000 --- a/anyview.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef ANYVIEW_H -#define ANYVIEW_H - -#include -#include -class FolderPanel; -class SimpleTextView; -class SimpleImageView; - -namespace Ui { -class AnyView; -} - -class AnyView : public QWidget -{ - Q_OBJECT - -public: - enum { - ViewFolder = 1, - ViewText = 2, - ViewImage = 3, - }; - - explicit AnyView(QWidget *parent = 0); - ~AnyView(); - - // action - void changeView(int viewType); - bool setViewItem(const QFileInfo &info); - - // getter - FolderPanel* folderPanel() const; - SimpleImageView* imageView() const; - SimpleTextView* textView() const; - QWidget* visibleView() const; - -private: - Ui::AnyView *ui; - - // QWidget interface -protected: - void focusInEvent(QFocusEvent *); -}; - -#endif // ANYVIEW_H diff --git a/bookmarkdialog.cpp b/bookmarkdialog.cpp index b252623..dc5d0b7 100644 --- a/bookmarkdialog.cpp +++ b/bookmarkdialog.cpp @@ -1,4 +1,4 @@ -#include "common.h" +#include "preferences.h" #include "bookmarkdialog.h" #include "ui_bookmarkdialog.h" @@ -6,7 +6,6 @@ #include #include #include -#include BookmarkDialog::BookmarkDialog(QWidget *parent) : QDialog(parent), @@ -36,18 +35,19 @@ void BookmarkDialog::setEditMode(bool edit) setWindowTitle(tr("ブックマークを開く")); } - QSettings settings; - for (int i = 0; ; i++) { - QString name = settings.value(IniKey_BookmarkEntryName(i), "").toString(); + Preferences prefs(this); + for (int i = 1; ; i++) { + QString name = prefs.getBookmarkEntry(i); if (name.isEmpty()) { break; } - QString path = settings.value(IniKey_BookmarkEntryPath(i)).toString(); - insertData(i, name, path); + QString path = prefs.getBookmarkPath(i); + insertData(i - 1, name, path); } ui->tableWidget->resizeColumnsToContents(); ui->tableWidget->resizeRowsToContents(); + ui->tableWidget->horizontalHeader()->setStretchLastSection(true); ui->tableWidget->setCurrentCell(0, 0); } @@ -147,7 +147,9 @@ void BookmarkDialog::moveSelectedRows(bool up) void BookmarkDialog::accept() { - QSettings settings; + Preferences prefs(this); + prefs.clearBookmark(); + QModelIndex index; int i; for (i = 0; i < ui->tableWidget->rowCount(); i++) { @@ -162,13 +164,7 @@ void BookmarkDialog::accept() index = ui->tableWidget->model()->index(i, 1); QString path = ui->tableWidget->model()->data(index).toString(); - settings.setValue(IniKey_BookmarkEntryName(i), name); - settings.setValue(IniKey_BookmarkEntryPath(i), path); - } - while (!settings.value(IniKey_BookmarkEntryName(i), "").toString().isEmpty()) { - settings.remove(IniKey_BookmarkEntryName(i)); - settings.remove(IniKey_BookmarkEntryPath(i)); - i++; + prefs.addBookmark(name, path); } QDialog::accept(); diff --git a/colorsamplemodel.cpp b/colorsamplemodel.cpp deleted file mode 100644 index 7590448..0000000 --- a/colorsamplemodel.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "colorsamplemodel.h" - -#include - -ColorSampleModel::ColorSampleModel(QObject *parent) : - QAbstractTableModel(parent) -{ -} - -void ColorSampleModel::setFont(const QFont &font) -{ - m_font = font; -} - -int ColorSampleModel::rowCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent); - return 5; -} - -int ColorSampleModel::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent); - return 3; -} - -QVariant ColorSampleModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) { - return QVariant(); - } - - const QString strText[5][3] = { - { tr("通常"), tr(""), tr("12/34/56 78:90") }, - { tr("マーク"), tr("123B"), tr("12/34/56 78:90") }, - { tr("システム"), tr("456KB"), tr("12/34/56 78:90") }, - { tr("隠し属性"), tr("789MB"), tr("12/34/56 78:90") }, - { tr("読取専用"), tr("10.2GB"), tr("12/34/56 78:90") } - }; - - switch (role) { - case Qt::DisplayRole: - return strText[index.row()][index.column()]; - - case Qt::FontRole: - return m_font; - break; - - case Qt::BackgroundRole: - if (index.row() == 1) { - return QBrush(m_colorMap->value("clrBgMark")); - } - else { - return QBrush(m_colorMap->value("clrBgNormal")); - } - break; - - case Qt::ForegroundRole: - switch (index.row()) { - case 0: return QBrush(m_colorMap->value("clrFgNormal")); - case 1: return QBrush(m_colorMap->value("clrFgMark")); - case 2: return QBrush(m_colorMap->value("clrFgSystem")); - case 3: return QBrush(m_colorMap->value("clrFgHidden")); - case 4: return QBrush(m_colorMap->value("clrFgReadonly")); - break; - } - } - - return QVariant(); -} diff --git a/colorsamplemodel.h b/colorsamplemodel.h deleted file mode 100644 index 0593383..0000000 --- a/colorsamplemodel.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef COLORSAMPLEMODEL_H -#define COLORSAMPLEMODEL_H - -#include -#include -#include - -typedef QMap ColorMap; - -class ColorSampleModel : public QAbstractTableModel -{ - Q_OBJECT -public: - explicit ColorSampleModel(QObject *parent = 0); - - const QFont& font() { return m_font; } - void setFont(const QFont &font); - - void setColorMap(ColorMap *colorMap) { - m_colorMap = colorMap; - } - - void update() { - beginResetModel(); - endResetModel(); - } - -private: - ColorMap *m_colorMap; - QFont m_font; - -signals: - -public slots: - - - // QAbstractItemModel interface -public: - int rowCount(const QModelIndex &parent) const; - int columnCount(const QModelIndex &parent) const; - QVariant data(const QModelIndex &index, int role) const; -}; - - -#endif // COLORSAMPLEMODEL_H diff --git a/common.h b/common.h deleted file mode 100644 index 05f7162..0000000 --- a/common.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef COMMON_H -#define COMMON_H - -#include -typedef QMap StringMap; - -class QObject; -class QKeyEvent; -extern QString FilesizeToString(quint64 size); -extern QString ViewerIgnoreExt(); -extern QString KeyEventToSequence(const QKeyEvent *event); -extern bool IsKeyUpDown(const QKeyEvent *event); -extern bool ProcessShortcut(const QString &ksq, const QObject *object); -extern void Sleep(int msec); - -#define slash QString("/") -#define QQ(x) ("\"" + QString(x) + "\"") - -#define IniKey_ShowHidden "Common/ShowHidden" -#define IniKey_ShowSystem "Common/ShowSystem" -#define IniKey_DefaultOnCopy "Common/DefaultCopyMode" -#define IniKey_MoveAfterCreateFolder "Common/MoveAfterFolderCreation" -#define IniKey_OpenAfterCreateFile "Common/OpenAfterFileCreation" -#define IniKey_CheckUpdates "Common/CheckUpdates" -#define IniKey_BookmarkEntryName(x) QString("Bookmark/Name%1").arg(x) -#define IniKey_BookmarkEntryPath(x) QString("Bookmark/Path%1").arg(x) -#define IniKey_BootSizeSpec "BootAndExit/SizeSpec" -#define IniKey_BootSizeRel "BootAndExit/SizeRel" -#define IniKey_BootSizeAbs "BootAndExit/SizeAbs" -#define IniKey_BootPosSpec "BootAndExit/PosSpec" -#define IniKey_BootPosRel "BootAndExit/PosRel" -#define IniKey_BootPosAbs "BootAndExit/PosAbs" -#define IniKey_ResetOnBoot "BootAndExit/Reset" -#define IniKey_BoxColorFg "Appearance/BoxColorFg" -#define IniKey_BoxColorBg "Appearance/BoxColorBg" -#define IniKey_BoxFont "Appearance/BoxFont" -#define IniKey_ViewFont "Appearance/ViewFont" -#define IniKey_ViewColorBgNormal "Appearance/ViewColorBgNormal" -#define IniKey_ViewColorBgMark "Appearance/ViewColorBgMark" -#define IniKey_ViewColorFgNormal "Appearance/ViewColorFgNormal" -#define IniKey_ViewColorFgMark "Appearance/ViewColorFgMark" -#define IniKey_ViewColorFgSystem "Appearance/ViewColorFgSystem" -#define IniKey_ViewColorFgHidden "Appearance/ViewColorFgHidden" -#define IniKey_ViewColorFgReadonly "Appearance/ViewColorFgReadonly" -#define IniKey_Darkness "Appearance/Darkness" -#define IniKey_ConfirmExit "Confirm/Exit" -#define IniKey_ConfirmCopy "Confirm/Copy" -#define IniKey_ConfirmMove "Confirm/Move" -#define IniKey_ConfirmDelete "Confirm/Delete" -#define IniKey_ConfirmRename "Confirm/Rename" -#define IniKey_AutoCloseCopy "AutoClose/Copy" -#define IniKey_AutoCloseMove "AutoClose/Move" -#define IniKey_AutoCloseDelete "AutoClose/Delete" -#define IniKey_AutoCloseRename "AutoClose/Rename" -#define IniKey_PathEditor "Path/Editor" -#define IniKey_PathTerminal "Path/Terminal" -#define IniKey_PathArchiver "Path/Archiver" -#define IniKey_InflateOptions "Path/InflateOptions" -#define IniKey_DeflateOptions "Path/DeflateOptions" -#define IniKey_ViewerFont "Viewer/Font" -#define IniKey_ViewerColorBg "Viewer/ColorBg" -#define IniKey_ViewerColorFg "Viewer/ColorFg" -#define IniKey_ViewerInherit "Viewer/Inherit" -#define IniKey_ViewerForceOpen "Viewer/ForceOpen" -#define IniKey_ViewerIgnoreExt "Viewer/IgnoreExt" -#define IniKey_WindowGeometry "Window/Geometry" -#define iniKey_WindowState "Window/State" -// 以下は[Left/Right]セクションのキー -#define IniKey_Dir "dir" -#define IniKey_SortBy "SortBy" -#define IniKey_OrderBy "OrderBy" -#define IniKey_PutDirs "PutDirs" -#define IniKey_IgnoreCase "IgnoreCase" - -#define SortByName QDir::Name -#define SortByDate QDir::Time -#define SortBySize QDir::Size -#define SortByType QDir::Type - -#define OrderByAsc 0 -#define OrderByDesc QDir::Reversed - -#define PutDirsFirst QDir::DirsFirst -#define PutDirsLast QDir::DirsLast -#define PutDirsDefault 0 - -#endif // COMMON_H diff --git a/copymoveworker.h b/copymoveworker.h index c677fe4..45e0030 100644 --- a/copymoveworker.h +++ b/copymoveworker.h @@ -1,11 +1,10 @@ #ifndef COPYWORKER_H #define COPYWORKER_H -#include "common.h" #include "abstractworker.h" +#include "global.h" #include -#include class CopyMoveWorker : public AbstractWorker { diff --git a/filetablemodel.cpp b/filetablemodel.cpp deleted file mode 100644 index 0388a0b..0000000 --- a/filetablemodel.cpp +++ /dev/null @@ -1,350 +0,0 @@ -#include "common.h" -#include "filetablemodel.h" - -#include -#include -#include -#include -#include -#ifdef Q_OS_WIN32 - #include -#endif - -FileTableModel::FileTableModel(QObject *parent) : - QAbstractTableModel(parent), - m_dir(), - m_fileInfoList(), - m_checkStates(), - m_IconFactory(), - m_fsWatcher(this), - m_font(), - m_NormalBrush(), - m_NormalTextBrush(), - m_MarkBrush(), - m_MarkTextBrush(), - m_SystemBrush(), - m_HiddenBrush(), - m_ReadonlyBrush() -{ - // デフォルトフィルタを設定する - setFilter(QDir::NoDot | QDir::AllDirs | QDir::Files); -} - -bool FileTableModel::setPath(const QString &path) -{ - qDebug() << "FileTableModel::setPath" << path; - - if (!QFileInfo::exists(path)) { - qDebug() << "パスが存在しません"; - qDebug() << path; - return false; - } - QFileInfo info(path); - if (!info.isDir()) { - qDebug() << "フォルダではありません"; - qDebug() << path; - return false; - } - - beginResetModel(); - - m_dir.setPath(path); - m_fileInfoList = m_dir.entryInfoList(); - m_checkStates.clear(); - - if (m_fileInfoList.isEmpty()) { - qDebug() << "ファイルリストを取得できません"; - qDebug() << path; - } - else { - QFileInfoList::iterator it; - for (it = m_fileInfoList.begin(); it != m_fileInfoList.end(); ) { -#ifdef Q_OS_WIN32 - if (!(filter() & QDir::System)){ - DWORD dwFlags = ::GetFileAttributes( - it->absoluteFilePath().toStdWString().c_str()); - if (dwFlags != DWORD(-1) && it->fileName() != ".." && - ((dwFlags & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM)) - { - qDebug() << it->fileName() << " is system file."; - it = m_fileInfoList.erase(it); - continue; - } - } -#endif - if (it->fileName() == "..") { - if (m_dir.isRoot()) { - qDebug() << m_dir.absolutePath() << " is root."; - it = m_fileInfoList.erase(it); - continue; - } - } - it++; - } - // ソート方法によらず、".."は必ず先頭にする - QFileInfoList::iterator itRoot = m_fileInfoList.end(); - for (it = m_fileInfoList.begin(); it != m_fileInfoList.end(); it++) { - if (it->fileName() == "..") { - itRoot = it; - break; - } - } - if (itRoot != m_fileInfoList.end()) { - QFileInfo info(*itRoot); - m_fileInfoList.erase(itRoot); - m_fileInfoList.push_front(info); - } - } - - m_checkStates.resize(m_fileInfoList.size()); - m_checkStates.fill(Qt::Unchecked); - - m_fsWatcher.addPath(path); - connect(&m_fsWatcher, SIGNAL(directoryChanged(QString)), - this, SLOT(directoryChange(QString))); - - endResetModel(); - - emit dataChanged(QModelIndex(), QModelIndex()); - - return !m_fileInfoList.isEmpty(); -} - -QFileInfo FileTableModel::fileInfo(const QModelIndex &index) const -{ - qDebug() << "FileTableModel::fileInfo()" << index; - - if (index.isValid()) { - return m_fileInfoList[index.row()]; - } - return QFileInfo(); -} - -void FileTableModel::updateAppearance(int darkness) -{ - qDebug() << "FileTableModel::updateAppearance();" << darkness; - - QSettings settings; - - m_font = settings.value(IniKey_ViewFont).value(); - m_NormalBrush = QBrush(settings.value(IniKey_ViewColorBgNormal).value().darker(darkness)); - m_NormalTextBrush = QBrush(settings.value(IniKey_ViewColorFgNormal).value().darker(darkness)); - m_MarkBrush = QBrush(settings.value(IniKey_ViewColorBgMark).value().darker(darkness)); - m_MarkTextBrush = QBrush(settings.value(IniKey_ViewColorFgMark).value().darker(darkness)); - m_SystemBrush = QBrush(settings.value(IniKey_ViewColorFgSystem).value().darker(darkness)); - m_HiddenBrush = QBrush(settings.value(IniKey_ViewColorFgHidden).value().darker(darkness)); - m_ReadonlyBrush = QBrush(settings.value(IniKey_ViewColorFgReadonly).value().darker(darkness)); - m_ReadonlyBrush = QBrush(settings.value(IniKey_ViewColorFgReadonly).value().darker(darkness)); -} - -void FileTableModel::directoryChange(const QString &path) -{ - qDebug() << "FileTableModel::directoryChange" << path; - - emit preReload(); - - m_fsWatcher.removePath(m_dir.absolutePath()); - setPath(path); - - emit postReload(); -} - -int FileTableModel::rowCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent); - return m_fileInfoList.size(); -} - -int FileTableModel::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent); - return 5; -} - -QVariant FileTableModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) { - return QVariant(); - } - - const QFileInfo &info = m_fileInfoList.at(index.row()); - int checked = m_checkStates.at(index.row()); - - switch (role) { - case Qt::DisplayRole: - switch (index.column()) { - case 0: // チェックボックス - return QString(""); - - case 1: // ファイル名 - if (info.isDir()) { - return info.fileName(); - } - if (info.fileName().left(1) == ".") { // "."で始まるファイル - int pos = info.fileName().lastIndexOf("."); - if (pos == 0) { - return info.fileName(); - } - } - return info.completeBaseName(); - - case 2: // 拡張子 - if (info.isDir()) { - return QString(); - } - if (info.fileName().left(1) == ".") { // "."で始まるファイル - int pos = info.fileName().lastIndexOf("."); - if (pos == 0) { - return QString(); - } - } - return info.suffix(); - - case 3: // サイズ - if (info.isDir()) { - return QString(""); - } - else { - return FilesizeToString(info.size()); - } - break; - - case 4: // 更新日時 - return info.lastModified().toString("yy/MM/dd hh:mm"); - } - break; - - case Qt::DecorationRole: - if (index.column() == 1) { - if (info.fileName() == "..") { - return QIcon(":/images/Up.png"); - } - else { - // infoを使うと、正しいアイコンが取れない場合がある…なぜ? - return m_IconFactory.icon(QFileInfo(info)); - } - } - break; - - case Qt::FontRole: - return m_font; - - case Qt::TextAlignmentRole: - switch (index.column()) { - case 3: - case 4: - return Qt::AlignRight + Qt::AlignVCenter; - default: - return Qt::AlignLeft + Qt::AlignVCenter; - } - break; - - case Qt::BackgroundRole: - if (checked) { - return m_MarkBrush; - } - return m_NormalBrush; - - case Qt::ForegroundRole: - if (checked) { - return m_MarkTextBrush; - } -#ifdef Q_OS_WIN32 - { - DWORD dwFlags = ::GetFileAttributes( - info.absoluteFilePath().toStdWString().c_str()); - if (dwFlags != DWORD(-1) && (dwFlags & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM) - { - return m_SystemBrush; - } - } -#endif - if (info.isHidden() && info.fileName() != "..") { - return m_HiddenBrush; - } - if (!info.isWritable()) { - return m_ReadonlyBrush; - } - return m_NormalTextBrush; - - case Qt::CheckStateRole: - if (index.column() == 0 && info.fileName() != "..") { - return checked; - } - break; - } - - return QVariant(); -} - -QVariant FileTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role == Qt::DisplayRole) { - if (orientation == Qt::Horizontal) { - switch (section) { - case 0: return QString(""); - case 1: return tr("名前"); - case 2: return tr("拡張子"); - case 3: return tr("サイズ"); - case 4: return tr("更新日時"); - } - } - } - return QVariant(); -} - -Qt::ItemFlags FileTableModel::flags(const QModelIndex &index) const -{ - Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; - - if (!index.isValid()) { - return flags | Qt::ItemIsDropEnabled; - } - - if (m_fileInfoList[index.row()].fileName() != "..") { - if (index.column() == 0) { - flags |= Qt::ItemIsUserCheckable; - } - flags |= Qt::ItemIsDropEnabled; - } - return flags; -} - -bool FileTableModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - qDebug() << "FileTableModel::setData()" << index; - - if (!index.isValid()) { - return false; - } - - switch (role) { - case Qt::CheckStateRole: - if (index.column() == 0) { - m_checkStates[index.row()] = static_cast(value.toInt()); - emit dataChanged(index, this->index(index.row(), 4)); - return true; - } - break; - } - - return false; -} - -Qt::DropActions FileTableModel::supportedDropActions() const -{ - qDebug() << "FileTableModel::supportedDropActions()"; - - return Qt::CopyAction; -} - -QStringList FileTableModel::mimeTypes() const -{ - qDebug() << "FileTableModel::mimeTypes()"; - - QStringList types; - - types << "text/uri-list"; - - return types; -} diff --git a/filetablemodel.h b/filetablemodel.h deleted file mode 100644 index ec9af4b..0000000 --- a/filetablemodel.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef FILETABLEMODEL_H -#define FILETABLEMODEL_H - -#include -#include -#include -#include -#include -#include - -class FileTableModel : public QAbstractTableModel -{ - Q_OBJECT -public: - explicit FileTableModel(QObject *parent = 0); - - // action - bool setPath(const QString &path); - void updateAppearance(int darkness = false); - - // getter - QDir::SortFlags sorting() const { return m_dir.sorting(); } - QDir::Filters filter() const { return m_dir.filter(); } - QStringList nameFilters() const { return m_dir.nameFilters(); } - const QString absolutePath() const { return m_dir.absolutePath(); } - QFileInfo fileInfo(const QModelIndex &index) const; - QFont font() const { return m_font; } - - // setter - void setSorting(QDir::SortFlags sort) { m_dir.setSorting(sort); } - void setFilter(QDir::Filters filters) { m_dir.setFilter(filters); } - void setNameFilters(const QStringList &nameFiltes) { - m_dir.setNameFilters(nameFiltes); - } - -signals: - void selectionChanged(int checkedFoldrs, int checkedFiles, quint64 totalSize); - void preReload(); - void postReload(); - -public slots: - void directoryChange(const QString &path); - -private: - QDir m_dir; - QFileInfoList m_fileInfoList; - QVector m_checkStates; - QFileIconProvider m_IconFactory; - QFileSystemWatcher m_fsWatcher; - QFont m_font; - QBrush m_NormalBrush; - QBrush m_NormalTextBrush; - QBrush m_MarkBrush; - QBrush m_MarkTextBrush; - QBrush m_SystemBrush; - QBrush m_HiddenBrush; - QBrush m_ReadonlyBrush; - - // QAbstractItemModel interface -public: - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - bool setData(const QModelIndex &index, const QVariant &value, int role); - Qt::DropActions supportedDropActions() const; - QStringList mimeTypes() const; -}; - -#endif // FILETABLEMODEL_H diff --git a/foldermodel.cpp b/foldermodel.cpp new file mode 100644 index 0000000..9d881ef --- /dev/null +++ b/foldermodel.cpp @@ -0,0 +1,529 @@ +#include "global.h" +#include "preferences.h" +#include "win32.h" +#include "foldermodel.h" + +#include +#include +#include +#include +#include + +FolderModel* FolderModel::m_activeModel = NULL; + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::FolderModel +/// \param parent 親オブジェクト +/// +/// コンストラクタ +/// +FolderModel::FolderModel(QObject *parent) : + QAbstractTableModel(parent), + m_dir(), + m_fileInfoList(), + m_checkStates(), + m_IconProvider(), + m_fsWatcher(this), + m_history(), + m_historyPos(-1) +{ + connect(&m_fsWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(fsWatcher_directoryChanged(QString))); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::fileIcon +/// \param index アイテムのインデックス +/// \return アイコンを返します。 +/// +QIcon FolderModel::fileIcon(const QModelIndex &index) const +{ + if (fileName(index) == "..") { + return QIcon("://images/Up.png"); + } + return m_IconProvider.icon(fileInfo(index)); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::isMarked +/// \param index アイテムのインデックス +/// \return マークされていればtrueを返します。 +/// +bool FolderModel::isMarked(const QModelIndex &index) const +{ + CheckContainer::const_iterator it = m_checkStates.find(fileName(index)); + if (it != m_checkStates.end()) { + return *it == Qt::Checked; + } + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::markedItems +/// \return マークされているアイテムのリストを返します。 +/// +QFileInfoList FolderModel::markedItems() const +{ + QFileInfoList list; + for (int n = 0; n < rowCount(); ++n) { + QModelIndex index = this->index(n, 0); + if (isMarked(index)) { + list << fileInfo(index); + } + } + + return list; +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::mkdir +/// \param name 作成するフォルダ名 +/// \return 作成したフォルダのインデックス +/// +/// フォルダを作成します。 +/// +QModelIndex FolderModel::mkdir(const QString &name) +{ + qDebug() << "FolderModel::mkdir()" << name; + + if (!m_dir.mkdir(name)) { + return QModelIndex(); + } + + refresh(); + + for (int n = 0; n < rowCount(); ++n) { + if (m_fileInfoList[n].fileName() == name) { + return index(n, 0); + } + } + + return QModelIndex(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::search +/// \param value 検索する文字列 +/// \param start 開始位置 +/// \param step ステップ数 +/// \return 見つかったアイテムのインデックスを返します。 +/// +QModelIndex FolderModel::search(const QString &value, const QModelIndex &start, int step) +{ + qDebug() << "FolderModel::search()" << value << start << step; + + const QString searchText = value.toLower(); + for (int n = start.row() + step; 0 <= n && n < rowCount(); n += step) { + if (m_fileInfoList[n].fileName().toLower().indexOf(searchText) != -1) { + return index(n, 0); + } + } + + return QModelIndex(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::setHistoryAt +/// \param path 設定するパス +/// +/// 指定したパスに履歴を移動します。 +/// +void FolderModel::setHistoryAt(const QString &path) +{ + qDebug() << "FolderModel::setHistoryAt()" << path; + + for (int n = 0; n < m_history.size(); ++n) { + if (m_history[n] == path) { + m_historyPos = n; + setRootPath(path, false); + return; + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::setRootPath +/// \param path 設定するパス +/// \param addHistory 履歴に追加する場合はtrue +/// +/// ルートパスを設定します。 +/// +void FolderModel::setRootPath(const QString &path, bool addHistory) +{ + qDebug() << "FolderModel::setRootPath()" << path; + + beginResetModel(); + setError(); + + try { + if (!QFileInfo::exists(path)) { + throw tr("フォルダが存在しないか、利用できません:%1").arg(path); + } + + QDir dir(path); + dir.setFilter(m_dir.filter()); + dir.setNameFilters(m_dir.nameFilters()); + dir.setSorting(m_dir.sorting()); + + QFileInfoList list = dir.entryInfoList(); + if (list.isEmpty()) { + throw tr("ファイルリストを取得できません:%1").arg(path); + } + + m_fileInfoList.clear(); + if (m_dir.absolutePath() != dir.absolutePath()) { + m_fsWatcher.removePath(m_dir.absolutePath()); + m_fsWatcher.addPath(dir.absolutePath()); + m_checkStates.clear(); + m_dir.setPath(dir.absolutePath()); + if (addHistory) { + m_history.resize(m_historyPos + 1); + m_history << m_dir.absolutePath(); + m_historyPos = m_history.size() - 1; + } + } + + foreach (const QFileInfo &fi, list) { + if (fi.fileName() == "..") { + if (!m_dir.isRoot()) { + m_fileInfoList.push_front(fi); + } + continue; + } + else if (!(filter() & QDir::System) && + Win32::hasSystemAttribute(fi.absoluteFilePath())) + { + continue; + } + + m_fileInfoList << fi; + if (m_checkStates.find(fi.fileName()) == m_checkStates.end()) { + m_checkStates[fi.fileName()] = Qt::Unchecked; + } + } + } + catch (const QString &s) { + setError(s); + } + + endResetModel(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::touch +/// \param name 作成するファイル名 +/// \return 作成したファイルのインデックス +/// +/// 空のファイルを作成します。 +/// +QModelIndex FolderModel::touch(const QString &name) +{ + QFile file(m_dir.absoluteFilePath(name)); + if (!file.open(QIODevice::WriteOnly)) { + return QModelIndex(); + } + file.close(); + + refresh(); + + for (int n = 0; n < rowCount(); ++n) { + if (m_fileInfoList[n].fileName() == name) { + return index(n, 0); + } + } + + return QModelIndex(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::activeModel +/// \return アクティブなモデルを返します。 +/// +FolderModel *FolderModel::activeModel() +{ + return m_activeModel; +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::onCdHome +/// +/// ホームフォルダに移動します。 +/// +void FolderModel::onCdHome() +{ + setRootPath(QDir::homePath()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::onCdRoot +/// +/// ルートフォルダに移動します。 +/// +void FolderModel::onCdRoot() +{ + setRootPath(QDir::rootPath()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::onCdUp +/// +/// 親フォルダに移動します。 +/// +void FolderModel::onCdUp() +{ + if (!m_dir.isRoot()) { + QDir dir(m_dir); + dir.cdUp(); + setRootPath(dir.absolutePath()); + } +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::onHistoryBack +/// +/// 履歴を戻ります。 +/// +void FolderModel::onHistoryBack() +{ + if (m_historyPos > 0) { + setRootPath(m_history[--m_historyPos], false); + } +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::onHistoryForward +/// +/// 履歴を進みます。 +/// +void FolderModel::onHistoryForward() +{ + if (m_historyPos < m_history.size() - 1) { + setRootPath(m_history[++m_historyPos], false); + } +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::onMarkAll +/// +/// 全てのマークをONにします。 +/// +void FolderModel::onMarkAll() +{ + CheckContainer::iterator it; + for (it = m_checkStates.begin(); it != m_checkStates.end(); ++it) { + it.value() = Qt::Checked; + } + emit dataChanged(index(0, 0), index(rowCount(), columnCount())); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::onMarkAllFiles +/// +/// 全てのフォルダをマークOFF、ファイルをマークONにします。 +/// +void FolderModel::onMarkAllFiles() +{ + foreach (const QFileInfo &fi, m_fileInfoList) { + if (fi.fileName() == "..") { + continue; + } + if (fi.isDir()) { + m_checkStates[fi.fileName()] = Qt::Unchecked; + } + else { + m_checkStates[fi.fileName()] = Qt::Checked; + } + } + emit dataChanged(index(0, 0), index(rowCount(), columnCount())); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::onMarkAllOff +/// +/// 全てのマークをOFFにします。 +/// +void FolderModel::onMarkAllOff() +{ + CheckContainer::iterator it; + for (it = m_checkStates.begin(); it != m_checkStates.end(); ++it) { + it.value() = Qt::Unchecked; + } + emit dataChanged(index(0, 0), index(rowCount(), columnCount())); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderModel::onMarkInvert +/// +/// 全てのマークを反転します。 +/// +void FolderModel::onMarkInvert() +{ + CheckContainer::iterator it; + for (it = m_checkStates.begin(); it != m_checkStates.end(); ++it) { + it.value() = (it.value() == Qt::Checked) ? Qt::Unchecked : Qt::Checked; + } + emit dataChanged(index(0, 0), index(rowCount(), columnCount())); +} + +int FolderModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return m_fileInfoList.size(); +} + +int FolderModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return ColumnCount; +} + +QVariant FolderModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + + Preferences prefs(const_cast(this)); + + switch (role) { + case Qt::DisplayRole: + switch (index.column()) { + case Name: + if (isDir(index) || isDotFile(index)) { + return fileName(index); + } + return fileInfo(index).completeBaseName(); + + case Extension: + if (isDir(index) || isDotFile(index)) { + return QVariant(); + } + return fileInfo(index).suffix(); + + case Size: // サイズ + if (isDir(index)) { + return QString(""); + } + return FileSizeToString(fileInfo(index).size()); + + case LastModified: // 更新日時 + return fileInfo(index).lastModified().toString("yy/MM/dd hh:mm"); + } + break; + + case Qt::DecorationRole: + if (index.column() == Name) { + return fileIcon(index); + } + break; + + case Qt::FontRole: + return prefs.getFolderViewFont(); + + case Qt::TextAlignmentRole: + switch (index.column()) { + case Size: + case LastModified: + return Qt::AlignRight + Qt::AlignVCenter; + } + return Qt::AlignLeft + Qt::AlignVCenter; + + case Qt::BackgroundRole: + if (isMarked(index)) { + return QBrush(prefs.folderViewMarkedBgColor(isActive())); + } + return QBrush(prefs.folderViewBgColor(isActive())); + + case Qt::ForegroundRole: + if (isMarked(index)) { + return QBrush(prefs.folderViewMarkedFgColor(isActive())); + } + if (fileName(index) != ".." && Win32::hasSystemAttribute(filePath(index))) { + return QBrush(prefs.folderViewSystemColor(isActive())); + } + if (fileName(index) != ".." && fileInfo(index).isHidden()) { + return QBrush(prefs.folderViewHiddenColor(isActive())); + } + if (fileName(index) != ".." && !fileInfo(index).isWritable()) { + return QBrush(prefs.folderViewReadOnlyColor(isActive())); + } + return QBrush(prefs.folderViewFgColor(isActive())); + + case Qt::CheckStateRole: + if (index.column() == Name && fileName(index) != "..") { + return isMarked(index) ? Qt::Checked : Qt::Unchecked; + } + break; + } + + return QVariant(); +} + +QVariant FolderModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { + switch (section) { + case Name: return tr("名前"); + case Extension: return tr("拡張子"); + case Size: return tr("サイズ"); + case LastModified: return tr("更新日時"); + } + } + return QVariant(); +} + +Qt::ItemFlags FolderModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + + if (!index.isValid()) { + return flags | Qt::ItemIsDropEnabled; + } + + if (m_fileInfoList[index.row()].fileName() != "..") { + if (index.column() == Name) { + flags |= Qt::ItemIsUserCheckable; + } + flags |= Qt::ItemIsDropEnabled; + } + return flags; +} + +bool FolderModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + qDebug() << "FolderModel::setData()" << index; + + if (!index.isValid()) { + return false; + } + + switch (role) { + case Qt::CheckStateRole: + if (index.column() == Name && fileName(index) != "..") { + m_checkStates[fileName(index)] = value.toInt(); + emit dataChanged(this->index(index.row(), 0), + this->index(index.row(), ColumnCount - 1)); + return true; + } + break; + } + + return false; +} + +Qt::DropActions FolderModel::supportedDropActions() const +{ + qDebug() << "FolderModel::supportedDropActions()"; + + return Qt::CopyAction; +} + +QStringList FolderModel::mimeTypes() const +{ + qDebug() << "FolderModel::mimeTypes()"; + + QStringList types; + + types << "text/uri-list"; + + return types; +} diff --git a/foldermodel.h b/foldermodel.h new file mode 100644 index 0000000..15b0e56 --- /dev/null +++ b/foldermodel.h @@ -0,0 +1,209 @@ +#ifndef FOLDERMODEL_H +#define FOLDERMODEL_H + +#include +#include +#include +#include +#include +#include + +class FolderModel : public QAbstractTableModel +{ + Q_OBJECT +public: + enum Column { + Name = 0, + Extension, + Size, + LastModified, + ColumnCount, + }; + typedef QVector History; + + explicit FolderModel(QObject *parent = 0); + + QString error() const; + QIcon fileIcon(const QModelIndex &index) const; + QFileInfo fileInfo(const QModelIndex &index) const; + QString fileName(const QModelIndex &index) const; + QString filePath(const QModelIndex &index) const; + QDir::Filters filter() const; + const History& history() const; + bool isActive() const; + bool isDir(const QModelIndex &index) const; + bool isHistoryBegin() const; + bool isHistoryEnd() const; + bool isMarked(const QModelIndex &index) const; + QFileInfoList markedItems() const; + QModelIndex mkdir(const QString &name); + QStringList nameFilters() const; + QString rootPath() const; + QModelIndex search(const QString &value, const QModelIndex &start = QModelIndex(), int step = 1); + void setActive(); + void setFilter(QDir::Filters filters); + void setHistoryAt(const QString &path); + void setNameFilters(const QStringList &nameFiltes); + void setRootPath(const QString &path, bool addHistory = true); + void setSorting(QDir::SortFlags sort); + QDir::SortFlags sorting() const; + QModelIndex touch(const QString &name); + + static FolderModel* activeModel(); + +signals: + +public slots: + void onCdHome(); + void onCdRoot(); + void onCdUp(); + void onHistoryBack(); + void onHistoryForward(); + void onMarkAll(); + void onMarkAllFiles(); + void onMarkAllOff(); + void onMarkInvert(); + void refresh(); + +private slots: + void fsWatcher_directoryChanged(const QString &path); + +private: + static FolderModel* m_activeModel; + + typedef QMap CheckContainer; + + QString m_error; + QDir m_dir; + QFileInfoList m_fileInfoList; + CheckContainer m_checkStates; + QFileIconProvider m_IconProvider; + QFileSystemWatcher m_fsWatcher; + History m_history; + int m_historyPos; + + bool isDotFile(const QModelIndex &index) const; + void setError(const QString &error = QString()); + + // QAbstractItemModel interface +public: + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + Qt::DropActions supportedDropActions() const; + QStringList mimeTypes() const; +}; + +inline QString FolderModel::error() const +{ + return m_error; +} + +inline QFileInfo FolderModel::fileInfo(const QModelIndex &index) const +{ + Q_ASSERT(index.isValid()); + return m_fileInfoList[index.row()]; +} + +inline QString FolderModel::fileName(const QModelIndex &index) const +{ + Q_ASSERT(index.isValid()); + return m_fileInfoList[index.row()].fileName(); +} + +inline QString FolderModel::filePath(const QModelIndex &index) const +{ + Q_ASSERT(index.isValid()); + return m_fileInfoList[index.row()].absoluteFilePath(); +} + +inline QDir::Filters FolderModel::filter() const +{ + return m_dir.filter(); +} + +inline const FolderModel::History &FolderModel::history() const +{ + return m_history; +} + +inline bool FolderModel::isActive() const +{ + return m_activeModel == this; +} + +inline bool FolderModel::isDir(const QModelIndex &index) const +{ + return m_fileInfoList[index.row()].isDir(); +} + +inline bool FolderModel::isHistoryBegin() const +{ + return m_historyPos == 0; +} + +inline bool FolderModel::isHistoryEnd() const +{ + return m_historyPos == m_history.size() - 1; +} + +inline bool FolderModel::isDotFile(const QModelIndex &index) const +{ + return fileName(index).lastIndexOf(".") == 0; +} + +inline QStringList FolderModel::nameFilters() const +{ + return m_dir.nameFilters(); +} + +inline void FolderModel::refresh() +{ + setRootPath(rootPath()); +} + +inline QString FolderModel::rootPath() const +{ + return m_dir.absolutePath(); +} + +inline void FolderModel::setActive() +{ + m_activeModel = this; +} + +inline void FolderModel::setError(const QString &error) +{ + m_error = error; +} + +inline void FolderModel::setFilter(QDir::Filters filters) +{ + m_dir.setFilter(filters); +} + +inline void FolderModel::setSorting(QDir::SortFlags sort) +{ + m_dir.setSorting(sort); +} + +inline void FolderModel::setNameFilters(const QStringList &nameFiltes) +{ + m_dir.setNameFilters(nameFiltes); +} + +inline QDir::SortFlags FolderModel::sorting() const +{ + return m_dir.sorting(); +} + +inline void FolderModel::fsWatcher_directoryChanged(const QString &path) +{ + Q_UNUSED(path); + refresh(); +} + +#endif // FOLDERMODEL_H diff --git a/folderpanel.cpp b/folderpanel.cpp index 051ebb3..f8e0c84 100644 --- a/folderpanel.cpp +++ b/folderpanel.cpp @@ -1,6 +1,6 @@ -#include "common.h" +#include "global.h" +#include "preferences.h" #include "mainwindow.h" -#include "searchbox.h" #include "folderpanel.h" #include "ui_folderpanel.h" @@ -8,213 +8,303 @@ #include #include +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::FolderPanel +/// \param parent 親ウィジェット +/// +/// コンストラクタ +/// FolderPanel::FolderPanel(QWidget *parent) : QWidget(parent), ui(new Ui::FolderPanel), m_mainWnd(NULL) { ui->setupUi(this); + ui->searchBox->setText(""); + ui->searchBox->setVisible(false); + ui->thumbnailView->setVisible(false); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::~FolderPanel +/// +/// デストラクタ +/// FolderPanel::~FolderPanel() { delete ui; } -void FolderPanel::initialize(MainWindow *mainWnd) +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::initialize +/// \param w メインウィンドウオブジェクト +/// +/// 初期化処理を行います。 +/// +void FolderPanel::initialize(MainWindow *w) { qDebug() << "FolderPanel::initialize();"; - m_mainWnd = mainWnd; - - // シグナル&スロット - connect(ui->searchBox, SIGNAL(textEdited(QString)), this, SLOT(searchItem(QString))); - connect(ui->folderView, SIGNAL(doubleClicked(QModelIndex)), mainWnd, SLOT(open(QModelIndex))); - connect(ui->folderView, SIGNAL(dropAccepted(QFileInfoList,QDropEvent*)), mainWnd, SLOT(dropAccept(QFileInfoList,QDropEvent*))); - connect(ui->folderView, SIGNAL(currentChanged(QFileInfo)), mainWnd, SLOT(currentChange(QFileInfo))); - connect(ui->folderView, SIGNAL(requestContextMenu(QContextMenuEvent*)), mainWnd, SLOT(showContextMenu(QContextMenuEvent*))); - connect(ui->folderView, SIGNAL(retrieveStarted(QString)), ui->locationBox, SLOT(setText(QString))); - connect(ui->folderView, SIGNAL(dataChanged()), this, SLOT(dataChange())); - connect(ui->folderView, SIGNAL(itemFound()), this, SLOT(itemFound())); - connect(ui->folderView, SIGNAL(itemNotFound()), this, SLOT(itemNotFound())); - connect(ui->bookmarkBtn, SIGNAL(clicked()), this, SLOT(addBookmark())); - - // 初期状態では検索ボックスは非表示 - ui->searchBox->setVisible(false); // フォルダビューを初期化する - ui->folderView->initialize(mainWnd); + ui->folderView->initialize(w); + // サムネイルビューを初期化する + ui->thumbnailView->initialize(w); + + connect(ui->bookmarkBtn, SIGNAL(clicked()), w, SLOT(onAddBookmark())); } -void FolderPanel::updateAppearance(bool darker) +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::itemView +/// \return アイテムビューを返します。 +/// +QAbstractItemView *FolderPanel::itemView() const { - QSettings settings; - QPalette pal; - int darkness = 100; - if (darker) { - darkness += settings.value(IniKey_Darkness).toInt(); + if (ui->thumbnailView->isVisible()) { + return ui->thumbnailView; } - - // ロケーションボックス - pal = ui->locationBox->palette(); - pal.setColor(QPalette::Base, settings.value(IniKey_BoxColorBg).value().darker(darkness)); - pal.setColor(QPalette::Text, settings.value(IniKey_BoxColorFg).value().darker(darkness)); - ui->locationBox->setPalette(pal); - ui->locationBox->setFont(settings.value(IniKey_BoxFont).value()); - - // モデル - FileTableModel *model = qobject_cast(ui->folderView->model()); - model->updateAppearance(darkness); - - // ビュー - pal = ui->folderView->palette(); - pal.setColor(QPalette::Base, settings.value(IniKey_ViewColorBgNormal).value().darker(darkness)); - ui->folderView->setPalette(pal); - - // 行の高さを設定する - QHeaderView *header = ui->folderView->verticalHeader(); - header->setDefaultSectionSize(QFontMetrics(model->font()).height() * 1.5); - - // 列の幅を設定する - header = ui->folderView->horizontalHeader(); - header->setSectionResizeMode(0, QHeaderView::Fixed); - header->setSectionResizeMode(1, QHeaderView::Stretch); - header->setSectionResizeMode(2, QHeaderView::ResizeToContents); - header->setSectionResizeMode(3, QHeaderView::ResizeToContents); - header->setSectionResizeMode(4, QHeaderView::ResizeToContents); + return ui->folderView; } -QLineEdit *FolderPanel::locationBox() const +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::folderView +/// \return フォルダビューを返します。 +/// +//FolderView *FolderPanel::folderView() const +//{ +// return ui->folderView; +//} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::model +/// \return 関連付けられたフォルダモデルを返します。 +/// +FolderModel *FolderPanel::model() const { - return ui->locationBox; + return static_cast(ui->folderView->model()); } -FolderView *FolderPanel::folderView() const +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::setModel +/// \param m 設定するモデル +/// +/// モデルを設定します。 +/// +void FolderPanel::setModel(FolderModel *m) { - return ui->folderView; -} + qDebug() << "FolderPanel::setModel()" << m; + if (model()) { + model()->disconnect(this); + } -SearchBox *FolderPanel::searchBox() const -{ - return ui->searchBox; -} + ui->folderView->setModel(m); + ui->thumbnailView->setModel(m); -QLabel *FolderPanel::filterLabel() const -{ - return ui->filterLabel; -} + if (model()) { + connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), + this, SLOT(model_dataChanged(QModelIndex,QModelIndex))); + connect(model(), SIGNAL(modelReset()), this, SLOT(model_Reset())); -void FolderPanel::setNameFilters(const QString &filters) -{ - QStringList list = filters.split(" ", QString::SkipEmptyParts); - if (list.isEmpty()) { - list << "*"; + model_Reset(); + model_dataChanged(QModelIndex(), QModelIndex()); } - ui->folderView->setNameFilters(list); - showNameFilters(); -} - -void FolderPanel::showNameFilters() -{ - ui->filterLabel->setText(tr("フィルタ:") + ui->folderView->nameFilters().join(" ")); } -void FolderPanel::dataChange() +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::toggleSearch +/// \param checked メニューのチェック状態 +/// +/// 検索ボックスの表示/非表示を切り替えます。 +/// +void FolderPanel::toggleSearch(bool checked) { - qDebug() << "FolderPanel::dataChange();"; + qDebug() << "FolderPanel::toggleSearch()" << checked; - FolderView *view = static_cast(sender()); - Q_CHECK_PTR(view); + if (checked) { + if (!model()->isActive()) { + return; + } - QFileInfoList list = view->checkedItems(); - if (list.isEmpty()) { - showNameFilters(); + ui->searchBox->setVisible(true); + ui->searchBox->setFocus(); + ui->searchBox->selectAll(); } else { - int numFolders = 0; - int numFiles = 0; - quint64 size = 0; - foreach (const QFileInfo &info, list) { - if (info.isDir()) { - numFolders++; - } - else { - numFiles++; - size += info.size(); - } - } - - QString msg = QString::null; - if (numFolders > 0) { - msg += tr("%1個のフォルダ ").arg(numFolders); - } - if (numFiles > 0) { - msg += tr("%1個のファイル ").arg(numFiles); + if (!ui->searchBox->isVisible()) { + return; } - if (!msg.isEmpty()) { - msg += tr("を選択 合計%1").arg(FilesizeToString(size)); + if (ui->searchBox->hasFocus()) { + itemView()->setFocus(); } + ui->searchBox->setVisible(false); + } +} - ui->filterLabel->setText(msg); +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::toggleView +/// \param checked メニューのチェック状態 +/// +/// リスト/サムネイルを切り替えます。 +/// +void FolderPanel::toggleView(bool checked) +{ + QModelIndex index = itemView()->currentIndex(); + if (checked) { + ui->folderView->setVisible(false); + ui->thumbnailView->setVisible(true); + ui->thumbnailView->setFocus(); } + else { + ui->thumbnailView->setVisible(false); + ui->folderView->setVisible(true); + ui->folderView->setFocus(); + } + itemView()->setCurrentIndex(index); } -void FolderPanel::addBookmark() +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::updateAppearance +/// +/// 外観を変更します。 +/// +void FolderPanel::updateAppearance() { - qDebug() << "FolderPanel::addBookmark();"; + qDebug() << "FolderPanel::updateAppearance()"; - QSettings settings; - int i = 0; - while (!settings.value(IniKey_BookmarkEntryName(i), "").toString().isEmpty()) { - i++; - } + Preferences prefs(this); + QPalette pal; - QFileInfo info(ui->folderView->dir()); - QString name = info.fileName(); - if (name.isEmpty()) { - name = "root"; - } - settings.setValue(IniKey_BookmarkEntryName(i), name); - settings.setValue(IniKey_BookmarkEntryPath(i), info.absoluteFilePath()); + pal = ui->locationBox->palette(); + pal.setColor(QPalette::Base, prefs.locationBoxBgColor(model()->isActive())); + pal.setColor(QPalette::Text, prefs.locationBoxFgColor(model()->isActive())); + ui->locationBox->setPalette(pal); + + pal = ui->searchBox->palette(); + pal.setColor(QPalette::Base, prefs.getSearchBoxBgColor()); + pal.setColor(QPalette::Text, prefs.getSearchBoxFgColor()); + ui->searchBox->setPalette(pal); + + pal = ui->folderView->palette(); + pal.setColor(QPalette::Base, prefs.folderViewBgColor(model()->isActive())); + ui->folderView->setPalette(pal); + + pal = ui->thumbnailView->palette(); + pal.setColor(QPalette::Base, prefs.folderViewBgColor(model()->isActive())); + ui->thumbnailView->setPalette(pal); - m_mainWnd->statusBar()->showMessage(tr("%1をブックマークに追加しました").arg(name)); + QHeaderView *header = ui->folderView->verticalHeader(); + QFont font = prefs.getFolderViewFont(); + header->setDefaultSectionSize(QFontMetrics(font).height() * prefs.getLineHeight()); } -void FolderPanel::itemFound() +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::searchNext +/// \param step 次なら1, 前なら-1 +/// +/// 次または前のアイテムを検索します。 +/// +void FolderPanel::searchNext(int step) { - qDebug() << "FolderPanel::itemFound"; + qDebug() << "FolderPanel::searchNext()" << step; - QPalette pal = ui->searchBox->palette(); - pal.setColor(QPalette::Text, QPalette().text().color()); - ui->searchBox->setPalette(pal); + QModelIndex index = model()->search(ui->searchBox->text(), + itemView()->currentIndex(), + step); + showSearchResult(index); } -void FolderPanel::itemNotFound() +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::showSearchResult +/// \param index 検索されたアイテム +/// +/// 検索結果を表示します。 +/// +void FolderPanel::showSearchResult(const QModelIndex &index) { - qDebug() << "FolderPanel::itemNotFound"; + Preferences prefs(this); QPalette pal = ui->searchBox->palette(); - pal.setColor(QPalette::Text, Qt::red); + if (index.isValid()) { + itemView()->setCurrentIndex(index); + pal.setColor(QPalette::Base, prefs.getSearchBoxBgColor()); + pal.setColor(QPalette::Text, prefs.getSearchBoxFgColor()); + } + else { + pal.setColor(QPalette::Base, prefs.getSearchBoxUnmatchBgColor()); + pal.setColor(QPalette::Text, prefs.getSearchBoxUnmatchFgColor()); + } ui->searchBox->setPalette(pal); } -void FolderPanel::searchItem(const QString &text) +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::model_dataChanged +/// \param topLeft (使用しません) +/// \param bottomRight (使用しません) +/// +/// アイテムの選択状態変更に伴う処理を行います。 +/// +void FolderPanel::model_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { - qDebug() << "FolderPanel::searchItem" << text; + Q_UNUSED(topLeft); + Q_UNUSED(bottomRight); - if (text.right(1) == "/") { - // '/'が入力されたら、検索終了 - ui->searchBox->setText(text.left(text.length() - 1)); - ui->folderView->setFocus(); + QFileInfoList list = model()->markedItems(); + if (list.isEmpty()) { + ui->filterLabel->setText(tr("フィルタ:%1").arg(model()->nameFilters().join(" "))); } else { - ui->folderView->searchItem(ui->searchBox->text()); + int numFolders = 0; + int numFiles = 0; + qint64 totalSize = 0; + foreach (const QFileInfo &fi, list) { + if (fi.isDir()) { + ++numFolders; + } + else { + ++numFiles; + totalSize += fi.size(); + } + } + + QString text; + if (numFolders > 0) { + text += tr("%1個のフォルダ ").arg(numFolders); + } + if (numFiles > 0) { + text += tr("%1個のファイル ").arg(numFiles); + } + if (!text.isEmpty()) { + text += tr("を選択 合計%1").arg(FileSizeToString(totalSize)); + } + ui->filterLabel->setText(text); } } -void FolderPanel::focusInEvent(QFocusEvent *) +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::model_Reset +/// +/// モデルリセット後の処理を行います。 +/// +void FolderPanel::model_Reset() { - qDebug() << "FolderPanel::focusInEvent();"; + ui->locationBox->setText(model()->rootPath()); + ui->filterLabel->setText(tr("フィルタ:%1").arg(model()->nameFilters().join(" "))); +} - ui->folderView->setFocus(); +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderPanel::on_searchBox_textEdited +/// \param arg1 入力テキスト +/// +/// 検索ボックスのテキストが変更された場合の処理を行います。 +/// +void FolderPanel::on_searchBox_textEdited(const QString &arg1) +{ + if (arg1.right(1) == "/") { + ui->searchBox->setText(arg1.left(arg1.size() - 1)); + // 検索終了 + itemView()->setFocus(); + } + else { + showSearchResult(model()->search(arg1)); + } } diff --git a/folderpanel.h b/folderpanel.h index 10209d6..363abb0 100644 --- a/folderpanel.h +++ b/folderpanel.h @@ -2,13 +2,11 @@ #define FOLDERPANEL_H #include -class QLabel; -class QLineEdit; -class LocationBox; -class FolderView; -class SearchBox; +#include +class FolderModel; class MainWindow; + namespace Ui { class FolderPanel; } @@ -21,34 +19,28 @@ public: explicit FolderPanel(QWidget *parent = 0); ~FolderPanel(); - void initialize(MainWindow *mainWnd); - void updateAppearance(bool darker = false); - - // getter - QLineEdit *locationBox() const; - FolderView* folderView() const; - SearchBox* searchBox() const; - QLabel* filterLabel() const; - - // setter - void setNameFilters(const QString &filters = QString()); +// FolderView* folderView() const; + void initialize(MainWindow *w); + QAbstractItemView* itemView() const; + FolderModel* model() const; + void searchNext(int step = 1); + void setModel(FolderModel *m); + void toggleSearch(bool checked); + void toggleView(bool checked); + void updateAppearance(); private: Ui::FolderPanel *ui; MainWindow *m_mainWnd; - void showNameFilters(); + void showSearchResult(const QModelIndex &index); public slots: - void dataChange(); - void addBookmark(); - void itemFound(); - void itemNotFound(); - void searchItem(const QString& text); - - // QWidget interface -protected: - void focusInEvent(QFocusEvent *); + +private slots: + void model_dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight); + void model_Reset(); + void on_searchBox_textEdited(const QString &arg1); }; #endif // FOLDERPANEL_H diff --git a/folderpanel.ui b/folderpanel.ui index e52dcd6..d58c939 100644 --- a/folderpanel.ui +++ b/folderpanel.ui @@ -36,9 +36,18 @@ + + + 0 + 26 + + Qt::ClickFocus + + LocationBox + @@ -92,6 +101,9 @@ false + + false + false @@ -101,10 +113,23 @@ - + + + Qt::ElideMiddle + + + QListView::IconMode + + + + + Qt::ClickFocus + + SearchBox + @@ -118,15 +143,15 @@ - SearchBox - QLineEdit -
searchbox.h
-
- FolderView QTableView
folderview.h
+ + ThumbnailView + QListView +
thumbnailview.h
+
diff --git a/folderview.cpp b/folderview.cpp index 301e80d..a9619fc 100644 --- a/folderview.cpp +++ b/folderview.cpp @@ -1,439 +1,162 @@ -#include "common.h" #include "mainwindow.h" +#include "preferences.h" #include "folderpanel.h" #include "folderview.h" +#include #include +#include #include -#include -#include +#include #include -#include -#include -#include -#include - -QString FilesizeToString(quint64 size) -{ - if (size >= 1024 * 1024 * 1024) { - return QString("%1GB").arg(int(10 * size / (1024 * 1024 * 1024)) / 10); - } - if (size >= 1024 * 1024) { - return QString("%1MB").arg(int(10 * size / (1024 * 1024)) / 10); - } - if (size >= 1024) { - return QString("%1KB").arg(int(10 * size / (1024)) / 10); - } - return QString("%1B").arg(size); -} +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderView::FolderView +/// \param parent 親ウィジェット +/// +/// コンストラクタ +/// FolderView::FolderView(QWidget *parent) : QTableView(parent), - m_mainWnd(NULL), - m_model(), + AbstractView(), m_dragStartPos(), - m_dragging(false) + m_dragging(false), + m_saveRow(0), + m_savePath(), + m_saveName() { - setModel(&m_model); - connect(&m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataChanged(QModelIndex,QModelIndex))); - connect(&m_model, SIGNAL(preReload()), this, SLOT(preReload())); - connect(&m_model, SIGNAL(postReload()), this, SLOT(postReload())); - setDragEnabled(true); setAcceptDrops(true); setDropIndicatorShown(true); - setContextMenuPolicy(Qt::DefaultContextMenu); } -QString FolderView::side() const -{ - if (this->objectName() == "folderView1") { - return QString("Left"); - } - else { - Q_ASSERT(this->objectName() == "folderView2"); - return QString("Right"); - } -} - -void FolderView::initialize(MainWindow *mainWnd) -{ - qDebug() << side() << "initialize"; - - m_mainWnd = mainWnd; - - setColumnWidth(0, 30); - - // ソート順を初期化する - setSorting(); - - // ネームフィルタを初期化する - setNameFilters(QStringList() << "*"); - - // 前回終了時のパスを開く - QSettings settings; - setPath(settings.value(side() + slash + IniKey_Dir).toString(), true); -} - -void FolderView::refresh() -{ - qDebug() << side() << "refresh"; - - preReload(); - - setPath(m_model.absolutePath(), false); - - postReload(); -} - -void FolderView::preReload() -{ - // 現在行と名前を保存しておく - m_saveRow = currentIndex().row(); - m_saveName = currentItem().fileName(); -} - -void FolderView::postReload() -{ - // 保存した名前と同名アイテムが見つかれば、再選択する - for (int row = 0; row < m_model.rowCount(); row++) { - QModelIndex index = m_model.index(row, 1); - if (m_model.fileInfo(index).fileName().indexOf(m_saveName) != -1) { - setCurrentIndex(index); - return; - } - } - - // 同名アイテムが見つからなければ、行を維持する - if (m_saveRow >= m_model.rowCount()) { - m_saveRow = m_model.rowCount() - 1; - } - setCurrentIndex(m_model.index(m_saveRow, 1)); -} - -void FolderView::searchItem(const QString &text) -{ - qDebug() << side() << "searchItem" << text; - - for (int row = 0; row < m_model.rowCount(); row++) { - QModelIndex index = m_model.index(row, 1); - QString name = m_model.fileInfo(index).fileName().toLower(); - if (name.indexOf(text.toLower()) != -1) { - setCurrentIndex(index); - emit itemFound(); - return; - } - } - - emit itemNotFound(); -} - -void FolderView::searchNext(const QString &text) -{ - qDebug() << side() << "searchNext" << text; - - for (int row = currentIndex().row() + 1; row < m_model.rowCount(); row++) { - QModelIndex index = m_model.index(row, 1); - QString name = m_model.fileInfo(index).fileName().toLower(); - if (name.indexOf(text.toLower()) != -1) { - setCurrentIndex(index); - emit itemFound(); - return; - } - } - - emit itemNotFound(); -} - -void FolderView::searchPrev(const QString &text) -{ - qDebug() << side() << "searchPrev" << text; - - for (int row = currentIndex().row() - 1; row >= 0; row--) { - QModelIndex index = m_model.index(row, 1); - QString name = m_model.fileInfo(index).fileName().toLower(); - if (name.indexOf(text.toLower()) != -1) { - setCurrentIndex(index); - emit itemFound(); - return; - } - } - - emit itemNotFound(); -} - -void FolderView::setCheckStateAll(Qt::CheckState state) -{ - qDebug() << side() << "setCheckStateAll();" << state; - - QModelIndex current = currentIndex(); - - for (int n = 0; n < m_model.rowCount(); n++) { - m_model.setData(m_model.index(n, 0), state, Qt::CheckStateRole); - } - - setCurrentIndex(current); -} - -void FolderView::setCheckStateAllFiles() -{ - qDebug() << side() << "setCheckStateAllFiles();"; - - QModelIndex current = currentIndex(); - - for (int n = 0; n < m_model.rowCount(); n++) { - QModelIndex index = m_model.index(n, 0); - QFileInfo info = m_model.fileInfo(index); - if (info.isDir()) { - m_model.setData(index, Qt::Unchecked, Qt::CheckStateRole); - } - else { - m_model.setData(index, Qt::Checked, Qt::CheckStateRole); - } - } - - setCurrentIndex(current); -} - -void FolderView::invertCheckState() +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderView::initialize +/// \param w メインウィンドウオブジェクト +/// +/// 初期化処理を行います。 +/// +void FolderView::initialize(MainWindow *w) { - qDebug() << side() << "invertCheckState();"; + qDebug() << "FolderView::initialize()"; - QModelIndex current = currentIndex(); + connect(this, SIGNAL(doubleClicked(QModelIndex)), w, SLOT(onOpen(QModelIndex))); + connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), + w, SLOT(view_currentChanged(QModelIndex,QModelIndex))); - for (int n = 0; n < m_model.rowCount(); n++) { - QModelIndex index = m_model.index(n, 0); - if (m_model.data(index, Qt::CheckStateRole).toInt() == Qt::Checked) { - m_model.setData(index, Qt::Unchecked, Qt::CheckStateRole); - } - else { - m_model.setData(index, Qt::Checked, Qt::CheckStateRole); - } - } - - setCurrentIndex(current); -} - -void FolderView::toggleCheckState(const QModelIndex &index) -{ - qDebug() << side() << "toggleCheckState();" << index; - - QFileInfo info = m_model.fileInfo(index); - if (info.fileName() != "..") { - QModelIndex chkIndex = m_model.index(index.row(), 0); - if (m_model.data(chkIndex, Qt::CheckStateRole).toInt() == Qt::Checked) { - m_model.setData(chkIndex, Qt::Unchecked, Qt::CheckStateRole); - } - else { - m_model.setData(chkIndex, Qt::Checked, Qt::CheckStateRole); - } - } - // 最終行でなければ、次のアイテムに移動する - if (index.row() == m_model.rowCount() - 1) { - setCurrentIndex(index); - } - else if (index.row() < m_model.rowCount() - 1) { - setCurrentIndex(m_model.index(index.row() + 1, 1)); - } -} - -bool FolderView::historyBack() -{ - if (!m_history.isBegin()) { - setPath(m_history.back(), false); - return true; - } - return false; -} - -bool FolderView::historyForward() -{ - if (!m_history.isEnd()) { - setPath(m_history.forward(), false); - return true; - } - return false; -} - -QFileInfo FolderView::currentItem() const -{ - qDebug() << side() << "currentItem"; - - return m_model.fileInfo(currentIndex()); -} - -QFileInfoList FolderView::checkedItems() const -{ - qDebug() << side() << "checkedItems()"; - - QFileInfoList list; - for (int n = 0; n < m_model.rowCount(); n++) { - QModelIndex index = m_model.index(n, 0); - if (m_model.data(index, Qt::CheckStateRole).toInt() == Qt::Checked) { - list << m_model.fileInfo(index); - } - } - return list; + installEventFilter(w); + viewport()->installEventFilter(w); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderView::selectedItems +/// \return +/// QFileInfoList FolderView::selectedItems() const { - qDebug() << side() << "selectedItems"; - - // マークされているアイテムを取得する - QFileInfoList list = checkedItems(); - - // 一つもマークされていなければ、カーソル位置のアイテムを取得する + QFileInfoList list = folderModel()->markedItems(); if (list.isEmpty()) { - list << currentItem(); + list << folderModel()->fileInfo(currentIndex()); } return list; } -FolderPanel *FolderView::parentPanel() const -{ - return qobject_cast(parentWidget()); -} - -void FolderView::setPath(const QString &path, bool addHistory) -{ - qDebug() << side() << "setPath" << path << addHistory; - - Q_ASSERT(QFileInfo(path).isDir()); - - m_mainWnd->statusBar()->showMessage(tr("ファイルリストを取得しています...")); - emit retrieveStarted(path); - - m_model.setPath(path); - setCurrentIndex(m_model.index(0, 1)); - - if (addHistory) { - m_history.add(path); - } - - m_mainWnd->statusBar()->showMessage(tr("レディ")); -} - -void FolderView::setFilter(QDir::Filters filter, bool enable) +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderView::model_PreReset +/// +/// モデルリセット前の処理 +/// +void FolderView::model_PreReset() { - qDebug() << side() << "setFilter" << enable; + qDebug() << "FolderView::model_PreReset()"; - if (enable) { - m_model.setFilter(m_model.filter() | filter); + // 現在行と名前を保存しておく + if (model() && currentIndex().isValid()) { + m_saveRow = currentIndex().row(); + m_saveName = folderModel()->fileName(currentIndex()); + m_savePath = folderModel()->rootPath(); } else { - m_model.setFilter(m_model.filter() ^ filter); + m_saveRow = 0; + m_saveName = QString::null; + m_savePath = QString::null; } } -void FolderView::setHistoryIndexAt(int index) -{ - m_history.setAt(index); - setPath(m_history.current(), false); -} - -void FolderView::setNameFilters(const QStringList &list) -{ - m_model.setNameFilters(list); -} - -void FolderView::setSorting() +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderView::model_PostReset +/// +/// モデルリセット後の処理 +/// +void FolderView::model_PostReset() { - qDebug() << side() << "setSorting();"; - - QSettings settings; - QDir::SortFlags flags; + qDebug() << "FolderView::model_PostReset()"; - int sortBy = settings.value(side() + slash + IniKey_SortBy).toInt(); - switch (sortBy) { - case SortByDate: flags |= QDir::Time; break; - case SortBySize: flags |= QDir::Size; break; - case SortByType: flags |= QDir::Type; break; - default: flags |= QDir::Name; break; - } - - // デフォルトだと文字列は昇順で、数値は降順…orz - int orderBy = settings.value(side() + slash + IniKey_OrderBy).toInt(); - if (((sortBy == SortByName || sortBy == SortByType) && orderBy == OrderByDesc) || - ((sortBy == SortByDate || sortBy == SortBySize) && orderBy == OrderByAsc)) - { - flags |= QDir::Reversed; - } - - switch (settings.value(side() + slash + IniKey_PutDirs).toInt()) { - case PutDirsFirst: flags |= QDir::DirsFirst; break; - case PutDirsLast: flags |= QDir::DirsLast; break; + // フォルダが変わった場合は先頭行を選択する + if (m_savePath != folderModel()->rootPath()) { + setCurrentIndex(model()->index(0, 0)); + return; } - if (settings.value(side() + slash + IniKey_IgnoreCase).toBool()) { - flags |= QDir::IgnoreCase; + // 保存した名前と同名アイテムが見つかれば、再選択する + for (int row = 0; row < model()->rowCount(); row++) { + QModelIndex index = model()->index(row, 0); + if (folderModel()->fileName(index) == m_saveName) { + setCurrentIndex(index); + return; + } } - m_model.setSorting(flags); -} - -void FolderView::keyPressEvent(QKeyEvent *event) -{ - qDebug() << side() << "keyPressEvent"; - - if (IsKeyUpDown(event)) { - QTableView::keyPressEvent(event); - event->accept(); - return; + // 同名アイテムが見つからなければ、行を維持する + if (m_saveRow >= model()->rowCount()) { + m_saveRow = model()->rowCount() - 1; } - - // MainWindowへ - event->ignore(); -} - -void FolderView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) -{ - qDebug() << side() << "dataChanged();"; - - emit dataChanged(); - - QTableView::dataChanged(topLeft, bottomRight, roles); -} - -void FolderView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) -{ - qDebug() << side() << "currentChanged();" << current; - - emit currentChanged(m_model.fileInfo(current)); - - QTableView::currentChanged(current, previous); + setCurrentIndex(model()->index(m_saveRow, 1)); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief FolderView::mousePressEvent +/// \param event +/// void FolderView::mousePressEvent(QMouseEvent *event) { - if ((event->buttons() & Qt::LeftButton) || (event->buttons() & Qt::RightButton)) + m_dragStartPos = QPoint(); + if ((event->buttons() & Qt::LeftButton) || + (event->buttons() & Qt::RightButton)) { - m_dragStartPos = event->pos(); + 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)) + !(event->buttons() & Qt::RightButton)) { QTableView::mouseMoveEvent(event); return; } - if ((event->pos() - m_dragStartPos).manhattanLength() - < QApplication::startDragDistance()) + if (m_dragStartPos.isNull() || + (event->pos() - m_dragStartPos).manhattanLength() < qApp->startDragDistance()) { QTableView::mouseMoveEvent(event); return; } QFileInfoList list = selectedItems(); - if (list.isEmpty()) { - QTableView::mousePressEvent(event); + if (list.size() == 1 && list[0].fileName() == "..") { + QTableView::mouseMoveEvent(event); return; } @@ -448,17 +171,15 @@ void FolderView::mouseMoveEvent(QMouseEvent *event) drag->setMimeData(mimeData); m_dragging = true; - if (event->buttons() & Qt::RightButton) { - drag->exec(Qt::CopyAction | Qt::MoveAction); - } - else { - drag->exec(Qt::CopyAction); - } + 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; @@ -467,40 +188,37 @@ void FolderView::dragEnterEvent(QDragEnterEvent *event) QTableView::dragEnterEvent(event); } -void FolderView::dropEvent(QDropEvent *event) +void FolderView::setModel(QAbstractItemModel *model) { - qDebug() << side() << "dropEvent();"; - - if (m_dragging) { - event->ignore(); - return; + if (this->model()) { + this->model()->disconnect(this); } - QFileInfoList list; - foreach (const QUrl &url, event->mimeData()->urls()) { - QString path = QFileInfo(url.toLocalFile()).canonicalFilePath(); - if (!path.isEmpty()) { - list << path; - } - else { - qDebug() << "path is empty." << url; - } - } + QTableView::setModel(model); - if (list.isEmpty()) { - event->ignore(); - return; - } + if (this->model()) { + connect(this->model(), SIGNAL(modelAboutToBeReset()), this, SLOT(model_PreReset())); + connect(this->model(), SIGNAL(modelReset()), this, SLOT(model_PostReset())); - event->acceptProposedAction(); - - emit dropAccepted(list, event); + // 列の幅を設定する + horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + horizontalHeader()->setSectionResizeMode(FolderModel::Name, + QHeaderView::Stretch); + } } - -void FolderView::contextMenuEvent(QContextMenuEvent *event) +void FolderView::scaleUp() { - qDebug() << side() << "contextMenuEvent();"; + Preferences prefs(this); + QFont font = prefs.getFolderViewFont(); + font.setPointSize(font.pointSize() + 1); + prefs.setFolderViewFont(font); +} - emit requestContextMenu(event); +void FolderView::scaleDown() +{ + Preferences prefs(this); + QFont font = prefs.getFolderViewFont(); + font.setPointSize(font.pointSize() - 1); + prefs.setFolderViewFont(font); } diff --git a/folderview.h b/folderview.h index e23813c..930d115 100644 --- a/folderview.h +++ b/folderview.h @@ -1,89 +1,62 @@ #ifndef FOLDERVIEW_H #define FOLDERVIEW_H -#include "filetablemodel.h" -#include "history.h" +#include "abstractview.h" +#include "foldermodel.h" #include class MainWindow; -class FolderPanel; -class FolderView : public QTableView +class FolderView : public QTableView, public AbstractView { Q_OBJECT + Q_PROPERTY(bool dragging MEMBER m_dragging READ isDragging()) + public: explicit FolderView(QWidget *parent = 0); - QString side() const; - - // actions - void initialize(MainWindow *mainWnd); - - void searchItem(const QString &text); - void searchNext(const QString &text); - void searchPrev(const QString &text); - - void setCheckStateAll(Qt::CheckState state); - void setCheckStateAllFiles(); - void invertCheckState(); - void toggleCheckState(const QModelIndex &index); - - bool historyBack(); - bool historyForward(); - - // getter - QFileInfo currentItem() const; - QString dir() const { return m_model.absolutePath(); } - QFileInfoList checkedItems() const; - QFileInfoList selectedItems() const; - const History* history() const { return &m_history; } - QStringList nameFilters() const { return m_model.nameFilters(); } - FolderPanel *parentPanel() const; - - - // setter - void setPath(const QString &path, bool addHistory); - void setFilter(QDir::Filters filter, bool enable); - void setHistoryIndexAt(int index); - void setNameFilters(const QStringList &list); - void setSorting(); + void initialize(MainWindow *w); + bool isDragging(); + FolderModel* folderModel() const; + QFileInfoList selectedItems() const; private: - MainWindow *m_mainWnd; - FileTableModel m_model; - History m_history; - QPoint m_dragStartPos; - bool m_dragging; - int m_saveRow; + QPoint m_dragStartPos; + bool m_dragging; + int m_saveRow; + QString m_savePath; QString m_saveName; signals: - void currentChanged(const QFileInfo &info); - void dataChanged(); - void dropAccepted(const QFileInfoList &list, QDropEvent *event); - void itemFound(); - void itemNotFound(); - void retrieveStarted(const QString &path); - void requestContextMenu(QContextMenuEvent *event); -public slots: - void refresh(); - void preReload(); - void postReload(); - - // QAbstractItemView interface -protected slots: - void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); - void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector()); +private slots: + void model_PreReset(); + void model_PostReset(); // QWidget interface protected: - void keyPressEvent(QKeyEvent *event); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void dragEnterEvent(QDragEnterEvent *event); - void dropEvent(QDropEvent *event); - void contextMenuEvent(QContextMenuEvent *event); + + // QAbstractItemView interface +public: + void setModel(QAbstractItemModel *model); + + // AbstractView interface +public: + void scaleUp(); + void scaleDown(); }; +inline bool FolderView::isDragging() +{ + return m_dragging; +} + +inline FolderModel *FolderView::folderModel() const +{ + return static_cast(model()); +} + #endif // FOLDERVIEW_H diff --git a/global.cpp b/global.cpp new file mode 100644 index 0000000..789184f --- /dev/null +++ b/global.cpp @@ -0,0 +1,22 @@ +#include "global.h" + +void appendActionShortcut(QAction *action, const QString &ks) +{ + QList shortcuts = action->shortcuts(); + shortcuts << QKeySequence(ks); + action->setShortcuts(shortcuts); +} + +QString FileSizeToString(qint64 size) +{ + if (size >= 1024 * 1024 * 1024) { + return QString("%1GB").arg(int(10 * size / (1024 * 1024 * 1024)) / 10); + } + if (size >= 1024 * 1024) { + return QString("%1MB").arg(int(10 * size / (1024 * 1024)) / 10); + } + if (size >= 1024) { + return QString("%1KB").arg(int(10 * size / (1024)) / 10); + } + return QString("%1B").arg(size); +} diff --git a/global.h b/global.h new file mode 100644 index 0000000..9a72364 --- /dev/null +++ b/global.h @@ -0,0 +1,16 @@ +#ifndef GLOBAL_H +#define GLOBAL_H + +#define QQ(x) ("\"" + QString(x) + "\"") + +#include +#include +#include +#include + +typedef QMap StringMap; + +extern void appendActionShortcut(QAction *action, const QString &ks); +extern QString FileSizeToString(qint64 size); + +#endif // GLOBAL_H diff --git a/history.cpp b/history.cpp deleted file mode 100644 index 733ceb4..0000000 --- a/history.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "history.h" - -History::History() : - m_list(), - m_pos(0) -{ -} - -void History::add(const QString &path) -{ - // 現在位置より後ろのデータは削除する - if (!isEmpty() && !isEnd()) { - m_list.resize(m_pos + 1); - } - // 現在位置と異なるパスであれば追加する - if (isEmpty() || (m_list[m_pos] != path)) { - m_list << path; - } - m_pos = m_list.size() - 1; -} - -const QString &History::back() -{ - if (!isBegin()) { - m_pos--; - } - return m_list[m_pos]; -} - -const QString &History::forward() -{ - if (!isEnd()) { - m_pos++; - } - return m_list[m_pos]; -} diff --git a/history.h b/history.h deleted file mode 100644 index 0d86e4d..0000000 --- a/history.h +++ /dev/null @@ -1,34 +0,0 @@ -#include - -#ifndef HISTORY_H -#define HISTORY_H - -#include - -class History -{ - typedef QVector Container; - -public: - History(); - - void add(const QString &path); - - const QString& back(); - const QString& forward(); - const QString& current() const { return m_list[m_pos]; } - - bool isBegin() const { return m_pos == 0; } - bool isEnd() const { return m_pos == m_list.size() - 1; } - bool isEmpty() const { return m_list.isEmpty(); } - - int size() const { return m_list.size(); } - const QString& at(int n) const { return m_list.at(n); } - void setAt(int n) { m_pos = n; } - -private: - Container m_list; - int m_pos; -}; - -#endif // HISTORY_H diff --git a/historydialog.cpp b/historydialog.cpp index ff3f1aa..a44b4f6 100644 --- a/historydialog.cpp +++ b/historydialog.cpp @@ -1,14 +1,13 @@ -#include "common.h" -#include "mainwindow.h" +#include "foldermodel.h" #include "historydialog.h" #include "ui_historydialog.h" HistoryDialog::HistoryDialog(QWidget *parent) : QDialog(parent), ui(new Ui::HistoryDialog), - m_leftHistory(NULL), - m_rightHistory(NULL), - m_displaying(NULL) + m_leftModel(NULL), + m_rightModel(NULL), + m_activeModel(NULL) { ui->setupUi(this); resize(parent->width() * 0.8, height()); @@ -19,76 +18,56 @@ HistoryDialog::~HistoryDialog() delete ui; } -void HistoryDialog::setHistory(const History *left, const History *right) +void HistoryDialog::setModel(const FolderModel *left, const FolderModel *right, FolderModel *active) { - m_leftHistory = left; - m_rightHistory = right; -} + m_leftModel = left; + m_rightModel = right; + m_activeModel = active; -void HistoryDialog::setDefaultLeft(bool bLeft) -{ - if (bLeft) { - ui->leftPane->setChecked(true); + if (active == left) { + ui->radioLeft->click(); } else { - ui->rightPane->setChecked(true); + ui->radioRight->click(); } -} -int HistoryDialog::selectedIndex() const -{ - int row = ui->listWidget->currentIndex().row(); - return m_displaying->size() - row - 1; -} - -const QString HistoryDialog::selectedSide() const -{ - if (ui->leftPane->isChecked()) { - return QString("Left"); + for (int n = left->history().size() - 1; n >= 0; --n) { + ui->listLeft->addItem(left->history().at(n)); } - else { - return QString("Right"); + for (int n = right->history().size() - 1; n >= 0; --n) { + ui->listRight->addItem(right->history().at(n)); } } -void HistoryDialog::showLeftHistory() +void HistoryDialog::on_radioLeft_clicked() { - if (m_displaying != m_leftHistory) { - m_displaying = m_leftHistory; - showHistory(); - } - + ui->listRight->setVisible(false); + ui->listLeft->setVisible(true); } -void HistoryDialog::showRightHistory() +void HistoryDialog::on_radioRight_clicked() { - if (m_displaying != m_rightHistory) { - m_displaying = m_rightHistory; - showHistory(); - } + ui->listLeft->setVisible(false); + ui->listRight->setVisible(true); } -void HistoryDialog::showHistory() +void HistoryDialog::accept() { - ui->listWidget->clear(); - for (int n = 0; n < m_displaying->size(); n++) { - ui->listWidget->insertItem(0, m_displaying->at(n)); + QString path; + const FolderModel *selected; + if (ui->radioLeft->isChecked()) { + selected = m_leftModel; + path = ui->listLeft->currentItem()->text(); + } + else { + selected = m_rightModel; + path = ui->listRight->currentItem()->text(); } - ui->listWidget->setCurrentRow(0); -} - -void HistoryDialog::showEvent(QShowEvent *event) -{ - Q_UNUSED(event); - if (ui->leftPane->isChecked()) { - showLeftHistory(); + if (selected == m_activeModel) { + m_activeModel->setHistoryAt(path); } else { - showRightHistory(); + m_activeModel->setRootPath(path); } - - connect(ui->leftPane, SIGNAL(clicked()), this, SLOT(showLeftHistory())); - connect(ui->rightPane, SIGNAL(clicked()), this, SLOT(showRightHistory())); - connect(ui->listWidget, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept())); } diff --git a/historydialog.h b/historydialog.h index b48b014..7903e2c 100644 --- a/historydialog.h +++ b/historydialog.h @@ -1,9 +1,8 @@ #ifndef HISTORYDIALOG_H #define HISTORYDIALOG_H -#include "history.h" - #include +class FolderModel; namespace Ui { class HistoryDialog; @@ -17,26 +16,23 @@ public: explicit HistoryDialog(QWidget *parent = 0); ~HistoryDialog(); - void setHistory(const History *left, const History *right); - void setDefaultLeft(bool bLeft); + void setModel(const FolderModel *left, + const FolderModel *right, + FolderModel *active); - int selectedIndex() const; - const QString selectedSide() const; +private slots: + void on_radioLeft_clicked(); + void on_radioRight_clicked(); private: Ui::HistoryDialog *ui; - const History *m_leftHistory; - const History *m_rightHistory; - const History *m_displaying; - -private slots: - void showLeftHistory(); - void showRightHistory(); - void showHistory(); + const FolderModel *m_leftModel; + const FolderModel *m_rightModel; + FolderModel *m_activeModel; - // QWidget interface -protected: - void showEvent(QShowEvent *event); + // QDialog interface +public slots: + void accept(); }; #endif // HISTORYDIALOG_H diff --git a/historydialog.ui b/historydialog.ui index 311e85f..6cc2ee0 100644 --- a/historydialog.ui +++ b/historydialog.ui @@ -6,8 +6,8 @@ 0 0 - 280 - 286 + 548 + 288 @@ -17,12 +17,12 @@ - + Qt::StrongFocus - 左ペイン + 左パネル buttonGroup @@ -30,12 +30,12 @@ - + Qt::StrongFocus - 右ペイン + 右パネル buttonGroup @@ -45,11 +45,22 @@ - - - Qt::StrongFocus - - + + + + + Qt::StrongFocus + + + + + + + Qt::StrongFocus + + + + @@ -67,9 +78,9 @@ - listWidget - leftPane - rightPane + listLeft + radioLeft + radioRight diff --git a/images/Picture.png b/images/Picture.png deleted file mode 100644 index c992023b8df38d315a38ee1cc320033cc2fe8175..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1994 zcmV;*2Q~PKP)gUG5~!lYjbm@TzOC0@+k2gzot@d4!#}%Tdt*_=Q~Cho z^`4n?`Oo)%|M&lMmf=&r*#7}=y8fGqocj2nyZ$EU;OK%J!sH(5k0eHXf0%&;0Skp(=K+2j_?Q^jgxn^f$;VuQNF}yd8 zH*A6L&!d~IZ}lS-3dQRHB0rklozD+!!Sx>w7W4af7=I8()5gqKqliYMab{T-KlyIr0OEr*w3=qT2S65e@nP!zw|0=l~yVgkVFObPQ%W3rYc{#rGOg9Wk#I=7c z;netHJk}q?YN~{5^EupDH;}FfDAx7?u-#Pc_K48Pj%L~T{g)0Q7K_E1VHo_?iz~>M z_&(j#MrGh>`sz|;L_8L*Zy4A#8J-`GBAH%8uBg@d?2U%;!s%f+Mg^82VoSGC&}z7z z)NysmfNpVgc!7y9Lpy<1y)raK#+d;dJ&*LnnXcY^pFovbvlrh z09My`&=HZ*7mFgG_)sX7abac_<%(7JOV=xS_Ng)Sg%w1?0f?d(0&~DbU@cR|)!7WP zo7*_#55N-$AP`XC;SQb{l+fFIIL@@P#`Pjlt=foo`7oO*LXv>to_2hcNa4Mij}h>B zF*eYFt^hF5-vdGR;-k4VZhpKBMG^7RGh>*$zm5WV|Aomx_`M>D)4_6D#~(kKg;ld5 z5Id42gGnA@#lg!@MsRdwD9(z-62Elq4h9DLq0+|bl7+--7DcUyT)Em%g)3c(-LWH` z81Da1y;x|{0(Zi`UdtI*0OR#uX3e&h2~BiPE4P9!f(6S(%zB-XaFd(wVxq8n#V6M$?s%Wtig zv9OZC{j~y$6yv&PcgtufpkivQ7bCqf+_{}X#ja6|4VZQgi|Gx7y%LTcJqn+qK+l)3 zkjg*__%YfS1#BQ+(1>;ga^MjDK9?c3@~DxG7f<%$*;5m7w!OX0FW=1IueTDgtlDlV zZ=`}shR#ksO0AE=K@@Km5$kNn-GzI&boDZ1p9r5XP!CUAFpQzzK_u?ahSFSU4`(6Uv)y|z+++SV5#UH+o$%)U#+2&@3zy9<0A1FS8Ai%b5bOvm^c={BU zwhOqI-a$HBL|3#6neBC4|8NF2w;;ZoKmr#>dCwER{;}={J7~y;8tVAqz&iZkBaO6av$BU_gLKLb59rx+9#FPO|7g z4f;?eb%`X(pz4E{Hsubfof1c*FE6neA;6iEL-#&*j#XptPP_A;yR}ajpg(`WaD1I2F9NI|PC8`w?v7|UUh6WGU(=@$J%H}m< z$_GDHIHRJGHdK^!6PeT!gjxk&Ss^~-1&z4kdWXWSugkToQ6FP@fAq)z9jQE6(=-$cCEAF==c?T!V{0b^ zExSo+ZNe`L5U2#ZnldUzU1vdJ=E^V5VRDkvaB*>wzx>7z>Xa!yg+PeN8w~R+TQEo$ zA=NFzomfk!kt>jhs8%@S@zJ42(4mT0)(mh#LYdM_AnzoqfIHcBh>C+CF)2FaF^Sa` zxhrmo9Cb_e#q&SG@#DwiERjg?=U#o2s-Of>pd2T}#6B!rM2;wTD9r@Yd69HcC8aY0 z;MNJ1HW=%VB2{)^l3whp2Cc9Idb!YERWJ{uaQR>qb<&1GI+E%IHAtz=Dco0na~@Mu zQ*kywKhMv8<1K_d0%{aLf$Fx`rJf6QwN~h@;tFdcUx7(9I|R^uS@W8KSlEYHB!K1A zI`X*!fvb{0-9qBP;~_RF)*vCvWZQ-bkHp|15gO#+<=_1lCr+G*v$?suym6%F`-g1K zTaMV+J6`Ygvj@j{^T4^gzPW}qPXf*L2d+8*YKQ56dbfSpSHcD07On2x_F-Szr~lLJ ce;&ZU0J9d+w&YlRsQ>@~07*qoM6N<$g1j%zwg3PC diff --git a/images/Pictures.png b/images/Pictures.png new file mode 100644 index 0000000000000000000000000000000000000000..588947ab0e16d01f6140c0458b9ff1ab72d43aa7 GIT binary patch literal 26452 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 XijPO~mbm?&1qe`-Q+ZP%V;Jy%hIQ>R literal 0 HcmV?d00001 diff --git a/installer-full.nsi b/installer-full.nsi index 921179b..b54cd61 100644 --- a/installer-full.nsi +++ b/installer-full.nsi @@ -2,7 +2,7 @@ ; HM NIS Edit Wizard helper defines !define PRODUCT_NAME "Gefu" -!define PRODUCT_VERSION "0.20" +!define PRODUCT_VERSION "0.21" !define PRODUCT_PUBLISHER "@miyabi_satoh" !define PRODUCT_WEB_SITE "http://gefu.sourceforge.jp/" !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\Gefu.exe" @@ -51,7 +51,7 @@ var ICONS_GROUP ; MUI end ------ Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" -OutFile "Gefu020_full_setup.exe" +OutFile "Gefu021_full_setup.exe" InstallDir "$PROGRAMFILES\Gefu" InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" ShowInstDetails show diff --git a/installer.nsi b/installer.nsi index 920f98b..ad6d550 100644 --- a/installer.nsi +++ b/installer.nsi @@ -2,7 +2,7 @@ ; HM NIS Edit Wizard helper defines !define PRODUCT_NAME "Gefu" -!define PRODUCT_VERSION "0.20" +!define PRODUCT_VERSION "0.21" !define PRODUCT_PUBLISHER "@miyabi_satoh" !define PRODUCT_WEB_SITE "http://gefu.sourceforge.jp/" !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\Gefu.exe" @@ -51,7 +51,7 @@ var ICONS_GROUP ; MUI end ------ Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" -OutFile "Gefu020_Setup.exe" +OutFile "Gefu021_Setup.exe" InstallDir "$PROGRAMFILES\Gefu" InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" ShowInstDetails show diff --git a/irenamedialog.cpp b/irenamedialog.cpp deleted file mode 100644 index 25248e1..0000000 --- a/irenamedialog.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "irenamedialog.h" - -IRenameDialog::IRenameDialog(QWidget *parent) : - QDialog(parent) -{ -} - -void IRenameDialog::setWorkingDirectory(const QString &path) -{ - m_dir.setPath(path); -} diff --git a/irenamedialog.h b/irenamedialog.h deleted file mode 100644 index 89e3bae..0000000 --- a/irenamedialog.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef IRENAMEDIALOG_H -#define IRENAMEDIALOG_H - -#include -#include -#include "common.h" - -class IRenameDialog : public QDialog -{ - Q_OBJECT -public: - explicit IRenameDialog(QWidget *parent = 0); - - const StringMap& renameMap() const { return m_RenameMap; } - - void setWorkingDirectory(const QString &path); - virtual void setNames(const QFileInfoList &names) = 0; - -signals: - -public slots: - -protected: - QDir m_dir; - StringMap m_RenameMap; -}; - -#endif // IRENAMEDIALOG_H diff --git a/keybind.txt b/keybind.txt index 20d4b4c..8c813af 100644 --- a/keybind.txt +++ b/keybind.txt @@ -11,10 +11,10 @@ = フォルダビュー ||キー ||装飾なし ||Shift ||Alt ||Ctrl(Command) ||覚え方 || ||A ||すべてのファイルをマーク ||すべてマーク || || ||All || -||B ||ブックマークを表示 ||ブックマークを編集 || || ||Bookmark || +||B ||ブックマークを表示 ||ブックマークを編集 || ||ブックマークを追加 ||Bookmark || ||C ||ファイル名をクリップボードにコピー ||フルパスをクリップボードにコピー || ||隣のパネルにアイテムをコピー ||Copy || ||D || || || ||選択アイテムを削除 ||Delete || -||E ||外部エディタで開く || || ||ファイルを作成 ||Edit, newの「E」 || +||E ||外部エディタで開く || || ||ファイルを作成 ||Edit || ||G ||フォルダを選択して移動 || || || ||Go || ||H ||ホームフォルダに移動 ||隠しファイルを表示/非表示 || || ||Home, Hide || ||I ||マークを反転 || || || ||Invert || @@ -24,7 +24,7 @@ ||M ||開く ||アプリケーションで開く || ||隣のパネルにアイテムを移動 ||viのキーバインド, Move || ||O ||隣のパネルと同じフォルダを表示 ||隣のパネルに同じフォルダを表示 || || ||Onaji(同じ) || ||P ||プレビューモードに切り替え/解除 || || || ||Preview || -||R ||履歴を表示 || || ||名前の変更 ||Rireki, Rename || +||R ||履歴を表示 || || ||名前の変更 ||Rireki(履歴), Rename || ||S ||ソート方法を選択 ||システムファイルを表示/非表示 || || ||Sort, System || ||U ||すべてのマークを解除 ||アーカイバで開く || || ||Unmark, Unpack || ||W ||表示フォルダを交換 || || || ||swapの「W」 || @@ -41,6 +41,8 @@ ||/ ||ファイル検索開始/終了 || || || || || ||← ||親フォルダに移動/隣のパネルに移動 ||右パネルを拡大 || || || || ||→ ||親フォルダに移動/隣のパネルに移動 ||左パネルを拡大 || || || || +||, ||単画面/二画面を切り替え || || || ||< || +||. ||リスト/サムネイルを切り替え || || || ||> || = テキストビューア ||キー ||装飾なし ||Shift ||Alt ||Ctrl(Command) ||覚え方 || diff --git a/main.cpp b/main.cpp index 883cd03..83ede96 100644 --- a/main.cpp +++ b/main.cpp @@ -1,220 +1,12 @@ -#include "common.h" #include "mainwindow.h" -#include #include -#include -#include -#include -#include int main(int argc, char *argv[]) { QApplication a(argc, argv); - a.setOrganizationName("gefu"); - a.setOrganizationDomain("sourceforge.jp"); - a.setApplicationName("Gefu"); - a.setWindowIcon(QIcon("://images/file-manager.png")); - - QSettings::setDefaultFormat(QSettings::IniFormat); - QSettings settings; - if (settings.value(IniKey_ResetOnBoot, false).toBool()) { - settings.clear(); - } - - // 各オプションのデフォルト値を設定する - QFont font = a.font(); -#ifdef Q_OS_WIN - font.setFamily("ï¼­ï¼³ ゴシック"); -#else - font.setFamily("Monaco"); -#endif - //>>>>> 起動と終了 - if (settings.value(IniKey_ConfirmExit, "").toString().isEmpty()) { - settings.setValue(IniKey_ConfirmExit, true); - settings.setValue(IniKey_BootSizeSpec, "sizeRelative"); - settings.setValue(IniKey_BootSizeAbs, QSize(800,600)); - settings.setValue(IniKey_BootSizeRel, QSize(75,75)); - settings.setValue(IniKey_BootPosSpec, "posCenter"); - settings.setValue(IniKey_BootPosAbs, QPoint(0, 0)); - settings.setValue(IniKey_BootPosRel, QPoint(0, 0)); - } - //>>>>> 色とフォント - if (settings.value(IniKey_BoxFont, "").toString().isEmpty()) { - settings.setValue(IniKey_BoxFont, font); - settings.setValue(IniKey_BoxColorBg, QPalette().base().color()); - settings.setValue(IniKey_BoxColorFg, QPalette().text().color()); - } - if (settings.value(IniKey_ViewFont, "").toString().isEmpty()) { - settings.setValue(IniKey_ViewFont, font); - settings.setValue(IniKey_ViewColorBgMark, QColor(0,192,0)); - settings.setValue(IniKey_ViewColorBgNormal, QPalette().base().color()); - settings.setValue(IniKey_ViewColorFgHidden, QColor(128,128,128)); - settings.setValue(IniKey_ViewColorFgMark, QColor(128,0,0)); - settings.setValue(IniKey_ViewColorFgNormal, QPalette().text().color()); - settings.setValue(IniKey_ViewColorFgReadonly, QColor(0,128,0)); - settings.setValue(IniKey_ViewColorFgSystem, QColor(128,0,128)); - } - //>>>>> ファイル操作 - if (settings.value(IniKey_AutoCloseCopy, "").toString().isEmpty()) { - settings.setValue(IniKey_AutoCloseCopy, false); - settings.setValue(IniKey_AutoCloseDelete, false); - settings.setValue(IniKey_AutoCloseMove, false); - settings.setValue(IniKey_AutoCloseRename, false); - } - if (settings.value(IniKey_ConfirmCopy, "").toString().isEmpty()) { - settings.setValue(IniKey_ConfirmCopy, true); - settings.setValue(IniKey_ConfirmDelete, true); - settings.setValue(IniKey_ConfirmMove, true); - settings.setValue(IniKey_ConfirmRename, true); - } - if (settings.value(IniKey_DefaultOnCopy, "").toString().isEmpty()) - settings.setValue(IniKey_DefaultOnCopy, "owDefIfNew"); - if (settings.value(IniKey_MoveAfterCreateFolder, "").toString().isEmpty()) - settings.setValue(IniKey_MoveAfterCreateFolder, false); - if (settings.value(IniKey_OpenAfterCreateFile, "").toString().isEmpty()) - settings.setValue(IniKey_OpenAfterCreateFile, false); - //>>>>> パス設定 - // エディタ - if (settings.value(IniKey_PathEditor, "").toString().isEmpty()) { -#if defined(Q_OS_WIN) - settings.setValue(IniKey_PathEditor, "notepad.exe"); -#elif defined(Q_OS_MAC) - settings.setValue(IniKey_PathEditor, "/Applications/TextEdit.app"); -#else - settings.setValue(IniKey_PathEditor, "gedit"); -#endif - } - // ターミナル - if (settings.value(IniKey_PathTerminal, "").toString().isEmpty()) { -#if defined(Q_OS_WIN) - settings.setValue(IniKey_PathTerminal, "cmd.exe /k cd"); -#elif defined(Q_OS_MAC) - settings.setValue(IniKey_PathTerminal, "/Applications/Utilities/Terminal.app --args -c cd"); -#else - settings.setValue(IniKey_TerminalPath, "gnome-terminal"); -#endif - } - // アーカイバ - if (settings.value(IniKey_PathArchiver, "").toString().isEmpty()) { -#if defined(Q_OS_WIN) - if (QFileInfo::exists("C:/Program Files/Lhaplus/Lhaplus.exe")) { - settings.setValue(IniKey_PathArchiver, QQ("C:/Program Files/Lhaplus/Lhaplus.exe")); - } - else if (QFileInfo::exists("C:/Program Files/Lhaca/Lhaca.exe")) { - settings.setValue(IniKey_PathArchiver, QQ("C:/Program Files/Lhaca/Lhaca.exe")); - } - else if (QFileInfo::exists("C:/Program Files/7-zip/7zFM.exe")) { - settings.setValue(IniKey_PathArchiver, QQ("C:/Program Files/7-zip/7zFM.exe")); - } - -#elif defined(Q_OS_MAC) - settings.setValue(IniKey_PathArchiver, QQ("/System/Library/CoreServices/Archive Utility.app")); -#else -#endif - } - - //>>>>> テキストビューア - if (settings.value(IniKey_ViewerFont, "").toString().isEmpty()) { - settings.setValue(IniKey_ViewerColorBg, QPalette().base().color()); - settings.setValue(IniKey_ViewerColorFg, QPalette().text().color()); - settings.setValue(IniKey_ViewerFont, font); - settings.setValue(IniKey_ViewerForceOpen, false); - settings.setValue(IniKey_ViewerInherit, true); - settings.setValue(IniKey_ViewerIgnoreExt, ViewerIgnoreExt()); - } - - //>>>>> 隠しファイルの表示 - if (settings.value(IniKey_ShowHidden, "").toString().isEmpty()) - settings.setValue(IniKey_ShowHidden, false); - //>>>>> システムファイルの表示 - if (settings.value(IniKey_ShowSystem, "").toString().isEmpty()) - settings.setValue(IniKey_ShowSystem, false); - //>>>>> 最新版のチェック - if (settings.value(IniKey_CheckUpdates, "").toString().isEmpty()) - settings.setValue(IniKey_CheckUpdates, true); - //>>>>> 最後のフォルダとソート方法 - QString side = "Left/"; - if (settings.value(side + IniKey_Dir, "").toString().isEmpty()) { - settings.setValue(side + IniKey_Dir, QDir::homePath()); - settings.setValue(side + IniKey_SortBy, SortByName); - settings.setValue(side + IniKey_OrderBy, OrderByAsc); - settings.setValue(side + IniKey_PutDirs, PutDirsFirst); - settings.setValue(side + IniKey_IgnoreCase, true); - } - side = "Right/"; - if (settings.value(side + IniKey_Dir, "").toString().isEmpty()) { - settings.setValue(side + IniKey_Dir, QDir::homePath()); - settings.setValue(side + IniKey_SortBy, SortByName); - settings.setValue(side + IniKey_OrderBy, OrderByAsc); - settings.setValue(side + IniKey_PutDirs, PutDirsFirst); - settings.setValue(side + IniKey_IgnoreCase, true); - } - MainWindow w; w.show(); return a.exec(); } - -QString ViewerIgnoreExt() -{ - QStringList list; - // 画像系 - list << "ico" << "ai" << "psd" << "xcf" << "tif" << "tiff" << "wmf"; - // 音・動画系 - list << "wav" << "mp3" << "ogg" << "midi" << "mid" << "aif" << "aiff"; - list << "mov" << "mpg" << "mpeg" << "wma" << "wmv" << "asf" << "avi"; - list << "flac" << "mkv"; - // 実行ファイル系 - list << "exe" << "com" << "lib" << "dll" << "msi" << "scr" << "sys"; - list << "o" << "obj" << "ocx" << "a" << "so" << "app"; - // アーカイブ系 - list << "lzh" << "zip" << "cab" << "tar" << "rar" << "gz" << "tgz"; - list << "bz2" << "xz" << "jar" << "7z" << "dmg"; - // ドキュメント系 - list << "pdf" << "doc" << "docx" << "xls" << "xlsx" << "ppt" << "pptx"; - // フォント - list << "ttf" << "ttc"; - - list.sort(); - - return list.join(","); -} - -bool ProcessShortcut(const QString &ksq, const QObject *object) -{ - qDebug() << "ProcessShortcut()"; - - if (ksq.isEmpty()) { - return false; - } - - foreach (QObject *obj, object->children()) { - QAction *action = qobject_cast(obj); - if (!action || !action->isEnabled()) { - continue; - } - - foreach (const QKeySequence &k, action->shortcuts()) { - if (ksq == k.toString()) { - if (action->isCheckable()) { - action->setChecked(!action->isChecked()); - } - else { - emit action->triggered(); - } - qDebug() << "emit" << action->objectName(); - return true; - } - } - } - return false; -} - -void Sleep(int msec) -{ - QEventLoop loop; - QTimer::singleShot(msec, &loop, SLOT(quit())); - loop.exec(); -} diff --git a/mainwindow.cpp b/mainwindow.cpp index f0486d6..7d933d9 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,8 +1,9 @@ -#include "common.h" +#include "global.h" #include "version.h" #include "preferencedialog.h" -#include "folderview.h" -#include "searchbox.h" +#include "foldermodel.h" +#include "folderpanel.h" +//#include "folderview.h" #include "copymoveworker.h" #include "operationdialog.h" #include "overwritedialog.h" @@ -14,208 +15,178 @@ #include "sortdialog.h" #include "simpletextview.h" #include "simpleimageview.h" +#include "bookmarkdialog.h" +#include "preferences.h" #include "mainwindow.h" #include "ui_mainwindow.h" -#include "bookmarkdialog.h" #include #include #include -#include #include -#include +#include #include -#include #include #include #include #include #include -#include +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::MainWindow +/// \param parent 親ウィジェット +/// +/// コンストラクタ +/// MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), - m_activeView(NULL), - m_overwriteDialog(NULL), - m_viewMode(ModeBasic) + m_overwriteDialog(this), + m_viewMode(ModeBasic), + m_prevMode(ModeBasic) { - qDebug() << ">>>>>>>>>> MainWindowの構築開始 <<<<<"; ui->setupUi(this); - - m_overwriteDialog = new OverWriteDialog(this); - - initActionConnections(); - connect(qApp, SIGNAL(focusChanged(QWidget*,QWidget*)), this, SLOT(focusChange(QWidget*,QWidget*))); - connect(ui->pane3->textView(), SIGNAL(viewFinished()), this, SLOT(viewFinish())); - connect(ui->pane3->imageView(), SIGNAL(viewFinished()), this, SLOT(viewFinish())); - connect(ui->pane1->textView(), SIGNAL(fileInfo(QString)), this, SLOT(showFileInfo(QString))); - connect(ui->pane2->textView(), SIGNAL(fileInfo(QString)), this, SLOT(showFileInfo(QString))); - connect(ui->pane3->textView(), SIGNAL(fileInfo(QString)), this, SLOT(showFileInfo(QString))); - connect(ui->pane1->imageView(), SIGNAL(fileInfo(QString)), this, SLOT(showFileInfo(QString))); - connect(ui->pane2->imageView(), SIGNAL(fileInfo(QString)), this, SLOT(showFileInfo(QString))); - connect(ui->pane3->imageView(), SIGNAL(fileInfo(QString)), this, SLOT(showFileInfo(QString))); - - // ビューアは初期状態で非表示 - ui->pane3->setVisible(false); + connect(qApp, SIGNAL(focusChanged(QWidget*,QWidget*)), this, SLOT(app_focusChange(QWidget*,QWidget*))); // ステータスバーにウィジェットを設定する - QLabel *label = new QLabel("", this); + QLabel *label = new QLabel(this); label->setAlignment(Qt::AlignRight); label->setObjectName("Right"); ui->statusBar->addPermanentWidget(label, 0); - for (int i = 1; i <= 2; i++) { - // pane1 or pane2 - AnyView *anyView = findChild(QString("pane%1").arg(i)); - Q_CHECK_PTR(anyView); - - FolderPanel *fp = anyView->findChild("folderPanel"); - Q_CHECK_PTR(fp); - - // FolderPanelとFolderViewの名前を変更する - fp->setObjectName(QString("folderPanel%1").arg(i)); - fp->folderView()->setObjectName(QString("folderView%1").arg(i)); + // アプリケーション情報を初期化する + qApp->setApplicationDisplayName(tr("げふぅ Ver%1").arg(VERSION_VALUE)); + qApp->setApplicationName("Gefu"); + qApp->setApplicationVersion(QString("%1").arg(VERSION_VALUE)); + qApp->setOrganizationDomain("sourceforge.jp"); + qApp->setOrganizationName("gefu"); + qApp->setWindowIcon(QIcon("://images/file-manager.png")); + + // 古い設定ファイルを削除する + QSettings::setDefaultFormat(QSettings::IniFormat); + QSettings settings(this); + if (QFileInfo::exists(settings.fileName())) { + QFile(settings.fileName()).remove(); + QDir().rmdir(QFileInfo(settings.fileName()).absolutePath()); + } + + // パネルにモデルを割り当てる + ui->LPanel->setModel(new FolderModel(this)); + ui->RPanel->setModel(new FolderModel(this)); + setActiveModel(ui->LPanel->model()); + + // パネルを初期化する + ui->LPanel->initialize(this); + ui->RPanel->initialize(this); + ui->FPanel->initialize(this); + ui->FPanel->setVisible(false); + + // モデルを初期化する + Preferences prefs(this); + prefs.restoreModel("Left", ui->LPanel->model()); + prefs.restoreModel("Right", ui->RPanel->model()); + + // アクションを初期化する + initActions(); - fp->initialize(this); - fp->updateAppearance(i == 2); - } - - QSettings settings; // ブックマークメニューを初期化する - initBookmark(); - - // メニュー項目の状態を初期化する - ui->view_Hidden->setChecked(settings.value(IniKey_ShowHidden).toBool()); - ui->view_System->setChecked(settings.value(IniKey_ShowSystem).toBool()); - - // 追加のショートカットキーを設定する - QList shortcuts; - shortcuts = ui->action_Open->shortcuts(); - shortcuts.append(QKeySequence("M")); - ui->action_Open->setShortcuts(shortcuts); - - shortcuts = ui->action_Exec->shortcuts(); - shortcuts.append(QKeySequence("Shift+M")); - ui->action_Exec->setShortcuts(shortcuts); + initBookmarkMenu(); - // MacだとShift+の形で認識されてしまうもの - shortcuts = ui->view_FontSizeUp->shortcuts(); - shortcuts.append(QKeySequence("Shift++")); - ui->view_FontSizeUp->setShortcuts(shortcuts); - - shortcuts = ui->view_Filter->shortcuts(); - shortcuts.append(QKeySequence("Shift+*")); - ui->view_Filter->setShortcuts(shortcuts); - - shortcuts = ui->action_OpenTerminal->shortcuts(); - shortcuts.append(QKeySequence("Shift+>")); - ui->action_OpenTerminal->setShortcuts(shortcuts); - - shortcuts = ui->help_About->shortcuts(); - shortcuts.append(QKeySequence("Shift+?")); - ui->help_About->setShortcuts(shortcuts); - - // ウィンドウタイトルを設定する - setWindowTitle(tr("げふぅ v%1").arg(VERSION_VALUE)); - - // ウィンドウアイコンを設定する + // メインウィンドウを初期化する + setWindowTitle(qApp->applicationDisplayName()); setWindowIcon(QIcon("://images/file-manager.png")); - - //>>>>> ウィンドウサイズと位置を設定する - QString strValue; - QPoint point = this->geometry().topLeft(); - QSize size = this->geometry().size(); - //>>>> 前回の位置・サイズ・状態を復元する - if (!settings.value(IniKey_WindowGeometry, "").toString().isEmpty()) { - restoreGeometry(settings.value(IniKey_WindowGeometry).toByteArray()); - restoreState(settings.value(iniKey_WindowState).toByteArray()); - } - //>>>> INIファイルの設定から復元する - //>>> サイズ - strValue = settings.value(IniKey_BootSizeSpec).toString(); - if (strValue == "sizeAbsolute") { - size = settings.value(IniKey_BootSizeAbs).toSize(); - } - else if (strValue == "sizeRelative") { - size = settings.value(IniKey_BootSizeRel).toSize(); - size.setWidth(size.width() * QApplication::desktop()->width() / 100.0); - size.setHeight(size.height() * QApplication::desktop()->height() / 100.0); - } - else if (strValue == "sizeLast") { - size = this->geometry().size(); - } - //>>> 位置 - strValue = settings.value(IniKey_BootPosSpec).toString(); - if (strValue == "posAbsolute") { - point = settings.value(IniKey_BootPosAbs).toPoint(); - } - else if (strValue == "posRelative") { - point = settings.value(IniKey_BootPosRel).toPoint(); - point.setX(point.x() * QApplication::desktop()->width() / 100.0); - point.setY(point.y() * QApplication::desktop()->height() / 100.0); - } - else if (strValue == "posLast") { - point = this->geometry().topLeft(); - } - else { - point.setX((QApplication::desktop()->width() - size.width()) / 2); - point.setY((QApplication::desktop()->height() - size.height()) / 2); - } - this->setGeometry(QRect(point, size)); + prefs.restoreWindow(this); // 最新バージョンをチェックする - if (settings.value(IniKey_CheckUpdates).toBool()) { - checkUpdate(true); + if (prefs.isCheckUpdate()) { + onCheckUpdate(true); } - - ui->pane2->changeView(AnyView::ViewFolder); - ui->pane2->repaint(); - - ui->pane1->changeView(AnyView::ViewFolder); - ui->pane1->repaint(); - - qDebug() << ">>>>>>>>>> MainWindowの構築終了 <<<<<"; } +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::~MainWindow +/// +/// デストラクタ +/// MainWindow::~MainWindow() { delete ui; } -void MainWindow::focusChange(QWidget *old, QWidget *now) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::app_focusChange +/// \param old フォーカスを失うウィジェット +/// \param now フォーカスを得るウィジェット +/// +/// フォーカス変更時の処理 +/// +void MainWindow::app_focusChange(QWidget *old, QWidget *now) { - qDebug() << ">>>>> フォーカス変更"; - if (old) qDebug() << "old is" << old->objectName(); - if (now) qDebug() << "now is" << now->objectName(); + qDebug() << "MainWindow::app_focusChange()"; + if (old) qDebug() << " old is" << old->objectName(); + if (now) qDebug() << " now is" << now->objectName(); - // 検索ボックスがフォーカスを失ったら、非表示にする - if (old == ui->pane1->folderPanel()->searchBox() || - old == ui->pane2->folderPanel()->searchBox()) + // フォルダビューがフォーカスを得た場合 + if (now && (now->objectName() == "folderView" || + now->objectName() == "thumbnailView")) { - ui->action_Search->setChecked(false); + FolderModel *m = static_cast(focusItemView()->model()); + setActiveModel(m); + ui->statusBar->showMessage(m->filePath(focusItemView()->currentIndex())); } - // フォルダビューにフォーカスが移ったら、ステータスバーの表示を更新する - if (now == ui->pane1->folderPanel()->folderView() || - now == ui->pane2->folderPanel()->folderView()) - { - m_activeView = qobject_cast(now); - ui->statusBar->showMessage(m_activeView->currentItem().absoluteFilePath()); - m_activeView->parentPanel()->updateAppearance(false); - otherSideFolderView(m_activeView)->parentPanel()->updateAppearance(true); + // 検索ボックスがフォーカスを失った場合 + if (old && old->objectName() == "searchBox") { + // 検索モード終了 + ui->toggle_Search->setChecked(false); } + // アクションの有効/無効を設定する if (now) { updateActions(); } } -void MainWindow::executeCommand() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::model_PreReset +/// +/// FolderModelリセット前の処理 +/// +void MainWindow::model_PreReset() { - qDebug() << "MainWindow::executeCommand"; + qDebug() << "MainWindow::model_PreReset()"; + + ui->statusBar->showMessage(tr("ファイルリストを取得しています...")); +} - QFileInfoList list = m_activeView->selectedItems(); +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::model_PostReset +/// +/// FolderModelリセット後の処理 +/// +void MainWindow::model_PostReset() +{ + qDebug() << "MainWindow::model_PostReset()"; + + FolderModel *m = static_cast(sender()); + if (!m->error().isEmpty()) { + ui->statusBar->showMessage(m->error()); + } + else { + ui->statusBar->showMessage(tr("レディ")); + } +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onRunCommand +/// +/// 入力されたコマンドを実行します。 +/// +void MainWindow::onRunCommand() +{ + qDebug() << "MainWindow::onRunCommand"; + + QFileInfoList list = selectedItems(); QString command = QString::null; foreach (const QFileInfo &info, list) { #ifdef Q_OS_MAC @@ -241,13 +212,18 @@ void MainWindow::executeCommand() int ret = dlg.exec(); command = dlg.textValue(); if (ret == QDialog::Accepted && !command.isEmpty()) { - startProcess(command, m_activeView->dir(), tr("コマンドの実行に失敗しました。")); + startProcess(command, tr("コマンドの実行に失敗しました。")); } } -void MainWindow::expandLeft() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onExpandLeft +/// +/// 左パネルを拡大します。 +/// +void MainWindow::onExpandLeft() { - qDebug() << "MainWindow::expandLeft();"; + qDebug() << "MainWindow::onExpandLeft()"; QList sizes = ui->splitter->sizes(); QList newSizes; @@ -256,12 +232,16 @@ void MainWindow::expandLeft() newSizes << sizes[1] - 30; ui->splitter->setSizes(newSizes); - } -void MainWindow::expandRight() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onExpandRight +/// +/// 右パネルを拡大します。 +/// +void MainWindow::onExpandRight() { - qDebug() << "MainWindow::expandLeft();"; + qDebug() << "MainWindow::onExpandLeft()"; QList sizes = ui->splitter->sizes(); QList newSizes; @@ -270,240 +250,291 @@ void MainWindow::expandRight() newSizes << sizes[1] + 30; ui->splitter->setSizes(newSizes); - } -void MainWindow::historyBack() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onToggleMark +/// +/// マーク状態を反転します。 +/// +void MainWindow::onToggleMark() { - qDebug() << "MainWindow::historyBack();"; + qDebug() << "MainWindow::onToggleMark()"; - if (m_activeView->historyBack()) { - updateActions(); + QModelIndex index = focusItemView()->currentIndex(); + if (activeModel()->isMarked(index)) { + activeModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole); + } + else { + activeModel()->setData(index, Qt::Checked, Qt::CheckStateRole); } -} - -void MainWindow::historyForward() -{ - qDebug() << "MainWindow::historyForward();"; - if (m_activeView->historyForward()) { - updateActions(); + if (index.row() < activeModel()->rowCount() - 1) { + index = activeModel()->index(index.row() + 1, 0); + focusItemView()->setCurrentIndex(index); } } -void MainWindow::markAll() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::view_statusChanged +/// \param text ステータス文字列 +/// +/// ビューから受け取った文字列をステータスバーに表示します。 +/// +void MainWindow::view_statusChanged(const QString &text) { - qDebug() << "MainWindow::markAll();"; - - m_activeView->setCheckStateAll(Qt::Checked); + ui->statusBar->findChild("Right")->setText(text); } -void MainWindow::markAllFiles() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::view_currentChanged +/// \param current 新しいカレントインデックス +/// \param previous (使用しません) +/// +/// カレントインデックスが変更された場合の処理を行います。 +/// +void MainWindow::view_currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { - qDebug() << "MainWindow::markAllFiles();"; - - m_activeView->setCheckStateAllFiles(); -} + qDebug() << "MainWindow::view_currentChanged()" << current; + Q_UNUSED(previous); -void MainWindow::markAllOff() -{ - qDebug() << "MainWindow::markAllOff();"; + if (focusItemView() != sender()->parent()) { + return; + } - m_activeView->setCheckStateAll(Qt::Unchecked); -} + ui->statusBar->showMessage(activeModel()->filePath(current)); -void MainWindow::markInvert() -{ - qDebug() << "MainWindow::markInvert();"; + if (m_viewMode == ModePreview) { + inactivePanel()->setViewItem(current); + } - m_activeView->invertCheckState(); + updateActions(); } -void MainWindow::markToggle() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::view_finished +/// +/// ビューアの終了 +/// +void MainWindow::view_finished() { - qDebug() << "MainWindow::markToggle();"; + qDebug() << "MainWindow::view_finished()"; + + ui->statusBar->findChild("Right")->setText(""); - m_activeView->toggleCheckState(m_activeView->currentIndex()); + setViewMode(m_prevMode); } -void MainWindow::moveItems() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onMove +/// +/// 選択アイテムを隣のパネルに移動します。 +/// +void MainWindow::onMove() { - qDebug() << "MainWindow::moveItems"; + qDebug() << "MainWindow::onMove"; - QFileInfoList list = m_activeView->selectedItems(); + QFileInfoList list = selectedItems(); if (list.isEmpty()) { return; } - int row = m_activeView->currentIndex().row(); + int row = focusItemView()->currentIndex().row(); - QString tgtPath = otherSideFolderView(m_activeView)->dir(); + QString tgtPath = inactiveModel()->rootPath(); moveItems(list, tgtPath); - m_activeView->refresh(); - if (row >= m_activeView->model()->rowCount()) { - row = m_activeView->model()->rowCount() - 1; + if (row >= activeModel()->rowCount()) { + row = activeModel()->rowCount() - 1; } - m_activeView->setCurrentIndex(m_activeView->model()->index(row, 1)); + focusItemView()->setCurrentIndex(activeModel()->index(row, 1)); } - -void MainWindow::leftKeyPress() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onKeyLeft +/// +/// ←キー押下時の処理を行います。 +/// +void MainWindow::onKeyLeft() { - qDebug() << "MainWindow::leftKeyPress();"; + qDebug() << "MainWindow::onKeyLeft()"; - if (ui->pane3->textView()->hasFocus()) { - QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_PageUp, Qt::NoModifier); - QApplication::sendEvent(ui->pane3->textView(), &event); - } - else if (ui->pane1->folderPanel()->folderView()->hasFocus()) { - setPathToParent(); + QWidget *w = qApp->focusWidget(); + if (w->objectName() == "folderView") + { + QWidget *panel = w->parentWidget()->parentWidget(); + if (panel == ui->LPanel) { + activeModel()->onCdUp(); + } + else if (ui->LPanel->folderPanel()->isVisible()){ + ui->LPanel->folderPanel()->itemView()->setFocus(); + } } - else if (ui->pane2->folderPanel()->folderView()->hasFocus()) { - ui->pane1->folderPanel()->folderView()->setFocus(); + else { + QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_PageUp, Qt::NoModifier); + qApp->sendEvent(w, &event); } } -void MainWindow::rightKeyPress() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onKeyRight +/// +/// →キー押下時の処理を行います。 +/// +void MainWindow::onKeyRight() { - qDebug() << "MainWindow::rightKeyPress();"; + qDebug() << "MainWindow::onKeyRight()"; - if (ui->pane3->textView()->hasFocus()) { - QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_PageDown, Qt::NoModifier); - QApplication::sendEvent(ui->pane3->textView(), &event); - } - else if (ui->pane1->folderPanel()->folderView()->hasFocus()) { - ui->pane2->folderPanel()->folderView()->setFocus(); + QWidget *w = qApp->focusWidget(); + if (w->objectName() == "folderView") + { + QWidget *panel = w->parentWidget()->parentWidget(); + if (panel == ui->RPanel) { + activeModel()->onCdUp(); + } + else if (ui->RPanel->folderPanel()->isVisible()){ + ui->RPanel->folderPanel()->itemView()->setFocus(); + } } - else if (ui->pane2->folderPanel()->folderView()->hasFocus()) { - setPathToParent(); + else { + QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_PageDown, Qt::NoModifier); + qApp->sendEvent(w, &event); } } -void MainWindow::showFileInfo(const QString &str) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onChooseFolder +/// +/// 選択したフォルダに移動します。 +/// +void MainWindow::onChooseFolder() { - qDebug() << "MainWindow::showFileInfo();" << str; - QLabel *label = ui->statusBar->findChild("Right"); - Q_CHECK_PTR(label); - - label->setText(str); -} - -void MainWindow::chooseFolder() -{ - qDebug() << "MainWindow::chooseFolder();"; + qDebug() << "MainWindow::onChooseFolder()"; QString path = QFileDialog::getExistingDirectory( - this, tr("フォルダを選択"), m_activeView->dir()); + this, tr("フォルダを選択"), activeModel()->rootPath()); if (!path.isEmpty()) { - m_activeView->setPath(path, true); - updateActions(); + activeModel()->setRootPath(path); +// updateActions(); } } -void MainWindow::copyFilenameToClipboard() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onCopyFileName +/// +/// ファイル名をクリップボードにコピーします。 +/// +void MainWindow::onCopyFileName() { - qDebug() << "MainWindow::copyFilenameToClipboard();"; + qDebug() << "MainWindow::onCopyFileName()"; - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(m_activeView->currentItem().fileName()); + QClipboard *clipboard = qApp->clipboard(); + clipboard->setText(activeModel()->fileName(focusItemView()->currentIndex())); } -void MainWindow::copyFullpathTpClipboard() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onCopyFilePath +/// +/// フルパスをクリップボードにコピーします。 +/// +void MainWindow::onCopyFilePath() { - qDebug() << "MainWindow::copyFullpathTpClipboard();"; + qDebug() << "MainWindow::onCopyFilePath()"; - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(m_activeView->currentItem().absoluteFilePath()); + QClipboard *clipboard = qApp->clipboard(); + clipboard->setText(activeModel()->filePath(focusItemView()->currentIndex())); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::askOverWrite +/// \param copyMethod 上書き方法 +/// \param alias 別名 +/// \param srcPath コピー元パス +/// \param tgtPath コピー先パス +/// +/// 上書きの処理方法を選択するダイアログを表示します。 +/// void MainWindow::askOverWrite(QString *copyMethod, QString *alias, const QString &srcPath, const QString &tgtPath) { - qDebug() << "MainWindow::askOverWrite();"; + qDebug() << "MainWindow::askOverWrite()"; CopyMoveWorker *worker = static_cast(sender()); - if (!m_overwriteDialog->isKeepSetting() || - m_overwriteDialog->copyMethod() == "rbRename") + if (!m_overwriteDialog.isKeepSetting() || + m_overwriteDialog.copyMethod() == "rbRename") { - m_overwriteDialog->setFileInfo(srcPath, tgtPath); - if (m_overwriteDialog->exec() == QDialog::Rejected) { + m_overwriteDialog.setFileInfo(srcPath, tgtPath); + if (m_overwriteDialog.exec() == QDialog::Rejected) { worker->requestStop(); } } - *copyMethod = m_overwriteDialog->copyMethod(); - *alias = m_overwriteDialog->alias(); + *copyMethod = m_overwriteDialog.copyMethod(); + *alias = m_overwriteDialog.alias(); worker->endAsking(); } -void MainWindow::currentChange(const QFileInfo &info) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onAddBookmark +/// +/// ブックマークを追加します。 +/// +void MainWindow::onAddBookmark() { - qDebug() << ">>>>> カーソル変更 <<<<<"; - - FolderView *view = static_cast(sender()); - Q_CHECK_PTR(view); + qDebug() << "MainWindow::onAddBookmark()"; + qDebug() << sender()->objectName(); - if (!view->hasFocus()) { - return; + FolderModel *m; + if (sender()->objectName() == "bookmarkBtn") { + FolderPanel *p = static_cast(sender()->parent()); + m = p->model(); } - - // ステータスバーにカーソルのフルパスを表示する - ui->statusBar->showMessage(info.absoluteFilePath()); - - // ハーフモードで変更された場合 - if (m_viewMode & ModeHalfView) { - AnyView *otherSide = static_cast( - otherSideFolderView(view)->parent()->parent()); - Q_CHECK_PTR(otherSide); - - if (!otherSide->setViewItem(view->currentItem())) { - showFileInfo(""); - } + else { + m = activeModel(); } - updateActions(); + QFileInfo fi(m->rootPath()); + Preferences(this).addBookmark(fi.fileName(), fi.absoluteFilePath()); + initBookmarkMenu(); + + activePanel()->folderPanel()->itemView()->setFocus(); + ui->statusBar->showMessage(tr("%1をブックマークに追加しました").arg(fi.absoluteFilePath())); } -void MainWindow::dropAccept(const QFileInfoList &list, QDropEvent *event) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::view_copyAvailable +/// \param yes コピー可能ならtrue +/// +/// 選択範囲の有無をメニューに反映します。 +/// +void MainWindow::view_copyAvailable(bool yes) { - qDebug() << "MainWindow::dropAccept();"; - - FolderView *view = static_cast(sender()); - Q_CHECK_PTR(view); - - QMenu menu(this); - QAction *actCopy = menu.addAction(tr("コピー")); - QAction *actMove = menu.addAction(tr("移動")); - menu.addSeparator(); - menu.addAction(tr("キャンセル")); - - QAction *selected = menu.exec(view->mapToGlobal(event->pos())); - if (selected == actMove) { - moveItems(list, view->dir()); - } - else if (selected == actCopy) { - copyItems(list, view->dir()); - } + ui->text_Copy->setEnabled(yes); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::copyItems +/// \param list コピー元リスト +/// \param tgtDir コピー先フォルダ +/// +/// アイテムをコピーします。 +/// void MainWindow::copyItems(const QFileInfoList &list, const QString &tgtDir) { - qDebug() << "MainWindow::copyItems();" << tgtDir; + qDebug() << "MainWindow::copyItems()" << tgtDir; - QSettings settings; - if (settings.value(IniKey_ConfirmCopy).toBool()) { - if (QMessageBox::question(this, tr("確認"), tr("コピーを実行しますか?")) + Preferences prefs(this); + if (prefs.isConfirmCopy() && + QMessageBox::question(this, tr("確認"), tr("コピーを実行しますか?")) != QMessageBox::Yes) - { - return; - } + { + return; } // 上書き確認ダイアログを初期化する - m_overwriteDialog->reset(); + m_overwriteDialog.reset(); // ワーカースレッドを作成する CopyMoveWorker *worker = new CopyMoveWorker(); @@ -517,28 +548,34 @@ void MainWindow::copyItems(const QFileInfoList &list, const QString &tgtDir) OperationDialog opDlg(this); opDlg.setWindowTitle(tr("コピー")); opDlg.setWorker(worker); - opDlg.setAutoClose(settings.value(IniKey_AutoCloseCopy).toBool()); + opDlg.setAutoClose(prefs.isAutoCloseCopy()); opDlg.exec(); - settings.setValue(IniKey_AutoCloseCopy, opDlg.autoClose()); + prefs.setAutoCloseCopy(opDlg.autoClose()); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::moveItems +/// \param list 移動元リスト +/// \param tgtDir 移動先フォルダ +/// +/// アイテムを移動します。 +/// void MainWindow::moveItems(const QFileInfoList &list, const QString &tgtDir) { - qDebug() << "MainWindow::moveItems();" << tgtDir; + qDebug() << "MainWindow::moveItems()" << tgtDir; - QSettings settings; - if (settings.value(IniKey_ConfirmMove).toBool()) { - if (QMessageBox::question(this, tr("確認"), tr("移動を実行しますか?")) + Preferences prefs(this); + if (prefs.isConfirmMove() && + QMessageBox::question(this, tr("確認"), tr("移動を実行しますか?")) != QMessageBox::Yes) - { - return; - } + { + return; } // 上書き確認ダイアログを初期化する - m_overwriteDialog->reset(); + m_overwriteDialog.reset(); // ワーカースレッドを作成する CopyMoveWorker *worker = new CopyMoveWorker(); @@ -552,29 +589,245 @@ void MainWindow::moveItems(const QFileInfoList &list, const QString &tgtDir) OperationDialog opDlg(this); opDlg.setWindowTitle(tr("移動")); opDlg.setWorker(worker); - opDlg.setAutoClose(settings.value(IniKey_AutoCloseMove).toBool()); + opDlg.setAutoClose(prefs.isAutoCloseMove()); opDlg.exec(); - settings.setValue(IniKey_AutoCloseMove, opDlg.autoClose()); + prefs.setAutoCloseMove(opDlg.autoClose()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onContextMenuEvent +/// \param obj イベントが発生したオブジェクト +/// \param e コンテキストメニューイベント +/// \return 処理した場合はtrue, 処理しなかった場合はfalseを返します。 +/// +bool MainWindow::onContextMenuEvent(QObject *obj, QContextMenuEvent *e) +{ + QMenu menu(this); + if (obj->objectName() == "textView") { + menu.addAction(ui->text_ConvertFromEUC); + menu.addAction(ui->text_ConvertFromJIS); + menu.addAction(ui->text_ConvertFromSJIS); + menu.addAction(ui->text_ConvertFromUTF8); + menu.addAction(ui->text_ConvertFromUTF16); + menu.addAction(ui->text_ConvertFromUTF16BE); + menu.addAction(ui->text_ConvertFromUTF16LE); + menu.addSeparator(); + menu.addAction(ui->text_Copy); + if (m_viewMode == ModeView) { + menu.addSeparator(); + menu.addAction(ui->view_Back); + } + } + else if (obj->objectName() == "imageView") { + menu.addAction(ui->image_FitToWindow); + menu.addAction(ui->action_ScaleDown); + menu.addAction(ui->action_ScaleUp); + menu.addAction(ui->image_ScaleNormal); + menu.addSeparator(); + menu.addAction(ui->image_Rotate90); + menu.addAction(ui->image_Rotate180); + + if (m_viewMode == ModeView) { + menu.addSeparator(); + menu.addAction(ui->view_Back); + } + } + else if (obj->objectName() == "folderView" || obj->objectName() == "thumbnailView") { + QModelIndex index = focusItemView()->indexAt(e->pos()); + if (index.isValid()) { + menu.addAction(ui->action_Open); + menu.addAction(ui->action_OpenWith); + menu.addAction(ui->action_OpenEditor); + menu.addAction(ui->action_OpenTerminal); + menu.addAction(ui->action_OpenArchiver); + menu.addSeparator(); + menu.addAction(ui->action_Copy); + menu.addAction(ui->action_Move); + menu.addSeparator(); + menu.addAction(ui->action_Delete); + menu.addSeparator(); + menu.addAction(ui->action_CopyFileName); + menu.addAction(ui->action_CopyFilePath); + menu.addSeparator(); + menu.addAction(ui->action_Rename); + } + else { + menu.addAction(ui->action_historyBack); + menu.addAction(ui->action_HistoryForward); + menu.addSeparator(); + menu.addAction(ui->action_CdUp); + menu.addAction(ui->action_CdHome); + menu.addAction(ui->action_CdRoot); + menu.addAction(ui->action_Cd); + menu.addSeparator(); + menu.addAction(ui->action_CreateFile); + menu.addAction(ui->action_CreateFolder); + } + } + else { + qDebug() << "No context menu" << obj->objectName(); + return false; + } + + QAction *selected = menu.exec(e->globalPos()); + if (selected == ui->action_ScaleDown || + selected == ui->action_ScaleUp) + { + ui->image_FitToWindow->blockSignals(true); + ui->image_FitToWindow->setChecked(false); + ui->image_FitToWindow->blockSignals(false); + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onDropEvent +/// \param obj イベントが発生したオブジェクト +/// \param e ドロップイベントオブジェクト +/// \return 処理した場合はtrue, 処理しなかった場合はfalseを返します。 +/// +bool MainWindow::onDropEvent(QObject *obj, QDropEvent *e) +{ + qDebug() << "MainWindow::onDropEvent()"; + + if (obj->parent()->objectName() == "folderView" || + obj->parent()->objectName() == "thumbnailView") + { + QAbstractItemView *v = static_cast(obj->parent()); + if (v->property("dragging").toBool()) { + // 自分自身へのドロップなら何もしない + return true; + } + + QFileInfoList 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(this); + QAction *actCopy = menu.addAction(tr("コピー")); + QAction *actMove = menu.addAction(tr("移動")); + menu.addSeparator(); + menu.addAction(tr("キャンセル")); + + QAction *selected = menu.exec(v->mapToGlobal(e->pos())); + FolderModel *m = static_cast(v->model()); + if (selected == actMove) { + moveItems(list, m->rootPath()); + } + else if (selected == actCopy) { + copyItems(list, m->rootPath()); + } + return true; + } + else { + qDebug() << obj->parent()->objectName(); + } + + return true; } -void MainWindow::copyItems() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onKeyPressEvent +/// \param obj イベントが発生したオブジェクト +/// \param e キーイベントオブジェクト +/// \return 処理した場合はtrue, 処理しなかった場合はfalseを返します。 +/// +bool MainWindow::onKeyPressEvent(QObject *obj, QKeyEvent *e) { - qDebug() << "MainWindow::copyItems"; + qDebug() << "MainWindow::onKeyPressEvent()"; + + QString modifier = QString::null; + if (e->modifiers() & Qt::ShiftModifier) { modifier += "Shift+"; } + if (e->modifiers() & Qt::ControlModifier) { modifier += "Ctrl+"; } + if (e->modifiers() & Qt::AltModifier) { modifier += "Alt+"; } + if (e->modifiers() & Qt::MetaModifier) { modifier += "Meta+"; } + + QString key = modifier + QKeySequence(e->key()).toString(); - QFileInfoList list = m_activeView->selectedItems(); + foreach (QAction *action, findChildren()) { + if (action->isEnabled()) { + foreach (const QKeySequence &ks, action->shortcuts()) { + if (ks.toString() == key) { + qDebug() << "emit" << action->objectName(); + if (action->isCheckable()) { + action->toggle(); + } + else { + action->trigger(); + } + return true; + } + } + } + } + + if (obj->objectName() == "folderView" || obj->objectName() == "thumbnailView") + { + // カーソル移動系のみ有効にする + switch (e->key()) { + case Qt::Key_Down: + case Qt::Key_Up: + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Home: + case Qt::Key_End: + case Qt::Key_PageDown: + case Qt::Key_PageUp: + case Qt::Key_Tab: + return false; + } + return true; + } + + + + + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onCopy +/// +/// 選択アイテムを隣のパネルにコピーします。 +/// +void MainWindow::onCopy() +{ + qDebug() << "MainWindow::onCopy"; + + QFileInfoList list = selectedItems(); if (list.isEmpty()) { return; } - QString tgtPath = otherSideFolderView(m_activeView)->dir(); + QString tgtPath = inactiveModel()->rootPath(); copyItems(list, tgtPath); } -void MainWindow::createFile() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onCreateFile +/// +/// ファイルを作成します。 +/// +void MainWindow::onCreateFile() { - qDebug() << "MainWindow::createFile"; + qDebug() << "MainWindow::onCreateFile"; bool bOk; QString name = QInputDialog::getText( @@ -584,29 +837,28 @@ void MainWindow::createFile() return; } - QDir dir(m_activeView->dir()); - QFile file(dir.absoluteFilePath(name)); - if (!file.open(QIODevice::WriteOnly)) { + QModelIndex index = activeModel()->touch(name); + if (!index.isValid()) { QMessageBox::critical( this, tr("エラー"), tr("ファイルの作成に失敗しました。")); + return; } - else { - file.close(); - QSettings settings; - if (settings.value(IniKey_OpenAfterCreateFile).toBool()) { - openEditor(dir.absoluteFilePath(name)); - } - - m_activeView->refresh(); - m_activeView->searchItem(name); + focusItemView()->setCurrentIndex(index); + if (Preferences(this).isOpenAfterCreation()) { + onOpenEditor(index); } } -void MainWindow::createFolder() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onCreateFolder +/// +/// フォルダを作成します。 +/// +void MainWindow::onCreateFolder() { - qDebug() << "MainWindow::createFolder"; + qDebug() << "MainWindow::onCreateFolder"; bool bOk; QString name = QInputDialog::getText( @@ -616,34 +868,36 @@ void MainWindow::createFolder() return; } - QDir dir(m_activeView->dir()); - if (!dir.mkpath(name)) { + QModelIndex index = activeModel()->mkdir(name); + if (!index.isValid()) { QMessageBox::critical( this, tr("エラー"), tr("フォルダの作成に失敗しました。")); + return; } - else { - QSettings settings; - if (settings.value(IniKey_MoveAfterCreateFolder).toBool()) { - m_activeView->setPath(dir.absoluteFilePath(name), true); - } - m_activeView->refresh(); - m_activeView->searchItem(name); + focusItemView()->setCurrentIndex(index); + if (Preferences(this).isMoveAfterCreation()) { + onOpen(index); } } -void MainWindow::deleteItems() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onDelete +/// +/// 選択アイテムを削除します。 +/// +void MainWindow::onDelete() { - qDebug() << "MainWindow::deleteItems"; + qDebug() << "MainWindow::onDelete"; - QFileInfoList list = m_activeView->selectedItems(); + QFileInfoList list = selectedItems(); if (list.isEmpty()) { return; } - QSettings settings; - if (settings.value(IniKey_ConfirmDelete).toBool()) { + Preferences prefs(this); + if (prefs.isConfirmDelete()) { QString msg; if (list.size() == 1) { msg = list[0].fileName(); @@ -665,54 +919,63 @@ void MainWindow::deleteItems() OperationDialog opDlg(this); opDlg.setWindowTitle(tr("削除")); opDlg.setWorker(worker); - opDlg.setAutoClose(settings.value(IniKey_AutoCloseDelete).toBool()); + opDlg.setAutoClose(prefs.isAutoCloseDelete()); - int row = m_activeView->currentIndex().row(); + int row = focusItemView()->currentIndex().row(); opDlg.exec(); - m_activeView->refresh(); - if (row >= m_activeView->model()->rowCount()) { - row = m_activeView->model()->rowCount() - 1; + if (row >= activeModel()->rowCount()) { + row = activeModel()->rowCount() - 1; } - m_activeView->setCurrentIndex(m_activeView->model()->index(row, 1)); + focusItemView()->setCurrentIndex(activeModel()->index(row, 1)); - settings.setValue(IniKey_AutoCloseDelete, opDlg.autoClose()); + prefs.setAutoCloseDelete(opDlg.autoClose()); } -void MainWindow::open(const QModelIndex &index) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onOpen +/// \param index (使用しません) +/// +/// アイテムを開きます。 +/// +void MainWindow::onOpen(const QModelIndex &index) { Q_UNUSED(index); - qDebug() << "MainWindow::open" << index; + qDebug() << "MainWindow::onOpen()" << index; - QFileInfo info = m_activeView->currentItem(); - if (info.isDir()) { - m_activeView->setPath(info.absoluteFilePath(), true); - updateActions(); + QModelIndex current = focusItemView()->currentIndex(); + if (activeModel()->isDir(current)) { + activeModel()->setRootPath(activeModel()->filePath(current)); return; } - if (ui->pane3->setViewItem(info)) { - ui->pane3->setVisible(true); - ui->splitter->setVisible(false); - - setViewMode(ModeFullView); - } - else { - ui->pane3->setVisible(false); - if (index.isValid()) { - QString path = QDir::toNativeSeparators(info.absoluteFilePath()); + // 外部アプリを優先する場合 + QString ext = activeModel()->fileInfo(current).suffix().toLower(); + QStringList list = Preferences(this).getPreferExtensions().split(",", QString::SkipEmptyParts); + foreach (const QString& s, list) { + if (ext == s.trimmed().toLower()) { + QString path = QDir::toNativeSeparators(activeModel()->filePath(current)); QDesktopServices::openUrl(QUrl("file:///" + path)); + return; } } + + // 内蔵ビューアで表示する + setViewMode(ModeView); } -void MainWindow::openEditor(const QString &path) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onOpenEditor +/// \param path +/// +/// 選択アイテムを外部エディタで開きます。 +/// +void MainWindow::onOpenEditor(const QModelIndex &index) { - qDebug() << "MainWindow::openEditor"; + qDebug() << "MainWindow::onOpenEditor"; - QSettings settings; - QString exe = settings.value(IniKey_PathEditor).toString(); + QString exe = Preferences(this).getEditorPath(); if (exe.isEmpty()) { QMessageBox::critical( this, tr("エラー"), @@ -721,11 +984,11 @@ void MainWindow::openEditor(const QString &path) } QFileInfoList list; - if (path.isEmpty()) { - list = m_activeView->selectedItems(); + if (index.isValid()) { + list << activeModel()->fileInfo(index); } else { - list << path; + list = selectedItems(); } QString files; @@ -737,17 +1000,21 @@ void MainWindow::openEditor(const QString &path) #else QString command = exe + files; #endif - if (!startProcess(command, m_activeView->dir(), tr("外部エディタの起動に失敗しました。"))) { + if (!startProcess(command, tr("外部エディタの起動に失敗しました。"))) { qDebug() << command; } } -void MainWindow::openTerminal() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onOpenTerminal +/// +/// 選択アイテムをターミナルで開きます。 +/// +void MainWindow::onOpenTerminal() { - qDebug() << "MainWindow::openTerminal"; + qDebug() << "MainWindow::onOpenTerminal"; - QSettings settings; - QString exe = settings.value(IniKey_PathTerminal).toString(); + QString exe = Preferences(this).getTerminalPath(); if (exe.isEmpty()) { QMessageBox::critical( this, tr("エラー"), @@ -756,7 +1023,7 @@ void MainWindow::openTerminal() } QSet dirs; - foreach (const QFileInfo &info, m_activeView->selectedItems()) { + foreach (const QFileInfo &info, selectedItems()) { if (info.isDir()) { dirs.insert(info.absoluteFilePath()); } @@ -771,19 +1038,23 @@ void MainWindow::openTerminal() #else QString command = exe + " " + QQ(dir); #endif - if (!startProcess(command, m_activeView->dir(), tr("ターミナルの起動に失敗しました。"))) { + if (!startProcess(command, tr("ターミナルの起動に失敗しました。"))) { qDebug() << command; break; } } } -void MainWindow::openArchiver() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onOpenArchiver +/// +/// 選択アイテムをアーカイバで開きます。 +/// +void MainWindow::onOpenArchiver() { - qDebug() << "MainWindow::openArchiver"; + qDebug() << "MainWindow::onOpenArchiver"; - QSettings settings; - QString exe = settings.value(IniKey_PathArchiver).toString(); + QString exe = Preferences(this).getArchiverPath(); if (exe.isEmpty()) { QMessageBox::critical( this, tr("エラー"), @@ -792,7 +1063,7 @@ void MainWindow::openArchiver() } QString files; - foreach (const QFileInfo &info, m_activeView->selectedItems()) { + foreach (const QFileInfo &info, selectedItems()) { files += " " + QQ(info.absoluteFilePath()); } #ifdef Q_OS_MAC @@ -800,60 +1071,61 @@ void MainWindow::openArchiver() #else QString command = exe + files; #endif - if (!startProcess(command, m_activeView->dir(), tr("アーカイバの起動に失敗しました。"))) { + if (!startProcess(command, tr("アーカイバの起動に失敗しました。"))) { qDebug() << command; } } -void MainWindow::openBookmark() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onOpenBookmark +/// +/// ブックマークのメニュー項目をクリックしたときの処理を行います。 +/// +void MainWindow::onOpenBookmark() { - qDebug() << "MainWindow::openBookmark();"; + qDebug() << "MainWindow::onOpenBookmark()"; QAction *action = qobject_cast(sender()); Q_CHECK_PTR(action); - QSettings settings; int i = action->data().toInt(); - m_activeView->setPath(settings.value(IniKey_BookmarkEntryPath(i)).toString(), true); + activeModel()->setRootPath(Preferences(this).getBookmarkPath(i)); } -void MainWindow::refresh() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onRename +/// +/// 選択アイテムの名前を変更します。 +/// +void MainWindow::onRename() { - qDebug() << "MainWindow::refresh();"; + qDebug() << "MainWindow::onRename"; - m_activeView->refresh(); -} - -void MainWindow::renameItems() -{ - qDebug() << "MainWindow::renameItems"; - - QFileInfoList list = m_activeView->selectedItems(); + QFileInfoList list = selectedItems(); if (list.isEmpty()) { return; } - IRenameDialog *dlg; + AbstractRenameDialog *dlg; if (list.size() == 1) { dlg = new RenameSingleDialog(this); } else { dlg = new RenameMultiDialog(this); } - dlg->setWorkingDirectory(m_activeView->dir()); + dlg->setWorkingDirectory(activeModel()->rootPath()); dlg->setNames(list); int dlgResult = dlg->exec(); if (dlgResult != QDialog::Accepted || dlg->renameMap().isEmpty()) { return; } - QSettings settings; - if (settings.value(IniKey_ConfirmRename).toBool()) { - int ret = QMessageBox::question(this, tr("確認"), - tr("名前の変更を実行しますか?")); - if (ret != QMessageBox::Yes) { - return; - } + Preferences prefs(this); + if (prefs.isConfirmRename() && + QMessageBox::question(this, tr("確認"), tr("名前の変更を実行しますか?")) + != QMessageBox::Yes) + { + return; } RenameWorker *worker = new RenameWorker(); @@ -862,58 +1134,75 @@ void MainWindow::renameItems() OperationDialog opDlg(this); opDlg.setWindowTitle(tr("名前を変更")); opDlg.setWorker(worker); - opDlg.setAutoClose(settings.value(IniKey_AutoCloseRename).toBool()); + opDlg.setAutoClose(prefs.isAutoCloseRename()); opDlg.exec(); - m_activeView->refresh(); - QFileInfo info(dlg->renameMap().first()); - m_activeView->searchItem(info.fileName()); + focusItemView()->setCurrentIndex( + activeModel()->search(dlg->renameMap().first())); - settings.setValue(IniKey_AutoCloseRename, opDlg.autoClose()); + prefs.setAutoCloseRename(opDlg.autoClose()); } -void MainWindow::shellExecute() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onOpenWith +/// +/// 関連付けられたアプリで開きます。 +/// +void MainWindow::onOpenWith() { - qDebug() << "MainWindow::shellExecute"; + qDebug() << "MainWindow::onOpenWith"; - foreach (const QFileInfo &info, m_activeView->selectedItems()) { + foreach (const QFileInfo &info, selectedItems()) { QString path = QDir::toNativeSeparators(info.absoluteFilePath()); QDesktopServices::openUrl(QUrl("file:///" + path)); } } +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::showBookmarkDialog +/// +/// ブックマーク一覧ダイアログを表示します。 +/// void MainWindow::showBookmarkDialog() { - qDebug() << "MainWindow::showBookmarkDialog();"; + qDebug() << "MainWindow::showBookmarkDialog()"; BookmarkDialog dlg(this); dlg.setEditMode(false); if (dlg.exec() == QDialog::Accepted) { int n = dlg.selectedIndex(); - - QSettings settings; - m_activeView->setPath(settings.value(IniKey_BookmarkEntryPath(n)).toString(), true); + activeModel()->setRootPath(Preferences(this).getBookmarkPath(n + 1)); } } -void MainWindow::editBookmark() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onEditBookmark +/// +/// ブックマークの編集ダイアログを表示します。 +/// +void MainWindow::onEditBookmark() { - qDebug() << "MainWindow::showBookmarkDialog();"; + qDebug() << "MainWindow::onEditBookmark()"; BookmarkDialog dlg(this); dlg.setEditMode(true); if (dlg.exec() == QDialog::Accepted) { - initBookmark(); + initBookmarkMenu(); } } +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::showFilterDialog +/// +/// フィルタ設定ダイアログを表示します。 +/// void MainWindow::showFilterDialog() { - qDebug() << "MainWindow::showFilterDialog();"; + qDebug() << "MainWindow::showFilterDialog()"; - QString filters = m_activeView->nameFilters().join(" "); + QString filters = activeModel()->nameFilters().join(" "); QInputDialog dlg(this); dlg.setInputMode(QInputDialog::TextInput); @@ -923,62 +1212,52 @@ void MainWindow::showFilterDialog() dlg.resize(width() * 0.8, dlg.height()); if (dlg.exec() == QDialog::Accepted) { - static_cast(m_activeView->parent())->setNameFilters(dlg.textValue()); - int row = m_activeView->currentIndex().row(); - - m_activeView->refresh(); - - if (row >= m_activeView->model()->rowCount()) { - row = m_activeView->model()->rowCount() - 1; + filters = dlg.textValue(); + if (filters.isEmpty()) { + filters = "*"; } - m_activeView->setCurrentIndex(m_activeView->model()->index(row, 1)); - + activeModel()->setNameFilters(filters.split(" ", QString::SkipEmptyParts)); + activeModel()->refresh(); } } +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::showHistoryDialog +/// +/// 履歴選択ダイアログを表示します。 +/// void MainWindow::showHistoryDialog() { - qDebug() << "MainWindow::showHistoryDialog();"; - - FolderView *vOther = otherSideFolderView(m_activeView); + qDebug() << "MainWindow::showHistoryDialog()"; HistoryDialog dlg(this); - if (m_activeView->side() == "Left") { - dlg.setDefaultLeft(true); - dlg.setHistory(m_activeView->history(), vOther->history()); - } - else { - dlg.setDefaultLeft(false); - dlg.setHistory(vOther->history(), m_activeView->history()); - } - - if (dlg.exec() == QDialog::Accepted) { - if (m_activeView->side() == dlg.selectedSide()) { - m_activeView->setHistoryIndexAt(dlg.selectedIndex()); - } - else { - m_activeView->setPath(vOther->history()->at(dlg.selectedIndex()), true); - } - } + dlg.setModel(ui->LPanel->model(), ui->RPanel->model(), activeModel()); + dlg.exec(); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::showSortDialog +/// +/// ソート方法選択ダイアログを表示します。 +/// void MainWindow::showSortDialog() { - qDebug() << "MainWindow::showSortDialog();"; + qDebug() << "MainWindow::showSortDialog()"; SortDialog dlg(this); - dlg.setRightOrLeft(m_activeView->side()); - - if (dlg.exec() == QDialog::Accepted) { - m_activeView->setSorting(); - m_activeView->refresh(); - } + dlg.setModel(activeModel()); + dlg.exec(); } -void MainWindow::splitCenter() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onSplitCenter +/// +/// パネルを中央で分割します。 +/// +void MainWindow::onSplitCenter() { - qDebug() << "MainWindow::splitCenter();"; + qDebug() << "MainWindow::onSplitCenter()"; QList sizes = ui->splitter->sizes(); int sizeTotal = sizes[0] + sizes[1]; @@ -987,101 +1266,136 @@ void MainWindow::splitCenter() ui->splitter->setSizes(sizes); } -void MainWindow::swapView() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onSwap +/// +/// 左右のパネルでモデルを入れ替えます。 +/// +void MainWindow::onSwap() { - qDebug() << "MainWindow::swapView();"; - - QString dir1 = ui->pane1->folderPanel()->folderView()->dir(); - QString dir2 = ui->pane2->folderPanel()->folderView()->dir(); + qDebug() << "MainWindow::onSwap()"; - ui->pane1->folderPanel()->folderView()->setPath(dir2, true); - ui->pane2->folderPanel()->folderView()->setPath(dir1, true); + FolderModel *tmp = ui->LPanel->model(); + ui->LPanel->setModel(ui->RPanel->model()); + ui->RPanel->setModel(tmp); - updateActions(); + // アクティブ状態も変更する + if (ui->LPanel->model()->isActive()) { + setActiveModel(ui->RPanel->model()); + } + else { + setActiveModel(ui->LPanel->model()); + } } -void MainWindow::switchHalfMode(bool checked) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onTogglePreviewMode +/// \param checked メニューのチェック状態 +/// +/// 通常モード/プレビューモードを切り替えます。 +/// +void MainWindow::onTogglePreviewMode(bool checked) { - qDebug() << "MainWindow::switchHalfMode();" << checked; - - AnyView *pane = static_cast( - otherSideFolderView(m_activeView)->parent()->parent()); - Q_CHECK_PTR(pane); + qDebug() << "MainWindow::onTogglePreviewMode()" << checked; if (checked) { - // ハーフモードへ移行する - setViewMode(ModeHalfView); - pane->setViewItem(m_activeView->currentItem()); + setViewMode(ModePreview); } else { - // ハーフモードを解除する setViewMode(ModeBasic); - pane->changeView(AnyView::ViewFolder); } - updateActions(); } -void MainWindow::searchNext() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onSearchNext +/// +/// 次のアイテムを検索します。 +/// +void MainWindow::onSearchNext() { - qDebug() << "MainWindow::searchNext"; - - SearchBox *box = qobject_cast(qApp->focusWidget()); - Q_CHECK_PTR(box); + qDebug() << "MainWindow::onSearchNext"; - m_activeView->searchNext(box->text()); + static_cast(qApp->focusWidget()->parentWidget())->searchNext(); } -void MainWindow::searchPrev() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onSearchPrev +/// +/// 前のアイテムを検索します。 +/// +void MainWindow::onSearchPrev() { - qDebug() << "MainWindow::searchPrev"; + qDebug() << "MainWindow::onSearchPrev"; - SearchBox *box = qobject_cast(qApp->focusWidget()); - Q_CHECK_PTR(box); - - m_activeView->searchPrev(box->text()); + static_cast(qApp->focusWidget()->parentWidget())->searchNext(-1); } -void MainWindow::setCursorToBegin() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onKeyDown +/// +/// フォーカスウィジェットに↓キーイベントを送信します。 +/// +void MainWindow::onKeyDown() { - qDebug() << "MainWindow::setCursorToBegin();"; - - QKeyEvent event1 = QKeyEvent(QEvent::KeyPress, Qt::Key_Home, Qt::NoModifier); - QApplication::sendEvent(QApplication::focusWidget(), &event1); + qDebug() << "MainWindow::onKeyDown()"; - QKeyEvent event2 = QKeyEvent(QEvent::KeyPress, Qt::Key_Home, Qt::ControlModifier); - QApplication::sendEvent(QApplication::focusWidget(), &event2); + QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier); + qApp->sendEvent(qApp->focusWidget(), &event); } -void MainWindow::cursorDown() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onKeyEnd +/// +/// フォーカスウィジェットにEND, Ctrl+ENDキーイベントを送信します。 +/// +void MainWindow::onKeyEnd() { - qDebug() << "MainWindow::cursorDown();"; + qDebug() << "MainWindow::onKeyEnd()"; - QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier); - QApplication::sendEvent(QApplication::focusWidget(), &event); + QKeyEvent event1 = QKeyEvent(QEvent::KeyPress, Qt::Key_End, Qt::NoModifier); + qApp->sendEvent(qApp->focusWidget(), &event1); + + QKeyEvent event2 = QKeyEvent(QEvent::KeyPress, Qt::Key_End, Qt::ControlModifier); + qApp->sendEvent(qApp->focusWidget(), &event2); } -void MainWindow::cursorUp() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onKeyHome +/// +/// フォーカスウィジェットにHOME, Ctrl+HOMEキーイベントを送信します。 +/// +void MainWindow::onKeyHome() { - qDebug() << "MainWindow::cursorUp();"; + qDebug() << "MainWindow::onKeyHome()"; - QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier); - QApplication::sendEvent(QApplication::focusWidget(), &event); + QKeyEvent event1 = QKeyEvent(QEvent::KeyPress, Qt::Key_Home, Qt::NoModifier); + qApp->sendEvent(qApp->focusWidget(), &event1); + + QKeyEvent event2 = QKeyEvent(QEvent::KeyPress, Qt::Key_Home, Qt::ControlModifier); + qApp->sendEvent(qApp->focusWidget(), &event2); } -void MainWindow::setCursorToEnd() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onKeyUp +/// +/// フォーカスウィジェットに↑キーイベントを送信します。 +/// +void MainWindow::onKeyUp() { - qDebug() << "MainWindow::setCursorToEnd();"; + qDebug() << "MainWindow::onKeyUp()"; - QKeyEvent event1 = QKeyEvent(QEvent::KeyPress, Qt::Key_End, Qt::NoModifier); - QApplication::sendEvent(QApplication::focusWidget(), &event1); - - QKeyEvent event2 = QKeyEvent(QEvent::KeyPress, Qt::Key_End, Qt::ControlModifier); - QApplication::sendEvent(QApplication::focusWidget(), &event2); + QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier); + qApp->sendEvent(qApp->focusWidget(), &event); } -void MainWindow::setCursorToBeginOther() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onKeyHomeOther +/// +/// 非フォーカスビューにHOME, Ctrl+HOMEキーイベントを送信します。 +/// +void MainWindow::onKeyHomeOther() { - qDebug() << "MainWindow::setCursorToBeginOther();"; + qDebug() << "MainWindow::onKeyHomeOther()"; QKeyEvent event1 = QKeyEvent(QEvent::KeyPress, Qt::Key_Home, Qt::NoModifier); sendEventOther(&event1); @@ -1090,25 +1404,40 @@ void MainWindow::setCursorToBeginOther() sendEventOther(&event2); } -void MainWindow::cursorDownOther() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onKeyDownOther +/// +/// 非フォーカスビューに↓キーイベントを送信します。 +/// +void MainWindow::onKeyDownOther() { - qDebug() << "MainWindow::cursorDownOther();"; + qDebug() << "MainWindow::onKeyDownOther()"; QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier); sendEventOther(&event); } -void MainWindow::cursorUpOther() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onKeyUpOther +/// +/// 非フォーカスビューに↑キーイベントを送信します。 +/// +void MainWindow::onKeyUpOther() { - qDebug() << "MainWindow::cursorUpOther();"; + qDebug() << "MainWindow::onKeyUpOther()"; QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier); sendEventOther(&event); } -void MainWindow::setCursorToEndOther() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onKeyEndOther +/// +/// 非フォーカスビューにEND, Ctrl+ENDキーイベントを送信します。 +/// +void MainWindow::onKeyEndOther() { - qDebug() << "MainWindow::setCursorToEndOther();"; + qDebug() << "MainWindow::onKeyEndOther()"; QKeyEvent event1 = QKeyEvent(QEvent::KeyPress, Qt::Key_End, Qt::NoModifier); sendEventOther(&event1); @@ -1117,287 +1446,233 @@ void MainWindow::setCursorToEndOther() sendEventOther(&event2); } -void MainWindow::setFontSizeDown() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onScaleDown +/// +/// 表示を縮小します。 +/// +void MainWindow::onScaleDown() { - qDebug() << "MainWindow::setFontSizeDown();"; - - changeFontSize(-1); -} + qDebug() << "MainWindow::onScaleDown()"; -void MainWindow::setFontSizeUp() -{ - qDebug() << "MainWindow::setFontSizeUp();"; + AbstractView *view = dynamic_cast(qApp->focusWidget()); + if (view) { + view->scaleDown(); + } - changeFontSize(1); + ui->LPanel->updateAppearance(); + ui->RPanel->updateAppearance(); + ui->FPanel->updateAppearance(); } -void MainWindow::changeFontSize(int diff) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onScaleUp +/// +/// 表示を拡大します。 +/// +void MainWindow::onScaleUp() { - qDebug() << "MainWindow::changeFontSize(;"; - - QSettings settings; - QFont font; + qDebug() << "MainWindow::onScaleUp()"; - // フォルダビューのフォントサイズ変更 - if (ui->pane1->folderPanel()->folderView()->hasFocus() || - ui->pane2->folderPanel()->folderView()->hasFocus()) - { - font = settings.value(IniKey_ViewFont).value(); - font.setPointSize(font.pointSize() + diff); - settings.setValue(IniKey_ViewFont, font); - - ui->pane1->folderPanel()->updateAppearance(); - ui->pane2->folderPanel()->updateAppearance(); + AbstractView *view = dynamic_cast(qApp->focusWidget()); + if (view) { + view->scaleUp(); } - // テキストビューのフォントサイズ変更 - if (ui->pane1->textView()->hasFocus() || - ui->pane2->textView()->hasFocus() || - ui->pane3->textView()->hasFocus()) - { - font = settings.value(IniKey_ViewerFont).value(); - font.setPointSize(font.pointSize() + diff); - settings.setValue(IniKey_ViewerFont, font); - - ui->pane1->textView()->updateAppearance(); - ui->pane2->textView()->updateAppearance(); - ui->pane3->textView()->updateAppearance(); - } - - if (ui->pane1->imageView()->hasFocus() || - ui->pane2->imageView()->hasFocus() || - ui->pane3->imageView()->hasFocus()) - { - ui->pane1->imageView()->changeScale(diff > 0); - ui->pane2->imageView()->changeScale(diff > 0); - ui->pane3->imageView()->changeScale(diff > 0); - } + ui->LPanel->updateAppearance(); + ui->RPanel->updateAppearance(); + ui->FPanel->updateAppearance(); } -void MainWindow::initBookmark() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::initBookmarkMenu +/// +/// ブックマークメニューを初期化します。 +/// +void MainWindow::initBookmarkMenu() { - QSettings settings; + qDebug() << "MainWindow::initBookmarkMenu()"; + + Preferences prefs(this); QFileIconProvider iconProvider; ui->menu_Bookmark->clear(); - ui->menu_Bookmark->addAction(ui->bookmark_Edit); + ui->menu_Bookmark->addAction(ui->action_AddBookmark); + ui->menu_Bookmark->addAction(ui->action_EditBookmark); ui->menu_Bookmark->addSeparator(); - int i = 0; - while (!settings.value(IniKey_BookmarkEntryName(i), "").toString().isEmpty()) { - QString path = settings.value(IniKey_BookmarkEntryPath(i)).toString(); - QAction *action = new QAction(this); - action->setText(settings.value(IniKey_BookmarkEntryName(i)).toString()); - action->setData(i); - action->setIcon(iconProvider.icon(QFileInfo(path))); - ui->menu_Bookmark->addAction(action); - connect(action, SIGNAL(triggered()), this, SLOT(openBookmark())); - i++; + for (int n = 1; ; n++) { + QString name = prefs.getBookmarkEntry(n); + if (name.isEmpty()) { + break; + } + QString path = prefs.getBookmarkPath(n); + + QAction *action = ui->menu_Bookmark->addAction( + iconProvider.icon(QFileInfo(path)), name, this, + SLOT(onOpenBookmark())); + action->setData(n); } } +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::sendEventOther +/// \param event 送信するイベント +/// +/// 非フォーカスのビューにイベントを送信します。 +/// void MainWindow::sendEventOther(QEvent *event) { - qDebug() << "MainWindow::sendEventOther();"; - - QWidget *widget = NULL; + qDebug() << "MainWindow::sendEventOther()"; - if (m_viewMode & ModeBasic) { - // 検索ボックスにフォーカスがある場合も考慮して、 - // FolderPanalを介してViewを取得する - FolderPanel *fp = qobject_cast(qApp->focusWidget()->parentWidget()); - Q_CHECK_PTR(fp); - - widget = otherSideFolderView(fp->folderView()); - } - else if (m_viewMode & ModeHalfView) { - AnyView *focusedView = qobject_cast(qApp->focusWidget()->parentWidget()); - if (!focusedView) { - focusedView = qobject_cast(qApp->focusWidget()->parentWidget()->parentWidget()); - } - Q_CHECK_PTR(focusedView); - - if (focusedView == ui->pane1) { - widget = ui->pane2->visibleView(); - } - else { - Q_ASSERT(focusedView == ui->pane2); - widget = ui->pane1->visibleView(); + // フォーカスを持たない、可視状態のビューを検索する + foreach (QWidget *w, findChildren()) { + AbstractView *view = dynamic_cast(w); + if (view) { + if (w->isVisible() && !w->hasFocus()) { + qDebug() << "Send event to" << w->objectName(); + qApp->sendEvent(w, event); + } } } - else { - return; - } - - Q_CHECK_PTR(widget); - QApplication::sendEvent(widget, event); -} - -void MainWindow::setPathFromOther() -{ - qDebug() << "MainWindow::setPathFromOther();"; - - FolderView *other = otherSideFolderView(m_activeView); - - m_activeView->setPath(other->dir(), true); } -void MainWindow::setPathToHome() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onSyncPanel +/// +/// 隣のパネルと同じフォルダを表示します。 +/// +void MainWindow::onSyncPanel() { - qDebug() << "MainWindow::setPathToHome();"; + qDebug() << "MainWindow::onSyncPanel()"; - m_activeView->setPath(QDir::homePath(), true); + activeModel()->setRootPath(inactiveModel()->rootPath()); } -void MainWindow::setPathToOther() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onSyncPanelTo +/// +/// 隣のパネルに同じフォルダを表示します。 +/// +void MainWindow::onSyncPanelTo() { - qDebug() << "MainWindow::setPathToOther();"; - - FolderView *other = otherSideFolderView(m_activeView); + qDebug() << "MainWindow::onSyncPanelTo()"; - other->setPath(m_activeView->dir(), true); + inactiveModel()->setRootPath(activeModel()->rootPath()); } -void MainWindow::setPathToParent() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onToggleFullMode +/// \param checked メニューのチェック状態 +/// +/// 単画面/二画面を切り替えます。 +/// +void MainWindow::onToggleFullMode(bool checked) { - qDebug() << "MainWindow::setPathToParent();"; + qDebug() << "MainWindow::onToggleFullMode()" << checked; - QDir dir(m_activeView->dir()); - if (!dir.isRoot()) { - dir.cdUp(); - m_activeView->setPath(dir.absolutePath(), true); + if (checked) { + setViewMode(ModeFull); + } + else { + setViewMode(ModeBasic); } } -void MainWindow::setPathToRoot() -{ - qDebug() << "MainWindow::setPathToRoot();"; - - m_activeView->setPath(QDir::rootPath(), true); -} -void MainWindow::toggleSearchBox(bool checked) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onToggleSearch +/// \param checked メニューのチェック状態 +/// +/// 検索ボックスの表示/非表示を切り替えます。 +/// +void MainWindow::onToggleSearch(bool checked) { - qDebug() << "MainWindow::toggleSearchBox" << checked; - - FolderView *view; - SearchBox *box; + qDebug() << "MainWindow::onToggleSearch" << checked; - if (checked) { - setViewMode(m_viewMode | ModeSearch); - - box = m_activeView->parent()->findChild("searchBox"); - Q_CHECK_PTR(box); - - box->setVisible(true); - box->setFocus(); - box->selectAll(); - } - else { - setViewMode(m_viewMode ^ ModeSearch); - if (ui->pane1->folderPanel()->searchBox()->isVisible()) { - box = ui->pane1->folderPanel()->searchBox(); - view = ui->pane1->folderPanel()->folderView(); - } - else { - Q_ASSERT(ui->pane2->folderPanel()->searchBox()->isVisible()); - box = ui->pane2->folderPanel()->searchBox(); - view = ui->pane2->folderPanel()->folderView(); - } - - if (box->hasFocus()) { - view->setFocus(); - } - box->setVisible(false); - } + // 丸投げ + ui->LPanel->folderPanel()->toggleSearch(checked); + ui->RPanel->folderPanel()->toggleSearch(checked); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::showPreferenceDialog +/// +/// 環境設定ダイアログを表示します。 +/// void MainWindow::showPreferenceDialog() { qDebug() << "MainWindow::showPreferenceDialog"; PreferenceDialog dlg(this); if (dlg.exec() == QDialog::Accepted) { - bool dark1 = m_activeView != ui->pane1->folderPanel()->folderView(); - bool dark2 = m_activeView != ui->pane2->folderPanel()->folderView(); - - ui->pane1->folderPanel()->updateAppearance(dark1); - ui->pane2->folderPanel()->updateAppearance(dark2); - ui->pane1->textView()->updateAppearance(); - ui->pane2->textView()->updateAppearance(); - ui->pane3->textView()->updateAppearance(); - - updateActions(); + ui->LPanel->updateAppearance(); + ui->RPanel->updateAppearance(); + ui->FPanel->updateAppearance(); } } -void MainWindow::toggleShowHiddenFiles(bool checked) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onToggleHidden +/// \param checked メニューのチェック状態 +/// +/// 隠しファイルの表示/非表示を切り替えます。 +/// +void MainWindow::onToggleHidden(bool checked) { - qDebug() << "MainWindow::toggleShowHiddenFiles" << checked; + qDebug() << "MainWindow::onToggleHidden" << checked; - ui->pane1->folderPanel()->folderView()->setFilter(QDir::Hidden, checked); - ui->pane1->folderPanel()->folderView()->refresh(); + if (checked) { + activeModel()->setFilter(activeModel()->filter() | QDir::Hidden); + } + else { + activeModel()->setFilter(activeModel()->filter() ^ QDir::Hidden); + } - ui->pane2->folderPanel()->folderView()->setFilter(QDir::Hidden, checked); - ui->pane2->folderPanel()->folderView()->refresh(); + activeModel()->refresh(); } -void MainWindow::toggleShowSystemFiles(bool checked) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onToggleSystem +/// \param checked メニューのチェック状態 +/// +/// システムファイルの表示/非表示を切り替えます。 +/// +void MainWindow::onToggleSystem(bool checked) { - qDebug() << "MainWindow::toggleShowSystemFiles" << checked; + qDebug() << "MainWindow::onToggleSystem" << checked; - ui->pane1->folderPanel()->folderView()->setFilter(QDir::System, checked); - ui->pane1->folderPanel()->folderView()->refresh(); + if (checked) { + activeModel()->setFilter(activeModel()->filter() | QDir::System); + } + else { + activeModel()->setFilter(activeModel()->filter() ^ QDir::System); + } - ui->pane2->folderPanel()->folderView()->setFilter(QDir::System, checked); - ui->pane2->folderPanel()->folderView()->refresh(); + activeModel()->refresh(); } -void MainWindow::showContextMenu(QContextMenuEvent *event) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onToggleThumbnailMode +/// \param checked メニューのチェック状態 +/// +/// サムネイルモードの切り替えを行います。 +/// +void MainWindow::onToggleThumbnailMode(bool checked) { - qDebug() << "MainWindow::showContextMenu();"; - - FolderView *view = static_cast(sender()); - Q_CHECK_PTR(view); - - QModelIndex index = view->indexAt(event->pos()); - - QMenu menu(this); - if (index.isValid()) { - menu.addAction(ui->action_Open); - menu.addAction(ui->action_Exec); - menu.addAction(ui->action_OpenEditor); - menu.addAction(ui->action_OpenTerminal); - menu.addAction(ui->action_OpenArchiver); - menu.addSeparator(); - menu.addAction(ui->cmd_Copy); - menu.addAction(ui->cmd_Move); - menu.addSeparator(); - menu.addAction(ui->cmd_Delete); - menu.addSeparator(); - menu.addAction(ui->copy_Filename); - menu.addAction(ui->copy_Fullpath); - menu.addSeparator(); - menu.addAction(ui->cmd_Rename); - } - else { - menu.addAction(ui->move_Back); - menu.addAction(ui->move_Forward); - menu.addSeparator(); - menu.addAction(ui->move_Parent); - menu.addAction(ui->move_Home); - menu.addAction(ui->move_Root); - menu.addAction(ui->move_Jump); - menu.addSeparator(); - menu.addAction(ui->cmd_NewFile); - menu.addAction(ui->cmd_NewFolder); - } + qDebug() << "MainWindow::onToggleThumbnailMode()" << checked; - menu.exec(event->globalPos()); + activePanel()->folderPanel()->toggleView(checked); } -void MainWindow::checkUpdate(bool silent) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onCheckUpdate +/// \param silent 最新版を使用している場合に何も表示しないならtrue +/// +/// アップデートの有無を確認します。 +/// +void MainWindow::onCheckUpdate(bool silent) { - qDebug() << "MainWindow::checkUpdate()" << silent; + qDebug() << "MainWindow::onCheckUpdate()" << silent; QNetworkAccessManager *manager = new QNetworkAccessManager(this); @@ -1451,124 +1726,290 @@ void MainWindow::checkUpdateFinished(QNetworkReply *reply, bool silent) } } -void MainWindow::viewFinish() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::initActions +/// +/// アクションを初期化します。 +/// +void MainWindow::initActions() { - qDebug() << "MainWindow::viewFinish();" << sender()->objectName(); + qDebug() << "MainWindow::initActions()"; + + QList shortcuts; + + //>>>>> 追加のショートカットキーを設定する + appendActionShortcut(ui->action_Open, "M"); + appendActionShortcut(ui->action_OpenWith, "Shift+M"); + appendActionShortcut(ui->view_Back, "Backspace"); + // MacだとShift+の形で認識されてしまうもの + appendActionShortcut(ui->action_ScaleUp, "Shift++"); + appendActionShortcut(ui->action_Filter, "Shift+*"); + appendActionShortcut(ui->action_OpenTerminal, "Shift+>"); + appendActionShortcut(ui->action_About, "Shift+?"); + appendActionShortcut(ui->image_ScaleNormal, "Shift+="); + + // SIGNAL -> SLOT + connect(ui->action_About, SIGNAL(triggered()), this, SLOT(onAbout())); + connect(ui->action_AddBookmark, SIGNAL(triggered()), this, SLOT(onAddBookmark())); + connect(ui->action_Cd, SIGNAL(triggered()), this, SLOT(onChooseFolder())); + connect(ui->action_CheckUpdate, SIGNAL(triggered()), this, SLOT(onCheckUpdate())); + connect(ui->action_Copy, SIGNAL(triggered()), this, SLOT(onCopy())); + connect(ui->action_CopyFileName, SIGNAL(triggered()), this, SLOT(onCopyFileName())); + connect(ui->action_CopyFilePath, SIGNAL(triggered()), this, SLOT(onCopyFilePath())); + connect(ui->action_CreateFile, SIGNAL(triggered()), this, SLOT(onCreateFile())); + connect(ui->action_CreateFolder, SIGNAL(triggered()), this, SLOT(onCreateFolder())); + connect(ui->action_Delete, SIGNAL(triggered()), this, SLOT(onDelete())); + connect(ui->action_EditBookmark, SIGNAL(triggered()), this, SLOT(onEditBookmark())); + connect(ui->action_ExpandLeft, SIGNAL(triggered()), this, SLOT(onExpandLeft())); + connect(ui->action_ExpandRight, SIGNAL(triggered()), this, SLOT(onExpandRight())); + connect(ui->action_Filter, SIGNAL(triggered()), this, SLOT(showFilterDialog())); + connect(ui->action_History, SIGNAL(triggered()), this, SLOT(showHistoryDialog())); + connect(ui->action_KeyDown, SIGNAL(triggered()), this, SLOT(onKeyDown())); + connect(ui->action_KeyDownOther, SIGNAL(triggered()), this, SLOT(onKeyDownOther())); + connect(ui->action_KeyEnd, SIGNAL(triggered()), this, SLOT(onKeyEnd())); + connect(ui->action_KeyEndOther, SIGNAL(triggered()), this, SLOT(onKeyEndOther())); + connect(ui->action_KeyHome, SIGNAL(triggered()), this, SLOT(onKeyHome())); + connect(ui->action_KeyHomeOther, SIGNAL(triggered()), this, SLOT(onKeyHomeOther())); + connect(ui->action_KeyLeft, SIGNAL(triggered()), this, SLOT(onKeyLeft())); + connect(ui->action_KeyUp, SIGNAL(triggered()), this, SLOT(onKeyUp())); + connect(ui->action_KeyUpOther, SIGNAL(triggered()), this, SLOT(onKeyUpOther())); + connect(ui->action_Move, SIGNAL(triggered()), this, SLOT(onMove())); + connect(ui->action_Open, SIGNAL(triggered()), this, SLOT(onOpen())); + connect(ui->action_OpenArchiver, SIGNAL(triggered()), this, SLOT(onOpenArchiver())); + connect(ui->action_OpenEditor, SIGNAL(triggered()), this, SLOT(onOpenEditor())); + connect(ui->action_OpenTerminal, SIGNAL(triggered()), this, SLOT(onOpenTerminal())); + connect(ui->action_OpenWith, SIGNAL(triggered()), this, SLOT(onOpenWith())); + connect(ui->action_Quit, SIGNAL(triggered()), this, SLOT(close())); + connect(ui->action_Rename, SIGNAL(triggered()), this, SLOT(onRename())); + connect(ui->action_KeyRight, SIGNAL(triggered()), this, SLOT(onKeyRight())); + connect(ui->action_RunCommand, SIGNAL(triggered()), this, SLOT(onRunCommand())); + connect(ui->action_ScaleDown, SIGNAL(triggered()), this, SLOT(onScaleDown())); + connect(ui->action_ScaleUp, SIGNAL(triggered()), this, SLOT(onScaleUp())); + connect(ui->action_SearchNext, SIGNAL(triggered()), this, SLOT(onSearchNext())); + connect(ui->action_SearchPrev, SIGNAL(triggered()), this, SLOT(onSearchPrev())); + connect(ui->action_Setting, SIGNAL(triggered()), this, SLOT(showPreferenceDialog())); + connect(ui->action_ShowBookmark, SIGNAL(triggered()), this, SLOT(showBookmarkDialog())); + connect(ui->action_Sort, SIGNAL(triggered()), this, SLOT(showSortDialog())); + connect(ui->action_SplitCenter, SIGNAL(triggered()), this, SLOT(onSplitCenter())); + connect(ui->action_Swap, SIGNAL(triggered()), this, SLOT(onSwap())); + connect(ui->action_SyncPanel, SIGNAL(triggered()), this, SLOT(onSyncPanel())); + connect(ui->action_SyncPanelTo, SIGNAL(triggered()), this, SLOT(onSyncPanelTo())); + + connect(ui->toggle_FullMode, SIGNAL(toggled(bool)), this, SLOT(onToggleFullMode(bool))); + connect(ui->toggle_Hidden, SIGNAL(toggled(bool)), this, SLOT(onToggleHidden(bool))); + connect(ui->toggle_Mark, SIGNAL(triggered()), this, SLOT(onToggleMark())); + connect(ui->toggle_PreviewMode, SIGNAL(toggled(bool)), this, SLOT(onTogglePreviewMode(bool))); + connect(ui->toggle_Search, SIGNAL(toggled(bool)), this, SLOT(onToggleSearch(bool))); + connect(ui->toggle_System, SIGNAL(toggled(bool)), this, SLOT(onToggleSystem(bool))); + connect(ui->toggle_ThumbnailMode, SIGNAL(toggled(bool)), this, SLOT(onToggleThumbnailMode(bool))); + + connect(ui->view_Back, SIGNAL(triggered()), this, SLOT(view_finished())); - ui->statusBar->findChild("Right")->setText(""); - ui->pane3->setVisible(false); - ui->splitter->setVisible(true); - m_activeView->setFocus(); } -void MainWindow::initActionConnections() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::setActiveModel +/// \param m 新しいアクティブモデル +/// +/// アクティブモデルを変更します。 +/// +void MainWindow::setActiveModel(FolderModel *m) { - qDebug() << "MainWindow::initActionConnections"; + qDebug() << "MainWindow::setActiveModel()" << m; - connect(ui->key_Left, SIGNAL(triggered()), this, SLOT(leftKeyPress())); - connect(ui->key_Right, SIGNAL(triggered()), this, SLOT(rightKeyPress())); + if (activeModel()) { + activeModel()->disconnect(this); + ui->action_CdHome->disconnect(); + ui->action_CdRoot->disconnect(); + ui->action_CdUp->disconnect(); + ui->action_historyBack->disconnect(); + ui->action_HistoryForward->disconnect(); + ui->action_MarkAll->disconnect(); + ui->action_MarkAllFiles->disconnect(); + ui->action_MarkAllOff->disconnect(); + ui->action_MarkInvert->disconnect(); + ui->action_Refresh->disconnect(); + } - connect(ui->action_Command, SIGNAL(triggered()), this, SLOT(executeCommand())); - connect(ui->action_Exec, SIGNAL(triggered()), this, SLOT(shellExecute())); - connect(ui->action_Open, SIGNAL(triggered()), this, SLOT(open())); - connect(ui->action_OpenEditor, SIGNAL(triggered()), this, SLOT(openEditor())); - connect(ui->action_OpenTerminal, SIGNAL(triggered()), this, SLOT(openTerminal())); - connect(ui->action_OpenArchiver, SIGNAL(triggered()), this, SLOT(openArchiver())); - connect(ui->action_Quit, SIGNAL(triggered()), this, SLOT(close())); - connect(ui->action_Search, SIGNAL(toggled(bool)), this, SLOT(toggleSearchBox(bool))); - connect(ui->action_SearchNext, SIGNAL(triggered()), this, SLOT(searchNext())); - connect(ui->action_SearchPrev, SIGNAL(triggered()), this, SLOT(searchPrev())); - connect(ui->action_Setting, SIGNAL(triggered()), this, SLOT(showPreferenceDialog())); - connect(ui->check_Update, SIGNAL(triggered()), this, SLOT(checkUpdate())); - connect(ui->cmd_Copy, SIGNAL(triggered()), this, SLOT(copyItems())); - connect(ui->cmd_Delete, SIGNAL(triggered()), this, SLOT(deleteItems())); - connect(ui->cmd_Move, SIGNAL(triggered()), this, SLOT(moveItems())); - connect(ui->cmd_NewFile, SIGNAL(triggered()), this, SLOT(createFile())); - connect(ui->cmd_NewFolder, SIGNAL(triggered()), this, SLOT(createFolder())); - connect(ui->cmd_Rename, SIGNAL(triggered()), this, SLOT(renameItems())); - connect(ui->copy_Filename, SIGNAL(triggered()), this, SLOT(copyFilenameToClipboard())); - connect(ui->copy_Fullpath, SIGNAL(triggered()), this, SLOT(copyFullpathTpClipboard())); - connect(ui->help_About, SIGNAL(triggered()), this, SLOT(about())); - connect(ui->mark_All, SIGNAL(triggered()), this, SLOT(markAll())); - connect(ui->mark_AllFiles, SIGNAL(triggered()), this, SLOT(markAllFiles())); - connect(ui->mark_AllOff, SIGNAL(triggered()), this, SLOT(markAllOff())); - connect(ui->mark_Invert, SIGNAL(triggered()), this, SLOT(markInvert())); - connect(ui->mark_Toggle, SIGNAL(triggered()), this, SLOT(markToggle())); - connect(ui->move_Back, SIGNAL(triggered()), this, SLOT(historyBack())); - connect(ui->move_Begin, SIGNAL(triggered()), this, SLOT(setCursorToBegin())); - connect(ui->move_Down, SIGNAL(triggered()), this, SLOT(cursorDown())); - connect(ui->move_End, SIGNAL(triggered()), this, SLOT(setCursorToEnd())); - connect(ui->move_Up, SIGNAL(triggered()), this, SLOT(cursorUp())); - connect(ui->move_BeginOther, SIGNAL(triggered()), this, SLOT(setCursorToBeginOther())); - connect(ui->move_DownOther, SIGNAL(triggered()), this, SLOT(cursorDownOther())); - connect(ui->move_EndOther, SIGNAL(triggered()), this, SLOT(setCursorToEndOther())); - connect(ui->move_UpOther, SIGNAL(triggered()), this, SLOT(cursorUpOther())); - connect(ui->move_Forward, SIGNAL(triggered()), this, SLOT(historyForward())); - connect(ui->move_History, SIGNAL(triggered()), this, SLOT(showHistoryDialog())); - connect(ui->move_Home, SIGNAL(triggered()), this, SLOT(setPathToHome())); - connect(ui->move_Jump, SIGNAL(triggered()), this, SLOT(chooseFolder())); - connect(ui->move_Parent, SIGNAL(triggered()), this, SLOT(setPathToParent())); - connect(ui->move_Root, SIGNAL(triggered()), this, SLOT(setPathToRoot())); - connect(ui->view_Filter, SIGNAL(triggered()), this, SLOT(showFilterDialog())); - connect(ui->view_FontSizeDown, SIGNAL(triggered()), this, SLOT(setFontSizeDown())); - connect(ui->view_FontSizeUp, SIGNAL(triggered()), this, SLOT(setFontSizeUp())); - connect(ui->view_FromOther, SIGNAL(triggered()), this, SLOT(setPathFromOther())); - connect(ui->view_HalfMode, SIGNAL(toggled(bool)), this, SLOT(switchHalfMode(bool))); - connect(ui->view_Hidden, SIGNAL(toggled(bool)), this, SLOT(toggleShowHiddenFiles(bool))); - connect(ui->view_Refresh, SIGNAL(triggered()), this, SLOT(refresh())); - - connect(ui->view_Sort, SIGNAL(triggered()), this, SLOT(showSortDialog())); - connect(ui->view_Swap, SIGNAL(triggered()), this, SLOT(swapView())); - connect(ui->view_System, SIGNAL(toggled(bool)), this, SLOT(toggleShowSystemFiles(bool))); - connect(ui->view_ToOther, SIGNAL(triggered()), this, SLOT(setPathToOther())); - connect(ui->bookmark_Edit, SIGNAL(triggered()), this, SLOT(editBookmark())); - connect(ui->bookmark_Show, SIGNAL(triggered()), this, SLOT(showBookmarkDialog())); - connect(ui->split_Center, SIGNAL(triggered()), this, SLOT(splitCenter())); - connect(ui->expand_Left, SIGNAL(triggered()), this, SLOT(expandLeft())); - connect(ui->expand_Right, SIGNAL(triggered()), this, SLOT(expandRight())); -} - -void MainWindow::replaceVars(QString &str, const QFileInfo info) -{ - qDebug() << "MainWindow::replaceVars" << str; - - str.replace("$B", info.completeBaseName()); - str.replace("$E", info.suffix()); - str.replace("$F", info.fileName()); - if (info.isDir()) { - str.replace("$D", info.absoluteFilePath()); + m->setActive(); + + connect(activeModel(), SIGNAL(modelAboutToBeReset()), this, SLOT(model_PreReset())); + connect(activeModel(), SIGNAL(modelReset()), this, SLOT(model_PostReset())); + connect(ui->action_CdHome, SIGNAL(triggered()), activeModel(), SLOT(onCdHome())); + connect(ui->action_CdRoot, SIGNAL(triggered()), activeModel(), SLOT(onCdRoot())); + connect(ui->action_CdUp, SIGNAL(triggered()), activeModel(), SLOT(onCdUp())); + connect(ui->action_historyBack, SIGNAL(triggered()), activeModel(), SLOT(onHistoryBack())); + connect(ui->action_HistoryForward, SIGNAL(triggered()), activeModel(), SLOT(onHistoryForward())); + connect(ui->action_MarkAll, SIGNAL(triggered()), activeModel(), SLOT(onMarkAll())); + connect(ui->action_MarkAllFiles, SIGNAL(triggered()), activeModel(), SLOT(onMarkAllFiles())); + connect(ui->action_MarkAllOff, SIGNAL(triggered()), activeModel(), SLOT(onMarkAllOff())); + connect(ui->action_MarkInvert, SIGNAL(triggered()), activeModel(), SLOT(onMarkInvert())); + connect(ui->action_Refresh, SIGNAL(triggered()), activeModel(), SLOT(refresh())); + + ui->LPanel->updateAppearance(); + ui->RPanel->updateAppearance(); + ui->FPanel->updateAppearance(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::activeModel +/// \return アクティブなフォルダモデルを返します。 +/// +FolderModel *MainWindow::activeModel() const +{ + return FolderModel::activeModel(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::activePanel +/// \return アクティブモデルを所有している可視状態のパネルを返します。 +/// +Panel *MainWindow::activePanel() const +{ + if (ui->FPanel->model() == activeModel() && ui->FPanel->isVisible()) { + return ui->FPanel; } - else { - str.replace("$D", info.absolutePath()); + if (ui->LPanel->model() == activeModel() && ui->LPanel->isVisible()) { + return ui->LPanel; + } + if (ui->RPanel->model() == activeModel() && ui->RPanel->isVisible()) { + return ui->RPanel; } - str.replace("$P", info.absoluteFilePath()); + + qDebug() << ">>>>>>>>>> activePanel() Logic error <<<<<<<<<<"; + return NULL; } -FolderView* MainWindow::otherSideFolderView(const FolderView *view) const +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::inactiveModel +/// \return 非アクティブなフォルダモデルを返します。 +/// +FolderModel *MainWindow::inactiveModel() const { - qDebug() << "MainWindow::otherSideFolderView()"; + if (ui->LPanel->model()->isActive()) { + return ui->RPanel->model(); + } + Q_ASSERT(ui->RPanel->model()->isActive()); + return ui->LPanel->model(); +} - if (view == ui->pane1->folderPanel()->folderView()) { - return ui->pane2->folderPanel()->folderView(); +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::inactivePanel +/// \return 非アクティブモデルを所有している可視状態のパネルを返します。 +/// +Panel *MainWindow::inactivePanel() const +{ + if (ui->LPanel->model() == inactiveModel() && ui->LPanel->isVisible()) { + return ui->LPanel; } - else { - Q_ASSERT(view == ui->pane2->folderPanel()->folderView()); - return ui->pane1->folderPanel()->folderView(); + if (ui->RPanel->model() == inactiveModel() && ui->RPanel->isVisible()) { + return ui->RPanel; + } + if (ui->FPanel->model() == inactiveModel() && ui->FPanel->isVisible()) { + return ui->FPanel; } + + qDebug() << ">>>>>>>>>> inactivePanel() Logic error <<<<<<<<<<"; + return NULL; +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::selectedItems +/// \return マークされているアイテムまたはカレントアイテムのリスト +/// +QFileInfoList MainWindow::selectedItems() const +{ + QFileInfoList list = activeModel()->markedItems(); + if (list.isEmpty()) { + qDebug() << focusItemView(); + qDebug() << focusItemView()->currentIndex(); + Q_ASSERT(focusItemView()->currentIndex().isValid()); + list << activeModel()->fileInfo(focusItemView()->currentIndex()); + } + + return list; } -void MainWindow::setViewMode(ModeFlags flags) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::focusItemView +/// \return フォーカスを持つアイテムビュー +/// +QAbstractItemView *MainWindow::focusItemView() const { - qDebug() << "MainWindow::setViewMode();" << flags; - m_viewMode = flags; + return static_cast(qApp->focusWidget()); } -bool MainWindow::startProcess(const QString &cmd, const QString &workDir, const QString &errMsg) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::setViewMode +/// \param mode 新しいビューモード +/// +/// ビューモードを変更します。 +/// +void MainWindow::setViewMode(Mode mode) { - qDebug() << "MainWindow::startProcess" << cmd << workDir << errMsg; + qDebug() << "MainWindow::setViewMode()" << mode; + + QWidget *newFocusWidget = NULL; + + switch (mode) { + case ModeBasic: + ui->FPanel->setVisible(false); + ui->splitter->setVisible(true); + ui->LPanel->setViewItem(); + ui->RPanel->setViewItem(); + if (m_viewMode == ModeFull) { + activePanel()->folderPanel()->itemView()->setCurrentIndex( + focusItemView()->currentIndex()); + ui->FPanel->setModel(NULL); + } + newFocusWidget = activePanel()->folderPanel()->itemView(); + break; + + case ModeFull: + if (m_viewMode == ModeBasic) { + ui->FPanel->setModel(activeModel()); + ui->splitter->setVisible(false); + ui->FPanel->setVisible(true); + ui->FPanel->folderPanel()->itemView()->setCurrentIndex( + focusItemView()->currentIndex()); + } + ui->FPanel->setViewItem(); + newFocusWidget = activePanel()->folderPanel()->itemView(); + break; + + case ModeView: + ui->FPanel->setViewItem(focusItemView()->currentIndex()); + ui->splitter->setVisible(false); + ui->FPanel->setVisible(true); + newFocusWidget = ui->FPanel->visibleView(); + break; + + case ModePreview: + inactivePanel()->setViewItem(focusItemView()->currentIndex()); + break; + } + + m_prevMode = m_viewMode; + m_viewMode = mode; + + if (newFocusWidget) + newFocusWidget->setFocus(); + else + updateActions(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::startProcess +/// \param cmd 実行するコマンド +/// \param errMsg エラー時の表示メッセージ +/// \return true:成功, false:失敗 +/// +bool MainWindow::startProcess(const QString &cmd, const QString &errMsg) +{ + qDebug() << "MainWindow::startProcess" << cmd << errMsg; QProcess process(this); - process.setWorkingDirectory(workDir); + process.setWorkingDirectory(activeModel()->rootPath()); if (!process.startDetached(cmd)) { QMessageBox::critical(this, tr("エラー"), errMsg + "
" + cmd); return false; @@ -1576,11 +2017,160 @@ bool MainWindow::startProcess(const QString &cmd, const QString &workDir, const return true; } +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::updateActions +/// +/// アクションの有効/無効を設定します。 +/// void MainWindow::updateActions() { - qDebug() << "MainWindow::updateActions" << m_viewMode; + qDebug() << "MainWindow::updateActions"; + + bool isView = true; + bool isSearch = false; + bool isImageView = false; + bool toggleSearch = true; + QWidget *w = qApp->focusWidget(); + if (w->objectName() == "folderView" || w->objectName() == "thumbnailView") { + setEnabledAllActions(true); + + // 現在の選択アイテムが".."の場合、ファイル操作系アクションは無効にする + QFileInfoList list = selectedItems(); + if (list.size() == 1 && list[0].fileName() == "..") { + ui->action_Copy->setEnabled(false); + ui->action_Delete->setEnabled(false); + ui->action_Move->setEnabled(false); + ui->action_Rename->setEnabled(false); + } + + // 非二画面の場合、隣のパネルが必要な操作は無効にする + if (!ui->LPanel->folderPanel()->isVisible() || + !ui->RPanel->folderPanel()->isVisible()) + { + ui->action_Copy->setEnabled(false); + ui->action_Move->setEnabled(false); + ui->action_Swap->setEnabled(false); + ui->action_SyncPanel->setEnabled(false); + ui->action_SyncPanelTo->setEnabled(false); + } + + // 単画面の場合、プレビューモードは無効にする + if (m_viewMode == ModeFull) { + ui->toggle_PreviewMode->setEnabled(false); + } + + // サムネイル表示の場合、左右キーはカーソル移動 + if (w->objectName() == "thumbnailView") { + ui->action_KeyLeft->setEnabled(false); + ui->action_KeyRight->setEnabled(false); + } + } + else if (w->objectName() == "searchBox"){ + setEnabledAllActions(false); + isView = false; + isSearch = true; + } + else if (w->objectName() == "locationBox") { + setEnabledAllActions(false); + isView = false; + } + else if (w->objectName() == "textView") { + SimpleTextView *v = static_cast(w); + setEnabledAllActions(false); + toggleSearch = false; + + ui->text_ConvertFromEUC->setEnabled(true); + ui->text_ConvertFromEUC->disconnect(); + connect(ui->text_ConvertFromEUC, SIGNAL(triggered()), v, SLOT(convertFromEUC())); + + ui->text_ConvertFromJIS->setEnabled(true); + ui->text_ConvertFromJIS->disconnect(); + connect(ui->text_ConvertFromJIS, SIGNAL(triggered()), v, SLOT(convertFromJIS())); + + ui->text_ConvertFromSJIS->setEnabled(true); + ui->text_ConvertFromSJIS->disconnect(); + connect(ui->text_ConvertFromSJIS, SIGNAL(triggered()), v, SLOT(convertFromSJIS())); + + ui->text_ConvertFromUTF8->setEnabled(true); + ui->text_ConvertFromUTF8->disconnect(); + connect(ui->text_ConvertFromUTF8, SIGNAL(triggered()), v, SLOT(convertFromUTF8())); + + ui->text_ConvertFromUTF16->setEnabled(true); + ui->text_ConvertFromUTF16->disconnect(); + connect(ui->text_ConvertFromUTF16, SIGNAL(triggered()), v, SLOT(convertFromUTF16())); + + ui->text_ConvertFromUTF16BE->setEnabled(true); + ui->text_ConvertFromUTF16BE->disconnect(); + connect(ui->text_ConvertFromUTF16BE, SIGNAL(triggered()), v, SLOT(convertFromUTF16BE())); + + ui->text_ConvertFromUTF16LE->setEnabled(true); + ui->text_ConvertFromUTF16LE->disconnect(); + connect(ui->text_ConvertFromUTF16LE, SIGNAL(triggered()), v, SLOT(convertFromUTF16LE())); + + ui->text_Copy->disconnect(); + connect(ui->text_Copy, SIGNAL(triggered()), v, SLOT(copy())); + + } + else if (w->objectName() == "imageView") { + SimpleImageView *v = static_cast(w); + setEnabledAllActions(false); + toggleSearch = false; + isImageView = true; + + ui->image_FitToWindow->setEnabled(true); + ui->image_FitToWindow->disconnect(); + connect(ui->image_FitToWindow, SIGNAL(toggled(bool)), v, SLOT(fitToWindow(bool))); + + ui->image_ScaleNormal->setEnabled(true); + ui->image_ScaleNormal->disconnect(); + connect(ui->image_ScaleNormal, SIGNAL(triggered()), v, SLOT(scaleNormal())); + + ui->image_Rotate90->setEnabled(true); + ui->image_Rotate90->disconnect(); + connect(ui->image_Rotate90, SIGNAL(triggered()), v, SLOT(rotate90())); + + ui->image_Rotate180->setEnabled(true); + ui->image_Rotate180->disconnect(); + connect(ui->image_Rotate180, SIGNAL(triggered()), v, SLOT(rotate180())); + } + + ui->action_About->setEnabled(true); + ui->action_CheckUpdate->setEnabled(true); + ui->action_KeyDown->setEnabled(isView); + ui->action_KeyEnd->setEnabled(isView); + ui->action_KeyHome->setEnabled(isView); + ui->action_KeyUp->setEnabled(isView); + ui->action_Quit->setEnabled(true); + ui->action_ScaleDown->setEnabled(isView); + ui->action_ScaleUp->setEnabled(isView); + ui->action_SearchNext->setEnabled(isSearch); + ui->action_SearchPrev->setEnabled(isSearch); + ui->action_Setting->setEnabled(true); + ui->toggle_Search->setEnabled(toggleSearch); + ui->view_Back->setEnabled(m_viewMode == ModeView); + + if (isImageView) { + ui->action_ScaleDown->setText(tr("縮小")); + ui->action_ScaleUp->setText(tr("拡大")); + } + else { + ui->action_ScaleDown->setText(tr("文字を小さく")); + ui->action_ScaleUp->setText(tr("文字を大きく")); + } + + if (m_viewMode == ModeBasic || m_viewMode == ModeFull) { + ui->toggle_FullMode->setEnabled(true); + } + else { + ui->toggle_FullMode->setEnabled(false); + } + + ui->action_historyBack->setEnabled(!activeModel()->isHistoryBegin()); + ui->action_HistoryForward->setEnabled(!activeModel()->isHistoryEnd()); + +#if 0 FolderView *view; if ((view = qobject_cast(w))) { setEnabledAllActions(true); @@ -1589,14 +2179,14 @@ void MainWindow::updateActions() ui->action_SearchPrev->setEnabled(false); // 「開く」アクションを変更する - QFileInfo info(view->currentItem()); + QFileInfo info(activeModel()->fileInfo(view->currentIndex())); if (info.isDir()) { - ui->action_Open->setIcon(QIcon(":/images/Open.png")); + ui->action_Open->setIcon(QIcon("://images/Open.png")); ui->action_Open->setText(tr("開く")); ui->action_Open->setToolTip(tr("開く")); } else { - ui->action_Open->setIcon(QIcon(":/images/Search text.png")); + ui->action_Open->setIcon(QIcon("://images/Search text.png")); ui->action_Open->setText(tr("内蔵ビューアで開く")); ui->action_Open->setToolTip(tr("内蔵ビューアで開く")); @@ -1612,12 +2202,12 @@ void MainWindow::updateActions() } } - if (info.fileName() == ".." && view->checkedItems().isEmpty()) { + if (info.fileName() == ".." && activeModel()->markedItems().isEmpty()) { // ファイル操作を抑止 - ui->cmd_Copy->setEnabled(false); - ui->cmd_Delete->setEnabled(false); - ui->cmd_Move->setEnabled(false); - ui->cmd_Rename->setEnabled(false); + ui->action_Copy->setEnabled(false); + ui->action_Delete->setEnabled(false); + ui->action_Move->setEnabled(false); + ui->action_Rename->setEnabled(false); } if (m_viewMode & ModeBasic) { @@ -1625,8 +2215,8 @@ void MainWindow::updateActions() ui->action_SearchNext->setEnabled(false); ui->action_SearchPrev->setEnabled(false); - ui->move_Back->setEnabled(!view->history()->isBegin()); - ui->move_Forward->setEnabled(!view->history()->isEnd()); + ui->action_historyBack->setEnabled(!activeModel()->isHistoryBegin()); + ui->action_HistoryForward->setEnabled(!activeModel()->isHistoryEnd()); QSettings settings; ui->action_OpenEditor->setEnabled(!settings.value(IniKey_PathEditor).toString().isEmpty()); @@ -1635,19 +2225,19 @@ void MainWindow::updateActions() } else if (!otherSideFolderView(view)->isVisible()) { qDebug() << ">>>>> ハーフモードのメニュー設定 <<<<<"; - ui->view_FromOther->setEnabled(false); - ui->view_ToOther->setEnabled(false); - ui->cmd_Copy->setEnabled(false); - ui->cmd_Move->setEnabled(false); + ui->action_SyncPanel->setEnabled(false); + ui->action_SyncPanelTo->setEnabled(false); + ui->action_Copy->setEnabled(false); + ui->action_Move->setEnabled(false); } } else if (qobject_cast(w)) { qDebug() << ">>>>> 検索モードのメニュー設定 <<<<<"; setEnabledAllActions(false); - ui->action_Search->setEnabled(true); + ui->toggle_Search->setEnabled(true); ui->action_SearchNext->setEnabled(true); ui->action_SearchPrev->setEnabled(true); - ui->help_About->setEnabled(true); + ui->action_About->setEnabled(true); } else if (qobject_cast(w) || qobject_cast(w)) @@ -1656,54 +2246,66 @@ void MainWindow::updateActions() setEnabledAllActions(false); ui->action_Quit->setEnabled(true); ui->action_Setting->setEnabled(true); - ui->check_Update->setEnabled(true); + ui->action_CheckUpdate->setEnabled(true); ui->view_FontSizeDown->setEnabled(true); ui->view_FontSizeUp->setEnabled(true); - ui->move_Begin->setEnabled(true); - ui->move_Down->setEnabled(true); - ui->move_End->setEnabled(true); - ui->move_Up->setEnabled(true); - ui->help_About->setEnabled(true); + ui->action_KeyDown->setEnabled(true); + ui->action_KeyEnd->setEnabled(true); + ui->action_KeyHome->setEnabled(true); + ui->action_KeyUp->setEnabled(true); + ui->action_About->setEnabled(true); ui->key_Left->setEnabled(true); ui->key_Right->setEnabled(true); - if (m_viewMode & ModeHalfView) { + if (m_viewMode == ModePreview) { ui->view_HalfMode->setEnabled(true); } } +#endif } +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::setEnabledAllActions +/// \param enable 有効にする場合はtrue +/// +/// 全てのアクションを有効または無効にします。 +/// void MainWindow::setEnabledAllActions(bool enable) { - qDebug() << "MainWindow::setEnabledAllActions();" << enable; - foreach (QObject *obj, children()) { - QAction *action = qobject_cast(obj); - if (action) { - action->setEnabled(enable); - } + qDebug() << "MainWindow::setEnabledAllActions()" << enable; + foreach (QAction *action, findChildren()) { + action->setEnabled(enable); } } -void MainWindow::about() +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::onAbout +/// +/// Aboutダイアログを表示します。 +/// +void MainWindow::onAbout() { - qDebug() << ">>>>> about <<<<<"; - QMessageBox::about( this, tr("げふぅ について"), - tr("

Gefu Ver%1

").arg(VERSION_VALUE) + + qApp->applicationDisplayName() + tr("
Gefu is an Experimental File Utility.
" "(げふぅは実験的なファイルユーティリティです)
" - "

最新版の情報はプロジェクトサイトで公開しています。

" + "

最新版の情報は公式サイトで公開しています。

" "

Copyright 2014 @miyabi_satoh All rights reserved.

")); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::closeEvent +/// \param event クローズイベント +/// +/// 終了処理を行います。 +/// void MainWindow::closeEvent(QCloseEvent *event) { - qDebug() << "MainWindow::closeEvent();"; - qDebug() << ">>>>> アプリケーションの終了要求 <<<<<"; - QSettings settings; + qDebug() << "MainWindow::closeEvent()"; + Preferences prefs(this); - if (settings.value(IniKey_ConfirmExit).toBool()) { + if (prefs.isConfirmQuit()) { QMessageBox msgBox; QCheckBox *checkBox = new QCheckBox(); checkBox->setText(tr("次回以降は確認しない")); @@ -1717,31 +2319,40 @@ void MainWindow::closeEvent(QCloseEvent *event) event->ignore(); return; } - settings.setValue(IniKey_ConfirmExit, !checkBox->isChecked()); + prefs.setConfirmQuit(!checkBox->isChecked()); } - settings.setValue(QString("Left/") + IniKey_Dir, ui->pane1->folderPanel()->folderView()->dir()); - settings.setValue(QString("Right/") + IniKey_Dir, ui->pane2->folderPanel()->folderView()->dir()); - settings.setValue(IniKey_ShowHidden, ui->view_Hidden->isChecked()); - settings.setValue(IniKey_ShowSystem, ui->view_System->isChecked()); - settings.setValue(IniKey_WindowGeometry, saveGeometry()); - settings.setValue(iniKey_WindowState, saveState()); + prefs.saveModel("Left", ui->LPanel->model()); + prefs.saveModel("Right", ui->RPanel->model()); + prefs.saveWindow(this); QMainWindow::closeEvent(event); } - -void MainWindow::keyPressEvent(QKeyEvent *event) +/////////////////////////////////////////////////////////////////////////////// +/// \brief MainWindow::eventFilter +/// \param watched イベントの発生元オブジェクト +/// \param e 発生したイベント +/// \return イベントを処理した場合はtrueを返します。 +/// +bool MainWindow::eventFilter(QObject *watched, QEvent *e) { + switch (e->type()) { + case QEvent::KeyPress: + // キーイベントの処理 + return onKeyPressEvent(watched, static_cast(e)); - QString ksq = KeyEventToSequence(event); + case QEvent::ContextMenu: + // コンテキストメニューイベントの処理 + return onContextMenuEvent(watched, static_cast(e)); - qDebug() << ">>>>> キーイベントを受信(MainWindow)" << ksq << "<<<<<"; - qDebug() << qApp->keyboardModifiers().testFlag(Qt::ShiftModifier); + case QEvent::Drop: + qDebug() << "QEvent::Drop"; + // ドロップイベントの処理 + return onDropEvent(watched, static_cast(e)); - if (ProcessShortcut(ksq, this)) { - event->accept(); - return; + default: + break; } - QMainWindow::keyPressEvent(event); + return false; } diff --git a/mainwindow.h b/mainwindow.h index 484b908..bfef3e2 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -1,15 +1,17 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H +#include "overwritedialog.h" + #include #include +#include +#include #include -class QNetworkReply; -class OverWriteDialog; -class QLabel; + class FolderView; -class SearchBox; -class AnyView; +class FolderModel; +class Panel; namespace Ui { class MainWindow; @@ -27,121 +29,113 @@ public: ~MainWindow(); signals: - void showHiddenFiles(bool show); - void showSystemFiles(bool show); - -public slots: - void askOverWrite(QString *copyMethod, QString *alias, - const QString &srcPath, const QString &tgtPath); - void currentChange(const QFileInfo &info); - void dropAccept(const QFileInfoList &list, QDropEvent *event); - void focusChange(QWidget * old, QWidget * now); - void leftKeyPress(); - void rightKeyPress(); - void showFileInfo(const QString &str); +private slots: + void app_focusChange(QWidget *old, QWidget *now); + void checkUpdateFinished(QNetworkReply *reply, bool silent = false); + void checkUpdateFinishedSilent(QNetworkReply *reply); + void model_PreReset(); + void model_PostReset(); + void onAbout(); + void onCheckUpdate(bool silent = false); + void onChooseFolder(); + void onCopy(); + void onCopyFileName(); + void onCopyFilePath(); + void onCreateFile(); + void onCreateFolder(); + void onDelete(); + void onEditBookmark(); + void onExpandLeft(); + void onExpandRight(); + void onKeyDown(); + void onKeyDownOther(); + void onKeyEnd(); + void onKeyEndOther(); + void onKeyHome(); + void onKeyHomeOther(); + void onKeyLeft(); + void onKeyRight(); + void onKeyUp(); + void onKeyUpOther(); + void onMove(); + void onOpenArchiver(); + void onOpenBookmark(); + void onOpenEditor(const QModelIndex &index = QModelIndex()); + void onOpenTerminal(); + void onOpenWith(); + void onRename(); + void onRunCommand(); + void onScaleDown(); + void onScaleUp(); + void onSearchNext(); + void onSearchPrev(); + void onSplitCenter(); + void onSwap(); + void onSyncPanel(); + void onSyncPanelTo(); + void onToggleFullMode(bool checked); + void onToggleHidden(bool checked); + void onToggleMark(); + void onTogglePreviewMode(bool checked); + void onToggleSearch(bool checked); + void onToggleSystem(bool checked); + void onToggleThumbnailMode(bool checked); + void showBookmarkDialog(); + void showFilterDialog(); + void showHistoryDialog(); + void showPreferenceDialog(); + void showSortDialog(); - void about(); - void checkUpdate(bool silent = false); - void checkUpdateFinished(QNetworkReply *reply, bool silent = false); - void checkUpdateFinishedSilent(QNetworkReply *reply); - void chooseFolder(); - void copyFilenameToClipboard(); - void copyFullpathTpClipboard(); - void copyItems(); - void createFile(); - void createFolder(); - void cursorDown(); - void cursorUp(); - void cursorDownOther(); - void cursorUpOther(); - void deleteItems(); - void editBookmark(); - void executeCommand(); - void expandLeft(); - void expandRight(); - void historyBack(); - void historyForward(); - void markAll(); - void markAllFiles(); - void markAllOff(); - void markInvert(); - void markToggle(); - void moveItems(); - void open(const QModelIndex &index = QModelIndex()); - void openEditor(const QString &path = QString()); - void openTerminal(); - void openArchiver(); - void openBookmark(); - void refresh(); - void renameItems(); - void searchNext(); - void searchPrev(); - void setCursorToBegin(); - void setCursorToEnd(); - void setCursorToBeginOther(); - void setCursorToEndOther(); - void setFontSizeDown(); - void setFontSizeUp(); - void setPathFromOther(); - void setPathToHome(); - void setPathToOther(); - void setPathToParent(); - void setPathToRoot(); - void shellExecute(); - void showBookmarkDialog(); - void showFilterDialog(); - void showHistoryDialog(); - void showPreferenceDialog(); - void showSortDialog(); - void splitCenter(); - void swapView(); - void switchHalfMode(bool checked); - void toggleSearchBox(bool checked); - void toggleShowHiddenFiles(bool checked); - void toggleShowSystemFiles(bool checked); - - void showContextMenu(QContextMenuEvent *event); - - void viewFinish(); +public slots: + void askOverWrite(QString *copyMethod, QString *alias, + const QString &srcPath, const QString &tgtPath); + void onAddBookmark(); + void onOpen(const QModelIndex &index = QModelIndex()); + void view_copyAvailable(bool yes); + void view_currentChanged(const QModelIndex & current, const QModelIndex & previous); + void view_finished(); + void view_statusChanged(const QString &text); private: enum Mode { - ModeBasic = 0x01, - ModeSearch = 0x02, - ModeFullView = 0x04, - ModeHalfView = 0x08, + ModeBasic, // 二画面モード + ModeFull, // 単画面モード + ModeView, // ビューモード + ModePreview, // プレビューモード }; - typedef QFlags ModeFlags; - Ui::MainWindow *ui; - FolderView *m_activeView; - OverWriteDialog *m_overwriteDialog; - ModeFlags m_viewMode; - - // action - void initActionConnections(); - static void replaceVars(QString &str, const QFileInfo info); - bool startProcess(const QString &cmd, const QString &workDir, const QString &errMsg); - void updateActions(); - void setEnabledAllActions(bool enable); - void showNameFilters(FolderView *view); - void copyItems(const QFileInfoList &list, const QString &tgtDir); - void moveItems(const QFileInfoList &list, const QString &tgtDir); - void changeFontSize(int diff); - void initBookmark(); - void sendEventOther(QEvent *event); - - // getter - FolderView* otherSideFolderView(const FolderView *view) const; - - // setter - void setViewMode(ModeFlags flags); + OverWriteDialog m_overwriteDialog; + Mode m_viewMode; + Mode m_prevMode; + + FolderModel* activeModel() const; + Panel* activePanel() const; + void copyItems(const QFileInfoList &list, const QString &tgtDir); + QAbstractItemView* focusItemView() const; + FolderModel* inactiveModel() const; + Panel* inactivePanel() const; + void initActions(); + void initBookmarkMenu(); + void moveItems(const QFileInfoList &list, const QString &tgtDir); + bool onContextMenuEvent(QObject *obj, QContextMenuEvent *e); + bool onDropEvent(QObject *obj, QDropEvent *e); + bool onKeyPressEvent(QObject *obj, QKeyEvent *e); + QFileInfoList selectedItems() const; + void sendEventOther(QEvent *event); + void setActiveModel(FolderModel *m); + void setEnabledAllActions(bool enable); + void setViewMode(Mode mode); + bool startProcess(const QString &cmd, const QString &errMsg); + void updateActions(); // QWidget interface protected: void closeEvent(QCloseEvent *event); - void keyPressEvent(QKeyEvent *event); + + // QObject interface +public: + bool eventFilter(QObject *watched, QEvent *e); }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index d0138cd..8a44a8c 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 656 - 133 + 669 + 433
@@ -19,38 +19,32 @@ + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + Qt::Horizontal - - - - 0 - 0 - - - - - - - 0 - 0 - - - + + - - - - 0 - 0 - - - + @@ -70,27 +64,29 @@ false - + - - - + + + - - - + + + + + - - - - - + + + + + - - + + - + @@ -98,7 +94,7 @@ 0 0 - 656 + 669 22 @@ -106,14 +102,13 @@ ファイル(&F) - - + - + - + @@ -125,91 +120,92 @@ マーク(&M) - - - - - + + + + 表示(&V) - - - - - + + + + + + + - - + + - - + + - - + + 移動(&E) - - - + + + - - - - + + + + - - - - + + + + - - - - + + + + 操作(&O) - - - + + + - + - - + + - - + + ヘルプ(&H) - - + + ブックマーク(&B) - + パネル(&P) - - - + + + @@ -220,6 +216,17 @@ + + + toolBar + + + TopToolBarArea + + + false + + @@ -253,7 +260,7 @@ Return - + :/images/Play.png:/images/Play.png @@ -268,9 +275,11 @@ Shift+Return - + - + + + 隣のパネルと同じフォルダを表示 @@ -279,7 +288,7 @@ O - + 隣のパネルに同じフォルダを表示 @@ -290,7 +299,7 @@ Shift+O - + マーク/解除 @@ -301,7 +310,7 @@ Space - + :/images/Ok.png:/images/Ok.png @@ -316,7 +325,7 @@ Shift+A - + :/images/Check boxes.png:/images/Check boxes.png @@ -331,7 +340,7 @@ A - + :/images/Cancel.png:/images/Cancel.png @@ -346,7 +355,7 @@ U - + マークを反転 @@ -357,7 +366,7 @@ I - + :/images/Flip.png:/images/Flip.png @@ -390,7 +399,7 @@ QAction::PreferencesRole - + true @@ -404,7 +413,7 @@ Shift+H - + ソート方法... @@ -415,7 +424,7 @@ S - + :/images/Go down.png:/images/Go down.png @@ -430,7 +439,7 @@ J - + :/images/Go up.png:/images/Go up.png @@ -445,7 +454,7 @@ K - + :/images/Back.png:/images/Back.png @@ -460,7 +469,7 @@ [ - + :/images/Forward.png:/images/Forward.png @@ -475,7 +484,7 @@ ] - + 履歴... @@ -486,7 +495,7 @@ R - + :/images/Up.png:/images/Up.png @@ -501,7 +510,7 @@ Backspace - + :/images/Monitor.png:/images/Monitor.png @@ -516,7 +525,7 @@ Shift+Backspace - + :/images/Folder.png:/images/Folder.png @@ -531,7 +540,7 @@ G - + :/images/Home.png:/images/Home.png @@ -546,7 +555,7 @@ H - + カーソルを先頭に @@ -557,7 +566,7 @@ Shift+J - + カーソルを末尾に @@ -583,7 +592,7 @@ E - + :/images/Export.png:/images/Export.png @@ -598,7 +607,7 @@ X - + :/images/Copy.png:/images/Copy.png @@ -613,7 +622,7 @@ Ctrl+C - + :/images/Paste.png:/images/Paste.png @@ -625,7 +634,7 @@ Ctrl+M - + :/images/Close file.png:/images/Close file.png @@ -640,7 +649,7 @@ Ctrl+D - + :/images/Rename.png:/images/Rename.png @@ -655,7 +664,7 @@ Ctrl+R - + :/images/New file.png:/images/New file.png @@ -670,7 +679,7 @@ Ctrl+E - + :/images/Add folder.png:/images/Add folder.png @@ -685,7 +694,7 @@ Ctrl+K - + :/images/Help.png:/images/Help.png @@ -703,7 +712,7 @@ QAction::AboutRole - + true @@ -717,7 +726,7 @@ Shift+S - + :/images/Refresh.png:/images/Refresh.png @@ -747,7 +756,7 @@ > - + :/images/Funnel.png:/images/Funnel.png @@ -762,7 +771,7 @@ * - + アップデートを確認 @@ -773,7 +782,7 @@ Shift+Z - + ファイル名をクリップボードにコピー @@ -784,7 +793,7 @@ C - + フルパス名をクリップボードにコピー @@ -795,7 +804,7 @@ Shift+C - + true @@ -835,7 +844,7 @@ Shift+Return - + :/images/Zoom in.png:/images/Zoom in.png @@ -850,7 +859,7 @@ + - + :/images/Zoom out.png:/images/Zoom out.png @@ -865,51 +874,39 @@ - - + - 隣ペインのカーソルを上に - - - 隣ペインのカーソルを上に + 隣パネルのカーソルを上に Shift+Up - + - 隣ペインのカーソルを下に - - - 隣ペインのカーソルを下に + 隣パネルのカーソルを下に Shift+Down - + - 隣ペインのカーソルを先頭に - - - 隣ペインのカーソルを先頭に + 隣パネルのカーソルを先頭に Alt+Up - + - 隣ペインのカーソルを末尾に - - - 隣ペインのカーソルを末尾に + 隣パネルのカーソルを末尾に Alt+Down - + key_Left @@ -917,7 +914,7 @@ Left - + key_Right @@ -925,7 +922,7 @@ Right - + true @@ -943,7 +940,7 @@ P - + ブックマークを編集... @@ -954,7 +951,7 @@ Shift+B - + ブックマークを表示 @@ -962,7 +959,7 @@ B - + 中央で分割 @@ -973,7 +970,7 @@ Shift+Space - + 左パネルを拡大 @@ -984,7 +981,7 @@ Shift+Right - + 右パネルを拡大 @@ -1010,13 +1007,162 @@ Shift+U + + + EUC-JPで再読込 + + + Ctrl+E + + + + + ISO 2022-JP(JIS)で再読込 + + + Ctrl+J + + + + + Shift-JISで再読込 + + + Ctrl+S + + + + + UTF-8で再読込 + + + Ctrl+U + + + + + UTF-16で再読込 + + + Ctrl+I + + + + + UTF-16BEで再読込 + + + Ctrl+O + + + + + UTF-16LEで再読込 + + + Ctrl+P + + + + + 選択範囲をクリップボードにコピー + + + Ctrl+C + + + + + 戻る + + + Return + + + + + true + + + ウィンドウにフィット + + + Space + + + + + 等倍 + + + = + + + + + 右に90度回転 + + + 9 + + + + + 右に180度回転 + + + 0 + + + + + + :/images/Favourites.png:/images/Favourites.png + + + 現在のフォルダをブックマークに追加 + + + Ctrl+B + + + + + true + + + + :/images/windows_fullscreen.png:/images/windows_fullscreen.png + + + 単画面モード + + + , + + + + + true + + + + :/images/Pictures.png:/images/Pictures.png + + + サムネイルモード + + + . + + - AnyView + Panel QWidget -
anyview.h
+
panel.h
1
diff --git a/operationdialog.cpp b/operationdialog.cpp index 839952a..13a29d4 100644 --- a/operationdialog.cpp +++ b/operationdialog.cpp @@ -1,4 +1,3 @@ -#include "common.h" #include "mainwindow.h" #include "operationdialog.h" #include "ui_operationdialog.h" diff --git a/overwritedialog.cpp b/overwritedialog.cpp index a44bd47..9aa56c1 100644 --- a/overwritedialog.cpp +++ b/overwritedialog.cpp @@ -1,11 +1,10 @@ -#include "common.h" +#include "preferences.h" #include "overwritedialog.h" #include "ui_overwritedialog.h" #include #include #include -#include OverWriteDialog::OverWriteDialog(QWidget *parent) : QDialog(parent), @@ -32,9 +31,8 @@ OverWriteDialog::~OverWriteDialog() void OverWriteDialog::reset() { - QSettings settings; - QString method = settings.value(IniKey_DefaultOnCopy).toString(); - QRadioButton *radio = findChild(method); + QString method = Preferences(this).getCopyBehavior(); + QRadioButton *radio = findChild("rb" + method); if (radio == NULL) { radio = ui->rbOverWriteIfNew; } diff --git a/panel.cpp b/panel.cpp new file mode 100644 index 0000000..c39332f --- /dev/null +++ b/panel.cpp @@ -0,0 +1,173 @@ +#include "foldermodel.h" +#include "folderview.h" +#include "mainwindow.h" +#include "preferences.h" +#include "panel.h" +#include "ui_panel.h" + +#include + +/////////////////////////////////////////////////////////////////////////////// +/// \brief Panel::Panel +/// \param parent 親ウィジェット +/// +/// コンストラクタ +/// +Panel::Panel(QWidget *parent) : + QWidget(parent), + ui(new Ui::Panel) +{ + ui->setupUi(this); + ui->imageView->setVisible(false); + ui->textView->setVisible(false); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief Panel::~Panel +/// +/// デストラクタ +/// +Panel::~Panel() +{ + delete ui; +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief Panel::folderPanel +/// \return フォルダパネルを返します。 +/// +FolderPanel *Panel::folderPanel() const +{ + return ui->folderPanel; +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief Panel::initialize +/// \param w メインウィンドウオブジェクト +/// +/// パネルを初期化します。 +/// +void Panel::initialize(MainWindow *w) +{ + qDebug() << "Panel::initialize()"; + + ui->imageView->initialize(w); + ui->folderPanel->initialize(w); + ui->textView->initialize(w); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief Panel::model +/// \return フォルダモデルを返します。 +/// +FolderModel *Panel::model() const +{ + return ui->folderPanel->model(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief Panel::setModel +/// \param m 設定するモデル +/// +/// モデルを設定します。 +/// +void Panel::setModel(FolderModel *m) +{ + qDebug() << "Panel::setModel()"; + + ui->folderPanel->setModel(m); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief Panel::setViewItem +/// \param index 設定するアイテムのインデックス +/// +/// ビューにアイテムを設定し、表示します。 +/// +void Panel::setViewItem(const QModelIndex &index) +{ + qDebug() << "Panel::setViewItem()" << index; + + if (!index.isValid()) { + ui->imageView->setVisible(false); + ui->textView->setVisible(false); + ui->folderPanel->setVisible(true); + return; + } + + const FolderModel *m = static_cast(index.model()); + QString path = m->filePath(index); + if (m->isDir(index)) { + model()->setRootPath(path); + ui->imageView->setVisible(false); + ui->textView->setVisible(false); + ui->folderPanel->setVisible(true); + return; + } + + QPixmap pixmap(path); + if (!pixmap.isNull()) { + ui->imageView->setSource(pixmap); + ui->folderPanel->setVisible(false); + ui->textView->setVisible(false); + ui->imageView->setVisible(true); + return; + } + + QFile file(path); + QByteArray data; + if (file.open(QIODevice::ReadOnly)) { + data = file.readAll(); + file.close(); + } + + ui->textView->setSource(data); + ui->folderPanel->setVisible(false); + ui->imageView->setVisible(false); + ui->textView->setVisible(true); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief Panel::updateAppearance +/// +/// 外観を変更します。 +/// +void Panel::updateAppearance() +{ + qDebug() << "Panel::updateAppearance()"; + + Preferences prefs(this); + QPalette pal; + + pal = ui->imageView->palette(); + pal.setColor(QPalette::Base, prefs.getImageViewBgColor()); + ui->imageView->setPalette(pal); + + pal = ui->textView->palette(); + pal.setColor(QPalette::Base, prefs.getTextViewBgColor()); + pal.setColor(QPalette::Text, prefs.getTextViewFgColor()); + ui->textView->setPalette(pal); + ui->textView->setFont(prefs.getTextViewFont()); + + ui->folderPanel->updateAppearance(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief Panel::visibleView +/// \return 可視状態のビューを返します。 +/// +QWidget *Panel::visibleView() const +{ + if (ui->textView->isVisible()) { + return ui->textView; + } + if (ui->imageView->isVisible()) { + return ui->imageView; + } + if (ui->folderPanel->isVisible()) { + return ui->folderPanel->itemView(); + } + + qDebug() << ">>>>>>>>>> visibleView() Logic error <<<<<<<<<<"; + return NULL; +} diff --git a/panel.h b/panel.h new file mode 100644 index 0000000..d10cb2c --- /dev/null +++ b/panel.h @@ -0,0 +1,34 @@ +#ifndef PANEL_H +#define PANEL_H + +#include +#include +class MainWindow; +class FolderPanel; +class FolderModel; + +namespace Ui { +class Panel; +} + +class Panel : public QWidget +{ + Q_OBJECT + +public: + explicit Panel(QWidget *parent = 0); + ~Panel(); + + FolderPanel* folderPanel() const; + void initialize(MainWindow *w); + FolderModel* model() const; + void setModel(FolderModel *m); + void setViewItem(const QModelIndex &index = QModelIndex()); + void updateAppearance(); + QWidget* visibleView() const; + +private: + Ui::Panel *ui; +}; + +#endif // PANEL_H diff --git a/anyview.ui b/panel.ui similarity index 70% rename from anyview.ui rename to panel.ui index f9ce915..7d3d7b2 100644 --- a/anyview.ui +++ b/panel.ui @@ -1,7 +1,7 @@ - AnyView - + Panel + 0 @@ -31,48 +31,32 @@ - - false - - - true - - - true - - Simple Text View + TextView - + - - - - 0 - 0 - - - + - SimpleTextView - QPlainTextEdit -
simpletextview.h
-
- FolderPanel QWidget
folderpanel.h
1
+ SimpleTextView + QPlainTextEdit +
simpletextview.h
+
+ SimpleImageView QGraphicsView
simpleimageview.h
diff --git a/preferencedialog.cpp b/preferencedialog.cpp index 1a6a2e7..075da0e 100644 --- a/preferencedialog.cpp +++ b/preferencedialog.cpp @@ -1,164 +1,92 @@ -#include "colorsamplemodel.h" -#include"common.h" +#include "global.h" +#include "preferences.h" #include "preferencedialog.h" #include "ui_preferencedialog.h" -#include #include -#include #include #include #include -#include #include +#include PreferenceDialog::PreferenceDialog(QWidget *parent) : QDialog(parent), - ui(new Ui::PreferenceDialog), - m_model(), - m_colorMap() + ui(new Ui::PreferenceDialog) { - m_model.setColorMap(&m_colorMap); - ui->setupUi(this); ui->tabWidget->setCurrentIndex(0); - // アドレスボックスの外観サンプル - ui->sampleEdit->setText(QDir::homePath()); - // ファイルビューの外観サンプル - ui->sampleTable->setModel(&m_model); - - QHeaderView *header; - header = ui->sampleTable->horizontalHeader(); - header->setSectionResizeMode(0, QHeaderView::Stretch); - header->setSectionResizeMode(1, QHeaderView::ResizeToContents); - header->setSectionResizeMode(2, QHeaderView::ResizeToContents); - header = ui->sampleTable->verticalHeader(); - header->setDefaultSectionSize(header->defaultSectionSize() * 0.75); - - // シグナル&スロット - connect(ui->bootSize, SIGNAL(toggled(bool)), this, SLOT(setControlsEnabled(bool))); - connect(ui->sizeAbsolute, SIGNAL(toggled(bool)), this, SLOT(setControlsEnabled(bool))); - connect(ui->sizeRelative, SIGNAL(toggled(bool)), this, SLOT(setControlsEnabled(bool))); - connect(ui->bootPos, SIGNAL(toggled(bool)), this, SLOT(setControlsEnabled(bool))); - connect(ui->posAbsolute, SIGNAL(toggled(bool)), this, SLOT(setControlsEnabled(bool))); - connect(ui->posRelative, SIGNAL(toggled(bool)), this, SLOT(setControlsEnabled(bool))); - - connect(ui->boxClrBg, SIGNAL(clicked()), this, SLOT(selectBoxColor())); - connect(ui->boxClrFg, SIGNAL(clicked()), this, SLOT(selectBoxColor())); - connect(ui->chooseBoxFont, SIGNAL(clicked()), this, SLOT(chooseFont())); - - connect(ui->clrBgMark, SIGNAL(clicked()), this, SLOT(selectViewColor())); - connect(ui->clrBgNormal, SIGNAL(clicked()), this, SLOT(selectViewColor())); - connect(ui->clrFgHidden, SIGNAL(clicked()), this, SLOT(selectViewColor())); - connect(ui->clrFgMark, SIGNAL(clicked()), this, SLOT(selectViewColor())); - connect(ui->clrFgNormal, SIGNAL(clicked()), this, SLOT(selectViewColor())); - connect(ui->clrFgReadonly, SIGNAL(clicked()), this, SLOT(selectViewColor())); - connect(ui->clrFgSystem, SIGNAL(clicked()), this, SLOT(selectViewColor())); - connect(ui->chooseViewFont, SIGNAL(clicked()), this, SLOT(chooseFont())); + ui->lBoxSample->setText(QDir::homePath()); + + connect(ui->fvNormal, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->fvNormalBg, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->fvMarked, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->fvMarkedBg, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->fvSystem, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->fvHidden, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->fvReadOnly, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->lBoxBg, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->lBoxFg, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->sBoxNormal, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->sBoxNormalBg, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->sBoxUnmatch, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->sBoxUnmatchBg, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->tvBg, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->tvFg, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->gvBg, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->allBg, SIGNAL(clicked()), this, SLOT(chooseColor())); + connect(ui->allFg, SIGNAL(clicked()), this, SLOT(chooseColor())); + + connect(ui->fvFont, SIGNAL(clicked()), this, SLOT(chooseFont())); + connect(ui->lBoxFont, SIGNAL(clicked()), this, SLOT(chooseFont())); + connect(ui->sBoxFont, SIGNAL(clicked()), this, SLOT(chooseFont())); + connect(ui->tvFont, SIGNAL(clicked()), this, SLOT(chooseFont())); + connect(ui->allFont, SIGNAL(clicked()), this, SLOT(chooseFont())); + + connect(ui->browseArchiver, SIGNAL(clicked()), this, SLOT(choosePath())); + connect(ui->browseEditor, SIGNAL(clicked()), this, SLOT(choosePath())); + connect(ui->browseTerminal, SIGNAL(clicked()), this, SLOT(choosePath())); - connect(ui->importAppearance, SIGNAL(clicked()), this, SLOT(importAppearance())); connect(ui->exportAppearance, SIGNAL(clicked()), this, SLOT(exportAppearance())); + connect(ui->importAppearance, SIGNAL(clicked()), this, SLOT(importAppearance())); - connect(ui->browseArchiver, SIGNAL(clicked()), this, SLOT(browseApp())); - connect(ui->browseEditor, SIGNAL(clicked()), this, SLOT(browseApp())); - connect(ui->browseTerminal, SIGNAL(clicked()), this, SLOT(browseApp())); - - connect(ui->chooseViewerFont, SIGNAL(clicked()), this, SLOT(chooseFont())); - connect(ui->viewerClrBg, SIGNAL(clicked()), this, SLOT(selectViewerColor())); - connect(ui->viewerClrFg, SIGNAL(clicked()), this, SLOT(selectViewerColor())); - connect(ui->viewerInherit, SIGNAL(toggled(bool)), this, SLOT(setControlsEnabled(bool))); - connect(ui->enableViewerIgnoreExt, SIGNAL(toggled(bool)), this, SLOT(setControlsEnabled(bool))); - connect(ui->defaultIgnoreExt, SIGNAL(clicked()), this, SLOT(setIgnoreExtDefault())); - - // 現在の設定で各コントロールを初期化する - QSettings settings; - QString strValue; - QSize size; - QPoint point; - QRadioButton *radioBtn; - - //>>>>> 起動と終了 - // 起動時のサイズ - ui->bootSize->setChecked(true); - strValue = settings.value(IniKey_BootSizeSpec).toString(); - radioBtn = findChild(strValue); - if (radioBtn == NULL) { - radioBtn = ui->sizeRelative; - } - radioBtn->setChecked(true); - if (strValue.isEmpty()) { - ui->bootSize->setChecked(false); - } - size = settings.value(IniKey_BootSizeAbs).toSize(); - ui->absoluteWidth->setValue(size.width()); - ui->absoluteHeight->setValue(size.height()); - size = settings.value(IniKey_BootSizeRel).toSize(); - ui->relativeWidth->setValue(size.width()); - ui->relativeHeight->setValue(size.height()); - // 起動時の位置 - ui->bootPos->setChecked(true); - strValue = settings.value(IniKey_BootPosSpec).toString(); - radioBtn = findChild(strValue); - if (radioBtn == NULL) { - radioBtn = ui->posCenter; - } - radioBtn->setChecked(true); - if (strValue.isEmpty()) { - ui->bootPos->setChecked(false); - } - point = settings.value(IniKey_BootPosAbs).toPoint(); - ui->absoluteLeft->setValue(point.x()); - ui->absoluteTop->setValue(point.y()); - point = settings.value(IniKey_BootPosRel).toPoint(); - ui->relativeLeft->setValue(point.x()); - ui->relativeTop->setValue(point.y()); - // 起動時の設定削除 - ui->resetOnBoot->setChecked(settings.value(IniKey_ResetOnBoot).toBool()); - // アップデートの確認 - ui->checkUpdates->setChecked(settings.value(IniKey_CheckUpdates).toBool()); - // 終了時の確認ダイアログ - ui->confirmExit->setChecked(settings.value(IniKey_ConfirmExit).toBool()); - - //>>>>> 色とフォント、テキストビューア - loadAppearance(settings, false); - ui->dark->setValue(settings.value(IniKey_Darkness).toInt()); - - //>>>>> ファイル操作 - // 確認ダイアログの表示 - ui->confirmCopy->setChecked(settings.value(IniKey_ConfirmCopy).toBool()); - ui->confirmDelete->setChecked(settings.value(IniKey_ConfirmDelete).toBool()); - ui->confirmMove->setChecked(settings.value(IniKey_ConfirmMove).toBool()); - ui->confirmRename->setChecked(settings.value(IniKey_ConfirmRename).toBool()); - // 完了ダイアログの自動クローズ - ui->autoCloseCopy->setChecked(settings.value(IniKey_AutoCloseCopy).toBool()); - ui->autoCloseDelete->setChecked(settings.value(IniKey_AutoCloseDelete).toBool()); - ui->autoCloseMove->setChecked(settings.value(IniKey_AutoCloseMove).toBool()); - ui->autoCloseRename->setChecked(settings.value(IniKey_AutoCloseRename).toBool()); - // 上書き時の既定動作 - strValue = settings.value(IniKey_DefaultOnCopy).toString(); - if (strValue.isEmpty()) { - strValue = "owDefIfNew"; - } - radioBtn = findChild(strValue); - if (radioBtn == NULL) { - radioBtn = ui->rbOverWriteIfNew; - } - radioBtn->setChecked(true); - ui->moveAfterCreate->setChecked(settings.value(IniKey_MoveAfterCreateFolder).toBool()); - ui->openAfterCreate->setChecked(settings.value(IniKey_OpenAfterCreateFile).toBool()); - - //>>>>> パス設定 - // エディタ - ui->editorPath->setText(settings.value(IniKey_PathEditor).toString()); - // ターミナル - ui->terminalPath->setText(settings.value(IniKey_PathTerminal).toString()); - // アーカイバ - ui->archiverPath->setText(settings.value(IniKey_PathArchiver).toString()); - - //>>>>> テキストビューア - ui->enableViewerIgnoreExt->setChecked(true); - ui->enableViewerIgnoreExt->setChecked(!settings.value(IniKey_ViewerForceOpen).toBool()); - ui->viewerIgnoreExt->setPlainText(settings.value(IniKey_ViewerIgnoreExt).toString()); + Preferences prefs(this); + + // [全般] + ui->checkUpdate->setChecked(prefs.isCheckUpdate()); + ui->confirmQuit->setChecked(prefs.isConfirmQuit()); + ui->moveAfterCreation->setChecked(prefs.isMoveAfterCreation()); + ui->openAfterCreation->setChecked(prefs.isOpenAfterCreation()); + ui->confirmCopy->setChecked(prefs.isConfirmCopy()); + ui->confirmMove->setChecked(prefs.isConfirmMove()); + ui->confirmDelete->setChecked(prefs.isConfirmDelete()); + ui->confirmRename->setChecked(prefs.isConfirmRename()); + ui->autoCloseCopy->setChecked(prefs.isAutoCloseCopy()); + ui->autoCloseMove->setChecked(prefs.isAutoCloseMove()); + ui->autoCloseDelete->setChecked(prefs.isAutoCloseDelete()); + ui->autoCloseRename->setChecked(prefs.isAutoCloseRename()); + QRadioButton *radio = findChild("rb" + prefs.getCopyBehavior()); + if (radio) + radio->setChecked(true); + else + ui->rbOverWriteIfNew->setChecked(true); + ui->preferExtensions->setPlainText(prefs.getPreferExtensions()); + + // [外観(色)] + loadAppearance(prefs); + + // [外観(フォント)] + setFont(ui->fvFontSpec, prefs.getFolderViewFont()); + setFont(ui->lBoxFontSpec, prefs.getLocationBoxFont()); + setFont(ui->sBoxFontSpec, prefs.getSearchBoxFont()); + setFont(ui->tvFontSpec, prefs.getTextViewFont()); + + ui->lineHeight->setValue(prefs.getLineHeight()); + + // [プログラムパス] + ui->editorPath->setText(prefs.getEditorPath()); + ui->terminalPath->setText(prefs.getTerminalPath()); + ui->archiverPath->setText(prefs.getArchiverPath()); } PreferenceDialog::~PreferenceDialog() @@ -166,273 +94,263 @@ PreferenceDialog::~PreferenceDialog() delete ui; } -void PreferenceDialog::saveAppearance(QSettings &settings) +void PreferenceDialog::loadAppearance(Preferences &prefs) { - QFont font = ui->sampleEdit->font(); - QPalette palette = ui->sampleEdit->palette(); - settings.setValue(IniKey_BoxColorBg, palette.base().color()); - settings.setValue(IniKey_BoxColorFg, palette.text().color()); - settings.setValue(IniKey_BoxFont, font); - - settings.setValue(IniKey_ViewColorBgMark, m_colorMap["clrBgMark"]); - settings.setValue(IniKey_ViewColorBgNormal, m_colorMap["clrBgNormal"]); - settings.setValue(IniKey_ViewColorFgHidden, m_colorMap["clrFgHidden"]); - settings.setValue(IniKey_ViewColorFgMark, m_colorMap["clrFgMark"]); - settings.setValue(IniKey_ViewColorFgNormal, m_colorMap["clrFgNormal"]); - settings.setValue(IniKey_ViewColorFgReadonly, m_colorMap["clrFgReadonly"]); - settings.setValue(IniKey_ViewColorFgSystem, m_colorMap["clrFgSystem"]); - settings.setValue(IniKey_ViewFont, m_model.font()); -} + setPalette(ui->fvNormalSample, QPalette::Base, prefs.getFolderViewBgColor()); + setPalette(ui->fvNormalSample, QPalette::Text, prefs.getFolderViewFgColor()); -void PreferenceDialog::loadAppearance(QSettings &settings, bool import) -{ - QPalette palette; - QColor color; - QFont font; + setPalette(ui->fvMarkedSample, QPalette::Base, prefs.getFolderViewMarkedBgColor()); + setPalette(ui->fvMarkedSample, QPalette::Text, prefs.getFolderViewMarkedFgColor()); - //>>>> アドレスボックス - palette = QPalette(); - // 背景色 - color = settings.value(IniKey_BoxColorBg).value(); - palette.setColor(QPalette::Base, color); - // 文字色 - color = settings.value(IniKey_BoxColorFg).value(); - palette.setColor(QPalette::Text, color); - // フォント - font = settings.value(IniKey_BoxFont).value(); - ui->boxFont->setText(tr("%1, %2pt").arg(font.family()).arg(font.pointSize())); - // サンプル表示 - ui->sampleEdit->setPalette(palette); - ui->sampleEdit->setFont(font); - - //>>>> ファイルビュー - // 背景色 - color = settings.value(IniKey_ViewColorBgMark).value(); - m_colorMap["clrBgMark"] = color; - color = settings.value(IniKey_ViewColorBgNormal).value(); - m_colorMap["clrBgNormal"] = color; - // 文字色 - color = settings.value(IniKey_ViewColorFgHidden).value(); - m_colorMap["clrFgHidden"] = color; - color = settings.value(IniKey_ViewColorFgMark).value(); - m_colorMap["clrFgMark"] = color; - color = settings.value(IniKey_ViewColorFgNormal).value(); - m_colorMap["clrFgNormal"] = color; - color = settings.value(IniKey_ViewColorFgReadonly).value(); - m_colorMap["clrFgReadonly"] = color; - color = settings.value(IniKey_ViewColorFgSystem).value(); - m_colorMap["clrFgSystem"] = color; - // フォント - font = settings.value(IniKey_ViewFont).value(); - ui->viewFont->setText(tr("%1, %2pt").arg(font.family()).arg(font.pointSize())); - // サンプル表示 - QHeaderView *header = ui->sampleTable->verticalHeader(); - header->setDefaultSectionSize(QFontMetrics(font).height() * 1.5); - ui->sampleTable->setMinimumHeight(header->sectionSize(0) * 5); - ui->sampleTable->setMaximumHeight(ui->sampleTable->minimumHeight() + 2); - m_model.setFont(font); - m_model.update(); - - //>>>> テキストビューア - // 文字色と背景色 - if (settings.value(IniKey_ViewerInherit).toBool()) { - ui->viewerInherit->setChecked(true); - color = settings.value(IniKey_ViewColorBgNormal).value(); - palette.setColor(QPalette::Base, color); - color = settings.value(IniKey_ViewColorFgNormal).value(); - palette.setColor(QPalette::Text, color); - } - else if (!import){ - ui->viewerInherit->setChecked(false); - color = settings.value(IniKey_ViewerColorBg).value(); - palette.setColor(QPalette::Base, color); - color = settings.value(IniKey_ViewerColorFg).value(); - palette.setColor(QPalette::Text, color); - } - ui->viewerSample->setPalette(palette); - // フォント - if (!import) { - font = settings.value(IniKey_ViewerFont).value(); - ui->viewerFont->setText(tr("%1, %2pt").arg(font.family()).arg(font.pointSize())); - ui->viewerSample->setFont(font); - } + setPalette(ui->fvSystemSample, QPalette::Base, prefs.getFolderViewBgColor()); + setPalette(ui->fvSystemSample, QPalette::Text, prefs.getFolderViewSystemColor()); + + setPalette(ui->fvHiddenSample, QPalette::Base, prefs.getFolderViewBgColor()); + setPalette(ui->fvHiddenSample, QPalette::Text, prefs.getFolderViewHiddenColor()); + + setPalette(ui->fvReadOnlySample, QPalette::Base, prefs.getFolderViewBgColor()); + setPalette(ui->fvReadOnlySample, QPalette::Text, prefs.getFolderViewReadOnlyColor()); + + setPalette(ui->lBoxSample, QPalette::Base, prefs.getLocationBoxBgColor()); + setPalette(ui->lBoxSample, QPalette::Text, prefs.getLocationBoxFgColor()); + + setPalette(ui->sBoxNormalSample, QPalette::Base, prefs.getSearchBoxBgColor()); + setPalette(ui->sBoxNormalSample, QPalette::Text, prefs.getSearchBoxFgColor()); + + setPalette(ui->sBoxUnmatchSample, QPalette::Base, prefs.getSearchBoxUnmatchBgColor()); + setPalette(ui->sBoxUnmatchSample, QPalette::Text, prefs.getSearchBoxUnmatchFgColor()); + + setPalette(ui->tvSample, QPalette::Base, prefs.getTextViewBgColor()); + setPalette(ui->tvSample, QPalette::Text, prefs.getTextViewFgColor()); + + setPalette(ui->gvSample, QPalette::Base, prefs.getImageViewBgColor()); + + ui->darkFactor->setValue(prefs.getDarkFacotr()); } -void PreferenceDialog::chooseFont() +void PreferenceDialog::saveAppearance(Preferences &prefs) { - bool ok; - QFont font; - QLabel *label = NULL; + prefs.setFolderViewBgColor(ui->fvNormalSample->palette().base().color()); + prefs.setFolderViewFgColor(ui->fvNormalSample->palette().text().color()); - if (sender() == ui->chooseViewerFont) { - font = ui->viewerSample->font(); - } - else if (sender() == ui->chooseBoxFont) { - font = ui->sampleEdit->font(); - } - else if (sender() == ui->chooseViewFont) { - font = m_model.font(); - } + prefs.setFolderViewMarkedBgColor(ui->fvMarkedSample->palette().base().color()); + prefs.setFolderViewMarkedFgColor(ui->fvMarkedSample->palette().text().color()); - font = QFontDialog::getFont(&ok, font, this); + prefs.setFolderViewHiddenColor(ui->fvHiddenSample->palette().text().color()); + prefs.setFolderViewReadOnlyColor(ui->fvReadOnlySample->palette().text().color()); + prefs.setFolderViewSystemColor(ui->fvSystemSample->palette().text().color()); - if (sender() == ui->chooseViewerFont) { - ui->viewerSample->setFont(font); - label = ui->viewerFont; - } - else if (sender() == ui->chooseBoxFont) { - ui->sampleEdit->setFont(font); - label = ui->boxFont; - } - else if (sender() == ui->chooseViewFont) { - QHeaderView *header = ui->sampleTable->verticalHeader(); - header->setDefaultSectionSize(QFontMetrics(font).height() * 1.5); - ui->sampleTable->setMinimumHeight(header->sectionSize(0) * 5); - ui->sampleTable->setMaximumHeight(ui->sampleTable->minimumHeight() + 2); - m_model.setFont(font); - m_model.update(); - label = ui->viewFont; - } - label->setText(tr("%1, %2pt").arg(font.family()).arg(font.pointSize())); + prefs.setLocationBoxBgColor(ui->lBoxSample->palette().base().color()); + prefs.setLocationBoxFgColor(ui->lBoxSample->palette().text().color()); + + prefs.setSearchBoxBgColor(ui->sBoxNormalSample->palette().base().color()); + prefs.setSearchBoxFgColor(ui->sBoxNormalSample->palette().text().color()); + + prefs.setSearchBoxUnmatchBgColor(ui->sBoxUnmatchSample->palette().base().color()); + prefs.setSearchBoxUnmatchFgColor(ui->sBoxUnmatchSample->palette().text().color()); + + prefs.setTextViewBgColor(ui->tvSample->palette().base().color()); + prefs.setTextViewFgColor(ui->tvSample->palette().text().color()); + prefs.setImageViewBgColor(ui->gvSample->palette().base().color()); + + prefs.setDarkFacotr(ui->darkFactor->value()); } -void PreferenceDialog::setControlsEnabled(bool enabled) +void PreferenceDialog::setFont(QLabel *label, const QFont &font) { - if (sender() == ui->bootSize) { - ui->sizeAbsolute->setEnabled(enabled); - ui->sizeLast->setEnabled(enabled); - ui->sizeRelative->setEnabled(enabled); - if (enabled) { - emit ui->sizeAbsolute->toggled(ui->sizeAbsolute->isChecked()); - emit ui->sizeRelative->toggled(ui->sizeRelative->isChecked()); - } - else { - emit ui->sizeAbsolute->toggled(false); - emit ui->sizeRelative->toggled(false); - } - } - else if (sender() == ui->sizeAbsolute) { - ui->absoluteHeight->setEnabled(enabled); - ui->absoluteWidth->setEnabled(enabled); - } - else if (sender() == ui->sizeRelative) { - ui->relativeHeight->setEnabled(enabled); - ui->relativeWidth->setEnabled(enabled); - } - else if (sender() == ui->bootPos) { - ui->posAbsolute->setEnabled(enabled); - ui->posCenter->setEnabled(enabled); - ui->posLast->setEnabled(enabled); - ui->posRelative->setEnabled(enabled); - if (enabled) { - emit ui->posAbsolute->toggled(ui->posAbsolute->isChecked()); - emit ui->posRelative->toggled(ui->posRelative->isChecked()); - } - else { - emit ui->posAbsolute->toggled(false); - emit ui->posRelative->toggled(false); - } - } - else if (sender() == ui->posAbsolute) { - ui->absoluteLeft->setEnabled(enabled); - ui->absoluteTop->setEnabled(enabled); - } - else if (sender() == ui->posRelative) { - ui->relativeLeft->setEnabled(enabled); - ui->relativeTop->setEnabled(enabled); - } - else if (sender() == ui->viewerInherit) { - ui->viewerClrBg->setEnabled(!enabled); - ui->viewerClrFg->setEnabled(!enabled); - // サンプル表示も更新 - QPalette pal = ui->viewerSample->palette(); - if (enabled) { - pal.setColor(QPalette::Base, m_colorMap["clrBgNormal"]); - pal.setColor(QPalette::Text, m_colorMap["clrFgNormal"]); - } - else { - QSettings settings; - pal.setColor(QPalette::Base, settings.value(IniKey_ViewerColorBg).value()); - pal.setColor(QPalette::Text, settings.value(IniKey_ViewerColorFg).value()); - } - ui->viewerSample->setPalette(pal); - } - else if (sender() == ui->enableViewerIgnoreExt) { - ui->viewerIgnoreExt->setEnabled(enabled); - } + label->setFont(font); + label->setText(QString("%1, %2pt").arg(font.family()).arg(font.pointSize())); } -void PreferenceDialog::setIgnoreExtDefault() +void PreferenceDialog::setPalette(QWidget *w, QPalette::ColorRole role, const QColor &color) { - ui->viewerIgnoreExt->setPlainText(ViewerIgnoreExt()); + QPalette pal = w->palette(); + pal.setColor(role, color); + w->setPalette(pal); } -void PreferenceDialog::selectBoxColor() +void PreferenceDialog::chooseColor() { QColor color; - QPalette palette = ui->sampleEdit->palette(); - if (sender() == ui->boxClrBg) { - color = palette.background().color(); + + if (sender() == ui->fvNormal) { + color = ui->fvNormalSample->palette().text().color(); } - else if (sender() == ui->boxClrFg) { - color = palette.text().color(); + else if (sender() == ui->fvNormalBg) { + color = ui->fvNormalSample->palette().base().color(); } - - color = QColorDialog::getColor(color, this, tr("色選択")); - if (!color.isValid()) { - return; + else if (sender() == ui->fvMarked) { + color = ui->fvMarkedSample->palette().text().color(); } - - if (sender() == ui->boxClrBg) { - palette.setColor(QPalette::Base, color); + else if (sender() == ui->fvMarkedBg) { + color = ui->fvMarkedSample->palette().base().color(); } - else if (sender() == ui->boxClrFg) { - palette.setColor(QPalette::Text, color); + else if (sender() == ui->fvSystem) { + color = ui->fvSystemSample->palette().text().color(); + } + else if (sender() == ui->fvHidden) { + color = ui->fvHiddenSample->palette().text().color(); + } + else if (sender() == ui->fvReadOnly) { + color = ui->fvReadOnlySample->palette().text().color(); + } + else if (sender() == ui->lBoxBg) { + color = ui->lBoxSample->palette().base().color(); + } + else if (sender() == ui->lBoxFg) { + color = ui->lBoxSample->palette().text().color(); + } + else if (sender() == ui->sBoxNormal) { + color = ui->sBoxNormalSample->palette().text().color(); + } + else if (sender() == ui->sBoxNormalBg) { + color = ui->sBoxNormalSample->palette().base().color(); + } + else if (sender() == ui->sBoxUnmatch) { + color = ui->sBoxUnmatchSample->palette().text().color(); + } + else if (sender() == ui->sBoxUnmatchBg) { + color = ui->sBoxUnmatchSample->palette().base().color(); + } + else if (sender() == ui->tvBg) { + color = ui->tvSample->palette().base().color(); + } + else if (sender() == ui->tvFg) { + color = ui->tvSample->palette().text().color(); + } + else if (sender() == ui->gvBg) { + color = ui->gvSample->palette().base().color(); + } + else if (sender() == ui->allBg) { + color = ui->fvNormalSample->palette().base().color(); + } + else if (sender() == ui->allFg) { + color = ui->fvNormalSample->palette().text().color(); } - ui->sampleEdit->setPalette(palette); -} - -void PreferenceDialog::selectViewColor() -{ - const QString objName = sender()->objectName(); - QColor color = m_colorMap[objName]; - color = QColorDialog::getColor(color, this, tr("色選択")); + color = QColorDialog::getColor(color, this, tr("色を選択")); if (!color.isValid()) { return; } - m_colorMap[objName] = color; - m_model.update(); + QPalette pal; + if (sender() == ui->fvNormal) { + setPalette(ui->fvNormalSample, QPalette::Text, color); + } + else if (sender() == ui->fvNormalBg) { + setPalette(ui->fvNormalSample, QPalette::Base, color); + setPalette(ui->fvHiddenSample, QPalette::Base, color); + setPalette(ui->fvReadOnlySample, QPalette::Base, color); + setPalette(ui->fvSystemSample, QPalette::Base, color); + } + else if (sender() == ui->fvMarked) { + setPalette(ui->fvMarkedSample, QPalette::Text, color); + } + else if (sender() == ui->fvMarkedBg) { + setPalette(ui->fvMarkedSample, QPalette::Base, color); + } + else if (sender() == ui->fvSystem) { + setPalette(ui->fvSystemSample, QPalette::Text, color); + } + else if (sender() == ui->fvHidden) { + setPalette(ui->fvHiddenSample, QPalette::Text, color); + } + else if (sender() == ui->fvReadOnly) { + setPalette(ui->fvReadOnlySample, QPalette::Text, color); + } + else if (sender() == ui->lBoxBg) { + setPalette(ui->lBoxSample, QPalette::Base, color); + } + else if (sender() == ui->lBoxFg) { + setPalette(ui->lBoxSample, QPalette::Text, color); + } + else if (sender() == ui->sBoxNormal) { + setPalette(ui->sBoxNormalSample, QPalette::Text, color); + } + else if (sender() == ui->sBoxNormalBg) { + setPalette(ui->sBoxNormalSample, QPalette::Base, color); + } + else if (sender() == ui->sBoxUnmatch) { + setPalette(ui->sBoxUnmatchSample, QPalette::Text, color); + } + else if (sender() == ui->sBoxUnmatchBg) { + setPalette(ui->sBoxUnmatchSample, QPalette::Base, color); + } + else if (sender() == ui->tvBg) { + setPalette(ui->tvSample, QPalette::Base, color); + } + else if (sender() == ui->tvFg) { + setPalette(ui->tvSample, QPalette::Text, color); + } + else if (sender() == ui->gvBg) { + setPalette(ui->gvSample, QPalette::Base, color); + } + else if (sender() == ui->allBg) { + setPalette(ui->fvNormalSample, QPalette::Base, color); + setPalette(ui->fvHiddenSample, QPalette::Base, color); + setPalette(ui->fvReadOnlySample, QPalette::Base, color); + setPalette(ui->fvSystemSample, QPalette::Base, color); + setPalette(ui->lBoxSample, QPalette::Base, color); + setPalette(ui->sBoxNormalSample, QPalette::Base, color); + setPalette(ui->tvSample, QPalette::Base, color); + setPalette(ui->gvSample, QPalette::Base, color); + } + else if (sender() == ui->allFg) { + setPalette(ui->fvNormalSample, QPalette::Text, color); + setPalette(ui->lBoxSample, QPalette::Text, color); + setPalette(ui->sBoxNormalSample, QPalette::Text, color); + setPalette(ui->tvSample, QPalette::Text, color); + } } -void PreferenceDialog::selectViewerColor() +void PreferenceDialog::chooseFont() { - QColor color; - QPalette palette = ui->viewerSample->palette(); - if (sender() == ui->viewerClrBg) { - color = palette.background().color(); + QFont font; + if (sender() == ui->fvFont) { + font = ui->fvFontSpec->font(); + } + else if (sender() == ui->lBoxFont) { + font = ui->lBoxFontSpec->font(); } - else if (sender() == ui->viewerClrFg) { - color = palette.text().color(); + else if (sender() == ui->sBoxFont) { + font = ui->sBoxFontSpec->font(); + } + else if (sender() == ui->tvFont) { + font = ui->tvFontSpec->font(); + } + else if (sender() == ui->allFont) { + font = ui->fvFontSpec->font(); } - color = QColorDialog::getColor(color, this, tr("色選択")); - if (!color.isValid()) { + bool ok; + font = QFontDialog::getFont(&ok, font, this, tr("フォントを選択")); + + if (!ok) { return; } - if (sender() == ui->viewerClrBg) { - palette.setColor(QPalette::Base, color); + if (sender() == ui->fvFont) { + setFont(ui->fvFontSpec, font); + } + else if (sender() == ui->lBoxFont) { + setFont(ui->lBoxFontSpec, font); + } + else if (sender() == ui->sBoxFont) { + setFont(ui->sBoxFontSpec, font); } - else if (sender() == ui->viewerClrFg) { - palette.setColor(QPalette::Text, color); + else if (sender() == ui->tvFont) { + setFont(ui->tvFontSpec, font); + } + else if (sender() == ui->allFont) { + setFont(ui->fvFontSpec, font); + setFont(ui->lBoxFontSpec, font); + setFont(ui->sBoxFontSpec, font); + setFont(ui->tvFontSpec, font); } - ui->viewerSample->setPalette(palette); } -void PreferenceDialog::browseApp() +void PreferenceDialog::choosePath() { QStringList list = QStandardPaths::standardLocations( QStandardPaths::ApplicationsLocation); @@ -449,134 +367,94 @@ void PreferenceDialog::browseApp() this, tr("アプリケーションを選択"), list.at(0), tr("すべてのファイル (*)")); #endif - if (!path.isEmpty()) { - if (path.indexOf(" ") != -1) { - path = QQ(path); - } - - if (sender() == ui->browseEditor) { - ui->editorPath->setText(path); - } - else if (sender() == ui->browseTerminal) { - ui->terminalPath->setText(path); - } - else if (sender() == ui->browseArchiver) { - ui->archiverPath->setText(path); - } + if (path.isEmpty()) { + return; + } + + if (path.indexOf(" ") != -1) { + path = QQ(path); + } + + if (sender() == ui->browseEditor) { + ui->editorPath->setText(path); + } + else if (sender() == ui->browseTerminal) { + ui->terminalPath->setText(path); + } + else if (sender() == ui->browseArchiver) { + ui->archiverPath->setText(path); } } -void PreferenceDialog::importAppearance() +void PreferenceDialog::exportAppearance() { QStringList list = QStandardPaths::standardLocations( QStandardPaths::DocumentsLocation); - QString path = QFileDialog::getOpenFileName( - this, tr("ファイルを選択"), list.at(0), + QString path = QFileDialog::getSaveFileName( + this, tr("ファイルを選択"), list.at(0) + "/gefu_appearance.ini", tr("設定ファイル (*.ini);;すべてのファイル (*)")); if (path.isEmpty()) { return; } - QSettings settings(path, QSettings::IniFormat); - loadAppearance(settings, true); + Preferences prefs(path, this); + saveAppearance(prefs); } -void PreferenceDialog::exportAppearance() +void PreferenceDialog::importAppearance() { QStringList list = QStandardPaths::standardLocations( QStandardPaths::DocumentsLocation); - QString path = QFileDialog::getSaveFileName( - this, tr("ファイルを選択"), list.at(0) + "/gefu_appearance.ini", + QString path = QFileDialog::getOpenFileName( + this, tr("ファイルを選択"), list.at(0), tr("設定ファイル (*.ini);;すべてのファイル (*)")); if (path.isEmpty()) { return; } - QSettings settings(path, QSettings::IniFormat); - saveAppearance(settings); + Preferences prefs(path, this); + loadAppearance(prefs); } void PreferenceDialog::accept() { - QSettings settings; - QAbstractButton *selected; - - //>>>>> 起動と終了 - // 起動時のサイズ - if (!ui->bootSize->isChecked()) { - settings.setValue(IniKey_BootSizeSpec, ""); - } - else { - selected = ui->sizeOptions->checkedButton(); - settings.setValue(IniKey_BootSizeSpec, selected->objectName()); - QSize size; - // 絶対指定 - size = QSize(ui->absoluteWidth->value(), ui->absoluteHeight->value()); - settings.setValue(IniKey_BootSizeAbs, size); - // 相対指定 - size = QSize(ui->relativeWidth->value(), ui->relativeHeight->value()); - settings.setValue(IniKey_BootSizeRel, size); - } - // 起動時の位置 - if (!ui->bootPos->isChecked()) { - settings.setValue(IniKey_BootPosSpec, ""); - } - else { - selected = ui->posOptions->checkedButton(); - settings.setValue(IniKey_BootPosSpec, selected->objectName()); - // 絶対指定 - QPoint pos; - pos = QPoint(ui->absoluteLeft->value(), ui->absoluteTop->value()); - settings.setValue(IniKey_BootPosAbs, pos); - // 相対指定 - pos = QPoint(ui->relativeLeft->value(), ui->relativeTop->value()); - settings.setValue(IniKey_BootPosRel, pos); - } - // 起動時の設定削除 - settings.setValue(IniKey_ResetOnBoot, ui->resetOnBoot->isChecked()); - // 終了時の確認ダイアログ - settings.setValue(IniKey_ConfirmExit, ui->confirmExit->isChecked()); - // アップデートのチェック - settings.setValue(IniKey_CheckUpdates, ui->checkUpdates->isChecked()); - - //>>>>> 色とフォント - saveAppearance(settings); - settings.setValue(IniKey_Darkness, ui->dark->value()); - - //>>>>> ファイル操作 - settings.setValue(IniKey_ConfirmCopy, ui->confirmCopy->isChecked()); - settings.setValue(IniKey_ConfirmDelete, ui->confirmDelete->isChecked()); - settings.setValue(IniKey_ConfirmMove, ui->confirmMove->isChecked()); - settings.setValue(IniKey_ConfirmRename, ui->confirmRename->isChecked()); - - settings.setValue(IniKey_AutoCloseCopy, ui->autoCloseCopy->isChecked()); - settings.setValue(IniKey_AutoCloseDelete, ui->autoCloseDelete->isChecked()); - settings.setValue(IniKey_AutoCloseMove, ui->autoCloseMove->isChecked()); - settings.setValue(IniKey_AutoCloseRename, ui->autoCloseRename->isChecked()); - - selected = ui->overwriteOptions->checkedButton(); - settings.setValue(IniKey_DefaultOnCopy, selected->objectName()); - - settings.setValue(IniKey_MoveAfterCreateFolder, ui->moveAfterCreate->isChecked()); - settings.setValue(IniKey_OpenAfterCreateFile, ui->openAfterCreate->isChecked()); - - //>>>>> パス設定 - settings.setValue(IniKey_PathEditor, ui->editorPath->text().trimmed()); - settings.setValue(IniKey_PathTerminal, ui->terminalPath->text().trimmed()); - settings.setValue(IniKey_PathArchiver, ui->archiverPath->text().trimmed()); - - //>>>>> テキストビューア - settings.setValue(IniKey_ViewerFont, ui->viewerSample->font()); - settings.setValue(IniKey_ViewerColorBg, ui->viewerSample->palette().base().color()); - settings.setValue(IniKey_ViewerColorFg, ui->viewerSample->palette().text().color()); - settings.setValue(IniKey_ViewerInherit, ui->viewerInherit->isChecked()); - settings.setValue(IniKey_ViewerForceOpen, !ui->enableViewerIgnoreExt->isChecked()); - QStringList list = ui->viewerIgnoreExt->toPlainText().split(",", QString::SkipEmptyParts); - QStringList::iterator it; - for (it = list.begin(); it != list.end(); it++) { - *it = it->trimmed(); - } - settings.setValue(IniKey_ViewerIgnoreExt, list.join(",")); + Preferences prefs(this); + + // [全般] + prefs.setCheckUpdate(ui->checkUpdate->isChecked()); + prefs.setConfirmQuit(ui->confirmQuit->isChecked()); + prefs.setMoveAfterCreation(ui->moveAfterCreation->isChecked()); + prefs.setOpenAfterCreation(ui->openAfterCreation->isChecked()); + prefs.setConfirmCopy(ui->confirmCopy->isChecked()); + prefs.setConfirmMove(ui->confirmMove->isChecked()); + prefs.setConfirmDelete(ui->confirmDelete->isChecked()); + prefs.setConfirmRename(ui->confirmRename->isChecked()); + prefs.setAutoCloseCopy(ui->autoCloseCopy->isChecked()); + prefs.setAutoCloseMove(ui->autoCloseMove->isChecked()); + prefs.setAutoCloseDelete(ui->autoCloseDelete->isChecked()); + prefs.setAutoCloseRename(ui->autoCloseRename->isChecked()); + + QAbstractButton *checked = ui->copyBehavior->checkedButton(); + prefs.setCopyBehavior(checked->objectName().mid(2)); + + prefs.setPreferExtensions(ui->preferExtensions->toPlainText()); + + // [外観(色)] + saveAppearance(prefs); + + // [外観(フォント)] + prefs.setFolderViewFont(ui->fvFontSpec->font()); + prefs.setLocationBoxFont(ui->lBoxFontSpec->font()); + prefs.setSearchBoxFont(ui->sBoxFontSpec->font()); + prefs.setTextViewFont(ui->tvFontSpec->font()); + + prefs.setLineHeight(ui->lineHeight->value()); + + // [プログラムパス] + prefs.setEditorPath(ui->editorPath->text()); + prefs.setTerminalPath(ui->terminalPath->text()); + prefs.setArchiverPath(ui->archiverPath->text()); QDialog::accept(); } + diff --git a/preferencedialog.h b/preferencedialog.h index 9385208..0f7ab9c 100644 --- a/preferencedialog.h +++ b/preferencedialog.h @@ -1,11 +1,9 @@ #ifndef PREFERENCEDIALOG_H #define PREFERENCEDIALOG_H -#include "colorsamplemodel.h" - #include -#include -#include +#include +class Preferences; namespace Ui { class PreferenceDialog; @@ -21,22 +19,18 @@ public: private: Ui::PreferenceDialog *ui; - ColorSampleModel m_model; - ColorMap m_colorMap; - void saveAppearance(QSettings &settings); - void loadAppearance(QSettings &settings, bool import); + void loadAppearance(Preferences &prefs); + void saveAppearance(Preferences &prefs); + void setFont(QLabel *label, const QFont &font); + void setPalette(QWidget *w, QPalette::ColorRole role, const QColor &color); private slots: - void chooseFont(); - void setControlsEnabled(bool enabled); - void setIgnoreExtDefault(); - void selectBoxColor(); - void selectViewColor(); - void selectViewerColor(); - void browseApp(); - void importAppearance(); - void exportAppearance(); + void chooseColor(); + void chooseFont(); + void choosePath(); + void exportAppearance(); + void importAppearance(); // QDialog interface public slots: diff --git a/preferencedialog.ui b/preferencedialog.ui index d9e4d19..052cd28 100644 --- a/preferencedialog.ui +++ b/preferencedialog.ui @@ -6,8 +6,8 @@ 0 0 - 671 - 535 + 673 + 553 @@ -19,7 +19,7 @@ 環境設定 - + @@ -31,452 +31,317 @@ Qt::StrongFocus + + QTabWidget::Rounded + - 4 + 0 - + - 起動と終了 + 全般 - - - 起動時のウィンドウサイズを指定する + + + Qt::StrongFocus - - true + + 起動時にアップデートを確認する + + + + + + + Qt::StrongFocus - - true + + 終了時に確認ダイアログを表示する - - - + + + + + + Qt::StrongFocus + + + フォルダ作成後は、そのフォルダに移動する + + + + + + + Qt::StrongFocus + + + ファイル作成後は、そのファイルを外部エディタで開く + + + + + + + + + 操作の開始時、確認ダイアログを表示する + + -1 - - - - - 0 - 24 - - + + 12 + + + 12 + + + 12 + + + 12 + + + Qt::StrongFocus - 絶対指定 + コピー - - sizeOptions - - - - - - - 幅 - - - - - - - px - - - 9999 - - - - - - - - - - - 高さ - - - - - - - px - - - 9999 - - - - + + + + Qt::StrongFocus + + + 移動 + + - - - - - 0 - 0 - + + + + Qt::StrongFocus - - - 0 - 24 - + + 削除 + + + + Qt::StrongFocus - 相対指定 + 名前変更 - - sizeOptions - - - - - - - 幅 - - - - - - - % - - - 100 - - - - - - - Qt::Horizontal - - - - 0 - 20 - - - - - + + + + + + + 操作の成功時、進捗ダイアログを自動で閉じる + + + + -1 + + + 12 + + + 12 + + + 12 + + + 12 + + + + + Qt::StrongFocus + + + コピー + + - - - - - - 高さ - - - - - - - % - - - - - - 100 - - - - - - - Qt::Horizontal - - - - 0 - 20 - - - - - + + + + Qt::StrongFocus + + + 移動 + + - - - - - 0 - 24 - + + + + Qt::StrongFocus + + 削除 + + + + + Qt::StrongFocus - 前回終了時のサイズ + 名前変更 - - sizeOptions - - - - - - Qt::Horizontal - - - - 95 - 20 - - - - - - + + + + + + Qt::Horizontal + + + + 1 + 20 + + + + +
- - - 起動時のウィンドウ位置を指定する - - - true - - - true - - - - - - - - - 0 - 24 - - + + + + + 同名ファイル存在時の既定の動作 + + + + Qt::StrongFocus - 絶対指定 + 上書き - posOptions + copyBehavior - - - - - - X - - - - - - - px - - - 9999 - - - - - - - - - - - Y - - - - - - - px - - - 9999 - - - - - - - - - - 0 - 24 - + + + + Qt::StrongFocus + + + 新しければ上書き + + copyBehavior + + + + + Qt::StrongFocus - 相対指定 + スキップ - posOptions + copyBehavior - - - - - - X - - - - - - - % - - - 100 - - - - - - - Qt::Horizontal - - - - 0 - 20 - - - - - - - - - - - - Y - - - - - - - % - - - 100 - - - - - - - Qt::Horizontal - - - - 0 - 20 - - - - - - - - - - - 0 - 24 - - + + Qt::StrongFocus - 画面中央 + ファイル名末尾に数字を付与 - posOptions + copyBehavior - - - - - 0 - 24 - - + + Qt::StrongFocus - 前回終了時の位置 + 名前を変更 - posOptions + copyBehavior - + + + + + + Qt::Horizontal + + + + 1 + 41 + + + + + + + + + + 外部アプリを優先する拡張子 + + - - - Qt::Horizontal - - - - 40 - 20 - - - + - - - Qt::StrongFocus + + + Qt::Vertical - - 起動時にアップデートを確認する + + + 20 + 0 + - + @@ -488,160 +353,230 @@ - - - - Qt::StrongFocus - - - 終了時に確認ダイアログを表示する - - - - - - - Qt::Vertical - - - - 20 - 45 - - - - - + - 色とフォント + 外観(色) - + - アドレスボックス + フォルダビュー - - - 0 - - - 4 - - - 4 - - - 4 - - - 4 - + - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - - - + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Qt::StrongFocus + - フォント: + 通 常 - - + + + + Qt::NoFocus + - font family, point + Normal + + + true - - + + + + + 0 + 0 + + + + + 100 + 0 + + Qt::StrongFocus - 選択 + マーク - - + + + + Qt::NoFocus + + + Marked + + + true + + + + + Qt::Horizontal - 40 + 85 20 - - + + + + Qt::StrongFocus + + + 背景 + + + + + + + Qt::StrongFocus + + + マーク背景 + + + + + + + + + 0 0 + + + 100 + 0 + + Qt::StrongFocus - 文字色 + システム - - + + + + Qt::NoFocus + + + System + + + true + + + + + + + + 0 + 0 + + + + + 100 + 0 + + Qt::StrongFocus - 背景色 + 隠し属性 - - - - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - - - + + + + + 0 + 0 + + + + + 100 + 0 + + + + Qt::StrongFocus + + + 読取専用 + + + + + + + Qt::NoFocus + + + ReadOnly + + + true + + + + + + + Qt::NoFocus + - サンプルテキスト + Hidden + + + true @@ -651,374 +586,361 @@ - - - ファイルビュー - - - - 0 - - - - - 4 - - - 4 - - - 4 - - - 4 - - + + + + + ロケーションボックス + + + 4 - - + + + + Qt::StrongFocus + - フォント: + 背景 - - + + + + + 0 + 0 + + + + Qt::StrongFocus + - font family, point + 文字 - - + + - Qt::StrongFocus + Qt::NoFocus - - 選択 + + true + + + + + + + 検索ボックス + + - - - Qt::Horizontal - - - - 40 - 20 - + + + 4 - + + + + 通 常 + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Qt::StrongFocus + + + 文字 + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + 背景 + + + + + + + Qt::NoFocus + + + abc123あいう + + + true + + + + - + + + 4 + + + + + 不一致 + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Qt::StrongFocus + + + 文字 + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + 背景 + + + + + + + Qt::NoFocus + + + abc123あいう + + + true + + + + + + + + + + + + Qt::Horizontal + + + + 13 + 20 + + + + + + + + + + + + 内蔵テキストビューア + + + + 4 + + + + + + 0 + 0 + + Qt::StrongFocus - 文字色 + 文字 - - + + Qt::StrongFocus - 背景色 + 背景 - - - - - - -1 - - - - - 文字色 - - - - 12 - - - - - - 0 - 0 - - - - - 100 - 0 - - - - Qt::StrongFocus - - - システム - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - Qt::StrongFocus - - - マーク - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - Qt::StrongFocus - - - 隠し属性 - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - Qt::StrongFocus - - - 読取専用 - - - - - - - - - - Qt::Horizontal + + + + Qt::NoFocus - - QSizePolicy::Fixed + + abc123あいう - - - 10 - 20 - + + true - - - - - - 背景色 - - - - - - Qt::StrongFocus - - - マーク - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - + + + + + + 内蔵画像ビューア + + + + 4 + + + + + Qt::StrongFocus + - 非アクティブパネルの暗さ(0〜100) + 背景 - - - - + + + + Qt::NoFocus - - 100 + + true - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 0 - - - - - 0 - 100 - - - - - 16777215 - 100 - - - - Qt::ClickFocus - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - Qt::ElideMiddle - - - false - - - false - - - false - - - false - - - - - + + + + + + Qt::Horizontal + + + + 13 + 17 + + + + + + + + + + Qt::StrongFocus + + + 全ての通常文字を一括指定 + + + + + + + Qt::StrongFocus + + + 全ての通常背景を一括指定 + + + + + + - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - + - - - Qt::StrongFocus - + - インポート + 非アクティブパネルの暗さ(0〜1) - - - Qt::StrongFocus + + + 1.000000000000000 - - エクスポート + + 0.010000000000000 - + Qt::Horizontal - 40 - 20 + 13 + 17 @@ -1033,150 +955,35 @@ 20 - 1 + 0 - - - - - ファイル操作 - - - + - - - 操作の開始時、確認ダイアログを表示する + + + Qt::StrongFocus + + + インポート - - - -1 - - - 12 - - - 12 - - - 12 - - - 12 - - - - - Qt::StrongFocus - - - コピー - - - - - - - Qt::StrongFocus - - - 移動 - - - - - - - Qt::StrongFocus - - - 削除 - - - - - - - Qt::StrongFocus - - - 名前変更 - - - - - - - 操作の成功時、進捗ダイアログを自動で閉じる + + + Qt::StrongFocus + + + エクスポート - - - -1 - - - 12 - - - 12 - - - 12 - - - 12 - - - - - Qt::StrongFocus - - - コピー - - - - - - - Qt::StrongFocus - - - 移動 - - - - - - - Qt::StrongFocus - - - 削除 - - - - - - - Qt::StrongFocus - - - 名前変更 - - - - - + Qt::Horizontal @@ -1190,122 +997,152 @@ + + + + + 外観(フォント) + + - - - - - 同名ファイル存在時の既定の動作 + + + + + Qt::StrongFocus + + + フォルダビューのフォント + + + + + + + font family, point + + + + + + + Qt::StrongFocus + + + ロケーションボックスのフォント + + + + + + + font family, point + + + + + + + Qt::StrongFocus + + + 検索ボックスのフォント + + + + + + + font family, point - - - - - Qt::StrongFocus - - - 上書き - - - overwriteOptions - - - - - - - Qt::StrongFocus - - - 新しければ上書き - - - overwriteOptions - - - - - - - Qt::StrongFocus - - - スキップ - - - overwriteOptions - - - - - - - Qt::StrongFocus - - - ファイル名末尾に数字を付与 - - - overwriteOptions - - - - - - - Qt::StrongFocus - - - 名前を変更 - - - overwriteOptions - - - - + + + + Qt::StrongFocus + + + 内蔵テキストビューアのフォント + + + + + + + font family, point + + + + + + + フォルダビューの行の高さ(1〜2) + + + + + + + 2 + + + 1.000000000000000 + + + 2.000000000000000 + + + 0.010000000000000 + + + 1.500000000000000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + - - - Qt::StrongFocus + + + Qt::Vertical - - フォルダ作成後は、そのフォルダに移動する + + + 20 + 223 + - + - + Qt::StrongFocus - ファイル作成後は、そのファイルをエディタで開く + 全てのフォントを一括指定 - - - - Qt::Vertical - - - - 20 - 102 - - - - - パス設定 + プログラムパス @@ -1335,6 +1172,9 @@ + + Qt::StrongFocus + 参照 @@ -1370,6 +1210,9 @@ + + Qt::StrongFocus + 参照 @@ -1405,6 +1248,9 @@ + + Qt::StrongFocus + 参照 @@ -1428,357 +1274,6 @@ - - - 内蔵ビューア - - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - - - - - テキストビューアの外観 - - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - - - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - - - - - フォント: - - - - - - - font family, point - - - - - - - Qt::StrongFocus - - - 選択 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - 文字色 - - - - - - - Qt::StrongFocus - - - 背景色 - - - - - - - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 文字色と背景色はファイルビューを継承 - - - - - - - - - - 0 - 0 - - - - - 0 - 130 - - - - - 16777215 - 130 - - - - true - - - 01234567890 -abcdefghijklmnopqrstuvwxyz -ABCDEFGHIJKLMNOPQRSTUVWXYZ -!"#$%&'()+-*=^~¥|@`[]{}<>;:,./?_ -あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。 - - - - - - - - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - - - - - 4 - - - 4 - - - 4 - - - 4 - - - 4 - - - - - 以下の拡張子は外部アプリを優先する - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - デフォルトに戻す - - - - - - - - - 4 - - - QLayout::SetDefaultConstraint - - - 4 - - - 4 - - - 4 - - - 4 - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 13 - 17 - - - - - - - - - 0 - 0 - - - - - 0 - 100 - - - - - 16777215 - 110 - - - - - Monaco - 13 - - - - 1 -2 -3 -4 -5 -6 - - - - - - - - - - - Qt::Vertical - - - - 20 - 3 - - - - - - @@ -1797,41 +1292,10 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ - bootSize - sizeAbsolute - absoluteWidth - absoluteHeight - sizeRelative - relativeWidth - relativeHeight - sizeLast - bootPos - posAbsolute - absoluteLeft - absoluteTop - posRelative - relativeLeft - relativeTop - posCenter - posLast - checkUpdates - resetOnBoot - confirmExit - chooseBoxFont - boxClrFg - boxClrBg - sampleEdit - chooseViewFont - clrFgNormal - clrBgNormal - clrFgSystem - clrFgMark - clrFgHidden - clrFgReadonly - clrBgMark - dark - importAppearance - exportAppearance + checkUpdate + confirmQuit + moveAfterCreation + openAfterCreation confirmCopy confirmMove confirmDelete @@ -1845,20 +1309,37 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ rbSkip rbAppendNumber rbRename - moveAfterCreate - openAfterCreate + preferExtensions + resetOnBoot + fvNormal + fvMarked + fvNormalBg + fvMarkedBg + fvSystem + fvHidden + fvReadOnly + lBoxFg + lBoxBg + sBoxNormal + sBoxNormalBg + sBoxUnmatch + sBoxUnmatchBg + tvFg + tvBg + gvBg + importAppearance + exportAppearance + fvFont + lBoxFont + sBoxFont + tvFont + allFont editorPath browseEditor terminalPath browseTerminal - chooseViewerFont - viewerClrFg - viewerClrBg - viewerInherit - viewerSample - enableViewerIgnoreExt - viewerIgnoreExt - defaultIgnoreExt + archiverPath + browseArchiver buttonBox @@ -1897,8 +1378,6 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ - - - + diff --git a/preferences.cpp b/preferences.cpp new file mode 100644 index 0000000..32fb146 --- /dev/null +++ b/preferences.cpp @@ -0,0 +1,340 @@ +#include "foldermodel.h" +#include "global.h" +#include "preferences.h" + +#include +#include +#include + +QString DefaultPreferExtensions() +{ + QStringList list; + + // 画像系 + list << "ico" << "ai" << "psd" << "xcf" << "tif" << "tiff" << "wmf"; + // 音・動画系 + list << "wav" << "mp3" << "ogg" << "midi" << "mid" << "aif" << "aiff"; + list << "mov" << "mpg" << "mpeg" << "wma" << "wmv" << "asf" << "avi"; + list << "flac" << "mkv"; + // 実行ファイル系 + list << "exe" << "com" << "msi" << "scr"; + // アーカイブ系 + list << "lzh" << "zip" << "cab" << "tar" << "rar" << "gz" << "tgz"; + list << "bz2" << "xz" << "jar" << "7z" << "dmg"; + // ドキュメント系 + list << "pdf" << "doc" << "docx" << "xls" << "xlsx" << "ppt" << "pptx"; + // フォント + list << "ttf" << "ttc"; + + list.sort(); + + return list.join(","); +} + +QFont DefaultFixedFont() +{ + QFont font = qApp->font(); +#ifdef Q_OS_WIN + font.setFamily("MS ゴシック"); +#elif defined(Q_OS_MAC) + font.setFamily("Monaco"); +#else +#endif + return font; +} + +Preferences::Preferences(QObject *parent) : + QSettings(QSettings::IniFormat, + QSettings::UserScope, + qApp->organizationName(), + qApp->applicationName(), + parent) +{ +} + +Preferences::Preferences(const QString &path, QObject *parent) : + QSettings(path, QSettings::IniFormat, parent) +{ +} + +#define Key_Filter(side) (side + "/Filter") +#define Key_NameFilter(side) (side + "/NameFilter") +#define Key_Sort(side) (side + "/Sort") +#define Key_Path(side) (side + "/Path") +void Preferences::restoreModel(const QString &side, FolderModel *m) +{ + qDebug() << "Preferences::restoreModel()" << side; + + int filter = value(Key_Filter(side), 0).toInt(); + filter |= QDir::NoDot | QDir::AllDirs | QDir::Files; + m->setFilter(QFlag(filter)); + + QString nameFilter = value(Key_NameFilter(side), "*").toString(); + m->setNameFilters(nameFilter.split(" ", QString::SkipEmptyParts)); + + int sort = QDir::Name | QDir::DirsFirst | QDir::IgnoreCase; + sort = value(Key_Sort(side), sort).toInt(); + m->setSorting(QFlag(sort)); + + QString path = QDir::homePath(); + path = value(Key_Path(side), path).toString(); + m->setRootPath(path); +} + +void Preferences::saveModel(const QString &side, const FolderModel *m) +{ + qDebug() << "Preferences::saveModel()" << side; + + setValue(Key_Filter(side), static_cast(m->filter())); + setValue(Key_Sort(side), static_cast(m->sorting())); + setValue(Key_Path(side), m->rootPath()); +} + +#define Key_WindowGeometry "WindowGeometry" +#define Key_WindowState "WindowState" +void Preferences::restoreWindow(QMainWindow *w) +{ + qDebug() << "Preferences::restoreWindow()"; + + QByteArray geometry = value(Key_WindowGeometry).toByteArray(); + if (geometry.isNull()) { + QSize size(700, 400); + QPoint point; + point.setX((qApp->desktop()->width() - size.width()) / 2); + point.setY((qApp->desktop()->height() - size.height()) / 2); + w->setGeometry(QRect(point, size)); + } + else { + w->restoreGeometry(geometry); + } + + QByteArray state = value(Key_WindowState).toByteArray(); + if (!state.isEmpty()) { + w->restoreState(state); + } +} + +void Preferences::saveWindow(const QMainWindow *w) +{ + setValue(Key_WindowGeometry, w->saveGeometry()); + setValue(Key_WindowState, w->saveState()); +} + +/////////////////////////////////////////////////////////////////////////////// +#define Key_BookmarkEntry(i) QString("Bookmark/Entry%1").arg(i) +#define Key_BookmarkPath(i) QString("Bookmark/Path%1").arg(i) +void Preferences::addBookmark(const QString &name, const QString &path) +{ + int n; + for (n = 1; !value(Key_BookmarkEntry(n)).isNull(); n++) + ; + + setValue(Key_BookmarkEntry(n), name); + setValue(Key_BookmarkPath(n), path); +} + +void Preferences::clearBookmark() +{ + beginGroup("Bookmark"); + remove(""); + endGroup(); +} + +QString Preferences::getBookmarkEntry(int n) const +{ + return value(Key_BookmarkEntry(n)).toString(); +} + +QString Preferences::getBookmarkPath(int n) const +{ + return value(Key_BookmarkPath(n)).toString(); +} + +QColor Preferences::folderViewFgColor(bool active) +{ + int darkFactor = 100; + if (!active) { + darkFactor += getDarkFacotr() * 100; + } + return getFolderViewFgColor().darker(darkFactor); +} + +QColor Preferences::folderViewBgColor(bool active) +{ + int darkFactor = 100; + if (!active) { + darkFactor += getDarkFacotr() * 100; + } + return getFolderViewBgColor().darker(darkFactor); +} + +QColor Preferences::folderViewMarkedFgColor(bool active) +{ + int darkFactor = 100; + if (!active) { + darkFactor += getDarkFacotr() * 100; + } + return getFolderViewMarkedFgColor().darker(darkFactor); +} + +QColor Preferences::folderViewMarkedBgColor(bool active) +{ + int darkFactor = 100; + if (!active) { + darkFactor += getDarkFacotr() * 100; + } + return getFolderViewMarkedBgColor().darker(darkFactor); +} + +QColor Preferences::folderViewSystemColor(bool active) +{ + int darkFactor = 100; + if (!active) { + darkFactor += getDarkFacotr() * 100; + } + return getFolderViewSystemColor().darker(darkFactor); +} + +QColor Preferences::folderViewHiddenColor(bool active) +{ + int darkFactor = 100; + if (!active) { + darkFactor += getDarkFacotr() * 100; + } + return getFolderViewHiddenColor().darker(darkFactor); +} + +QColor Preferences::folderViewReadOnlyColor(bool active) +{ + int darkFactor = 100; + if (!active) { + darkFactor += getDarkFacotr() * 100; + } + return getFolderViewReadOnlyColor().darker(darkFactor); +} + +QColor Preferences::locationBoxFgColor(bool active) +{ + int darkFactor = 100; + if (!active) { + darkFactor += getDarkFacotr() * 100; + } + return getLocationBoxFgColor().darker(darkFactor); +} + +QColor Preferences::locationBoxBgColor(bool active) +{ + int darkFactor = 100; + if (!active) { + darkFactor += getDarkFacotr() * 100; + } + return getLocationBoxBgColor().darker(darkFactor); +} + +#define IMPLEMENT_BOOL(key, defVal) \ + bool Preferences::is##key() const { \ + return value(#key, def##key()).toBool(); \ + } \ + bool Preferences::def##key() const { \ + return defVal; \ + } \ + void Preferences::set##key(bool value) { \ + setValue(#key, value); \ + } + +IMPLEMENT_BOOL(CheckUpdate, true) +IMPLEMENT_BOOL(ConfirmQuit, true) +IMPLEMENT_BOOL(ConfirmCopy, true) +IMPLEMENT_BOOL(AutoCloseCopy, false) +IMPLEMENT_BOOL(ConfirmMove, true) +IMPLEMENT_BOOL(AutoCloseMove, false) +IMPLEMENT_BOOL(ConfirmDelete, true) +IMPLEMENT_BOOL(AutoCloseDelete, false) +IMPLEMENT_BOOL(ConfirmRename, true) +IMPLEMENT_BOOL(AutoCloseRename, false) +IMPLEMENT_BOOL(OpenAfterCreation, false) +IMPLEMENT_BOOL(MoveAfterCreation, false) + +#define IMPLEMENT_STRING(key, defVal) \ + QString Preferences::get##key() const { \ + return value(#key, def##key()).toString(); \ + } \ + QString Preferences::def##key() const { \ + return defVal; \ + } \ + void Preferences::set##key(const QString &value) { \ + setValue(#key, value); \ + } + +#ifdef Q_OS_LINUX + +#elif defined(Q_OS_MAC) + IMPLEMENT_STRING(ArchiverPath, QQ("/System/Library/CoreServices/Archive Utility.app")) + IMPLEMENT_STRING(EditorPath, "/Applications/TextEdit.app") + IMPLEMENT_STRING(TerminalPath, "/Applications/Utilities/Terminal.app --args -c cd") +#else + IMPLEMENT_STRING(ArchiverPath, QQ("C:/Program Files/Lhaplus/Lhaplus.exe")) + IMPLEMENT_STRING(EditorPath, "notepad.exe") + IMPLEMENT_STRING(TerminalPath, "cmd.exe /k cd") +#endif + +IMPLEMENT_STRING(CopyBehavior, "OverWriteIfNew") +IMPLEMENT_STRING(PreferExtensions, DefaultPreferExtensions()) + +#define IMPLEMENT_COLOR(key, defVal) \ + QColor Preferences::get##key() const { \ + return value("Appearance/"#key, def##key()).value(); \ + } \ + QColor Preferences::def##key() const { \ + return defVal; \ + } \ + void Preferences::set##key(const QColor &value) { \ + setValue("Appearance/"#key, value); \ + } + +IMPLEMENT_COLOR(FolderViewFgColor, QPalette().text().color()) +IMPLEMENT_COLOR(FolderViewBgColor, QPalette().base().color()) +IMPLEMENT_COLOR(FolderViewMarkedFgColor, QColor(128, 0, 0)) +IMPLEMENT_COLOR(FolderViewMarkedBgColor, QColor(0, 192, 0)) +IMPLEMENT_COLOR(FolderViewSystemColor, QColor(128, 0, 128)) +IMPLEMENT_COLOR(FolderViewHiddenColor, QColor(128, 128, 128)) +IMPLEMENT_COLOR(FolderViewReadOnlyColor, QColor(0, 128, 0)) +IMPLEMENT_COLOR(LocationBoxFgColor, QPalette().text().color()) +IMPLEMENT_COLOR(LocationBoxBgColor, QPalette().base().color()) +IMPLEMENT_COLOR(SearchBoxFgColor, QPalette().text().color()) +IMPLEMENT_COLOR(SearchBoxBgColor, QPalette().base().color()) +IMPLEMENT_COLOR(SearchBoxUnmatchFgColor, QColor(255, 0, 0)) +IMPLEMENT_COLOR(SearchBoxUnmatchBgColor, QPalette().base().color()) +IMPLEMENT_COLOR(TextViewFgColor, QPalette().text().color()) +IMPLEMENT_COLOR(TextViewBgColor, QPalette().base().color()) +IMPLEMENT_COLOR(ImageViewBgColor, QPalette().base().color()) + +#define IMPLEMENT_DOUBLE(key, defVal) \ + double Preferences::get##key() const { \ + return value("Appearance/"#key, def##key()).toDouble(); \ + } \ + double Preferences::def##key() const { \ + return defVal; \ + } \ + void Preferences::set##key(double value) { \ + setValue("Appearance/"#key, value); \ + } + +IMPLEMENT_DOUBLE(DarkFacotr, 0) +IMPLEMENT_DOUBLE(LineHeight, 1.5) + +#define IMPLEMENT_FONT(key, defVal) \ + QFont Preferences::get##key() const { \ + return value("Appearance/"#key, def##key()).value(); \ + } \ + QFont Preferences::def##key() const { \ + return defVal; \ + } \ + void Preferences::set##key(const QFont &value) { \ + setValue("Appearance/"#key, value); \ + } + +IMPLEMENT_FONT(FolderViewFont, DefaultFixedFont()) +IMPLEMENT_FONT(LocationBoxFont, DefaultFixedFont()) +IMPLEMENT_FONT(SearchBoxFont, DefaultFixedFont()) +IMPLEMENT_FONT(TextViewFont, DefaultFixedFont()) diff --git a/preferences.h b/preferences.h new file mode 100644 index 0000000..04d3dd0 --- /dev/null +++ b/preferences.h @@ -0,0 +1,103 @@ +#ifndef PREFERENCES_H +#define PREFERENCES_H + +#include +#include +class FolderModel; + +#define DECLARE_BOOL(key) \ + bool is##key() const; \ + bool def##key() const; \ + void set##key(bool value) + +#define DECLARE_OBJECT(Type, key) \ + Type get##key() const; \ + Type def##key() const; \ + void set##key(const Type &value) + +#define DECLARE_PRIMITIVE(Type, key) \ + Type get##key() const; \ + Type def##key() const; \ + void set##key(Type value) + +class Preferences : public QSettings +{ + Q_OBJECT +public: + explicit Preferences(QObject *parent = 0); + Preferences(const QString &path, QObject *parent = 0); + + void restoreModel(const QString &side, FolderModel *m); + void saveModel(const QString &side, const FolderModel *m); + + void restoreWindow(QMainWindow *w); + void saveWindow(const QMainWindow *w); + + void addBookmark(const QString &name, const QString &path); + void clearBookmark(); + QString getBookmarkEntry(int n) const; + QString getBookmarkPath(int n) const; + + QColor folderViewFgColor(bool active); + QColor folderViewBgColor(bool active); + QColor folderViewMarkedFgColor(bool active); + QColor folderViewMarkedBgColor(bool active); + QColor folderViewSystemColor(bool active); + QColor folderViewHiddenColor(bool active); + QColor folderViewReadOnlyColor(bool active); + QColor locationBoxFgColor(bool active); + QColor locationBoxBgColor(bool active); + + DECLARE_BOOL(CheckUpdate); + DECLARE_BOOL(ConfirmQuit); + DECLARE_BOOL(ConfirmCopy); + DECLARE_BOOL(AutoCloseCopy); + DECLARE_BOOL(ConfirmMove); + DECLARE_BOOL(AutoCloseMove); + DECLARE_BOOL(ConfirmDelete); + DECLARE_BOOL(AutoCloseDelete); + DECLARE_BOOL(ConfirmRename); + DECLARE_BOOL(AutoCloseRename); + DECLARE_BOOL(OpenAfterCreation); + DECLARE_BOOL(MoveAfterCreation); + + DECLARE_OBJECT(QString, ArchiverPath); + DECLARE_OBJECT(QString, EditorPath); + DECLARE_OBJECT(QString, TerminalPath); + DECLARE_OBJECT(QString, CopyBehavior); + DECLARE_OBJECT(QString, PreferExtensions); + + DECLARE_OBJECT(QColor, FolderViewFgColor); + DECLARE_OBJECT(QColor, FolderViewBgColor); + DECLARE_OBJECT(QColor, FolderViewMarkedFgColor); + DECLARE_OBJECT(QColor, FolderViewMarkedBgColor); + DECLARE_OBJECT(QColor, FolderViewSystemColor); + DECLARE_OBJECT(QColor, FolderViewHiddenColor); + DECLARE_OBJECT(QColor, FolderViewReadOnlyColor); + DECLARE_OBJECT(QColor, LocationBoxFgColor); + DECLARE_OBJECT(QColor, LocationBoxBgColor); + DECLARE_OBJECT(QColor, SearchBoxFgColor); + DECLARE_OBJECT(QColor, SearchBoxBgColor); + DECLARE_OBJECT(QColor, SearchBoxUnmatchFgColor); + DECLARE_OBJECT(QColor, SearchBoxUnmatchBgColor); + DECLARE_OBJECT(QColor, TextViewFgColor); + DECLARE_OBJECT(QColor, TextViewBgColor); + DECLARE_OBJECT(QColor, ImageViewBgColor); + + DECLARE_PRIMITIVE(double, DarkFacotr); + DECLARE_PRIMITIVE(double, LineHeight); + + DECLARE_OBJECT(QFont, FolderViewFont); + DECLARE_OBJECT(QFont, LocationBoxFont); + DECLARE_OBJECT(QFont, SearchBoxFont); + DECLARE_OBJECT(QFont, TextViewFont); + + + +signals: + +public slots: + +}; + +#endif // PREFERENCES_H diff --git a/renamemultidialog.cpp b/renamemultidialog.cpp index d7f4021..e3c946e 100644 --- a/renamemultidialog.cpp +++ b/renamemultidialog.cpp @@ -4,7 +4,7 @@ #include RenameMultiDialog::RenameMultiDialog(QWidget *parent) : - IRenameDialog(parent), + AbstractRenameDialog(parent), ui(new Ui::RenameMultiDialog) { ui->setupUi(this); @@ -164,6 +164,6 @@ void RenameMultiDialog::accept() } } - IRenameDialog::accept(); + AbstractRenameDialog::accept(); } diff --git a/renamemultidialog.h b/renamemultidialog.h index 4336438..cf907eb 100644 --- a/renamemultidialog.h +++ b/renamemultidialog.h @@ -2,13 +2,13 @@ #define RENAMEMULTIDIALOG_H #include -#include "irenamedialog.h" +#include "abstractrenamedialog.h" namespace Ui { class RenameMultiDialog; } -class RenameMultiDialog : public IRenameDialog +class RenameMultiDialog : public AbstractRenameDialog { Q_OBJECT diff --git a/renamesingledialog.cpp b/renamesingledialog.cpp index a1adf90..e658d36 100644 --- a/renamesingledialog.cpp +++ b/renamesingledialog.cpp @@ -3,7 +3,7 @@ #include RenameSingleDialog::RenameSingleDialog(QWidget *parent) : - IRenameDialog(parent), + AbstractRenameDialog(parent), ui(new Ui::RenameSingleDialog) { ui->setupUi(this); @@ -51,5 +51,5 @@ void RenameSingleDialog::accept() m_dir.absoluteFilePath(ui->nameAfter->text())); } - IRenameDialog::accept(); + AbstractRenameDialog::accept(); } diff --git a/renamesingledialog.h b/renamesingledialog.h index 2b85c3b..b6cb4c9 100644 --- a/renamesingledialog.h +++ b/renamesingledialog.h @@ -1,13 +1,13 @@ #ifndef RENAMESINGLEDIALOG_H #define RENAMESINGLEDIALOG_H -#include "irenamedialog.h" +#include "abstractrenamedialog.h" namespace Ui { class RenameSingleDialog; } -class RenameSingleDialog : public IRenameDialog +class RenameSingleDialog : public AbstractRenameDialog { Q_OBJECT diff --git a/renameworker.h b/renameworker.h index f571501..a2ba4e6 100644 --- a/renameworker.h +++ b/renameworker.h @@ -1,8 +1,8 @@ #ifndef RENAMEWORKER_H #define RENAMEWORKER_H -#include "common.h" #include "abstractworker.h" +#include "global.h" class RenameWorker : public AbstractWorker { diff --git a/resource.qrc b/resource.qrc index 31540ba..a073f60 100644 --- a/resource.qrc +++ b/resource.qrc @@ -34,8 +34,9 @@ images/Zoom in.png images/Zoom out.png images/Search text.png - images/Picture.png images/Lightbrown Zip.png images/file-manager.png + images/windows_fullscreen.png + images/Pictures.png diff --git a/searchbox.cpp b/searchbox.cpp deleted file mode 100644 index b78565f..0000000 --- a/searchbox.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "common.h" -#include "mainwindow.h" -#include "searchbox.h" - -#include -#include -#include -#include - -SearchBox::SearchBox(QWidget *parent) : - QLineEdit(parent) -{ -} - -void SearchBox::itemFound() -{ - QPalette palette = this->palette(); - palette.setColor(QPalette::Text, Qt::black); - setPalette(palette); -} - -void SearchBox::itemNotFound() -{ - QPalette palette = this->palette(); - palette.setColor(QPalette::Text, Qt::red); - setPalette(palette); -} - -void SearchBox::keyPressEvent(QKeyEvent *event) -{ -#if 0 - QString ksq = KeyEventToSequence(event); - - if (ksq == "/") { - QAction *action = getMainWnd()->findChild("action_Search"); - action->toggle(); - event->accept(); - return; - } - - QString textBefore = text(); - QLineEdit::keyPressEvent(event); - - - if (ksq == "Shift+Return"){ - qDebug() << ksq; - emit getMainWnd()->findChild("action_SearchPrev")->triggered(); - } - else if (ksq.indexOf("Return") != -1) { - qDebug() << ksq; - emit getMainWnd()->findChild("action_SearchNext")->triggered(); - } - else if (textBefore != text()) { - emit searchItem(text()); - } - else { - qDebug() << ksq; - } -#endif - - QLineEdit::keyPressEvent(event); - -} diff --git a/searchbox.h b/searchbox.h deleted file mode 100644 index 0f901df..0000000 --- a/searchbox.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef SEARCHBOX_H -#define SEARCHBOX_H - -#include - -class SearchBox : public QLineEdit -{ - Q_OBJECT -public: - explicit SearchBox(QWidget *parent = 0); - -signals: - void searchItem(const QString &text); - void searchNext(const QString &text); - void searchPrev(const QString &next); - -private slots: - void itemFound(); - void itemNotFound(); - -public slots: - - // QWidget interface -protected: - void keyPressEvent(QKeyEvent *event); -}; - -#endif // SEARCHBOX_H diff --git a/simpleimageview.cpp b/simpleimageview.cpp index 4978785..604d689 100644 --- a/simpleimageview.cpp +++ b/simpleimageview.cpp @@ -1,4 +1,4 @@ -#include "common.h" +#include "mainwindow.h" #include "simpleimageview.h" #include @@ -9,139 +9,88 @@ #include #include +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleImageView::SimpleImageView +/// \param parent 親ウィジェット +/// +/// コンストラクタ +/// SimpleImageView::SimpleImageView(QWidget *parent) : QGraphicsView(parent), - m_back(NULL), - m_fitToWindow(NULL), - m_scaleUp(NULL), - m_scaleDown(NULL), - m_scaleNormal(NULL), - m_rot90(NULL), - m_rot180(NULL), + AbstractView(), m_imgSrc(), + m_scene(this), m_scaleFactor(0), m_rotateDeg(0) { - QSettings settings; - QPalette pal = palette(); - pal.setColor(QPalette::Base, settings.value(IniKey_ViewColorBgNormal).value()); - setBackgroundRole(QPalette::Base); - setPalette(pal); - - setContextMenuPolicy(Qt::DefaultContextMenu); - - QList shortcuts; - //>>>>> 「戻る」メニュー - m_back = new QAction(tr("戻る"), this); - m_back->setObjectName("back"); - shortcuts.clear(); - shortcuts << QKeySequence("Return"); - shortcuts << QKeySequence("Backspace"); - m_back->setShortcuts(shortcuts); - - //>>>>> 「ウィンドウにフィット」メニュー - m_fitToWindow = new QAction(tr("ウィンドウにフィット"), this); - m_fitToWindow->setObjectName("fitToWindow"); - m_fitToWindow->setCheckable(true); - m_fitToWindow->setChecked(true); - m_fitToWindow->setShortcut(QKeySequence("Space")); - - //>>>>> 「拡大」メニュー - m_scaleUp = new QAction(tr("拡大"), this); - m_scaleUp->setObjectName("scaleUp"); - shortcuts.clear(); - shortcuts << QKeySequence("+"); - shortcuts << QKeySequence("Shift++"); - m_scaleUp->setShortcuts(shortcuts); - - //>>>>> 「縮小」メニュー - m_scaleDown = new QAction(tr("縮小"), this); - m_scaleDown->setObjectName("scaleDown"); - m_scaleDown->setShortcut(QKeySequence("-")); - - //>>>>> 「等倍」メニュー - m_scaleNormal = new QAction(tr("等倍"), this); - m_scaleNormal->setObjectName("scaleNormal"); - shortcuts.clear(); - shortcuts << QKeySequence("="); - shortcuts << QKeySequence("Shift+="); - m_scaleNormal->setShortcuts(shortcuts); - - //>>>>> 「右に90度回転」メニュー - m_rot90 = new QAction(tr("右に90度回転"), this); - m_rot90->setObjectName("rot90"); - m_rot90->setShortcut(QKeySequence("9")); - - //>>>>> 「右に180度回転」メニュー - m_rot180 = new QAction(tr("右に180度回転"), this); - m_rot180->setObjectName("rot180"); - m_rot180->setShortcut(QKeySequence("0")); - - connect(m_back, SIGNAL(triggered()), this, SIGNAL(viewFinished())); - connect(m_fitToWindow, SIGNAL(toggled(bool)), this, SLOT(fitToWindow(bool))); - connect(m_scaleDown, SIGNAL(triggered()), this, SLOT(scaleDown())); - connect(m_scaleNormal, SIGNAL(triggered()), this, SLOT(scaleNormal())); - connect(m_scaleUp, SIGNAL(triggered()), this, SLOT(scaleUp())); - connect(m_rot90, SIGNAL(triggered()), this, SLOT(rotate90())); - connect(m_rot180, SIGNAL(triggered()), this, SLOT(rotate180())); - + setContextMenuPolicy(Qt::NoContextMenu); setDragMode(ScrollHandDrag); + setScene(&m_scene); } -bool SimpleImageView::setSource(const QString &path) +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleImageView::initialize +/// \param w メインウィンドウオブジェクト +/// +/// 初期化処理を行います。 +/// +void SimpleImageView::initialize(MainWindow *w) { - QPixmap pixmap(path); - if (pixmap.isNull()) { - return false; - } + connect(this, SIGNAL(statusChanged(QString)), w, SLOT(view_statusChanged(QString))); + installEventFilter(w); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleImageView::setSource +/// \param pixmap +/// +void SimpleImageView::setSource(const QPixmap &pixmap) +{ + qDebug() << "SimpleImageView::setSource()"; m_imgSrc = pixmap; m_rotateDeg = 0; - m_scaleFactor = 0; - m_fitToWindow->blockSignals(true); - m_fitToWindow->setChecked(true); - m_fitToWindow->blockSignals(false); + m_scaleFactor = -1; - QGraphicsScene *scene = new QGraphicsScene(this); - scene->addPixmap(pixmap); - setScene(scene); resizeImage(); - - return true; } -void SimpleImageView::changeScale(bool up) +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleImageView::scaleFactor +/// \return 倍率を返します。 +/// +double SimpleImageView::scaleFactor() { - if (up) { - scaleUp(); + // すでに倍率が指定されている場合は、そのまま。 + if (m_scaleFactor > 0) { + return m_scaleFactor; } - else { - scaleDown(); - } -} -double SimpleImageView::scaleFactor(const QSize &size) -{ - double scaleFactor; - if (m_scaleFactor == 0) { - double scaleX, scaleY; - if (m_rotateDeg == 90 || m_rotateDeg == 270) { - scaleX = 1.0 * size.width() / m_imgSrc.height(); - scaleY = 1.0 * size.height() / m_imgSrc.width(); - } - else { - scaleX = 1.0 * size.width() / m_imgSrc.width(); - scaleY = 1.0 * size.height() / m_imgSrc.height(); - } - scaleFactor = (scaleX > scaleY) ? scaleY : scaleX; + // ビューポートに対する適切な倍率を計算する + double scaleFactor, scaleX, scaleY; + if (m_rotateDeg == 90 || m_rotateDeg == 270) { + scaleX = 1.0 * viewport()->width() / m_imgSrc.height(); + scaleY = 1.0 * viewport()->height() / m_imgSrc.width(); } else { - scaleFactor = m_scaleFactor; + scaleX = 1.0 * viewport()->width() / m_imgSrc.width(); + scaleY = 1.0 * viewport()->height() / m_imgSrc.height(); + } + scaleFactor = (scaleX > scaleY) ? scaleY : scaleX; + + // 縮小もしくは等倍の場合 + if (m_scaleFactor == -1) { + return (scaleFactor > 1) ? 1 : scaleFactor; } return scaleFactor; } +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleImageView::sizeChanged +/// +/// サイズ変更後の処理を行います。 +/// void SimpleImageView::sizeChanged() { QString str; @@ -149,28 +98,40 @@ void SimpleImageView::sizeChanged() .arg(m_imgSrc.width()) .arg(m_imgSrc.height()) .arg(m_imgSrc.depth()) - .arg(int(scaleFactor(viewport()->size()) * 100)); - emit fileInfo(str); + .arg(int(scaleFactor() * 100)); + emit statusChanged(str); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleImageView::resizeImage +/// \return 倍率 +/// +/// イメージの拡大・縮小と回転を行います。 +/// double SimpleImageView::resizeImage() { - if (m_imgSrc.isNull()) { - return 1; - } - - double scaleFactor = this->scaleFactor(viewport()->size()); - m_rotateDeg %= 360; - + double scaleFactor = this->scaleFactor(); + QPixmap scaledImg = m_imgSrc.scaled(scaleFactor * m_imgSrc.width(), + scaleFactor * m_imgSrc.height(), + Qt::IgnoreAspectRatio, + Qt::SmoothTransformation); + this->scene()->clear(); + this->scene()->addPixmap(scaledImg); + this->setSceneRect(scaledImg.rect()); this->setTransform(QTransform()); this->translate(width() / 2, height() / 2); this->rotate(m_rotateDeg); - this->scale(scaleFactor, scaleFactor); sizeChanged(); return scaleFactor; } +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleImageView::fitToWindow +/// \param checked メニューのチェック状態 +/// +/// ウィンドウへのフィットを切り替えます。 +/// void SimpleImageView::fitToWindow(bool checked) { if (checked) { @@ -182,92 +143,67 @@ void SimpleImageView::fitToWindow(bool checked) if (!checked) { m_scaleFactor = scaleFactor; } - - sizeChanged(); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleImageView::scaleNormal +/// +/// 等倍で表示します。 +/// void SimpleImageView::scaleNormal() { m_scaleFactor = 1; resizeImage(); - - m_fitToWindow->blockSignals(true); - m_fitToWindow->setChecked(false); - m_fitToWindow->blockSignals(false); -} - -void SimpleImageView::scaleUp() -{ - m_scaleFactor = scaleFactor(viewport()->size()) * 1.25; - resizeImage(); - - m_fitToWindow->blockSignals(true); - m_fitToWindow->setChecked(false); - m_fitToWindow->blockSignals(false); -} - -void SimpleImageView::scaleDown() -{ - m_scaleFactor = scaleFactor(viewport()->size()) * 0.8; - resizeImage(); - - m_fitToWindow->blockSignals(true); - m_fitToWindow->setChecked(false); - m_fitToWindow->blockSignals(false); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleImageView::rotate90 +/// +/// 右に90度回転します。 +/// void SimpleImageView::rotate90() { m_rotateDeg += 90; + m_rotateDeg %= 360; resizeImage(); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleImageView::rotate180 +/// +/// 180度回転します。 +/// void SimpleImageView::rotate180() { m_rotateDeg += 180; + m_rotateDeg %= 360; resizeImage(); } -void SimpleImageView::keyPressEvent(QKeyEvent *event) +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleImageView::resizeEvent +/// \param event +/// +void SimpleImageView::resizeEvent(QResizeEvent *event) { - qDebug() << "SimpleImageView::keyPressEvent();"; - - QString ksq = KeyEventToSequence(event); - - if (ProcessShortcut(ksq, this)) { - event->accept(); - return; - } - - QGraphicsView::keyReleaseEvent(event); - if (IsKeyUpDown(event)) { - event->accept(); - return; - } - - // MainWindowへ - event->ignore(); + resizeImage(); + QGraphicsView::resizeEvent(event); } -void SimpleImageView::contextMenuEvent(QContextMenuEvent *event) +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleImageView::scaleUp +/// +void SimpleImageView::scaleUp() { - qDebug() << "SimpleImageView::contextMenuEvent();"; - - QMenu menu(this); - menu.addAction(m_fitToWindow); - menu.addAction(m_scaleUp); - menu.addAction(m_scaleDown); - menu.addAction(m_scaleNormal); - menu.addSeparator(); - menu.addAction(m_rot90); - menu.addAction(m_rot180); - menu.addSeparator(); - menu.addAction(m_back); - menu.exec(event->globalPos()); + m_scaleFactor = scaleFactor() * 1.25; + resizeImage(); } -void SimpleImageView::resizeEvent(QResizeEvent *event) +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleImageView::scaleDown +/// +void SimpleImageView::scaleDown() { + m_scaleFactor = scaleFactor() * 0.8; resizeImage(); - QGraphicsView::resizeEvent(event); } diff --git a/simpleimageview.h b/simpleimageview.h index 58b6bef..d7ceef7 100644 --- a/simpleimageview.h +++ b/simpleimageview.h @@ -1,53 +1,49 @@ #ifndef SIMPLEIMAGEVIEW_H #define SIMPLEIMAGEVIEW_H +#include "abstractview.h" + #include -class SimpleImageView : public QGraphicsView +class MainWindow; + +class SimpleImageView : public QGraphicsView, public AbstractView { Q_OBJECT public: explicit SimpleImageView(QWidget *parent = 0); - bool setSource(const QString &path); - - void changeScale(bool up); + void initialize(MainWindow *w); + void setSource(const QPixmap &pixmap); private: - QAction *m_back; - QAction *m_fitToWindow; - QAction *m_scaleUp; - QAction *m_scaleDown; - QAction *m_scaleNormal; - QAction *m_rot90; - QAction *m_rot180; - QPixmap m_imgSrc; - double m_scaleFactor; - int m_rotateDeg; + QPixmap m_imgSrc; + QGraphicsScene m_scene; + double m_scaleFactor; + int m_rotateDeg; private: - double scaleFactor(const QSize &size); - void updateActions(); - void sizeChanged(); - double resizeImage(); + double scaleFactor(); + void sizeChanged(); + double resizeImage(); signals: - void viewFinished(); - void fileInfo(const QString &info); + void statusChanged(const QString &info); -private slots: - void fitToWindow(bool checked); - void scaleNormal(); - void scaleUp(); - void scaleDown(); - void rotate90(); - void rotate180(); +public slots: + void fitToWindow(bool checked); + void scaleNormal(); + void rotate90(); + void rotate180(); // QWidget interface protected: - void keyPressEvent(QKeyEvent *event); - void contextMenuEvent(QContextMenuEvent *event); void resizeEvent(QResizeEvent *event); + + // AbstractView interface +public slots: + void scaleUp(); + void scaleDown(); }; #endif // SIMPLEIMAGEVIEW_H diff --git a/simpletextview.cpp b/simpletextview.cpp index deadb64..d78482b 100644 --- a/simpletextview.cpp +++ b/simpletextview.cpp @@ -1,6 +1,6 @@ -#include "common.h" -#include "simpletextview.h" #include "mainwindow.h" +#include "preferences.h" +#include "simpletextview.h" #include #include @@ -11,122 +11,50 @@ #include /////////////////////////////////////////////////////////////////////////////// -/// \brief KeyEventToSequence -/// \param event キーイベントオブジェクト -/// \return キーシーケンスの文字列(Ctrl+C等) +/// \brief SimpleTextView::SimpleTextView +/// \param parent 親ウィジェット /// -/// キーイベントで押されているキーをキーシーケンス文字列に変換します +/// コンストラクタ /// -QString KeyEventToSequence(const QKeyEvent *event) +SimpleTextView::SimpleTextView(QWidget *parent) : + QPlainTextEdit(parent), + AbstractView(), + m_source() { - QString modifier = QString::null; - - if (event->modifiers() & Qt::ShiftModifier) { modifier += "Shift+"; } - if (event->modifiers() & Qt::ControlModifier) { modifier += "Ctrl+"; } - if (event->modifiers() & Qt::AltModifier) { modifier += "Alt+"; } - if (event->modifiers() & Qt::MetaModifier) { modifier += "Meta+"; } - - QString key = QKeySequence(event->key()).toString(); - - return modifier + key; + setReadOnly(true); + setContextMenuPolicy(Qt::NoContextMenu); } /////////////////////////////////////////////////////////////////////////////// -/// \brief IsKeyUpDown -/// \param event キーイベントオブジェクト -/// \return (Up/Down/Home/End)+(!Shift)の場合true +/// \brief SimpleTextView::initialize +/// \param w メインウィンドウオブジェクト /// -/// カーソル移動系のキーが押されたかを判定します +/// 初期化処理を行います。 /// -bool IsKeyUpDown(const QKeyEvent *event) -{ - QString ksq = KeyEventToSequence(event); - - switch (event->key()) { - case Qt::Key_Up: - case Qt::Key_Down: - case Qt::Key_Home: - case Qt::Key_End: - if (event->modifiers() & Qt::ShiftModifier) { - return false; - } - else { - return true; - } - } - return false; -} - -SimpleTextView::SimpleTextView(QWidget *parent) : - QPlainTextEdit(parent), - m_convEUC(NULL), - m_convJIS(NULL), - m_convSJIS(NULL), - m_convUTF8(NULL), - m_convUTF16BE(NULL), - m_convUTF16LE(NULL), - m_copy(NULL), - m_back(NULL) +void SimpleTextView::initialize(MainWindow *w) { - setReadOnly(true); - updateAppearance(); - - setContextMenuPolicy(Qt::DefaultContextMenu); - m_convEUC = new QAction(tr("EUC-JPで再読込"), this); - m_convJIS = new QAction(tr("ISO 2022-JP(JIS)で再読込"), this); - m_convSJIS = new QAction(tr("Shift-JISで再読込"), this); - m_convUTF8 = new QAction(tr("UTF-8で再読込"), this); - m_convUTF16 = new QAction(tr("UTF-16で再読込"), this); - m_convUTF16BE = new QAction(tr("UTF-16BEで再読込"), this); - m_convUTF16LE = new QAction(tr("UTF-16LEで再読込"), this); - m_copy = new QAction(tr("選択範囲をクリップボードにコピー"), this); - m_back = new QAction(tr("戻る"), this); - - m_convEUC->setObjectName("convertFromEUC"); - m_convJIS->setObjectName("convertFromJIS"); - m_convSJIS->setObjectName("convertFromSJIS"); - m_convUTF8->setObjectName("convertFromUTF8"); - m_convUTF16->setObjectName("convertFromUTF16"); - m_convUTF16BE->setObjectName("convertFromUTF16BE"); - m_convUTF16LE->setObjectName("convertFromUTF16LE"); - m_copy->setObjectName("copy"); - m_back->setObjectName("back"); + qDebug() << "SimpleTextView::initialize()"; - m_convEUC->setShortcut(QKeySequence("Ctrl+E")); - m_convJIS->setShortcut(QKeySequence("Ctrl+J")); - m_convSJIS->setShortcut(QKeySequence("Ctrl+S")); - m_convUTF8->setShortcut(QKeySequence("Ctrl+U")); - m_convUTF16->setShortcut(QKeySequence("Ctrl+I")); - m_convUTF16BE->setShortcut(QKeySequence("Ctrl+O")); - m_convUTF16LE->setShortcut(QKeySequence("Ctrl+P")); - m_copy->setShortcut(QKeySequence::Copy); + connect(this, SIGNAL(statusChanged(QString)), w, SLOT(view_statusChanged(QString))); + connect(this, SIGNAL(copyAvailable(bool)), w, SLOT(view_copyAvailable(bool))); - QList shortcuts; - shortcuts << QKeySequence("Return"); - shortcuts << QKeySequence("Backspace"); - m_back->setShortcuts(shortcuts); - - connect(m_convEUC, SIGNAL(triggered()), this, SLOT(convertFromEUC())); - connect(m_convJIS, SIGNAL(triggered()), this, SLOT(convertFromJIS())); - connect(m_convSJIS, SIGNAL(triggered()), this, SLOT(convertFromSJIS())); - connect(m_convUTF8, SIGNAL(triggered()), this, SLOT(convertFromUTF8())); - connect(m_convUTF16, SIGNAL(triggered()), this, SLOT(convertFromUTF16())); - connect(m_convUTF16BE, SIGNAL(triggered()), this, SLOT(convertFromUTF16BE())); - connect(m_convUTF16LE, SIGNAL(triggered()), this, SLOT(convertFromUTF16LE())); - connect(m_copy, SIGNAL(triggered()), this, SLOT(copy())); - connect(m_back, SIGNAL(triggered()), this, SLOT(back())); - - connect(this, SIGNAL(copyAvailable(bool)), this, SLOT(onCopyAvailable(bool))); - - m_copy->setEnabled(false); + installEventFilter(w); } +/////////////////////////////////////////////////////////////////////////////// +/// \brief SimpleTextView::setSource +/// \param source 表示するデータ +/// +/// データを表示します。 +/// void SimpleTextView::setSource(const QByteArray &source) { + qDebug() << "SimpleTextView::setSource()" << source.size(); + m_source = source; if (m_source.size() == 0) { setPlainText(""); - emit fileInfo(""); + emit statusChanged(""); return; } @@ -135,125 +63,56 @@ void SimpleTextView::setSource(const QByteArray &source) setPlainText(codec->toUnicode(m_source)); - emit fileInfo(code.c_str()); -} - -void SimpleTextView::updateAppearance() -{ - QSettings settings; - - QPalette pal = this->palette(); - if (settings.value(IniKey_ViewerInherit).toBool()) { - pal.setColor(QPalette::Base, - settings.value(IniKey_ViewColorBgNormal).value()); - pal.setColor(QPalette::Text, - settings.value(IniKey_ViewColorFgNormal).value()); - } - else { - pal.setColor(QPalette::Base, - settings.value(IniKey_ViewerColorBg).value()); - pal.setColor(QPalette::Text, - settings.value(IniKey_ViewerColorFg).value()); - } - setPalette(pal); - setFont(settings.value(IniKey_ViewerFont).value()); + emit statusChanged(code.c_str()); } void SimpleTextView::convertFromEUC() { QTextCodec *codec = QTextCodec::codecForName("EUC-JP"); setPlainText(codec->toUnicode(m_source)); - emit fileInfo("EUC-JP"); + emit statusChanged("EUC-JP"); } void SimpleTextView::convertFromJIS() { QTextCodec *codec = QTextCodec::codecForName("ISO 2022-JP"); setPlainText(codec->toUnicode(m_source)); - emit fileInfo("ISO 2022-JP"); + emit statusChanged("ISO 2022-JP"); } void SimpleTextView::convertFromSJIS() { QTextCodec *codec = QTextCodec::codecForName("Shift-JIS"); setPlainText(codec->toUnicode(m_source)); - emit fileInfo("Shift-JIS"); + emit statusChanged("Shift-JIS"); } void SimpleTextView::convertFromUTF8() { QTextCodec *codec = QTextCodec::codecForName("UTF-8"); setPlainText(codec->toUnicode(m_source)); - emit fileInfo("UTF-8"); + emit statusChanged("UTF-8"); } void SimpleTextView::convertFromUTF16() { QTextCodec *codec = QTextCodec::codecForName("UTF-16"); setPlainText(codec->toUnicode(m_source)); - emit fileInfo("UTF-16"); + emit statusChanged("UTF-16"); } void SimpleTextView::convertFromUTF16BE() { QTextCodec *codec = QTextCodec::codecForName("UTF-16BE"); setPlainText(codec->toUnicode(m_source)); - emit fileInfo("UTF-16BE"); + emit statusChanged("UTF-16BE"); } void SimpleTextView::convertFromUTF16LE() { QTextCodec *codec = QTextCodec::codecForName("UTF-16LE"); setPlainText(codec->toUnicode(m_source)); - emit fileInfo("UTF-16LE"); -} - -void SimpleTextView::onCopyAvailable(bool yes) -{ - m_copy->setEnabled(yes); -} - -void SimpleTextView::back() -{ - emit viewFinished(); -} - -void SimpleTextView::keyPressEvent(QKeyEvent *event) -{ - QString ksq = KeyEventToSequence(event); - - if (ProcessShortcut(ksq, this)) { - event->accept(); - return; - } - - QPlainTextEdit::keyPressEvent(event); - if (IsKeyUpDown(event)) { - event->accept(); - return; - } - - // MainWindowへ - event->ignore(); -} - - -void SimpleTextView::contextMenuEvent(QContextMenuEvent *event) -{ - qDebug() << "SimpleTextView::contextMenuEvent();"; - - QMenu menu(this); - menu.addAction(m_convEUC); - menu.addAction(m_convJIS); - menu.addAction(m_convSJIS); - menu.addAction(m_convUTF8); - menu.addAction(m_convUTF16BE); - menu.addAction(m_convUTF16LE); - menu.addSeparator(); - menu.addAction(m_copy); - menu.addSeparator(); - menu.addAction(m_back); - menu.exec(event->globalPos()); + emit statusChanged("UTF-16LE"); } // http://dobon.net/vb/dotnet/string/detectcode.html より拝借 @@ -394,3 +253,24 @@ std::string SimpleTextView::detectCode(const QByteArray &bytes) return "UTF-8"; #endif } + + +void SimpleTextView::scaleUp() +{ + qDebug() << "SimpleTextView::scaleUp()"; + + Preferences prefs(this); + QFont font = prefs.getTextViewFont(); + font.setPointSize(font.pointSize() + 1); + prefs.setTextViewFont(font); +} + +void SimpleTextView::scaleDown() +{ + qDebug() << "SimpleTextView::scaleDown()"; + + Preferences prefs(this); + QFont font = prefs.getTextViewFont(); + font.setPointSize(font.pointSize() - 1); + prefs.setTextViewFont(font); +} diff --git a/simpletextview.h b/simpletextview.h index 5e4626f..02056f1 100644 --- a/simpletextview.h +++ b/simpletextview.h @@ -1,52 +1,42 @@ #ifndef SIMPLETEXTVIEW_H #define SIMPLETEXTVIEW_H +#include "abstractview.h" + #include -class SimpleTextView : public QPlainTextEdit +class MainWindow; + +class SimpleTextView : public QPlainTextEdit, public AbstractView { Q_OBJECT public: explicit SimpleTextView(QWidget *parent = 0); - void setSource(const QByteArray &source); - void updateAppearance(); + void initialize(MainWindow *w); + void setSource(const QByteArray &source); private: - QAction *m_convEUC; - QAction *m_convJIS; - QAction *m_convSJIS; - QAction *m_convUTF8; - QAction *m_convUTF16; - QAction *m_convUTF16BE; - QAction *m_convUTF16LE; - QAction *m_copy; - QAction *m_back; QByteArray m_source; - std::string detectCode(const QByteArray &bytes); + static std::string detectCode(const QByteArray &bytes); signals: - void viewFinished(); - void fileInfo(const QString &info); + void statusChanged(const QString &info); public slots: - -private slots: - void convertFromEUC(); - void convertFromJIS(); - void convertFromSJIS(); - void convertFromUTF8(); - void convertFromUTF16(); - void convertFromUTF16BE(); - void convertFromUTF16LE(); - void onCopyAvailable(bool yes); - void back(); - - // QWidget interface -protected: - void keyPressEvent(QKeyEvent *event); - void contextMenuEvent(QContextMenuEvent *event); + void convertFromEUC(); + void convertFromJIS(); + void convertFromSJIS(); + void convertFromUTF8(); + void convertFromUTF16(); + void convertFromUTF16BE(); + void convertFromUTF16LE(); + + // AbstractView interface +public: + void scaleUp(); + void scaleDown(); }; #endif // SIMPLETEXTVIEW_H diff --git a/sortdialog.cpp b/sortdialog.cpp index fd3b967..9f40f7a 100644 --- a/sortdialog.cpp +++ b/sortdialog.cpp @@ -1,13 +1,11 @@ -#include "common.h" +#include "foldermodel.h" #include "sortdialog.h" #include "ui_sortdialog.h" -#include -#include SortDialog::SortDialog(QWidget *parent) : QDialog(parent), ui(new Ui::SortDialog), - m_RightOrLeft() + m_model(NULL) { ui->setupUi(this); } @@ -17,87 +15,84 @@ SortDialog::~SortDialog() delete ui; } -void SortDialog::setRightOrLeft(const QString &s) +void SortDialog::setModel(FolderModel *m) { - QSettings settings; + m_model = m; + QDir::SortFlags sort = m->sorting(); - m_RightOrLeft = s; - int sortBy = settings.value(m_RightOrLeft + slash + IniKey_SortBy).toInt(); - if (sortBy == SortByType) { - ui->sortByType->setChecked(true); + if (sort & QDir::Time) { + ui->sortByDate->setChecked(true); + if (sort & QDir::Reversed) + ui->orderAsc->setChecked(true); } - else if (sortBy == SortBySize) { + else if (sort & QDir::Size) { ui->sortBySize->setChecked(true); + if (sort & QDir::Reversed) + ui->orderAsc->setChecked(true); } - else if (sortBy == SortByDate) { - ui->sortByDate->setChecked(true); + else if (sort & QDir::Type) { + ui->sortByType->setChecked(true); + if (sort & QDir::Reversed) + ui->orderDesc->setChecked(true); } else { ui->sortByName->setChecked(true); + if (sort & QDir::Reversed) + ui->orderDesc->setChecked(true); } - int orderBy = settings.value(m_RightOrLeft + slash + IniKey_OrderBy).toInt(); - if (orderBy == OrderByDesc) { - ui->orderDesc->setChecked(true); - } - else { - ui->orderAsc->setChecked(true); - } - - int putDirs = settings.value(m_RightOrLeft + slash + IniKey_PutDirs).toInt(); - if (putDirs == PutDirsDefault) { - ui->dirsDefault->setChecked(true); + if (sort & QDir::DirsFirst) { + ui->dirsFirst->setChecked(true); } - else if (putDirs == PutDirsLast) { + else if (sort & QDir::DirsLast) { ui->dirsLast->setChecked(true); } else { - ui->dirsFirst->setChecked(true); + ui->dirsLast->setChecked(true); } - bool ignoreCase = settings.value(m_RightOrLeft + slash + IniKey_IgnoreCase).toBool(); - ui->ignoreCase->setChecked(ignoreCase); + if (sort & QDir::IgnoreCase) + ui->ignoreCase->setChecked(true); } + void SortDialog::accept() { - QSettings settings; + QDir::SortFlags sort; - QString key = m_RightOrLeft + slash + IniKey_SortBy; if (ui->sortByDate->isChecked()) { - settings.setValue(key, SortByDate); - } - else if (ui->sortByName->isChecked()) { - settings.setValue(key, SortByName); + sort |= QDir::Time; + if (ui->orderAsc->isChecked()) + sort |= QDir::Reversed; } else if (ui->sortBySize->isChecked()) { - settings.setValue(key, SortBySize); + sort |= QDir::Size; + if (ui->orderAsc->isChecked()) + sort |= QDir::Reversed; } - else { - settings.setValue(key, SortByType); - } - - key = m_RightOrLeft + slash + IniKey_OrderBy; - if (ui->orderAsc->isChecked()) { - settings.setValue(key, OrderByAsc); + else if (ui->sortByType->isChecked()) { + sort |= QDir::Type; + if (ui->orderDesc->isChecked()) + sort |= QDir::Reversed; } else { - settings.setValue(key, OrderByDesc); + sort |= QDir::Name; + if (ui->orderDesc->isChecked()) + sort |= QDir::Reversed; } - key = m_RightOrLeft + slash + IniKey_PutDirs; - if (ui->dirsDefault->isChecked()) { - settings.setValue(key, PutDirsDefault); - } - else if (ui->dirsFirst->isChecked()) { - settings.setValue(key, PutDirsFirst); + if (ui->dirsFirst->isChecked()) { + sort |= QDir::DirsFirst; } - else { - settings.setValue(key, PutDirsLast); + else if (ui->dirsLast->isChecked()) { + sort |= QDir::DirsLast; } - key = m_RightOrLeft + slash + IniKey_IgnoreCase; - settings.setValue(key, ui->ignoreCase->isChecked()); + if (ui->ignoreCase->isChecked()) + sort |= QDir::IgnoreCase; + + m_model->setSorting(sort); + m_model->refresh(); QDialog::accept(); } diff --git a/sortdialog.h b/sortdialog.h index 04b5ce5..79c4988 100644 --- a/sortdialog.h +++ b/sortdialog.h @@ -2,6 +2,7 @@ #define SORTDIALOG_H #include +class FolderModel; namespace Ui { class SortDialog; @@ -15,14 +16,14 @@ public: explicit SortDialog(QWidget *parent = 0); ~SortDialog(); - void setRightOrLeft(const QString &s); + void setModel(FolderModel *m); protected: void accept(); private: Ui::SortDialog *ui; - QString m_RightOrLeft; + FolderModel *m_model; }; #endif // SORTDIALOG_H diff --git a/thumbnaildelegate.cpp b/thumbnaildelegate.cpp new file mode 100644 index 0000000..fcb79c6 --- /dev/null +++ b/thumbnaildelegate.cpp @@ -0,0 +1,90 @@ +#include "foldermodel.h" +#include "thumbnaildelegate.h" + +#include +#include +#include +#include + +ThumbnailDelegate::ThumbnailDelegate(QObject *parent) : + QStyledItemDelegate(parent), + m_pixmapCache() +{ +} + +void ThumbnailDelegate::model_Reset() +{ + m_pixmapCache.clear(); +} + +void ThumbnailDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + const FolderModel *model = static_cast(index.model()); + bool checked = model->data(index, Qt::CheckStateRole).toInt() == Qt::Checked; + + // マーク + if (checked) { + painter->fillRect(option.rect, model->data(index, Qt::BackgroundRole).value()); + } + // ハイライト + if (option.state & QStyle::State_Selected) { + painter->fillRect(option.rect, option.palette.highlight()); + } + + // ファイル名 + QFont font = model->data(index, Qt::FontRole).value(); + QFontMetrics fm(font); + QSize padding(20, fm.height()); + QRect rc(option.rect); + rc.setLeft(rc.left() + padding.width()); + QString name = fm.elidedText(model->fileName(index), Qt::ElideMiddle, rc.width()); + painter->setFont(font); + painter->setPen(model->data(index, Qt::ForegroundRole).value().color()); + painter->drawText(rc, name, Qt::AlignCenter | Qt::AlignBottom); + + // チェックボックス + if (model->flags(index) & Qt::ItemIsUserCheckable) { + QStyleOptionButton optBtn; + optBtn.rect = option.rect; + optBtn.state = option.state; + if (checked) + optBtn.state |= QStyle::State_On; + qApp->style()->drawControl(QStyle::CE_CheckBox, &optBtn, painter); + } + + // アイコンまたは画像 + QSize size(option.rect.size()); + size -= padding; + if (m_pixmapCache.find(model->fileName(index)) == m_pixmapCache.end()) { + QPixmap pixmap(model->filePath(index)); + if (pixmap.isNull()) { + pixmap = model->fileIcon(index).pixmap(32, 32); + } + if (pixmap.width() > size.width() || pixmap.height() > size.height()) { + double scaleX = 1.0 * size.width() / pixmap.width(); + double scaleY = 1.0 * size.height() / pixmap.height(); + double scaleFactor = (scaleX > scaleY) ? scaleY : scaleX; + pixmap = pixmap.scaled(pixmap.size() * scaleFactor, + Qt::IgnoreAspectRatio, + Qt::SmoothTransformation); + } + const_cast(this)->m_pixmapCache[model->fileName(index)] = pixmap; + } + const QPixmap &pixmap = m_pixmapCache[model->fileName(index)]; + + painter->drawPixmap(padding.width() + option.rect.left() + (size.width() - pixmap.width()) / 2, + option.rect.top() + (size.height() - pixmap.height()) / 2, + pixmap); + + //QStyledItemDelegate::paint(painter, option, index); +} + +QSize ThumbnailDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(option); + + const FolderModel *model = static_cast(index.model()); + int pointSize = model->data(index, Qt::FontRole).value().pointSize(); + + return QSize(pointSize * 10, pointSize * 10 * 11 / 16); +} diff --git a/thumbnaildelegate.h b/thumbnaildelegate.h new file mode 100644 index 0000000..75207b6 --- /dev/null +++ b/thumbnaildelegate.h @@ -0,0 +1,27 @@ +#ifndef THUMBNAILDELEGATE_H +#define THUMBNAILDELEGATE_H + +#include + +class ThumbnailDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + explicit ThumbnailDelegate(QObject *parent = 0); + +private: + typedef QMap ImageMap; + ImageMap m_pixmapCache; + +signals: + +public slots: + void model_Reset(); + + // QAbstractItemDelegate interface +public: + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; +}; + +#endif // THUMBNAILDELEGATE_H diff --git a/thumbnailview.cpp b/thumbnailview.cpp new file mode 100644 index 0000000..be1ef6c --- /dev/null +++ b/thumbnailview.cpp @@ -0,0 +1,61 @@ +#include "mainwindow.h" +#include "thumbnaildelegate.h" +#include "thumbnailview.h" + +#include + +/////////////////////////////////////////////////////////////////////////////// +/// \brief ThumbnailView::ThumbnailView +/// \param parent 親ウィジェット +/// +/// コンストラクタ +/// +ThumbnailView::ThumbnailView(QWidget *parent) : + QListView(parent) +{ + setItemDelegate(new ThumbnailDelegate(this)); + setSpacing(12); +} + +/////////////////////////////////////////////////////////////////////////////// +/// \brief ThumbnailView::initialize +/// \param w メインウィンドウオブジェクト +/// +/// 初期化処理を行います。 +/// +void ThumbnailView::initialize(MainWindow *w) +{ + qDebug() << "ThumbnailView::initialize()"; + + connect(this, SIGNAL(doubleClicked(QModelIndex)), w, SLOT(onOpen(QModelIndex))); + connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), + w, SLOT(view_currentChanged(QModelIndex,QModelIndex))); + + installEventFilter(w); + viewport()->installEventFilter(w); +} + +void ThumbnailView::scaleUp() +{ + // TODO +} + +void ThumbnailView::scaleDown() +{ + // TODO +} + +void ThumbnailView::setModel(QAbstractItemModel *model) +{ + ThumbnailDelegate *delegate = static_cast(itemDelegate()); + if (this->model()) { + this->model()->disconnect(delegate); + } + + QListView::setModel(model); + + if (this->model()) { + connect(this->model(), SIGNAL(modelReset()), delegate, SLOT(model_Reset())); + } +} + diff --git a/thumbnailview.h b/thumbnailview.h new file mode 100644 index 0000000..d5c3c27 --- /dev/null +++ b/thumbnailview.h @@ -0,0 +1,34 @@ +#ifndef THUMBNAILVIEW_H +#define THUMBNAILVIEW_H + +#include "abstractview.h" + +#include + +class MainWindow; + +class ThumbnailView : public QListView, public AbstractView +{ + Q_OBJECT +public: + explicit ThumbnailView(QWidget *parent = 0); + + void initialize(MainWindow *w); + +signals: + +public slots: + + + // AbstractView interface +public: + void scaleUp(); + void scaleDown(); + + // QAbstractItemView interface +public: + void setModel(QAbstractItemModel *model); + +}; + +#endif // THUMBNAILVIEW_H diff --git a/win32.cpp b/win32.cpp new file mode 100644 index 0000000..8fd8a27 --- /dev/null +++ b/win32.cpp @@ -0,0 +1,22 @@ +//#define Q_OS_WIN + +#include "win32.h" + +#ifdef Q_OS_WIN + #include +#endif + +bool Win32::hasSystemAttribute(const QString &path) +{ +#ifdef Q_OS_WIN + DWORD dwFlags = ::GetFileAttributes(path.toStdWString().c_str()); + if (dwFlags != DWORD(-1) && + (dwFlags & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM) + { + return true; + } +#else + Q_UNUSED(path); +#endif + return false; +} diff --git a/win32.h b/win32.h new file mode 100644 index 0000000..74228ab --- /dev/null +++ b/win32.h @@ -0,0 +1,11 @@ +#ifndef WIN32_H +#define WIN32_H + +#include + +namespace Win32 { + +bool hasSystemAttribute(const QString &path); + +} +#endif // WIN32_H -- 2.11.0