OSDN Git Service

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