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