OSDN Git Service

リターンキーのイベントを処理していなかったのを修正。
[gefu/Gefu.git] / folderpanel.cpp
1 #include "folderpanel.h"\r
2 #include "mainwindow.h"\r
3 #include "ui_folderpanel.h"\r
4 #include <QCheckBox>\r
5 #include <QMessageBox>\r
6 #include <QKeyEvent>\r
7 #include <QDebug>\r
8 #include <QDateTime>\r
9 #include <QDesktopServices>\r
10 \r
11 FolderPanel::FolderPanel(QWidget *parent) :\r
12     QWidget(parent),\r
13     ui(new Ui::FolderPanel),\r
14     m_dir(),\r
15     m_IconFactory(),\r
16     m_fsWatcher(new QFileSystemWatcher(this)),\r
17     m_bUpdating(false)\r
18 {\r
19     ui->setupUi(this);\r
20 \r
21     // MainWindowのスロットに接続する\r
22     MainWindow *mainWnd = this->mainWindow();\r
23     if (mainWnd) {\r
24         connect(ui->fileTable, SIGNAL(cellDoubleClicked(int,int)), mainWnd, SLOT(onActionOpen()));\r
25     }\r
26 \r
27     // ヘッダーラベルを設定する\r
28     QStringList labels;\r
29     labels << tr("") << tr("名前") << tr("サイズ") << tr("更新日時");\r
30     ui->fileTable->setHorizontalHeaderLabels(labels);\r
31 \r
32     // イベントフィルタを設定する\r
33     ui->fileTable->installEventFilter(this);\r
34 \r
35     // リサイズ時の動作を設定する\r
36     ui->fileTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);\r
37     ui->fileTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);\r
38     ui->fileTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents);\r
39     ui->fileTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::ResizeToContents);\r
40 \r
41     // フォルダの要素を表示\r
42     m_dir.setFilter(QDir::NoDot | QDir::AllEntries);\r
43     m_dir.setSorting(QDir::DirsFirst | QDir::Name);\r
44 }\r
45 \r
46 FolderPanel::~FolderPanel()\r
47 {\r
48     UninstallWatcher();\r
49     delete ui;\r
50 }\r
51 \r
52 QTableWidget* FolderPanel::fileTable()\r
53 {\r
54     return ui->fileTable;\r
55 }\r
56 \r
57 const QTableWidget* FolderPanel::fileTable() const\r
58 {\r
59     return ui->fileTable;\r
60 }\r
61 \r
62 MainWindow* FolderPanel::mainWindow()\r
63 {\r
64     foreach (QWidget *w, qApp->topLevelWidgets()) {\r
65         if (w->objectName() == "MainWindow") {\r
66             return static_cast<MainWindow*>(w);\r
67         }\r
68     }\r
69     return NULL;\r
70 }\r
71 \r
72 bool FolderPanel::eventFilter(QObject *obj, QEvent *event)\r
73 {\r
74     if (event->type() == QEvent::KeyPress) {\r
75         QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);\r
76         switch (keyEvent->key()) {\r
77         case Qt::Key_A: {\r
78             // A            すべてのファイルをマーク\r
79             // Shift + A    すべてマーク\r
80             MainWindow *mainWnd = this->mainWindow();\r
81             if (mainWnd) {\r
82                 if (keyEvent->modifiers() & Qt::ShiftModifier) {\r
83                     mainWnd->onMarkAll();\r
84                 }\r
85                 else {\r
86                     mainWnd->onMarkAllFiles();\r
87                 }\r
88             }\r
89             keyEvent->accept();\r
90             return true; }\r
91 \r
92         case Qt::Key_D: {\r
93             // Ctrl + D ファイルを削除\r
94             MainWindow *mainWnd = this->mainWindow();\r
95             if (mainWnd) {\r
96                 if (keyEvent->modifiers() & Qt::ControlModifier) {\r
97                     mainWnd->onCmdDelete();\r
98                 }\r
99             }\r
100             keyEvent->accept();\r
101             return true; }\r
102 \r
103         case Qt::Key_E: {\r
104             // E        エディタで開く\r
105             // Ctrl + E ファイルを作成\r
106             MainWindow *mainWnd = this->mainWindow();\r
107             if (mainWnd) {\r
108                 if (keyEvent->modifiers() & Qt::ControlModifier) {\r
109                     mainWnd->onCmdNewFile();\r
110                 }\r
111                 else {\r
112                 }\r
113             }\r
114             keyEvent->accept();\r
115             return true; }\r
116 \r
117         case Qt::Key_G: {\r
118             // G            カーソルを先頭に移動\r
119             // Shift + G    カーソルを末尾に移動\r
120             MainWindow *mainWnd = this->mainWindow();\r
121             if (mainWnd) {\r
122                 if (keyEvent->modifiers() & Qt::ShiftModifier) {\r
123                     mainWnd->onMoveCursorEnd();\r
124                 }\r
125                 else {\r
126                     mainWnd->onMoveCursorBegin();\r
127                 }\r
128             }\r
129             keyEvent->accept();\r
130             return true; }\r
131 \r
132         case Qt::Key_H: {\r
133             // H            ホームフォルダに移動\r
134             // Shift + H    隠しファイルを表示/非表示\r
135             MainWindow *mainWnd = this->mainWindow();\r
136             if (mainWnd) {\r
137                 if (keyEvent->modifiers() & Qt::ShiftModifier) {\r
138                     mainWnd->onViewHidden();\r
139                 }\r
140                 else {\r
141                     mainWnd->onMoveHome();\r
142                 }\r
143             }\r
144             keyEvent->accept();\r
145             return true; }\r
146 \r
147         case Qt::Key_I: {\r
148             // I    マークを反転\r
149             MainWindow *mainWnd = this->mainWindow();\r
150             if (mainWnd) {\r
151                 mainWnd->onMarkInvert();\r
152             }\r
153             keyEvent->accept();\r
154             return true; }\r
155 \r
156         case Qt::Key_J: {\r
157             // J            カーソルを下に移動\r
158             // Shift + J    フォルダを選択して移動\r
159             MainWindow *mainWnd = this->mainWindow();\r
160             if (mainWnd) {\r
161                 if (keyEvent->modifiers() & Qt::ShiftModifier) {\r
162                     mainWnd->onMoveJump();\r
163                 }\r
164                 else {\r
165                     mainWnd->onMoveCursorDown();\r
166                 }\r
167             }\r
168             keyEvent->accept();\r
169             return true; }\r
170 \r
171         case Qt::Key_K: {\r
172             // K        カーソルを上に移動\r
173             // Ctrl + K フォルダを作成\r
174             MainWindow *mainWnd = this->mainWindow();\r
175             if (mainWnd) {\r
176                 if (keyEvent->modifiers() & Qt::ControlModifier) {\r
177                     mainWnd->onCmdNewFolder();\r
178                 }\r
179                 else {\r
180                     mainWnd->onMoveCursorUp();\r
181                 }\r
182             }\r
183             keyEvent->accept();\r
184             return true; }\r
185 \r
186         case Qt::Key_O: {\r
187             // O            隣のパネルと同じフォルダを表示\r
188             // Shift + O    隣のパネルに同じフォルダを表示\r
189             MainWindow *mainWnd = this->mainWindow();\r
190             if (mainWnd) {\r
191                 if (keyEvent->modifiers() & Qt::ShiftModifier) {\r
192                     mainWnd->onViewToOther();\r
193                 }\r
194                 else {\r
195                     mainWnd->onViewFromOther();\r
196                 }\r
197             }\r
198             keyEvent->accept();\r
199             return true; }\r
200 \r
201         case Qt::Key_Q: {\r
202             // Q    アプリケーションを終了\r
203             MainWindow *mainWnd = this->mainWindow();\r
204             if (mainWnd) {\r
205                 mainWnd->onActionQuit();\r
206             }\r
207             keyEvent->accept();\r
208             return true; }\r
209 \r
210         case Qt::Key_R: {\r
211             // R        履歴を表示\r
212             // Ctrl + R 名前を変更\r
213             MainWindow *mainWnd = this->mainWindow();\r
214             if (mainWnd) {\r
215                 if (keyEvent->modifiers() & Qt::ControlModifier) {\r
216                     mainWnd->onCmdRename();\r
217                 }\r
218                 else {\r
219 \r
220                 }\r
221             }\r
222             keyEvent->accept();\r
223             return true; }\r
224 \r
225         case Qt::Key_U: {\r
226             // U    すべてのマークを解除\r
227             MainWindow *mainWnd = this->mainWindow();\r
228             if (mainWnd) {\r
229                 mainWnd->onMarkAllOff();\r
230             }\r
231             keyEvent->accept();\r
232             return true; }\r
233 \r
234         case Qt::Key_W: {\r
235             // W    表示フォルダを交換\r
236             MainWindow *mainWnd = this->mainWindow();\r
237             if (mainWnd) {\r
238                 mainWnd->onViewSwap();\r
239             }\r
240             keyEvent->accept();\r
241             return true; }\r
242 \r
243         case Qt::Key_X: {\r
244             // X     コマンドを実行\r
245             MainWindow *mainWnd = this->mainWindow();\r
246             if (mainWnd) {\r
247                 mainWnd->onActionCommand();\r
248             }\r
249             keyEvent->accept();\r
250             return true; }\r
251 \r
252         case Qt::Key_Question: {\r
253             // ?    アプリケーション情報を表示\r
254             MainWindow *mainWnd = this->mainWindow();\r
255             if (mainWnd) {\r
256                 mainWnd->onHelpAbout();\r
257             }\r
258             keyEvent->accept();\r
259             return true; }\r
260 \r
261         case Qt::Key_Space: {\r
262             // マーク/解除\r
263             MainWindow *mainWnd = this->mainWindow();\r
264             if (mainWnd) {\r
265                 mainWnd->onMarkToggle();\r
266             }\r
267             keyEvent->accept();\r
268             return true; }\r
269 \r
270         case Qt::Key_Tab: {\r
271             // 隣のパネルに移動\r
272             MainWindow *mainWnd = this->mainWindow();\r
273             if (mainWnd) {\r
274                 mainWnd->onMoveOther();\r
275             }\r
276             keyEvent->accept();\r
277             return true; }\r
278 \r
279         case Qt::Key_Backspace: {\r
280             // BS           親フォルダに移動\r
281             // Shift + BS   ルートフォルダに移動\r
282             MainWindow *mainWnd = this->mainWindow();\r
283             if (mainWnd) {\r
284                 if (keyEvent->modifiers() & Qt::ShiftModifier) {\r
285                     mainWnd->onMoveRoot();\r
286                 }\r
287                 else {\r
288                     mainWnd->onMoveParent();\r
289                 }\r
290             }\r
291             keyEvent->accept();\r
292             return true; }\r
293 \r
294         case Qt::Key_Return: {\r
295             // RET          開く\r
296             // Shift + RET  アプリケーションで開く\r
297             MainWindow *mainWnd = this->mainWindow();\r
298             if (mainWnd) {\r
299                 if (keyEvent->modifiers() & Qt::ShiftModifier) {\r
300                     mainWnd->onActionExec();\r
301                 }\r
302                 else {\r
303                     mainWnd->onActionOpen();\r
304                 }\r
305             }\r
306             keyEvent->accept();\r
307             return true; }\r
308         }\r
309     }\r
310 \r
311     return QWidget::eventFilter(obj, event);\r
312 }\r
313 \r
314 void FolderPanel::setCurrentFolder(const QString &path)\r
315 {\r
316     mainWindow()->setStatusText(tr("ファイルリストを更新中..."));\r
317     QString curDir = m_dir.absolutePath();\r
318     m_dir.setPath(QDir::cleanPath(path));\r
319     m_dir.canonicalPath();\r
320     QFileInfoList list = m_dir.entryInfoList();\r
321 \r
322     if (list.empty()) {\r
323         QMessageBox::critical(\r
324                     this,\r
325                     tr("エラー"),\r
326                     tr("フォルダが存在しないか利用できません。"));\r
327         m_dir.setPath(curDir);\r
328         ui->locationField->setText(curDir);\r
329         mainWindow()->setStatusText(tr("レディ"));\r
330         return;\r
331     }\r
332 \r
333     // フォルダの変更監視\r
334     InstallWatcher();\r
335 \r
336     m_bUpdating = true;\r
337     ui->fileTable->model()->removeRows(0, ui->fileTable->rowCount());\r
338     for (int i = 0; i < list.size(); i++) {\r
339         QFileInfo info = list.at(i);\r
340         if (info.fileName() == ".." && m_dir.isRoot()) {\r
341             continue;\r
342         }\r
343 \r
344         int row = ui->fileTable->rowCount();\r
345         ui->fileTable->insertRow(row);\r
346 \r
347         // ファイル名とアイコン\r
348         QTableWidgetItem *iName = new QTableWidgetItem(info.fileName());\r
349         iName->setFlags(iName->flags() ^ Qt::ItemIsEditable);\r
350         if (info.fileName() == "..") {\r
351             iName->setIcon(QIcon(":/images/Up.png"));\r
352         }\r
353         else {\r
354             iName->setIcon(m_IconFactory.icon(info));\r
355         }\r
356         ui->fileTable->setItem(row, 1, iName);\r
357 \r
358         // サイズ\r
359         QString str;\r
360         if (info.isDir()) {\r
361             str = tr("<DIR>");\r
362         }\r
363         else if (info.size() >= 1024 * 1024 * 1024) {\r
364             str = tr("%1GB").arg(int(info.size() / (1024 * 1024 * 1024)));\r
365         }\r
366         else if (info.size() >= 1024 * 1024) {\r
367             str = tr("%1MB").arg(int(info.size() / (1024 * 1024)));\r
368         }\r
369         else if (info.size() >= 1024) {\r
370             str = tr("%1KB").arg(int(info.size() / 1024));\r
371         }\r
372         else {\r
373             str = tr("%1B").arg(info.size());\r
374         }\r
375         QTableWidgetItem *iSize = new QTableWidgetItem(str);\r
376         iSize->setFlags(iSize->flags() ^ Qt::ItemIsEditable);\r
377         iSize->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);\r
378 \r
379         ui->fileTable->setItem(row, 2, iSize);\r
380 \r
381         // 最終更新日時\r
382         QTableWidgetItem *iDateTime = new QTableWidgetItem(\r
383                     info.lastModified().toString("yy/MM/dd hh:mm"));\r
384         iDateTime->setFlags(iDateTime->flags() ^ Qt::ItemIsEditable);\r
385         ui->fileTable->setItem(row, 3, iDateTime);\r
386 \r
387         // シグナル処理の関係で、チェックボックスは最後に追加する\r
388         QTableWidgetItem *iCheck = new QTableWidgetItem(tr(""));\r
389         iCheck->setFlags(iCheck->flags() ^ Qt::ItemIsEditable);\r
390         if (info.fileName() != "..") {\r
391             iCheck->setFlags(iCheck->flags() | Qt::ItemIsUserCheckable);\r
392             iCheck->setCheckState(Qt::Unchecked);\r
393         }\r
394         ui->fileTable->setItem(row, 0, iCheck);\r
395 \r
396     }\r
397     ui->fileTable->selectRow(0);\r
398     ui->fileTable->resizeRowsToContents();\r
399 \r
400     ui->locationField->setText(m_dir.absolutePath());\r
401     mainWindow()->setStatusText(tr("レディ"));\r
402     m_bUpdating = false;\r
403 }\r
404 \r
405 void FolderPanel::InstallWatcher()\r
406 {\r
407     UninstallWatcher();\r
408 \r
409     m_fsWatcher = new QFileSystemWatcher(this);\r
410     m_fsWatcher->addPath(m_dir.absolutePath());\r
411     connect(m_fsWatcher, SIGNAL(directoryChanged(QString)),\r
412             this, SLOT(on_directoryChanged(QString)));\r
413 }\r
414 \r
415 void FolderPanel::UninstallWatcher()\r
416 {\r
417     if (m_fsWatcher != NULL) {\r
418         delete m_fsWatcher;\r
419     }\r
420     m_fsWatcher = NULL;\r
421 }\r
422 \r
423 void FolderPanel::on_fileTable_cellChanged(int row, int column)\r
424 {\r
425     if (column == 0) {\r
426         if (ui->fileTable->item(row, 0)->checkState() == Qt::Checked) {\r
427             for (int n = 0; n < 4; n++) {\r
428                 ui->fileTable->item(row, n)->setForeground(Qt::red);\r
429                 ui->fileTable->item(row, n)->setBackground(Qt::green);\r
430             }\r
431         }\r
432         else {\r
433             for (int n = 0; n < 4; n++) {\r
434                 ui->fileTable->item(row, n)->setForeground(Qt::black);\r
435                 ui->fileTable->item(row, n)->setBackground(Qt::white);\r
436             }\r
437         }\r
438         ui->fileTable->selectRow(row);\r
439     }\r
440 }\r
441 \r
442 void FolderPanel::on_locationField_editingFinished()\r
443 {\r
444     ui->locationField->blockSignals(true);\r
445 \r
446     QString path = ui->locationField->text();\r
447     setCurrentFolder(path);\r
448 \r
449     ui->locationField->blockSignals(false);\r
450 }\r
451 \r
452 void FolderPanel::on_directoryChanged(QString)\r
453 {\r
454     int row = ui->fileTable->currentRow();\r
455     this->setCurrentFolder(m_dir.absolutePath());\r
456     if (row >= ui->fileTable->rowCount()) {\r
457         row = ui->fileTable->rowCount() - 1;\r
458     }\r
459     ui->fileTable->selectRow(row);\r
460 }\r
461 \r
462 void FolderPanel::on_fileTable_itemSelectionChanged()\r
463 {\r
464     if (m_bUpdating) {\r
465         return;\r
466     }\r
467 \r
468     int row = ui->fileTable->currentRow();\r
469     if (0 <= row && row < ui->fileTable->rowCount()) {\r
470         mainWindow()->setStatusText(ui->fileTable->item(row, 1)->text());\r
471     }\r
472 }\r