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