OSDN Git Service

aa41e46717719b0635c0821758685ee08fa0aa49
[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 <QMenuBar>\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(NULL),\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 \r
31 bool FileTableModel::setPath(const QString &path)\r
32 {\r
33     if (!QFileInfo::exists(path)) {\r
34         qDebug() << "パスが存在しません";\r
35         qDebug() << path;\r
36         return false;\r
37     }\r
38     QFileInfo info(path);\r
39     if (!info.isDir()) {\r
40         qDebug() << "フォルダではありません";\r
41         qDebug() << path;\r
42         return false;\r
43     }\r
44 \r
45     beginResetModel();\r
46 \r
47     m_dir.setPath(path);\r
48     m_fileInfoList = m_dir.entryInfoList();\r
49     m_checkStates.clear();\r
50 \r
51     if (m_fileInfoList.isEmpty()) {\r
52         qDebug() << "ファイルリストを取得できません";\r
53         qDebug() << path;\r
54     }\r
55     else {\r
56         QFileInfoList::iterator it;\r
57         for (it = m_fileInfoList.begin(); it != m_fileInfoList.end(); ) {\r
58             if (it->fileName() == ".." && m_dir.isRoot()) {\r
59                 it = m_fileInfoList.erase(it);\r
60                 continue;\r
61             }\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             it++;\r
76         }\r
77     }\r
78     m_checkStates.resize(m_fileInfoList.size());\r
79     m_checkStates.fill(Qt::Unchecked);\r
80 \r
81     if (m_fsWatcher) {\r
82         delete m_fsWatcher;\r
83     }\r
84     m_fsWatcher = new QFileSystemWatcher(this);\r
85     m_fsWatcher->addPath(path);\r
86     connect(m_fsWatcher, SIGNAL(directoryChanged(QString)),\r
87             this, SLOT(refresh()));\r
88 \r
89     endResetModel();\r
90 \r
91     emit rootChanged(m_dir.absolutePath());\r
92     stateChanged();\r
93 \r
94     return !m_fileInfoList.isEmpty();\r
95 }\r
96 \r
97 Qt::CheckState FileTableModel::checkState(const QModelIndex &index) const\r
98 {\r
99     return m_checkStates[index.row()];\r
100 }\r
101 \r
102 void FileTableModel::setCheckState(const QModelIndex &index, Qt::CheckState state)\r
103 {\r
104     beginResetModel();\r
105     m_checkStates[index.row()] = state;\r
106     if (state == Qt::Checked && index.row() == 0 &&\r
107         m_fileInfoList[0].fileName() == "..")\r
108     {\r
109         m_checkStates[0] = Qt::Unchecked;\r
110     }\r
111     endResetModel();;\r
112     emit dataChanged(index, this->index(index.row(), 3));\r
113 \r
114     stateChanged();\r
115 }\r
116 \r
117 void FileTableModel::setCheckStateAll(Qt::CheckState state)\r
118 {\r
119     beginResetModel();\r
120     m_checkStates.fill(state);\r
121     if (state == Qt::Checked && m_fileInfoList.size() > 1 &&\r
122         m_fileInfoList[0].fileName() == "..")\r
123     {\r
124         m_checkStates[0] = Qt::Unchecked;\r
125     }\r
126     endResetModel();\r
127 \r
128     stateChanged();\r
129 }\r
130 \r
131 \r
132 bool FileTableModel::isDir(const QModelIndex &index) const\r
133 {\r
134     return m_fileInfoList[index.row()].isDir();\r
135 }\r
136 \r
137 const QString FileTableModel::absoluteFilePath(const QModelIndex &index) const\r
138 {\r
139     return m_dir.absoluteFilePath(m_fileInfoList[index.row()].fileName());\r
140 }\r
141 \r
142 QFileInfo FileTableModel::fileInfo(const QModelIndex &index) const\r
143 {\r
144     return m_fileInfoList[index.row()];\r
145 }\r
146 \r
147 #define Brush(x, y, z)  QBrush((x).value((y), (z)).value<QColor>());\r
148 \r
149 \r
150 void FileTableModel::updateAppearance()\r
151 {\r
152     QSettings settings;\r
153     QPalette palette(QApplication::palette("QTableView"));\r
154 \r
155     m_font = settings.value(IniKey_ViewFont, QApplication::font()).value<QFont>();\r
156     m_NormalBrush = Brush(settings, IniKey_ViewColorBgNormal, palette.base());\r
157     m_NormalTextBrush = Brush(settings, IniKey_ViewColorFgNormal, palette.text());\r
158     m_MarkBrush = Brush(settings, IniKey_ViewColorBgMark, DefaultMarkBgColor);\r
159     m_MarkTextBrush = Brush(settings, IniKey_ViewColorFgMark, DefaultMarkFgColor);\r
160     m_SystemBrush = Brush(settings, IniKey_ViewColorFgSystem, DefaultSystemColor);\r
161     m_HiddenBrush = Brush(settings, IniKey_ViewColorFgHidden, DefaultHiddenColor);\r
162     m_ReadonlyBrush = Brush(settings, IniKey_ViewColorFgReadonly, DefaultReadonlyColor);\r
163 \r
164     beginResetModel();\r
165     endResetModel();\r
166 }\r
167 \r
168 void FileTableModel::stateChanged()\r
169 {\r
170     int numFolder = 0;\r
171     int numFile = 0;\r
172     quint64 totalSize = 0;\r
173     for (int n = 0; n < m_checkStates.size(); n++) {\r
174         if (m_checkStates[n] == Qt::Checked) {\r
175             if (m_fileInfoList[n].isDir()) {\r
176                 numFolder++;\r
177             }\r
178             else {\r
179                 numFile++;\r
180                 totalSize += m_fileInfoList[n].size();\r
181             }\r
182         }\r
183     }\r
184 \r
185     emit stateChanged(numFolder, numFile, totalSize);\r
186 }\r
187 \r
188 QFileInfoList FileTableModel::checkedItems() const\r
189 {\r
190     QFileInfoList list;\r
191     for (int n = 0; n < m_checkStates.size(); n++) {\r
192         if (m_fileInfoList[n].fileName() != ".." &&\r
193             m_checkStates[n] == Qt::Checked)\r
194         {\r
195             list.append(m_fileInfoList[n]);\r
196         }\r
197     }\r
198     return list;\r
199 }\r
200 \r
201 int FileTableModel::rowCount(const QModelIndex &parent) const\r
202 {\r
203     Q_UNUSED(parent);\r
204     return m_fileInfoList.size();\r
205 }\r
206 \r
207 int FileTableModel::columnCount(const QModelIndex &parent) const\r
208 {\r
209     Q_UNUSED(parent);\r
210     return 4;\r
211 }\r
212 \r
213 QVariant FileTableModel::data(const QModelIndex &index, int role) const\r
214 {\r
215     if (!index.isValid()) {\r
216         return QVariant();\r
217     }\r
218 \r
219     const QFileInfo &info = m_fileInfoList.at(index.row());\r
220     int checked = m_checkStates.at(index.row());\r
221 \r
222     switch (role) {\r
223     case Qt::DisplayRole:\r
224         switch (index.column()) {\r
225         case 0: // チェックボックス\r
226             return QString("");\r
227         case 1: // ファイル名\r
228             return info.fileName();\r
229         case 2: // サイズ\r
230             if (info.isDir()) {\r
231                 return QString("<DIR>");\r
232             }\r
233             else {\r
234                 return FilesizeToString(info.size());\r
235             }\r
236             break;\r
237         case 3:\r
238             return info.lastModified().toString("yy/MM/dd hh:mm");\r
239         }\r
240         break;\r
241 \r
242     case Qt::DecorationRole:\r
243         if (index.column() == 1) {\r
244             if (info.fileName() == "..") {\r
245                 return QIcon(":/images/Up.png");\r
246             }\r
247             else {\r
248                 // infoを使うと、正しいアイコンが取れない場合がある…なぜ?\r
249                 return m_IconFactory.icon(QFileInfo(info.absoluteFilePath()));\r
250             }\r
251         }\r
252         break;\r
253 \r
254     case Qt::FontRole:\r
255         return m_font;\r
256 \r
257     case Qt::TextAlignmentRole:\r
258         switch (index.column()) {\r
259         case 0:\r
260         case 1:\r
261             return Qt::AlignLeft + Qt::AlignVCenter;\r
262         case 2:\r
263         case 3:\r
264             return Qt::AlignRight + Qt::AlignVCenter;\r
265         }\r
266         break;\r
267 \r
268     case Qt::BackgroundRole:\r
269         if (checked) {\r
270             return m_MarkBrush;\r
271         }\r
272         return m_NormalBrush;\r
273 \r
274     case Qt::ForegroundRole:\r
275         if (checked) {\r
276             return m_MarkTextBrush;\r
277         }\r
278 #ifdef Q_OS_WIN32\r
279         {\r
280             DWORD dwFlags = ::GetFileAttributes(\r
281                         info.absoluteFilePath().toStdWString().c_str());\r
282             if (dwFlags != DWORD(-1) && (dwFlags & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM))\r
283             {\r
284                 return m_SystemBrush;\r
285             }\r
286         }\r
287 #endif\r
288         if (info.isHidden() && info.fileName() != "..") {\r
289             return m_HiddenBrush;\r
290         }\r
291         if (!info.isWritable()) {\r
292             return m_ReadonlyBrush;\r
293         }\r
294         return m_NormalTextBrush;\r
295 \r
296     case Qt::CheckStateRole:\r
297         if (index.column() == 0 && info.fileName() != "..") {\r
298             return checked;\r
299         }\r
300         break;\r
301     }\r
302 \r
303     return QVariant();\r
304 }\r
305 \r
306 QVariant FileTableModel::headerData(int section, Qt::Orientation orientation, int role) const\r
307 {\r
308     if (role == Qt::DisplayRole) {\r
309         if (orientation == Qt::Horizontal) {\r
310             switch (section) {\r
311             case 0: return QString("");\r
312             case 1: return tr("名前");\r
313             case 2: return tr("サイズ");\r
314             case 3: return tr("更新日時");\r
315             }\r
316         }\r
317     }\r
318     return QVariant();\r
319 }\r
320 \r
321 Qt::ItemFlags FileTableModel::flags(const QModelIndex &index) const\r
322 {\r
323     Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;\r
324     if (index.column() == 0 && m_fileInfoList[index.row()].fileName() != "..")\r
325     {\r
326         flags |= Qt::ItemIsUserCheckable;\r
327     }\r
328     return flags;\r
329 }\r
330 \r
331 bool FileTableModel::setData(const QModelIndex &index, const QVariant &value, int role)\r
332 {\r
333     if (!index.isValid()) {\r
334         return false;\r
335     }\r
336 \r
337     switch (role) {\r
338     case Qt::CheckStateRole:\r
339         if (index.column() == 0) {\r
340             m_checkStates[index.row()] = static_cast<Qt::CheckState>(value.toInt());\r
341             emit dataChanged(index, this->index(index.row(), 3));\r
342             stateChanged();\r
343             return true;\r
344         }\r
345         break;\r
346     }\r
347 \r
348     return false;\r
349 }\r