OSDN Git Service

Ver0.19
[gefu/Gefu.git] / filetablemodel.cpp
1 #include "common.h"\r
2 #include "filetablemodel.h"\r
3 \r
4 #include <QDateTime>\r
5 #include <QDebug>\r
6 #include <QApplication>\r
7 #include <QSettings>\r
8 #include <QPalette>\r
9 #ifdef Q_OS_WIN32\r
10     #include <windows.h>\r
11 #endif\r
12 \r
13 FileTableModel::FileTableModel(QObject *parent) :\r
14     QAbstractTableModel(parent),\r
15     m_dir(),\r
16     m_fileInfoList(),\r
17     m_checkStates(),\r
18     m_IconFactory(),\r
19     m_fsWatcher(this),\r
20     m_font(),\r
21     m_NormalBrush(),\r
22     m_NormalTextBrush(),\r
23     m_MarkBrush(),\r
24     m_MarkTextBrush(),\r
25     m_SystemBrush(),\r
26     m_HiddenBrush(),\r
27     m_ReadonlyBrush()\r
28 {\r
29     // デフォルトフィルタを設定する\r
30     setFilter(QDir::NoDot | QDir::AllDirs | QDir::Files);\r
31 }\r
32 \r
33 bool FileTableModel::setPath(const QString &path)\r
34 {\r
35     qDebug() << "FileTableModel::setPath" << path;\r
36 \r
37     if (!QFileInfo::exists(path)) {\r
38         qDebug() << "パスが存在しません";\r
39         qDebug() << path;\r
40         return false;\r
41     }\r
42     QFileInfo info(path);\r
43     if (!info.isDir()) {\r
44         qDebug() << "フォルダではありません";\r
45         qDebug() << path;\r
46         return false;\r
47     }\r
48 \r
49     beginResetModel();\r
50 \r
51     m_dir.setPath(path);\r
52     m_fileInfoList = m_dir.entryInfoList();\r
53     m_checkStates.clear();\r
54 \r
55     if (m_fileInfoList.isEmpty()) {\r
56         qDebug() << "ファイルリストを取得できません";\r
57         qDebug() << path;\r
58     }\r
59     else {\r
60         QFileInfoList::iterator it;\r
61         for (it = m_fileInfoList.begin(); it != m_fileInfoList.end(); ) {\r
62 #ifdef Q_OS_WIN32\r
63             if (!(filter() & QDir::System)){\r
64                 DWORD dwFlags = ::GetFileAttributes(\r
65                             it->absoluteFilePath().toStdWString().c_str());\r
66                 if (dwFlags != DWORD(-1) && it->fileName() != ".." &&\r
67                     ((dwFlags & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM))\r
68                 {\r
69                     qDebug() << it->fileName() << " is system file.";\r
70                     it = m_fileInfoList.erase(it);\r
71                     continue;\r
72                 }\r
73             }\r
74 #endif\r
75             if (it->fileName() == "..") {\r
76                 if (m_dir.isRoot()) {\r
77                     qDebug() << m_dir.absolutePath() << " is root.";\r
78                     it = m_fileInfoList.erase(it);\r
79                     continue;\r
80                 }\r
81             }\r
82             it++;\r
83         }\r
84         // ソート方法によらず、".."は必ず先頭にする\r
85         QFileInfoList::iterator itRoot = m_fileInfoList.end();\r
86         for (it = m_fileInfoList.begin(); it != m_fileInfoList.end(); it++) {\r
87             if (it->fileName() == "..") {\r
88                 itRoot = it;\r
89                 break;\r
90             }\r
91         }\r
92         if (itRoot != m_fileInfoList.end()) {\r
93             QFileInfo info(*itRoot);\r
94             m_fileInfoList.erase(itRoot);\r
95             m_fileInfoList.push_front(info);\r
96         }\r
97     }\r
98 \r
99     m_checkStates.resize(m_fileInfoList.size());\r
100     m_checkStates.fill(Qt::Unchecked);\r
101 \r
102     m_fsWatcher.addPath(path);\r
103     connect(&m_fsWatcher, SIGNAL(directoryChanged(QString)),\r
104             this, SLOT(directoryChange(QString)));\r
105 \r
106     endResetModel();\r
107 \r
108     emit dataChanged(QModelIndex(), QModelIndex());\r
109 \r
110     return !m_fileInfoList.isEmpty();\r
111 }\r
112 \r
113 QFileInfo FileTableModel::fileInfo(const QModelIndex &index) const\r
114 {\r
115     qDebug() << "FileTableModel::fileInfo()" << index;\r
116 \r
117     if (index.isValid()) {\r
118         return m_fileInfoList[index.row()];\r
119     }\r
120     return QFileInfo();\r
121 }\r
122 \r
123 void FileTableModel::updateAppearance(bool darker)\r
124 {\r
125     qDebug() << "FileTableModel::updateAppearance();" << darker;\r
126 \r
127     QSettings settings;\r
128     int darkness = 100;\r
129     if (darker) {\r
130         darkness += settings.value(IniKey_Darkness).toInt();\r
131     }\r
132     m_font = settings.value(IniKey_ViewFont).value<QFont>();\r
133 \r
134     m_NormalBrush = QBrush(settings.value(IniKey_ViewColorBgNormal).value<QColor>().darker(darkness));\r
135     m_NormalTextBrush = QBrush(settings.value(IniKey_ViewColorFgNormal).value<QColor>().darker(darkness));\r
136     m_MarkBrush = QBrush(settings.value(IniKey_ViewColorBgMark).value<QColor>().darker(darkness));\r
137     m_MarkTextBrush = QBrush(settings.value(IniKey_ViewColorFgMark).value<QColor>().darker(darkness));\r
138     m_SystemBrush = QBrush(settings.value(IniKey_ViewColorFgSystem).value<QColor>().darker(darkness));\r
139     m_HiddenBrush = QBrush(settings.value(IniKey_ViewColorFgHidden).value<QColor>().darker(darkness));\r
140     m_ReadonlyBrush = QBrush(settings.value(IniKey_ViewColorFgReadonly).value<QColor>().darker(darkness));\r
141     m_ReadonlyBrush = QBrush(settings.value(IniKey_ViewColorFgReadonly).value<QColor>().darker(darkness));\r
142 }\r
143 \r
144 void FileTableModel::directoryChange(const QString &path)\r
145 {\r
146     qDebug() << "FileTableModel::directoryChange" << path;\r
147 \r
148     m_fsWatcher.removePath(m_dir.absolutePath());\r
149     setPath(path);\r
150 }\r
151 \r
152 int FileTableModel::rowCount(const QModelIndex &parent) const\r
153 {\r
154     Q_UNUSED(parent);\r
155     return m_fileInfoList.size();\r
156 }\r
157 \r
158 int FileTableModel::columnCount(const QModelIndex &parent) const\r
159 {\r
160     Q_UNUSED(parent);\r
161     return 5;\r
162 }\r
163 \r
164 QVariant FileTableModel::data(const QModelIndex &index, int role) const\r
165 {\r
166     if (!index.isValid()) {\r
167         return QVariant();\r
168     }\r
169 \r
170     const QFileInfo &info = m_fileInfoList.at(index.row());\r
171     int checked = m_checkStates.at(index.row());\r
172 \r
173     switch (role) {\r
174     case Qt::DisplayRole:\r
175         switch (index.column()) {\r
176         case 0: // チェックボックス\r
177             return QString("");\r
178 \r
179         case 1: // ファイル名\r
180             if (info.isDir()) {\r
181                 return info.fileName();\r
182             }\r
183             if (info.fileName().left(1) == ".") {   // "."で始まるファイル\r
184                 int pos = info.fileName().lastIndexOf(".");\r
185                 if (pos == 0) {\r
186                     return info.fileName();\r
187                 }\r
188             }\r
189             return info.completeBaseName();\r
190 \r
191         case 2: // 拡張子\r
192             if (info.isDir()) {\r
193                 return QString();\r
194             }\r
195             if (info.fileName().left(1) == ".") {   // "."で始まるファイル\r
196                 int pos = info.fileName().lastIndexOf(".");\r
197                 if (pos == 0) {\r
198                     return QString();\r
199                 }\r
200             }\r
201             return info.suffix();\r
202 \r
203         case 3: // サイズ\r
204             if (info.isDir()) {\r
205                 return QString("<DIR>");\r
206             }\r
207             else {\r
208                 return FilesizeToString(info.size());\r
209             }\r
210             break;\r
211 \r
212         case 4: // 更新日時\r
213             return info.lastModified().toString("yy/MM/dd hh:mm");\r
214         }\r
215         break;\r
216 \r
217     case Qt::DecorationRole:\r
218         if (index.column() == 1) {\r
219             if (info.fileName() == "..") {\r
220                 return QIcon(":/images/Up.png");\r
221             }\r
222             else {\r
223                 // infoを使うと、正しいアイコンが取れない場合がある…なぜ?\r
224 //                return m_IconFactory.icon(QFileInfo(info.absoluteFilePath()));\r
225                 return m_IconFactory.icon(QFileInfo(info));\r
226             }\r
227         }\r
228         break;\r
229 \r
230     case Qt::FontRole:\r
231         return m_font;\r
232 \r
233     case Qt::TextAlignmentRole:\r
234         switch (index.column()) {\r
235         case 3:\r
236         case 4:\r
237             return Qt::AlignRight + Qt::AlignVCenter;\r
238         default:\r
239             return Qt::AlignLeft + Qt::AlignVCenter;\r
240         }\r
241         break;\r
242 \r
243     case Qt::BackgroundRole:\r
244         if (checked) {\r
245             return m_MarkBrush;\r
246         }\r
247         return m_NormalBrush;\r
248 \r
249     case Qt::ForegroundRole:\r
250         if (checked) {\r
251             return m_MarkTextBrush;\r
252         }\r
253 #ifdef Q_OS_WIN32\r
254         {\r
255             DWORD dwFlags = ::GetFileAttributes(\r
256                         info.absoluteFilePath().toStdWString().c_str());\r
257             if (dwFlags != DWORD(-1) && (dwFlags & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM)\r
258             {\r
259                 return m_SystemBrush;\r
260             }\r
261         }\r
262 #endif\r
263         if (info.isHidden() && info.fileName() != "..") {\r
264             return m_HiddenBrush;\r
265         }\r
266         if (!info.isWritable()) {\r
267             return m_ReadonlyBrush;\r
268         }\r
269         return m_NormalTextBrush;\r
270 \r
271     case Qt::CheckStateRole:\r
272         if (index.column() == 0 && info.fileName() != "..") {\r
273             return checked;\r
274         }\r
275         break;\r
276     }\r
277 \r
278     return QVariant();\r
279 }\r
280 \r
281 QVariant FileTableModel::headerData(int section, Qt::Orientation orientation, int role) const\r
282 {\r
283     if (role == Qt::DisplayRole) {\r
284         if (orientation == Qt::Horizontal) {\r
285             switch (section) {\r
286             case 0: return QString("");\r
287             case 1: return tr("名前");\r
288             case 2: return tr("拡張子");\r
289             case 3: return tr("サイズ");\r
290             case 4: return tr("更新日時");\r
291             }\r
292         }\r
293     }\r
294     return QVariant();\r
295 }\r
296 \r
297 Qt::ItemFlags FileTableModel::flags(const QModelIndex &index) const\r
298 {\r
299     Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;\r
300 \r
301     if (!index.isValid()) {\r
302         return flags | Qt::ItemIsDropEnabled;\r
303     }\r
304 \r
305     if (m_fileInfoList[index.row()].fileName() != "..") {\r
306         if (index.column() == 0) {\r
307             flags |= Qt::ItemIsUserCheckable;\r
308         }\r
309         flags |= Qt::ItemIsDropEnabled;\r
310     }\r
311     return flags;\r
312 }\r
313 \r
314 bool FileTableModel::setData(const QModelIndex &index, const QVariant &value, int role)\r
315 {\r
316     qDebug() << "FileTableModel::setData()" << index;\r
317 \r
318     if (!index.isValid()) {\r
319         return false;\r
320     }\r
321 \r
322     switch (role) {\r
323     case Qt::CheckStateRole:\r
324         if (index.column() == 0) {\r
325             m_checkStates[index.row()] = static_cast<Qt::CheckState>(value.toInt());\r
326             emit dataChanged(index, index);\r
327             return true;\r
328         }\r
329         break;\r
330     }\r
331 \r
332     return false;\r
333 }\r
334 \r
335 Qt::DropActions FileTableModel::supportedDropActions() const\r
336 {\r
337     qDebug() << "FileTableModel::supportedDropActions()";\r
338 \r
339     return Qt::CopyAction;\r
340 }\r
341 \r
342 QStringList FileTableModel::mimeTypes() const\r
343 {\r
344     qDebug() << "FileTableModel::mimeTypes()";\r
345 \r
346     QStringList types;\r
347 \r
348     types << "text/uri-list";\r
349 \r
350     return types;\r
351 }\r