OSDN Git Service

Ver 0.02
[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 <QBrush>\r
7 #ifdef Q_OS_WIN32\r
8     #include <windows.h>\r
9 #endif\r
10 \r
11 FileTableModel::FileTableModel(QObject *parent) :\r
12     QAbstractTableModel(parent),\r
13     m_dir(),\r
14     m_fileInfoList(),\r
15     m_checkStates(),\r
16     m_IconFactory(),\r
17     m_fsWatcher(NULL)\r
18 {\r
19 }\r
20 \r
21 bool FileTableModel::setPath(const QString &path)\r
22 {\r
23     if (!QFileInfo::exists(path)) {\r
24         qDebug() << "パスが存在しません";\r
25         qDebug() << path;\r
26         return false;\r
27     }\r
28     QFileInfo info(path);\r
29     if (!info.isDir()) {\r
30         qDebug() << "フォルダではありません";\r
31         qDebug() << path;\r
32         return false;\r
33     }\r
34 \r
35     beginResetModel();\r
36 \r
37     m_dir.setPath(path);\r
38     m_fileInfoList = m_dir.entryInfoList();\r
39     m_checkStates.clear();\r
40 \r
41     if (m_fileInfoList.isEmpty()) {\r
42         qDebug() << "ファイルリストを取得できません";\r
43         qDebug() << path;\r
44     }\r
45     else {\r
46         QFileInfoList::iterator it;\r
47         for (it = m_fileInfoList.begin(); it != m_fileInfoList.end(); ) {\r
48             if (it->fileName() == ".." && m_dir.isRoot()) {\r
49                 it = m_fileInfoList.erase(it);\r
50                 continue;\r
51             }\r
52 #ifdef Q_OS_WIN32\r
53             if (!(filter() & QDir::System)){\r
54                 DWORD dwFlags = ::GetFileAttributes(\r
55                             it->absoluteFilePath().toStdWString().c_str());\r
56                 if (dwFlags != DWORD(-1) && it->fileName() != ".." &&\r
57                     ((dwFlags & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM))\r
58                 {\r
59                     qDebug() << it->fileName() << " is system file.";\r
60                     it = m_fileInfoList.erase(it);\r
61                     continue;\r
62                 }\r
63             }\r
64 #endif\r
65             it++;\r
66         }\r
67     }\r
68     m_checkStates.resize(m_fileInfoList.size());\r
69     m_checkStates.fill(Qt::Unchecked);\r
70 \r
71     if (m_fsWatcher) {\r
72         delete m_fsWatcher;\r
73     }\r
74     m_fsWatcher = new QFileSystemWatcher(this);\r
75     m_fsWatcher->addPath(path);\r
76     connect(m_fsWatcher, SIGNAL(directoryChanged(QString)),\r
77             this, SLOT(refresh()));\r
78 \r
79     endResetModel();\r
80 \r
81     emit rootChanged(m_dir.absolutePath());\r
82     stateChanged();\r
83 \r
84     return !m_fileInfoList.isEmpty();\r
85 }\r
86 \r
87 Qt::CheckState FileTableModel::checkState(const QModelIndex &index) const\r
88 {\r
89     return m_checkStates[index.row()];\r
90 }\r
91 \r
92 void FileTableModel::setCheckState(const QModelIndex &index, Qt::CheckState state)\r
93 {\r
94     beginResetModel();\r
95     m_checkStates[index.row()] = state;\r
96     if (state == Qt::Checked && index.row() == 0 &&\r
97         m_fileInfoList[0].fileName() == "..")\r
98     {\r
99         m_checkStates[0] = Qt::Unchecked;\r
100     }\r
101     endResetModel();;\r
102     emit dataChanged(index, this->index(index.row(), 3));\r
103 \r
104     stateChanged();\r
105 }\r
106 \r
107 void FileTableModel::setCheckStateAll(Qt::CheckState state)\r
108 {\r
109     beginResetModel();\r
110     m_checkStates.fill(state);\r
111     if (state == Qt::Checked && m_fileInfoList.size() > 1 &&\r
112         m_fileInfoList[0].fileName() == "..")\r
113     {\r
114         m_checkStates[0] = Qt::Unchecked;\r
115     }\r
116     endResetModel();\r
117 \r
118     stateChanged();\r
119 }\r
120 \r
121 \r
122 bool FileTableModel::isDir(const QModelIndex &index) const\r
123 {\r
124     return m_fileInfoList[index.row()].isDir();\r
125 }\r
126 \r
127 const QString FileTableModel::absoluteFilePath(const QModelIndex &index) const\r
128 {\r
129     return m_dir.absoluteFilePath(m_fileInfoList[index.row()].fileName());\r
130 }\r
131 \r
132 QFileInfo FileTableModel::fileInfo(const QModelIndex &index) const\r
133 {\r
134     return m_fileInfoList[index.row()];\r
135 }\r
136 \r
137 void FileTableModel::stateChanged()\r
138 {\r
139     int numFolder = 0;\r
140     int numFile = 0;\r
141     quint64 totalSize = 0;\r
142     for (int n = 0; n < m_checkStates.size(); n++) {\r
143         if (m_checkStates[n] == Qt::Checked) {\r
144             if (m_fileInfoList[n].isDir()) {\r
145                 numFolder++;\r
146             }\r
147             else {\r
148                 numFile++;\r
149                 totalSize += m_fileInfoList[n].size();\r
150             }\r
151         }\r
152     }\r
153 \r
154     emit stateChanged(numFolder, numFile, totalSize);\r
155 }\r
156 \r
157 QFileInfoList FileTableModel::checkedItems() const\r
158 {\r
159     QFileInfoList list;\r
160     for (int n = 0; n < m_checkStates.size(); n++) {\r
161         if (m_fileInfoList[n].fileName() != ".." &&\r
162             m_checkStates[n] == Qt::Checked)\r
163         {\r
164             list.append(m_fileInfoList[n]);\r
165         }\r
166     }\r
167     return list;\r
168 }\r
169 \r
170 int FileTableModel::rowCount(const QModelIndex &parent) const\r
171 {\r
172     Q_UNUSED(parent);\r
173     return m_fileInfoList.size();\r
174 }\r
175 \r
176 int FileTableModel::columnCount(const QModelIndex &parent) const\r
177 {\r
178     Q_UNUSED(parent);\r
179     return 4;\r
180 }\r
181 \r
182 QVariant FileTableModel::data(const QModelIndex &index, int role) const\r
183 {\r
184     if (!index.isValid()) {\r
185         return QVariant();\r
186     }\r
187 \r
188     const QFileInfo &info = m_fileInfoList.at(index.row());\r
189     int checked = m_checkStates.at(index.row());\r
190 \r
191     switch (role) {\r
192     case Qt::DisplayRole:\r
193         switch (index.column()) {\r
194         case 0: // チェックボックス\r
195             return QString("");\r
196         case 1: // ファイル名\r
197             return info.fileName();\r
198         case 2: // サイズ\r
199             if (info.isDir()) {\r
200                 return QString("<DIR>");\r
201             }\r
202             else {\r
203                 return FilesizeToString(info.size());\r
204             }\r
205             break;\r
206         case 3:\r
207             return info.lastModified().toString("yy/MM/dd hh:mm");\r
208         }\r
209         break;\r
210 \r
211     case Qt::DecorationRole:\r
212         if (index.column() == 1) {\r
213             if (info.fileName() == "..") {\r
214                 return QIcon(":/images/Up.png");\r
215             }\r
216             else {\r
217                 // infoを使うと、正しいアイコンが取れない場合がある…なぜ?\r
218                 return m_IconFactory.icon(QFileInfo(info.absoluteFilePath()));\r
219             }\r
220         }\r
221         break;\r
222 \r
223     case Qt::TextAlignmentRole:\r
224         switch (index.column()) {\r
225         case 0:\r
226         case 1:\r
227             return Qt::AlignLeft + Qt::AlignVCenter;\r
228         case 2:\r
229         case 3:\r
230             return Qt::AlignRight + Qt::AlignVCenter;\r
231         }\r
232         break;\r
233 \r
234     case Qt::BackgroundRole:\r
235         if (checked) {\r
236             return QBrush(QColor(0, 196, 0));\r
237         }\r
238         break;\r
239 \r
240     case Qt::ForegroundRole:\r
241         if (checked) {\r
242             return QBrush(QColor(196, 0, 0));\r
243         }\r
244         break;\r
245 \r
246     case Qt::CheckStateRole:\r
247         if (index.column() == 0 && info.fileName() != "..") {\r
248             return checked;\r
249         }\r
250         break;\r
251     }\r
252 \r
253     return QVariant();\r
254 }\r
255 \r
256 QVariant FileTableModel::headerData(int section, Qt::Orientation orientation, int role) const\r
257 {\r
258     if (role == Qt::DisplayRole) {\r
259         if (orientation == Qt::Horizontal) {\r
260             switch (section) {\r
261             case 0: return QString("");\r
262             case 1: return tr("名前");\r
263             case 2: return tr("サイズ");\r
264             case 3: return tr("更新日時");\r
265             }\r
266         }\r
267     }\r
268     return QVariant();\r
269 }\r
270 \r
271 Qt::ItemFlags FileTableModel::flags(const QModelIndex &index) const\r
272 {\r
273     Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;\r
274     if (index.column() == 0 && m_fileInfoList[index.row()].fileName() != "..")\r
275     {\r
276         flags |= Qt::ItemIsUserCheckable;\r
277     }\r
278     return flags;\r
279 }\r
280 \r
281 bool FileTableModel::setData(const QModelIndex &index, const QVariant &value, int role)\r
282 {\r
283     if (!index.isValid()) {\r
284         return false;\r
285     }\r
286 \r
287     switch (role) {\r
288     case Qt::CheckStateRole:\r
289         if (index.column() == 0) {\r
290             m_checkStates[index.row()] = static_cast<Qt::CheckState>(value.toInt());\r
291             emit dataChanged(index, this->index(index.row(), 3));\r
292             stateChanged();\r
293             return true;\r
294         }\r
295         break;\r
296     }\r
297 \r
298     return false;\r
299 }\r