OSDN Git Service

Ver0.26
[gefu/Gefu.git] / mainwindow.cpp
1 #include "bookmarkdialog.h"\r
2 #include "copymoveworker.h"\r
3 #include "deleteworker.h"\r
4 #include "foldermodel.h"\r
5 #include "folderpanel.h"\r
6 #include "global.h"\r
7 #include "historydialog.h"\r
8 #include "operationdialog.h"\r
9 #include "overwritedialog.h"\r
10 #include "preferences.h"\r
11 #include "preferencedialog.h"\r
12 #include "renameworker.h"\r
13 #include "renamesingledialog.h"\r
14 #include "renamemultidialog.h"\r
15 #include "sortdialog.h"\r
16 #include "version.h"\r
17 #include "mainwindow.h"\r
18 #include "ui_mainwindow.h"\r
19 \r
20 #include <QCheckBox>\r
21 #include <QClipboard>\r
22 #include <QCloseEvent>\r
23 #include <QDebug>\r
24 #include <QDesktopServices>\r
25 #include <QFileDialog>\r
26 #include <QInputDialog>\r
27 #include <QMessageBox>\r
28 #include <QMimeData>\r
29 #include <QNetworkAccessManager>\r
30 #include <QProcess>\r
31 #include <QScrollArea>\r
32 \r
33 ///////////////////////////////////////////////////////////////////////////////\r
34 /// \brief MainWindow::MainWindow\r
35 /// \param parent   親ウィジェット\r
36 ///\r
37 /// コンストラクタ\r
38 ///\r
39 MainWindow::MainWindow(QWidget *parent) :\r
40     QMainWindow(parent),\r
41     ui(new Ui::MainWindow),\r
42     m_overwriteDialog(this),\r
43     m_viewMode(ModeBasic),\r
44     m_prevMode(ModeBasic),\r
45     m_actions()\r
46 {\r
47     ui->setupUi(this);\r
48     connect(qApp, SIGNAL(focusChanged(QWidget*,QWidget*)), this, SLOT(app_focusChange(QWidget*,QWidget*)));\r
49 \r
50     // ステータスバーにウィジェットを設定する\r
51     QLabel *label = new QLabel(this);\r
52     label->setAlignment(Qt::AlignRight);\r
53     label->setObjectName("Right");\r
54     statusBar()->addPermanentWidget(label, 0);\r
55 \r
56     // アプリケーション情報を初期化する\r
57     qApp->setApplicationName("Gefu");\r
58     qApp->setApplicationVersion(QString("%1").arg(VERSION_VALUE));\r
59     qApp->setOrganizationDomain("sourceforge.jp");\r
60     qApp->setOrganizationName("gefu");\r
61     qApp->setWindowIcon(QIcon("://images/file-manager.png"));\r
62 \r
63     // 設定の初期化\r
64     Preferences prefs(this);\r
65     if (prefs.isReset()) {\r
66         prefs.clear();\r
67     }\r
68 \r
69     // パネルにモデルを割り当てる\r
70     ui->LPanel->setModel(new FolderModel(this));\r
71     ui->RPanel->setModel(new FolderModel(this));\r
72     setActiveModel(ui->LPanel->model());\r
73 \r
74     // パネルを初期化する\r
75     ui->LPanel->initialize(this);\r
76     ui->RPanel->initialize(this);\r
77     ui->FPanel->initialize(this);\r
78     ui->FPanel->setVisible(false);\r
79 \r
80     // モデルを初期化する\r
81     prefs.restoreModel("Left", ui->LPanel->model());\r
82     prefs.restoreModel("Right", ui->RPanel->model());\r
83 \r
84     // アクションを初期化する\r
85     initActions();\r
86 \r
87     // ブックマークメニューを初期化する\r
88     initBookmarkMenu();\r
89 \r
90     // メインウィンドウを初期化する\r
91     setWindowTitle(tr("げふぅ Ver%1").arg(VERSION_VALUE));\r
92     setWindowIcon(QIcon("://images/file-manager.png"));\r
93     prefs.restoreWindow(this);\r
94 \r
95     // 最新バージョンをチェックする\r
96     if (prefs.isCheckUpdate()) {\r
97         onCheckUpdate(true);\r
98     }\r
99 \r
100     prefs_updated();\r
101 \r
102     connect(ui->FPanel, SIGNAL(showed(QWidget*)), this, SLOT(view_showed(QWidget*)));\r
103 }\r
104 \r
105 ///////////////////////////////////////////////////////////////////////////////\r
106 /// \brief MainWindow::~MainWindow\r
107 ///\r
108 /// デストラクタ\r
109 ///\r
110 MainWindow::~MainWindow()\r
111 {\r
112     delete ui;\r
113 }\r
114 \r
115 ///////////////////////////////////////////////////////////////////////////////\r
116 /// \brief MainWindow::app_focusChange\r
117 /// \param old  フォーカスを失うウィジェット\r
118 /// \param now  フォーカスを得るウィジェット\r
119 ///\r
120 /// フォーカス変更時の処理\r
121 ///\r
122 void MainWindow::app_focusChange(QWidget *old, QWidget *now)\r
123 {\r
124     qDebug() << "MainWindow::app_focusChange()";\r
125     if (old) qDebug() << "  old is" << old->objectName();\r
126     if (now) qDebug() << "  now is" << now->objectName();\r
127 \r
128     // フォルダビューがフォーカスを得た場合\r
129     if (now && (now->objectName() == "folderView" ||\r
130                 now->objectName() == "thumbnailView"))\r
131     {\r
132         connect(focusItemView()->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),\r
133                 this, SLOT(view_currentChanged(QModelIndex,QModelIndex)));\r
134         FolderModel *m = static_cast<FolderModel*>(focusItemView()->model());\r
135         setActiveModel(m);\r
136         statusBar()->showMessage(m->filePath(focusItemView()->currentIndex()));\r
137     }\r
138 \r
139     // 検索ボックスがフォーカスを失った場合\r
140     if (old && old->objectName() == "searchBox") {\r
141         // 検索モード終了\r
142         ui->toggle_Search->setChecked(false);\r
143     }\r
144 \r
145     // アクションの有効/無効を設定する\r
146     if (now) {\r
147         updateActions();\r
148     }\r
149 }\r
150 \r
151 ///////////////////////////////////////////////////////////////////////////////\r
152 /// \brief MainWindow::model_PreReset\r
153 ///\r
154 /// FolderModelリセット前の処理\r
155 ///\r
156 void MainWindow::model_PreReset()\r
157 {\r
158     qDebug() << "MainWindow::model_PreReset()";\r
159 \r
160     statusBar()->showMessage(tr("ファイルリストを取得しています..."));\r
161 }\r
162 \r
163 ///////////////////////////////////////////////////////////////////////////////\r
164 /// \brief MainWindow::model_PostReset\r
165 ///\r
166 /// FolderModelリセット後の処理\r
167 ///\r
168 void MainWindow::model_PostReset()\r
169 {\r
170     qDebug() << "MainWindow::model_PostReset()";\r
171 \r
172     FolderModel *m = static_cast<FolderModel*>(sender());\r
173     if (!m->error().isEmpty()) {\r
174         statusBar()->showMessage(m->error());\r
175     }\r
176     else {\r
177         statusBar()->showMessage(tr("レディ"));\r
178     }\r
179 }\r
180 \r
181 ///////////////////////////////////////////////////////////////////////////////\r
182 /// \brief MainWindow::onRunCommand\r
183 ///\r
184 /// 入力されたコマンドを実行します。\r
185 ///\r
186 void MainWindow::onRunCommand()\r
187 {\r
188     qDebug() << "MainWindow::onRunCommand";\r
189 \r
190     QFileInfoList list = selectedItems();\r
191     QString command = QString::null;\r
192     foreach (const QFileInfo &info, list) {\r
193 #ifdef Q_OS_MAC\r
194         QString path = info.absoluteFilePath();\r
195 #else\r
196         QString path = info.fileName();\r
197 #endif\r
198         if (info.isExecutable()) {\r
199             command = QQ(path) + " " + command;\r
200         }\r
201         else {\r
202             command += " " + QQ(path);\r
203         }\r
204     }\r
205 \r
206     QInputDialog dlg(this);\r
207     dlg.setInputMode(QInputDialog::TextInput);\r
208     dlg.setWindowTitle(tr("コマンドを実行"));\r
209     dlg.setLabelText(tr("コマンド:"));\r
210     dlg.setTextValue(command);\r
211     dlg.resize(width() * 0.8, dlg.height());\r
212 \r
213     int ret = dlg.exec();\r
214     command = dlg.textValue();\r
215     if (ret == QDialog::Accepted && !command.isEmpty()) {\r
216         startProcess(command, tr("コマンドの実行に失敗しました。"));\r
217     }\r
218 }\r
219 \r
220 ///////////////////////////////////////////////////////////////////////////////\r
221 /// \brief MainWindow::onExpandLeft\r
222 ///\r
223 /// 左パネルを拡大します。\r
224 ///\r
225 void MainWindow::onExpandLeft()\r
226 {\r
227     qDebug() << "MainWindow::onExpandLeft()";\r
228 \r
229     QList<int> sizes = ui->splitter->sizes();\r
230     QList<int> newSizes;\r
231 \r
232     newSizes << sizes[0] + 30;\r
233     newSizes << sizes[1] - 30;\r
234 \r
235     ui->splitter->setSizes(newSizes);\r
236 }\r
237 \r
238 ///////////////////////////////////////////////////////////////////////////////\r
239 /// \brief MainWindow::onExpandRight\r
240 ///\r
241 /// 右パネルを拡大します。\r
242 ///\r
243 void MainWindow::onExpandRight()\r
244 {\r
245     qDebug() << "MainWindow::onExpandLeft()";\r
246 \r
247     QList<int> sizes = ui->splitter->sizes();\r
248     QList<int> newSizes;\r
249 \r
250     newSizes << sizes[0] - 30;\r
251     newSizes << sizes[1] + 30;\r
252 \r
253     ui->splitter->setSizes(newSizes);\r
254 }\r
255 \r
256 ///////////////////////////////////////////////////////////////////////////////\r
257 /// \brief MainWindow::onToggleMark\r
258 ///\r
259 /// マーク状態を反転します。\r
260 ///\r
261 void MainWindow::onToggleMark()\r
262 {\r
263     qDebug() << "MainWindow::onToggleMark()";\r
264 \r
265     QModelIndex index = focusItemView()->currentIndex();\r
266     if (activeModel()->isMarked(index)) {\r
267         activeModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole);\r
268     }\r
269     else {\r
270         activeModel()->setData(index, Qt::Checked, Qt::CheckStateRole);\r
271     }\r
272 \r
273     if (index.row() < activeModel()->rowCount() - 1) {\r
274         index = activeModel()->index(index.row() + 1, 0);\r
275         focusItemView()->setCurrentIndex(index);\r
276     }\r
277 }\r
278 \r
279 ///////////////////////////////////////////////////////////////////////////////\r
280 /// \brief MainWindow::view_statusChanged\r
281 /// \param text ステータス文字列\r
282 ///\r
283 /// ビューから受け取った文字列をステータスバーに表示します。\r
284 ///\r
285 void MainWindow::view_statusChanged(const QString &text)\r
286 {\r
287     statusBar()->findChild<QLabel*>("Right")->setText(text);\r
288 }\r
289 \r
290 ///////////////////////////////////////////////////////////////////////////////\r
291 /// \brief MainWindow::view_showed\r
292 /// \param w    表示されたビュー\r
293 ///\r
294 /// パネルのビューが表示された場合の処理を行います。\r
295 ///\r
296 void MainWindow::view_showed(QWidget *w)\r
297 {\r
298     w->setFocus();\r
299 }\r
300 \r
301 ///////////////////////////////////////////////////////////////////////////////\r
302 /// \brief MainWindow::view_currentChanged\r
303 /// \param current  新しいカレントインデックス\r
304 /// \param previous (使用しません)\r
305 ///\r
306 /// カレントインデックスが変更された場合の処理を行います。\r
307 ///\r
308 void MainWindow::view_currentChanged(const QModelIndex &current, const QModelIndex &previous)\r
309 {\r
310     qDebug() << "MainWindow::view_currentChanged()" << current;\r
311     Q_UNUSED(previous);\r
312 \r
313     if (focusItemView() != sender()->parent()) {\r
314         return;\r
315     }\r
316 \r
317     statusBar()->showMessage(activeModel()->filePath(current));\r
318 \r
319     if (m_viewMode == ModePreview) {\r
320         view_statusChanged();\r
321         inactivePanel()->setViewItem(current);\r
322     }\r
323 \r
324     updateActions();\r
325 }\r
326 \r
327 ///////////////////////////////////////////////////////////////////////////////\r
328 /// \brief MainWindow::view_finished\r
329 ///\r
330 /// ビューアの終了\r
331 ///\r
332 void MainWindow::view_finished()\r
333 {\r
334     qDebug() << "MainWindow::view_finished()";\r
335 \r
336     statusBar()->findChild<QLabel*>("Right")->setText("");\r
337 \r
338     setViewMode(m_prevMode);\r
339 }\r
340 \r
341 ///////////////////////////////////////////////////////////////////////////////\r
342 /// \brief MainWindow::onMove\r
343 ///\r
344 /// 選択アイテムを隣のパネルに移動します。\r
345 ///\r
346 void MainWindow::onMove()\r
347 {\r
348     qDebug() << "MainWindow::onMove";\r
349 \r
350     QStringList list;\r
351     foreach (const QFileInfo &fi, selectedItems()) {\r
352         list << fi.absoluteFilePath();\r
353     }\r
354     if (list.isEmpty()) {\r
355         return;\r
356     }\r
357 \r
358     int row = focusItemView()->currentIndex().row();\r
359 \r
360     QString tgtPath = inactiveModel()->rootPath();\r
361     moveItems(list, tgtPath);\r
362 \r
363     if (row >= activeModel()->rowCount()) {\r
364         row = activeModel()->rowCount() - 1;\r
365     }\r
366     focusItemView()->setCurrentIndex(activeModel()->index(row, 1));\r
367 }\r
368 \r
369 ///////////////////////////////////////////////////////////////////////////////\r
370 /// \brief MainWindow::onKeyLeft\r
371 ///\r
372 /// ←キー押下時の処理を行います。\r
373 ///\r
374 void MainWindow::onKeyLeft()\r
375 {\r
376     qDebug() << "MainWindow::onKeyLeft()";\r
377 \r
378     QWidget *w = qApp->focusWidget();\r
379     if (w->objectName() == "folderView")\r
380     {\r
381         QWidget *panel = w->parentWidget()->parentWidget();\r
382         if (panel == ui->LPanel) {\r
383             activeModel()->onCdUp();\r
384         }\r
385         else if (ui->LPanel->folderPanel()->isVisible()){\r
386             ui->LPanel->folderPanel()->itemView()->setFocus();\r
387         }\r
388     }\r
389     else {\r
390         QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_PageUp, Qt::NoModifier);\r
391         qApp->sendEvent(w, &event);\r
392     }\r
393 }\r
394 \r
395 ///////////////////////////////////////////////////////////////////////////////\r
396 /// \brief MainWindow::onKeyRight\r
397 ///\r
398 /// →キー押下時の処理を行います。\r
399 ///\r
400 void MainWindow::onKeyRight()\r
401 {\r
402     qDebug() << "MainWindow::onKeyRight()";\r
403 \r
404     QWidget *w = qApp->focusWidget();\r
405     if (w->objectName() == "folderView")\r
406     {\r
407         QWidget *panel = w->parentWidget()->parentWidget();\r
408         if (panel == ui->RPanel) {\r
409             activeModel()->onCdUp();\r
410         }\r
411         else if (ui->RPanel->folderPanel()->isVisible()){\r
412             ui->RPanel->folderPanel()->itemView()->setFocus();\r
413         }\r
414     }\r
415     else {\r
416         QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_PageDown, Qt::NoModifier);\r
417         qDebug() << w->objectName();\r
418         qApp->sendEvent(w, &event);\r
419     }\r
420 }\r
421 \r
422 ///////////////////////////////////////////////////////////////////////////////\r
423 /// \brief MainWindow::onChooseFolder\r
424 ///\r
425 /// 選択したフォルダに移動します。\r
426 ///\r
427 void MainWindow::onChooseFolder()\r
428 {\r
429     qDebug() << "MainWindow::onChooseFolder()";\r
430 \r
431     QString path = QFileDialog::getExistingDirectory(\r
432                 this, tr("フォルダを選択"), activeModel()->rootPath());\r
433     if (!path.isEmpty()) {\r
434         activeModel()->setRootPath(path);\r
435     }\r
436 }\r
437 \r
438 ///////////////////////////////////////////////////////////////////////////////\r
439 /// \brief MainWindow::onCopyFileName\r
440 ///\r
441 /// ファイル名をクリップボードにコピーします。\r
442 ///\r
443 void MainWindow::onCopyFileName()\r
444 {\r
445     qDebug() << "MainWindow::onCopyFileName()";\r
446 \r
447     QClipboard *clipboard = qApp->clipboard();\r
448     clipboard->setText(activeModel()->fileName(focusItemView()->currentIndex()));\r
449 }\r
450 \r
451 ///////////////////////////////////////////////////////////////////////////////\r
452 /// \brief MainWindow::onCopyFilePath\r
453 ///\r
454 /// フルパスをクリップボードにコピーします。\r
455 ///\r
456 void MainWindow::onCopyFilePath()\r
457 {\r
458     qDebug() << "MainWindow::onCopyFilePath()";\r
459 \r
460     QClipboard *clipboard = qApp->clipboard();\r
461     clipboard->setText(activeModel()->filePath(focusItemView()->currentIndex()));\r
462 }\r
463 \r
464 ///////////////////////////////////////////////////////////////////////////////\r
465 /// \brief MainWindow::askOverWrite\r
466 /// \param copyMethod   上書き方法\r
467 /// \param alias        別名\r
468 /// \param srcPath      コピー元パス\r
469 /// \param tgtPath      コピー先パス\r
470 ///\r
471 /// 上書きの処理方法を選択するダイアログを表示します。\r
472 ///\r
473 void MainWindow::askOverWrite(QString *copyMethod,\r
474                               QString *alias,\r
475                               const QString &srcPath,\r
476                               const QString &tgtPath)\r
477 {\r
478     qDebug() << "MainWindow::askOverWrite()";\r
479 \r
480     CopyMoveWorker *worker = static_cast<CopyMoveWorker*>(sender());\r
481     if (!m_overwriteDialog.isKeepSetting() ||\r
482         m_overwriteDialog.copyMethod() == "rbRename")\r
483     {\r
484         m_overwriteDialog.setFileInfo(srcPath, tgtPath);\r
485         if (m_overwriteDialog.exec() == QDialog::Rejected) {\r
486             worker->abort();\r
487         }\r
488     }\r
489     *copyMethod = m_overwriteDialog.copyMethod();\r
490     *alias = m_overwriteDialog.alias();\r
491 \r
492     worker->endAsking();\r
493 }\r
494 \r
495 ///////////////////////////////////////////////////////////////////////////////\r
496 /// \brief MainWindow::onAddBookmark\r
497 ///\r
498 /// ブックマークを追加します。\r
499 ///\r
500 void MainWindow::onAddBookmark()\r
501 {\r
502     qDebug() << "MainWindow::onAddBookmark()";\r
503     qDebug() << sender()->objectName();\r
504 \r
505     FolderModel *m;\r
506     if (sender()->objectName() == "bookmarkBtn") {\r
507         FolderPanel *p = static_cast<FolderPanel*>(sender()->parent());\r
508         m = p->model();\r
509     }\r
510     else {\r
511         m = activeModel();\r
512     }\r
513 \r
514     QFileInfo fi(m->rootPath());\r
515     Preferences(this).addBookmark(fi.fileName(), fi.absoluteFilePath());\r
516     initBookmarkMenu();\r
517 \r
518     activePanel()->folderPanel()->itemView()->setFocus();\r
519     statusBar()->showMessage(tr("%1をブックマークに追加しました").arg(fi.absoluteFilePath()));\r
520 }\r
521 \r
522 ///////////////////////////////////////////////////////////////////////////////\r
523 /// \brief MainWindow::view_copyAvailable\r
524 /// \param yes  コピー可能ならtrue\r
525 ///\r
526 /// 選択範囲の有無をメニューに反映します。\r
527 ///\r
528 void MainWindow::view_copyAvailable(bool yes)\r
529 {\r
530     ui->text_Copy->setEnabled(yes);\r
531 }\r
532 \r
533 ///////////////////////////////////////////////////////////////////////////////\r
534 /// \brief MainWindow::copyItems\r
535 /// \param list     コピー元リスト\r
536 /// \param tgtDir   コピー先フォルダ\r
537 ///\r
538 /// アイテムをコピーします。\r
539 ///\r
540 void MainWindow::copyItems(const QStringList &list, const QString &tgtDir)\r
541 {\r
542     qDebug() << "MainWindow::copyItems()" << tgtDir;\r
543 \r
544     Preferences prefs(this);\r
545     if (prefs.isConfirmCopy() &&\r
546         QMessageBox::question(this, tr("確認"), tr("コピーを実行しますか?"))\r
547             != QMessageBox::Yes)\r
548     {\r
549         return;\r
550     }\r
551 \r
552     // 上書き確認ダイアログを初期化する\r
553     m_overwriteDialog.reset();\r
554 \r
555     // ワーカースレッドを作成する\r
556     CopyMoveWorker *worker = new CopyMoveWorker();\r
557     connect(worker, SIGNAL(askOverWrite(QString*,QString*,QString,QString)),\r
558             this, SLOT(askOverWrite(QString*,QString*,QString,QString)));\r
559     worker->setCopyList(list);\r
560     worker->setTargetDir(tgtDir);\r
561     worker->setMoveMode(false);\r
562 \r
563     // 進捗ダイアログを表示して、処理を開始する\r
564     OperationDialog opDlg(this);\r
565     opDlg.setWindowTitle(tr("コピー"));\r
566     opDlg.setWorker(worker);\r
567     opDlg.setAutoClose(prefs.isAutoCloseCopy());\r
568 \r
569     opDlg.exec();\r
570 \r
571     prefs.setAutoCloseCopy(opDlg.autoClose());\r
572 }\r
573 \r
574 ///////////////////////////////////////////////////////////////////////////////\r
575 /// \brief MainWindow::moveItems\r
576 /// \param list     移動元リスト\r
577 /// \param tgtDir   移動先フォルダ\r
578 ///\r
579 /// アイテムを移動します。\r
580 ///\r
581 void MainWindow::moveItems(const QStringList &list, const QString &tgtDir)\r
582 {\r
583     qDebug() << "MainWindow::moveItems()" << tgtDir;\r
584 \r
585     Preferences prefs(this);\r
586     if (prefs.isConfirmMove() &&\r
587         QMessageBox::question(this, tr("確認"), tr("移動を実行しますか?"))\r
588             != QMessageBox::Yes)\r
589     {\r
590         return;\r
591     }\r
592 \r
593     // 上書き確認ダイアログを初期化する\r
594     m_overwriteDialog.reset();\r
595 \r
596     // ワーカースレッドを作成する\r
597     CopyMoveWorker *worker = new CopyMoveWorker();\r
598     connect(worker, SIGNAL(askOverWrite(QString*,QString*,QString,QString)),\r
599             this, SLOT(askOverWrite(QString*,QString*,QString,QString)));\r
600     worker->setCopyList(list);\r
601     worker->setTargetDir(tgtDir);\r
602     worker->setMoveMode(true);\r
603 \r
604     // 進捗ダイアログを表示して、処理を開始する\r
605     OperationDialog opDlg(this);\r
606     opDlg.setWindowTitle(tr("移動"));\r
607     opDlg.setWorker(worker);\r
608     opDlg.setAutoClose(prefs.isAutoCloseMove());\r
609 \r
610     opDlg.exec();\r
611 \r
612     prefs.setAutoCloseMove(opDlg.autoClose());\r
613 }\r
614 \r
615 ///////////////////////////////////////////////////////////////////////////////\r
616 /// \brief MainWindow::onContextMenuEvent\r
617 /// \param obj  イベントが発生したオブジェクト\r
618 /// \param e    コンテキストメニューイベント\r
619 /// \return 処理した場合はtrue, 処理しなかった場合はfalseを返します。\r
620 ///\r
621 bool MainWindow::onContextMenuEvent(QObject *obj, QContextMenuEvent *e)\r
622 {\r
623     QMenu menu(this);\r
624     if (obj->objectName() == "textView") {\r
625         menu.addAction(ui->text_ConvertFromEUC);\r
626         menu.addAction(ui->text_ConvertFromJIS);\r
627         menu.addAction(ui->text_ConvertFromSJIS);\r
628         menu.addAction(ui->text_ConvertFromUTF8);\r
629         menu.addAction(ui->text_ConvertFromUTF16);\r
630         menu.addAction(ui->text_ConvertFromUTF16BE);\r
631         menu.addAction(ui->text_ConvertFromUTF16LE);\r
632         menu.addSeparator();\r
633         menu.addAction(ui->view_SelectAll);\r
634         menu.addAction(ui->text_Copy);\r
635         if (m_viewMode == ModeView) {\r
636             menu.addSeparator();\r
637             menu.addAction(ui->view_Back);\r
638         }\r
639     }\r
640     else if (obj->objectName() == "hexView") {\r
641         menu.addAction(ui->view_SelectAll);\r
642         menu.addAction(ui->text_Copy);\r
643         if (m_viewMode == ModeView) {\r
644             menu.addSeparator();\r
645             menu.addAction(ui->view_Back);\r
646         }\r
647     }\r
648     else if (obj->objectName() == "imageView") {\r
649         menu.addAction(ui->image_FitToWindow);\r
650         menu.addAction(ui->action_ScaleDown);\r
651         menu.addAction(ui->action_ScaleUp);\r
652         menu.addAction(ui->image_ScaleNormal);\r
653         menu.addSeparator();\r
654         menu.addAction(ui->image_Rotate90);\r
655         menu.addAction(ui->image_Rotate180);\r
656 \r
657         if (m_viewMode == ModeView) {\r
658             menu.addSeparator();\r
659             menu.addAction(ui->view_Back);\r
660         }\r
661     }\r
662     else if (obj->objectName() == "folderView" || obj->objectName() == "thumbnailView") {\r
663         menu.addAction(ui->action_OpenWith);\r
664         menu.addAction(ui->action_OpenEditor);\r
665         menu.addAction(ui->action_OpenTerminal);\r
666         menu.addAction(ui->action_OpenArchiver);\r
667         menu.addSeparator();\r
668         menu.addAction(ui->action_Copy);\r
669         menu.addAction(ui->action_Move);\r
670         menu.addSeparator();\r
671         menu.addAction(ui->action_Delete);\r
672         menu.addSeparator();\r
673         menu.addAction(ui->action_CopyFileName);\r
674         menu.addAction(ui->action_CopyFilePath);\r
675         menu.addSeparator();\r
676         menu.addAction(ui->action_Rename);\r
677     }\r
678     else {\r
679         qDebug() << "No context menu" << obj->objectName();\r
680         return false;\r
681     }\r
682 \r
683     QString statusText = statusBar()->currentMessage();\r
684     menu.exec(e->globalPos());\r
685     statusBar()->showMessage(statusText);\r
686 \r
687     return true;\r
688 }\r
689 \r
690 ///////////////////////////////////////////////////////////////////////////////\r
691 /// \brief MainWindow::onKeyPressEvent\r
692 /// \param obj  イベントが発生したオブジェクト\r
693 /// \param e    キーイベントオブジェクト\r
694 /// \return 処理した場合はtrue, 処理しなかった場合はfalseを返します。\r
695 ///\r
696 bool MainWindow::onKeyPressEvent(QObject *obj, QKeyEvent *e)\r
697 {\r
698     qDebug() << "MainWindow::onKeyPressEvent()";\r
699 \r
700     QString modifier = QString::null;\r
701     if (e->modifiers() & Qt::ShiftModifier)     { modifier += "Shift+"; }\r
702     if (e->modifiers() & Qt::ControlModifier)   { modifier += "Ctrl+"; }\r
703     if (e->modifiers() & Qt::AltModifier)       { modifier += "Alt+"; }\r
704     if (e->modifiers() & Qt::MetaModifier)      { modifier += "Meta+"; }\r
705 \r
706     QString key = modifier + QKeySequence(e->key()).toString();\r
707 \r
708     foreach (QAction *action, findChildren<QAction*>()) {\r
709         if (action->isEnabled()) {\r
710             foreach (const QKeySequence &ks, action->shortcuts()) {\r
711                 if (ks.toString() == key) {\r
712                     qDebug() << "emit" << action->objectName();\r
713                     if (action->isCheckable()) {\r
714                         action->toggle();\r
715                     }\r
716                     else {\r
717                         action->trigger();\r
718                     }\r
719                     return true;\r
720                 }\r
721              }\r
722         }\r
723     }\r
724 \r
725     if (obj->objectName() == "folderView" || obj->objectName() == "thumbnailView")\r
726     {\r
727         // カーソル移動系のみ有効にする\r
728         switch (e->key()) {\r
729         case Qt::Key_Down:\r
730         case Qt::Key_Up:\r
731         case Qt::Key_Left:\r
732         case Qt::Key_Right:\r
733         case Qt::Key_Home:\r
734         case Qt::Key_End:\r
735         case Qt::Key_PageDown:\r
736         case Qt::Key_PageUp:\r
737         case Qt::Key_Tab:\r
738             return false;\r
739         }\r
740         return true;\r
741     }\r
742 \r
743     return false;\r
744 }\r
745 \r
746 ///////////////////////////////////////////////////////////////////////////////\r
747 /// \brief MainWindow::onCopy\r
748 ///\r
749 /// 選択アイテムを隣のパネルにコピーします。\r
750 ///\r
751 void MainWindow::onCopy()\r
752 {\r
753     qDebug() << "MainWindow::onCopy";\r
754 \r
755     QStringList list;\r
756     foreach (const QFileInfo &fi, selectedItems()) {\r
757         list << fi.absoluteFilePath();\r
758     }\r
759     if (list.isEmpty()) {\r
760         return;\r
761     }\r
762 \r
763     QString tgtPath = inactiveModel()->rootPath();\r
764     copyItems(list, tgtPath);\r
765 }\r
766 \r
767 ///////////////////////////////////////////////////////////////////////////////\r
768 /// \brief MainWindow::onCreateFile\r
769 ///\r
770 /// ファイルを作成します。\r
771 ///\r
772 void MainWindow::onCreateFile()\r
773 {\r
774     qDebug() << "MainWindow::onCreateFile";\r
775 \r
776     bool bOk;\r
777     QString name = QInputDialog::getText(\r
778                 this, tr("ファイルを作成"), tr("ファイル名:"),\r
779                 QLineEdit::Normal, "", &bOk);\r
780     if (!bOk || name.isEmpty()) {\r
781         return;\r
782     }\r
783 \r
784     QModelIndex index = activeModel()->touch(name);\r
785     if (!index.isValid()) {\r
786         QMessageBox::critical(\r
787                     this, tr("エラー"),\r
788                     tr("ファイルの作成に失敗しました。"));\r
789         return;\r
790     }\r
791 \r
792     focusItemView()->setCurrentIndex(index);\r
793     if (Preferences(this).isOpenAfterCreation()) {\r
794         onOpenEditor(index);\r
795     }\r
796 }\r
797 \r
798 ///////////////////////////////////////////////////////////////////////////////\r
799 /// \brief MainWindow::onCreateFolder\r
800 ///\r
801 /// フォルダを作成します。\r
802 ///\r
803 void MainWindow::onCreateFolder()\r
804 {\r
805     qDebug() << "MainWindow::onCreateFolder";\r
806 \r
807     bool bOk;\r
808     QString name = QInputDialog::getText(\r
809                 this, tr("フォルダを作成"), tr("フォルダ名:"),\r
810                 QLineEdit::Normal, "", &bOk);\r
811     if (!bOk || name.isEmpty()) {\r
812         return;\r
813     }\r
814 \r
815     QModelIndex index = activeModel()->mkdir(name);\r
816     if (!index.isValid()) {\r
817         QMessageBox::critical(\r
818                     this, tr("エラー"),\r
819                     tr("フォルダの作成に失敗しました。"));\r
820         return;\r
821     }\r
822 \r
823     focusItemView()->setCurrentIndex(index);\r
824     if (Preferences(this).isMoveAfterCreation()) {\r
825         onOpen(index);\r
826     }\r
827 }\r
828 \r
829 ///////////////////////////////////////////////////////////////////////////////\r
830 /// \brief MainWindow::onDelete\r
831 ///\r
832 /// 選択アイテムを削除します。\r
833 ///\r
834 void MainWindow::onDelete()\r
835 {\r
836     qDebug() << "MainWindow::onDelete";\r
837 \r
838     QFileInfoList list = selectedItems();\r
839     if (list.isEmpty()) {\r
840         return;\r
841     }\r
842 \r
843     Preferences prefs(this);\r
844     if (prefs.isConfirmDelete()) {\r
845         QString msg;\r
846         if (list.size() == 1) {\r
847             msg = list[0].fileName();\r
848         }\r
849         else {\r
850             msg = tr("%1個のアイテム").arg(list.size());\r
851         }\r
852         int ret = QMessageBox::question(\r
853                     this, tr("確認"),\r
854                     tr("%1を削除しますか?").arg(msg));\r
855         if (ret != QMessageBox::Yes) {\r
856             return;\r
857         }\r
858     }\r
859 \r
860     DeleteWorker *worker = new DeleteWorker();\r
861     worker->setDeleteList(list);\r
862 \r
863     OperationDialog opDlg(this);\r
864     opDlg.setWindowTitle(tr("削除"));\r
865     opDlg.setWorker(worker);\r
866     opDlg.setAutoClose(prefs.isAutoCloseDelete());\r
867 \r
868     opDlg.exec();\r
869 \r
870     prefs.setAutoCloseDelete(opDlg.autoClose());\r
871 }\r
872 \r
873 ///////////////////////////////////////////////////////////////////////////////\r
874 /// \brief MainWindow::onOpen\r
875 /// \param index    (使用しません)\r
876 ///\r
877 /// アイテムを開きます。\r
878 ///\r
879 void MainWindow::onOpen(const QModelIndex &index)\r
880 {\r
881     Q_UNUSED(index);\r
882     qDebug() << "MainWindow::onOpen()" << index;\r
883 \r
884     QModelIndex current = focusItemView()->currentIndex();\r
885     if (activeModel()->isDir(current)) {\r
886         activeModel()->setRootPath(activeModel()->filePath(current));\r
887         return;\r
888     }\r
889 \r
890     // 外部アプリを優先する場合\r
891     QString ext = activeModel()->fileInfo(current).suffix().toLower();\r
892     QStringList list = Preferences(this).getPreferExtensions().split(",", QString::SkipEmptyParts);\r
893     foreach (const QString& s, list) {\r
894         if (ext == s.trimmed().toLower()) {\r
895             QString path = QDir::toNativeSeparators(activeModel()->filePath(current));\r
896             QDesktopServices::openUrl(QUrl("file:///" + path));\r
897             return;\r
898         }\r
899     }\r
900 \r
901     // 内蔵ビューアで表示する\r
902     setViewMode(ModeView);\r
903 }\r
904 \r
905 ///////////////////////////////////////////////////////////////////////////////\r
906 /// \brief MainWindow::prefs_updated\r
907 ///\r
908 /// 設定が変更された場合の処理を行います。\r
909 ///\r
910 void MainWindow::prefs_updated()\r
911 {\r
912     Preferences prefs(this);\r
913     ui->LPanel->updateAppearance(prefs);\r
914     ui->RPanel->updateAppearance(prefs);\r
915     ui->FPanel->updateAppearance(prefs);\r
916 }\r
917 \r
918 ///////////////////////////////////////////////////////////////////////////////\r
919 /// \brief MainWindow::onOpenEditor\r
920 /// \param path\r
921 ///\r
922 /// 選択アイテムを外部エディタで開きます。\r
923 ///\r
924 void MainWindow::onOpenEditor(const QModelIndex &index)\r
925 {\r
926     qDebug() << "MainWindow::onOpenEditor";\r
927 \r
928     QString exe = Preferences(this).getEditorPath();\r
929     if (exe.isEmpty()) {\r
930         QMessageBox::critical(\r
931                     this, tr("エラー"),\r
932                     tr("外部エディタのパスが未定義です。"));\r
933         return;\r
934     }\r
935 \r
936     QFileInfoList list;\r
937     if (index.isValid()) {\r
938         list << activeModel()->fileInfo(index);\r
939     }\r
940     else {\r
941         list = selectedItems();\r
942     }\r
943 \r
944     QString files;\r
945     foreach (const QFileInfo &info, list) {\r
946         files += " " + QQ(info.absoluteFilePath());\r
947     }\r
948 #ifdef Q_OS_MAC\r
949     QString command = "open -a " + exe + files;\r
950 #else\r
951     QString command = exe + files;\r
952 #endif\r
953     if (!startProcess(command, tr("外部エディタの起動に失敗しました。"))) {\r
954         qDebug() << command;\r
955     }\r
956 }\r
957 \r
958 ///////////////////////////////////////////////////////////////////////////////\r
959 /// \brief MainWindow::onOpenTerminal\r
960 ///\r
961 /// 選択アイテムをターミナルで開きます。\r
962 ///\r
963 void MainWindow::onOpenTerminal()\r
964 {\r
965     qDebug() << "MainWindow::onOpenTerminal";\r
966 \r
967     QString exe = Preferences(this).getTerminalPath();\r
968     if (exe.isEmpty()) {\r
969         QMessageBox::critical(\r
970                     this, tr("エラー"),\r
971                     tr("ターミナルのパスが未定義です。"));\r
972         return;\r
973     }\r
974 \r
975     QSet<QString> dirs;\r
976     foreach (const QFileInfo &info, selectedItems()) {\r
977         if (info.isDir()) {\r
978             dirs.insert(info.absoluteFilePath());\r
979         }\r
980         else {\r
981             dirs.insert(info.absolutePath());\r
982         }\r
983     }\r
984 \r
985     foreach (const QString &dir, dirs) {\r
986 #ifdef Q_OS_MAC\r
987         QString command = "open -n -a " + exe + " " + QQ(dir);\r
988 #else\r
989         QString command = exe + " " + QQ(dir);\r
990 #endif\r
991         if (!startProcess(command, tr("ターミナルの起動に失敗しました。"))) {\r
992             qDebug() << command;\r
993             break;\r
994         }\r
995     }\r
996 }\r
997 \r
998 ///////////////////////////////////////////////////////////////////////////////\r
999 /// \brief MainWindow::onOpenArchiver\r
1000 ///\r
1001 /// 選択アイテムをアーカイバで開きます。\r
1002 ///\r
1003 void MainWindow::onOpenArchiver()\r
1004 {\r
1005     qDebug() << "MainWindow::onOpenArchiver";\r
1006 \r
1007     QString exe = Preferences(this).getArchiverPath();\r
1008     if (exe.isEmpty()) {\r
1009         QMessageBox::critical(\r
1010                     this, tr("エラー"),\r
1011                     tr("アーカイバのパスが未定義です。"));\r
1012         return;\r
1013     }\r
1014 \r
1015     QString files;\r
1016     foreach (const QFileInfo &info, selectedItems()) {\r
1017         files += " " + QQ(info.absoluteFilePath());\r
1018     }\r
1019 #ifdef Q_OS_MAC\r
1020     QString command = "open -a " + exe + files;\r
1021 #else\r
1022     QString command = exe + files;\r
1023 #endif\r
1024     if (!startProcess(command, tr("アーカイバの起動に失敗しました。"))) {\r
1025         qDebug() << command;\r
1026     }\r
1027 }\r
1028 \r
1029 ///////////////////////////////////////////////////////////////////////////////\r
1030 /// \brief MainWindow::onOpenBookmark\r
1031 ///\r
1032 /// ブックマークのメニュー項目をクリックしたときの処理を行います。\r
1033 ///\r
1034 void MainWindow::onOpenBookmark()\r
1035 {\r
1036     qDebug() << "MainWindow::onOpenBookmark()";\r
1037 \r
1038     QAction *action = qobject_cast<QAction*>(sender());\r
1039     Q_CHECK_PTR(action);\r
1040 \r
1041     int i = action->data().toInt();\r
1042     activeModel()->setRootPath(Preferences(this).getBookmarkPath(i));\r
1043 }\r
1044 \r
1045 ///////////////////////////////////////////////////////////////////////////////\r
1046 /// \brief MainWindow::onRename\r
1047 ///\r
1048 /// 選択アイテムの名前を変更します。\r
1049 ///\r
1050 void MainWindow::onRename()\r
1051 {\r
1052     qDebug() << "MainWindow::onRename";\r
1053 \r
1054     QFileInfoList list = selectedItems();\r
1055     if (list.isEmpty()) {\r
1056         return;\r
1057     }\r
1058 \r
1059     AbstractRenameDialog *dlg;\r
1060     if (list.size() == 1) {\r
1061         dlg = new RenameSingleDialog(this);\r
1062     }\r
1063     else {\r
1064         dlg = new RenameMultiDialog(this);\r
1065     }\r
1066     dlg->setWorkingDirectory(activeModel()->rootPath());\r
1067     dlg->setNames(list);\r
1068     int dlgResult = dlg->exec();\r
1069     if (dlgResult != QDialog::Accepted || dlg->renameMap().isEmpty()) {\r
1070         return;\r
1071     }\r
1072 \r
1073     Preferences prefs(this);\r
1074     if (prefs.isConfirmRename() &&\r
1075         QMessageBox::question(this, tr("確認"), tr("名前の変更を実行しますか?"))\r
1076             != QMessageBox::Yes)\r
1077     {\r
1078         return;\r
1079     }\r
1080 \r
1081     RenameWorker *worker = new RenameWorker();\r
1082     worker->setRenameMap(&dlg->renameMap());\r
1083 \r
1084     OperationDialog opDlg(this);\r
1085     opDlg.setWindowTitle(tr("名前を変更"));\r
1086     opDlg.setWorker(worker);\r
1087     opDlg.setAutoClose(prefs.isAutoCloseRename());\r
1088 \r
1089     opDlg.exec();\r
1090 \r
1091     QFileInfo fi(dlg->renameMap().first());\r
1092     focusItemView()->setCurrentIndex(activeModel()->search(fi.fileName()));\r
1093 \r
1094     prefs.setAutoCloseRename(opDlg.autoClose());\r
1095 }\r
1096 \r
1097 ///////////////////////////////////////////////////////////////////////////////\r
1098 /// \brief MainWindow::onOpenWith\r
1099 ///\r
1100 /// 関連付けられたアプリで開きます。\r
1101 ///\r
1102 void MainWindow::onOpenWith()\r
1103 {\r
1104     qDebug() << "MainWindow::onOpenWith";\r
1105 \r
1106     foreach (const QFileInfo &info, selectedItems()) {\r
1107         QString path = QDir::toNativeSeparators(info.absoluteFilePath());\r
1108         QDesktopServices::openUrl(QUrl("file:///" + path));\r
1109     }\r
1110 }\r
1111 \r
1112 ///////////////////////////////////////////////////////////////////////////////\r
1113 /// \brief MainWindow::showBookmarkDialog\r
1114 ///\r
1115 /// ブックマーク一覧ダイアログを表示します。\r
1116 ///\r
1117 void MainWindow::showBookmarkDialog()\r
1118 {\r
1119     qDebug() << "MainWindow::showBookmarkDialog()";\r
1120 \r
1121     BookmarkDialog dlg(this);\r
1122     dlg.setEditMode(false);\r
1123     if (dlg.exec() == QDialog::Accepted) {\r
1124         int n = dlg.selectedIndex();\r
1125         activeModel()->setRootPath(Preferences(this).getBookmarkPath(n + 1));\r
1126     }\r
1127 }\r
1128 \r
1129 ///////////////////////////////////////////////////////////////////////////////\r
1130 /// \brief MainWindow::onEditBookmark\r
1131 ///\r
1132 /// ブックマークの編集ダイアログを表示します。\r
1133 ///\r
1134 void MainWindow::onEditBookmark()\r
1135 {\r
1136     qDebug() << "MainWindow::onEditBookmark()";\r
1137 \r
1138     BookmarkDialog dlg(this);\r
1139     dlg.setEditMode(true);\r
1140 \r
1141     if (dlg.exec() == QDialog::Accepted) {\r
1142         initBookmarkMenu();\r
1143     }\r
1144 }\r
1145 \r
1146 ///////////////////////////////////////////////////////////////////////////////\r
1147 /// \brief MainWindow::showFilterDialog\r
1148 ///\r
1149 /// フィルタ設定ダイアログを表示します。\r
1150 ///\r
1151 void MainWindow::showFilterDialog()\r
1152 {\r
1153     qDebug() << "MainWindow::showFilterDialog()";\r
1154 \r
1155     QString filters = activeModel()->nameFilters().join(" ");\r
1156 \r
1157     QInputDialog dlg(this);\r
1158     dlg.setInputMode(QInputDialog::TextInput);\r
1159     dlg.setWindowTitle(tr("フィルタを設定"));\r
1160     dlg.setLabelText(tr("フィルタ:"));\r
1161     dlg.setTextValue(filters);\r
1162     dlg.resize(width() * 0.8, dlg.height());\r
1163 \r
1164     if (dlg.exec() == QDialog::Accepted) {\r
1165         filters = dlg.textValue();\r
1166         if (filters.isEmpty()) {\r
1167             filters = "*";\r
1168         }\r
1169 \r
1170         activeModel()->setNameFilters(filters.split(" ", QString::SkipEmptyParts));\r
1171         activeModel()->refresh();\r
1172     }\r
1173 }\r
1174 \r
1175 ///////////////////////////////////////////////////////////////////////////////\r
1176 /// \brief MainWindow::showHistoryDialog\r
1177 ///\r
1178 /// 履歴選択ダイアログを表示します。\r
1179 ///\r
1180 void MainWindow::showHistoryDialog()\r
1181 {\r
1182     qDebug() << "MainWindow::showHistoryDialog()";\r
1183 \r
1184     HistoryDialog dlg(this);\r
1185     dlg.setModel(ui->LPanel->model(), ui->RPanel->model(), activeModel());\r
1186     dlg.exec();\r
1187 }\r
1188 \r
1189 ///////////////////////////////////////////////////////////////////////////////\r
1190 /// \brief MainWindow::showSortDialog\r
1191 ///\r
1192 /// ソート方法選択ダイアログを表示します。\r
1193 ///\r
1194 void MainWindow::showSortDialog()\r
1195 {\r
1196     qDebug() << "MainWindow::showSortDialog()";\r
1197 \r
1198     SortDialog dlg(this);\r
1199     dlg.setModel(activeModel());\r
1200     dlg.exec();\r
1201 }\r
1202 \r
1203 ///////////////////////////////////////////////////////////////////////////////\r
1204 /// \brief MainWindow::onSplitCenter\r
1205 ///\r
1206 /// パネルを中央で分割します。\r
1207 ///\r
1208 void MainWindow::onSplitCenter()\r
1209 {\r
1210     qDebug() << "MainWindow::onSplitCenter()";\r
1211 \r
1212     QList<int> sizes = ui->splitter->sizes();\r
1213     int sizeTotal = sizes[0] + sizes[1];\r
1214     sizes[0] = sizeTotal / 2;\r
1215     sizes[1] = sizeTotal - sizes[0];\r
1216     ui->splitter->setSizes(sizes);\r
1217 }\r
1218 \r
1219 ///////////////////////////////////////////////////////////////////////////////\r
1220 /// \brief MainWindow::onSwap\r
1221 ///\r
1222 /// 左右のパネルでモデルを入れ替えます。\r
1223 ///\r
1224 void MainWindow::onSwap()\r
1225 {\r
1226     qDebug() << "MainWindow::onSwap()";\r
1227 \r
1228     FolderModel *tmp = ui->LPanel->model();\r
1229     ui->LPanel->setModel(ui->RPanel->model());\r
1230     ui->RPanel->setModel(tmp);\r
1231 \r
1232     // アクティブ状態も変更する\r
1233     if (ui->LPanel->model()->isActive()) {\r
1234         setActiveModel(ui->RPanel->model());\r
1235     }\r
1236     else {\r
1237         setActiveModel(ui->LPanel->model());\r
1238     }\r
1239 }\r
1240 \r
1241 ///////////////////////////////////////////////////////////////////////////////\r
1242 /// \brief MainWindow::onTogglePreviewMode\r
1243 /// \param checked  メニューのチェック状態\r
1244 ///\r
1245 /// 通常モード/プレビューモードを切り替えます。\r
1246 ///\r
1247 void MainWindow::onTogglePreviewMode(bool checked)\r
1248 {\r
1249     qDebug() << "MainWindow::onTogglePreviewMode()" << checked;\r
1250 \r
1251     if (checked) {\r
1252         setViewMode(ModePreview);\r
1253     }\r
1254     else {\r
1255         setViewMode(ModeBasic);\r
1256     }\r
1257 }\r
1258 \r
1259 ///////////////////////////////////////////////////////////////////////////////\r
1260 /// \brief MainWindow::onSearchNext\r
1261 ///\r
1262 /// 次のアイテムを検索します。\r
1263 ///\r
1264 void MainWindow::onSearchNext()\r
1265 {\r
1266     qDebug() << "MainWindow::onSearchNext";\r
1267 \r
1268     static_cast<FolderPanel*>(qApp->focusWidget()->parentWidget())->searchNext();\r
1269 }\r
1270 \r
1271 ///////////////////////////////////////////////////////////////////////////////\r
1272 /// \brief MainWindow::onSearchPrev\r
1273 ///\r
1274 /// 前のアイテムを検索します。\r
1275 ///\r
1276 void MainWindow::onSearchPrev()\r
1277 {\r
1278     qDebug() << "MainWindow::onSearchPrev";\r
1279 \r
1280     static_cast<FolderPanel*>(qApp->focusWidget()->parentWidget())->searchNext(-1);\r
1281 }\r
1282 \r
1283 ///////////////////////////////////////////////////////////////////////////////\r
1284 /// \brief MainWindow::onKeyDown\r
1285 ///\r
1286 /// フォーカスウィジェットに↓キーイベントを送信します。\r
1287 ///\r
1288 void MainWindow::onKeyDown()\r
1289 {\r
1290     qDebug() << "MainWindow::onKeyDown()";\r
1291 \r
1292     QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier);\r
1293     qApp->sendEvent(qApp->focusWidget(), &event);\r
1294 }\r
1295 \r
1296 ///////////////////////////////////////////////////////////////////////////////\r
1297 /// \brief MainWindow::onKeyEnd\r
1298 ///\r
1299 /// フォーカスウィジェットにEND, Ctrl+ENDキーイベントを送信します。\r
1300 ///\r
1301 void MainWindow::onKeyEnd()\r
1302 {\r
1303     qDebug() << "MainWindow::onKeyEnd()";\r
1304 \r
1305     QKeyEvent event1 = QKeyEvent(QEvent::KeyPress, Qt::Key_End, Qt::NoModifier);\r
1306     qApp->sendEvent(qApp->focusWidget(), &event1);\r
1307 \r
1308     QKeyEvent event2 = QKeyEvent(QEvent::KeyPress, Qt::Key_End, Qt::ControlModifier);\r
1309     qApp->sendEvent(qApp->focusWidget(), &event2);\r
1310 }\r
1311 \r
1312 ///////////////////////////////////////////////////////////////////////////////\r
1313 /// \brief MainWindow::onKeyHome\r
1314 ///\r
1315 /// フォーカスウィジェットにHOME, Ctrl+HOMEキーイベントを送信します。\r
1316 ///\r
1317 void MainWindow::onKeyHome()\r
1318 {\r
1319     qDebug() << "MainWindow::onKeyHome()";\r
1320 \r
1321     QKeyEvent event1 = QKeyEvent(QEvent::KeyPress, Qt::Key_Home, Qt::NoModifier);\r
1322     qApp->sendEvent(qApp->focusWidget(), &event1);\r
1323 \r
1324     QKeyEvent event2 = QKeyEvent(QEvent::KeyPress, Qt::Key_Home, Qt::ControlModifier);\r
1325     qApp->sendEvent(qApp->focusWidget(), &event2);\r
1326 }\r
1327 \r
1328 ///////////////////////////////////////////////////////////////////////////////\r
1329 /// \brief MainWindow::onKeyUp\r
1330 ///\r
1331 /// フォーカスウィジェットに↑キーイベントを送信します。\r
1332 ///\r
1333 void MainWindow::onKeyUp()\r
1334 {\r
1335     qDebug() << "MainWindow::onKeyUp()";\r
1336 \r
1337     QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier);\r
1338     qApp->sendEvent(qApp->focusWidget(), &event);\r
1339 }\r
1340 \r
1341 ///////////////////////////////////////////////////////////////////////////////\r
1342 /// \brief MainWindow::onKeyHomeOther\r
1343 ///\r
1344 /// 非フォーカスビューにHOME, Ctrl+HOMEキーイベントを送信します。\r
1345 ///\r
1346 void MainWindow::onKeyHomeOther()\r
1347 {\r
1348     qDebug() << "MainWindow::onKeyHomeOther()";\r
1349 \r
1350     QKeyEvent event1 = QKeyEvent(QEvent::KeyPress, Qt::Key_Home, Qt::NoModifier);\r
1351     sendEventOther(&event1);\r
1352 \r
1353     QKeyEvent event2 = QKeyEvent(QEvent::KeyPress, Qt::Key_Home, Qt::ControlModifier);\r
1354     sendEventOther(&event2);\r
1355 }\r
1356 \r
1357 ///////////////////////////////////////////////////////////////////////////////\r
1358 /// \brief MainWindow::onKeyDownOther\r
1359 ///\r
1360 /// 非フォーカスビューに↓キーイベントを送信します。\r
1361 ///\r
1362 void MainWindow::onKeyDownOther()\r
1363 {\r
1364     qDebug() << "MainWindow::onKeyDownOther()";\r
1365 \r
1366     QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier);\r
1367     sendEventOther(&event);\r
1368 }\r
1369 \r
1370 ///////////////////////////////////////////////////////////////////////////////\r
1371 /// \brief MainWindow::onKeyUpOther\r
1372 ///\r
1373 /// 非フォーカスビューに↑キーイベントを送信します。\r
1374 ///\r
1375 void MainWindow::onKeyUpOther()\r
1376 {\r
1377     qDebug() << "MainWindow::onKeyUpOther()";\r
1378 \r
1379     QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier);\r
1380     sendEventOther(&event);\r
1381 }\r
1382 \r
1383 ///////////////////////////////////////////////////////////////////////////////\r
1384 /// \brief MainWindow::onKeyEndOther\r
1385 ///\r
1386 /// 非フォーカスビューにEND, Ctrl+ENDキーイベントを送信します。\r
1387 ///\r
1388 void MainWindow::onKeyEndOther()\r
1389 {\r
1390     qDebug() << "MainWindow::onKeyEndOther()";\r
1391 \r
1392     QKeyEvent event1 = QKeyEvent(QEvent::KeyPress, Qt::Key_End, Qt::NoModifier);\r
1393     sendEventOther(&event1);\r
1394 \r
1395     QKeyEvent event2 = QKeyEvent(QEvent::KeyPress, Qt::Key_End, Qt::ControlModifier);\r
1396     sendEventOther(&event2);\r
1397 }\r
1398 \r
1399 ///////////////////////////////////////////////////////////////////////////////\r
1400 /// \brief MainWindow::initBookmarkMenu\r
1401 ///\r
1402 /// ブックマークメニューを初期化します。\r
1403 ///\r
1404 void MainWindow::initBookmarkMenu()\r
1405 {\r
1406     qDebug() << "MainWindow::initBookmarkMenu()";\r
1407 \r
1408     Preferences prefs(this);\r
1409     QFileIconProvider iconProvider;\r
1410 \r
1411     ui->menu_Bookmark->clear();\r
1412     ui->menu_Bookmark->addAction(ui->action_AddBookmark);\r
1413     ui->menu_Bookmark->addAction(ui->action_EditBookmark);\r
1414     ui->menu_Bookmark->addSeparator();\r
1415     for (int n = 1; ; n++) {\r
1416         QString name = prefs.getBookmarkEntry(n);\r
1417         if (name.isEmpty()) {\r
1418             break;\r
1419         }\r
1420         QString path = prefs.getBookmarkPath(n);\r
1421 \r
1422         QAction *action = ui->menu_Bookmark->addAction(\r
1423                     iconProvider.icon(QFileInfo(path)), name, this,\r
1424                     SLOT(onOpenBookmark()));\r
1425         action->setData(n);\r
1426     }\r
1427 \r
1428     m_actions = findChildren<QAction*>();\r
1429 }\r
1430 \r
1431 ///////////////////////////////////////////////////////////////////////////////\r
1432 /// \brief MainWindow::sendEventOther\r
1433 /// \param event    送信するイベント\r
1434 ///\r
1435 /// 非フォーカスのビューにイベントを送信します。\r
1436 ///\r
1437 void MainWindow::sendEventOther(QEvent *event)\r
1438 {\r
1439     qDebug() << "MainWindow::sendEventOther()";\r
1440 \r
1441     qApp->sendEvent(inactivePanel()->visibleView(), event);\r
1442 }\r
1443 \r
1444 ///////////////////////////////////////////////////////////////////////////////\r
1445 /// \brief MainWindow::onSyncPanel\r
1446 ///\r
1447 /// 隣のパネルと同じフォルダを表示します。\r
1448 ///\r
1449 void MainWindow::onSyncPanel()\r
1450 {\r
1451     qDebug() << "MainWindow::onSyncPanel()";\r
1452 \r
1453     activeModel()->setRootPath(inactiveModel()->rootPath());\r
1454 }\r
1455 \r
1456 ///////////////////////////////////////////////////////////////////////////////\r
1457 /// \brief MainWindow::onSyncPanelTo\r
1458 ///\r
1459 /// 隣のパネルに同じフォルダを表示します。\r
1460 ///\r
1461 void MainWindow::onSyncPanelTo()\r
1462 {\r
1463     qDebug() << "MainWindow::onSyncPanelTo()";\r
1464 \r
1465     inactiveModel()->setRootPath(activeModel()->rootPath());\r
1466 }\r
1467 \r
1468 ///////////////////////////////////////////////////////////////////////////////\r
1469 /// \brief MainWindow::onToggleFullMode\r
1470 /// \param checked  メニューのチェック状態\r
1471 ///\r
1472 /// 単画面/二画面を切り替えます。\r
1473 ///\r
1474 void MainWindow::onToggleFullMode(bool checked)\r
1475 {\r
1476     qDebug() << "MainWindow::onToggleFullMode()" << checked;\r
1477 \r
1478     if (checked) {\r
1479         setViewMode(ModeFull);\r
1480     }\r
1481     else {\r
1482         setViewMode(ModeBasic);\r
1483     }\r
1484 }\r
1485 \r
1486 ///////////////////////////////////////////////////////////////////////////////\r
1487 /// \brief MainWindow::onToggleSearch\r
1488 /// \param checked  メニューのチェック状態\r
1489 ///\r
1490 /// 検索ボックスの表示/非表示を切り替えます。\r
1491 ///\r
1492 void MainWindow::onToggleSearch(bool checked)\r
1493 {\r
1494     qDebug() << "MainWindow::onToggleSearch" << checked;\r
1495 \r
1496     // 丸投げ\r
1497     ui->LPanel->folderPanel()->toggleSearch(checked);\r
1498     ui->RPanel->folderPanel()->toggleSearch(checked);\r
1499     ui->FPanel->folderPanel()->toggleSearch(checked);\r
1500 }\r
1501 \r
1502 ///////////////////////////////////////////////////////////////////////////////\r
1503 /// \brief MainWindow::showPreferenceDialog\r
1504 ///\r
1505 /// 環境設定ダイアログを表示します。\r
1506 ///\r
1507 void MainWindow::showPreferenceDialog()\r
1508 {\r
1509     qDebug() << "MainWindow::showPreferenceDialog";\r
1510 \r
1511     PreferenceDialog dlg(this);\r
1512     if (dlg.exec() == QDialog::Accepted) {\r
1513         prefs_updated();\r
1514     }\r
1515 }\r
1516 \r
1517 ///////////////////////////////////////////////////////////////////////////////\r
1518 /// \brief MainWindow::onToggleHidden\r
1519 /// \param checked  メニューのチェック状態\r
1520 ///\r
1521 /// 隠しファイルの表示/非表示を切り替えます。\r
1522 ///\r
1523 void MainWindow::onToggleHidden(bool checked)\r
1524 {\r
1525     qDebug() << "MainWindow::onToggleHidden" << checked;\r
1526 \r
1527     if (checked) {\r
1528         activeModel()->setFilter(activeModel()->filter() | QDir::Hidden);\r
1529     }\r
1530     else {\r
1531         activeModel()->setFilter(activeModel()->filter() ^ QDir::Hidden);\r
1532     }\r
1533 \r
1534     activeModel()->refresh();\r
1535 }\r
1536 \r
1537 ///////////////////////////////////////////////////////////////////////////////\r
1538 /// \brief MainWindow::onToggleSystem\r
1539 /// \param checked  メニューのチェック状態\r
1540 ///\r
1541 /// システムファイルの表示/非表示を切り替えます。\r
1542 ///\r
1543 void MainWindow::onToggleSystem(bool checked)\r
1544 {\r
1545     qDebug() << "MainWindow::onToggleSystem" << checked;\r
1546 \r
1547     if (checked) {\r
1548         activeModel()->setFilter(activeModel()->filter() | QDir::System);\r
1549     }\r
1550     else {\r
1551         activeModel()->setFilter(activeModel()->filter() ^ QDir::System);\r
1552     }\r
1553 \r
1554     activeModel()->refresh();\r
1555 }\r
1556 \r
1557 ///////////////////////////////////////////////////////////////////////////////\r
1558 /// \brief MainWindow::onToggleThumbnailMode\r
1559 /// \param checked  メニューのチェック状態\r
1560 ///\r
1561 /// サムネイルモードの切り替えを行います。\r
1562 ///\r
1563 void MainWindow::onToggleThumbnailMode(bool checked)\r
1564 {\r
1565     qDebug() << "MainWindow::onToggleThumbnailMode()" << checked;\r
1566 \r
1567     activePanel()->folderPanel()->toggleView(checked);\r
1568 }\r
1569 \r
1570 ///////////////////////////////////////////////////////////////////////////////\r
1571 /// \brief MainWindow::onToggleToolbar\r
1572 /// \param checked メニューのチェック状態\r
1573 ///\r
1574 /// ツールバーの表示/非表示を切り替えます。\r
1575 ///\r
1576 void MainWindow::onToggleToolbar(bool checked)\r
1577 {\r
1578     ui->mainToolBar->setVisible(checked);\r
1579 }\r
1580 \r
1581 ///////////////////////////////////////////////////////////////////////////////\r
1582 /// \brief MainWindow::onCheckUpdate\r
1583 /// \param silent   最新版を使用している場合に何も表示しないならtrue\r
1584 ///\r
1585 /// アップデートの有無を確認します。\r
1586 ///\r
1587 void MainWindow::onCheckUpdate(bool silent)\r
1588 {\r
1589     qDebug() << "MainWindow::onCheckUpdate()" << silent;\r
1590 \r
1591     QNetworkAccessManager *manager = new QNetworkAccessManager(this);\r
1592 \r
1593     if (silent) {\r
1594         connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(checkUpdateFinishedSilent(QNetworkReply*)));\r
1595     }\r
1596     else {\r
1597         connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(checkUpdateFinished(QNetworkReply*)));\r
1598     }\r
1599 #ifdef Q_OS_WIN\r
1600     manager->get(QNetworkRequest(QUrl("http://gefu.sourceforge.jp/gefu_latest_win.html")));\r
1601 #elif defined(Q_OS_MAC)\r
1602     manager->get(QNetworkRequest(QUrl("http://gefu.sourceforge.jp/gefu_latest_mac.html")));\r
1603 #endif\r
1604 }\r
1605 \r
1606 void MainWindow::checkUpdateFinishedSilent(QNetworkReply *reply)\r
1607 {\r
1608     qDebug() << "MainWindow::checkUpdateFinishedSilent";\r
1609 \r
1610     checkUpdateFinished(reply, true);\r
1611 }\r
1612 \r
1613 void MainWindow::checkUpdateFinished(QNetworkReply *reply, bool silent)\r
1614 {\r
1615     qDebug() << "MainWindow::checkUpdateFinished" << silent;\r
1616 \r
1617     if (reply->error() == QNetworkReply::NoError) {\r
1618         QString str = reply->readAll();\r
1619         str = str.split(QRegExp("[\r\n]"), QString::SkipEmptyParts).at(0);\r
1620         QRegExp rx("Gefu([0-9]+)");\r
1621         rx.indexIn(str);\r
1622         QString version = rx.cap(1);\r
1623         if (version.toInt() > VERSION_VALUE * 100) {\r
1624             QMessageBox::information(\r
1625                         this, tr("情報"),\r
1626                         tr("最新のバージョンが存在します。<br/>") +\r
1627                         tr("<a href='%1'>こちらからダウンロードしてください。</a>").arg(str));\r
1628         }\r
1629         else if (!silent) {\r
1630             QMessageBox::information(\r
1631                         this, tr("情報"),\r
1632                         tr("お使いのバージョンは最新です。"));\r
1633         }\r
1634     }\r
1635     else if (!silent){\r
1636         QMessageBox::critical(\r
1637                     this, tr("エラー"),\r
1638                     tr("最新バージョンのチェックに失敗しました。<br/>") +\r
1639                     reply->errorString());\r
1640     }\r
1641 }\r
1642 \r
1643 ///////////////////////////////////////////////////////////////////////////////\r
1644 /// \brief MainWindow::initActions\r
1645 ///\r
1646 /// アクションを初期化します。\r
1647 ///\r
1648 void MainWindow::initActions()\r
1649 {\r
1650     qDebug() << "MainWindow::initActions()";\r
1651 \r
1652     QList<QKeySequence> shortcuts;\r
1653 \r
1654     //>>>>> 追加のショートカットキーを設定する\r
1655     appendActionShortcut(ui->action_Open, "M");\r
1656     appendActionShortcut(ui->action_OpenWith, "Shift+M");\r
1657     appendActionShortcut(ui->view_Back, "Backspace");\r
1658     // MacだとShift+の形で認識されてしまうもの\r
1659     appendActionShortcut(ui->action_ScaleUp, "Shift++");\r
1660     appendActionShortcut(ui->action_Filter, "Shift+*");\r
1661     appendActionShortcut(ui->action_OpenTerminal, "Shift+>");\r
1662     appendActionShortcut(ui->action_About, "Shift+?");\r
1663     appendActionShortcut(ui->image_ScaleNormal, "Shift+=");\r
1664 \r
1665     // SIGNAL -> SLOT\r
1666     connect(ui->action_About, SIGNAL(triggered()), this, SLOT(onAbout()));\r
1667     connect(ui->action_AddBookmark, SIGNAL(triggered()), this, SLOT(onAddBookmark()));\r
1668     connect(ui->action_Cd, SIGNAL(triggered()), this, SLOT(onChooseFolder()));\r
1669     connect(ui->action_CheckUpdate, SIGNAL(triggered()), this, SLOT(onCheckUpdate()));\r
1670     connect(ui->action_Copy, SIGNAL(triggered()), this, SLOT(onCopy()));\r
1671     connect(ui->action_CopyFileName, SIGNAL(triggered()), this, SLOT(onCopyFileName()));\r
1672     connect(ui->action_CopyFilePath, SIGNAL(triggered()), this, SLOT(onCopyFilePath()));\r
1673     connect(ui->action_CreateFile, SIGNAL(triggered()), this, SLOT(onCreateFile()));\r
1674     connect(ui->action_CreateFolder, SIGNAL(triggered()), this, SLOT(onCreateFolder()));\r
1675     connect(ui->action_Delete, SIGNAL(triggered()), this, SLOT(onDelete()));\r
1676     connect(ui->action_EditBookmark, SIGNAL(triggered()), this, SLOT(onEditBookmark()));\r
1677     connect(ui->action_ExpandLeft, SIGNAL(triggered()), this, SLOT(onExpandLeft()));\r
1678     connect(ui->action_ExpandRight, SIGNAL(triggered()), this, SLOT(onExpandRight()));\r
1679     connect(ui->action_Filter, SIGNAL(triggered()), this, SLOT(showFilterDialog()));\r
1680     connect(ui->action_History, SIGNAL(triggered()), this, SLOT(showHistoryDialog()));\r
1681     connect(ui->action_KeyDown, SIGNAL(triggered()), this, SLOT(onKeyDown()));\r
1682     connect(ui->action_KeyDownOther, SIGNAL(triggered()), this, SLOT(onKeyDownOther()));\r
1683     connect(ui->action_KeyEnd, SIGNAL(triggered()), this, SLOT(onKeyEnd()));\r
1684     connect(ui->action_KeyEndOther, SIGNAL(triggered()), this, SLOT(onKeyEndOther()));\r
1685     connect(ui->action_KeyHome, SIGNAL(triggered()), this, SLOT(onKeyHome()));\r
1686     connect(ui->action_KeyHomeOther, SIGNAL(triggered()), this, SLOT(onKeyHomeOther()));\r
1687     connect(ui->action_KeyLeft, SIGNAL(triggered()), this, SLOT(onKeyLeft()));\r
1688     connect(ui->action_KeyUp, SIGNAL(triggered()), this, SLOT(onKeyUp()));\r
1689     connect(ui->action_KeyUpOther, SIGNAL(triggered()), this, SLOT(onKeyUpOther()));\r
1690     connect(ui->action_Move, SIGNAL(triggered()), this, SLOT(onMove()));\r
1691     connect(ui->action_Open, SIGNAL(triggered()), this, SLOT(onOpen()));\r
1692     connect(ui->action_OpenArchiver, SIGNAL(triggered()), this, SLOT(onOpenArchiver()));\r
1693     connect(ui->action_OpenEditor, SIGNAL(triggered()), this, SLOT(onOpenEditor()));\r
1694     connect(ui->action_OpenTerminal, SIGNAL(triggered()), this, SLOT(onOpenTerminal()));\r
1695     connect(ui->action_OpenWith, SIGNAL(triggered()), this, SLOT(onOpenWith()));\r
1696     connect(ui->action_Quit, SIGNAL(triggered()), this, SLOT(close()));\r
1697     connect(ui->action_Rename, SIGNAL(triggered()), this, SLOT(onRename()));\r
1698     connect(ui->action_KeyRight, SIGNAL(triggered()), this, SLOT(onKeyRight()));\r
1699     connect(ui->action_RunCommand, SIGNAL(triggered()), this, SLOT(onRunCommand()));\r
1700     connect(ui->action_SearchNext, SIGNAL(triggered()), this, SLOT(onSearchNext()));\r
1701     connect(ui->action_SearchPrev, SIGNAL(triggered()), this, SLOT(onSearchPrev()));\r
1702     connect(ui->action_Setting, SIGNAL(triggered()), this, SLOT(showPreferenceDialog()));\r
1703     connect(ui->action_ShowBookmark, SIGNAL(triggered()), this, SLOT(showBookmarkDialog()));\r
1704     connect(ui->action_Sort, SIGNAL(triggered()), this, SLOT(showSortDialog()));\r
1705     connect(ui->action_SplitCenter, SIGNAL(triggered()), this, SLOT(onSplitCenter()));\r
1706     connect(ui->action_Swap, SIGNAL(triggered()), this, SLOT(onSwap()));\r
1707     connect(ui->action_SyncPanel, SIGNAL(triggered()), this, SLOT(onSyncPanel()));\r
1708     connect(ui->action_SyncPanelTo, SIGNAL(triggered()), this, SLOT(onSyncPanelTo()));\r
1709 \r
1710     connect(ui->toggle_FullMode, SIGNAL(toggled(bool)), this, SLOT(onToggleFullMode(bool)));\r
1711     connect(ui->toggle_Hidden, SIGNAL(toggled(bool)), this, SLOT(onToggleHidden(bool)));\r
1712     connect(ui->toggle_Mark, SIGNAL(triggered()), this, SLOT(onToggleMark()));\r
1713     connect(ui->toggle_PreviewMode, SIGNAL(toggled(bool)), this, SLOT(onTogglePreviewMode(bool)));\r
1714     connect(ui->toggle_Search, SIGNAL(toggled(bool)), this, SLOT(onToggleSearch(bool)));\r
1715     connect(ui->toggle_System, SIGNAL(toggled(bool)), this, SLOT(onToggleSystem(bool)));\r
1716     connect(ui->toggle_ThumbnailMode, SIGNAL(toggled(bool)), this, SLOT(onToggleThumbnailMode(bool)));\r
1717     connect(ui->toggle_Toolbar, SIGNAL(toggled(bool)), this, SLOT(onToggleToolbar(bool)));\r
1718 \r
1719     connect(ui->view_Back, SIGNAL(triggered()), this, SLOT(view_finished()));\r
1720 }\r
1721 \r
1722 ///////////////////////////////////////////////////////////////////////////////\r
1723 /// \brief MainWindow::setActiveModel\r
1724 /// \param m    新しいアクティブモデル\r
1725 ///\r
1726 /// アクティブモデルを変更します。\r
1727 ///\r
1728 void MainWindow::setActiveModel(FolderModel *m)\r
1729 {\r
1730     qDebug() << "MainWindow::setActiveModel()" << m;\r
1731 \r
1732     if (activeModel()) {\r
1733         activeModel()->disconnect(this);\r
1734         ui->action_CdHome->disconnect();\r
1735         ui->action_CdRoot->disconnect();\r
1736         ui->action_CdUp->disconnect();\r
1737         ui->action_historyBack->disconnect();\r
1738         ui->action_HistoryForward->disconnect();\r
1739         ui->action_MarkAll->disconnect();\r
1740         ui->action_MarkAllFiles->disconnect();\r
1741         ui->action_MarkAllOff->disconnect();\r
1742         ui->action_MarkInvert->disconnect();\r
1743         ui->action_Refresh->disconnect();\r
1744     }\r
1745 \r
1746     m->setActive();\r
1747 \r
1748     connect(activeModel(), SIGNAL(modelAboutToBeReset()), this, SLOT(model_PreReset()));\r
1749     connect(activeModel(), SIGNAL(modelReset()), this, SLOT(model_PostReset()));\r
1750     connect(ui->action_CdHome, SIGNAL(triggered()), activeModel(), SLOT(onCdHome()));\r
1751     connect(ui->action_CdRoot, SIGNAL(triggered()), activeModel(), SLOT(onCdRoot()));\r
1752     connect(ui->action_CdUp, SIGNAL(triggered()), activeModel(), SLOT(onCdUp()));\r
1753     connect(ui->action_historyBack, SIGNAL(triggered()), activeModel(), SLOT(onHistoryBack()));\r
1754     connect(ui->action_HistoryForward, SIGNAL(triggered()), activeModel(), SLOT(onHistoryForward()));\r
1755     connect(ui->action_MarkAll, SIGNAL(triggered()), activeModel(), SLOT(onMarkAll()));\r
1756     connect(ui->action_MarkAllFiles, SIGNAL(triggered()), activeModel(), SLOT(onMarkAllFiles()));\r
1757     connect(ui->action_MarkAllOff, SIGNAL(triggered()), activeModel(), SLOT(onMarkAllOff()));\r
1758     connect(ui->action_MarkInvert, SIGNAL(triggered()), activeModel(), SLOT(onMarkInvert()));\r
1759     connect(ui->action_Refresh, SIGNAL(triggered()), activeModel(), SLOT(refresh()));\r
1760 \r
1761     prefs_updated();\r
1762 }\r
1763 \r
1764 ///////////////////////////////////////////////////////////////////////////////\r
1765 /// \brief MainWindow::activeModel\r
1766 /// \return アクティブなフォルダモデルを返します。\r
1767 ///\r
1768 FolderModel *MainWindow::activeModel() const\r
1769 {\r
1770     return FolderModel::activeModel();\r
1771 }\r
1772 \r
1773 ///////////////////////////////////////////////////////////////////////////////\r
1774 /// \brief MainWindow::activePanel\r
1775 /// \return アクティブモデルを所有している可視状態のパネルを返します。\r
1776 ///\r
1777 Panel *MainWindow::activePanel() const\r
1778 {\r
1779     if (ui->FPanel->model()->isActive() && ui->FPanel->isVisible()) {\r
1780         return ui->FPanel;\r
1781     }\r
1782     if (ui->RPanel->model()->isActive() && ui->RPanel->isVisible()) {\r
1783         return ui->RPanel;\r
1784     }\r
1785     if (ui->LPanel->model()->isActive() && ui->LPanel->isVisible()) {\r
1786         return ui->LPanel;\r
1787     }\r
1788 \r
1789     qDebug() << ">>>>>>>>>> activePanel() Logic error <<<<<<<<<<";\r
1790     return NULL;\r
1791 }\r
1792 \r
1793 ///////////////////////////////////////////////////////////////////////////////\r
1794 /// \brief MainWindow::inactiveModel\r
1795 /// \return 非アクティブなフォルダモデルを返します。\r
1796 ///\r
1797 FolderModel *MainWindow::inactiveModel() const\r
1798 {\r
1799     if (ui->LPanel->model()->isActive()) {\r
1800         return ui->RPanel->model();\r
1801     }\r
1802     Q_ASSERT(ui->RPanel->model()->isActive());\r
1803     return ui->LPanel->model();\r
1804 }\r
1805 \r
1806 ///////////////////////////////////////////////////////////////////////////////\r
1807 /// \brief MainWindow::inactivePanel\r
1808 /// \return 非アクティブモデルを所有している可視状態のパネルを返します。\r
1809 ///\r
1810 Panel *MainWindow::inactivePanel() const\r
1811 {\r
1812     if (ui->LPanel->model() == inactiveModel() && ui->LPanel->isVisible()) {\r
1813         return ui->LPanel;\r
1814     }\r
1815     if (ui->RPanel->model() == inactiveModel() && ui->RPanel->isVisible()) {\r
1816         return ui->RPanel;\r
1817     }\r
1818     if (ui->FPanel->model() == inactiveModel() && ui->FPanel->isVisible()) {\r
1819         return ui->FPanel;\r
1820     }\r
1821 \r
1822     qDebug() << ">>>>>>>>>> inactivePanel() Logic error <<<<<<<<<<";\r
1823     return NULL;\r
1824 }\r
1825 \r
1826 ///////////////////////////////////////////////////////////////////////////////\r
1827 /// \brief MainWindow::selectedItems\r
1828 /// \return マークされているアイテムまたはカレントアイテムのリスト\r
1829 ///\r
1830 QFileInfoList MainWindow::selectedItems() const\r
1831 {\r
1832     QFileInfoList list = activeModel()->markedItems();\r
1833     if (list.isEmpty()) {\r
1834         Q_ASSERT(focusItemView()->currentIndex().isValid());\r
1835         list << activeModel()->fileInfo(focusItemView()->currentIndex());\r
1836     }\r
1837 \r
1838     return list;\r
1839 }\r
1840 \r
1841 ///////////////////////////////////////////////////////////////////////////////\r
1842 /// \brief MainWindow::focusItemView\r
1843 /// \return フォーカスを持つアイテムビュー\r
1844 ///\r
1845 QAbstractItemView *MainWindow::focusItemView() const\r
1846 {\r
1847     return static_cast<QAbstractItemView*>(qApp->focusWidget());\r
1848 }\r
1849 \r
1850 ///////////////////////////////////////////////////////////////////////////////\r
1851 /// \brief MainWindow::setViewMode\r
1852 /// \param mode 新しいビューモード\r
1853 ///\r
1854 /// ビューモードを変更します。\r
1855 ///\r
1856 void MainWindow::setViewMode(Mode mode)\r
1857 {\r
1858     qDebug() << "MainWindow::setViewMode()" << mode;\r
1859 \r
1860     QWidget *newFocusWidget = NULL;\r
1861 \r
1862     m_prevMode = m_viewMode;\r
1863     m_viewMode = mode;\r
1864 \r
1865     switch (mode) {\r
1866     case ModeBasic:\r
1867         ui->FPanel->setVisible(false);\r
1868         ui->splitter->setVisible(true);\r
1869         newFocusWidget = activePanel()->folderPanel()->itemView();\r
1870 \r
1871         ui->LPanel->setViewItem();\r
1872         ui->RPanel->setViewItem();\r
1873         ui->FPanel->setViewItem();\r
1874         if (m_prevMode == ModeFull) {\r
1875             activePanel()->folderPanel()->setItemView(focusItemView()->objectName());\r
1876             activePanel()->folderPanel()->itemView()->setCurrentIndex(\r
1877                         focusItemView()->currentIndex());\r
1878             ui->FPanel->setModel(NULL);\r
1879         }\r
1880         break;\r
1881 \r
1882     case ModeFull:\r
1883         if (m_prevMode == ModeBasic) {\r
1884             ui->FPanel->setModel(activeModel());\r
1885             ui->FPanel->folderPanel()->setItemView(focusItemView()->objectName());\r
1886             ui->FPanel->folderPanel()->itemView()->setCurrentIndex(\r
1887                             focusItemView()->currentIndex());\r
1888         }\r
1889         ui->splitter->setVisible(false);\r
1890         ui->FPanel->setVisible(true);\r
1891         ui->FPanel->setViewItem();\r
1892         newFocusWidget = activePanel()->folderPanel()->itemView();\r
1893         break;\r
1894 \r
1895     case ModeView:\r
1896         ui->FPanel->setViewItem(focusItemView()->currentIndex());\r
1897         ui->splitter->setVisible(false);\r
1898         ui->FPanel->setVisible(true);\r
1899         newFocusWidget = ui->FPanel->visibleView();\r
1900         break;\r
1901 \r
1902     case ModePreview:\r
1903         inactivePanel()->setViewItem(focusItemView()->currentIndex());\r
1904         break;\r
1905     }\r
1906 \r
1907     if (newFocusWidget)\r
1908         newFocusWidget->setFocus();\r
1909     else\r
1910         updateActions();\r
1911 \r
1912     qDebug() << "MainWindow::setViewMode() end";\r
1913 }\r
1914 \r
1915 ///////////////////////////////////////////////////////////////////////////////\r
1916 /// \brief MainWindow::startProcess\r
1917 /// \param cmd      実行するコマンド\r
1918 /// \param errMsg   エラー時の表示メッセージ\r
1919 /// \return true:成功, false:失敗\r
1920 ///\r
1921 bool MainWindow::startProcess(const QString &cmd, const QString &errMsg)\r
1922 {\r
1923     qDebug() << "MainWindow::startProcess" << cmd << errMsg;\r
1924 \r
1925     QProcess process(this);\r
1926     process.setWorkingDirectory(activeModel()->rootPath());\r
1927     if (!process.startDetached(cmd)) {\r
1928         QMessageBox::critical(this, tr("エラー"), errMsg + "<br/>" + cmd);\r
1929         return false;\r
1930     }\r
1931     return true;\r
1932 }\r
1933 \r
1934 ///////////////////////////////////////////////////////////////////////////////\r
1935 /// \brief MainWindow::updateActions\r
1936 ///\r
1937 /// アクションの有効/無効を設定します。\r
1938 ///\r
1939 void MainWindow::updateActions()\r
1940 {\r
1941     qDebug() << "MainWindow::updateActions";\r
1942 \r
1943     bool isView = true;\r
1944     bool isSearch = false;\r
1945     bool isImageView = false;\r
1946     bool toggleSearch = true;\r
1947 \r
1948     QWidget *w = qApp->focusWidget();\r
1949     if (w->objectName() == "scrollArea") {\r
1950         w = static_cast<QScrollArea*>(w)->widget();\r
1951     }\r
1952 \r
1953     if (w->objectName() == "folderView" || w->objectName() == "thumbnailView") {\r
1954         setEnabledAllActions(true);\r
1955         // 履歴\r
1956         ui->action_historyBack->setEnabled(!activeModel()->isHistoryBegin());\r
1957         ui->action_HistoryForward->setEnabled(!activeModel()->isHistoryEnd());\r
1958         // チェック状態\r
1959         ui->toggle_Hidden->blockSignals(true);\r
1960         ui->toggle_Hidden->setChecked(activeModel()->filter() & QDir::Hidden);\r
1961         ui->toggle_Hidden->blockSignals(false);\r
1962 \r
1963         ui->toggle_System->blockSignals(true);\r
1964         ui->toggle_System->setChecked(activeModel()->filter() & QDir::System);\r
1965         ui->toggle_System->blockSignals(false);\r
1966 \r
1967         ui->toggle_ThumbnailMode->blockSignals(true);\r
1968         ui->toggle_ThumbnailMode->setChecked(w->objectName() == "thumbnailView");\r
1969         ui->toggle_ThumbnailMode->blockSignals(false);\r
1970 \r
1971         // 現在の選択アイテムが".."の場合、ファイル操作系アクションは無効にする\r
1972         QFileInfoList list = selectedItems();\r
1973         if (list.size() == 1 && list[0].fileName() == "..") {\r
1974             ui->action_Copy->setEnabled(false);\r
1975             ui->action_Delete->setEnabled(false);\r
1976             ui->action_Move->setEnabled(false);\r
1977             ui->action_Rename->setEnabled(false);\r
1978         }\r
1979 \r
1980         // 単画面またはプレビューモードの場合\r
1981         if (!ui->LPanel->folderPanel()->isVisible() ||\r
1982             !ui->RPanel->folderPanel()->isVisible())\r
1983         {\r
1984             ui->action_Copy->setEnabled(false);\r
1985             ui->action_Move->setEnabled(false);\r
1986             ui->action_Swap->setEnabled(false);\r
1987             ui->action_SyncPanel->setEnabled(false);\r
1988             ui->action_SyncPanelTo->setEnabled(false);\r
1989         }\r
1990 \r
1991         // 単画面の場合\r
1992         if (m_viewMode == ModeFull) {\r
1993             ui->toggle_PreviewMode->setEnabled(false);\r
1994             ui->action_SplitCenter->setEnabled(false);\r
1995             ui->action_ExpandLeft->setEnabled(false);\r
1996             ui->action_ExpandRight->setEnabled(false);\r
1997             ui->action_KeyDownOther->setEnabled(false);\r
1998             ui->action_KeyEndOther->setEnabled(false);\r
1999             ui->action_KeyHomeOther->setEnabled(false);\r
2000             ui->action_KeyUpOther->setEnabled(false);\r
2001         }\r
2002 \r
2003         if (w->objectName() == "thumbnailView") {\r
2004             isImageView = true;\r
2005         }\r
2006     }\r
2007     else if (w->objectName() == "searchBox"){\r
2008         setEnabledAllActions(false);\r
2009         isView = false;\r
2010         isSearch = true;\r
2011     }\r
2012     else if (w->objectName() == "locationBox") {\r
2013         setEnabledAllActions(false);\r
2014         isView = false;\r
2015     }\r
2016     else if (w->objectName() == "textView") {\r
2017         setEnabledAllActions(false);\r
2018         toggleSearch = false;\r
2019 \r
2020         reconnectAction(ui->text_ConvertFromEUC, SIGNAL(triggered()), w, SLOT(onConvertFromEUC()));\r
2021         reconnectAction(ui->text_ConvertFromJIS, SIGNAL(triggered()), w, SLOT(onConvertFromJIS()));\r
2022         reconnectAction(ui->text_ConvertFromSJIS, SIGNAL(triggered()), w, SLOT(onConvertFromSJIS()));\r
2023         reconnectAction(ui->text_ConvertFromUTF8, SIGNAL(triggered()), w, SLOT(onConvertFromUTF8()));\r
2024         reconnectAction(ui->text_ConvertFromUTF16, SIGNAL(triggered()), w, SLOT(onConvertFromUTF16()));\r
2025         reconnectAction(ui->text_ConvertFromUTF16BE, SIGNAL(triggered()), w, SLOT(onConvertFromUTF16BE()));\r
2026         reconnectAction(ui->text_ConvertFromUTF16LE, SIGNAL(triggered()), w, SLOT(onConvertFromUTF16LE()));\r
2027         reconnectAction(ui->view_SelectAll, SIGNAL(triggered()), w, SLOT(onSelectAll()));\r
2028         reconnectAction(ui->text_Copy, SIGNAL(triggered()), w, SLOT(onCopy()));\r
2029     }\r
2030     else if (w->objectName() == "imageView") {\r
2031         setEnabledAllActions(false);\r
2032         toggleSearch = false;\r
2033         isImageView = true;\r
2034 \r
2035         reconnectAction(ui->image_FitToWindow, SIGNAL(triggered()), w, SLOT(onFitToWindow()));\r
2036         reconnectAction(ui->image_ScaleNormal, SIGNAL(triggered()), w, SLOT(onScaleNormal()));\r
2037         reconnectAction(ui->image_Rotate90, SIGNAL(triggered()), w, SLOT(onRotate90()));\r
2038         reconnectAction(ui->image_Rotate180, SIGNAL(triggered()), w, SLOT(onRotate180()));\r
2039     }\r
2040     else if (w->objectName() == "hexView") {\r
2041         setEnabledAllActions(false);\r
2042         toggleSearch = false;\r
2043 \r
2044         reconnectAction(ui->view_SelectAll, SIGNAL(triggered()), w, SLOT(onSelectAll()));\r
2045         reconnectAction(ui->text_Copy, SIGNAL(triggered()), w, SLOT(onCopy()));\r
2046     }\r
2047     else if (w->objectName() == "progressBar") {\r
2048         setEnabledAllActions(false);\r
2049         toggleSearch = false;\r
2050         isView = false;\r
2051     }\r
2052     else {\r
2053         toggleSearch = false;\r
2054         isView = false;\r
2055     }\r
2056 \r
2057     ui->toggle_Toolbar->blockSignals(true);\r
2058     ui->toggle_Toolbar->setChecked(ui->mainToolBar->isVisible());\r
2059     ui->toggle_Toolbar->blockSignals(false);\r
2060 \r
2061     ui->action_About->setEnabled(true);\r
2062     ui->action_CheckUpdate->setEnabled(true);\r
2063     ui->action_KeyDown->setEnabled(isView);\r
2064     ui->action_KeyEnd->setEnabled(isView);\r
2065     ui->action_KeyHome->setEnabled(isView);\r
2066     ui->action_KeyUp->setEnabled(isView);\r
2067     ui->action_Quit->setEnabled(true);\r
2068     ui->action_SearchNext->setEnabled(isSearch);\r
2069     ui->action_SearchPrev->setEnabled(isSearch);\r
2070     ui->action_Setting->setEnabled(true);\r
2071     ui->toggle_Search->setEnabled(toggleSearch);\r
2072     ui->view_Back->setEnabled(m_viewMode == ModeView);\r
2073 \r
2074     if (isImageView) {\r
2075         ui->action_ScaleDown->setText(tr("縮小"));\r
2076         ui->action_ScaleUp->setText(tr("拡大"));\r
2077         ui->action_KeyLeft->setEnabled(false);\r
2078         ui->action_KeyRight->setEnabled(false);\r
2079     }\r
2080     else {\r
2081         ui->action_ScaleDown->setText(tr("文字を小さく"));\r
2082         ui->action_ScaleUp->setText(tr("文字を大きく"));\r
2083         ui->action_KeyLeft->setEnabled(isView);\r
2084         ui->action_KeyRight->setEnabled(isView);\r
2085     }\r
2086     if (isView) {\r
2087         reconnectAction(ui->action_ScaleDown, SIGNAL(triggered()), w, SLOT(onScaleDown()));\r
2088         reconnectAction(ui->action_ScaleUp, SIGNAL(triggered()), w, SLOT(onScaleUp()));\r
2089     }\r
2090     else {\r
2091         ui->action_ScaleDown->setEnabled(false);\r
2092         ui->action_ScaleUp->setEnabled(false);\r
2093     }\r
2094 \r
2095     ui->toggle_FullMode->setEnabled(m_viewMode == ModeBasic || m_viewMode == ModeFull);\r
2096 }\r
2097 \r
2098 ///////////////////////////////////////////////////////////////////////////////\r
2099 /// \brief MainWindow::setEnabledAllActions\r
2100 /// \param enable   有効にする場合はtrue\r
2101 ///\r
2102 /// 全てのアクションを有効または無効にします。\r
2103 ///\r
2104 void MainWindow::setEnabledAllActions(bool enable)\r
2105 {\r
2106     qDebug() << "MainWindow::setEnabledAllActions()" << enable;\r
2107     foreach (QAction *action, m_actions) {\r
2108         action->setEnabled(enable);\r
2109     }\r
2110 }\r
2111 \r
2112 ///////////////////////////////////////////////////////////////////////////////\r
2113 /// \brief MainWindow::onAbout\r
2114 ///\r
2115 /// Aboutダイアログを表示します。\r
2116 ///\r
2117 void MainWindow::onAbout()\r
2118 {\r
2119     QMessageBox::about(\r
2120                 this,\r
2121                 tr("げふぅ について"),\r
2122                 windowTitle() +\r
2123                 tr("<center>Gefu is an Experimental File Utility.<br/>"\r
2124                    "<small>(げふぅは実験的なファイルユーティリティです)</small></center>"\r
2125                    "<p>最新版の情報は<a href='http://gefu.sourceforge.jp/'>公式サイト</a>で公開しています。</p>"\r
2126                    "<p><small>Copyright 2014 @miyabi_satoh All rights reserved.</small></p>"));\r
2127 }\r
2128 \r
2129 ///////////////////////////////////////////////////////////////////////////////\r
2130 /// \brief MainWindow::closeEvent\r
2131 /// \param event    クローズイベント\r
2132 ///\r
2133 /// 終了処理を行います。\r
2134 ///\r
2135 void MainWindow::closeEvent(QCloseEvent *event)\r
2136 {\r
2137     qDebug() << "MainWindow::closeEvent()";\r
2138     Preferences prefs(this);\r
2139 \r
2140     if (prefs.isConfirmQuit()) {\r
2141         QMessageBox msgBox;\r
2142         QCheckBox *checkBox = new QCheckBox();\r
2143         checkBox->setText(tr("次回以降は確認しない"));\r
2144         msgBox.setCheckBox(checkBox);\r
2145         msgBox.setText(tr("終了しますか?"));\r
2146         msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);\r
2147         msgBox.setIcon(QMessageBox::Question);\r
2148 \r
2149         if (msgBox.exec() == QMessageBox::No) {\r
2150             qDebug() << ">>>>> ユーザによりキャンセルされました <<<<<";\r
2151             event->ignore();\r
2152             return;\r
2153         }\r
2154         prefs.setConfirmQuit(!checkBox->isChecked());\r
2155     }\r
2156 \r
2157     prefs.saveModel("Left", ui->LPanel->model());\r
2158     prefs.saveModel("Right", ui->RPanel->model());\r
2159     prefs.saveWindow(this);\r
2160     QMainWindow::closeEvent(event);\r
2161 }\r
2162 \r
2163 ///////////////////////////////////////////////////////////////////////////////\r
2164 /// \brief MainWindow::eventFilter\r
2165 /// \param watched  イベントの発生元オブジェクト\r
2166 /// \param e        発生したイベント\r
2167 /// \return イベントを処理した場合はtrueを返します。\r
2168 ///\r
2169 bool MainWindow::eventFilter(QObject *watched, QEvent *e)\r
2170 {\r
2171     switch (e->type()) {\r
2172     case QEvent::KeyPress:\r
2173         // キーイベントの処理\r
2174         return onKeyPressEvent(watched, static_cast<QKeyEvent*>(e));\r
2175 \r
2176     case QEvent::ContextMenu:\r
2177         // コンテキストメニューイベントの処理\r
2178         return onContextMenuEvent(watched, static_cast<QContextMenuEvent*>(e));\r
2179 \r
2180     default:\r
2181         break;\r
2182     }\r
2183 \r
2184     return false;\r
2185 }\r