]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphinview.cpp
Step one for having DolphinParts for the icons and details view, which can be used...
[dolphin.git] / src / dolphinview.cpp
1 /***************************************************************************
2 * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> *
3 * Copyright (C) 2006 by Gregor Kališnik <gregor@podnapisi.net> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
19 ***************************************************************************/
20
21 #include "dolphinview.h"
22
23 #include <assert.h>
24
25 #include <QApplication>
26 #include <QDropEvent>
27 #include <QItemSelectionModel>
28 #include <QMouseEvent>
29 #include <QVBoxLayout>
30
31 #include <kdirmodel.h>
32 #include <kfileitemdelegate.h>
33 #include <klocale.h>
34 #include <kio/netaccess.h>
35 #include <kio/renamedialog.h>
36 #include <kmimetyperesolver.h>
37 #include <konq_operations.h>
38 #include <kurl.h>
39
40 #include "dolphincontroller.h"
41 #include "dolphinstatusbar.h"
42 #include "dolphinmainwindow.h"
43 #include "dolphindirlister.h"
44 #include "dolphinsortfilterproxymodel.h"
45 #include "dolphindetailsview.h"
46 #include "dolphiniconsview.h"
47 #include "dolphincontextmenu.h"
48 #include "filterbar.h"
49 #include "renamedialog.h"
50 #include "urlnavigator.h"
51 #include "viewproperties.h"
52
53 DolphinView::DolphinView(DolphinMainWindow* mainWindow,
54 QWidget* parent,
55 const KUrl& url,
56 Mode mode,
57 bool showHiddenFiles) :
58 QWidget(parent),
59 m_showProgress(false),
60 m_mode(mode),
61 m_iconSize(0),
62 m_folderCount(0),
63 m_fileCount(0),
64 m_mainWindow(mainWindow),
65 m_topLayout(0),
66 m_urlNavigator(0),
67 m_controller(0),
68 m_iconsView(0),
69 m_detailsView(0),
70 m_filterBar(0),
71 m_statusBar(0),
72 m_dirModel(0),
73 m_dirLister(0),
74 m_proxyModel(0)
75 {
76 hide();
77 setFocusPolicy(Qt::StrongFocus);
78 m_topLayout = new QVBoxLayout(this);
79 m_topLayout->setSpacing(0);
80 m_topLayout->setMargin(0);
81
82 m_urlNavigator = new UrlNavigator(url, this);
83 connect(m_urlNavigator, SIGNAL(urlChanged(const KUrl&)),
84 this, SLOT(loadDirectory(const KUrl&)));
85
86 m_statusBar = new DolphinStatusBar(this);
87
88 m_dirLister = new DolphinDirLister();
89 m_dirLister->setAutoUpdate(true);
90 m_dirLister->setMainWindow(this);
91 m_dirLister->setShowingDotFiles(showHiddenFiles);
92 m_dirLister->setDelayedMimeTypes(true);
93
94 connect(m_dirLister, SIGNAL(clear()),
95 this, SLOT(updateStatusBar()));
96 connect(m_dirLister, SIGNAL(percent(int)),
97 this, SLOT(updateProgress(int)));
98 connect(m_dirLister, SIGNAL(deleteItem(KFileItem*)),
99 this, SLOT(updateStatusBar()));
100 connect(m_dirLister, SIGNAL(completed()),
101 this, SLOT(updateItemCount()));
102 connect(m_dirLister, SIGNAL(infoMessage(const QString&)),
103 this, SLOT(showInfoMessage(const QString&)));
104 connect(m_dirLister, SIGNAL(errorMessage(const QString&)),
105 this, SLOT(showErrorMessage(const QString&)));
106
107 m_dirModel = new KDirModel();
108 m_dirModel->setDirLister(m_dirLister);
109 m_dirModel->setDropsAllowed(KDirModel::DropOnDirectory);
110
111 m_proxyModel = new DolphinSortFilterProxyModel(this);
112 m_proxyModel->setSourceModel(m_dirModel);
113
114 m_controller = new DolphinController(this);
115 connect(m_controller, SIGNAL(requestContextMenu(const QPoint&, const QPoint&)),
116 this, SLOT(openContextMenu(const QPoint&, const QPoint&)));
117 connect(m_controller, SIGNAL(sortingChanged(DolphinView::Sorting)),
118 this, SLOT(updateSorting(DolphinView::Sorting)));
119 connect(m_controller, SIGNAL(sortOrderChanged(Qt::SortOrder)),
120 this, SLOT(updateSortOrder(Qt::SortOrder)));
121 connect(m_controller, SIGNAL(itemTriggered(const QModelIndex&)),
122 this, SLOT(triggerItem(const QModelIndex&)));
123 connect(m_controller, SIGNAL(selectionChanged()),
124 this, SLOT(emitSelectionChangedSignal()));
125 connect(m_controller, SIGNAL(activated()),
126 this, SLOT(requestActivation()));
127
128 createView();
129
130 m_iconSize = K3Icon::SizeMedium;
131
132 m_filterBar = new FilterBar(this);
133 m_filterBar->hide();
134 connect(m_filterBar, SIGNAL(filterChanged(const QString&)),
135 this, SLOT(changeNameFilter(const QString&)));
136 connect(m_filterBar, SIGNAL(closeRequest()),
137 this, SLOT(closeFilterBar()));
138
139 m_topLayout->addWidget(m_urlNavigator);
140 m_topLayout->addWidget(itemView());
141 m_topLayout->addWidget(m_filterBar);
142 m_topLayout->addWidget(m_statusBar);
143
144 loadDirectory(m_urlNavigator->url());
145 }
146
147 DolphinView::~DolphinView()
148 {
149 delete m_dirLister;
150 m_dirLister = 0;
151 }
152
153 void DolphinView::setUrl(const KUrl& url)
154 {
155 m_urlNavigator->setUrl(url);
156 m_controller->setUrl(url);
157 }
158
159 const KUrl& DolphinView::url() const
160 {
161 return m_urlNavigator->url();
162 }
163
164 bool DolphinView::isActive() const
165 {
166 return (mainWindow()->activeView() == this);
167 }
168
169 void DolphinView::setMode(Mode mode)
170 {
171 if (mode == m_mode) {
172 return; // the wished mode is already set
173 }
174
175 m_mode = mode;
176
177 ViewProperties props(m_urlNavigator->url());
178 props.setViewMode(m_mode);
179
180 createView();
181 startDirLister(m_urlNavigator->url());
182
183 emit modeChanged();
184 }
185
186 DolphinView::Mode DolphinView::mode() const
187 {
188 return m_mode;
189 }
190
191 void DolphinView::setShowPreview(bool show)
192 {
193 ViewProperties props(m_urlNavigator->url());
194 props.setShowPreview(show);
195
196 // TODO: wait until previews are possible with KFileItemDelegate
197
198 emit showPreviewChanged();
199 }
200
201 bool DolphinView::showPreview() const
202 {
203 // TODO: wait until previews are possible with KFileItemDelegate
204 return true;
205 }
206
207 void DolphinView::setShowHiddenFiles(bool show)
208 {
209 if (m_dirLister->showingDotFiles() == show) {
210 return;
211 }
212
213 ViewProperties props(m_urlNavigator->url());
214 props.setShowHiddenFiles(show);
215 props.save();
216
217 m_dirLister->setShowingDotFiles(show);
218
219 emit showHiddenFilesChanged();
220
221 reload();
222 }
223
224 bool DolphinView::showHiddenFiles() const
225 {
226 return m_dirLister->showingDotFiles();
227 }
228
229 void DolphinView::renameSelectedItems()
230 {
231 const KUrl::List urls = selectedUrls();
232 if (urls.count() > 1) {
233 // More than one item has been selected for renaming. Open
234 // a rename dialog and rename all items afterwards.
235 RenameDialog dialog(urls);
236 if (dialog.exec() == QDialog::Rejected) {
237 return;
238 }
239
240 DolphinView* view = mainWindow()->activeView();
241 const QString& newName = dialog.newName();
242 if (newName.isEmpty()) {
243 view->statusBar()->setMessage(i18n("The new item name is invalid."),
244 DolphinStatusBar::Error);
245 }
246 else {
247 // TODO: check how this can be integrated into KonqUndoManager/KonqOperations
248
249 //UndoManager& undoMan = UndoManager::instance();
250 //undoMan.beginMacro();
251
252 assert(newName.contains('#'));
253
254 const int urlsCount = urls.count();
255
256 // iterate through all selected items and rename them...
257 const int replaceIndex = newName.indexOf('#');
258 assert(replaceIndex >= 0);
259 for (int i = 0; i < urlsCount; ++i) {
260 const KUrl& source = urls[i];
261 QString number;
262 number.setNum(i + 1);
263
264 QString name(newName);
265 name.replace(replaceIndex, 1, number);
266
267 if (source.fileName() != name) {
268 KUrl dest(source.upUrl());
269 dest.addPath(name);
270
271 const bool destExists = KIO::NetAccess::exists(dest, false, view);
272 if (destExists) {
273 view->statusBar()->setMessage(i18n("Renaming failed (item '%1' already exists).",name),
274 DolphinStatusBar::Error);
275 break;
276 }
277 else if (KIO::NetAccess::file_move(source, dest)) {
278 // TODO: From the users point of view he executed one 'rename n files' operation,
279 // but internally we store it as n 'rename 1 file' operations for the undo mechanism.
280 //DolphinCommand command(DolphinCommand::Rename, source, dest);
281 //undoMan.addCommand(command);
282 }
283 }
284 }
285
286 //undoMan.endMacro();
287 }
288 }
289 else {
290 // Only one item has been selected for renaming. Use the custom
291 // renaming mechanism from the views.
292 assert(urls.count() == 1);
293 // TODO:
294 /*if (m_mode == DetailsView) {
295 Q3ListViewItem* item = m_iconsView->firstChild();
296 while (item != 0) {
297 if (item->isSelected()) {
298 m_iconsView->rename(item, DolphinDetailsView::NameColumn);
299 break;
300 }
301 item = item->nextSibling();
302 }
303 }
304 else {
305 KFileIconViewItem* item = static_cast<KFileIconViewItem*>(m_iconsView->firstItem());
306 while (item != 0) {
307 if (item->isSelected()) {
308 item->rename();
309 break;
310 }
311 item = static_cast<KFileIconViewItem*>(item->nextItem());
312 }
313 }*/
314 }
315 }
316
317 void DolphinView::selectAll()
318 {
319 selectAll(QItemSelectionModel::Select);
320 }
321
322 void DolphinView::invertSelection()
323 {
324 selectAll(QItemSelectionModel::Toggle);
325 }
326
327 DolphinStatusBar* DolphinView::statusBar() const
328 {
329 return m_statusBar;
330 }
331
332 int DolphinView::contentsX() const
333 {
334
335 return itemView()->horizontalScrollBar()->value();
336 }
337
338 int DolphinView::contentsY() const
339 {
340 return itemView()->verticalScrollBar()->value();
341 }
342
343 void DolphinView::refreshSettings()
344 {
345 startDirLister(m_urlNavigator->url());
346 }
347
348 void DolphinView::emitRequestItemInfo(const KUrl& url)
349 {
350 emit requestItemInfo(url);
351 }
352
353 bool DolphinView::isFilterBarVisible() const
354 {
355 return m_filterBar->isVisible();
356 }
357
358 bool DolphinView::isUrlEditable() const
359 {
360 return m_urlNavigator->isUrlEditable();
361 }
362
363 void DolphinView::zoomIn()
364 {
365 //itemEffectsManager()->zoomIn();
366 }
367
368 void DolphinView::zoomOut()
369 {
370 //itemEffectsManager()->zoomOut();
371 }
372
373 bool DolphinView::isZoomInPossible() const
374 {
375 return false; //itemEffectsManager()->isZoomInPossible();
376 }
377
378 bool DolphinView::isZoomOutPossible() const
379 {
380 return false; //itemEffectsManager()->isZoomOutPossible();
381 }
382
383 void DolphinView::setSorting(Sorting sorting)
384 {
385 if (sorting != this->sorting()) {
386 updateSorting(sorting);
387 }
388 }
389
390 DolphinView::Sorting DolphinView::sorting() const
391 {
392 return m_proxyModel->sorting();
393 }
394
395 void DolphinView::setSortOrder(Qt::SortOrder order)
396 {
397 if (sortOrder() != order) {
398 updateSortOrder(order);
399 }
400 }
401
402 Qt::SortOrder DolphinView::sortOrder() const
403 {
404 return m_proxyModel->sortOrder();
405 }
406
407 void DolphinView::goBack()
408 {
409 m_urlNavigator->goBack();
410 }
411
412 void DolphinView::goForward()
413 {
414 m_urlNavigator->goForward();
415 }
416
417 void DolphinView::goUp()
418 {
419 m_urlNavigator->goUp();
420 }
421
422 void DolphinView::goHome()
423 {
424 m_urlNavigator->goHome();
425 }
426
427 void DolphinView::setUrlEditable(bool editable)
428 {
429 m_urlNavigator->editUrl(editable);
430 }
431
432 const QLinkedList<UrlNavigator::HistoryElem> DolphinView::urlHistory(int& index) const
433 {
434 return m_urlNavigator->history(index);
435 }
436
437 bool DolphinView::hasSelection() const
438 {
439 return itemView()->selectionModel()->hasSelection();
440 }
441
442 KFileItemList DolphinView::selectedItems() const
443 {
444 const QAbstractItemView* view = itemView();
445
446 // Our view has a selection, we will map them back to the DirModel
447 // and then fill the KFileItemList.
448 assert((view != 0) && (view->selectionModel() != 0));
449
450 const QItemSelection selection = m_proxyModel->mapSelectionToSource(view->selectionModel()->selection());
451 KFileItemList itemList;
452
453 const QModelIndexList indexList = selection.indexes();
454 QModelIndexList::const_iterator end = indexList.end();
455 for (QModelIndexList::const_iterator it = indexList.begin(); it != end; ++it) {
456 assert((*it).isValid());
457
458 KFileItem* item = m_dirModel->itemForIndex(*it);
459 if (item != 0) {
460 itemList.append(item);
461 }
462 }
463
464 return itemList;
465 }
466
467 KUrl::List DolphinView::selectedUrls() const
468 {
469 KUrl::List urls;
470
471 const KFileItemList list = selectedItems();
472 KFileItemList::const_iterator it = list.begin();
473 const KFileItemList::const_iterator end = list.end();
474 while (it != end) {
475 KFileItem* item = *it;
476 urls.append(item->url());
477 ++it;
478 }
479
480 return urls;
481 }
482
483 KFileItem* DolphinView::fileItem(const QModelIndex index) const
484 {
485 const QModelIndex dirModelIndex = m_proxyModel->mapToSource(index);
486 return m_dirModel->itemForIndex(dirModelIndex);
487 }
488
489 void DolphinView::rename(const KUrl& source, const QString& newName)
490 {
491 bool ok = false;
492
493 if (newName.isEmpty() || (source.fileName() == newName)) {
494 return;
495 }
496
497 KUrl dest(source.upUrl());
498 dest.addPath(newName);
499
500 const bool destExists = KIO::NetAccess::exists(dest,
501 false,
502 mainWindow()->activeView());
503 if (destExists) {
504 // the destination already exists, hence ask the user
505 // how to proceed...
506 KIO::RenameDialog renameDialog(this,
507 i18n("File Already Exists"),
508 source.path(),
509 dest.path(),
510 KIO::M_OVERWRITE);
511 switch (renameDialog.exec()) {
512 case KIO::R_OVERWRITE:
513 // the destination should be overwritten
514 ok = KIO::NetAccess::file_move(source, dest, -1, true);
515 break;
516
517 case KIO::R_RENAME: {
518 // a new name for the destination has been used
519 KUrl newDest(renameDialog.newDestUrl());
520 ok = KIO::NetAccess::file_move(source, newDest);
521 break;
522 }
523
524 default:
525 // the renaming operation has been canceled
526 reload();
527 return;
528 }
529 }
530 else {
531 // no destination exists, hence just move the file to
532 // do the renaming
533 ok = KIO::NetAccess::file_move(source, dest);
534 }
535
536 const QString destFileName = dest.fileName();
537 if (ok) {
538 m_statusBar->setMessage(i18n("Renamed file '%1' to '%2'.",source.fileName(), destFileName),
539 DolphinStatusBar::OperationCompleted);
540
541 KonqOperations::rename(this, source, destFileName);
542 }
543 else {
544 m_statusBar->setMessage(i18n("Renaming of file '%1' to '%2' failed.",source.fileName(), destFileName),
545 DolphinStatusBar::Error);
546 reload();
547 }
548 }
549
550 void DolphinView::reload()
551 {
552 startDirLister(m_urlNavigator->url(), true);
553 }
554
555 void DolphinView::declareViewActive()
556 {
557 mainWindow()->setActiveView( this );
558 }
559
560 void DolphinView::mouseReleaseEvent(QMouseEvent* event)
561 {
562 QWidget::mouseReleaseEvent(event);
563 mainWindow()->setActiveView(this);
564 }
565
566 DolphinMainWindow* DolphinView::mainWindow() const
567 {
568 return m_mainWindow;
569 }
570
571 void DolphinView::loadDirectory(const KUrl& url)
572 {
573 const ViewProperties props(url);
574
575 const Mode mode = props.viewMode();
576 if (m_mode != mode) {
577 m_mode = mode;
578 createView();
579 emit modeChanged();
580 }
581
582 const bool showHiddenFiles = props.showHiddenFiles();
583 if (showHiddenFiles != m_dirLister->showingDotFiles()) {
584 m_dirLister->setShowingDotFiles(showHiddenFiles);
585 emit showHiddenFilesChanged();
586 }
587
588 const DolphinView::Sorting sorting = props.sorting();
589 if (sorting != m_proxyModel->sorting()) {
590 m_proxyModel->setSorting(sorting);
591 emit sortingChanged(sorting);
592 }
593
594 const Qt::SortOrder sortOrder = props.sortOrder();
595 if (sortOrder != m_proxyModel->sortOrder()) {
596 m_proxyModel->setSortOrder(sortOrder);
597 emit sortOrderChanged(sortOrder);
598 }
599
600 // TODO: handle previews (props.showPreview())
601
602 startDirLister(url);
603 emit urlChanged(url);
604
605 m_statusBar->clear();
606 }
607
608 void DolphinView::triggerItem(const QModelIndex& index)
609 {
610 const Qt::KeyboardModifiers modifier = QApplication::keyboardModifiers();
611 if ((modifier & Qt::ShiftModifier) || (modifier & Qt::ControlModifier)) {
612 // items are selected by the user, hence don't trigger the
613 // item specified by 'index'
614 return;
615 }
616
617 KFileItem* item = m_dirModel->itemForIndex(m_proxyModel->mapToSource(index));
618 if (item == 0) {
619 return;
620 }
621
622 if (item->isDir()) {
623 // Prefer the local path over the URL. This assures that the
624 // volume space information is correct. Assuming that the URL is media:/sda1,
625 // and the local path is /windows/C: For the URL the space info is related
626 // to the root partition (and hence wrong) and for the local path the space
627 // info is related to the windows partition (-> correct).
628 const QString localPath(item->localPath());
629 if (localPath.isEmpty()) {
630 setUrl(item->url());
631 }
632 else {
633 setUrl(KUrl(localPath));
634 }
635 }
636 else {
637 item->run();
638 }
639 }
640
641 void DolphinView::updateProgress(int percent)
642 {
643 if (m_showProgress) {
644 m_statusBar->setProgress(percent);
645 }
646 }
647
648 void DolphinView::updateItemCount()
649 {
650 if (m_showProgress) {
651 m_statusBar->setProgressText(QString::null);
652 m_statusBar->setProgress(100);
653 m_showProgress = false;
654 }
655
656 KFileItemList items(m_dirLister->items());
657 KFileItemList::const_iterator it = items.begin();
658 const KFileItemList::const_iterator end = items.end();
659
660 m_fileCount = 0;
661 m_folderCount = 0;
662
663 while (it != end) {
664 KFileItem* item = *it;
665 if (item->isDir()) {
666 ++m_folderCount;
667 }
668 else {
669 ++m_fileCount;
670 }
671 ++it;
672 }
673
674 updateStatusBar();
675
676 QTimer::singleShot(0, this, SLOT(restoreContentsPos()));
677 }
678
679 void DolphinView::restoreContentsPos()
680 {
681 int index = 0;
682 const QLinkedList<UrlNavigator::HistoryElem> history = urlHistory(index);
683 if (!history.isEmpty()) {
684 QAbstractItemView* view = itemView();
685 // TODO: view->setCurrentItem(history[index].currentFileName());
686
687 QLinkedList<UrlNavigator::HistoryElem>::const_iterator it = history.begin();
688 it += index;
689 view->horizontalScrollBar()->setValue((*it).contentsX());
690 view->verticalScrollBar()->setValue((*it).contentsY());
691 }
692 }
693
694 void DolphinView::showInfoMessage(const QString& msg)
695 {
696 m_statusBar->setMessage(msg, DolphinStatusBar::Information);
697 }
698
699 void DolphinView::showErrorMessage(const QString& msg)
700 {
701 m_statusBar->setMessage(msg, DolphinStatusBar::Error);
702 }
703
704 void DolphinView::emitSelectionChangedSignal()
705 {
706 emit selectionChanged();
707 }
708
709 void DolphinView::closeFilterBar()
710 {
711 m_filterBar->hide();
712 emit showFilterBarChanged(false);
713 }
714
715 void DolphinView::startDirLister(const KUrl& url, bool reload)
716 {
717 if (!url.isValid()) {
718 const QString location(url.pathOrUrl());
719 if (location.isEmpty()) {
720 m_statusBar->setMessage(i18n("The location is empty."), DolphinStatusBar::Error);
721 }
722 else {
723 m_statusBar->setMessage(i18n("The location '%1' is invalid.",location),
724 DolphinStatusBar::Error);
725 }
726 return;
727 }
728
729 // Only show the directory loading progress if the status bar does
730 // not contain another progress information. This means that
731 // the directory loading progress information has the lowest priority.
732 const QString progressText(m_statusBar->progressText());
733 m_showProgress = progressText.isEmpty() ||
734 (progressText == i18n("Loading directory..."));
735 if (m_showProgress) {
736 m_statusBar->setProgressText(i18n("Loading directory..."));
737 m_statusBar->setProgress(0);
738 }
739
740 m_dirLister->stop();
741 m_dirLister->openUrl(url, false, reload);
742 }
743
744 QString DolphinView::defaultStatusBarText() const
745 {
746 return KIO::itemsSummaryString(m_fileCount + m_folderCount,
747 m_fileCount,
748 m_folderCount,
749 0, false);
750 }
751
752 QString DolphinView::selectionStatusBarText() const
753 {
754 QString text;
755 const KFileItemList list = selectedItems();
756 if (list.isEmpty()) {
757 // when an item is triggered, it is temporary selected but selectedItems()
758 // will return an empty list
759 return QString();
760 }
761
762 int fileCount = 0;
763 int folderCount = 0;
764 KIO::filesize_t byteSize = 0;
765 KFileItemList::const_iterator it = list.begin();
766 const KFileItemList::const_iterator end = list.end();
767 while (it != end){
768 KFileItem* item = *it;
769 if (item->isDir()) {
770 ++folderCount;
771 }
772 else {
773 ++fileCount;
774 byteSize += item->size();
775 }
776 ++it;
777 }
778
779 if (folderCount > 0) {
780 text = i18np("1 Folder selected", "%1 Folders selected", folderCount);
781 if (fileCount > 0) {
782 text += ", ";
783 }
784 }
785
786 if (fileCount > 0) {
787 const QString sizeText(KIO::convertSize(byteSize));
788 text += i18np("1 File selected (%2)", "%1 Files selected (%2)", fileCount, sizeText);
789 }
790
791 return text;
792 }
793
794 void DolphinView::showFilterBar(bool show)
795 {
796 assert(m_filterBar != 0);
797 if (show) {
798 m_filterBar->show();
799 }
800 else {
801 m_filterBar->hide();
802 }
803 }
804
805 void DolphinView::updateStatusBar()
806 {
807 // As the item count information is less important
808 // in comparison with other messages, it should only
809 // be shown if:
810 // - the status bar is empty or
811 // - shows already the item count information or
812 // - shows only a not very important information
813 // - if any progress is given don't show the item count info at all
814 const QString msg(m_statusBar->message());
815 const bool updateStatusBarMsg = (msg.isEmpty() ||
816 (msg == m_statusBar->defaultText()) ||
817 (m_statusBar->type() == DolphinStatusBar::Information)) &&
818 (m_statusBar->progress() == 100);
819
820 const QString text(hasSelection() ? selectionStatusBarText() : defaultStatusBarText());
821 m_statusBar->setDefaultText(text);
822
823 if (updateStatusBarMsg) {
824 m_statusBar->setMessage(text, DolphinStatusBar::Default);
825 }
826 }
827
828 void DolphinView::requestActivation()
829 {
830 m_mainWindow->setActiveView(this);
831 }
832
833 void DolphinView::changeNameFilter(const QString& nameFilter)
834 {
835 // The name filter of KDirLister does a 'hard' filtering, which
836 // means that only the items are shown where the names match
837 // exactly the filter. This is non-transparent for the user, which
838 // just wants to have a 'soft' filtering: does the name contain
839 // the filter string?
840 QString adjustedFilter(nameFilter);
841 adjustedFilter.insert(0, '*');
842 adjustedFilter.append('*');
843
844 // Use the ProxyModel to filter:
845 // This code is #ifdefed as setNameFilter behaves
846 // slightly different than the QSortFilterProxyModel
847 // as it will not remove directories. I will ask
848 // our beloved usability experts for input
849 // -- z.
850 #if 0
851 m_dirLister->setNameFilter(adjustedFilter);
852 m_dirLister->emitChanges();
853 #else
854 m_proxyModel->setFilterRegExp( nameFilter );
855 #endif
856 }
857
858 void DolphinView::openContextMenu(const QPoint& pos, const QPoint& globalPos)
859 {
860 KFileItem* item = 0;
861
862 const QModelIndex index = itemView()->indexAt(pos);
863 if (index.isValid()) {
864 item = fileItem(index);
865 }
866
867 DolphinContextMenu contextMenu(this, item, globalPos);
868 contextMenu.open();
869 }
870
871 void DolphinView::updateSorting(DolphinView::Sorting sorting)
872 {
873 ViewProperties props(url());
874 props.setSorting(sorting);
875
876 m_proxyModel->setSorting(sorting);
877
878 emit sortingChanged(sorting);
879 }
880
881 void DolphinView::updateSortOrder(Qt::SortOrder order)
882 {
883 ViewProperties props(url());
884 props.setSortOrder(order);
885
886 m_proxyModel->setSortOrder(order);
887
888 emit sortOrderChanged(order);
889 }
890
891 void DolphinView::createView()
892 {
893 // delete current view
894 QAbstractItemView* view = itemView();
895 if (view != 0) {
896 m_topLayout->removeWidget(view);
897 view->close();
898 view->deleteLater();
899 m_iconsView = 0;
900 m_detailsView = 0;
901 }
902
903 assert(m_iconsView == 0);
904 assert(m_detailsView == 0);
905
906 // ... and recreate it representing the current mode
907 switch (m_mode) {
908 case IconsView:
909 m_iconsView = new DolphinIconsView(this, m_controller);
910 view = m_iconsView;
911 break;
912
913 case DetailsView:
914 m_detailsView = new DolphinDetailsView(this, m_controller);
915 view = m_detailsView;
916 break;
917 }
918
919 view->setModel(m_proxyModel);
920 view->setSelectionMode(QAbstractItemView::ExtendedSelection);
921
922 KFileItemDelegate* delegate = new KFileItemDelegate(this);
923 delegate->setAdditionalInformation(KFileItemDelegate::FriendlyMimeType);
924 view->setItemDelegate(delegate);
925
926 new KMimeTypeResolver(view, m_dirModel);
927 m_topLayout->insertWidget(1, view);
928
929 connect(view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
930 m_controller, SLOT(indicateSelectionChange()));
931 }
932
933 int DolphinView::columnIndex(Sorting sorting) const
934 {
935 int index = 0;
936 switch (sorting) {
937 case SortByName: index = KDirModel::Name; break;
938 case SortBySize: index = KDirModel::Size; break;
939 case SortByDate: index = KDirModel::ModifiedTime; break;
940 default: assert(false);
941 }
942 return index;
943 }
944
945 void DolphinView::selectAll(QItemSelectionModel::SelectionFlags flags)
946 {
947 QItemSelectionModel* selectionModel = itemView()->selectionModel();
948 const QAbstractItemModel* itemModel = selectionModel->model();
949
950 const QModelIndex topLeft = itemModel->index(0, 0);
951 const QModelIndex bottomRight = itemModel->index(itemModel->rowCount() - 1,
952 itemModel->columnCount() - 1);
953
954 QItemSelection selection(topLeft, bottomRight);
955 selectionModel->select(selection, flags);
956 }
957
958 QAbstractItemView* DolphinView::itemView() const
959 {
960 assert((m_iconsView == 0) || (m_detailsView == 0));
961 if (m_detailsView != 0) {
962 return m_detailsView;
963 }
964 return m_iconsView;
965 }
966
967 #include "dolphinview.moc"