OSDN Git Service

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