OSDN Git Service

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