OSDN Git Service

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