OSDN Git Service

3e9c359c41e5b14fc2cb10ea7409139ed62c2551
[gefu/Gefu.git] / mainwindow.cpp
1 #include "common.h"\r
2 #include "mainwindow.h"\r
3 #include "preferencedialog.h"\r
4 #include "folderview.h"\r
5 #include "searchbox.h"\r
6 #include "locationbox.h"\r
7 #include "ui_mainwindow.h"\r
8 #include "copymoveworker.h"\r
9 #include "operationdialog.h"\r
10 #include "overwritedialog.h"\r
11 #include "deleteworker.h"\r
12 #include "renameworker.h"\r
13 #include "renamesingledialog.h"\r
14 #include "renamemultidialog.h"\r
15 #include "historydialog.h"\r
16 #include "sortdialog.h"\r
17 \r
18 #include <QCheckBox>\r
19 #include <QCloseEvent>\r
20 #include <QDebug>\r
21 #include <QDesktopWidget>\r
22 #include <QMessageBox>\r
23 #include <QSettings>\r
24 #include <QNetworkAccessManager>\r
25 #include <QNetworkReply>\r
26 #include <QInputDialog>\r
27 #include <QProcess>\r
28 #include <QDesktopServices>\r
29 #include <QClipboard>\r
30 #include <QFileDialog>\r
31 \r
32 MainWindow* getMainWnd()\r
33 {\r
34     foreach (QWidget *w, qApp->topLevelWidgets()) {\r
35         if (w->objectName() == "MainWindow") {\r
36             return static_cast<MainWindow*>(w);\r
37         }\r
38     }\r
39     qDebug() << "MainWindow not found !?";\r
40     return NULL;\r
41 }\r
42 \r
43 MainWindow::MainWindow(QWidget *parent) :\r
44     QMainWindow(parent),\r
45     ui(new Ui::MainWindow),\r
46     m_focusedView(NULL),\r
47     m_overwriteDialog(NULL)\r
48 {\r
49     ui->setupUi(this);\r
50 \r
51     m_overwriteDialog = new OverWriteDialog(this);\r
52 \r
53     initActionConnections();\r
54     connect(qApp, SIGNAL(focusChanged(QWidget*,QWidget*)), this, SLOT(focusChange(QWidget*,QWidget*)));\r
55     connect(ui->textView, SIGNAL(viewFinished(QWidget*)), this, SLOT(viewFinish(QWidget*)));\r
56 \r
57     // テキストビューアは初期状態で非表示\r
58     ui->textView->setVisible(false);\r
59 \r
60     for (int i = 1; i <= 2; i++) {\r
61         LocationBox *locationBox = findChild<LocationBox*>(QString("locationBox%1").arg(i));\r
62         Q_CHECK_PTR(locationBox);\r
63 \r
64         FolderView *folderView = findChild<FolderView*>(QString("folderView%1").arg(i));\r
65         Q_CHECK_PTR(folderView);\r
66 \r
67         SearchBox *searchBox = findChild<SearchBox*>(QString("searchBox%1").arg(i));\r
68         Q_CHECK_PTR(searchBox);\r
69 \r
70         // シグナル&スロット\r
71         connect(folderView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(open(QModelIndex)));\r
72         connect(folderView, SIGNAL(itemFound(FolderView*)), this, SLOT(itemFound(FolderView*)));\r
73         connect(folderView, SIGNAL(itemNotFound(FolderView*)), this, SLOT(itemNotFound(FolderView*)));\r
74         connect(folderView, SIGNAL(keyPressed(FolderView*,QKeyEvent*)), this, SLOT(keyPress(FolderView*,QKeyEvent*)));\r
75         connect(folderView, SIGNAL(retrieveFinished()), this, SLOT(retrieveFinish()));\r
76         connect(folderView, SIGNAL(retrieveStarted(QString)), this, SLOT(retrieveStart(QString)));\r
77         connect(searchBox, SIGNAL(textEdited(QString)), this, SLOT(searchItem(QString)));\r
78         connect(searchBox, SIGNAL(returnPressed()), this, SLOT(returnPressInSearchBox()));\r
79 \r
80         // 検索ボックスは初期状態で非表示\r
81         searchBox->setVisible(false);\r
82 \r
83         // ロケーションボックスを初期化する\r
84         locationBox->initialize();\r
85 \r
86         // フィルタを初期化する\r
87         setNameFilters(folderView);\r
88 \r
89         // ソートを初期化する\r
90         setSorting(folderView);\r
91 \r
92         // フォルダビューを初期化する\r
93         folderView->initialize();\r
94     }\r
95 \r
96     QSettings settings;\r
97     // メニュー項目の状態を初期化する\r
98     ui->view_Hidden->setChecked(settings.value(IniKey_ShowHidden).toBool());\r
99     ui->view_System->setChecked(settings.value(IniKey_ShowSystem).toBool());\r
100     ui->action_OpenEditor->setEnabled(!settings.value(IniKey_EditorPath).toString().isEmpty());\r
101     ui->action_OpenTerminal->setEnabled(!settings.value(IniKey_TerminalPath).toString().isEmpty());\r
102 \r
103     // 追加のショートカットキーを設定する\r
104     QList<QKeySequence> shortcuts;\r
105     shortcuts = ui->action_Open->shortcuts();\r
106     shortcuts.append(QKeySequence("M"));\r
107     ui->action_Open->setShortcuts(shortcuts);\r
108 \r
109     shortcuts = ui->action_Exec->shortcuts();\r
110     shortcuts.append(QKeySequence("Shift+M"));\r
111     ui->action_Exec->setShortcuts(shortcuts);\r
112 \r
113     // MacだとShift+の形で認識されてしまうもの\r
114     shortcuts = ui->view_Filter->shortcuts();\r
115     shortcuts.append(QKeySequence("Shift+*"));  // マヂで!?\r
116     ui->view_Filter->setShortcuts(shortcuts);\r
117 \r
118     shortcuts = ui->action_OpenTerminal->shortcuts();\r
119     shortcuts.append(QKeySequence("Shift+>"));  // マヂで!?\r
120     ui->action_OpenTerminal->setShortcuts(shortcuts);\r
121 \r
122     shortcuts = ui->help_About->shortcuts();\r
123     shortcuts.append(QKeySequence("Shift+?"));  // マヂで!?\r
124     ui->help_About->setShortcuts(shortcuts);\r
125 \r
126     // ウィンドウタイトルを設定する\r
127     setWindowTitle(tr("げふぅ v%1").arg(VERSION_VALUE));\r
128 \r
129     // ウィンドウアイコンを設定する\r
130 #if defined(Q_OS_MAC)\r
131     setWindowIcon(QIcon(":/images/Gefu.icns"));\r
132 #else\r
133     setWindowIcon(QIcon(":/images/Gefu.png"));\r
134 #endif\r
135 \r
136     //>>>>> ウィンドウサイズと位置を設定する\r
137     QString strValue;\r
138     QPoint point = this->geometry().topLeft();\r
139     QSize size = this->geometry().size();\r
140     //>>>> 前回の位置・サイズ・状態を復元する\r
141     if (!settings.value(IniKey_WindowGeometry, "").toString().isEmpty()) {\r
142         restoreGeometry(settings.value(IniKey_WindowGeometry).toByteArray());\r
143         restoreState(settings.value(iniKey_WindowState).toByteArray());\r
144     }\r
145     //>>>> INIファイルの設定から復元する\r
146     //>>> サイズ\r
147     strValue = settings.value(IniKey_BootSizeSpec).toString();\r
148     if (strValue == "sizeAbsolute") {\r
149         size = settings.value(IniKey_BootSizeAbs).toSize();\r
150     }\r
151     else if (strValue == "sizeRelative") {\r
152         size = settings.value(IniKey_BootSizeRel).toSize();\r
153         size.setWidth(size.width() * QApplication::desktop()->width() / 100.0);\r
154         size.setHeight(size.height() * QApplication::desktop()->height() / 100.0);\r
155     }\r
156     else if (strValue == "sizeLast") {\r
157         size = this->geometry().size();\r
158     }\r
159     //>>> 位置\r
160     strValue = settings.value(IniKey_BootPosSpec).toString();\r
161     if (strValue == "posAbsolute") {\r
162         point = settings.value(IniKey_BootPosAbs).toPoint();\r
163     }\r
164     else if (strValue == "posRelative") {\r
165         point = settings.value(IniKey_BootPosRel).toPoint();\r
166         point.setX(point.x() * QApplication::desktop()->width() / 100.0);\r
167         point.setY(point.y() * QApplication::desktop()->height() / 100.0);\r
168     }\r
169     else if (strValue == "posLast") {\r
170         point = this->geometry().topLeft();\r
171     }\r
172     else {\r
173         point.setX((QApplication::desktop()->width() - size.width()) / 2);\r
174         point.setY((QApplication::desktop()->height() - size.height()) / 2);\r
175     }\r
176     this->setGeometry(QRect(point, size));\r
177 \r
178     // 最新バージョンをチェックする\r
179     if (settings.value(IniKey_CheckUpdates).toBool()) {\r
180         checkUpdate(true);\r
181     }\r
182 \r
183     ui->folderView1->repaint();\r
184     ui->folderView2->repaint();\r
185 }\r
186 \r
187 MainWindow::~MainWindow()\r
188 {\r
189     delete ui;\r
190 }\r
191 \r
192 FolderView* MainWindow::otherSideView(const FolderView *view) const\r
193 {\r
194     qDebug() << "MainWindow::otherSideView()" << view->objectName();\r
195 \r
196     if (view == ui->folderView1) {\r
197         return ui->folderView2;\r
198     }\r
199 \r
200     Q_ASSERT(view == ui->folderView2);\r
201     return ui->folderView1;\r
202 }\r
203 \r
204 void MainWindow::focusChange(QWidget *old, QWidget *now)\r
205 {\r
206     Q_UNUSED(old);\r
207     Q_UNUSED(now);\r
208     qDebug() << "MainWindow::focusChange";\r
209 \r
210     updateActions();\r
211 }\r
212 \r
213 void MainWindow::executeCommand()\r
214 {\r
215     qDebug() << "MainWindow::executeCommand";\r
216 \r
217     FolderView *v = folderView();\r
218     Q_ASSERT(v);\r
219 \r
220     QFileInfoList list = v->selectedItems();\r
221     QString command = QString::null;\r
222     foreach (const QFileInfo &info, list) {\r
223 #ifdef Q_OS_MAC\r
224         QString path = info.absoluteFilePath();\r
225 #else\r
226         QString path = info.fileName();\r
227 #endif\r
228         if (info.isExecutable()) {\r
229             command = QQ(path) + " " + command;\r
230         }\r
231         else {\r
232             command += " " + QQ(path);\r
233         }\r
234     }\r
235 \r
236     QInputDialog dlg(this);\r
237     dlg.setInputMode(QInputDialog::TextInput);\r
238     dlg.setWindowTitle(tr("コマンドを実行"));\r
239     dlg.setLabelText(tr("コマンド:"));\r
240     dlg.setTextValue(command);\r
241     dlg.resize(width() * 0.8, dlg.height());\r
242 \r
243     int ret = dlg.exec();\r
244     command = dlg.textValue();\r
245     if (ret == QDialog::Accepted && !command.isEmpty()) {\r
246         startProcess(command, v->dir(), tr("コマンドの実行に失敗しました。"));\r
247     }\r
248 }\r
249 \r
250 void MainWindow::historyBack()\r
251 {\r
252     qDebug() << "MainWindow::historyBack();";\r
253 \r
254     if (folderView()->historyBack()) {\r
255         updateActions();\r
256     }\r
257 }\r
258 \r
259 void MainWindow::historyForward()\r
260 {\r
261     qDebug() << "MainWindow::historyForward();";\r
262 \r
263     if (folderView()->historyForward()) {\r
264         updateActions();\r
265     }\r
266 }\r
267 \r
268 void MainWindow::itemFound(FolderView *view)\r
269 {\r
270     qDebug() << "MainWindow::itemFound";\r
271 \r
272     SearchBox *box = searchBox(view);\r
273     QPalette pal = box->palette();\r
274     pal.setColor(QPalette::Text, QPalette().text().color());\r
275     box->setPalette(pal);\r
276 }\r
277 \r
278 void MainWindow::itemNotFound(FolderView *view)\r
279 {\r
280     qDebug() << "MainWindow::itemNotFound";\r
281 \r
282     SearchBox *box = searchBox(view);\r
283     QPalette pal = box->palette();\r
284     pal.setColor(QPalette::Text, Qt::red);\r
285     box->setPalette(pal);\r
286 }\r
287 \r
288 void MainWindow::markAll()\r
289 {\r
290     qDebug() << "MainWindow::markAll();";\r
291 \r
292     folderView()->setCheckStateAll(true);\r
293 }\r
294 \r
295 void MainWindow::markAllFiles()\r
296 {\r
297     qDebug() << "MainWindow::markAllFiles();";\r
298 \r
299     folderView()->setCheckStateAllFiles();\r
300 }\r
301 \r
302 void MainWindow::markAllOff()\r
303 {\r
304     qDebug() << "MainWindow::markAllOff();";\r
305 \r
306     folderView()->setCheckStateAll(false);\r
307 }\r
308 \r
309 void MainWindow::markInvert()\r
310 {\r
311     qDebug() << "MainWindow::markInvert();";\r
312 \r
313     folderView()->invertCheckState();\r
314 }\r
315 \r
316 void MainWindow::markToggle()\r
317 {\r
318     qDebug() << "MainWindow::markToggle();";\r
319 \r
320     folderView()->toggleCheckState(folderView()->currentIndex());\r
321 }\r
322 \r
323 void MainWindow::moveItems()\r
324 {\r
325     qDebug() << "MainWindow::moveItems";\r
326 \r
327     FolderView *v = folderView();\r
328     QFileInfoList list = v->selectedItems();\r
329     if (list.isEmpty()) {\r
330         return;\r
331     }\r
332 \r
333     QSettings settings;\r
334     if (settings.value(IniKey_ConfirmCopy).toBool()) {\r
335         if (QMessageBox::question(this, tr("確認"), tr("移動を実行しますか?"))\r
336             != QMessageBox::Yes)\r
337         {\r
338             return;\r
339         }\r
340     }\r
341 \r
342     // 上書き確認ダイアログを初期化する\r
343     m_overwriteDialog->reset();\r
344 \r
345     // ワーカースレッドを作成する\r
346     FolderView *other = otherSideView(v);\r
347     CopyMoveWorker *worker = new CopyMoveWorker();\r
348     connect(worker, SIGNAL(askOverWrite(QString*,QString*,QString,QString)),\r
349             this, SLOT(askOverWrite(QString*,QString*,QString,QString)));\r
350     worker->setCopyList(&list);\r
351     worker->setTargetDir(other->dir());\r
352     worker->setMoveMode(true);\r
353 \r
354     // 進捗ダイアログを表示して、処理を開始する\r
355     OperationDialog opDlg(this);\r
356     opDlg.setWindowTitle(tr("移動"));\r
357     opDlg.setWorker(worker);\r
358     opDlg.setAutoClose(settings.value(IniKey_AutoCloseCopy).toBool());\r
359 \r
360     opDlg.exec();\r
361 \r
362     settings.setValue(IniKey_AutoCloseCopy, opDlg.autoClose());\r
363 \r
364     // 念のため、リフレッシュ\r
365     ui->folderView1->refresh();\r
366     ui->folderView2->refresh();\r
367 }\r
368 \r
369 void MainWindow::keyPress(FolderView *view, QKeyEvent *event)\r
370 {\r
371     QString ksq = KeyEventToSequence(event);\r
372     if (ksq == "") {\r
373         event->ignore();\r
374         return;\r
375     }\r
376 \r
377     qDebug() << "MainWindow::keyPress" << ksq;\r
378 \r
379     foreach (QObject *obj, children()) {\r
380         QAction *action = qobject_cast<QAction*>(obj);\r
381         if (!action) {\r
382             continue;\r
383         }\r
384 \r
385         foreach (const QKeySequence &k, action->shortcuts()) {\r
386             if (ksq == k.toString()) {\r
387                 if (action->isEnabled()) {\r
388                     if (action->isCheckable()) {\r
389                         action->setChecked(!action->isChecked());\r
390                     }\r
391                     else {\r
392                         emit action->triggered();\r
393                     }\r
394                     qDebug() << "emit" << action->objectName();\r
395                 }\r
396                 event->accept();\r
397                 return;\r
398             }\r
399         }\r
400     }\r
401 \r
402     if (ksq == "Left" || ksq == "Right") {\r
403         if (view->side() == ksq) {\r
404             setPathToParent();\r
405         }\r
406         else {\r
407             otherSideView(view)->setFocus();\r
408         }\r
409         event->accept();\r
410         return;\r
411     }\r
412 \r
413     event->ignore();\r
414 }\r
415 \r
416 void MainWindow::returnPressInSearchBox()\r
417 {\r
418     qDebug() << "MainWindow::returnPressInSearchBox";\r
419 \r
420     if (QApplication::keyboardModifiers() & Qt::ShiftModifier) {\r
421         emit ui->action_SearchPrev->triggered();\r
422     }\r
423     else {\r
424         emit ui->action_SearchNext->triggered();\r
425     }\r
426 }\r
427 \r
428 void MainWindow::chooseFolder()\r
429 {\r
430     qDebug() << "MainWindow::chooseFolder();";\r
431 \r
432     QString path = QFileDialog::getExistingDirectory(\r
433                 this, tr("フォルダを選択"), folderView()->dir());\r
434     if (!path.isEmpty()) {\r
435         folderView()->setPath(path, true);\r
436         updateActions();\r
437     }\r
438 }\r
439 \r
440 void MainWindow::copyFilenameToClipboard()\r
441 {\r
442     qDebug() << "MainWindow::copyFilenameToClipboard();";\r
443 \r
444     QClipboard *clipboard = QApplication::clipboard();\r
445     clipboard->setText(folderView()->currentItem().fileName());\r
446 }\r
447 \r
448 void MainWindow::copyFullpathTpClipboard()\r
449 {\r
450     qDebug() << "MainWindow::copyFullpathTpClipboard();";\r
451 \r
452     QClipboard *clipboard = QApplication::clipboard();\r
453     clipboard->setText(folderView()->currentItem().absoluteFilePath());\r
454 }\r
455 \r
456 void MainWindow::askOverWrite(QString *copyMethod,\r
457                               QString *alias,\r
458                               const QString &srcPath,\r
459                               const QString &tgtPath)\r
460 {\r
461     qDebug() << "MainWindow::askOverWrite();";\r
462 \r
463     CopyMoveWorker *worker = static_cast<CopyMoveWorker*>(sender());\r
464     if (!m_overwriteDialog->isKeepSetting() ||\r
465         m_overwriteDialog->copyMethod() == "rbRename")\r
466     {\r
467         m_overwriteDialog->setFileInfo(srcPath, tgtPath);\r
468         if (m_overwriteDialog->exec() == QDialog::Rejected) {\r
469             worker->requestStop();\r
470         }\r
471     }\r
472     *copyMethod = m_overwriteDialog->copyMethod();\r
473     *alias = m_overwriteDialog->alias();\r
474 \r
475     worker->endAsking();\r
476 }\r
477 \r
478 void MainWindow::copyItems()\r
479 {\r
480     qDebug() << "MainWindow::copyItems";\r
481 \r
482     FolderView *v = folderView();\r
483     QFileInfoList list = v->selectedItems();\r
484     if (list.isEmpty()) {\r
485         return;\r
486     }\r
487 \r
488     QSettings settings;\r
489     if (settings.value(IniKey_ConfirmCopy).toBool()) {\r
490         if (QMessageBox::question(this, tr("確認"), tr("コピーを実行しますか?"))\r
491             != QMessageBox::Yes)\r
492         {\r
493             return;\r
494         }\r
495     }\r
496 \r
497     // 上書き確認ダイアログを初期化する\r
498     m_overwriteDialog->reset();\r
499 \r
500     // ワーカースレッドを作成する\r
501     FolderView *other = otherSideView(v);\r
502     CopyMoveWorker *worker = new CopyMoveWorker();\r
503     connect(worker, SIGNAL(askOverWrite(QString*,QString*,QString,QString)),\r
504             this, SLOT(askOverWrite(QString*,QString*,QString,QString)));\r
505     worker->setCopyList(&list);\r
506     worker->setTargetDir(other->dir());\r
507     worker->setMoveMode(false);\r
508 \r
509     // 進捗ダイアログを表示して、処理を開始する\r
510     OperationDialog opDlg(this);\r
511     opDlg.setWindowTitle(tr("コピー"));\r
512     opDlg.setWorker(worker);\r
513     opDlg.setAutoClose(settings.value(IniKey_AutoCloseCopy).toBool());\r
514 \r
515     opDlg.exec();\r
516 \r
517     settings.setValue(IniKey_AutoCloseCopy, opDlg.autoClose());\r
518 \r
519     // 念のため、リフレッシュ\r
520     ui->folderView1->refresh();\r
521     ui->folderView2->refresh();\r
522 }\r
523 \r
524 void MainWindow::createFile()\r
525 {\r
526     qDebug() << "MainWindow::createFile";\r
527 \r
528     bool bOk;\r
529     QString name = QInputDialog::getText(\r
530                 this, tr("ファイルを作成"), tr("ファイル名:"),\r
531                 QLineEdit::Normal, "", &bOk);\r
532     if (!bOk || name.isEmpty()) {\r
533         return;\r
534     }\r
535 \r
536     QDir dir(folderView()->dir());\r
537     QFile file(dir.absoluteFilePath(name));\r
538     if (!file.open(QIODevice::WriteOnly)) {\r
539         QMessageBox::critical(\r
540                     this, tr("エラー"),\r
541                     tr("ファイルの作成に失敗しました。"));\r
542     }\r
543     else {\r
544         file.close();\r
545 \r
546         QSettings settings;\r
547         if (settings.value(IniKey_OpenAfterCreateFile).toBool()) {\r
548             openEditor(dir.absoluteFilePath(name));\r
549         }\r
550     }\r
551 }\r
552 \r
553 void MainWindow::createFolder()\r
554 {\r
555     qDebug() << "MainWindow::createFolder";\r
556 \r
557     bool bOk;\r
558     QString name = QInputDialog::getText(\r
559                 this, tr("フォルダを作成"), tr("フォルダ名:"),\r
560                 QLineEdit::Normal, "", &bOk);\r
561     if (!bOk || name.isEmpty()) {\r
562         return;\r
563     }\r
564 \r
565     QDir dir(folderView()->dir());\r
566     if (!dir.mkpath(name)) {\r
567         QMessageBox::critical(\r
568                     this, tr("エラー"),\r
569                     tr("フォルダの作成に失敗しました。"));\r
570     }\r
571     else {\r
572         QSettings settings;\r
573         if (settings.value(IniKey_MoveAfterCreateFolder).toBool()) {\r
574             folderView()->setPath(dir.absoluteFilePath(name), true);\r
575             updateActions();\r
576         }\r
577     }\r
578 }\r
579 \r
580 void MainWindow::deleteItems()\r
581 {\r
582     qDebug() << "MainWindow::deleteItems";\r
583 \r
584     FolderView *v = folderView();\r
585     QFileInfoList list = v->selectedItems();\r
586     if (list.isEmpty()) {\r
587         return;\r
588     }\r
589 \r
590     QSettings settings;\r
591     if (settings.value(IniKey_ConfirmDelete).toBool()) {\r
592         QString msg;\r
593         if (list.size() == 1) {\r
594             msg = list[0].fileName();\r
595         }\r
596         else {\r
597             msg = tr("%1個のアイテム").arg(list.size());\r
598         }\r
599         int ret = QMessageBox::question(\r
600                     this, tr("確認"),\r
601                     msg + tr("を削除しますか?"));\r
602         if (ret != QMessageBox::Yes) {\r
603             return;\r
604         }\r
605     }\r
606 \r
607     DeleteWorker *worker = new DeleteWorker();\r
608     worker->setDeleteList(&list);\r
609 \r
610     OperationDialog opDlg(this);\r
611     opDlg.setWindowTitle(tr("削除"));\r
612     opDlg.setWorker(worker);\r
613     opDlg.setAutoClose(settings.value(IniKey_AutoCloseDelete).toBool());\r
614 \r
615     opDlg.exec();\r
616 \r
617     settings.setValue(IniKey_AutoCloseDelete, opDlg.autoClose());\r
618 \r
619     // 念のため、リフレッシュ\r
620     ui->folderView1->refresh();\r
621     ui->folderView2->refresh();\r
622 }\r
623 \r
624 void MainWindow::open(const QModelIndex &index)\r
625 {\r
626     Q_UNUSED(index);\r
627     qDebug() << "MainWindow::open";\r
628 \r
629     FolderView *v = folderView();\r
630     Q_ASSERT(v);\r
631 \r
632     QFileInfo info = v->currentItem();\r
633     if (info.isDir()) {\r
634         v->setPath(info.absoluteFilePath(), true);\r
635         updateActions();\r
636         return;\r
637     }\r
638 \r
639     QSettings settings;\r
640     if (!settings.value(IniKey_ViewerForceOpen).toBool()) {\r
641         QStringList list = settings.value(IniKey_ViewerIgnoreExt).toString().split(",");\r
642         foreach (const QString &ext, list) {\r
643             if (ext.toLower() == info.suffix().toLower()) {\r
644                 shellExecute();\r
645                 return;\r
646             }\r
647         }\r
648     }\r
649 \r
650     setUpdatesEnabled(false);\r
651 \r
652     foreach (QObject *obj, this->children()) {\r
653         QAction *action = qobject_cast<QAction*>(obj);\r
654         if (action) {\r
655             if (action->objectName() == "help_About" ||\r
656                 action->objectName() == "check_Update" ||\r
657                 action->objectName() == "copy_Fullpath" ||\r
658                 action->objectName() == "copy_Filename" ||\r
659                 action->objectName() == "action_Quit" ||\r
660                 action->objectName() == "action_Setting")\r
661             {\r
662                 continue;\r
663             }\r
664             action->setEnabled(false);\r
665         }\r
666     }\r
667 \r
668     m_focusedView = folderView();\r
669     ui->splitter->setVisible(false);\r
670     ui->textView->setVisible(true);\r
671     ui->textView->setFocus();\r
672 \r
673     setUpdatesEnabled(true);\r
674 \r
675     QFile file(info.absoluteFilePath());\r
676     if (file.open(QIODevice::ReadOnly)) {\r
677         ui->textView->setSource(file.readAll());\r
678     }\r
679 }\r
680 \r
681 void MainWindow::openEditor(const QString &path)\r
682 {\r
683     qDebug() << "MainWindow::openEditor";\r
684 \r
685     QSettings settings;\r
686     QString exe = settings.value(IniKey_EditorPath).toString();\r
687     if (exe.isEmpty()) {\r
688         QMessageBox::critical(\r
689                     this, tr("エラー"),\r
690                     tr("外部エディタのパスが未定義です。"));\r
691         return;\r
692     }\r
693 \r
694     FolderView *v = folderView();\r
695     Q_ASSERT(v);\r
696 \r
697     QFileInfoList list;\r
698     if (path.isEmpty()) {\r
699         list = v->selectedItems();\r
700     }\r
701     else {\r
702         list << path;\r
703     }\r
704 \r
705     foreach (const QFileInfo &info, list) {\r
706         QString opt = settings.value(IniKey_EditorOption).toString();\r
707         replaceVars(opt, info);\r
708 \r
709 #ifdef Q_OS_MAC\r
710         QString command = "open -a " + exe + " " + opt;\r
711 #else\r
712         QString command = QQ(exe) + " " + opt;\r
713 #endif\r
714         if (!startProcess(command, info.absolutePath(), tr("外部エディタの起動に失敗しました。"))) {\r
715             break;\r
716         }\r
717     }\r
718 }\r
719 \r
720 void MainWindow::openTerminal()\r
721 {\r
722     qDebug() << "MainWindow::openTerminal";\r
723 \r
724     QSettings settings;\r
725     QString exe = settings.value(IniKey_TerminalPath).toString();\r
726     if (exe.isEmpty()) {\r
727         QMessageBox::critical(\r
728                     this, tr("エラー"),\r
729                     tr("ターミナルのパスが未定義です。"));\r
730         return;\r
731     }\r
732 \r
733     FolderView *v = folderView();\r
734     Q_ASSERT(v);\r
735 \r
736     foreach (const QFileInfo &info, v->selectedItems()) {\r
737         QString opt = settings.value(IniKey_TerminalOption).toString();\r
738         replaceVars(opt, info);\r
739 \r
740 #ifdef Q_OS_MAC\r
741         QString command = "open -a " + QQ(exe) + " --args " + opt;\r
742 #else\r
743         QString command = QQ(exe) + " " + opt;\r
744 #endif\r
745         if (!startProcess(command, info.absolutePath(), tr("ターミナルの起動に失敗しました。"))) {\r
746             break;\r
747         }\r
748     }\r
749 }\r
750 \r
751 void MainWindow::refresh()\r
752 {\r
753     qDebug() << "MainWindow::refresh();";\r
754 \r
755     folderView()->refresh();\r
756     updateActions();\r
757 }\r
758 \r
759 void MainWindow::renameItems()\r
760 {\r
761     qDebug() << "MainWindow::renameItems";\r
762 \r
763     FolderView *v = folderView();\r
764 \r
765     QFileInfoList list = v->selectedItems();\r
766     if (list.isEmpty()) {\r
767         return;\r
768     }\r
769 \r
770     IRenameDialog *dlg;\r
771     if (list.size() == 1) {\r
772         dlg = new RenameSingleDialog(this);\r
773     }\r
774     else {\r
775         dlg = new RenameMultiDialog(this);\r
776     }\r
777     dlg->setWorkingDirectory(v->dir());\r
778     dlg->setNames(list);\r
779     int dlgResult = dlg->exec();\r
780     if (dlgResult != QDialog::Accepted || dlg->renameMap().isEmpty()) {\r
781         return;\r
782     }\r
783 \r
784     QSettings settings;\r
785     if (settings.value(IniKey_ConfirmRename).toBool()) {\r
786         int ret = QMessageBox::question(this, tr("確認"),\r
787                                         tr("名前の変更を実行しますか?"));\r
788         if (ret != QMessageBox::Yes) {\r
789             return;\r
790         }\r
791     }\r
792 \r
793     RenameWorker *worker = new RenameWorker();\r
794     worker->setRenameMap(&dlg->renameMap());\r
795 \r
796     OperationDialog opDlg(this);\r
797     opDlg.setWindowTitle(tr("名前を変更"));\r
798     opDlg.setWorker(worker);\r
799     opDlg.setAutoClose(settings.value(IniKey_AutoCloseRename).toBool());\r
800 \r
801     opDlg.exec();\r
802 \r
803     settings.setValue(IniKey_AutoCloseRename, opDlg.autoClose());\r
804 }\r
805 \r
806 void MainWindow::retrieveFinish()\r
807 {\r
808     qDebug() << "MainWindow::retrieveFinish();";\r
809 \r
810     ui->statusBar->showMessage(tr("レディ"), 5000);\r
811 }\r
812 \r
813 void MainWindow::retrieveStart(const QString &path)\r
814 {\r
815     qDebug() << "MainWindow::retrieveStart();" << path;\r
816 \r
817     ui->statusBar->showMessage(tr("ファイルリストを取得しています..."));\r
818     if (sender() == ui->folderView1) {\r
819         ui->locationBox1->setText(path);\r
820     }\r
821     else {\r
822         Q_ASSERT(sender() == ui->folderView2);\r
823         ui->locationBox2->setText(path);\r
824     }\r
825 }\r
826 \r
827 void MainWindow::shellExecute()\r
828 {\r
829     qDebug() << "MainWindow::shellExecute";\r
830 \r
831     FolderView *v = folderView();\r
832     Q_ASSERT(v);\r
833 \r
834     QFileInfoList list = v->selectedItems();\r
835     foreach (const QFileInfo &info, list) {\r
836         QString path = QDir::toNativeSeparators(info.absoluteFilePath());\r
837         QDesktopServices::openUrl(QUrl("file:///" + path));\r
838     }\r
839 }\r
840 \r
841 void MainWindow::showFilterDialog()\r
842 {\r
843     qDebug() << "MainWindow::showFilterDialog();";\r
844 \r
845     QString filters = folderView()->nameFilters().join(" ");\r
846 \r
847     QInputDialog dlg(this);\r
848     dlg.setInputMode(QInputDialog::TextInput);\r
849     dlg.setWindowTitle(tr("フィルタを設定"));\r
850     dlg.setLabelText(tr("フィルタ:"));\r
851     dlg.setTextValue(filters);\r
852     dlg.resize(width() * 0.8, dlg.height());\r
853 \r
854     if (dlg.exec() == QDialog::Accepted) {\r
855         setNameFilters(folderView(), dlg.textValue());\r
856     }\r
857 }\r
858 \r
859 void MainWindow::showHistoryDialog()\r
860 {\r
861     qDebug() << "MainWindow::showHistoryDialog();";\r
862 \r
863     FolderView *v = folderView();\r
864     FolderView *vOther = otherSideView(v);\r
865 \r
866     HistoryDialog dlg(this);\r
867     if (v->side() == "Left") {\r
868         dlg.setDefaultLeft(true);\r
869         dlg.setHistory(v->history(), vOther->history());\r
870     }\r
871     else {\r
872         dlg.setDefaultLeft(false);\r
873         dlg.setHistory(vOther->history(), v->history());\r
874     }\r
875 \r
876     if (dlg.exec() == QDialog::Accepted) {\r
877         if (v->side() == dlg.selectedSide()) {\r
878             v->setHistoryIndexAt(dlg.selectedIndex());\r
879         }\r
880         else {\r
881             v->setPath(vOther->history()->at(dlg.selectedIndex()), true);\r
882         }\r
883         updateActions();\r
884     }\r
885 }\r
886 \r
887 void MainWindow::showSortDialog()\r
888 {\r
889     qDebug() << "MainWindow::showSortDialog();";\r
890 \r
891     SortDialog dlg(this);\r
892     dlg.setRightOrLeft(folderView()->side());\r
893 \r
894     if (dlg.exec() != QDialog::Accepted) {\r
895         return;\r
896     }\r
897 \r
898     setSorting(folderView());\r
899 }\r
900 \r
901 void MainWindow::swapView()\r
902 {\r
903     qDebug() << "MainWindow::swapView();";\r
904 \r
905     QString dir1 = ui->folderView1->dir();\r
906     QString dir2 = ui->folderView2->dir();\r
907 \r
908     ui->folderView1->setPath(dir2, true);\r
909     ui->folderView2->setPath(dir1, true);\r
910 \r
911     updateActions();\r
912 }\r
913 \r
914 void MainWindow::setSorting(FolderView *view)\r
915 {\r
916     qDebug() << "MainWindow::setSorting();" << view->objectName();\r
917 \r
918     QSettings settings;\r
919     QDir::SortFlags flags;\r
920 \r
921     int sortBy = settings.value(view->side() + slash + IniKey_SortBy).toInt();\r
922     switch (sortBy) {\r
923     case SortByDate:    flags |= QDir::Time; break;\r
924     case SortBySize:    flags |= QDir::Size; break;\r
925     case SortByType:    flags |= QDir::Type; break;\r
926     default:            flags |= QDir::Name; break;\r
927     }\r
928 \r
929     // デフォルトだと文字列は昇順で、数値は降順…orz\r
930     int orderBy = settings.value(view->side() + slash + IniKey_OrderBy).toInt();\r
931     if (((sortBy == SortByName || sortBy == SortByType) && orderBy == OrderByDesc) ||\r
932         ((sortBy == SortByDate || sortBy == SortBySize) && orderBy == OrderByAsc))\r
933     {\r
934         flags |= QDir::Reversed;\r
935     }\r
936 \r
937     switch (settings.value(view->side() + slash + IniKey_PutDirs).toInt()) {\r
938     case PutDirsFirst:  flags |= QDir::DirsFirst; break;\r
939     case PutDirsLast:   flags |= QDir::DirsLast; break;\r
940     }\r
941 \r
942     if (settings.value(view->side() + slash + IniKey_IgnoreCase).toBool()) {\r
943         flags |= QDir::IgnoreCase;\r
944     }\r
945 \r
946     view->setSorting(flags);\r
947 }\r
948 \r
949 void MainWindow::searchItem(const QString &text)\r
950 {\r
951     qDebug() << "MainWindow::searchItem" << text;\r
952 \r
953     FolderView *v;\r
954     SearchBox *box;\r
955     if (ui->searchBox1->hasFocus()) {\r
956         v = ui->folderView1;\r
957         box = ui->searchBox1;\r
958     }\r
959     else {\r
960         Q_ASSERT(ui->searchBox2->hasFocus());\r
961         v = ui->folderView2;\r
962         box = ui->searchBox2;\r
963     }\r
964 \r
965     if (text.right(1) == "/") {\r
966         box->setText(text.left(text.length() - 1));\r
967         ui->action_Search->setChecked(false);\r
968         return;\r
969     }\r
970 \r
971     v->searchItem(box->text());\r
972 }\r
973 \r
974 void MainWindow::searchNext()\r
975 {\r
976     qDebug() << "MainWindow::searchNext";\r
977 \r
978     FolderView *v = folderView();\r
979     SearchBox *box = searchBox(v);\r
980     v->searchNext(box->text());\r
981 }\r
982 \r
983 void MainWindow::searchPrev()\r
984 {\r
985     qDebug() << "MainWindow::searchPrev";\r
986 \r
987     FolderView *v = folderView();\r
988     SearchBox *box = searchBox(v);\r
989     v->searchPrev(box->text());\r
990 }\r
991 \r
992 void MainWindow::setCursorToBegin()\r
993 {\r
994     qDebug() << "MainWindow::setCursorToBegin();";\r
995 \r
996     FolderView *v = folderView();\r
997     int row = 0;\r
998     v->setCurrentIndex(v->model()->index(row, 0));\r
999 }\r
1000 \r
1001 void MainWindow::cursorDown()\r
1002 {\r
1003     qDebug() << "MainWindow::cursorDown();";\r
1004 \r
1005     FolderView *v = folderView();\r
1006     int row = v->currentIndex().row() + 1;\r
1007     if (row < v->model()->rowCount()) {\r
1008         v->setCurrentIndex(v->model()->index(row, 0));\r
1009     }\r
1010 }\r
1011 \r
1012 void MainWindow::cursorUp()\r
1013 {\r
1014     qDebug() << "MainWindow::cursorUp();";\r
1015 \r
1016     FolderView *v = folderView();\r
1017     int row = v->currentIndex().row() - 1;\r
1018     if (row >= 0) {\r
1019         v->setCurrentIndex(v->model()->index(row, 0));\r
1020     }\r
1021 }\r
1022 \r
1023 void MainWindow::setCursorToEnd()\r
1024 {\r
1025     qDebug() << "MainWindow::setCursorToEnd();";\r
1026 \r
1027     FolderView *v = folderView();\r
1028     int row = v->model()->rowCount() - 1;\r
1029     v->setCurrentIndex(v->model()->index(row, 0));\r
1030 }\r
1031 \r
1032 void MainWindow::setPathFromOther()\r
1033 {\r
1034     qDebug() << "MainWindow::setPathFromOther();";\r
1035 \r
1036     FolderView *view = folderView();\r
1037     FolderView *other = otherSideView(view);\r
1038 \r
1039     view->setPath(other->dir(), true);\r
1040     updateActions();\r
1041 }\r
1042 \r
1043 void MainWindow::setPathToHome()\r
1044 {\r
1045     qDebug() << "MainWindow::setPathToHome();";\r
1046 \r
1047     folderView()->setPath(QDir::homePath(), true);\r
1048     updateActions();\r
1049 }\r
1050 \r
1051 void MainWindow::setPathToOther()\r
1052 {\r
1053     qDebug() << "MainWindow::setPathToOther();";\r
1054 \r
1055     FolderView *view = folderView();\r
1056     FolderView *other = otherSideView(view);\r
1057 \r
1058     other->setPath(view->dir(), true);\r
1059     updateActions();\r
1060 }\r
1061 \r
1062 void MainWindow::setPathToParent()\r
1063 {\r
1064     qDebug() << "MainWindow::setPathToParent();";\r
1065 \r
1066     QDir dir(folderView()->dir());\r
1067     if (!dir.isRoot()) {\r
1068         dir.cdUp();\r
1069         folderView()->setPath(dir.absolutePath(), true);\r
1070         updateActions();\r
1071     }\r
1072 }\r
1073 \r
1074 void MainWindow::setPathToRoot()\r
1075 {\r
1076     qDebug() << "MainWindow::setPathToRoot();";\r
1077 \r
1078     folderView()->setPath(QDir::rootPath(), true);\r
1079     updateActions();\r
1080 }\r
1081 \r
1082 void MainWindow::toggleSearchBox(bool checked)\r
1083 {\r
1084     qDebug() << "MainWindow::toggleSearchBox" << checked;\r
1085 \r
1086     FolderView *v;\r
1087     SearchBox *box;\r
1088 \r
1089     if (checked) {\r
1090         v = folderView();\r
1091         if (v == ui->folderView1) {\r
1092             box = ui->searchBox1;\r
1093         }\r
1094         else {\r
1095             Q_ASSERT(v == ui->folderView2);\r
1096             box = ui->searchBox2;\r
1097         }\r
1098 \r
1099         box->setVisible(true);\r
1100         box->setFocus();\r
1101         box->selectAll();\r
1102     }\r
1103     else {\r
1104         if (ui->searchBox1->isVisible()) {\r
1105             box = ui->searchBox1;\r
1106             v = ui->folderView1;\r
1107         }\r
1108         else {\r
1109             Q_ASSERT(ui->searchBox2->isVisible());\r
1110             box = ui->searchBox2;\r
1111             v = ui->folderView2;\r
1112         }\r
1113 \r
1114         if (box->hasFocus()) {\r
1115             v->setFocus();\r
1116         }\r
1117         box->setVisible(false);\r
1118     }\r
1119 }\r
1120 \r
1121 void MainWindow::openRequest(const QFileInfo &info)\r
1122 {\r
1123     m_focusedView = QApplication::focusWidget();\r
1124 \r
1125     QFile file(info.absoluteFilePath());\r
1126     if (file.open(QIODevice::ReadOnly)) {\r
1127         ui->splitter->setVisible(false);\r
1128         ui->textView->setVisible(true);\r
1129         ui->textView->setFocus();\r
1130         ui->textView->setSource(file.readAll());\r
1131     }\r
1132     else {\r
1133         QMessageBox::critical(\r
1134                     this, tr("エラー"),\r
1135                     tr("ファイルの読み込みに失敗しました。"));\r
1136     }\r
1137 }\r
1138 \r
1139 void MainWindow::showPreferenceDialog()\r
1140 {\r
1141     qDebug() << "MainWindow::showPreferenceDialog";\r
1142 \r
1143     PreferenceDialog dlg(this);\r
1144     if (dlg.exec() == QDialog::Accepted) {\r
1145         ui->locationBox1->updateAppearance();\r
1146         ui->locationBox2->updateAppearance();\r
1147         ui->folderView1->updateAppearance();\r
1148         ui->folderView2->updateAppearance();\r
1149 \r
1150         updateActions();\r
1151     }\r
1152 }\r
1153 \r
1154 void MainWindow::toggleShowHiddenFiles(bool checked)\r
1155 {\r
1156     qDebug() << "MainWindow::toggleShowHiddenFiles" << checked;\r
1157 \r
1158     ui->folderView1->setFilter(QDir::Hidden, checked);\r
1159     ui->folderView1->refresh();\r
1160 \r
1161     ui->folderView2->setFilter(QDir::Hidden, checked);\r
1162     ui->folderView2->refresh();\r
1163 }\r
1164 \r
1165 void MainWindow::toggleShowSystemFiles(bool checked)\r
1166 {\r
1167     qDebug() << "MainWindow::toggleShowSystemFiles" << checked;\r
1168 \r
1169     ui->folderView1->setFilter(QDir::System, checked);\r
1170     ui->folderView1->refresh();\r
1171 \r
1172     ui->folderView2->setFilter(QDir::System, checked);\r
1173     ui->folderView2->refresh();\r
1174 }\r
1175 \r
1176 void MainWindow::checkUpdate(bool silent)\r
1177 {\r
1178     qDebug() << "MainWindow::checkUpdate()" << silent;\r
1179 \r
1180     QNetworkAccessManager *manager = new QNetworkAccessManager(this);\r
1181 \r
1182     if (silent) {\r
1183         connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(checkUpdateFinishedSilent(QNetworkReply*)));\r
1184     }\r
1185     else {\r
1186         connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(checkUpdateFinished(QNetworkReply*)));\r
1187     }\r
1188 #ifdef Q_OS_WIN\r
1189     manager->get(QNetworkRequest(QUrl("http://miyabi.rakusaba.jp/wp-content/uploads/gefu_latest_win.html")));\r
1190 #elif defined(Q_OS_MAC)\r
1191     manager->get(QNetworkRequest(QUrl("http://miyabi.rakusaba.jp/wp-content/uploads/gefu_latest_mac.html")));\r
1192 #endif\r
1193 }\r
1194 \r
1195 void MainWindow::checkUpdateFinishedSilent(QNetworkReply *reply)\r
1196 {\r
1197     qDebug() << "MainWindow::checkUpdateFinishedSilent";\r
1198 \r
1199     checkUpdateFinished(reply, true);\r
1200 }\r
1201 \r
1202 void MainWindow::checkUpdateFinished(QNetworkReply *reply, bool silent)\r
1203 {\r
1204     qDebug() << "MainWindow::checkUpdateFinished" << silent;\r
1205 \r
1206     if (reply->error() == QNetworkReply::NoError) {\r
1207         QString str = reply->readAll();\r
1208         str = str.split(QRegExp("[\r\n]"), QString::SkipEmptyParts).at(0);\r
1209         QRegExp rx("Gefu([0-9]+)");\r
1210         rx.indexIn(str);\r
1211         QString version = rx.cap(1);\r
1212         if (version.toInt() > VERSION_VALUE * 100) {\r
1213             QMessageBox::information(\r
1214                         this, tr("情報"),\r
1215                         tr("最新のバージョンが存在します。<br/>") +\r
1216                         tr("<a href='%1'>こちらからダウンロードしてください。</a>").arg(str));\r
1217         }\r
1218         else if (!silent) {\r
1219             QMessageBox::information(\r
1220                         this, tr("情報"),\r
1221                         tr("お使いのバージョンは最新です。"));\r
1222         }\r
1223     }\r
1224     else if (!silent){\r
1225         QMessageBox::critical(\r
1226                     this, tr("エラー"),\r
1227                     tr("最新バージョンのチェックに失敗しました。<br/>") +\r
1228                     reply->errorString());\r
1229     }\r
1230 }\r
1231 \r
1232 void MainWindow::viewFinish(QWidget *sender)\r
1233 {\r
1234     qDebug() << "MainWindow::viewFinish();" << sender->objectName();\r
1235 \r
1236     sender->setVisible(false);\r
1237     ui->splitter->setVisible(true);\r
1238     m_focusedView->setFocus();\r
1239 }\r
1240 \r
1241 \r
1242 void MainWindow::initActionConnections()\r
1243 {\r
1244     qDebug() << "MainWindow::initActionConnections";\r
1245 \r
1246     connect(ui->action_Command, SIGNAL(triggered()), this, SLOT(executeCommand()));\r
1247     connect(ui->action_Exec, SIGNAL(triggered()), this, SLOT(shellExecute()));\r
1248     connect(ui->action_Open, SIGNAL(triggered()), this, SLOT(open()));\r
1249     connect(ui->action_OpenEditor, SIGNAL(triggered()), this, SLOT(openEditor()));\r
1250     connect(ui->action_OpenTerminal, SIGNAL(triggered()), this, SLOT(openTerminal()));\r
1251     connect(ui->action_Quit, SIGNAL(triggered()), this, SLOT(close()));\r
1252     connect(ui->action_Search, SIGNAL(toggled(bool)), this, SLOT(toggleSearchBox(bool)));\r
1253     connect(ui->action_SearchNext, SIGNAL(triggered()), this, SLOT(searchNext()));\r
1254     connect(ui->action_SearchPrev, SIGNAL(triggered()), this, SLOT(searchPrev()));\r
1255     connect(ui->action_Setting, SIGNAL(triggered()), this, SLOT(showPreferenceDialog()));\r
1256     connect(ui->check_Update, SIGNAL(triggered()), this, SLOT(checkUpdate()));\r
1257     connect(ui->cmd_Copy, SIGNAL(triggered()), this, SLOT(copyItems()));\r
1258     connect(ui->cmd_Delete, SIGNAL(triggered()), this, SLOT(deleteItems()));\r
1259     connect(ui->cmd_Move, SIGNAL(triggered()), this, SLOT(moveItems()));\r
1260     connect(ui->cmd_NewFile, SIGNAL(triggered()), this, SLOT(createFile()));\r
1261     connect(ui->cmd_NewFolder, SIGNAL(triggered()), this, SLOT(createFolder()));\r
1262     connect(ui->cmd_Rename, SIGNAL(triggered()), this, SLOT(renameItems()));\r
1263     connect(ui->copy_Filename, SIGNAL(triggered()), this, SLOT(copyFilenameToClipboard()));\r
1264     connect(ui->copy_Fullpath, SIGNAL(triggered()), this, SLOT(copyFullpathTpClipboard()));\r
1265     connect(ui->help_About, SIGNAL(triggered()), this, SLOT(about()));\r
1266     connect(ui->mark_All, SIGNAL(triggered()), this, SLOT(markAll()));\r
1267     connect(ui->mark_AllFiles, SIGNAL(triggered()), this, SLOT(markAllFiles()));\r
1268     connect(ui->mark_AllOff, SIGNAL(triggered()), this, SLOT(markAllOff()));\r
1269     connect(ui->mark_Invert, SIGNAL(triggered()), this, SLOT(markInvert()));\r
1270     connect(ui->mark_Toggle, SIGNAL(triggered()), this, SLOT(markToggle()));\r
1271     connect(ui->move_Back, SIGNAL(triggered()), this, SLOT(historyBack()));\r
1272     connect(ui->move_Begin, SIGNAL(triggered()), this, SLOT(setCursorToBegin()));\r
1273     connect(ui->move_Down, SIGNAL(triggered()), this, SLOT(cursorDown()));\r
1274     connect(ui->move_End, SIGNAL(triggered()), this, SLOT(setCursorToEnd()));\r
1275     connect(ui->move_Forward, SIGNAL(triggered()), this, SLOT(historyForward()));\r
1276     connect(ui->move_History, SIGNAL(triggered()), this, SLOT(showHistoryDialog()));\r
1277     connect(ui->move_Home, SIGNAL(triggered()), this, SLOT(setPathToHome()));\r
1278     connect(ui->move_Jump, SIGNAL(triggered()), this, SLOT(chooseFolder()));\r
1279     connect(ui->move_Parent, SIGNAL(triggered()), this, SLOT(setPathToParent()));\r
1280     connect(ui->move_Root, SIGNAL(triggered()), this, SLOT(setPathToRoot()));\r
1281     connect(ui->move_Up, SIGNAL(triggered()), this, SLOT(cursorUp()));\r
1282     connect(ui->view_Filter, SIGNAL(triggered()), this, SLOT(showFilterDialog()));\r
1283     connect(ui->view_FromOther, SIGNAL(triggered()), this, SLOT(setPathFromOther()));\r
1284     connect(ui->view_Hidden, SIGNAL(toggled(bool)), this, SLOT(toggleShowHiddenFiles(bool)));\r
1285     connect(ui->view_Refresh, SIGNAL(triggered()), this, SLOT(refresh()));\r
1286     connect(ui->view_Sort, SIGNAL(triggered()), this, SLOT(showSortDialog()));\r
1287     connect(ui->view_Swap, SIGNAL(triggered()), this, SLOT(swapView()));\r
1288     connect(ui->view_System, SIGNAL(toggled(bool)), this, SLOT(toggleShowSystemFiles(bool)));\r
1289     connect(ui->view_ToOther, SIGNAL(triggered()), this, SLOT(setPathToOther()));\r
1290 }\r
1291 \r
1292 FolderView *MainWindow::folderView() const\r
1293 {\r
1294     qDebug() << "MainWindow::folderView";\r
1295 \r
1296     QWidget *w = qApp->focusWidget();\r
1297     if (w == ui->folderView1 || w == ui->searchBox1 || w == ui->locationBox1) {\r
1298         return ui->folderView1;\r
1299     }\r
1300     if (w == ui->folderView2 || w == ui->searchBox2 || w == ui->locationBox2) {\r
1301         return ui->folderView2;\r
1302     }\r
1303 \r
1304     qDebug() << w->objectName();\r
1305     return NULL;\r
1306 }\r
1307 \r
1308 void MainWindow::replaceVars(QString &str, const QFileInfo info)\r
1309 {\r
1310     qDebug() << "MainWindow::replaceVars" << str;\r
1311 \r
1312     str.replace("$B", info.completeBaseName());\r
1313     str.replace("$E", info.suffix());\r
1314     str.replace("$F", info.fileName());\r
1315     if (info.isDir()) {\r
1316         str.replace("$D", info.absoluteFilePath());\r
1317     }\r
1318     else {\r
1319         str.replace("$D", info.absolutePath());\r
1320     }\r
1321     str.replace("$P", info.absoluteFilePath());\r
1322 }\r
1323 \r
1324 SearchBox *MainWindow::searchBox(FolderView *view) const\r
1325 {\r
1326     qDebug() << "MainWindow::searchBox()" << view->objectName();\r
1327 \r
1328     if (view == ui->folderView1) {\r
1329         return ui->searchBox1;\r
1330     }\r
1331     else {\r
1332         Q_ASSERT(view == ui->folderView2);\r
1333         return ui->searchBox2;\r
1334     }\r
1335 }\r
1336 \r
1337 bool MainWindow::startProcess(const QString &cmd, const QString &workDir, const QString &errMsg)\r
1338 {\r
1339     qDebug() << "MainWindow::startProcess" << cmd << workDir << errMsg;\r
1340 \r
1341     QProcess process(this);\r
1342     process.setWorkingDirectory(workDir);\r
1343     if (!process.startDetached(cmd)) {\r
1344         QMessageBox::critical(this, tr("エラー"), errMsg + "<br/>" + cmd);\r
1345         return false;\r
1346     }\r
1347     return true;\r
1348 }\r
1349 \r
1350 void MainWindow::updateActions()\r
1351 {\r
1352     qDebug() << "MainWindow::updateActions";\r
1353 \r
1354     if (ui->textView->hasFocus()) {\r
1355         // テキストビューア時\r
1356         setEnabledAllActions(false);\r
1357         ui->action_Quit->setEnabled(true);\r
1358         ui->action_Setting->setEnabled(true);\r
1359         ui->check_Update->setEnabled(true);\r
1360         ui->copy_Filename->setEnabled(true);\r
1361         ui->copy_Fullpath->setEnabled(true);\r
1362         ui->help_About->setEnabled(true);\r
1363     }\r
1364     else if (ui->searchBox1->hasFocus() || ui->searchBox2->hasFocus()) {\r
1365         // ファイル検索時\r
1366         setEnabledAllActions(false);\r
1367         ui->action_Search->setEnabled(true);\r
1368         ui->action_SearchNext->setEnabled(true);\r
1369         ui->action_SearchPrev->setEnabled(true);\r
1370         ui->help_About->setEnabled(true);\r
1371         ui->action_Quit->setEnabled(true);\r
1372     }\r
1373     else if (ui->folderView1->hasFocus() || ui->folderView2->hasFocus()) {\r
1374         // 通常時\r
1375         setEnabledAllActions(true);\r
1376         ui->action_SearchNext->setEnabled(false);\r
1377         ui->action_SearchPrev->setEnabled(false);\r
1378 \r
1379         ui->move_Back->setEnabled(!folderView()->history()->isBegin());\r
1380         ui->move_Forward->setEnabled(!folderView()->history()->isEnd());\r
1381 \r
1382         QSettings settings;\r
1383         ui->action_OpenEditor->setEnabled(!settings.value(IniKey_EditorPath).toString().isEmpty());\r
1384         ui->action_OpenTerminal->setEnabled(!settings.value(IniKey_TerminalPath).toString().isEmpty());\r
1385     }\r
1386 }\r
1387 \r
1388 void MainWindow::setEnabledAllActions(bool enable)\r
1389 {\r
1390     qDebug() << "MainWindow::setEnabledAllActions();" << enable;\r
1391     foreach (QObject *obj, children()) {\r
1392         QAction *action = qobject_cast<QAction*>(obj);\r
1393         if (action) {\r
1394             action->setEnabled(enable);\r
1395         }\r
1396     }\r
1397 }\r
1398 \r
1399 void MainWindow::setNameFilters(FolderView *view, const QString &filters)\r
1400 {\r
1401     qDebug() << "MainWindow::setNameFilters();" << view->objectName() << filters;\r
1402 \r
1403     QStringList list = filters.split(" ", QString::SkipEmptyParts);\r
1404     if (list.isEmpty()) {\r
1405         list << "*";\r
1406     }\r
1407     view->setNameFilters(list);\r
1408     filterLabel(view)->setText(tr("フィルタ:") + list.join(" "));\r
1409 }\r
1410 \r
1411 QLabel *MainWindow::filterLabel(const FolderView *view) const\r
1412 {\r
1413     qDebug() << "MainWindow::filterLabel()" << view->objectName();\r
1414     if (view == ui->folderView1) {\r
1415         return ui->filterLabel1;\r
1416     }\r
1417     else {\r
1418         Q_ASSERT(view == ui->folderView2);\r
1419         return ui->filterLabel2;\r
1420     }\r
1421 }\r
1422 \r
1423 void MainWindow::about()\r
1424 {\r
1425     QMessageBox::about(\r
1426                 this,\r
1427                 tr("げふぅ について"),\r
1428                 tr("<h3>Gefu Ver%1</h3>").arg(VERSION_VALUE) +\r
1429                 tr("<center>Gefu is an Experimental File Utility.<br/>"\r
1430                    "<small>(げふぅは実験的なファイルユーティリティです)</small></center>"\r
1431                    "<p>最新版の情報は<a href='https://sourceforge.jp/projects/gefu/'>プロジェクトサイト</a>で公開しています。</p>"\r
1432                    "<p><small>Copyright 2014 @miyabi_satoh All rights reserved.</small></p>"));\r
1433 }\r
1434 \r
1435 void MainWindow::closeEvent(QCloseEvent *event)\r
1436 {\r
1437     QSettings settings;\r
1438 \r
1439     if (settings.value(IniKey_ConfirmExit).toBool()) {\r
1440         QMessageBox msgBox;\r
1441         QCheckBox *checkBox = new QCheckBox();\r
1442         checkBox->setText(tr("次回以降は確認しない"));\r
1443         msgBox.setCheckBox(checkBox);\r
1444         msgBox.setText(tr("終了しますか?"));\r
1445         msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);\r
1446         msgBox.setIcon(QMessageBox::Question);\r
1447 \r
1448         if (msgBox.exec() == QMessageBox::No) {\r
1449             event->ignore();\r
1450             return;\r
1451         }\r
1452         settings.setValue(IniKey_ConfirmExit, !checkBox->isChecked());\r
1453     }\r
1454 \r
1455     settings.setValue(QString("Left/") + IniKey_Dir, ui->folderView1->dir());\r
1456     settings.setValue(QString("Right/") + IniKey_Dir, ui->folderView2->dir());\r
1457     settings.setValue(IniKey_ShowHidden, ui->view_Hidden->isChecked());\r
1458     settings.setValue(IniKey_ShowSystem, ui->view_System->isChecked());\r
1459     settings.setValue(IniKey_WindowGeometry, saveGeometry());\r
1460     settings.setValue(iniKey_WindowState, saveState());\r
1461     QMainWindow::closeEvent(event);\r
1462 }\r
1463 \r
1464 \r
1465 void MainWindow::keyPressEvent(QKeyEvent *event)\r
1466 {\r
1467     QString ksq = KeyEventToSequence(event);\r
1468     qDebug() << ksq << " @MainWindow";\r
1469 \r
1470     QMainWindow::keyPressEvent(event);\r
1471 }\r