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