OSDN Git Service

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