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