OSDN Git Service

ソート機能を実装。
[gefu/Gefu.git] / folderpanel.cpp
1 #include "common.h"\r
2 #include "folderpanel.h"\r
3 #include "mainwindow.h"\r
4 #include "ui_folderpanel.h"\r
5 #include <QCheckBox>\r
6 #include <QMessageBox>\r
7 #include <QKeyEvent>\r
8 #include <QDebug>\r
9 #include <QDateTime>\r
10 #include <QDesktopServices>\r
11 #include <QSettings>\r
12 #ifdef Q_OS_WIN32\r
13     #include <windows.h>\r
14 #endif\r
15 \r
16 QString FilesizeToString(quint64 size)\r
17 {\r
18     if (size >= 1024 * 1024 * 1024) {\r
19         return QString("%1GB").arg(int(10 * size / (1024 * 1024 * 1024)) / 10.0);\r
20     }\r
21     if (size >= 1024 * 1024) {\r
22         return QString("%1MB").arg(int(10 * size / (1024 * 1024)) / 10.0);\r
23     }\r
24     if (size >= 1024) {\r
25         return QString("%1KB").arg(int(10 * size / 1024) / 10.0);\r
26     }\r
27     return QString("%1B").arg(size);\r
28 }\r
29 \r
30 FolderPanel::FolderPanel(QWidget *parent) :\r
31     QWidget(parent),\r
32     ui(new Ui::FolderPanel),\r
33     m_dir(),\r
34     m_IconFactory(),\r
35     m_fsWatcher(new QFileSystemWatcher(this)),\r
36     m_bUpdating(false)\r
37 {\r
38     ui->setupUi(this);\r
39 \r
40     // セル(チェックボックス)の変更\r
41     connect(ui->fileTable, SIGNAL(cellChanged(int,int)),\r
42             this, SLOT(onUpdateMark(int,int)));\r
43 \r
44     // リサイズ時の動作を設定する\r
45     QHeaderView *header = ui->fileTable->horizontalHeader();\r
46     header->setSectionResizeMode(0, QHeaderView::ResizeToContents);\r
47     header->setSectionResizeMode(1, QHeaderView::Stretch);\r
48     header->setSectionResizeMode(2, QHeaderView::ResizeToContents);\r
49     header->setSectionResizeMode(3, QHeaderView::ResizeToContents);\r
50 \r
51     QSettings settings;\r
52     // フィルタ初期化\r
53     m_dir.setFilter(QDir::NoDot | QDir::AllDirs | QDir::Files);\r
54     if (settings.value(IniKey_ShowHidden, false).toBool()) {\r
55         m_dir.setFilter(m_dir.filter() | QDir::Hidden);\r
56     }\r
57     if (settings.value(IniKey_ShowSystem, false).toBool()) {\r
58         m_dir.setFilter(m_dir.filter() | QDir::System);\r
59     }\r
60 \r
61     // ソート順初期化\r
62     m_dir.setSorting(QDir::DirsFirst | QDir::IgnoreCase);\r
63 }\r
64 \r
65 FolderPanel::~FolderPanel()\r
66 {\r
67     UninstallWatcher();\r
68     delete ui;\r
69 }\r
70 \r
71 FileTableWidget* FolderPanel::fileTable()\r
72 {\r
73     return ui->fileTable;\r
74 }\r
75 \r
76 const FileTableWidget *FolderPanel::fileTable() const\r
77 {\r
78     return ui->fileTable;\r
79 }\r
80 \r
81 void FolderPanel::setCurrentFolder(const QString &path)\r
82 {\r
83     QSettings settings;\r
84 \r
85     getMainWnd()->setStatusText(tr("ファイルリストを更新中..."));\r
86     QString curDir = m_dir.absolutePath();\r
87     m_dir.setPath(QDir::cleanPath(path));\r
88     m_dir.canonicalPath();\r
89 \r
90     QFileInfoList list = m_dir.entryInfoList();\r
91 \r
92     if (list.empty()) {\r
93         QMessageBox::critical(\r
94                     this,\r
95                     tr("エラー"),\r
96                     tr("フォルダが存在しないか利用できません。"));\r
97         m_dir.setPath(curDir);\r
98         ui->locationField->setText(curDir);\r
99         getMainWnd()->setStatusText(tr("レディ"));\r
100         return;\r
101     }\r
102 \r
103     // フォルダの変更監視\r
104     InstallWatcher();\r
105 \r
106     // QtはWindowsのシステムファイル属性をうまく判定できていないため、\r
107     // GetFileAttributes APIを使ってフィルタする\r
108     bool showSystem;\r
109     showSystem = settings.value(IniKey_ShowSystem, false).toBool();\r
110 \r
111     beginUpdate();\r
112     ui->fileTable->model()->removeRows(0, ui->fileTable->rowCount());\r
113     for (int i = 0; i < list.size(); i++) {\r
114         QFileInfo info = list.at(i);\r
115         if (info.fileName() == ".." && m_dir.isRoot()) {\r
116             continue;\r
117         }\r
118 \r
119 #ifdef Q_OS_WIN32\r
120         DWORD dwFlags = ::GetFileAttributes(info.absoluteFilePath().toStdWString().c_str());\r
121         if (!showSystem && dwFlags != DWORD(-1) && (dwFlags & FILE_ATTRIBUTE_SYSTEM)) {\r
122             continue;\r
123         }\r
124 #endif\r
125 \r
126         int row = ui->fileTable->rowCount();\r
127         ui->fileTable->insertRow(row);\r
128 \r
129         // ファイル名とアイコン\r
130         QTableWidgetItem *iName = new QTableWidgetItem(info.fileName());\r
131         iName->setFlags(iName->flags() ^ Qt::ItemIsEditable);\r
132         if (info.fileName() == "..") {\r
133             iName->setIcon(QIcon(":/images/Up.png"));\r
134         }\r
135         else {\r
136             iName->setIcon(m_IconFactory.icon(info));\r
137         }\r
138         ui->fileTable->setItem(row, 1, iName);\r
139 \r
140         // サイズ\r
141         QString str;\r
142         if (info.isDir()) {\r
143             str = tr("<DIR>");\r
144         }\r
145         else {\r
146             str = FilesizeToString(info.size());\r
147         }\r
148         QTableWidgetItem *iSize = new QTableWidgetItem(str);\r
149         iSize->setFlags(iSize->flags() ^ Qt::ItemIsEditable);\r
150         iSize->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);\r
151         ui->fileTable->setItem(row, 2, iSize);\r
152 \r
153         // 最終更新日時\r
154         QTableWidgetItem *iDateTime = new QTableWidgetItem(\r
155                     info.lastModified().toString("yy/MM/dd hh:mm"));\r
156         iDateTime->setFlags(iDateTime->flags() ^ Qt::ItemIsEditable);\r
157         ui->fileTable->setItem(row, 3, iDateTime);\r
158 \r
159         // シグナル処理の関係で、チェックボックスは最後に追加する\r
160         QTableWidgetItem *iCheck = new QTableWidgetItem(tr(""));\r
161         iCheck->setFlags(iCheck->flags() ^ Qt::ItemIsEditable);\r
162         if (info.fileName() != "..") {\r
163             iCheck->setFlags(iCheck->flags() | Qt::ItemIsUserCheckable);\r
164             iCheck->setCheckState(Qt::Unchecked);\r
165         }\r
166         ui->fileTable->setItem(row, 0, iCheck);\r
167 \r
168     }\r
169     ui->fileTable->selectRow(0);\r
170     ui->fileTable->resizeRowsToContents();\r
171 \r
172     ui->locationField->setText(m_dir.absolutePath());\r
173     getMainWnd()->setStatusText(tr("レディ"));\r
174     endUpdate();\r
175 }\r
176 \r
177 void FolderPanel::InstallWatcher()\r
178 {\r
179     UninstallWatcher();\r
180 \r
181     m_fsWatcher = new QFileSystemWatcher(this);\r
182     m_fsWatcher->addPath(m_dir.absolutePath());\r
183     connect(m_fsWatcher, SIGNAL(directoryChanged(QString)),\r
184             this, SLOT(on_directoryChanged(QString)));\r
185 }\r
186 \r
187 void FolderPanel::UninstallWatcher()\r
188 {\r
189     if (m_fsWatcher != NULL) {\r
190         delete m_fsWatcher;\r
191     }\r
192     m_fsWatcher = NULL;\r
193 }\r
194 \r
195 void FolderPanel::onUpdateMark(int, int column)\r
196 {\r
197     if (column != 0 || isUpdating()) {\r
198         return;\r
199     }\r
200 \r
201     // マークフォルダ数、ファイル数、サイズを計算する\r
202     int numFolders = 0;\r
203     int numFiles = 0;\r
204     quint64 sizeTotal = 0;\r
205     for (int n = 0; n < ui->fileTable->rowCount(); n++) {\r
206         if (ui->fileTable->item(n, 0)->checkState() != Qt::Checked) {\r
207             continue;\r
208         }\r
209         QString name = ui->fileTable->item(n, 1)->text();\r
210         QFileInfo info(m_dir.absoluteFilePath(name));\r
211         if (info.isDir()) {\r
212             numFolders++;\r
213         }\r
214         else {\r
215             numFiles++;\r
216             sizeTotal += info.size();\r
217         }\r
218     }\r
219 \r
220     QString msg = "";\r
221     if (numFolders > 0) {\r
222         msg += tr("%1個のフォルダ ").arg(numFolders);\r
223     }\r
224     if (numFiles > 0) {\r
225         msg += tr("%1個のファイル ").arg(numFiles);\r
226     }\r
227     if (msg.length() > 0) {\r
228         msg += "を選択 合計 ";\r
229         msg += FilesizeToString(sizeTotal);\r
230     }\r
231 \r
232     ui->label->setText(msg);\r
233 }\r
234 \r
235 void FolderPanel::on_locationField_editingFinished()\r
236 {\r
237     ui->locationField->blockSignals(true);\r
238 \r
239     QString path = ui->locationField->text();\r
240     setCurrentFolder(path);\r
241 \r
242     ui->locationField->blockSignals(false);\r
243 }\r
244 \r
245 void FolderPanel::on_directoryChanged(QString)\r
246 {\r
247     int row = ui->fileTable->currentRow();\r
248     this->setCurrentFolder(m_dir.absolutePath());\r
249     if (row >= ui->fileTable->rowCount()) {\r
250         row = ui->fileTable->rowCount() - 1;\r
251     }\r
252     ui->fileTable->selectRow(row);\r
253 }\r
254 \r
255 void FolderPanel::on_fileTable_itemSelectionChanged()\r
256 {\r
257     if (isUpdating()) {\r
258         return;\r
259     }\r
260 \r
261     int row = ui->fileTable->currentRow();\r
262     if (0 <= row && row < ui->fileTable->rowCount()) {\r
263         getMainWnd()->setStatusText(ui->fileTable->item(row, 1)->text());\r
264     }\r
265 }\r