]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphinmainwindow.cpp
Ahhh, fixing the bugs you report, that rocks ;-)
[dolphin.git] / src / dolphinmainwindow.cpp
1 /***************************************************************************
2 * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> *
3 * Copyright (C) 2006 by Stefan Monov <logixoul@gmail.com> *
4 * Copyright (C) 2006 by Cvetoslav Ludmiloff <ludmiloff@gmail.com> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20 ***************************************************************************/
21
22 #include "dolphinmainwindow.h"
23
24 #include <config-nepomuk.h>
25
26 #include "dolphinapplication.h"
27 #include "dolphinnewmenu.h"
28 #include "dolphinsettings.h"
29 #include "dolphinsettingsdialog.h"
30 #include "dolphinstatusbar.h"
31 #include "dolphinviewcontainer.h"
32 #include "infosidebarpage.h"
33 #include "metadatawidget.h"
34 #include "mainwindowadaptor.h"
35 #include "terminalsidebarpage.h"
36 #include "treeviewsidebarpage.h"
37 #include "kurlnavigator.h"
38 #include "viewpropertiesdialog.h"
39 #include "viewproperties.h"
40 #include "kfileplacesmodel.h"
41 #include "kfileplacesview.h"
42
43 #include "dolphin_generalsettings.h"
44
45 #include <kaction.h>
46 #include <kactioncollection.h>
47 #include <kconfig.h>
48 #include <kdesktopfile.h>
49 #include <kdeversion.h>
50 #include <kfiledialog.h>
51 #include <kglobal.h>
52 #include <kicon.h>
53 #include <kiconloader.h>
54 #include <kio/netaccess.h>
55 #include <kinputdialog.h>
56 #include <klocale.h>
57 #include <kmenu.h>
58 #include <kmenubar.h>
59 #include <kmessagebox.h>
60 #include <konqmimedata.h>
61 #include <konq_operations.h>
62 #include <kpropertiesdialog.h>
63 #include <kprotocolinfo.h>
64 #include <ktoggleaction.h>
65 #include <krun.h>
66 #include <kshell.h>
67 #include <kstandarddirs.h>
68 #include <kstatusbar.h>
69 #include <kstandardaction.h>
70 #include <kurl.h>
71
72 #include <QtGui/QKeyEvent>
73 #include <QtGui/QClipboard>
74 #include <QtGui/QSplitter>
75 #include <QtGui/QDockWidget>
76
77 DolphinMainWindow::DolphinMainWindow(int id) :
78 KXmlGuiWindow(0),
79 m_newMenu(0),
80 m_showMenuBar(0),
81 m_splitter(0),
82 m_activeViewContainer(0),
83 m_id(id)
84 {
85 setObjectName("Dolphin");
86 m_viewContainer[PrimaryView] = 0;
87 m_viewContainer[SecondaryView] = 0;
88
89 new MainWindowAdaptor(this);
90 QDBusConnection::sessionBus().registerObject(QString("/dolphin/MainWindow%1").arg(m_id), this);
91
92 KonqFileUndoManager::incRef();
93
94 KonqFileUndoManager* undoManager = KonqFileUndoManager::self();
95 undoManager->setUiInterface(new UndoUiInterface(this));
96
97 connect(undoManager, SIGNAL(undoAvailable(bool)),
98 this, SLOT(slotUndoAvailable(bool)));
99 connect(undoManager, SIGNAL(undoTextChanged(const QString&)),
100 this, SLOT(slotUndoTextChanged(const QString&)));
101 connect(DolphinSettings::instance().placesModel(), SIGNAL(errorMessage(const QString&)),
102 this, SLOT(slotHandlePlacesError(const QString&)));
103 }
104
105 DolphinMainWindow::~DolphinMainWindow()
106 {
107 KonqFileUndoManager::decRef();
108 DolphinApplication::app()->removeMainWindow(this);
109 }
110
111 void DolphinMainWindow::toggleViews()
112 {
113 if (m_viewContainer[SecondaryView] == 0) {
114 return;
115 }
116
117 // move secondary view from the last position of the splitter
118 // to the first position
119 m_splitter->insertWidget(0, m_viewContainer[SecondaryView]);
120
121 DolphinViewContainer* container = m_viewContainer[PrimaryView];
122 m_viewContainer[PrimaryView] = m_viewContainer[SecondaryView];
123 m_viewContainer[SecondaryView] = container;
124 }
125
126 void DolphinMainWindow::slotDoingOperation(KonqFileUndoManager::CommandType commandType)
127 {
128 clearStatusBar();
129 m_undoCommandTypes.append(commandType);
130 }
131
132 void DolphinMainWindow::refreshViews()
133 {
134 Q_ASSERT(m_viewContainer[PrimaryView] != 0);
135
136 // remember the current active view, as because of
137 // the refreshing the active view might change to
138 // the secondary view
139 DolphinViewContainer* activeViewContainer = m_activeViewContainer;
140
141 m_viewContainer[PrimaryView]->view()->refresh();
142 if (m_viewContainer[SecondaryView] != 0) {
143 m_viewContainer[SecondaryView]->view()->refresh();
144 }
145
146 setActiveViewContainer(activeViewContainer);
147 }
148
149 void DolphinMainWindow::dropUrls(const KUrl::List& urls,
150 const KUrl& destination)
151 {
152 kDebug() << "Source" << urls;
153 kDebug() << "Destination:" << destination;
154
155 Qt::DropAction action = Qt::CopyAction;
156
157 Qt::KeyboardModifiers modifier = QApplication::keyboardModifiers();
158 const bool shiftPressed = modifier & Qt::ShiftModifier;
159 const bool controlPressed = modifier & Qt::ControlModifier;
160 if (shiftPressed && controlPressed) {
161 // shortcut for 'Link Here' is used
162 action = Qt::LinkAction;
163 } else if (shiftPressed) {
164 // shortcut for 'Move Here' is used
165 action = Qt::MoveAction;
166 } else if (controlPressed) {
167 // shortcut for 'Copy Here' is used
168 action = Qt::CopyAction;
169 } else {
170 // open a context menu which offers the following actions:
171 // - Move Here
172 // - Copy Here
173 // - Link Here
174 // - Cancel
175
176 KMenu popup(this);
177
178 QString seq = QKeySequence(Qt::ShiftModifier).toString();
179 seq.chop(1); // chop superfluous '+'
180 QAction* moveAction = popup.addAction(KIcon("go-jump"),
181 i18nc("@action:inmenu",
182 "&Move Here\t<shortcut>%1</shortcut>", seq));
183
184 seq = QKeySequence(Qt::ControlModifier).toString();
185 seq.chop(1);
186 QAction* copyAction = popup.addAction(KIcon("edit-copy"),
187 i18nc("@action:inmenu",
188 "&Copy Here\t<shortcut>%1</shortcut>", seq));
189
190 seq = QKeySequence(Qt::ControlModifier + Qt::ShiftModifier).toString();
191 seq.chop(1);
192 QAction* linkAction = popup.addAction(KIcon("insert-link"),
193 i18nc("@action:inmenu",
194 "&Link Here\t<shortcut>%1</shortcut>", seq));
195
196 popup.addSeparator();
197 popup.addAction(KIcon("process-stop"), i18nc("@action:inmenu", "Cancel"));
198
199 QAction* activatedAction = popup.exec(QCursor::pos());
200 if (activatedAction == moveAction) {
201 action = Qt::MoveAction;
202 } else if (activatedAction == copyAction) {
203 action = Qt::CopyAction;
204 } else if (activatedAction == linkAction) {
205 action = Qt::LinkAction;
206 } else {
207 return;
208 }
209 }
210
211 switch (action) {
212 case Qt::MoveAction:
213 moveUrls(urls, destination);
214 break;
215
216 case Qt::CopyAction:
217 copyUrls(urls, destination);
218 break;
219
220 case Qt::LinkAction:
221 linkUrls(urls, destination);
222 break;
223
224 default:
225 break;
226 }
227 }
228
229 void DolphinMainWindow::changeUrl(const KUrl& url)
230 {
231 DolphinViewContainer* view = activeViewContainer();
232 if (view != 0) {
233 view->setUrl(url);
234 updateEditActions();
235 updateViewActions();
236 updateGoActions();
237 setCaption(url.fileName());
238 emit urlChanged(url);
239 }
240 }
241
242 void DolphinMainWindow::changeSelection(const KFileItemList& selection)
243 {
244 activeViewContainer()->view()->changeSelection(selection);
245 }
246
247 void DolphinMainWindow::slotViewModeChanged()
248 {
249 updateViewActions();
250 }
251
252 void DolphinMainWindow::slotShowPreviewChanged()
253 {
254 // It is not enough to update the 'Show Preview' action, also
255 // the 'Zoom In' and 'Zoom Out' actions must be adapted.
256 updateViewActions();
257 }
258
259 void DolphinMainWindow::slotShowHiddenFilesChanged()
260 {
261 KToggleAction* showHiddenFilesAction =
262 static_cast<KToggleAction*>(actionCollection()->action("show_hidden_files"));
263 const DolphinView* view = m_activeViewContainer->view();
264 showHiddenFilesAction->setChecked(view->showHiddenFiles());
265 }
266
267 void DolphinMainWindow::slotCategorizedSortingChanged()
268 {
269 KToggleAction* showInGroupsAction =
270 static_cast<KToggleAction*>(actionCollection()->action("show_in_groups"));
271 const DolphinView* view = m_activeViewContainer->view();
272 showInGroupsAction->setChecked(view->categorizedSorting());
273 showInGroupsAction->setEnabled(view->supportsCategorizedSorting());
274 }
275
276 void DolphinMainWindow::slotSortingChanged(DolphinView::Sorting sorting)
277 {
278 QAction* action = 0;
279 switch (sorting) {
280 case DolphinView::SortByName:
281 action = actionCollection()->action("sort_by_name");
282 break;
283 case DolphinView::SortBySize:
284 action = actionCollection()->action("sort_by_size");
285 break;
286 case DolphinView::SortByDate:
287 action = actionCollection()->action("sort_by_date");
288 break;
289 case DolphinView::SortByPermissions:
290 action = actionCollection()->action("sort_by_permissions");
291 break;
292 case DolphinView::SortByOwner:
293 action = actionCollection()->action("sort_by_owner");
294 break;
295 case DolphinView::SortByGroup:
296 action = actionCollection()->action("sort_by_group");
297 break;
298 case DolphinView::SortByType:
299 action = actionCollection()->action("sort_by_type");
300 break;
301 #ifdef HAVE_NEPOMUK
302 case DolphinView::SortByRating:
303 action = actionCollection()->action("sort_by_rating");
304 break;
305 case DolphinView::SortByTags:
306 action = actionCollection()->action("sort_by_tags");
307 break;
308 #endif
309 default:
310 break;
311 }
312
313 if (action != 0) {
314 KToggleAction* toggleAction = static_cast<KToggleAction*>(action);
315 toggleAction->setChecked(true);
316 }
317 }
318
319 void DolphinMainWindow::slotSortOrderChanged(Qt::SortOrder order)
320 {
321 KToggleAction* descending = static_cast<KToggleAction*>(actionCollection()->action("descending"));
322 const bool sortDescending = (order == Qt::DescendingOrder);
323 descending->setChecked(sortDescending);
324 }
325
326 void DolphinMainWindow::slotAdditionalInfoChanged(KFileItemDelegate::InformationList list)
327 {
328 QAction* showSizeInfo = actionCollection()->action("show_size_info");
329 QAction* showDateInfo = actionCollection()->action("show_date_info");
330 QAction* showPermissionsInfo = actionCollection()->action("show_permissions_info");
331 QAction* showOwnerInfo = actionCollection()->action("show_owner_info");
332 QAction* showGroupInfo = actionCollection()->action("show_group_info");
333 QAction* showMimeInfo = actionCollection()->action("show_mime_info");
334
335 showSizeInfo->setChecked(false);
336 showDateInfo->setChecked(false);
337 showPermissionsInfo->setChecked(false);
338 showOwnerInfo->setChecked(false);
339 showGroupInfo->setChecked(false);
340 showMimeInfo->setChecked(false);
341
342 const DolphinView* view = m_activeViewContainer->view();
343
344 // currently the column view does not support additional information
345 const bool enable = (view->mode() != DolphinView::ColumnView);
346 showSizeInfo->setEnabled(enable);
347 showDateInfo->setEnabled(enable);
348 showPermissionsInfo->setEnabled(enable);
349 showOwnerInfo->setEnabled(enable);
350 showGroupInfo->setEnabled(enable);
351 showMimeInfo->setEnabled(enable);
352
353 foreach (KFileItemDelegate::Information info, list) {
354 switch (info) {
355 case KFileItemDelegate::Size:
356 showSizeInfo->setChecked(true);
357 break;
358 case KFileItemDelegate::ModificationTime:
359 showDateInfo->setChecked(true);
360 break;
361 case KFileItemDelegate::Permissions:
362 showPermissionsInfo->setChecked(true);
363 break;
364 case KFileItemDelegate::Owner:
365 showOwnerInfo->setChecked(true);
366 break;
367 case KFileItemDelegate::OwnerAndGroup:
368 showGroupInfo->setChecked(true);
369 break;
370 case KFileItemDelegate::FriendlyMimeType:
371 showMimeInfo->setChecked(true);
372 break;
373 default:
374 break;
375 }
376 }
377 }
378
379 void DolphinMainWindow::slotSelectionChanged(const KFileItemList& selection)
380 {
381 updateEditActions();
382
383 Q_ASSERT(m_viewContainer[PrimaryView] != 0);
384 int selectedUrlsCount = m_viewContainer[PrimaryView]->view()->selectedUrls().count();
385 if (m_viewContainer[SecondaryView] != 0) {
386 selectedUrlsCount += m_viewContainer[SecondaryView]->view()->selectedUrls().count();
387 }
388
389 QAction* compareFilesAction = actionCollection()->action("compare_files");
390 compareFilesAction->setEnabled(selectedUrlsCount == 2);
391
392 m_activeViewContainer->updateStatusBar();
393
394 emit selectionChanged(selection);
395 }
396
397 void DolphinMainWindow::slotRequestItemInfo(const KFileItem& item)
398 {
399 emit requestItemInfo(item);
400 }
401
402 void DolphinMainWindow::slotHistoryChanged()
403 {
404 updateHistory();
405 }
406
407 void DolphinMainWindow::updateFilterBarAction(bool show)
408 {
409 KToggleAction* showFilterBarAction =
410 static_cast<KToggleAction*>(actionCollection()->action("show_filter_bar"));
411 showFilterBarAction->setChecked(show);
412 }
413
414 void DolphinMainWindow::openNewMainWindow()
415 {
416 DolphinApplication::app()->createMainWindow()->show();
417 }
418
419 void DolphinMainWindow::toggleActiveView()
420 {
421 if (m_viewContainer[SecondaryView] == 0) {
422 // only one view is available
423 return;
424 }
425
426 Q_ASSERT(m_activeViewContainer != 0);
427 Q_ASSERT(m_viewContainer[PrimaryView] != 0);
428
429 DolphinViewContainer* left = m_viewContainer[PrimaryView];
430 DolphinViewContainer* right = m_viewContainer[SecondaryView];
431 setActiveViewContainer(m_activeViewContainer == right ? left : right);
432 }
433
434 void DolphinMainWindow::closeEvent(QCloseEvent* event)
435 {
436 DolphinSettings& settings = DolphinSettings::instance();
437 GeneralSettings* generalSettings = settings.generalSettings();
438 generalSettings->setFirstRun(false);
439
440 settings.save();
441
442 KXmlGuiWindow::closeEvent(event);
443 }
444
445 void DolphinMainWindow::saveProperties(KConfig* config)
446 {
447 KConfigGroup primaryView = config->group("Primary view");
448 primaryView.writeEntry("Url", m_viewContainer[PrimaryView]->url().url());
449 primaryView.writeEntry("Editable Url", m_viewContainer[PrimaryView]->isUrlEditable());
450 if (m_viewContainer[SecondaryView] != 0) {
451 KConfigGroup secondaryView = config->group("Secondary view");
452 secondaryView.writeEntry("Url", m_viewContainer[SecondaryView]->url().url());
453 secondaryView.writeEntry("Editable Url", m_viewContainer[SecondaryView]->isUrlEditable());
454 }
455 }
456
457 void DolphinMainWindow::readProperties(KConfig* config)
458 {
459 const KConfigGroup primaryViewGroup = config->group("Primary view");
460 m_viewContainer[PrimaryView]->setUrl(primaryViewGroup.readEntry("Url"));
461 bool editable = primaryViewGroup.readEntry("Editable Url", false);
462 m_viewContainer[PrimaryView]->urlNavigator()->setUrlEditable(editable);
463
464 if (config->hasGroup("Secondary view")) {
465 const KConfigGroup secondaryViewGroup = config->group("Secondary view");
466 if (m_viewContainer[PrimaryView] == 0) {
467 toggleSplitView();
468 }
469 m_viewContainer[PrimaryView]->setUrl(secondaryViewGroup.readEntry("Url"));
470 editable = secondaryViewGroup.readEntry("Editable Url", false);
471 m_viewContainer[PrimaryView]->urlNavigator()->setUrlEditable(editable);
472 } else if (m_viewContainer[SecondaryView] != 0) {
473 toggleSplitView();
474 }
475 }
476
477 void DolphinMainWindow::updateNewMenu()
478 {
479 m_newMenu->slotCheckUpToDate();
480 m_newMenu->setPopupFiles(activeViewContainer()->url());
481 }
482
483 void DolphinMainWindow::rename()
484 {
485 clearStatusBar();
486 m_activeViewContainer->view()->renameSelectedItems();
487 }
488
489 void DolphinMainWindow::moveToTrash()
490 {
491 clearStatusBar();
492
493 DolphinView* view = m_activeViewContainer->view();
494
495 if (QApplication::keyboardModifiers() & Qt::ShiftModifier) {
496 view->deleteSelectedItems();
497 } else {
498 view->trashSelectedItems();
499 }
500 }
501
502 void DolphinMainWindow::deleteItems()
503 {
504 clearStatusBar();
505 m_activeViewContainer->view()->deleteSelectedItems();
506 }
507
508 void DolphinMainWindow::properties()
509 {
510 const KFileItemList list = m_activeViewContainer->view()->selectedItems();
511
512 KPropertiesDialog dialog(list, this);
513 dialog.exec();
514 }
515
516 void DolphinMainWindow::quit()
517 {
518 close();
519 }
520
521 void DolphinMainWindow::slotHandlePlacesError(const QString &message)
522 {
523 if (!message.isEmpty()) {
524 DolphinStatusBar* statusBar = m_activeViewContainer->statusBar();
525 statusBar->setMessage(message, DolphinStatusBar::Error);
526 }
527 }
528
529 void DolphinMainWindow::slotUndoAvailable(bool available)
530 {
531 QAction* undoAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Undo));
532 if (undoAction != 0) {
533 undoAction->setEnabled(available);
534 }
535
536 if (available && (m_undoCommandTypes.count() > 0)) {
537 const KonqFileUndoManager::CommandType command = m_undoCommandTypes.takeFirst();
538 DolphinStatusBar* statusBar = m_activeViewContainer->statusBar();
539 switch (command) {
540 case KonqFileUndoManager::COPY:
541 statusBar->setMessage(i18nc("@info:status", "Copy operation completed."),
542 DolphinStatusBar::OperationCompleted);
543 break;
544 case KonqFileUndoManager::MOVE:
545 statusBar->setMessage(i18nc("@info:status", "Move operation completed."),
546 DolphinStatusBar::OperationCompleted);
547 break;
548 case KonqFileUndoManager::LINK:
549 statusBar->setMessage(i18nc("@info:status", "Link operation completed."),
550 DolphinStatusBar::OperationCompleted);
551 break;
552 case KonqFileUndoManager::TRASH:
553 statusBar->setMessage(i18nc("@info:status", "Move to trash operation completed."),
554 DolphinStatusBar::OperationCompleted);
555 break;
556 case KonqFileUndoManager::RENAME:
557 statusBar->setMessage(i18nc("@info:status", "Renaming operation completed."),
558 DolphinStatusBar::OperationCompleted);
559 break;
560
561 case KonqFileUndoManager::MKDIR:
562 statusBar->setMessage(i18nc("@info:status", "Created folder."),
563 DolphinStatusBar::OperationCompleted);
564 break;
565
566 default:
567 break;
568 }
569
570 }
571 }
572
573 void DolphinMainWindow::slotUndoTextChanged(const QString& text)
574 {
575 QAction* undoAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Undo));
576 if (undoAction != 0) {
577 undoAction->setText(text);
578 }
579 }
580
581 void DolphinMainWindow::undo()
582 {
583 clearStatusBar();
584 KonqFileUndoManager::self()->undo();
585 }
586
587 void DolphinMainWindow::cut()
588 {
589 m_activeViewContainer->view()->cutSelectedItems();
590 }
591
592 void DolphinMainWindow::copy()
593 {
594 m_activeViewContainer->view()->copySelectedItems();
595 }
596
597 void DolphinMainWindow::paste()
598 {
599 m_activeViewContainer->view()->paste();
600 }
601
602 void DolphinMainWindow::updatePasteAction()
603 {
604 QAction* pasteAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Paste));
605 if (pasteAction == 0) {
606 return;
607 }
608
609 QPair<bool, QString> pasteInfo = m_activeViewContainer->view()->pasteInfo();
610 pasteAction->setEnabled(pasteInfo.first);
611 pasteAction->setText(pasteInfo.second);
612 }
613
614 void DolphinMainWindow::selectAll()
615 {
616 clearStatusBar();
617 m_activeViewContainer->view()->selectAll();
618 }
619
620 void DolphinMainWindow::invertSelection()
621 {
622 clearStatusBar();
623 m_activeViewContainer->view()->invertSelection();
624 }
625
626 void DolphinMainWindow::setViewMode(QAction* action)
627 {
628 const DolphinView::Mode mode = action->data().value<DolphinView::Mode>();
629 m_activeViewContainer->view()->setMode(mode);
630 }
631
632 void DolphinMainWindow::sortByName()
633 {
634 m_activeViewContainer->view()->setSorting(DolphinView::SortByName);
635 }
636
637 void DolphinMainWindow::sortBySize()
638 {
639 m_activeViewContainer->view()->setSorting(DolphinView::SortBySize);
640 }
641
642 void DolphinMainWindow::sortByDate()
643 {
644 m_activeViewContainer->view()->setSorting(DolphinView::SortByDate);
645 }
646
647 void DolphinMainWindow::sortByPermissions()
648 {
649 m_activeViewContainer->view()->setSorting(DolphinView::SortByPermissions);
650 }
651
652 void DolphinMainWindow::sortByOwner()
653 {
654 m_activeViewContainer->view()->setSorting(DolphinView::SortByOwner);
655 }
656
657 void DolphinMainWindow::sortByGroup()
658 {
659 m_activeViewContainer->view()->setSorting(DolphinView::SortByGroup);
660 }
661
662 void DolphinMainWindow::sortByType()
663 {
664 m_activeViewContainer->view()->setSorting(DolphinView::SortByType);
665 }
666
667 void DolphinMainWindow::sortByRating()
668 {
669 #ifdef HAVE_NEPOMUK
670 m_activeViewContainer->view()->setSorting(DolphinView::SortByRating);
671 #endif
672 }
673
674 void DolphinMainWindow::sortByTags()
675 {
676 #ifdef HAVE_NEPOMUK
677 m_activeViewContainer->view()->setSorting(DolphinView::SortByTags);
678 #endif
679 }
680
681 void DolphinMainWindow::toggleSortOrder()
682 {
683 DolphinView* view = m_activeViewContainer->view();
684 const Qt::SortOrder order = (view->sortOrder() == Qt::AscendingOrder) ?
685 Qt::DescendingOrder :
686 Qt::AscendingOrder;
687 view->setSortOrder(order);
688 }
689
690 void DolphinMainWindow::toggleSortCategorization()
691 {
692 DolphinView* view = m_activeViewContainer->view();
693 const bool categorizedSorting = view->categorizedSorting();
694 view->setCategorizedSorting(!categorizedSorting);
695 }
696
697 void DolphinMainWindow::toggleSizeInfo()
698 {
699 toggleAdditionalInfo("show_size_info", KFileItemDelegate::Size);
700 }
701
702 void DolphinMainWindow::toggleDateInfo()
703 {
704 toggleAdditionalInfo("show_date_info", KFileItemDelegate::ModificationTime);
705 }
706
707 void DolphinMainWindow::togglePermissionsInfo()
708 {
709 toggleAdditionalInfo("show_permissions_info", KFileItemDelegate::Permissions);
710 }
711
712 void DolphinMainWindow::toggleOwnerInfo()
713 {
714 toggleAdditionalInfo("show_owner_info", KFileItemDelegate::Owner);
715 }
716
717 void DolphinMainWindow::toggleGroupInfo()
718 {
719 toggleAdditionalInfo("show_group_info", KFileItemDelegate::OwnerAndGroup);
720 }
721
722 void DolphinMainWindow::toggleMimeInfo()
723 {
724 toggleAdditionalInfo("show_mime_info", KFileItemDelegate::FriendlyMimeType);
725 }
726
727 void DolphinMainWindow::toggleSplitView()
728 {
729 if (m_viewContainer[SecondaryView] == 0) {
730 // create a secondary view
731 const int newWidth = (m_viewContainer[PrimaryView]->width() - m_splitter->handleWidth()) / 2;
732
733 const DolphinView* view = m_viewContainer[PrimaryView]->view();
734 m_viewContainer[SecondaryView] = new DolphinViewContainer(this, 0, view->rootUrl());
735 connectViewSignals(SecondaryView);
736 m_splitter->addWidget(m_viewContainer[SecondaryView]);
737 m_splitter->setSizes(QList<int>() << newWidth << newWidth);
738 m_viewContainer[SecondaryView]->view()->reload();
739 m_viewContainer[SecondaryView]->setActive(false);
740 m_viewContainer[SecondaryView]->show();
741 } else if (m_activeViewContainer == m_viewContainer[PrimaryView]) {
742 // remove secondary view
743 m_viewContainer[SecondaryView]->close();
744 m_viewContainer[SecondaryView]->deleteLater();
745 m_viewContainer[SecondaryView] = 0;
746 } else {
747 // The secondary view is active, hence from a users point of view
748 // the content of the secondary view should be moved to the primary view.
749 // From an implementation point of view it is more efficient to close
750 // the primary view and exchange the internal pointers afterwards.
751 m_viewContainer[PrimaryView]->close();
752 m_viewContainer[PrimaryView]->deleteLater();
753 m_viewContainer[PrimaryView] = m_viewContainer[SecondaryView];
754 m_viewContainer[SecondaryView] = 0;
755 }
756
757 setActiveViewContainer(m_viewContainer[PrimaryView]);
758 updateViewActions();
759 emit activeViewChanged();
760 }
761
762 void DolphinMainWindow::reloadView()
763 {
764 clearStatusBar();
765 m_activeViewContainer->view()->reload();
766 }
767
768 void DolphinMainWindow::stopLoading()
769 {
770 }
771
772 void DolphinMainWindow::togglePreview()
773 {
774 clearStatusBar();
775
776 const KToggleAction* showPreviewAction =
777 static_cast<KToggleAction*>(actionCollection()->action("show_preview"));
778 const bool show = showPreviewAction->isChecked();
779 m_activeViewContainer->view()->setShowPreview(show);
780 }
781
782 void DolphinMainWindow::toggleShowHiddenFiles()
783 {
784 clearStatusBar();
785
786 const KToggleAction* showHiddenFilesAction =
787 static_cast<KToggleAction*>(actionCollection()->action("show_hidden_files"));
788 const bool show = showHiddenFilesAction->isChecked();
789 m_activeViewContainer->view()->setShowHiddenFiles(show);
790 }
791
792 void DolphinMainWindow::toggleFilterBarVisibility()
793 {
794 const KToggleAction* showFilterBarAction =
795 static_cast<KToggleAction*>(actionCollection()->action("show_filter_bar"));
796 const bool show = showFilterBarAction->isChecked();
797 m_activeViewContainer->showFilterBar(show);
798 }
799
800 void DolphinMainWindow::zoomIn()
801 {
802 m_activeViewContainer->view()->zoomIn();
803 updateViewActions();
804 }
805
806 void DolphinMainWindow::zoomOut()
807 {
808 m_activeViewContainer->view()->zoomOut();
809 updateViewActions();
810 }
811
812 void DolphinMainWindow::toggleEditLocation()
813 {
814 clearStatusBar();
815
816 KToggleAction* action = static_cast<KToggleAction*>(actionCollection()->action("editable_location"));
817
818 bool editOrBrowse = action->isChecked();
819 KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
820 urlNavigator->setUrlEditable(editOrBrowse);
821 }
822
823 void DolphinMainWindow::editLocation()
824 {
825 KUrlNavigator* navigator = m_activeViewContainer->urlNavigator();
826 navigator->setUrlEditable(true);
827 navigator->setFocus();
828 }
829
830 void DolphinMainWindow::adjustViewProperties()
831 {
832 clearStatusBar();
833 ViewPropertiesDialog dlg(m_activeViewContainer->view());
834 dlg.exec();
835 }
836
837 void DolphinMainWindow::goBack()
838 {
839 clearStatusBar();
840 m_activeViewContainer->urlNavigator()->goBack();
841 }
842
843 void DolphinMainWindow::goForward()
844 {
845 clearStatusBar();
846 m_activeViewContainer->urlNavigator()->goForward();
847 }
848
849 void DolphinMainWindow::goUp()
850 {
851 clearStatusBar();
852 m_activeViewContainer->urlNavigator()->goUp();
853 }
854
855 void DolphinMainWindow::goHome()
856 {
857 clearStatusBar();
858 m_activeViewContainer->urlNavigator()->goHome();
859 }
860
861 void DolphinMainWindow::findFile()
862 {
863 KRun::run("kfind", m_activeViewContainer->url(), this);
864 }
865
866 void DolphinMainWindow::compareFiles()
867 {
868 // The method is only invoked if exactly 2 files have
869 // been selected. The selected files may be:
870 // - both in the primary view
871 // - both in the secondary view
872 // - one in the primary view and the other in the secondary
873 // view
874 Q_ASSERT(m_viewContainer[PrimaryView] != 0);
875
876 KUrl urlA;
877 KUrl urlB;
878 KUrl::List urls = m_viewContainer[PrimaryView]->view()->selectedUrls();
879
880 switch (urls.count()) {
881 case 0: {
882 Q_ASSERT(m_viewContainer[SecondaryView] != 0);
883 urls = m_viewContainer[SecondaryView]->view()->selectedUrls();
884 Q_ASSERT(urls.count() == 2);
885 urlA = urls[0];
886 urlB = urls[1];
887 break;
888 }
889
890 case 1: {
891 urlA = urls[0];
892 Q_ASSERT(m_viewContainer[SecondaryView] != 0);
893 urls = m_viewContainer[SecondaryView]->view()->selectedUrls();
894 Q_ASSERT(urls.count() == 1);
895 urlB = urls[0];
896 break;
897 }
898
899 case 2: {
900 urlA = urls[0];
901 urlB = urls[1];
902 break;
903 }
904
905 default: {
906 // may not happen: compareFiles may only get invoked if 2
907 // files are selected
908 Q_ASSERT(false);
909 }
910 }
911
912 QString command("kompare -c \"");
913 command.append(urlA.pathOrUrl());
914 command.append("\" \"");
915 command.append(urlB.pathOrUrl());
916 command.append('\"');
917 KRun::runCommand(command, "Kompare", "kompare", this);
918
919 }
920
921 void DolphinMainWindow::toggleShowMenuBar()
922 {
923 const bool visible = menuBar()->isVisible();
924 menuBar()->setVisible(!visible);
925 }
926
927 void DolphinMainWindow::editSettings()
928 {
929 DolphinSettingsDialog dialog(this);
930 dialog.exec();
931 }
932
933 void DolphinMainWindow::init()
934 {
935 // Check whether Dolphin runs the first time. If yes then
936 // a proper default window size is given at the end of DolphinMainWindow::init().
937 GeneralSettings* generalSettings = DolphinSettings::instance().generalSettings();
938 const bool firstRun = generalSettings->firstRun();
939 if (firstRun) {
940 generalSettings->setViewPropsTimestamp(QDateTime::currentDateTime());
941 }
942
943 setAcceptDrops(true);
944
945 m_splitter = new QSplitter(this);
946
947 DolphinSettings& settings = DolphinSettings::instance();
948
949 setupActions();
950
951 const KUrl& homeUrl = settings.generalSettings()->homeUrl();
952 setCaption(homeUrl.fileName());
953 ViewProperties props(homeUrl);
954 m_viewContainer[PrimaryView] = new DolphinViewContainer(this,
955 m_splitter,
956 homeUrl);
957
958 m_activeViewContainer = m_viewContainer[PrimaryView];
959 connectViewSignals(PrimaryView);
960 m_viewContainer[PrimaryView]->view()->reload();
961 m_viewContainer[PrimaryView]->show();
962
963 setCentralWidget(m_splitter);
964 setupDockWidgets();
965
966 setupGUI(Keys | Save | Create | ToolBar);
967 createGUI();
968
969 stateChanged("new_file");
970 setAutoSaveSettings();
971
972 QClipboard* clipboard = QApplication::clipboard();
973 connect(clipboard, SIGNAL(dataChanged()),
974 this, SLOT(updatePasteAction()));
975 updatePasteAction();
976 updateGoActions();
977
978 if (generalSettings->splitView()) {
979 toggleSplitView();
980 }
981 updateViewActions();
982
983 if (firstRun) {
984 // assure a proper default size if Dolphin runs the first time
985 resize(700, 500);
986 }
987
988 emit urlChanged(homeUrl);
989 }
990
991 void DolphinMainWindow::setActiveViewContainer(DolphinViewContainer* view)
992 {
993 Q_ASSERT(view != 0);
994 Q_ASSERT((view == m_viewContainer[PrimaryView]) || (view == m_viewContainer[SecondaryView]));
995 if (m_activeViewContainer == view) {
996 return;
997 }
998
999 m_activeViewContainer->setActive(false);
1000 m_activeViewContainer = view;
1001 m_activeViewContainer->setActive(true);
1002
1003 updateHistory();
1004 updateEditActions();
1005 updateViewActions();
1006 updateGoActions();
1007
1008 const KUrl& url = m_activeViewContainer->url();
1009 setCaption(url.fileName());
1010
1011 emit activeViewChanged();
1012 emit urlChanged(url);
1013 }
1014
1015 void DolphinMainWindow::setupActions()
1016 {
1017 // setup 'File' menu
1018 m_newMenu = new DolphinNewMenu(this);
1019 KMenu* menu = m_newMenu->menu();
1020 menu->setTitle(i18nc("@title:menu", "Create New"));
1021 menu->setIcon(KIcon("document-new"));
1022 connect(menu, SIGNAL(aboutToShow()),
1023 this, SLOT(updateNewMenu()));
1024
1025 KAction* newWindow = actionCollection()->addAction("new_window");
1026 newWindow->setIcon(KIcon("window-new"));
1027 newWindow->setText(i18nc("@action:inmenu File", "New &Window"));
1028 newWindow->setShortcut(Qt::CTRL | Qt::Key_N);
1029 connect(newWindow, SIGNAL(triggered()), this, SLOT(openNewMainWindow()));
1030
1031 KAction* rename = DolphinView::createRenameAction(actionCollection());
1032 connect(rename, SIGNAL(triggered()), this, SLOT(rename()));
1033
1034 KAction* moveToTrash = DolphinView::createMoveToTrashAction(actionCollection());
1035 connect(moveToTrash, SIGNAL(triggered()), this, SLOT(moveToTrash()));
1036
1037 KAction* deleteAction = DolphinView::createDeleteAction(actionCollection());
1038 connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteItems()));
1039
1040 KAction* properties = actionCollection()->addAction("properties");
1041 properties->setText(i18nc("@action:inmenu File", "Properties"));
1042 properties->setShortcut(Qt::ALT | Qt::Key_Return);
1043 connect(properties, SIGNAL(triggered()), this, SLOT(properties()));
1044
1045 KStandardAction::quit(this, SLOT(quit()), actionCollection());
1046
1047 // setup 'Edit' menu
1048 KStandardAction::undo(this,
1049 SLOT(undo()),
1050 actionCollection());
1051
1052 //Need to remove shift+del from cut action, else the shortcut for deletejob
1053 //doesn't work
1054 KAction* cut = KStandardAction::cut(this, SLOT(cut()), actionCollection());
1055 KShortcut cutShortcut = cut->shortcut();
1056 cutShortcut.remove(Qt::SHIFT + Qt::Key_Delete, KShortcut::KeepEmpty);
1057 cut->setShortcut(cutShortcut);
1058 KStandardAction::copy(this, SLOT(copy()), actionCollection());
1059 KStandardAction::paste(this, SLOT(paste()), actionCollection());
1060
1061 KAction* selectAll = actionCollection()->addAction("select_all");
1062 selectAll->setText(i18nc("@action:inmenu Edit", "Select All"));
1063 selectAll->setShortcut(Qt::CTRL + Qt::Key_A);
1064 connect(selectAll, SIGNAL(triggered()), this, SLOT(selectAll()));
1065
1066 KAction* invertSelection = actionCollection()->addAction("invert_selection");
1067 invertSelection->setText(i18nc("@action:inmenu Edit", "Invert Selection"));
1068 invertSelection->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_A);
1069 connect(invertSelection, SIGNAL(triggered()), this, SLOT(invertSelection()));
1070
1071 // setup 'View' menu
1072 KStandardAction::zoomIn(this,
1073 SLOT(zoomIn()),
1074 actionCollection());
1075
1076 KStandardAction::zoomOut(this,
1077 SLOT(zoomOut()),
1078 actionCollection());
1079
1080
1081 KToggleAction* iconsView = DolphinView::iconsModeAction(actionCollection());
1082 KToggleAction* detailsView = DolphinView::detailsModeAction(actionCollection());
1083 KToggleAction* columnView = DolphinView::columnsModeAction(actionCollection());
1084
1085 QActionGroup* viewModeGroup = new QActionGroup(this);
1086 viewModeGroup->addAction(iconsView);
1087 viewModeGroup->addAction(detailsView);
1088 viewModeGroup->addAction(columnView);
1089 connect(viewModeGroup, SIGNAL(triggered(QAction*)), this, SLOT(setViewMode(QAction*)));
1090
1091 KToggleAction* sortByName = actionCollection()->add<KToggleAction>("sort_by_name");
1092 sortByName->setText(i18nc("@action:inmenu Sort By", "Name"));
1093 connect(sortByName, SIGNAL(triggered()), this, SLOT(sortByName()));
1094
1095 KToggleAction* sortBySize = actionCollection()->add<KToggleAction>("sort_by_size");
1096 sortBySize->setText(i18nc("@action:inmenu Sort By", "Size"));
1097 connect(sortBySize, SIGNAL(triggered()), this, SLOT(sortBySize()));
1098
1099 KToggleAction* sortByDate = actionCollection()->add<KToggleAction>("sort_by_date");
1100 sortByDate->setText(i18nc("@action:inmenu Sort By", "Date"));
1101 connect(sortByDate, SIGNAL(triggered()), this, SLOT(sortByDate()));
1102
1103 KToggleAction* sortByPermissions = actionCollection()->add<KToggleAction>("sort_by_permissions");
1104 sortByPermissions->setText(i18nc("@action:inmenu Sort By", "Permissions"));
1105 connect(sortByPermissions, SIGNAL(triggered()), this, SLOT(sortByPermissions()));
1106
1107 KToggleAction* sortByOwner = actionCollection()->add<KToggleAction>("sort_by_owner");
1108 sortByOwner->setText(i18nc("@action:inmenu Sort By", "Owner"));
1109 connect(sortByOwner, SIGNAL(triggered()), this, SLOT(sortByOwner()));
1110
1111 KToggleAction* sortByGroup = actionCollection()->add<KToggleAction>("sort_by_group");
1112 sortByGroup->setText(i18nc("@action:inmenu Sort By", "Group"));
1113 connect(sortByGroup, SIGNAL(triggered()), this, SLOT(sortByGroup()));
1114
1115 KToggleAction* sortByType = actionCollection()->add<KToggleAction>("sort_by_type");
1116 sortByType->setText(i18nc("@action:inmenu Sort By", "Type"));
1117 connect(sortByType, SIGNAL(triggered()), this, SLOT(sortByType()));
1118
1119 KToggleAction* sortByRating = actionCollection()->add<KToggleAction>("sort_by_rating");
1120 sortByRating->setText(i18nc("@action:inmenu Sort By", "Rating"));
1121
1122 KToggleAction* sortByTags = actionCollection()->add<KToggleAction>("sort_by_tags");
1123 sortByTags->setText(i18nc("@action:inmenu Sort By", "Tags"));
1124
1125 #ifdef HAVE_NEPOMUK
1126 if (MetaDataWidget::metaDataAvailable()) {
1127 connect(sortByRating, SIGNAL(triggered()), this, SLOT(sortByRating()));
1128 connect(sortByTags, SIGNAL(triggered()), this, SLOT(sortByTags()));
1129 }
1130 else {
1131 sortByRating->setEnabled(false);
1132 sortByTags->setEnabled(false);
1133 }
1134 #else
1135 sortByRating->setEnabled(false);
1136 sortByTags->setEnabled(false);
1137 #endif
1138
1139 QActionGroup* sortGroup = new QActionGroup(this);
1140 sortGroup->addAction(sortByName);
1141 sortGroup->addAction(sortBySize);
1142 sortGroup->addAction(sortByDate);
1143 sortGroup->addAction(sortByPermissions);
1144 sortGroup->addAction(sortByOwner);
1145 sortGroup->addAction(sortByGroup);
1146 sortGroup->addAction(sortByType);
1147 sortGroup->addAction(sortByRating);
1148 sortGroup->addAction(sortByTags);
1149
1150 KToggleAction* sortDescending = actionCollection()->add<KToggleAction>("descending");
1151 sortDescending->setText(i18nc("@action:inmenu Sort", "Descending"));
1152 connect(sortDescending, SIGNAL(triggered()), this, SLOT(toggleSortOrder()));
1153
1154 KToggleAction* showInGroups = actionCollection()->add<KToggleAction>("show_in_groups");
1155 showInGroups->setText(i18nc("@action:inmenu View", "Show in Groups"));
1156 connect(showInGroups, SIGNAL(triggered()), this, SLOT(toggleSortCategorization()));
1157
1158 KToggleAction* showSizeInfo = actionCollection()->add<KToggleAction>("show_size_info");
1159 showSizeInfo->setText(i18nc("@action:inmenu Additional information", "Size"));
1160 connect(showSizeInfo, SIGNAL(triggered()), this, SLOT(toggleSizeInfo()));
1161
1162 KToggleAction* showDateInfo = actionCollection()->add<KToggleAction>("show_date_info");
1163 showDateInfo->setText(i18nc("@action:inmenu Additional information", "Date"));
1164 connect(showDateInfo, SIGNAL(triggered()), this, SLOT(toggleDateInfo()));
1165
1166 KToggleAction* showPermissionsInfo = actionCollection()->add<KToggleAction>("show_permissions_info");
1167 showPermissionsInfo->setText(i18nc("@action:inmenu Additional information", "Permissions"));
1168 connect(showPermissionsInfo, SIGNAL(triggered()), this, SLOT(togglePermissionsInfo()));
1169
1170 KToggleAction* showOwnerInfo = actionCollection()->add<KToggleAction>("show_owner_info");
1171 showOwnerInfo->setText(i18nc("@action:inmenu Additional information", "Owner"));
1172 connect(showOwnerInfo, SIGNAL(triggered()), this, SLOT(toggleOwnerInfo()));
1173
1174 KToggleAction* showGroupInfo = actionCollection()->add<KToggleAction>("show_group_info");
1175 showGroupInfo->setText(i18nc("@action:inmenu Additional information", "Group"));
1176 connect(showGroupInfo, SIGNAL(triggered()), this, SLOT(toggleGroupInfo()));
1177
1178 KToggleAction* showMimeInfo = actionCollection()->add<KToggleAction>("show_mime_info");
1179 showMimeInfo->setText(i18nc("@action:inmenu Additional information", "Type"));
1180 connect(showMimeInfo, SIGNAL(triggered()), this, SLOT(toggleMimeInfo()));
1181
1182 KToggleAction* showPreview = actionCollection()->add<KToggleAction>("show_preview");
1183 showPreview->setText(i18nc("@action:intoolbar", "Preview"));
1184 showPreview->setIcon(KIcon("fileview-preview"));
1185 connect(showPreview, SIGNAL(triggered()), this, SLOT(togglePreview()));
1186
1187 KToggleAction* showHiddenFiles = actionCollection()->add<KToggleAction>("show_hidden_files");
1188 showHiddenFiles->setText(i18nc("@action:inmenu View", "Show Hidden Files"));
1189 showHiddenFiles->setShortcut(Qt::ALT | Qt::Key_Period);
1190 connect(showHiddenFiles, SIGNAL(triggered()), this, SLOT(toggleShowHiddenFiles()));
1191
1192 KAction* split = actionCollection()->addAction("split_view");
1193 split->setShortcut(Qt::Key_F10);
1194 updateSplitAction();
1195 connect(split, SIGNAL(triggered()), this, SLOT(toggleSplitView()));
1196
1197 KAction* reload = actionCollection()->addAction("reload");
1198 reload->setText(i18nc("@action:inmenu View", "Reload"));
1199 reload->setShortcut(Qt::Key_F5);
1200 reload->setIcon(KIcon("view-refresh"));
1201 connect(reload, SIGNAL(triggered()), this, SLOT(reloadView()));
1202
1203 KAction* stop = actionCollection()->addAction("stop");
1204 stop->setText(i18nc("@action:inmenu View", "Stop"));
1205 stop->setIcon(KIcon("process-stop"));
1206 connect(stop, SIGNAL(triggered()), this, SLOT(stopLoading()));
1207
1208 // TODO: the URL navigator must emit a signal if the editable state has been
1209 // changed, so that the corresponding showFullLocation action is updated. Also
1210 // the naming "Show full Location" is currently confusing...
1211 KToggleAction* showFullLocation = actionCollection()->add<KToggleAction>("editable_location");
1212 showFullLocation->setText(i18nc("@action:inmenu Navigation Bar", "Show Full Location"));
1213 showFullLocation->setShortcut(Qt::CTRL | Qt::Key_L);
1214 connect(showFullLocation, SIGNAL(triggered()), this, SLOT(toggleEditLocation()));
1215
1216 KAction* editLocation = actionCollection()->addAction("edit_location");
1217 editLocation->setText(i18nc("@action:inmenu Navigation Bar", "Edit Location"));
1218 editLocation->setShortcut(Qt::Key_F6);
1219 connect(editLocation, SIGNAL(triggered()), this, SLOT(editLocation()));
1220
1221 KAction* adjustViewProps = actionCollection()->addAction("view_properties");
1222 adjustViewProps->setText(i18nc("@action:inmenu View", "Adjust View Properties..."));
1223 connect(adjustViewProps, SIGNAL(triggered()), this, SLOT(adjustViewProperties()));
1224
1225 // setup 'Go' menu
1226 KAction* backAction = KStandardAction::back(this, SLOT(goBack()), actionCollection());
1227 KShortcut backShortcut = backAction->shortcut();
1228 backShortcut.setAlternate(Qt::Key_Backspace);
1229 backAction->setShortcut(backShortcut);
1230
1231 KStandardAction::forward(this, SLOT(goForward()), actionCollection());
1232 KStandardAction::up(this, SLOT(goUp()), actionCollection());
1233 KStandardAction::home(this, SLOT(goHome()), actionCollection());
1234
1235 // setup 'Tools' menu
1236 QAction* findFile = actionCollection()->addAction("find_file");
1237 findFile->setText(i18nc("@action:inmenu Tools", "Find File..."));
1238 findFile->setShortcut(Qt::CTRL | Qt::Key_F);
1239 findFile->setIcon(KIcon("edit-find"));
1240 connect(findFile, SIGNAL(triggered()), this, SLOT(findFile()));
1241
1242 KToggleAction* showFilterBar = actionCollection()->add<KToggleAction>("show_filter_bar");
1243 showFilterBar->setText(i18nc("@action:inmenu Tools", "Show Filter Bar"));
1244 showFilterBar->setShortcut(Qt::CTRL | Qt::Key_I);
1245 connect(showFilterBar, SIGNAL(triggered()), this, SLOT(toggleFilterBarVisibility()));
1246
1247 KAction* compareFiles = actionCollection()->addAction("compare_files");
1248 compareFiles->setText(i18nc("@action:inmenu Tools", "Compare Files"));
1249 compareFiles->setIcon(KIcon("kompare"));
1250 compareFiles->setEnabled(false);
1251 connect(compareFiles, SIGNAL(triggered()), this, SLOT(compareFiles()));
1252
1253 // setup 'Settings' menu
1254 m_showMenuBar = KStandardAction::showMenubar(this, SLOT(toggleShowMenuBar()), actionCollection());
1255 KStandardAction::preferences(this, SLOT(editSettings()), actionCollection());
1256 }
1257
1258 void DolphinMainWindow::setupDockWidgets()
1259 {
1260 // setup "Information"
1261 QDockWidget* infoDock = new QDockWidget(i18nc("@title:window", "Information"));
1262 infoDock->setObjectName("infoDock");
1263 infoDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
1264 SidebarPage* infoWidget = new InfoSidebarPage(infoDock);
1265 infoDock->setWidget(infoWidget);
1266
1267 infoDock->toggleViewAction()->setText(i18nc("@title:window", "Information"));
1268 infoDock->toggleViewAction()->setShortcut(Qt::Key_F11);
1269 actionCollection()->addAction("show_info_panel", infoDock->toggleViewAction());
1270
1271 addDockWidget(Qt::RightDockWidgetArea, infoDock);
1272 connect(this, SIGNAL(urlChanged(KUrl)),
1273 infoWidget, SLOT(setUrl(KUrl)));
1274 connect(this, SIGNAL(selectionChanged(KFileItemList)),
1275 infoWidget, SLOT(setSelection(KFileItemList)));
1276 connect(this, SIGNAL(requestItemInfo(KFileItem)),
1277 infoWidget, SLOT(requestDelayedItemInfo(KFileItem)));
1278
1279 // setup "Tree View"
1280 QDockWidget* treeViewDock = new QDockWidget(i18nc("@title:window", "Folders"));
1281 treeViewDock->setObjectName("treeViewDock");
1282 treeViewDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
1283 TreeViewSidebarPage* treeWidget = new TreeViewSidebarPage(treeViewDock);
1284 treeViewDock->setWidget(treeWidget);
1285
1286 treeViewDock->toggleViewAction()->setText(i18nc("@title:window", "Folders"));
1287 treeViewDock->toggleViewAction()->setShortcut(Qt::Key_F7);
1288 actionCollection()->addAction("show_folders_panel", treeViewDock->toggleViewAction());
1289
1290 addDockWidget(Qt::LeftDockWidgetArea, treeViewDock);
1291 connect(this, SIGNAL(urlChanged(KUrl)),
1292 treeWidget, SLOT(setUrl(KUrl)));
1293 connect(treeWidget, SIGNAL(changeUrl(KUrl)),
1294 this, SLOT(changeUrl(KUrl)));
1295 connect(treeWidget, SIGNAL(changeSelection(KFileItemList)),
1296 this, SLOT(changeSelection(KFileItemList)));
1297 connect(treeWidget, SIGNAL(urlsDropped(KUrl::List, KUrl)),
1298 this, SLOT(dropUrls(KUrl::List, KUrl)));
1299
1300 // setup "Terminal"
1301 QDockWidget* terminalDock = new QDockWidget(i18nc("@title:window", "Terminal"));
1302 terminalDock->setObjectName("terminalDock");
1303 terminalDock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
1304 SidebarPage* terminalWidget = new TerminalSidebarPage(terminalDock);
1305 terminalDock->setWidget(terminalWidget);
1306
1307 terminalDock->toggleViewAction()->setText(i18nc("@title:window", "Terminal"));
1308 terminalDock->toggleViewAction()->setShortcut(Qt::Key_F4);
1309 actionCollection()->addAction("show_terminal_panel", terminalDock->toggleViewAction());
1310
1311 addDockWidget(Qt::BottomDockWidgetArea, terminalDock);
1312 connect(this, SIGNAL(urlChanged(KUrl)),
1313 terminalWidget, SLOT(setUrl(KUrl)));
1314
1315 const bool firstRun = DolphinSettings::instance().generalSettings()->firstRun();
1316 if (firstRun) {
1317 infoDock->hide();
1318 treeViewDock->hide();
1319 terminalDock->hide();
1320 }
1321
1322 QDockWidget* placesDock = new QDockWidget(i18nc("@title:window", "Places"));
1323 placesDock->setObjectName("placesDock");
1324 placesDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
1325 KFilePlacesView* placesView = new KFilePlacesView(placesDock);
1326 placesDock->setWidget(placesView);
1327 placesView->setModel(DolphinSettings::instance().placesModel());
1328 placesView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1329
1330 placesDock->toggleViewAction()->setText(i18nc("@title:window", "Places"));
1331 placesDock->toggleViewAction()->setShortcut(Qt::Key_F9);
1332 actionCollection()->addAction("show_places_panel", placesDock->toggleViewAction());
1333
1334 addDockWidget(Qt::LeftDockWidgetArea, placesDock);
1335 connect(placesView, SIGNAL(urlChanged(KUrl)),
1336 this, SLOT(changeUrl(KUrl)));
1337 connect(this, SIGNAL(urlChanged(KUrl)),
1338 placesView, SLOT(setUrl(KUrl)));
1339 }
1340
1341 void DolphinMainWindow::updateHistory()
1342 {
1343 const KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
1344 const int index = urlNavigator->historyIndex();
1345
1346 QAction* backAction = actionCollection()->action("go_back");
1347 if (backAction != 0) {
1348 backAction->setEnabled(index < urlNavigator->historySize() - 1);
1349 }
1350
1351 QAction* forwardAction = actionCollection()->action("go_forward");
1352 if (forwardAction != 0) {
1353 forwardAction->setEnabled(index > 0);
1354 }
1355 }
1356
1357 void DolphinMainWindow::updateEditActions()
1358 {
1359 const KFileItemList list = m_activeViewContainer->view()->selectedItems();
1360 if (list.isEmpty()) {
1361 stateChanged("has_no_selection");
1362 } else {
1363 stateChanged("has_selection");
1364
1365 QAction* renameAction = actionCollection()->action("rename");
1366 if (renameAction != 0) {
1367 renameAction->setEnabled(true);
1368 }
1369
1370 bool enableMoveToTrash = true;
1371
1372 KFileItemList::const_iterator it = list.begin();
1373 const KFileItemList::const_iterator end = list.end();
1374 while (it != end) {
1375 const KUrl& url = (*it).url();
1376 // only enable the 'Move to Trash' action for local files
1377 if (!url.isLocalFile()) {
1378 enableMoveToTrash = false;
1379 }
1380 ++it;
1381 }
1382
1383 QAction* moveToTrashAction = actionCollection()->action("move_to_trash");
1384 moveToTrashAction->setEnabled(enableMoveToTrash);
1385 }
1386 updatePasteAction();
1387 }
1388
1389 void DolphinMainWindow::updateViewActions()
1390 {
1391 const DolphinView* view = m_activeViewContainer->view();
1392 QAction* zoomInAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::ZoomIn));
1393 if (zoomInAction != 0) {
1394 zoomInAction->setEnabled(view->isZoomInPossible());
1395 }
1396
1397 QAction* zoomOutAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::ZoomOut));
1398 if (zoomOutAction != 0) {
1399 zoomOutAction->setEnabled(view->isZoomOutPossible());
1400 }
1401
1402 QAction* action = actionCollection()->action(view->currentViewModeActionName());
1403 if (action != 0) {
1404 KToggleAction* toggleAction = static_cast<KToggleAction*>(action);
1405 toggleAction->setChecked(true);
1406 }
1407
1408 slotSortingChanged(view->sorting());
1409 slotSortOrderChanged(view->sortOrder());
1410 slotCategorizedSortingChanged();
1411 slotAdditionalInfoChanged(view->additionalInfo());
1412
1413 KToggleAction* showFilterBarAction =
1414 static_cast<KToggleAction*>(actionCollection()->action("show_filter_bar"));
1415 showFilterBarAction->setChecked(m_activeViewContainer->isFilterBarVisible());
1416
1417 KToggleAction* showPreviewAction =
1418 static_cast<KToggleAction*>(actionCollection()->action("show_preview"));
1419 showPreviewAction->setChecked(view->showPreview());
1420
1421 KToggleAction* showHiddenFilesAction =
1422 static_cast<KToggleAction*>(actionCollection()->action("show_hidden_files"));
1423 showHiddenFilesAction->setChecked(view->showHiddenFiles());
1424
1425 updateSplitAction();
1426
1427 KToggleAction* editableLocactionAction =
1428 static_cast<KToggleAction*>(actionCollection()->action("editable_location"));
1429 const KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
1430 editableLocactionAction->setChecked(urlNavigator->isUrlEditable());
1431 }
1432
1433 void DolphinMainWindow::updateGoActions()
1434 {
1435 QAction* goUpAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Up));
1436 const KUrl& currentUrl = m_activeViewContainer->url();
1437 goUpAction->setEnabled(currentUrl.upUrl() != currentUrl);
1438 }
1439
1440 void DolphinMainWindow::copyUrls(const KUrl::List& source, const KUrl& dest)
1441 {
1442 KonqOperations::copy(this, KonqOperations::COPY, source, dest);
1443 m_undoCommandTypes.append(KonqFileUndoManager::COPY);
1444 }
1445
1446 void DolphinMainWindow::moveUrls(const KUrl::List& source, const KUrl& dest)
1447 {
1448 KonqOperations::copy(this, KonqOperations::MOVE, source, dest);
1449 m_undoCommandTypes.append(KonqFileUndoManager::MOVE);
1450 }
1451
1452 void DolphinMainWindow::linkUrls(const KUrl::List& source, const KUrl& dest)
1453 {
1454 KonqOperations::copy(this, KonqOperations::LINK, source, dest);
1455 m_undoCommandTypes.append(KonqFileUndoManager::LINK);
1456 }
1457
1458 void DolphinMainWindow::clearStatusBar()
1459 {
1460 m_activeViewContainer->statusBar()->clear();
1461 }
1462
1463 void DolphinMainWindow::connectViewSignals(int viewIndex)
1464 {
1465 DolphinViewContainer* container = m_viewContainer[viewIndex];
1466 connect(container, SIGNAL(showFilterBarChanged(bool)),
1467 this, SLOT(updateFilterBarAction(bool)));
1468
1469 DolphinView* view = container->view();
1470 connect(view, SIGNAL(modeChanged()),
1471 this, SLOT(slotViewModeChanged()));
1472 connect(view, SIGNAL(showPreviewChanged()),
1473 this, SLOT(slotShowPreviewChanged()));
1474 connect(view, SIGNAL(showHiddenFilesChanged()),
1475 this, SLOT(slotShowHiddenFilesChanged()));
1476 connect(view, SIGNAL(categorizedSortingChanged()),
1477 this, SLOT(slotCategorizedSortingChanged()));
1478 connect(view, SIGNAL(sortingChanged(DolphinView::Sorting)),
1479 this, SLOT(slotSortingChanged(DolphinView::Sorting)));
1480 connect(view, SIGNAL(sortOrderChanged(Qt::SortOrder)),
1481 this, SLOT(slotSortOrderChanged(Qt::SortOrder)));
1482 connect(view, SIGNAL(additionalInfoChanged(KFileItemDelegate::InformationList)),
1483 this, SLOT(slotAdditionalInfoChanged(KFileItemDelegate::InformationList)));
1484 connect(view, SIGNAL(selectionChanged(KFileItemList)),
1485 this, SLOT(slotSelectionChanged(KFileItemList)));
1486 connect(view, SIGNAL(requestItemInfo(KFileItem)),
1487 this, SLOT(slotRequestItemInfo(KFileItem)));
1488 connect(view, SIGNAL(activated()),
1489 this, SLOT(toggleActiveView()));
1490 connect(view, SIGNAL(doingOperation(KonqFileUndoManager::CommandType)),
1491 this, SLOT(slotDoingOperation(KonqFileUndoManager::CommandType)));
1492
1493 const KUrlNavigator* navigator = container->urlNavigator();
1494 connect(navigator, SIGNAL(urlChanged(const KUrl&)),
1495 this, SLOT(changeUrl(const KUrl&)));
1496 connect(navigator, SIGNAL(historyChanged()),
1497 this, SLOT(slotHistoryChanged()));
1498 }
1499
1500 void DolphinMainWindow::updateSplitAction()
1501 {
1502 QAction* splitAction = actionCollection()->action("split_view");
1503 if (m_viewContainer[SecondaryView] != 0) {
1504 if (m_activeViewContainer == m_viewContainer[PrimaryView]) {
1505 splitAction->setText(i18nc("@action:intoolbar Close right view", "Close"));
1506 splitAction->setIcon(KIcon("fileview-close-right"));
1507 } else {
1508 splitAction->setText(i18nc("@action:intoolbar Close left view", "Close"));
1509 splitAction->setIcon(KIcon("fileview-close-left"));
1510 }
1511 } else {
1512 splitAction->setText(i18nc("@action:intoolbar Split view", "Split"));
1513 splitAction->setIcon(KIcon("fileview-split"));
1514 }
1515 }
1516
1517 void DolphinMainWindow::toggleAdditionalInfo(const char* actionName,
1518 KFileItemDelegate::Information info)
1519 {
1520 clearStatusBar();
1521
1522 DolphinView* view = m_activeViewContainer->view();
1523 KFileItemDelegate::InformationList list = view->additionalInfo();
1524
1525 const bool show = actionCollection()->action(actionName)->isChecked();
1526
1527 const int index = list.indexOf(info);
1528 const bool containsInfo = (index >= 0);
1529 if (show && !containsInfo) {
1530 list.append(info);
1531 view->setAdditionalInfo(list);
1532 } else if (!show && containsInfo) {
1533 list.removeAt(index);
1534 view->setAdditionalInfo(list);
1535 Q_ASSERT(list.indexOf(info) < 0);
1536 }
1537 }
1538
1539 DolphinMainWindow::UndoUiInterface::UndoUiInterface(DolphinMainWindow* mainWin) :
1540 KonqFileUndoManager::UiInterface(mainWin),
1541 m_mainWin(mainWin)
1542 {
1543 Q_ASSERT(m_mainWin != 0);
1544 }
1545
1546 DolphinMainWindow::UndoUiInterface::~UndoUiInterface()
1547 {
1548 }
1549
1550 void DolphinMainWindow::UndoUiInterface::jobError(KIO::Job* job)
1551 {
1552 DolphinStatusBar* statusBar = m_mainWin->activeViewContainer()->statusBar();
1553 statusBar->setMessage(job->errorString(), DolphinStatusBar::Error);
1554 }
1555
1556 #include "dolphinmainwindow.moc"