]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphinview.cpp
Support changing the sorting type and sort order (TODO: does not work yet as the...
[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 <QItemSelectionModel>
24 #include <Q3ValueList>
25 #include <QDropEvent>
26 #include <QMouseEvent>
27 #include <QVBoxLayout>
28
29 #include <kdirmodel.h>
30 #include <kfileitemdelegate.h>
31 #include <kurl.h>
32 #include <klocale.h>
33 #include <kio/netaccess.h>
34 #include <kio/renamedlg.h>
35 #include <kmimetyperesolver.h>
36 #include <assert.h>
37
38 #include "urlnavigator.h"
39 #include "dolphinstatusbar.h"
40 #include "dolphinmainwindow.h"
41 #include "dolphindirlister.h"
42 #include "viewproperties.h"
43 #include "dolphindetailsview.h"
44 #include "dolphiniconsview.h"
45 #include "dolphincontextmenu.h"
46 #include "undomanager.h"
47 #include "renamedialog.h"
48 #include "progressindicator.h"
49 #include "filterbar.h"
50
51 DolphinView::DolphinView(DolphinMainWindow *mainWindow,
52 QWidget *parent,
53 const KUrl& url,
54 Mode mode,
55 bool showHiddenFiles) :
56 QWidget(parent),
57 m_refreshing(false),
58 m_showProgress(false),
59 m_mode(mode),
60 m_mainWindow(mainWindow),
61 m_statusBar(0),
62 m_iconSize(0),
63 m_folderCount(0),
64 m_fileCount(0),
65 m_filterBar(0)
66 {
67 hide();
68 setFocusPolicy(Qt::StrongFocus);
69 m_topLayout = new QVBoxLayout(this);
70 m_topLayout->setSpacing(0);
71 m_topLayout->setMargin(0);
72
73 m_urlNavigator = new UrlNavigator(url, this);
74 connect(m_urlNavigator, SIGNAL(urlChanged(const KUrl&)),
75 this, SLOT(loadDirectory(const KUrl&)));
76
77 m_statusBar = new DolphinStatusBar(this);
78
79 m_dirLister = new DolphinDirLister();
80 m_dirLister->setAutoUpdate(true);
81 m_dirLister->setMainWindow(this);
82 m_dirLister->setShowingDotFiles(showHiddenFiles);
83 connect(m_dirLister, SIGNAL(clear()),
84 this, SLOT(slotClear()));
85 connect(m_dirLister, SIGNAL(percent(int)),
86 this, SLOT(slotPercent(int)));
87 connect(m_dirLister, SIGNAL(deleteItem(KFileItem*)),
88 this, SLOT(slotDeleteItem(KFileItem*)));
89 connect(m_dirLister, SIGNAL(completed()),
90 this, SLOT(slotCompleted()));
91 connect(m_dirLister, SIGNAL(infoMessage(const QString&)),
92 this, SLOT(slotInfoMessage(const QString&)));
93 connect(m_dirLister, SIGNAL(errorMessage(const QString&)),
94 this, SLOT(slotErrorMessage(const QString&)));
95
96 m_iconsView = new DolphinIconsView(this);
97 applyModeToView();
98
99 KDirModel* model = new KDirModel();
100 model->setDirLister(m_dirLister);
101 m_iconsView->setModel(model);
102
103 KFileItemDelegate* delegate = new KFileItemDelegate(this);
104 m_iconsView->setItemDelegate(delegate);
105
106 m_dirLister->setDelayedMimeTypes(true);
107 new KMimeTypeResolver(m_iconsView, model);
108
109 m_iconSize = K3Icon::SizeMedium;
110
111 m_filterBar = new FilterBar(this);
112 m_filterBar->hide();
113 connect(m_filterBar, SIGNAL(filterChanged(const QString&)),
114 this, SLOT(slotChangeNameFilter(const QString&)));
115 connect(m_filterBar, SIGNAL(closed()),
116 this, SLOT(closeFilterBar()));
117
118 m_topLayout->addWidget(m_urlNavigator);
119 m_topLayout->addWidget(m_iconsView);
120 m_topLayout->addWidget(m_filterBar);
121 m_topLayout->addWidget(m_statusBar);
122
123 connect(m_iconsView, SIGNAL(clicked(const QModelIndex&)),
124 this, SLOT(triggerItem(const QModelIndex&)));
125 connect(m_iconsView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
126 this, SLOT(emitSelectionChangedSignal()));
127
128 startDirLister(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 applyModeToView();
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::setShowHiddenFiles(bool show)
180 {
181 if (m_dirLister->showingDotFiles() == show) {
182 return;
183 }
184
185 ViewProperties props(m_urlNavigator->url());
186 props.setShowHiddenFiles(show);
187 props.save();
188
189 m_dirLister->setShowingDotFiles(show);
190
191 emit showHiddenFilesChanged();
192
193 reload();
194 }
195
196 bool DolphinView::showHiddenFiles() const
197 {
198 return m_dirLister->showingDotFiles();
199 }
200
201 void DolphinView::setViewProperties(const ViewProperties& props)
202 {
203 setMode(props.viewMode());
204 setSorting(props.sorting());
205 setSortOrder(props.sortOrder());
206 setShowHiddenFiles(props.showHiddenFiles());
207 }
208
209 void DolphinView::renameSelectedItems()
210 {
211 const KUrl::List urls = selectedUrls();
212 if (urls.count() > 1) {
213 // More than one item has been selected for renaming. Open
214 // a rename dialog and rename all items afterwards.
215 RenameDialog dialog(urls);
216 if (dialog.exec() == QDialog::Rejected) {
217 return;
218 }
219
220 DolphinView* view = mainWindow()->activeView();
221 const QString& newName = dialog.newName();
222 if (newName.isEmpty()) {
223 view->statusBar()->setMessage(i18n("The new item name is invalid."),
224 DolphinStatusBar::Error);
225 }
226 else {
227 UndoManager& undoMan = UndoManager::instance();
228 undoMan.beginMacro();
229
230 assert(newName.contains('#'));
231
232 const int urlsCount = urls.count();
233 ProgressIndicator* progressIndicator =
234 new ProgressIndicator(mainWindow(),
235 i18n("Renaming items..."),
236 i18n("Renaming finished."),
237 urlsCount);
238
239 // iterate through all selected items and rename them...
240 const int replaceIndex = newName.indexOf('#');
241 assert(replaceIndex >= 0);
242 for (int i = 0; i < urlsCount; ++i) {
243 const KUrl& source = urls[i];
244 QString name(newName);
245 name.replace(replaceIndex, 1, renameIndexPresentation(i + 1, urlsCount));
246
247 if (source.fileName() != name) {
248 KUrl dest(source.upUrl());
249 dest.addPath(name);
250
251 const bool destExists = KIO::NetAccess::exists(dest, false, view);
252 if (destExists) {
253 delete progressIndicator;
254 progressIndicator = 0;
255 view->statusBar()->setMessage(i18n("Renaming failed (item '%1' already exists).",name),
256 DolphinStatusBar::Error);
257 break;
258 }
259 else if (KIO::NetAccess::file_move(source, dest)) {
260 // TODO: From the users point of view he executed one 'rename n files' operation,
261 // but internally we store it as n 'rename 1 file' operations for the undo mechanism.
262 DolphinCommand command(DolphinCommand::Rename, source, dest);
263 undoMan.addCommand(command);
264 }
265 }
266
267 progressIndicator->execOperation();
268 }
269 delete progressIndicator;
270 progressIndicator = 0;
271
272 undoMan.endMacro();
273 }
274 }
275 else {
276 // Only one item has been selected for renaming. Use the custom
277 // renaming mechanism from the views.
278 assert(urls.count() == 1);
279 // TODO:
280 /*if (m_mode == DetailsView) {
281 Q3ListViewItem* item = m_iconsView->firstChild();
282 while (item != 0) {
283 if (item->isSelected()) {
284 m_iconsView->rename(item, DolphinDetailsView::NameColumn);
285 break;
286 }
287 item = item->nextSibling();
288 }
289 }
290 else {
291 KFileIconViewItem* item = static_cast<KFileIconViewItem*>(m_iconsView->firstItem());
292 while (item != 0) {
293 if (item->isSelected()) {
294 item->rename();
295 break;
296 }
297 item = static_cast<KFileIconViewItem*>(item->nextItem());
298 }
299 }*/
300 }
301 }
302
303 void DolphinView::selectAll()
304 {
305 //fileView()->selectAll();
306 }
307
308 void DolphinView::invertSelection()
309 {
310 //fileView()->invertSelection();
311 }
312
313 DolphinStatusBar* DolphinView::statusBar() const
314 {
315 return m_statusBar;
316 }
317
318 int DolphinView::contentsX() const
319 {
320
321 return 0; //scrollView()->contentsX();
322 }
323
324 int DolphinView::contentsY() const
325 {
326 return 0; //scrollView()->contentsY();
327 }
328
329 void DolphinView::refreshSettings()
330 {
331 startDirLister(m_urlNavigator->url());
332 }
333
334 void DolphinView::updateStatusBar()
335 {
336 // As the item count information is less important
337 // in comparison with other messages, it should only
338 // be shown if:
339 // - the status bar is empty or
340 // - shows already the item count information or
341 // - shows only a not very important information
342 // - if any progress is given don't show the item count info at all
343 const QString msg(m_statusBar->message());
344 const bool updateStatusBarMsg = (msg.isEmpty() ||
345 (msg == m_statusBar->defaultText()) ||
346 (m_statusBar->type() == DolphinStatusBar::Information)) &&
347 (m_statusBar->progress() == 100);
348
349 const QString text(hasSelection() ? selectionStatusBarText() : defaultStatusBarText());
350 m_statusBar->setDefaultText(text);
351
352 if (updateStatusBarMsg) {
353 m_statusBar->setMessage(text, DolphinStatusBar::Default);
354 }
355 }
356
357 void DolphinView::emitRequestItemInfo(const KUrl& url)
358 {
359 emit requestItemInfo(url);
360 }
361
362 bool DolphinView::isFilterBarVisible() const
363 {
364 return m_filterBar->isVisible();
365 }
366
367 bool DolphinView::isUrlEditable() const
368 {
369 return m_urlNavigator->isUrlEditable();
370 }
371
372 void DolphinView::zoomIn()
373 {
374 //itemEffectsManager()->zoomIn();
375 }
376
377 void DolphinView::zoomOut()
378 {
379 //itemEffectsManager()->zoomOut();
380 }
381
382 bool DolphinView::isZoomInPossible() const
383 {
384 return false; //itemEffectsManager()->isZoomInPossible();
385 }
386
387 bool DolphinView::isZoomOutPossible() const
388 {
389 return false; //itemEffectsManager()->isZoomOutPossible();
390 }
391
392 void DolphinView::setSorting(Sorting sorting)
393 {
394 if (sorting != this->sorting()) {
395 ViewProperties props(url());
396 props.setSorting(sorting);
397
398 KDirModel* dirModel = static_cast<KDirModel*>(m_iconsView->model());
399 dirModel->sort(columnIndex(sorting), props.sortOrder());
400
401 emit sortingChanged(sorting);
402 }
403 }
404
405 DolphinView::Sorting DolphinView::sorting() const
406 {
407 // TODO: instead of getting the sorting from the properties just fetch
408 // them from KDirModel, if such an interface will be offered (David?)
409 ViewProperties props(url());
410 return props.sorting();
411 }
412
413 void DolphinView::setSortOrder(Qt::SortOrder order)
414 {
415 if (sortOrder() != order) {
416 ViewProperties props(url());
417 props.setSortOrder(order);
418
419 KDirModel* dirModel = static_cast<KDirModel*>(m_iconsView->model());
420 dirModel->sort(columnIndex(props.sorting()), order);
421
422 emit sortOrderChanged(order);
423 }
424 }
425
426 Qt::SortOrder DolphinView::sortOrder() const
427 {
428 // TODO: instead of getting the order from the properties just fetch
429 // them from KDirModel, if such an interface will be offered (David?)
430 ViewProperties props(url());
431 return props.sortOrder();
432 }
433
434 void DolphinView::goBack()
435 {
436 m_urlNavigator->goBack();
437 }
438
439 void DolphinView::goForward()
440 {
441 m_urlNavigator->goForward();
442 }
443
444 void DolphinView::goUp()
445 {
446 m_urlNavigator->goUp();
447 }
448
449 void DolphinView::goHome()
450 {
451 m_urlNavigator->goHome();
452 }
453
454 void DolphinView::setUrlEditable(bool editable)
455 {
456 m_urlNavigator->editUrl(editable);
457 }
458
459 const Q3ValueList<UrlNavigator::HistoryElem> DolphinView::urlHistory(int& index) const
460 {
461 return m_urlNavigator->history(index);
462 }
463
464 bool DolphinView::hasSelection() const
465 {
466 return m_iconsView->selectionModel()->hasSelection();
467 }
468
469 KFileItemList DolphinView::selectedItems() const
470 {
471 QItemSelectionModel* selModel = m_iconsView->selectionModel();
472 assert(selModel != 0);
473
474 KFileItemList itemList;
475 if (selModel->hasSelection()) {
476 KDirModel* dirModel = static_cast<KDirModel*>(m_iconsView->model());
477 const QModelIndexList indexList = selModel->selectedIndexes();
478
479 QModelIndexList::const_iterator end = indexList.end();
480 for (QModelIndexList::const_iterator it = indexList.begin(); it != end; ++it) {
481 KFileItem* item = dirModel->itemForIndex(*it);
482 if (item != 0) {
483 itemList.append(item);
484 }
485 }
486 }
487 return itemList;
488 }
489
490 KUrl::List DolphinView::selectedUrls() const
491 {
492 KUrl::List urls;
493
494 const KFileItemList list = selectedItems();
495 KFileItemList::const_iterator it = list.begin();
496 const KFileItemList::const_iterator end = list.end();
497 while (it != end) {
498 KFileItem* item = *it;
499 urls.append(item->url());
500 ++it;
501 }
502
503 return urls;
504 }
505
506 const KFileItem* DolphinView::currentFileItem() const
507 {
508 return 0; // fileView()->currentFileItem();
509 }
510
511 void DolphinView::openContextMenu(KFileItem* fileInfo, const QPoint& pos)
512 {
513 DolphinContextMenu contextMenu(this, fileInfo, pos);
514 contextMenu.open();
515 }
516
517 void DolphinView::rename(const KUrl& source, const QString& newName)
518 {
519 bool ok = false;
520
521 if (newName.isEmpty() || (source.fileName() == newName)) {
522 return;
523 }
524
525 KUrl dest(source.upUrl());
526 dest.addPath(newName);
527
528 const bool destExists = KIO::NetAccess::exists(dest,
529 false,
530 mainWindow()->activeView());
531 if (destExists) {
532 // the destination already exists, hence ask the user
533 // how to proceed...
534 KIO::RenameDlg renameDialog(this,
535 i18n("File Already Exists"),
536 source.path(),
537 dest.path(),
538 KIO::M_OVERWRITE);
539 switch (renameDialog.exec()) {
540 case KIO::R_OVERWRITE:
541 // the destination should be overwritten
542 ok = KIO::NetAccess::file_move(source, dest, -1, true);
543 break;
544
545 case KIO::R_RENAME: {
546 // a new name for the destination has been used
547 KUrl newDest(renameDialog.newDestUrl());
548 ok = KIO::NetAccess::file_move(source, newDest);
549 break;
550 }
551
552 default:
553 // the renaming operation has been canceled
554 reload();
555 return;
556 }
557 }
558 else {
559 // no destination exists, hence just move the file to
560 // do the renaming
561 ok = KIO::NetAccess::file_move(source, dest);
562 }
563
564 if (ok) {
565 m_statusBar->setMessage(i18n("Renamed file '%1' to '%2'.",source.fileName(), dest.fileName()),
566 DolphinStatusBar::OperationCompleted);
567
568 DolphinCommand command(DolphinCommand::Rename, source, dest);
569 UndoManager::instance().addCommand(command);
570 }
571 else {
572 m_statusBar->setMessage(i18n("Renaming of file '%1' to '%2' failed.",source.fileName(), dest.fileName()),
573 DolphinStatusBar::Error);
574 reload();
575 }
576 }
577
578 void DolphinView::reload()
579 {
580 startDirLister(m_urlNavigator->url(), true);
581 }
582
583 void DolphinView::slotUrlListDropped(QDropEvent* /* event */,
584 const KUrl::List& urls,
585 const KUrl& url)
586 {
587 KUrl destination(url);
588 if (destination.isEmpty()) {
589 destination = m_urlNavigator->url();
590 }
591 else {
592 // Check whether the destination Url is a directory. If this is not the
593 // case, use the navigator Url as destination (otherwise the destination,
594 // which represents a file, would be replaced by a copy- or move-operation).
595 KFileItem fileItem(KFileItem::Unknown, KFileItem::Unknown, destination);
596 if (!fileItem.isDir()) {
597 destination = m_urlNavigator->url();
598 }
599 }
600
601 mainWindow()->dropUrls(urls, destination);
602 }
603
604 void DolphinView::mouseReleaseEvent(QMouseEvent* event)
605 {
606 QWidget::mouseReleaseEvent(event);
607 mainWindow()->setActiveView(this);
608 }
609
610 DolphinMainWindow* DolphinView::mainWindow() const
611 {
612 return m_mainWindow;
613 }
614
615 void DolphinView::loadDirectory(const KUrl& url)
616 {
617 const ViewProperties props(url);
618 setMode(props.viewMode());
619
620 const bool showHiddenFiles = props.showHiddenFiles();
621 setShowHiddenFiles(showHiddenFiles);
622 m_dirLister->setShowingDotFiles(showHiddenFiles);
623
624 setSorting(props.sorting());
625 setSortOrder(props.sortOrder());
626
627 startDirLister(url);
628 emit urlChanged(url);
629 }
630
631 void DolphinView::triggerIconsViewItem(Q3IconViewItem* item)
632 {
633 /* KDE4-TODO:
634 const Qt::ButtonState keyboardState = KApplication::keyboardMouseState();
635 const bool isSelectionActive = ((keyboardState & Qt::ShiftModifier) > 0) ||
636 ((keyboardState & Qt::ControlModifier) > 0);*/
637 const bool isSelectionActive = false;
638 if ((item != 0) && !isSelectionActive) {
639 // Updating the Url must be done outside the scope of this slot,
640 // as iconview items will get deleted.
641 QTimer::singleShot(0, this, SLOT(updateUrl()));
642 mainWindow()->setActiveView(this);
643 }
644 }
645
646 void DolphinView::triggerItem(const QModelIndex& index)
647 {
648 KDirModel* dirModel = static_cast<KDirModel*>(m_iconsView->model());
649 KFileItem* item = dirModel->itemForIndex(index);
650 if (item == 0) {
651 return;
652 }
653
654 if (item->isDir()) {
655 // Prefer the local path over the Url. This assures that the
656 // volume space information is correct. Assuming that the Url is media:/sda1,
657 // and the local path is /windows/C: For the Url the space info is related
658 // to the root partition (and hence wrong) and for the local path the space
659 // info is related to the windows partition (-> correct).
660 //m_dirLister->stop();
661 //m_dirLister->openUrl(item->url());
662 //return;
663
664 const QString localPath(item->localPath());
665 if (localPath.isEmpty()) {
666 setUrl(item->url());
667 }
668 else {
669 setUrl(KUrl(localPath));
670 }
671 }
672 else {
673 item->run();
674 }
675 }
676
677 void DolphinView::updateUrl()
678 {
679 //KFileView* fileView = (m_iconsView != 0) ? static_cast<KFileView*>(m_iconsView) :
680 // static_cast<KFileView*>(m_iconsView);
681
682 KFileItem* fileItem = 0; // TODO: fileView->currentFileItem();
683 if (fileItem == 0) {
684 return;
685 }
686
687 if (fileItem->isDir()) {
688 // Prefer the local path over the Url. This assures that the
689 // volume space information is correct. Assuming that the Url is media:/sda1,
690 // and the local path is /windows/C: For the Url the space info is related
691 // to the root partition (and hence wrong) and for the local path the space
692 // info is related to the windows partition (-> correct).
693 const QString localPath(fileItem->localPath());
694 if (localPath.isEmpty()) {
695 setUrl(fileItem->url());
696 }
697 else {
698 setUrl(KUrl(localPath));
699 }
700 }
701 else {
702 fileItem->run();
703 }
704 }
705
706 void DolphinView::slotPercent(int percent)
707 {
708 if (m_showProgress) {
709 m_statusBar->setProgress(percent);
710 }
711 }
712
713 void DolphinView::slotClear()
714 {
715 //fileView()->clearView();
716 updateStatusBar();
717 }
718
719 void DolphinView::slotDeleteItem(KFileItem* item)
720 {
721 //fileView()->removeItem(item);
722 updateStatusBar();
723 }
724
725 void DolphinView::slotCompleted()
726 {
727 m_refreshing = true;
728
729 //KFileView* view = fileView();
730 //view->clearView();
731
732 // TODO: in Qt4 the code should get a lot
733 // simpler and nicer due to Interview...
734 /*if (m_iconsView != 0) {
735 m_iconsView->beginItemUpdates();
736 }
737 if (m_iconsView != 0) {
738 m_iconsView->beginItemUpdates();
739 }*/
740
741 if (m_showProgress) {
742 m_statusBar->setProgressText(QString::null);
743 m_statusBar->setProgress(100);
744 m_showProgress = false;
745 }
746
747 KFileItemList items(m_dirLister->items());
748 KFileItemList::const_iterator it = items.begin();
749 const KFileItemList::const_iterator end = items.end();
750
751 m_fileCount = 0;
752 m_folderCount = 0;
753
754 while (it != end) {
755 KFileItem* item = *it;
756 //view->insertItem(item);
757 if (item->isDir()) {
758 ++m_folderCount;
759 }
760 else {
761 ++m_fileCount;
762 }
763 ++it;
764 }
765
766 updateStatusBar();
767
768 /*if (m_iconsView != 0) {
769 // Prevent a flickering of the icon view widget by giving a small
770 // timeslot to swallow asynchronous update events.
771 m_iconsView->setUpdatesEnabled(false);
772 QTimer::singleShot(10, this, SLOT(slotDelayedUpdate()));
773 }
774
775 if (m_iconsView != 0) {
776 m_iconsView->endItemUpdates();
777 m_refreshing = false;
778 }*/
779 }
780
781 void DolphinView::slotInfoMessage(const QString& msg)
782 {
783 m_statusBar->setMessage(msg, DolphinStatusBar::Information);
784 }
785
786 void DolphinView::slotErrorMessage(const QString& msg)
787 {
788 m_statusBar->setMessage(msg, DolphinStatusBar::Error);
789 }
790
791 void DolphinView::slotGrabActivation()
792 {
793 mainWindow()->setActiveView(this);
794 }
795
796 void DolphinView::emitSelectionChangedSignal()
797 {
798 emit selectionChanged();
799 }
800
801 void DolphinView::closeFilterBar()
802 {
803 m_filterBar->hide();
804 emit showFilterBarChanged(false);
805 }
806
807 void DolphinView::slotContentsMoving(int x, int y)
808 {
809 if (!m_refreshing) {
810 // Only emit a 'contents moved' signal if the user
811 // moved the content by adjusting the sliders. Adjustments
812 // resulted by refreshing a directory should not be respected.
813 emit contentsMoved(x, y);
814 }
815 }
816
817 /*KFileView* DolphinView::fileView() const
818 {
819 return (m_mode == DetailsView) ? static_cast<KFileView*>(m_iconsView) :
820 static_cast<KFileView*>(m_iconsView);
821 }*/
822
823 Q3ScrollView* DolphinView::scrollView() const
824 {
825 return 0; //(m_mode == DetailsView) ? static_cast<Q3ScrollView*>(m_iconsView) :
826 // static_cast<Q3ScrollView*>(m_iconsView);
827 }
828
829 ItemEffectsManager* DolphinView::itemEffectsManager() const
830 {
831 return 0;
832 }
833
834 void DolphinView::startDirLister(const KUrl& url, bool reload)
835 {
836 if (!url.isValid()) {
837 const QString location(url.pathOrUrl());
838 if (location.isEmpty()) {
839 m_statusBar->setMessage(i18n("The location is empty."), DolphinStatusBar::Error);
840 }
841 else {
842 m_statusBar->setMessage(i18n("The location '%1' is invalid.",location),
843 DolphinStatusBar::Error);
844 }
845 return;
846 }
847
848 // Only show the directory loading progress if the status bar does
849 // not contain another progress information. This means that
850 // the directory loading progress information has the lowest priority.
851 const QString progressText(m_statusBar->progressText());
852 m_showProgress = progressText.isEmpty() ||
853 (progressText == i18n("Loading directory..."));
854 if (m_showProgress) {
855 m_statusBar->setProgressText(i18n("Loading directory..."));
856 m_statusBar->setProgress(0);
857 }
858
859 m_refreshing = true;
860 m_dirLister->stop();
861 m_dirLister->openUrl(url, false, reload);
862 }
863
864 QString DolphinView::defaultStatusBarText() const
865 {
866 // TODO: the following code is not suitable for languages where multiple forms
867 // of plurals are given (e. g. in Poland three forms of plurals exist).
868 const int itemCount = m_folderCount + m_fileCount;
869
870 QString text;
871 if (itemCount == 1) {
872 text = i18n("1 Item");
873 }
874 else {
875 text = i18n("%1 Items",itemCount);
876 }
877
878 text += " (";
879
880 if (m_folderCount == 1) {
881 text += i18n("1 Folder");
882 }
883 else {
884 text += i18n("%1 Folders",m_folderCount);
885 }
886
887 text += ", ";
888
889 if (m_fileCount == 1) {
890 text += i18n("1 File");
891 }
892 else {
893 text += i18n("%1 Files",m_fileCount);
894 }
895
896 text += ")";
897
898 return text;
899 }
900
901 QString DolphinView::selectionStatusBarText() const
902 {
903 // TODO: the following code is not suitable for languages where multiple forms
904 // of plurals are given (e. g. in Poland three forms of plurals exist).
905 QString text;
906 const KFileItemList list = selectedItems();
907 if (list.isEmpty()) {
908 // TODO: assert(!list.isEmpty()) should be used, as this method is only invoked if
909 // DolphinView::hasSelection() is true. Inconsistent behavior?
910 return QString();
911 }
912
913 int fileCount = 0;
914 int folderCount = 0;
915 KIO::filesize_t byteSize = 0;
916 KFileItemList::const_iterator it = list.begin();
917 const KFileItemList::const_iterator end = list.end();
918 while (it != end){
919 KFileItem* item = *it;
920 if (item->isDir()) {
921 ++folderCount;
922 }
923 else {
924 ++fileCount;
925 byteSize += item->size();
926 }
927 ++it;
928 }
929
930 if (folderCount == 1) {
931 text = i18n("1 Folder selected");
932 }
933 else if (folderCount > 1) {
934 text = i18n("%1 Folders selected",folderCount);
935 }
936
937 if ((fileCount > 0) && (folderCount > 0)) {
938 text += ", ";
939 }
940
941 const QString sizeText(KIO::convertSize(byteSize));
942 if (fileCount == 1) {
943 text += i18n("1 File selected (%1)",sizeText);
944 }
945 else if (fileCount > 1) {
946 text += i18n("%1 Files selected (%1)",fileCount,sizeText);
947 }
948
949 return text;
950 }
951
952 QString DolphinView::renameIndexPresentation(int index, int itemCount) const
953 {
954 // assure that the string reprentation for all indicess have the same
955 // number of characters based on the given number of items
956 QString str(QString::number(index));
957 int chrCount = 1;
958 while (itemCount >= 10) {
959 ++chrCount;
960 itemCount /= 10;
961 }
962 str.reserve(chrCount);
963
964 const int insertCount = chrCount - str.length();
965 for (int i = 0; i < insertCount; ++i) {
966 str.insert(0, '0');
967 }
968 return str;
969 }
970
971 void DolphinView::slotShowFilterBar(bool show)
972 {
973 assert(m_filterBar != 0);
974 if (show) {
975 m_filterBar->show();
976 }
977 else {
978 m_filterBar->hide();
979 }
980 }
981
982 void DolphinView::declareViewActive()
983 {
984 mainWindow()->setActiveView( this );
985 }
986
987 void DolphinView::slotChangeNameFilter(const QString& nameFilter)
988 {
989 // The name filter of KDirLister does a 'hard' filtering, which
990 // means that only the items are shown where the names match
991 // exactly the filter. This is non-transparent for the user, which
992 // just wants to have a 'soft' filtering: does the name contain
993 // the filter string?
994 QString adjustedFilter(nameFilter);
995 adjustedFilter.insert(0, '*');
996 adjustedFilter.append('*');
997
998 m_dirLister->setNameFilter(adjustedFilter);
999 m_dirLister->emitChanges();
1000
1001 // TODO: this is a workaround for QIconView: the item position
1002 // stay as they are by filtering, only an inserting of an item
1003 // results to an automatic adjusting of the item position. In Qt4/KDE4
1004 // this workaround should get obsolete due to Interview.
1005 /*KFileView* view = fileView();
1006 if (view == m_iconsView) {
1007 KFileItem* first = view->firstFileItem();
1008 if (first != 0) {
1009 view->removeItem(first);
1010 view->insertItem(first);
1011 }
1012 }*/
1013 }
1014
1015 void DolphinView::applyModeToView()
1016 {
1017 //m_iconsView->setAlternatingRowColors(true);
1018 m_iconsView->setSelectionMode(QAbstractItemView::ExtendedSelection);
1019
1020 // TODO: the following code just tries to test some QListView capabilities
1021 switch (m_mode) {
1022 case IconsView:
1023 m_iconsView->setViewMode(QListView::IconMode);
1024 m_iconsView->setGridSize(QSize(128, 64));
1025 break;
1026
1027 case DetailsView:
1028 m_iconsView->setViewMode(QListView::ListMode);
1029 m_iconsView->setGridSize(QSize(256, 24));
1030 break;
1031
1032 //case PreviewsView:
1033 // m_iconsView->setViewMode(QListView::IconMode);
1034 // m_iconsView->setGridSize(QSize(128, 128));
1035 // break;
1036 }
1037 }
1038
1039 int DolphinView::columnIndex(Sorting sorting) const
1040 {
1041 int index = 0;
1042 switch (sorting) {
1043 case SortByName: index = KDirModel::Name; break;
1044 case SortBySize: index = KDirModel::Size; break;
1045 case SortByDate: index = KDirModel::ModifiedTime; break;
1046 default: assert(false);
1047 }
1048 return index;
1049 }
1050
1051 #include "dolphinview.moc"