OSDN Git Service

スレッド処理を整理
[gefu/Gefu.git] / foldermodel.cpp
index 9d881ef..eb686d7 100644 (file)
@@ -1,13 +1,14 @@
 #include "global.h"\r
 #include "preferences.h"\r
+#include "thumbnailworker.h"\r
 #include "win32.h"\r
 #include "foldermodel.h"\r
 \r
+#include <QApplication>\r
 #include <QDateTime>\r
 #include <QDebug>\r
-#include <QApplication>\r
-#include <QSettings>\r
 #include <QPalette>\r
+#include <QThread>\r
 \r
 FolderModel* FolderModel::m_activeModel = NULL;\r
 \r
@@ -25,12 +26,47 @@ FolderModel::FolderModel(QObject *parent) :
     m_IconProvider(),\r
     m_fsWatcher(this),\r
     m_history(),\r
-    m_historyPos(-1)\r
+    m_historyPos(-1),\r
+    m_worker(),\r
+    m_pixmapCache(),\r
+    m_lastModifiedCache(),\r
+    m_pixmapCacheMutex(),\r
+    m_Palette(),\r
+    m_font()\r
 {\r
+    // サムネイル生成用スレッドを初期化する\r
+    m_worker = new ThumbnailWorker();\r
+    connect(m_worker, SIGNAL(resultReady(QString,QPixmap)), this, SLOT(thumbnail_Ready(QString,QPixmap)));\r
+    m_worker->start();\r
+\r
     connect(&m_fsWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(fsWatcher_directoryChanged(QString)));\r
 }\r
 \r
 ///////////////////////////////////////////////////////////////////////////////\r
+/// \brief FolderModel::~FolderModel\r
+///\r
+/// デストラクタ\r
+///\r
+FolderModel::~FolderModel()\r
+{\r
+    m_worker->abort();\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+/// \brief FolderModel::clearPixmapCache\r
+///\r
+/// サムネイルキャッシュをクリアしたように見せかけます。\r
+///\r
+void FolderModel::clearPixmapCache()\r
+{\r
+    beginResetModel();\r
+//    m_pixmapCacheMutex.lock();\r
+//    m_pixmapCache.clear();\r
+//    m_pixmapCacheMutex.unlock();\r
+    endResetModel();\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
 /// \brief FolderModel::fileIcon\r
 /// \param index    アイテムのインデックス\r
 /// \return アイコンを返します。\r
@@ -101,6 +137,37 @@ QModelIndex FolderModel::mkdir(const QString &name)
 }\r
 \r
 ///////////////////////////////////////////////////////////////////////////////\r
+/// \brief FolderModel::pixmap\r
+/// \param index    アイテムのインデックス\r
+/// \param size     要求サイズ\r
+/// \return 画像またはアイコンを返します。\r
+///\r
+QPixmap FolderModel::pixmap(const QModelIndex &index, const QSize &size) const\r
+{\r
+    QPixmap pixmap;\r
+    const_cast<FolderModel*>(this)->m_pixmapCacheMutex.lock();\r
+    if (m_pixmapCache.find(filePath(index)) != m_pixmapCache.end()) {\r
+        pixmap = m_pixmapCache[filePath(index)];\r
+    }\r
+    const_cast<FolderModel*>(this)->m_pixmapCacheMutex.unlock();\r
+\r
+    if (!pixmap.isNull()) {\r
+        double scaleX = 1.0 * size.width() / pixmap.width();\r
+        double scaleY = 1.0 * size.height() / pixmap.height();\r
+        double scaleFactor = qMin(scaleX, scaleY);\r
+        if (scaleFactor > 1) {\r
+            return pixmap;\r
+        }\r
+        return pixmap.scaled(pixmap.size() * scaleFactor,\r
+                             Qt::IgnoreAspectRatio,\r
+                             Qt::SmoothTransformation);\r
+    }\r
+\r
+    // とりあえずアイコンを返す。\r
+    return fileIcon(index).pixmap(32, 32);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
 /// \brief FolderModel::search\r
 /// \param value    検索する文字列\r
 /// \param start    開始位置\r
@@ -180,6 +247,11 @@ void FolderModel::setRootPath(const QString &path, bool addHistory)
                 m_history << m_dir.absolutePath();\r
                 m_historyPos = m_history.size() - 1;\r
             }\r
+            m_worker->clearPath();\r
+            m_pixmapCacheMutex.lock();\r
+            m_pixmapCache.clear();\r
+            m_pixmapCacheMutex.unlock();\r
+            m_lastModifiedCache.clear();\r
         }\r
 \r
         foreach (const QFileInfo &fi, list) {\r
@@ -199,6 +271,12 @@ void FolderModel::setRootPath(const QString &path, bool addHistory)
             if (m_checkStates.find(fi.fileName()) == m_checkStates.end()) {\r
                 m_checkStates[fi.fileName()] = Qt::Unchecked;\r
             }\r
+            if (m_lastModifiedCache.find(fi.fileName()) == m_lastModifiedCache.end() ||\r
+                m_lastModifiedCache[fi.fileName()] != fi.lastModified())\r
+            {\r
+                m_lastModifiedCache[fi.fileName()] = fi.lastModified();\r
+                m_worker->addPath(fi.absoluteFilePath());\r
+            }\r
         }\r
     }\r
     catch (const QString &s) {\r
@@ -235,6 +313,25 @@ QModelIndex FolderModel::touch(const QString &name)
 }\r
 \r
 ///////////////////////////////////////////////////////////////////////////////\r
+/// \brief FolderModel::updateAppearance\r
+///\r
+/// 外観を変更します。\r
+///\r
+void FolderModel::updateAppearance(const Preferences &prefs)\r
+{\r
+    qDebug() << "FolderModel::updateAppearance()";\r
+\r
+    m_font = prefs.getFolderViewFont();\r
+    m_Palette.setColor(QPalette::Base, prefs.folderViewBgColor(isActive()));\r
+    m_Palette.setColor(QPalette::Text, prefs.folderViewFgColor(isActive()));\r
+    m_Palette.setColor(QPalette::Highlight, prefs.folderViewMarkedBgColor(isActive()));\r
+    m_Palette.setColor(QPalette::HighlightedText, prefs.folderViewMarkedFgColor(isActive()));\r
+    m_Palette.setColor(QPalette::Dark, prefs.folderViewHiddenColor(isActive()));\r
+    m_Palette.setColor(QPalette::Light, prefs.folderViewReadOnlyColor(isActive()));\r
+    m_Palette.setColor(QPalette::Mid, prefs.folderViewSystemColor(isActive()));\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
 /// \brief FolderModel::activeModel\r
 /// \return アクティブなモデルを返します。\r
 ///\r
@@ -364,6 +461,29 @@ void FolderModel::onMarkInvert()
     emit dataChanged(index(0, 0), index(rowCount(), columnCount()));\r
 }\r
 \r
+///////////////////////////////////////////////////////////////////////////////\r
+/// \brief FolderModel::thumbnail_Ready\r
+/// \param path     ファイルパス\r
+/// \param pixmap   サムネイル画像\r
+///\r
+/// サムネイルの生成終了時の処理を行います。\r
+///\r
+void FolderModel::thumbnail_Ready(const QString &path, const QPixmap &pixmap)\r
+{\r
+    qDebug() << "FolderModel::thumbnail_Ready()" << path;\r
+    QFileInfo fi(path);\r
+    if (fi.absolutePath() == m_dir.absolutePath()) {\r
+        m_pixmapCacheMutex.lock();\r
+        m_pixmapCache[path] = pixmap;\r
+        m_pixmapCacheMutex.unlock();\r
+\r
+        QModelIndex index = search(fi.fileName());\r
+        if (index.isValid()) {\r
+            emit dataChanged(index, index);\r
+        }\r
+    }\r
+}\r
+\r
 int FolderModel::rowCount(const QModelIndex &parent) const\r
 {\r
     Q_UNUSED(parent);\r
@@ -382,8 +502,6 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const
         return QVariant();\r
     }\r
 \r
-    Preferences prefs(const_cast<FolderModel*>(this));\r
-\r
     switch (role) {\r
     case Qt::DisplayRole:\r
         switch (index.column()) {\r
@@ -417,7 +535,7 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const
         break;\r
 \r
     case Qt::FontRole:\r
-        return prefs.getFolderViewFont();\r
+        return m_font;\r
 \r
     case Qt::TextAlignmentRole:\r
         switch (index.column()) {\r
@@ -429,24 +547,24 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const
 \r
     case Qt::BackgroundRole:\r
         if (isMarked(index)) {\r
-            return QBrush(prefs.folderViewMarkedBgColor(isActive()));\r
+            return marked();\r
         }\r
-        return QBrush(prefs.folderViewBgColor(isActive()));\r
+        return base();\r
 \r
     case Qt::ForegroundRole:\r
         if (isMarked(index)) {\r
-            return QBrush(prefs.folderViewMarkedFgColor(isActive()));\r
+            return markedText();\r
         }\r
         if (fileName(index) != ".." && Win32::hasSystemAttribute(filePath(index))) {\r
-            return QBrush(prefs.folderViewSystemColor(isActive()));\r
+            return system();\r
         }\r
         if (fileName(index) != ".." && fileInfo(index).isHidden()) {\r
-            return QBrush(prefs.folderViewHiddenColor(isActive()));\r
+            return hidden();\r
         }\r
         if (fileName(index) != ".." && !fileInfo(index).isWritable()) {\r
-            return QBrush(prefs.folderViewReadOnlyColor(isActive()));\r
+            return readOnly();\r
         }\r
-        return QBrush(prefs.folderViewFgColor(isActive()));\r
+        return text();\r
 \r
     case Qt::CheckStateRole:\r
         if (index.column() == Name && fileName(index) != "..") {\r