From 8debdbafd8a42308bc460a76fd5ef08b13e91a43 Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Tue, 10 Jan 2012 15:50:18 +0100 Subject: SVN_SILENT made messages (.desktop file) --- src/dolphinpart.desktop | 1 + src/settings/kcm/kcmdolphingeneral.desktop | 1 + src/settings/kcm/kcmdolphinnavigation.desktop | 1 + src/settings/kcm/kcmdolphinservices.desktop | 1 + src/settings/kcm/kcmdolphinviewmodes.desktop | 1 + 5 files changed, 5 insertions(+) diff --git a/src/dolphinpart.desktop b/src/dolphinpart.desktop index ba42fad2b..d01b37a07 100644 --- a/src/dolphinpart.desktop +++ b/src/dolphinpart.desktop @@ -208,6 +208,7 @@ Name[ia]=Compacte Name[kk]=Ықшамды Name[km]=តូច​ល្មម Name[lt]=Kompaktiškas +Name[lv]=Kompakts Name[nb]=Kompakt Name[nds]=Drang Name[nl]=Compact diff --git a/src/settings/kcm/kcmdolphingeneral.desktop b/src/settings/kcm/kcmdolphingeneral.desktop index 632c655b4..5d760447d 100644 --- a/src/settings/kcm/kcmdolphingeneral.desktop +++ b/src/settings/kcm/kcmdolphingeneral.desktop @@ -305,6 +305,7 @@ X-KDE-Keywords[hu]=fájlkezelő X-KDE-Keywords[ia]=gerente de file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ +X-KDE-Keywords[lv]=failu pārvaldnieks X-KDE-Keywords[nb]=filbehandler X-KDE-Keywords[nds]=Dateipleger X-KDE-Keywords[nl]=bestandsbeheerder diff --git a/src/settings/kcm/kcmdolphinnavigation.desktop b/src/settings/kcm/kcmdolphinnavigation.desktop index 3b0b1a293..ba925d67d 100644 --- a/src/settings/kcm/kcmdolphinnavigation.desktop +++ b/src/settings/kcm/kcmdolphinnavigation.desktop @@ -305,6 +305,7 @@ X-KDE-Keywords[hu]=fájlkezelő X-KDE-Keywords[ia]=gerente de file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ +X-KDE-Keywords[lv]=failu pārvaldnieks X-KDE-Keywords[nb]=filbehandler X-KDE-Keywords[nds]=Dateipleger X-KDE-Keywords[nl]=bestandsbeheerder diff --git a/src/settings/kcm/kcmdolphinservices.desktop b/src/settings/kcm/kcmdolphinservices.desktop index 74a6711c4..841e1957d 100644 --- a/src/settings/kcm/kcmdolphinservices.desktop +++ b/src/settings/kcm/kcmdolphinservices.desktop @@ -256,6 +256,7 @@ X-KDE-Keywords[hu]=fájlkezelő X-KDE-Keywords[ia]=gerente de file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ +X-KDE-Keywords[lv]=failu pārvaldnieks X-KDE-Keywords[nb]=filbehandler X-KDE-Keywords[nds]=Dateipleger X-KDE-Keywords[nl]=bestandsbeheerder diff --git a/src/settings/kcm/kcmdolphinviewmodes.desktop b/src/settings/kcm/kcmdolphinviewmodes.desktop index 0e3c38308..5a7b5f2cd 100644 --- a/src/settings/kcm/kcmdolphinviewmodes.desktop +++ b/src/settings/kcm/kcmdolphinviewmodes.desktop @@ -303,6 +303,7 @@ X-KDE-Keywords[hu]=fájlkezelő X-KDE-Keywords[ia]=gerente de file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ +X-KDE-Keywords[lv]=failu pārvaldnieks X-KDE-Keywords[nb]=filbehandler X-KDE-Keywords[nds]=Dateipleger X-KDE-Keywords[nl]=bestandsbeheerder -- cgit v1.3 From 481eafc0c077f86b15834396ca6ef31abc8cdd8c Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Tue, 10 Jan 2012 17:06:40 +0100 Subject: Use the same icon size for the compact-view like the details-view per default --- src/settings/dolphin_compactmodesettings.kcfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/settings/dolphin_compactmodesettings.kcfg b/src/settings/dolphin_compactmodesettings.kcfg index bb050d480..40b9dfa32 100644 --- a/src/settings/dolphin_compactmodesettings.kcfg +++ b/src/settings/dolphin_compactmodesettings.kcfg @@ -30,11 +30,11 @@ - KIconLoader::SizeMedium + KIconLoader::SizeSmall - KIconLoader::SizeHuge + KIconLoader::SizeLarge -- cgit v1.3 From 4792037b0014be9f82c58b513f780c3485f82070 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Tue, 10 Jan 2012 17:22:30 +0100 Subject: Fix issue that shift + drag does not move files BUG: 291103 FIXED-IN: 4.8.0 --- src/kitemviews/kitemlistcontroller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 220748be7..9dda3384a 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -925,7 +925,7 @@ void KItemListController::startDragging() const QPixmap pixmap = m_view->createDragPixmap(selectedItems); drag->setPixmap(pixmap); - drag->exec(Qt::CopyAction); + drag->exec(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction, Qt::CopyAction); } KItemListWidget* KItemListController::hoveredWidget() const -- cgit v1.3 From 355b2c4fb65cc1390715187018e4d38561e584a0 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Wed, 11 Jan 2012 16:13:16 +0100 Subject: Prevent accessing an item with an invalid index --- src/kitemviews/kfileitemmodelrolesupdater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp index b00868a47..098c844ab 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.cpp +++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp @@ -310,7 +310,7 @@ void KFileItemModelRolesUpdater::slotItemsChanged(const KItemRangeList& itemRang // of the roles until the timer has exceeded. foreach (const KItemRange& itemRange, itemRanges) { int index = itemRange.index; - for (int count = itemRange.count; count >= 0; --count) { + for (int count = itemRange.count; count > 0; --count) { m_changedItems.insert(m_model->fileItem(index)); ++index; } -- cgit v1.3 From ac73b172fc5c08163b21d7edaf61aba46a899276 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Wed, 11 Jan 2012 22:33:20 +0100 Subject: Fix selection issue when expanding a tree The selection anchor must be reset when changing the current item to the root of the tree. BUG: 290832 FIXED-IN: 4.8.0 --- src/kitemviews/kitemlistcontroller.cpp | 2 ++ src/kitemviews/kitemlistselectionmanager.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 9dda3384a..d3365ab85 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -380,7 +380,9 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const } if (m_view->isAboveExpansionToggle(m_pressedIndex, m_pressedMousePos)) { + m_selectionManager->endAnchoredSelection(); m_selectionManager->setCurrentItem(m_pressedIndex); + m_selectionManager->beginAnchoredSelection(m_pressedIndex); return true; } diff --git a/src/kitemviews/kitemlistselectionmanager.h b/src/kitemviews/kitemlistselectionmanager.h index 4afad1f8b..43d0dcb80 100644 --- a/src/kitemviews/kitemlistselectionmanager.h +++ b/src/kitemviews/kitemlistselectionmanager.h @@ -92,7 +92,7 @@ private: KItemModelBase* m_model; friend class KItemListController; // Calls setModel() - friend class KItemListView; // Calls itemsInserted() and itemsRemoved() + friend class KItemListView; // Calls itemsInserted(), itemsRemoved() and itemsMoved() friend class KItemListSelectionManagerTest; }; -- cgit v1.3 From 419c95f4974ce8fb9d6aa5194f8c24b9a7a44c20 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sat, 14 Jan 2012 11:29:24 +0100 Subject: Fix current-item indicator in combination with the cleanlooks style Thanks to Christoph Feck for the hint. BUG: 290536 FIXED-IN: 4.8.0 --- src/kitemviews/kitemlistwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index 61e06078b..cd2bf4d40 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -132,7 +132,7 @@ void KItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* o focusRectOption.rect = textBounds.adjusted(1, 1, -1, -1); } - focusRectOption.state = QStyle::State_Enabled | QStyle::State_Item; + focusRectOption.state = QStyle::State_Enabled | QStyle::State_Item | QStyle::State_KeyboardFocusChange; if (m_selected) { focusRectOption.state |= QStyle::State_Selected; } -- cgit v1.3 From 33b9c7bed55542aac579b4e982161f09d33506df Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sat, 14 Jan 2012 19:25:49 +0100 Subject: Fix possible crash in version-control observer BUG: 291505 FIXED-IN: 4.8.0 --- src/views/versioncontrol/versioncontrolobserver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/versioncontrol/versioncontrolobserver.cpp b/src/views/versioncontrol/versioncontrolobserver.cpp index 86049efa3..ac4709069 100644 --- a/src/views/versioncontrol/versioncontrolobserver.cpp +++ b/src/views/versioncontrol/versioncontrolobserver.cpp @@ -195,7 +195,7 @@ void VersionControlObserver::slotThreadFinished() UpdateItemStatesThread* thread = m_updateItemStatesThread; m_updateItemStatesThread = 0; // The thread deletes itself automatically (see updateItemStates()) - if (!m_plugin) { + if (!m_plugin || !thread) { return; } -- cgit v1.3 From 9da248fa267f4d9e85cc12c1afbe859e4de7c233 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sat, 14 Jan 2012 20:02:11 +0100 Subject: Fix issue when deleting items with the context menu Thanks to Jekyll Wu for the analyses of the issue! BUG: 290307 BUG: 269096 BUG: 290954 BUG: 264583 FIXED-IN: 4.8.0 --- src/dolphincontextmenu.cpp | 16 ++++++++++------ src/dolphincontextmenu.h | 14 +++++++++++--- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/dolphincontextmenu.cpp b/src/dolphincontextmenu.cpp index 8d4a3173d..286d304c5 100644 --- a/src/dolphincontextmenu.cpp +++ b/src/dolphincontextmenu.cpp @@ -159,10 +159,10 @@ void DolphinContextMenu::slotKeyModifierPressed(Qt::Key key, bool pressed) void DolphinContextMenu::slotRemoveActionTriggered() { const KActionCollection* collection = m_mainWindow->actionCollection(); - if (m_shiftPressed) { - collection->action("delete")->trigger(); - } else { + if (moveToTrash()) { collection->action("move_to_trash")->trigger(); + } else { + collection->action("delete")->trigger(); } } @@ -449,7 +449,7 @@ QAction* DolphinContextMenu::createPasteAction() return action; } -KFileItemListProperties& DolphinContextMenu::selectedItemsProperties() +KFileItemListProperties& DolphinContextMenu::selectedItemsProperties() const { if (!m_selectedItemsProperties) { m_selectedItemsProperties = new KFileItemListProperties(m_selectedItems); @@ -541,13 +541,12 @@ void DolphinContextMenu::addCustomActions() void DolphinContextMenu::updateRemoveAction() { const KActionCollection* collection = m_mainWindow->actionCollection(); - const bool moveToTrash = selectedItemsProperties().isLocal() && !m_shiftPressed; // Using m_removeAction->setText(action->text()) does not apply the &-shortcut. // This is only done until the original action has been shown at least once. To // bypass this issue, the text and &-shortcut is applied manually. const QAction* action = 0; - if (moveToTrash) { + if (moveToTrash()) { action = collection->action("move_to_trash"); m_removeAction->setText(i18nc("@action:inmenu", "&Move to Trash")); } else { @@ -558,4 +557,9 @@ void DolphinContextMenu::updateRemoveAction() m_removeAction->setShortcuts(action->shortcuts()); } +bool DolphinContextMenu::moveToTrash() const +{ + return selectedItemsProperties().isLocal() && !m_shiftPressed; +} + #include "dolphincontextmenu.moc" diff --git a/src/dolphincontextmenu.h b/src/dolphincontextmenu.h index 7f43de368..9e8b804cd 100644 --- a/src/dolphincontextmenu.h +++ b/src/dolphincontextmenu.h @@ -139,7 +139,7 @@ private: QAction* createPasteAction(); - KFileItemListProperties& selectedItemsProperties(); + KFileItemListProperties& selectedItemsProperties() const; /** * Returns the file item for m_baseUrl. @@ -170,10 +170,18 @@ private: /** * Updates m_removeAction to represent the 'Delete'-action if the shift-key - * has been pressed. Otherwise it represents the 'Move to Trash'-action. + * has been pressed or the selection is not local. Otherwise it represents + * the 'Move to Trash'-action. */ void updateRemoveAction(); + /** + * @return True if no shift key has been pressed and the selection represents + * only local files. + * @see updateRemoveAction(), slotRemoveActionTriggered() + */ + bool moveToTrash() const; + private: struct Entry { @@ -201,7 +209,7 @@ private: KFileItem* m_baseFileItem; /// File item for m_baseUrl KFileItemList m_selectedItems; - KFileItemListProperties* m_selectedItemsProperties; + mutable KFileItemListProperties* m_selectedItemsProperties; int m_context; KonqCopyToMenu m_copyToMenu; -- cgit v1.3 From 538d9bf43f4164179f57495e582ef1f44331fde4 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sat, 14 Jan 2012 21:44:50 +0100 Subject: Fix "general settings" issues If the general settings for the "selection toggle" or "expanding folders during drag operations" are changed, those changes must be applied to the engine. --- src/views/dolphinitemlistcontainer.cpp | 13 +++++++++++++ src/views/dolphinitemlistcontainer.h | 6 ++++++ src/views/dolphinview.cpp | 3 --- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/views/dolphinitemlistcontainer.cpp b/src/views/dolphinitemlistcontainer.cpp index 9e7a15f74..d28aa363f 100644 --- a/src/views/dolphinitemlistcontainer.cpp +++ b/src/views/dolphinitemlistcontainer.cpp @@ -52,6 +52,7 @@ DolphinItemListContainer::DolphinItemListContainer(KDirLister* dirLister, m_fileItemListView->setEnabledSelectionToggles(GeneralSettings::showSelectionToggle()); controller()->setView(m_fileItemListView); + updateAutoActivationDelay(); updateFont(); updateGridSize(); } @@ -174,6 +175,10 @@ void DolphinItemListContainer::refresh() ViewModeSettings settings(viewMode()); settings.readConfig(); + beginTransaction(); + + m_fileItemListView->setEnabledSelectionToggles(GeneralSettings::showSelectionToggle()); + updateAutoActivationDelay(); updateFont(); updateGridSize(); @@ -183,6 +188,8 @@ void DolphinItemListContainer::refresh() << "imagethumbnail" << "jpegthumbnail"); m_fileItemListView->setEnabledPlugins(plugins); + + endTransaction(); } void DolphinItemListContainer::updateGridSize() @@ -247,6 +254,12 @@ void DolphinItemListContainer::updateFont() m_fileItemListView->setStyleOption(styleOption); } +void DolphinItemListContainer::updateAutoActivationDelay() +{ + const int delay = GeneralSettings::autoExpandFolders() ? 750 : -1; + controller()->setAutoActivationDelay(delay); +} + ViewModeSettings::ViewMode DolphinItemListContainer::viewMode() const { ViewModeSettings::ViewMode mode; diff --git a/src/views/dolphinitemlistcontainer.h b/src/views/dolphinitemlistcontainer.h index d91b96a34..251552cc8 100644 --- a/src/views/dolphinitemlistcontainer.h +++ b/src/views/dolphinitemlistcontainer.h @@ -73,6 +73,12 @@ private: void updateGridSize(); void updateFont(); + /** + * Updates the auto activation delay of the itemlist controller + * dependent on the 'autoExpand' setting from the general settings. + */ + void updateAutoActivationDelay(); + ViewModeSettings::ViewMode viewMode() const; private: diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index a31bf566d..83d80012c 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -137,9 +137,6 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) : KItemListController* controller = m_container->controller(); controller->setSelectionBehavior(KItemListController::MultiSelection); - if (GeneralSettings::autoExpandFolders()) { - controller->setAutoActivationDelay(750); - } connect(controller, SIGNAL(itemActivated(int)), this, SLOT(slotItemActivated(int))); connect(controller, SIGNAL(itemsActivated(QSet)), this, SLOT(slotItemsActivated(QSet))); connect(controller, SIGNAL(itemMiddleClicked(int)), this, SLOT(slotItemMiddleClicked(int))); -- cgit v1.3 From ed429d73097492591ee5025c80bea93eb4cbc23c Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sat, 14 Jan 2012 22:00:22 +0100 Subject: Assure an active view when activating an item This might not be the case when e.g. having a split view, having enabled the "auto expand folders" option and dragging an item from the active view to another folder of the inactive view. --- src/dolphinviewcontainer.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index df5fe6b15..2ad5bea5c 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -373,6 +373,11 @@ void DolphinViewContainer::slotFinishedPathLoading() void DolphinViewContainer::slotItemActivated(const KFileItem& item) { + // It is possible to activate items on inactive views by + // drag & drop operations. Assure that activating an item always + // results in an active view. + m_view->setActive(true); + KUrl url = item.targetUrl(); if (item.isDir()) { -- cgit v1.3 From df6a28653e1439885a719081f086070111484c3b Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sun, 15 Jan 2012 10:39:11 +0100 Subject: Don't show a expanding-toggle in the Folders Panel if there are no subdirectories BUG: 290745 FIXED-IN: 4.8.0 --- src/kitemviews/kfileitemmodel.cpp | 14 ++++++++++++++ src/kitemviews/kfileitemmodel.h | 7 +++++++ src/kitemviews/kfileitemmodelrolesupdater.cpp | 19 ++++++++++++++----- src/kitemviews/kfileitemmodelrolesupdater.h | 5 ++++- src/panels/folders/folderspanel.cpp | 2 +- 5 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index d81ddd965..b1a5fec42 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -183,6 +183,20 @@ bool KFileItemModel::showHiddenFiles() const return dirLister ? dirLister->showingDotFiles() : false; } +void KFileItemModel::setShowFoldersOnly(bool enabled) +{ + KDirLister* dirLister = m_dirLister.data(); + if (dirLister) { + dirLister->setDirOnlyMode(enabled); + } +} + +bool KFileItemModel::showFoldersOnly() const +{ + KDirLister* dirLister = m_dirLister.data(); + return dirLister ? dirLister->dirOnlyMode() : false; +} + QMimeData* KFileItemModel::createMimeData(const QSet& indexes) const { QMimeData* data = new QMimeData(); diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h index 07634655c..acb3eb153 100644 --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -73,6 +73,13 @@ public: void setShowHiddenFiles(bool show); bool showHiddenFiles() const; + /** + * If set to true, only folders are shown as items of the model. Files + * are ignored. + */ + void setShowFoldersOnly(bool enabled); + bool showFoldersOnly() const; + /** @reimp */ virtual QMimeData* createMimeData(const QSet& indexes) const; diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp index 098c844ab..a974094d5 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.cpp +++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp @@ -33,7 +33,7 @@ #include #include -// Required includes for subDirectoriesCount(): +// Required includes for subItemsCount(): #ifdef Q_WS_WIN #include #else @@ -770,7 +770,7 @@ QHash KFileItemModelRolesUpdater::rolesData(const KFileIte if ((getSizeRole || getIsExpandableRole) && item.isDir() && item.isLocalFile()) { const QString path = item.localPath(); - const int count = subDirectoriesCount(path); + const int count = subItemsCount(path); if (count >= 0) { if (getSizeRole) { data.insert("size", KIO::filesize_t(count)); @@ -826,16 +826,22 @@ KFileItemList KFileItemModelRolesUpdater::sortedItems(const QSet& ite return itemList; } -int KFileItemModelRolesUpdater::subDirectoriesCount(const QString& path) const +int KFileItemModelRolesUpdater::subItemsCount(const QString& path) const { const bool countHiddenFiles = m_model->showHiddenFiles(); + const bool showFoldersOnly = m_model->showFoldersOnly(); #ifdef Q_WS_WIN QDir dir(path); - QDir::Filters filters = QDir::AllEntries | QDir::NoDotAndDotDot | QDir::System; + QDir::Filters filters = QDir::NoDotAndDotDot | QDir::System; if (countHiddenFiles) { filters |= QDir::Hidden; } + if (showFoldersOnly) { + filters |= QDir::Dirs; + } else { + filters |= QDir::AllEntries; + } return dir.entryList(filters).count(); #else // Taken from kdelibs/kio/kio/kdirmodel.cpp @@ -857,7 +863,10 @@ int KFileItemModelRolesUpdater::subDirectoriesCount(const QString& path) const continue; } } - ++count; + + if (!showFoldersOnly || dirEntry->d_type == DT_DIR) { + ++count; + } } ::closedir(dir); } diff --git a/src/kitemviews/kfileitemmodelrolesupdater.h b/src/kitemviews/kfileitemmodelrolesupdater.h index 5ed45a6ec..b3945d14d 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.h +++ b/src/kitemviews/kfileitemmodelrolesupdater.h @@ -164,7 +164,10 @@ private: KFileItemList sortedItems(const QSet& items) const; - int subDirectoriesCount(const QString& path) const; + /** + * @return The number of items of the path \a path. + */ + int subItemsCount(const QString& path) const; private: // Property for setPaused()/isPaused(). diff --git a/src/panels/folders/folderspanel.cpp b/src/panels/folders/folderspanel.cpp index 86a1c0ccd..d9c8f71dc 100644 --- a/src/panels/folders/folderspanel.cpp +++ b/src/panels/folders/folderspanel.cpp @@ -140,7 +140,6 @@ void FoldersPanel::showEvent(QShowEvent* event) // This assures that no performance and memory overhead is given when the TreeView is not // used at all (see FoldersPanel::setUrl()). m_dirLister = new KDirLister(); - m_dirLister->setDirOnlyMode(true); m_dirLister->setAutoUpdate(true); m_dirLister->setMainWindow(window()); m_dirLister->setDelayedMimeTypes(true); @@ -163,6 +162,7 @@ void FoldersPanel::showEvent(QShowEvent* event) view->setOpacity(0); KFileItemModel* model = new KFileItemModel(m_dirLister, this); + model->setShowFoldersOnly(true); model->setShowHiddenFiles(FoldersPanelSettings::hiddenFilesShown()); // Use a QueuedConnection to give the view the possibility to react first on the // finished loading. -- cgit v1.3 From dd98f41056a4924acc09007ac82312e02cd66d7b Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sun, 15 Jan 2012 10:50:53 +0100 Subject: Don't select items if the selection toggle has been disabled --- src/kitemviews/kitemlistview.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 5dbc128b5..1f96b51ba 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -389,6 +389,10 @@ int KItemListView::itemAt(const QPointF& pos) const bool KItemListView::isAboveSelectionToggle(int index, const QPointF& pos) const { + if (!m_enabledSelectionToggles) { + return false; + } + const KItemListWidget* widget = m_visibleItems.value(index); if (widget) { const QRectF selectionToggleRect = widget->selectionToggleRect(); -- cgit v1.3 From 6e9c5ad58e238b3c6a3eef5159d9d56f89a36c42 Mon Sep 17 00:00:00 2001 From: Patrick Spendrin Date: Sun, 15 Jan 2012 15:49:34 +0100 Subject: fix build of tests on windows (cherry picked from commit 24213ae6cc2765ca8a2791aebb7c50bce0621cef) --- src/tests/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index d8f2250e9..c3360674c 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,6 +1,8 @@ set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BUILD_DIR}/.. ${KDE4_INCLUDES} ) +# needed on windows to correctly use the files from dolphinprivate +add_definitions(-DLIBDOLPHINPRIVATE_EXPORT=) # KItemListSelectionManagerTest set(kitemlistselectionmanagertest_SRCS kitemlistselectionmanagertest.cpp -- cgit v1.3 From d0fe7390b6cd39710c925dd9137ddacd3228aa7e Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Mon, 16 Jan 2012 09:28:43 +0100 Subject: SVN_SILENT made messages (.desktop file) --- src/dolphinpart.desktop | 5 +++++ src/settings/kcm/kcmdolphingeneral.desktop | 5 +++++ src/settings/kcm/kcmdolphinnavigation.desktop | 5 +++++ src/settings/kcm/kcmdolphinservices.desktop | 5 +++++ src/settings/kcm/kcmdolphinviewmodes.desktop | 5 +++++ 5 files changed, 25 insertions(+) diff --git a/src/dolphinpart.desktop b/src/dolphinpart.desktop index d01b37a07..fdb04c19a 100644 --- a/src/dolphinpart.desktop +++ b/src/dolphinpart.desktop @@ -213,9 +213,14 @@ Name[nb]=Kompakt Name[nds]=Drang Name[nl]=Compact Name[pa]=ਸੰਖੇਪ +Name[pl]=Kompaktowo Name[pt]=Compacto Name[pt_BR]=Compacto Name[sl]=Strnjeno +Name[sr]=Сажето +Name[sr@ijekavian]=Сажето +Name[sr@ijekavianlatin]=Sažeto +Name[sr@latin]=Sažeto Name[sv]=Kompakt Name[ug]=ئىخچام Name[uk]=Компактний diff --git a/src/settings/kcm/kcmdolphingeneral.desktop b/src/settings/kcm/kcmdolphingeneral.desktop index 5d760447d..45ff7862e 100644 --- a/src/settings/kcm/kcmdolphingeneral.desktop +++ b/src/settings/kcm/kcmdolphingeneral.desktop @@ -311,9 +311,14 @@ X-KDE-Keywords[nds]=Dateipleger X-KDE-Keywords[nl]=bestandsbeheerder X-KDE-Keywords[nn]=filhandsamar X-KDE-Keywords[pa]=ਫਾਇਲ ਮੈਨੇਜਰ +X-KDE-Keywords[pl]=menedżer plików X-KDE-Keywords[pt]=gestor de ficheiros X-KDE-Keywords[pt_BR]=gerenciador de arquivos X-KDE-Keywords[sl]=upravljalnik datotek +X-KDE-Keywords[sr]=file manager,менаџер фајлова +X-KDE-Keywords[sr@ijekavian]=file manager,менаџер фајлова +X-KDE-Keywords[sr@ijekavianlatin]=file manager,menadžer fajlova +X-KDE-Keywords[sr@latin]=file manager,menadžer fajlova X-KDE-Keywords[sv]=filhanterare X-KDE-Keywords[uk]=менеджер,керування,файл,файли X-KDE-Keywords[x-test]=xxfile managerxx diff --git a/src/settings/kcm/kcmdolphinnavigation.desktop b/src/settings/kcm/kcmdolphinnavigation.desktop index ba925d67d..83e7f65db 100644 --- a/src/settings/kcm/kcmdolphinnavigation.desktop +++ b/src/settings/kcm/kcmdolphinnavigation.desktop @@ -311,9 +311,14 @@ X-KDE-Keywords[nds]=Dateipleger X-KDE-Keywords[nl]=bestandsbeheerder X-KDE-Keywords[nn]=filhandsamar X-KDE-Keywords[pa]=ਫਾਇਲ ਮੈਨੇਜਰ +X-KDE-Keywords[pl]=menedżer plików X-KDE-Keywords[pt]=gestor de ficheiros X-KDE-Keywords[pt_BR]=gerenciador de arquivos X-KDE-Keywords[sl]=upravljalnik datotek +X-KDE-Keywords[sr]=file manager,менаџер фајлова +X-KDE-Keywords[sr@ijekavian]=file manager,менаџер фајлова +X-KDE-Keywords[sr@ijekavianlatin]=file manager,menadžer fajlova +X-KDE-Keywords[sr@latin]=file manager,menadžer fajlova X-KDE-Keywords[sv]=filhanterare X-KDE-Keywords[uk]=менеджер,керування,файл,файли X-KDE-Keywords[x-test]=xxfile managerxx diff --git a/src/settings/kcm/kcmdolphinservices.desktop b/src/settings/kcm/kcmdolphinservices.desktop index 841e1957d..369a136d0 100644 --- a/src/settings/kcm/kcmdolphinservices.desktop +++ b/src/settings/kcm/kcmdolphinservices.desktop @@ -262,9 +262,14 @@ X-KDE-Keywords[nds]=Dateipleger X-KDE-Keywords[nl]=bestandsbeheerder X-KDE-Keywords[nn]=filhandsamar X-KDE-Keywords[pa]=ਫਾਇਲ ਮੈਨੇਜਰ +X-KDE-Keywords[pl]=menedżer plików X-KDE-Keywords[pt]=gestor de ficheiros X-KDE-Keywords[pt_BR]=gerenciador de arquivos X-KDE-Keywords[sl]=upravljalnik datotek +X-KDE-Keywords[sr]=file manager,менаџер фајлова +X-KDE-Keywords[sr@ijekavian]=file manager,менаџер фајлова +X-KDE-Keywords[sr@ijekavianlatin]=file manager,menadžer fajlova +X-KDE-Keywords[sr@latin]=file manager,menadžer fajlova X-KDE-Keywords[sv]=filhanterare X-KDE-Keywords[uk]=менеджер,керування,файл,файли X-KDE-Keywords[x-test]=xxfile managerxx diff --git a/src/settings/kcm/kcmdolphinviewmodes.desktop b/src/settings/kcm/kcmdolphinviewmodes.desktop index 5a7b5f2cd..02fa07747 100644 --- a/src/settings/kcm/kcmdolphinviewmodes.desktop +++ b/src/settings/kcm/kcmdolphinviewmodes.desktop @@ -309,9 +309,14 @@ X-KDE-Keywords[nds]=Dateipleger X-KDE-Keywords[nl]=bestandsbeheerder X-KDE-Keywords[nn]=filhandsamar X-KDE-Keywords[pa]=ਫਾਇਲ ਮੈਨੇਜਰ +X-KDE-Keywords[pl]=menedżer plików X-KDE-Keywords[pt]=gestor de ficheiros X-KDE-Keywords[pt_BR]=gerenciador de arquivos X-KDE-Keywords[sl]=upravljalnik datotek +X-KDE-Keywords[sr]=file manager,менаџер фајлова +X-KDE-Keywords[sr@ijekavian]=file manager,менаџер фајлова +X-KDE-Keywords[sr@ijekavianlatin]=file manager,menadžer fajlova +X-KDE-Keywords[sr@latin]=file manager,menadžer fajlova X-KDE-Keywords[sv]=filhanterare X-KDE-Keywords[uk]=менеджер,керування,файл,файли X-KDE-Keywords[x-test]=xxfile managerxx -- cgit v1.3 From d93cf037ea6c37730cd7baf4ac14c9d4be4a3c7f Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Mon, 16 Jan 2012 15:37:32 +0100 Subject: Use new icon for "Show in groups" This allows adding the "Show in groups" action to the toolbar with a nice icon. CCBUG: 290632 --- src/views/dolphinviewactionhandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/dolphinviewactionhandler.cpp b/src/views/dolphinviewactionhandler.cpp index caa35230a..f66aebc84 100644 --- a/src/views/dolphinviewactionhandler.cpp +++ b/src/views/dolphinviewactionhandler.cpp @@ -195,6 +195,7 @@ void DolphinViewActionHandler::createActions() } KToggleAction* showInGroups = m_actionCollection->add("show_in_groups"); + showInGroups->setIcon(KIcon("view-group")); showInGroups->setText(i18nc("@action:inmenu View", "Show in Groups")); connect(showInGroups, SIGNAL(triggered(bool)), this, SLOT(toggleGroupedSorting(bool))); -- cgit v1.3 From 63cce810a3fd504c6077cbfb7bf10ed35ff1477f Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Mon, 16 Jan 2012 19:59:54 +0100 Subject: If an item is clicked to trigger it, clear the rest of the selection Note that the clearing is not done on mouse press, but on mouse release. The reason is that there are situations when multiple items are selected and pressing the mouse on one of them should not clear the selection (e.g., drag and drop of multiple items). BUG: 290854 REVIEW: 103703 FIXED-IN: 4.8.0 --- src/kitemviews/kitemlistcontroller.cpp | 22 ++++++++++++++++++++++ src/kitemviews/kitemlistcontroller.h | 1 + 2 files changed, 23 insertions(+) diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index d3365ab85..fedbe61a9 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -43,6 +43,7 @@ KItemListController::KItemListController(QObject* parent) : QObject(parent), m_singleClickActivation(KGlobalSettings::singleClick()), m_selectionTogglePressed(false), + m_clearSelectionIfItemsAreNotDragged(false), m_selectionBehavior(NoSelection), m_model(0), m_view(0), @@ -413,6 +414,13 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const (!shiftOrControlPressed && !pressedItemAlreadySelected); if (clearSelection) { m_selectionManager->clearSelection(); + } else if (pressedItemAlreadySelected && (event->buttons() & Qt::LeftButton)) { + // The user might want to start dragging multiple items, but if he clicks the item + // in order to trigger it instead, the other selected items must be deselected. + // However, we do not know yet what the user is going to do. + // -> remember that the user pressed an item which had been selected already and + // clear the selection in mouseReleaseEvent(), unless the items are dragged. + m_clearSelectionIfItemsAreNotDragged = true; } if (!shiftPressed) { @@ -505,7 +513,12 @@ bool KItemListController::mouseMoveEvent(QGraphicsSceneMouseEvent* event, const // done on the mouse-press event, but when using the selection-toggle on a // selected item the dragged item is not selected yet. m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Toggle); + } else { + // A selected item has been clicked to drag all selected items + // -> the selection should not be cleared when the mouse button is released. + m_clearSelectionIfItemsAreNotDragged = false; } + startDragging(); } } @@ -579,6 +592,14 @@ bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, con if (index >= 0 && index == m_pressedIndex) { // The release event is done above the same item as the press event + if (m_clearSelectionIfItemsAreNotDragged) { + // A selected item has been clicked, but no drag operation has been started + // -> clear the rest of the selection. + m_selectionManager->clearSelection(); + m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Select); + m_selectionManager->beginAnchoredSelection(m_pressedIndex); + } + if (event->button() & Qt::LeftButton) { bool emitItemActivated = true; if (m_view->isAboveExpansionToggle(index, pos)) { @@ -603,6 +624,7 @@ bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, con m_pressedMousePos = QPointF(); m_pressedIndex = -1; + m_clearSelectionIfItemsAreNotDragged = false; return false; } diff --git a/src/kitemviews/kitemlistcontroller.h b/src/kitemviews/kitemlistcontroller.h index b7efbde74..d0e5f72ec 100644 --- a/src/kitemviews/kitemlistcontroller.h +++ b/src/kitemviews/kitemlistcontroller.h @@ -260,6 +260,7 @@ private: private: bool m_singleClickActivation; bool m_selectionTogglePressed; + bool m_clearSelectionIfItemsAreNotDragged; SelectionBehavior m_selectionBehavior; KItemModelBase* m_model; KItemListView* m_view; -- cgit v1.3 From 52b6f68bf842d051a95a34728ce2f9c49c3ddb07 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Tue, 17 Jan 2012 09:57:58 +0100 Subject: Disable smooth-scrolling dependent on the graphics-effect level If the graphics-effect-level has been set to NoEffects (systemsettings -> Appearance -> Style -> Fine Tuning), the smooth scrolling in Dolphin will be disabled. Additionally the duration for the smooth-scrolling has been decreased from 200 ms to 100 ms to reduce the lag. A wrong calculation of the end-value has been fixed that might trigger a wrong position of the content. BUG: 291740 BUG: 291607 FIXED-IN: 4.8.0 --- src/kitemviews/kitemlistsmoothscroller.cpp | 10 ++++++++-- src/kitemviews/kitemlistwidget.cpp | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/kitemviews/kitemlistsmoothscroller.cpp b/src/kitemviews/kitemlistsmoothscroller.cpp index d966920cb..80f7f2883 100644 --- a/src/kitemviews/kitemlistsmoothscroller.cpp +++ b/src/kitemviews/kitemlistsmoothscroller.cpp @@ -19,6 +19,7 @@ #include "kitemlistsmoothscroller_p.h" +#include #include #include #include @@ -35,7 +36,8 @@ KItemListSmoothScroller::KItemListSmoothScroller(QScrollBar* scrollBar, m_animation(0) { m_animation = new QPropertyAnimation(this); - m_animation->setDuration(200); + const int duration = (KGlobalSettings::graphicEffectsLevel() == KGlobalSettings::NoEffects) ? 1 : 100; + m_animation->setDuration(duration); connect(m_animation, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)), this, SLOT(slotAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); @@ -100,7 +102,6 @@ void KItemListSmoothScroller::scrollContentsBy(qreal distance) } const qreal endOffset = currentOffset - distance; - if (m_smoothScrolling || animRunning) { qreal startOffset = currentOffset; if (animRunning) { @@ -109,6 +110,11 @@ void KItemListSmoothScroller::scrollContentsBy(qreal distance) // assures that animation proceeds even in cases where new end-offset are triggered // within a very short timeslots. startOffset += (endOffset - currentOffset) * 1000 / (m_animation->duration() * 60); + if (currentOffset < endOffset) { + startOffset = qMin(startOffset, endOffset); + } else { + startOffset = qMax(startOffset, endOffset); + } } m_animation->stop(); diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index cd2bf4d40..8e6c728f7 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -28,6 +28,7 @@ #include +#include #include #include #include @@ -243,7 +244,8 @@ void KItemListWidget::setHovered(bool hovered) if (!m_hoverAnimation) { m_hoverAnimation = new QPropertyAnimation(this, "hoverOpacity", this); - m_hoverAnimation->setDuration(200); + const int duration = (KGlobalSettings::graphicEffectsLevel() == KGlobalSettings::NoEffects) ? 1 : 200; + m_hoverAnimation->setDuration(duration); connect(m_hoverAnimation, SIGNAL(finished()), this, SLOT(slotHoverAnimationFinished())); } m_hoverAnimation->stop(); -- cgit v1.3 From cc9697b44cc64da2c7199a410416be79fe3a338e Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Tue, 17 Jan 2012 16:33:32 +0100 Subject: SVN_SILENT made messages (.desktop file) --- src/dolphinpart.desktop | 1 + src/settings/kcm/kcmdolphingeneral.desktop | 3 ++- src/settings/kcm/kcmdolphinnavigation.desktop | 1 + src/settings/kcm/kcmdolphinservices.desktop | 3 ++- src/settings/kcm/kcmdolphinviewmodes.desktop | 1 + 5 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/dolphinpart.desktop b/src/dolphinpart.desktop index fdb04c19a..5dc1755c6 100644 --- a/src/dolphinpart.desktop +++ b/src/dolphinpart.desktop @@ -205,6 +205,7 @@ Name[fi]=Tiivis Name[ga]=Dlúth Name[hu]=Kompakt Name[ia]=Compacte +Name[it]=Compatta Name[kk]=Ықшамды Name[km]=តូច​ល្មម Name[lt]=Kompaktiškas diff --git a/src/settings/kcm/kcmdolphingeneral.desktop b/src/settings/kcm/kcmdolphingeneral.desktop index 45ff7862e..27cfbf4b3 100644 --- a/src/settings/kcm/kcmdolphingeneral.desktop +++ b/src/settings/kcm/kcmdolphingeneral.desktop @@ -236,7 +236,7 @@ Comment[de]=Allgemeine Einstellungen am Dateimanager vornehmen Comment[el]=Ρύθμιση γενικών επιλογών διαχείρισης αρχείων Comment[en_GB]=Configure general file manager settings Comment[eo]=Agordi la ĝeneralan dosieradministrilon -Comment[es]=Configurar las preferencias gestor de archivos +Comment[es]=Configurar las preferencias del gestor de archivos Comment[et]=Failihalduri üldiste seadistuste seadistamine Comment[eu]=Konfiguratu fitxategi kudeatzailearen ezarpen orokorrak Comment[fi]=Muokkaa tiedostonhallinnan yleisasetuksia @@ -303,6 +303,7 @@ X-KDE-Keywords[fi]=tiedostonhallinta X-KDE-Keywords[ga]=bainisteoir comhad X-KDE-Keywords[hu]=fájlkezelő X-KDE-Keywords[ia]=gerente de file +X-KDE-Keywords[it]=gestore dei file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ X-KDE-Keywords[lv]=failu pārvaldnieks diff --git a/src/settings/kcm/kcmdolphinnavigation.desktop b/src/settings/kcm/kcmdolphinnavigation.desktop index 83e7f65db..a4b77fe76 100644 --- a/src/settings/kcm/kcmdolphinnavigation.desktop +++ b/src/settings/kcm/kcmdolphinnavigation.desktop @@ -303,6 +303,7 @@ X-KDE-Keywords[fi]=tiedostonhallinta X-KDE-Keywords[ga]=bainisteoir comhad X-KDE-Keywords[hu]=fájlkezelő X-KDE-Keywords[ia]=gerente de file +X-KDE-Keywords[it]=gestore dei file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ X-KDE-Keywords[lv]=failu pārvaldnieks diff --git a/src/settings/kcm/kcmdolphinservices.desktop b/src/settings/kcm/kcmdolphinservices.desktop index 369a136d0..a37b093c7 100644 --- a/src/settings/kcm/kcmdolphinservices.desktop +++ b/src/settings/kcm/kcmdolphinservices.desktop @@ -187,7 +187,7 @@ Comment[de]=Dateimanager-Dienste einrichten Comment[el]=Ρύθμιση υπηρεσιών διαχείρισης αρχείων Comment[en_GB]=Configure file manager services Comment[eo]=Agordi la dosieradministrilajn servojn -Comment[es]=Configurar las preferencias gestor de archivos +Comment[es]=Configurar las preferencias del gestor de archivos Comment[et]=Failihalduri teenuste seadistamine Comment[eu]=Konfiguratu fitxategi-kudeatzaile zerbitzuak Comment[fi]=Muokkaa tiedostonhallinnan palveluita @@ -254,6 +254,7 @@ X-KDE-Keywords[fi]=tiedostonhallinta X-KDE-Keywords[ga]=bainisteoir comhad X-KDE-Keywords[hu]=fájlkezelő X-KDE-Keywords[ia]=gerente de file +X-KDE-Keywords[it]=gestore dei file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ X-KDE-Keywords[lv]=failu pārvaldnieks diff --git a/src/settings/kcm/kcmdolphinviewmodes.desktop b/src/settings/kcm/kcmdolphinviewmodes.desktop index 02fa07747..b5d8644a0 100644 --- a/src/settings/kcm/kcmdolphinviewmodes.desktop +++ b/src/settings/kcm/kcmdolphinviewmodes.desktop @@ -301,6 +301,7 @@ X-KDE-Keywords[fi]=tiedostonhallinta X-KDE-Keywords[ga]=bainisteoir comhad X-KDE-Keywords[hu]=fájlkezelő X-KDE-Keywords[ia]=gerente de file +X-KDE-Keywords[it]=gestore dei file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ X-KDE-Keywords[lv]=failu pārvaldnieks -- cgit v1.3 From c712b9a42751ffc5006aafb08799019c5170e830 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Tue, 17 Jan 2012 21:08:39 +0100 Subject: Do a synchronous layout for dynamic item sizes when changing the geometry This prevents a delayed update when resizing the window e.g. in the details view. As no animated item position changes can happen for dynamic item sizes the synchronous relayout is fine from a performance point of view. BUG: 290953 FIXED-IN: 4.8.0 --- src/kitemviews/kitemlistview.cpp | 85 ++++++++++++++++++++++------------------ src/kitemviews/kitemlistview.h | 3 -- 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 1f96b51ba..49e23f9b7 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -355,20 +355,55 @@ void KItemListView::setGeometry(const QRectF& rect) return; } - if (m_model->count() > 0) { - prepareLayoutForIncreasedItemCount(rect.size(), LayouterSize); + const QSizeF newSize = rect.size(); + if (m_itemSize.isEmpty()) { + // The item size is dynamic: + // Changing the geometry does not require to do an expensive + // update of the visible-roles sizes, only the stretched sizes + // need to be adjusted to the new size. + updateStretchedVisibleRolesSizes(); + + if (m_useHeaderWidths) { + QSizeF dynamicItemSize = m_layouter->itemSize(); + + if (m_itemSize.width() < 0) { + const qreal requiredWidth = visibleRolesSizesWidthSum(); + if (newSize.width() > requiredWidth) { + dynamicItemSize.setWidth(newSize.width()); + } + const qreal headerWidth = qMax(newSize.width(), requiredWidth); + m_header->resize(headerWidth, m_header->size().height()); + } + + if (m_itemSize.height() < 0) { + const qreal requiredHeight = visibleRolesSizesHeightSum(); + if (newSize.height() > requiredHeight) { + dynamicItemSize.setHeight(newSize.height()); + } + // TODO: KItemListHeader is not prepared for vertical alignment + } + + m_layouter->setItemSize(dynamicItemSize); + } + + // Triggering a synchronous layout is fine from a performance point of view, + // as with dynamic item sizes no moving animation must be done. + m_layouter->setSize(newSize); + doLayout(Animation); } else { - m_layouter->setSize(rect.size()); - } + // The item size is not dynamic and most probably the geometry change results + // in animated position changes of the items. Trigger an asynchronous relayout + // with m_layoutTimer to prevent performance bottlenecks. + if (m_model->count() > 0) { + prepareLayoutForIncreasedItemCount(newSize, LayouterSize); + } else { + m_layouter->setSize(newSize); + } - if (!m_layoutTimer->isActive()) { - m_layoutTimer->start(); + if (!m_layoutTimer->isActive()) { + m_layoutTimer->start(); + } } - - // Changing the geometry does not require to do an expensive - // update of the visible-roles sizes, only the stretched sizes - // need to be adjusted to the new size. - updateStretchedVisibleRolesSizes(); } int KItemListView::itemAt(const QPointF& pos) const @@ -707,34 +742,6 @@ QList KItemListView::visibleItemListWidgets() const return m_visibleItems.values(); } -void KItemListView::resizeEvent(QGraphicsSceneResizeEvent* event) -{ - QGraphicsWidget::resizeEvent(event); - if (m_itemSize.isEmpty() && m_useHeaderWidths) { - QSizeF dynamicItemSize = m_layouter->itemSize(); - const QSizeF newSize = event->newSize(); - - if (m_itemSize.width() < 0) { - const qreal requiredWidth = visibleRolesSizesWidthSum(); - if (newSize.width() > requiredWidth) { - dynamicItemSize.setWidth(newSize.width()); - } - const qreal headerWidth = qMax(newSize.width(), requiredWidth); - m_header->resize(headerWidth, m_header->size().height()); - } - - if (m_itemSize.height() < 0) { - const qreal requiredHeight = visibleRolesSizesHeightSum(); - if (newSize.height() > requiredHeight) { - dynamicItemSize.setHeight(newSize.height()); - } - // TODO: KItemListHeader is not prepared for vertical alignment - } - - m_layouter->setItemSize(dynamicItemSize); - } -} - void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges) { updateVisibleRolesSizes(itemRanges); diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index d44a08c02..4969d01b7 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -286,9 +286,6 @@ protected: QList visibleItemListWidgets() const; - /** @reimp */ - virtual void resizeEvent(QGraphicsSceneResizeEvent* event); - protected slots: virtual void slotItemsInserted(const KItemRangeList& itemRanges); virtual void slotItemsRemoved(const KItemRangeList& itemRanges); -- cgit v1.3 From cc0ce2a7aade290595bb34891bb8a6ed4c78fd4d Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Tue, 17 Jan 2012 21:17:35 +0100 Subject: Fix probably wrong alternative background color Thanks to Nikita Skovoroda for the patch! CCMAIL: chalkerx@gmail.com --- src/kitemviews/kfileitemlistwidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kitemviews/kfileitemlistwidget.cpp b/src/kitemviews/kfileitemlistwidget.cpp index 62a2383d4..7e28c5d37 100644 --- a/src/kitemviews/kfileitemlistwidget.cpp +++ b/src/kitemviews/kfileitemlistwidget.cpp @@ -79,6 +79,7 @@ void KFileItemListWidget::setLayout(Layout layout) if (m_layout != layout) { m_layout = layout; m_dirtyLayout = true; + updateAdditionalInfoTextColor(); update(); } } -- cgit v1.3 From 61c742dada41194026063e9c9c7f40565c0693ff Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Tue, 17 Jan 2012 23:42:55 +0100 Subject: Avoid unnecessary animations when switching view modes Thanks to Nikita Skovoroda for the initial patch and the analyses. BUG: 290947 FIXED-IN: 4.8.0 --- src/kitemviews/kitemlistview.cpp | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 49e23f9b7..b6af42849 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -401,7 +401,7 @@ void KItemListView::setGeometry(const QRectF& rect) } if (!m_layoutTimer->isActive()) { - m_layoutTimer->start(); + m_layoutTimer->start(); } } } @@ -788,15 +788,23 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges) } m_layouter->markAsDirty(); - if (m_model->count() == count && maximumScrollOffset() > size().height()) { - const int scrollBarExtent = style()->pixelMetric(QStyle::PM_ScrollBarExtent); - QSizeF layouterSize = m_layouter->size(); - if (scrollOrientation() == Qt::Vertical) { - layouterSize.rwidth() -= scrollBarExtent; - } else { - layouterSize.rheight() -= scrollBarExtent; + if (m_model->count() == count && m_activeTransactions == 0) { + // Check whether a scrollbar is required to show the inserted items. In this case + // the size of the layouter will be decreased before calling doLayout(): This prevents + // an unnecessary temporary animation due to the geometry change of the inserted scrollbar. + const bool verticalScrollOrientation = (scrollOrientation() == Qt::Vertical); + const bool decreaseLayouterSize = ( verticalScrollOrientation && maximumScrollOffset() > size().height()) || + (!verticalScrollOrientation && maximumScrollOffset() > size().width()); + if (decreaseLayouterSize) { + const int scrollBarExtent = style()->pixelMetric(QStyle::PM_ScrollBarExtent); + QSizeF layouterSize = m_layouter->size(); + if (verticalScrollOrientation) { + layouterSize.rwidth() -= scrollBarExtent; + } else { + layouterSize.rheight() -= scrollBarExtent; + } + m_layouter->setSize(layouterSize); } - m_layouter->setSize(layouterSize); } if (!hasMultipleRanges) { @@ -880,7 +888,14 @@ void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges) m_layouter->markAsDirty(); if (!hasMultipleRanges) { + // The decrease-layout-size optimization in KItemListView::slotItemsInserted() + // assumes an updated geometry. If items are removed during an active transaction, + // the transaction will be temporary deactivated so that doLayout() triggers a + // geometry update if necessary. + const int activeTransactions = m_activeTransactions; + m_activeTransactions = 0; doLayout(Animation, index, -count); + m_activeTransactions = activeTransactions; } } -- cgit v1.3 From aff9b9570edf833eed12850c19b6833291822ea9 Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Wed, 18 Jan 2012 09:35:43 +0100 Subject: Fix typo, which caused a Qt runtime warning when closing Dolphin --- src/kitemviews/kitemlistcontainer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kitemviews/kitemlistcontainer.cpp b/src/kitemviews/kitemlistcontainer.cpp index 930762e62..58f2e3cd6 100644 --- a/src/kitemviews/kitemlistcontainer.cpp +++ b/src/kitemviews/kitemlistcontainer.cpp @@ -173,7 +173,7 @@ void KItemListContainer::slotViewChanged(KItemListView* current, KItemListView* QGraphicsScene* scene = static_cast(viewport())->scene(); if (previous) { scene->removeItem(previous); - disconnect(current, SIGNAL(scrollOrientationChanged(Qt::Orientation,Qt::Orientation)), this, SLOT(slotScrollOrientationChanged(Qt::Orientation,Qt::Orientation))); + disconnect(previous, SIGNAL(scrollOrientationChanged(Qt::Orientation,Qt::Orientation)), this, SLOT(slotScrollOrientationChanged(Qt::Orientation,Qt::Orientation))); disconnect(previous, SIGNAL(scrollOffsetChanged(qreal,qreal)), this, SLOT(updateScrollOffsetScrollBar())); disconnect(previous, SIGNAL(maximumScrollOffsetChanged(qreal,qreal)), this, SLOT(updateScrollOffsetScrollBar())); disconnect(previous, SIGNAL(itemOffsetChanged(qreal,qreal)), this, SLOT(updateItemOffsetScrollBar())); -- cgit v1.3 From 6a338f28e5cbdfb51aa391815453fe52c33ec590 Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Wed, 18 Jan 2012 10:18:47 +0100 Subject: Make PageUp/PageDown work in Dolphin's new view engine BUG: 288748 FIXED-IN: 4.8.0 REVIEW: 103721 --- src/kitemviews/kitemlistcontroller.cpp | 85 ++++++++++++++++++++++++++++------ src/kitemviews/kitemlistcontroller.h | 12 ++--- 2 files changed, 76 insertions(+), 21 deletions(-) diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index fedbe61a9..0f22d70bb 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -1,5 +1,6 @@ /*************************************************************************** * Copyright (C) 2011 by Peter Penz * + * Copyright (C) 2012 by Frank Reininghaus * * * * Based on the Itemviews NG project from Trolltech Labs: * * http://qt.gitorious.org/qt-labs/itemviews-ng * @@ -239,12 +240,68 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) case Qt::Key_Up: updateKeyboardAnchor(); - index = previousRowIndex(); + index = previousRowIndex(index); break; case Qt::Key_Down: updateKeyboardAnchor(); - index = nextRowIndex(); + index = nextRowIndex(index); + break; + + case Qt::Key_PageUp: + if (m_view->scrollOrientation() == Qt::Horizontal) { + // The new current index should correspond to the first item in the current column. + int newIndex = qMax(index - 1, 0); + while (newIndex != index && m_view->itemRect(newIndex).topLeft().y() < m_view->itemRect(index).topLeft().y()) { + index = newIndex; + newIndex = qMax(index - 1, 0); + } + m_keyboardAnchorIndex = index; + m_keyboardAnchorPos = keyboardAnchorPos(index); + } else { + const qreal currentItemBottom = m_view->itemRect(index).bottomLeft().y(); + const qreal height = m_view->geometry().height(); + + // The new current item should be the first item in the current + // column whose itemRect's top coordinate is larger than targetY. + const qreal targetY = currentItemBottom - height; + + updateKeyboardAnchor(); + int newIndex = previousRowIndex(index); + do { + index = newIndex; + updateKeyboardAnchor(); + newIndex = previousRowIndex(index); + } while (m_view->itemRect(newIndex).topLeft().y() > targetY && newIndex != index); + } + break; + + case Qt::Key_PageDown: + if (m_view->scrollOrientation() == Qt::Horizontal) { + // The new current index should correspond to the last item in the current column. + int newIndex = qMin(index + 1, m_model->count() - 1); + while (newIndex != index && m_view->itemRect(newIndex).topLeft().y() > m_view->itemRect(index).topLeft().y()) { + index = newIndex; + newIndex = qMin(index + 1, m_model->count() - 1); + } + m_keyboardAnchorIndex = index; + m_keyboardAnchorPos = keyboardAnchorPos(index); + } else { + const qreal currentItemTop = m_view->itemRect(index).topLeft().y(); + const qreal height = m_view->geometry().height(); + + // The new current item should be the last item in the current + // column whose itemRect's bottom coordinate is smaller than targetY. + const qreal targetY = currentItemTop + height; + + updateKeyboardAnchor(); + int newIndex = nextRowIndex(index); + do { + index = newIndex; + updateKeyboardAnchor(); + newIndex = nextRowIndex(index); + } while (m_view->itemRect(newIndex).bottomLeft().y() < targetY && newIndex != index); + } break; case Qt::Key_Enter: @@ -994,24 +1051,23 @@ void KItemListController::updateKeyboardAnchor() } } -int KItemListController::nextRowIndex() const +int KItemListController::nextRowIndex(int index) const { - const int currentIndex = m_selectionManager->currentItem(); if (m_keyboardAnchorIndex < 0) { - return currentIndex; + return index; } const int maxIndex = m_model->count() - 1; - if (currentIndex == maxIndex) { - return currentIndex; + if (index == maxIndex) { + return index; } // Calculate the index of the last column inside the row of the current index - int lastColumnIndex = currentIndex; + int lastColumnIndex = index; while (keyboardAnchorPos(lastColumnIndex + 1) > keyboardAnchorPos(lastColumnIndex)) { ++lastColumnIndex; if (lastColumnIndex >= maxIndex) { - return currentIndex; + return index; } } @@ -1032,19 +1088,18 @@ int KItemListController::nextRowIndex() const return nextRowIndex; } -int KItemListController::previousRowIndex() const +int KItemListController::previousRowIndex(int index) const { - const int currentIndex = m_selectionManager->currentItem(); - if (m_keyboardAnchorIndex < 0 || currentIndex == 0) { - return currentIndex; + if (m_keyboardAnchorIndex < 0 || index == 0) { + return index; } // Calculate the index of the first column inside the row of the current index - int firstColumnIndex = currentIndex; + int firstColumnIndex = index; while (keyboardAnchorPos(firstColumnIndex - 1) < keyboardAnchorPos(firstColumnIndex)) { --firstColumnIndex; if (firstColumnIndex <= 0) { - return currentIndex; + return index; } } diff --git a/src/kitemviews/kitemlistcontroller.h b/src/kitemviews/kitemlistcontroller.h index d0e5f72ec..9ac4c76e6 100644 --- a/src/kitemviews/kitemlistcontroller.h +++ b/src/kitemviews/kitemlistcontroller.h @@ -238,16 +238,16 @@ private: void updateKeyboardAnchor(); /** - * @return Index for the next row based on the current index. - * If there is no next row the current index will be returned. + * @return Index for the next row based on \a index. + * If there is no next row \a index will be returned. */ - int nextRowIndex() const; + int nextRowIndex(int index) const; /** - * @return Index for the previous row based on the current index. - * If there is no previous row the current index will be returned. + * @return Index for the previous row based on \a index. + * If there is no previous row \a index will be returned. */ - int previousRowIndex() const; + int previousRowIndex(int index) const; /** * Helper method for updateKeyboardAnchor(), previousRowIndex() and nextRowIndex(). -- cgit v1.3 From 7dc1741277b1cb6b9cb1f3c0ee754b32ad347a87 Mon Sep 17 00:00:00 2001 From: Dawit Alemayehu Date: Wed, 18 Jan 2012 13:30:54 -0500 Subject: When populating the "Show Remote Encoding" menu, put the check mark besides the correct saved remote encoding charset. BUG: 186289 FIXED-IN: 4.8.0 REVIEW: 103730 --- src/views/dolphinremoteencoding.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/views/dolphinremoteencoding.cpp b/src/views/dolphinremoteencoding.cpp index 8644f5cc2..375b3fd46 100644 --- a/src/views/dolphinremoteencoding.cpp +++ b/src/views/dolphinremoteencoding.cpp @@ -132,14 +132,14 @@ void DolphinRemoteEncoding::updateMenu() m_menu->menu()->actions().at(i)->setChecked(false); } - QString charset = KIO::SlaveConfig::self()->configData(m_currentURL.protocol(), - m_currentURL.host(), DATA_KEY); + QString charset = KGlobal::charsets()->descriptionForEncoding(KIO::SlaveConfig::self()->configData(m_currentURL.protocol(), + m_currentURL.host(), DATA_KEY)); if (!charset.isEmpty()) { int id = 0; bool isFound = false; for (int i = 0; i < m_encodingDescriptions.size(); i++) { - if (m_encodingDescriptions.at(i).contains(charset)) { + if (m_encodingDescriptions.at(i) == charset) { isFound = true; id = i; break; -- cgit v1.3 From 8b73ea3061eec0b0b9f11db6965ee77b487c0633 Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Thu, 19 Jan 2012 19:52:51 +0100 Subject: Do not make items invisible when turning off previews This commit fixes a problem in KItemListView::doLayout(): This function assumed that firstVisibleIndex is a constant. However, if the view is scrolled to the bottom with previews enabled, and then previews are disabled (and the icon size is much smaller without previews), this function changes the scroll offset, which also changes the the first visible index. Using the unchanged variable causes trouble later on (i.e., it makes items which are actually inside the view area invisible). lastVisibleIndex is not needed before the scroll offset change and is const after that, so its calculation is moved a few lines down. BUG: 291841 FIXED-IN: 4.8.1 REVIEW: 103731 --- src/kitemviews/kitemlistview.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index b6af42849..281fe96f8 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -1292,8 +1292,7 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha return; } - const int firstVisibleIndex = m_layouter->firstVisibleIndex(); - const int lastVisibleIndex = m_layouter->lastVisibleIndex(); + int firstVisibleIndex = m_layouter->firstVisibleIndex(); if (firstVisibleIndex < 0) { emitOffsetChanges(); return; @@ -1306,8 +1305,11 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha const qreal maxOffsetToShowFullRange = maximumScrollOffset() - visibleOffsetRange; if (scrollOffset() > maxOffsetToShowFullRange) { m_layouter->setScrollOffset(qMax(qreal(0), maxOffsetToShowFullRange)); + firstVisibleIndex = m_layouter->firstVisibleIndex(); } + const int lastVisibleIndex = m_layouter->lastVisibleIndex(); + // Determine all items that are completely invisible and might be // reused for items that just got (at least partly) visible. // Items that do e.g. an animated moving of their position are not -- cgit v1.3 From 0f2faadef4852ecda801004311078264d165765f Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Sun, 22 Jan 2012 09:28:28 +0100 Subject: SVN_SILENT made messages (.desktop file) --- src/dolphinpart.desktop | 1 + src/settings/kcm/kcmdolphingeneral.desktop | 1 + src/settings/kcm/kcmdolphinnavigation.desktop | 1 + src/settings/kcm/kcmdolphinservices.desktop | 1 + src/settings/kcm/kcmdolphinviewmodes.desktop | 1 + 5 files changed, 5 insertions(+) diff --git a/src/dolphinpart.desktop b/src/dolphinpart.desktop index 5dc1755c6..a8905bcef 100644 --- a/src/dolphinpart.desktop +++ b/src/dolphinpart.desktop @@ -208,6 +208,7 @@ Name[ia]=Compacte Name[it]=Compatta Name[kk]=Ықшамды Name[km]=តូច​ល្មម +Name[ko]=축소됨 Name[lt]=Kompaktiškas Name[lv]=Kompakts Name[nb]=Kompakt diff --git a/src/settings/kcm/kcmdolphingeneral.desktop b/src/settings/kcm/kcmdolphingeneral.desktop index 27cfbf4b3..fb97413b1 100644 --- a/src/settings/kcm/kcmdolphingeneral.desktop +++ b/src/settings/kcm/kcmdolphingeneral.desktop @@ -306,6 +306,7 @@ X-KDE-Keywords[ia]=gerente de file X-KDE-Keywords[it]=gestore dei file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ +X-KDE-Keywords[ko]=파일 관리자 X-KDE-Keywords[lv]=failu pārvaldnieks X-KDE-Keywords[nb]=filbehandler X-KDE-Keywords[nds]=Dateipleger diff --git a/src/settings/kcm/kcmdolphinnavigation.desktop b/src/settings/kcm/kcmdolphinnavigation.desktop index a4b77fe76..8998b64fb 100644 --- a/src/settings/kcm/kcmdolphinnavigation.desktop +++ b/src/settings/kcm/kcmdolphinnavigation.desktop @@ -306,6 +306,7 @@ X-KDE-Keywords[ia]=gerente de file X-KDE-Keywords[it]=gestore dei file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ +X-KDE-Keywords[ko]=파일 관리자 X-KDE-Keywords[lv]=failu pārvaldnieks X-KDE-Keywords[nb]=filbehandler X-KDE-Keywords[nds]=Dateipleger diff --git a/src/settings/kcm/kcmdolphinservices.desktop b/src/settings/kcm/kcmdolphinservices.desktop index a37b093c7..4307daa39 100644 --- a/src/settings/kcm/kcmdolphinservices.desktop +++ b/src/settings/kcm/kcmdolphinservices.desktop @@ -257,6 +257,7 @@ X-KDE-Keywords[ia]=gerente de file X-KDE-Keywords[it]=gestore dei file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ +X-KDE-Keywords[ko]=파일 관리자 X-KDE-Keywords[lv]=failu pārvaldnieks X-KDE-Keywords[nb]=filbehandler X-KDE-Keywords[nds]=Dateipleger diff --git a/src/settings/kcm/kcmdolphinviewmodes.desktop b/src/settings/kcm/kcmdolphinviewmodes.desktop index b5d8644a0..6507fa294 100644 --- a/src/settings/kcm/kcmdolphinviewmodes.desktop +++ b/src/settings/kcm/kcmdolphinviewmodes.desktop @@ -304,6 +304,7 @@ X-KDE-Keywords[ia]=gerente de file X-KDE-Keywords[it]=gestore dei file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ +X-KDE-Keywords[ko]=파일 관리자 X-KDE-Keywords[lv]=failu pārvaldnieks X-KDE-Keywords[nb]=filbehandler X-KDE-Keywords[nds]=Dateipleger -- cgit v1.3 From 30b65ef9395786d00c193175bc1e2eeb6aefb518 Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Mon, 23 Jan 2012 19:28:21 +0100 Subject: Make sure that Control+click toggles the selection state This commit fixes a regression caused by the recent commit 9f711b5f2e1d1fd856cd6b033e6adb96f9b46d8a. BUG: 292250 --- src/kitemviews/kitemlistcontroller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 0f22d70bb..560d16042 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -471,7 +471,7 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const (!shiftOrControlPressed && !pressedItemAlreadySelected); if (clearSelection) { m_selectionManager->clearSelection(); - } else if (pressedItemAlreadySelected && (event->buttons() & Qt::LeftButton)) { + } else if (pressedItemAlreadySelected && !shiftOrControlPressed && (event->buttons() & Qt::LeftButton)) { // The user might want to start dragging multiple items, but if he clicks the item // in order to trigger it instead, the other selected items must be deselected. // However, we do not know yet what the user is going to do. -- cgit v1.3 From 3a84f2223b71dba0c6a2934b8c7cf443306f5a3b Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Wed, 25 Jan 2012 15:18:09 +0100 Subject: Terminal: only consider process IDs > 0 Thanks to Jekyll Wu for the analyses. CCBUG: 286367 --- src/panels/terminal/terminalpanel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/panels/terminal/terminalpanel.cpp b/src/panels/terminal/terminalpanel.cpp index b3bf0506f..19c6cb1b7 100644 --- a/src/panels/terminal/terminalpanel.cpp +++ b/src/panels/terminal/terminalpanel.cpp @@ -127,7 +127,10 @@ void TerminalPanel::sendCdToTerminal(const QString& dir) // current line before sending a new input. This is mandatory, // otherwise sending a 'cd x' to a existing 'rm -rf *' might // result in data loss. As workaround SIGINT is send. - kill(m_terminal->terminalProcessId(), SIGINT); + const int processId = m_terminal->terminalProcessId(); + if (processId > 0) { + kill(processId, SIGINT); + } } m_terminal->sendInput("cd " + KShell::quoteArg(dir) + '\n'); -- cgit v1.3 From 2a812eaf7d733699c3d5e61497ca34ac2c2e2840 Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Wed, 25 Jan 2012 21:30:57 +0100 Subject: Handle folder names containing spaces correctly in the Folders Panel The problem was that KFileItemModel::setExpanded() used KUrl::url() to determine the names of the subfolders. This method encodes special characters, such that comparing the folder names with the unencoded URLs stored in the model fails. Using KUrl::path(), which does not encode special characters, fixes the problem. BUG: 291781 FIXED-IN: 4.8.1 --- src/kitemviews/kfileitemmodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index b1a5fec42..fb089077b 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -482,7 +482,7 @@ void KFileItemModel::setExpanded(const QSet& urls) return; } - const int pos = dirLister->url().url().length(); + const int pos = dirLister->url().path().length(); // Assure that each sub-path of the URLs that should be // expanded is added to m_urlsToExpand too. KDirLister @@ -493,7 +493,7 @@ void KFileItemModel::setExpanded(const QSet& urls) const KUrl& url = it1.next(); KUrl urlToExpand = dirLister->url(); - const QStringList subDirs = url.url().mid(pos).split(QDir::separator()); + const QStringList subDirs = url.path().mid(pos).split(QDir::separator()); for (int i = 0; i < subDirs.count(); ++i) { urlToExpand.addPath(subDirs.at(i)); m_urlsToExpand.insert(urlToExpand); -- cgit v1.3 From 05fec8d24bcfbcb7bccc923df95776c4dc89e99d Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Fri, 27 Jan 2012 21:30:27 +0100 Subject: Don't crash when opening a tab with enabled split view BUG: 292470 FIXED-IN: 4.8.1 --- src/dolphinmainwindow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 4502e703f..60fded631 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -510,12 +510,12 @@ void DolphinMainWindow::openNewTab(const KUrl& url) actionCollection()->action("close_tab")->setEnabled(true); - // provide a split view, if the startup settings are set this way + // Provide a split view, if the startup settings are set this way if (GeneralSettings::splitView()) { const int newTabIndex = m_viewTab.count() - 1; createSecondaryView(newTabIndex); - viewTab.secondaryView->setActive(true); - viewTab.isPrimaryViewActive = false; + m_viewTab[newTabIndex].secondaryView->setActive(true); + m_viewTab[newTabIndex].isPrimaryViewActive = false; } if (focusWidget) { -- cgit v1.3 From f8f5cf8760fbed119c7a171506c9c43b31d56e15 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Fri, 27 Jan 2012 21:52:29 +0100 Subject: Fix regression: Allow dragging items on a tab BUG: 292505 FIXED-IN: 4.8.1 --- src/dolphinmainwindow.cpp | 7 ++++--- src/views/dolphinview.cpp | 17 ++++++----------- src/views/dolphinview.h | 13 +------------ 3 files changed, 11 insertions(+), 26 deletions(-) diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 60fded631..3654ed6c9 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -41,6 +41,7 @@ #include "statusbar/dolphinstatusbar.h" #include "views/dolphinviewactionhandler.h" #include "views/dolphinremoteencoding.h" +#include "views/draganddrophelper.h" #include "views/viewproperties.h" #ifndef Q_OS_WIN @@ -1327,9 +1328,9 @@ void DolphinMainWindow::tabDropEvent(int tab, QDropEvent* event) const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData()); if (!urls.isEmpty() && tab != -1) { const ViewTab& viewTab = m_viewTab[tab]; - const KUrl destPath = viewTab.isPrimaryViewActive ? viewTab.primaryView->url() : viewTab.secondaryView->url(); - Q_UNUSED(destPath); - //DragAndDropHelper::instance().dropUrls(KFileItem(), destPath, event, m_tabBar); + const DolphinView* view = viewTab.isPrimaryViewActive ? viewTab.primaryView->view() + : viewTab.secondaryView->view(); + DragAndDropHelper::dropUrls(view->rootItem(), event); } } diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 83d80012c..539fcaacc 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -863,16 +863,6 @@ void DolphinView::emitSelectionChangedSignal() emit selectionChanged(selectedItems()); } -void DolphinView::dropUrls(const KFileItem& destItem, - const KUrl& destPath, - QDropEvent* event) -{ - Q_UNUSED(destItem); - Q_UNUSED(destPath); - markPastedUrlsAsSelected(event->mimeData()); - //DragAndDropHelper::instance().dropUrls(destItem, destPath, event, this); -} - void DolphinView::updateSorting(DolphinView::Sorting sorting) { ViewProperties props(url()); @@ -969,7 +959,12 @@ bool DolphinView::hasSelection() const KFileItem DolphinView::rootItem() const { - return m_dirLister->rootItem(); + KFileItem item = m_dirLister->rootItem(); + if (item.isNull()) { + // The directory has not been loaded yet + item = KFileItem(KFileItem::Unknown, KFileItem::Unknown, url()); + } + return item; } void DolphinView::observeCreatedItem(const KUrl& url) diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index a6b8fe3ae..197a41046 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -336,9 +336,7 @@ public: bool hasSelection() const; /** - * Returns the root item which represents the current URL. Note that the returned - * item can be null (KFileItem::isNull() will return true) in case that the directory - * has not been loaded. + * Returns the root item which represents the current URL. */ KFileItem rootItem() const; @@ -580,15 +578,6 @@ private slots: */ void emitSelectionChangedSignal(); - /** - * Drops dragged URLs to the destination path \a destPath. If - * the URLs are dropped above an item inside the destination path, - * the item is indicated by \a destItem. - */ - void dropUrls(const KFileItem& destItem, - const KUrl& destPath, - QDropEvent* event); - /** * Updates the view properties of the current URL to the * sorting given by \a sorting. -- cgit v1.3 From bcd2828f96903d962d059db51750f5e13ea47f08 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sat, 28 Jan 2012 10:46:59 +0100 Subject: --warning --- src/settings/viewmodes/viewmodesettings.cpp | 4 +++- src/settings/viewmodes/viewsettingstab.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/settings/viewmodes/viewmodesettings.cpp b/src/settings/viewmodes/viewmodesettings.cpp index 4cb59069a..5b9334c22 100644 --- a/src/settings/viewmodes/viewmodesettings.cpp +++ b/src/settings/viewmodes/viewmodesettings.cpp @@ -37,7 +37,9 @@ case IconsMode: value = IconsModeSettings::getValue(); break; \ case CompactMode: value = CompactModeSettings::getValue(); break; \ case DetailsMode: value = DetailsModeSettings::getValue(); break; \ - default: Q_ASSERT(false); break; \ + default: value = IconsModeSettings::getValue(); \ + Q_ASSERT(false); \ + break; \ } \ return value diff --git a/src/settings/viewmodes/viewsettingstab.cpp b/src/settings/viewmodes/viewsettingstab.cpp index 6ad8663a6..b5cacf787 100644 --- a/src/settings/viewmodes/viewsettingstab.cpp +++ b/src/settings/viewmodes/viewsettingstab.cpp @@ -181,7 +181,9 @@ ViewModeSettings::ViewMode ViewSettingsTab::viewMode() const case ViewSettingsTab::IconsMode: mode = ViewModeSettings::IconsMode; break; case ViewSettingsTab::CompactMode: mode = ViewModeSettings::CompactMode; break; case ViewSettingsTab::DetailsMode: mode = ViewModeSettings::DetailsMode; break; - default: Q_ASSERT(false); break; + default: mode = ViewModeSettings::IconsMode; + Q_ASSERT(false); + break; } return mode; -- cgit v1.3 From 2c3e9fa5b5052db2d735f28156a2f9b20e7138a2 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sat, 28 Jan 2012 10:50:38 +0100 Subject: --warning --- src/views/dolphinitemlistcontainer.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/views/dolphinitemlistcontainer.cpp b/src/views/dolphinitemlistcontainer.cpp index d28aa363f..38adfde64 100644 --- a/src/views/dolphinitemlistcontainer.cpp +++ b/src/views/dolphinitemlistcontainer.cpp @@ -227,7 +227,11 @@ void DolphinItemListContainer::updateGridSize() itemHeight = innerMargin * 2 + qMax(iconSize, styleOption.fontMetrics.height()); break; } - default: Q_ASSERT(false); break; + default: + itemWidth = -1; + itemHeight = -1; + Q_ASSERT(false); + break; } // Apply the calculated values @@ -268,7 +272,9 @@ ViewModeSettings::ViewMode DolphinItemListContainer::viewMode() const case KFileItemListView::IconsLayout: mode = ViewModeSettings::IconsMode; break; case KFileItemListView::CompactLayout: mode = ViewModeSettings::CompactMode; break; case KFileItemListView::DetailsLayout: mode = ViewModeSettings::DetailsMode; break; - default: Q_ASSERT(false); break; + default: mode = ViewModeSettings::IconsMode; + Q_ASSERT(false); + break; } return mode; -- cgit v1.3 From b2f9e0758ea3f50bc9c78229360f78d265ce27bd Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sat, 28 Jan 2012 11:03:22 +0100 Subject: Assure to mark an item as unhovered on a drag-leave event BUG: 292501 FIXED-IN: 4.8.1 --- src/kitemviews/kitemlistcontroller.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 560d16042..bd37aa964 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -710,6 +710,12 @@ bool KItemListController::dragLeaveEvent(QGraphicsSceneDragDropEvent* event, con { Q_UNUSED(event); Q_UNUSED(transform); + + KItemListWidget* widget = hoveredWidget(); + if (widget) { + widget->setHovered(false); + emit itemUnhovered(widget->index()); + } return false; } -- cgit v1.3 From 8bef3984bb7c3ec8d544a6088d5bad962796407b Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sat, 28 Jan 2012 21:17:01 +0100 Subject: Fix regression: Respect "natural sorting" setting BUG: 292270 FIXED-IN: 4.8.1 --- src/kitemviews/kfileitemmodel.cpp | 11 ++++++++++- src/kitemviews/kfileitemmodel.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index fb089077b..163db8270 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -33,7 +34,7 @@ KFileItemModel::KFileItemModel(KDirLister* dirLister, QObject* parent) : KItemModelBase("name", parent), m_dirLister(dirLister), - m_naturalSorting(true), + m_naturalSorting(KGlobalSettings::naturalSorting()), m_sortFoldersFirst(true), m_sortRole(NameRole), m_roles(), @@ -95,6 +96,8 @@ KFileItemModel::KFileItemModel(KDirLister* dirLister, QObject* parent) : connect(m_resortAllItemsTimer, SIGNAL(timeout()), this, SLOT(resortAllItems())); Q_ASSERT(m_minimumUpdateIntervalTimer->interval() <= m_maximumUpdateIntervalTimer->interval()); + + connect(KGlobalSettings::self(), SIGNAL(naturalSortingChanged()), this, SLOT(slotNaturalSortingChanged())); } KFileItemModel::~KFileItemModel() @@ -862,6 +865,12 @@ void KFileItemModel::slotClear(const KUrl& url) Q_UNUSED(url); } +void KFileItemModel::slotNaturalSortingChanged() +{ + m_naturalSorting = KGlobalSettings::naturalSorting(); + resortAllItems(); +} + void KFileItemModel::dispatchPendingItemsToInsert() { if (!m_pendingItemsToInsert.isEmpty()) { diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h index acb3eb153..6276dc229 100644 --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -186,6 +186,7 @@ private slots: void slotRefreshItems(const QList >& items); void slotClear(); void slotClear(const KUrl& url); + void slotNaturalSortingChanged(); void dispatchPendingItemsToInsert(); -- cgit v1.3 From db66391f0071e12b5d28d34a2e363b6b1878251c Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sun, 29 Jan 2012 18:29:00 +0100 Subject: Make moving animations less obtrusive Only animate the moving of items if the new position is within the same row or the same column. Otherwise just fade in the icon on the new position. This makes the the animations when resizing the window or changing the zoom-level a lot more pleasant. CCBUG: 289238 --- src/kitemviews/kitemlistview.cpp | 80 ++++++++++++++++++++++++++-------------- src/kitemviews/kitemlistview.h | 16 ++++++++ 2 files changed, 69 insertions(+), 27 deletions(-) diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 281fe96f8..578865741 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -1310,27 +1310,7 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha const int lastVisibleIndex = m_layouter->lastVisibleIndex(); - // Determine all items that are completely invisible and might be - // reused for items that just got (at least partly) visible. - // Items that do e.g. an animated moving of their position are not - // marked as invisible: This assures that a scrolling inside the view - // can be done without breaking an animation. - QList reusableItems; - QHashIterator it(m_visibleItems); - while (it.hasNext()) { - it.next(); - KItemListWidget* widget = it.value(); - const int index = widget->index(); - const bool invisible = (index < firstVisibleIndex) || (index > lastVisibleIndex); - if (invisible && !m_animation->isStarted(widget)) { - widget->setVisible(false); - reusableItems.append(index); - - if (m_grouped) { - recycleGroupHeaderForWidget(widget); - } - } - } + QList reusableItems = recycleInvisibleItems(firstVisibleIndex, lastVisibleIndex); // Assure that for each visible item a KItemListWidget is available. KItemListWidget // instances from invisible items are reused. If no reusable items are @@ -1383,8 +1363,7 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha const bool itemsInserted = (changedCount > 0); if (itemsRemoved && (i >= changedIndex + changedCount + 1)) { // The item is located after the removed items. Animate the moving of the position. - m_animation->start(widget, KItemListViewAnimation::MovingAnimation, newPos); - applyNewPos = false; + applyNewPos = !moveWidget(widget, newPos); } else if (itemsInserted && i >= changedIndex) { // The item is located after the first inserted item if (i <= changedIndex + changedCount - 1) { @@ -1398,13 +1377,11 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha // The item was already there before, so animate the moving of the position. // No moving animation is done if the item is animated by a create animation: This // prevents a "move animation mess" when inserting several ranges in parallel. - m_animation->start(widget, KItemListViewAnimation::MovingAnimation, newPos); - applyNewPos = false; + applyNewPos = !moveWidget(widget, newPos); } } else if (!itemsRemoved && !itemsInserted && !wasHidden) { // The size of the view might have been changed. Animate the moving of the position. - m_animation->start(widget, KItemListViewAnimation::MovingAnimation, newPos); - applyNewPos = false; + applyNewPos = !moveWidget(widget, newPos); } } @@ -1451,6 +1428,55 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha emitOffsetChanges(); } +QList KItemListView::recycleInvisibleItems(int firstVisibleIndex, int lastVisibleIndex) +{ + // Determine all items that are completely invisible and might be + // reused for items that just got (at least partly) visible. + // Items that do e.g. an animated moving of their position are not + // marked as invisible: This assures that a scrolling inside the view + // can be done without breaking an animation. + + QList items; + + QHashIterator it(m_visibleItems); + while (it.hasNext()) { + it.next(); + KItemListWidget* widget = it.value(); + const int index = widget->index(); + const bool invisible = (index < firstVisibleIndex) || (index > lastVisibleIndex); + if (invisible && !m_animation->isStarted(widget)) { + widget->setVisible(false); + items.append(index); + + if (m_grouped) { + recycleGroupHeaderForWidget(widget); + } + } + } + + return items; +} + +bool KItemListView::moveWidget(KItemListWidget* widget, const QPointF& newPos) +{ + // The moving-animation should only be started, if it is done within one + // row or one column. Otherwise instead of a moving-animation a + // create-animation on the new position will be used instead. This is done + // to prevent "irritating" moving-animations. + const QPointF oldPos = widget->pos(); + const qreal xDiff = qAbs(oldPos.x() - newPos.x()); + const qreal yDiff = qAbs(oldPos.y() - newPos.y()); + if (xDiff <= m_itemSize.width() || yDiff <= m_itemSize.height()) { + // The moving animation is done inside a column or a row. + m_animation->start(widget, KItemListViewAnimation::MovingAnimation, newPos); + return true; + } + + m_animation->stop(widget); + m_animation->start(widget, KItemListViewAnimation::CreateAnimation); + return false; +} + void KItemListView::emitOffsetChanges() { const qreal newScrollOffset = m_layouter->scrollOffset(); diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index 4969d01b7..e4f1cd0d9 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -344,6 +344,22 @@ private: void doLayout(LayoutAnimationHint hint, int changedIndex = 0, int changedCount = 0); + /** + * Helper method for doLayout: Returns a list of items that can be reused for the visible + * area. Invisible group headers get recycled. The reusable items are items that are + * invisible and not animated. Reusing items is faster in comparison to deleting invisible + * items and creating a new instance for visible items. + */ + QList recycleInvisibleItems(int firstVisibleIndex, int lastVisibleIndex); + + /** + * Helper method for doLayout: Starts a moving-animation for the widget to the given + * new position. The moving-animation is only started if the new position is within + * the same row or column, otherwise the create-animation is used instead. + * @return True if the moving-animation has been applied. + */ + bool moveWidget(KItemListWidget* widget, const QPointF& newPos); + void emitOffsetChanges(); KItemListWidget* createWidget(int index); -- cgit v1.3 From e778465bbccbb1646b118c9e13ac22dbadc2939b Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Mon, 30 Jan 2012 10:07:03 +0100 Subject: Fix crash in Compact View if view height is smaller then item height BUG: 292816 FIXED-IN: 4.8.1 --- src/kitemviews/kitemlistview.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 578865741..4b2c742d9 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -508,18 +508,16 @@ void KItemListView::scrollToItem(int index) if (!viewGeometry.contains(currentRect)) { qreal newOffset = scrollOffset(); - if (currentRect.top() < viewGeometry.top()) { - Q_ASSERT(scrollOrientation() == Qt::Vertical); - newOffset += currentRect.top() - viewGeometry.top(); - } else if ((currentRect.bottom() > viewGeometry.bottom())) { - Q_ASSERT(scrollOrientation() == Qt::Vertical); - newOffset += currentRect.bottom() - viewGeometry.bottom(); - } else if (currentRect.left() < viewGeometry.left()) { - if (scrollOrientation() == Qt::Horizontal) { - newOffset += currentRect.left() - viewGeometry.left(); + if (scrollOrientation() == Qt::Vertical) { + if (currentRect.top() < viewGeometry.top()) { + newOffset += currentRect.top() - viewGeometry.top(); + } else if (currentRect.bottom() > viewGeometry.bottom()) { + newOffset += currentRect.bottom() - viewGeometry.bottom(); } - } else if ((currentRect.right() > viewGeometry.right())) { - if (scrollOrientation() == Qt::Horizontal) { + } else { + if (currentRect.left() < viewGeometry.left()) { + newOffset += currentRect.left() - viewGeometry.left(); + } else if (currentRect.right() > viewGeometry.right()) { newOffset += currentRect.right() - viewGeometry.right(); } } -- cgit v1.3 From 517743a1bf2fab754182b53ba180be4043ed2148 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Mon, 30 Jan 2012 12:07:08 +0100 Subject: Fix drag & drop issues with non-local URLs BUG: 292821 BUG: 292355 FIXED-IN: 4.8.1 --- src/dolphinmainwindow.cpp | 2 +- src/dolphinviewcontainer.cpp | 3 +-- src/panels/folders/folderspanel.cpp | 8 ++------ src/panels/places/placespanel.cpp | 3 +-- src/views/dolphinview.cpp | 17 ++++++----------- src/views/draganddrophelper.cpp | 15 ++++++--------- src/views/draganddrophelper.h | 11 +++++++++-- 7 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 3654ed6c9..74b751f5a 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -1330,7 +1330,7 @@ void DolphinMainWindow::tabDropEvent(int tab, QDropEvent* event) const ViewTab& viewTab = m_viewTab[tab]; const DolphinView* view = viewTab.isPrimaryViewActive ? viewTab.primaryView->view() : viewTab.secondaryView->view(); - DragAndDropHelper::dropUrls(view->rootItem(), event); + DragAndDropHelper::dropUrls(view->rootItem(), view->url(), event); } } diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index 2ad5bea5c..72c943eb4 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -538,8 +538,7 @@ void DolphinViewContainer::slotUrlNavigatorLocationChanged(const KUrl& url) void DolphinViewContainer::dropUrls(const KUrl& destination, QDropEvent* event) { - const KFileItem destItem(KFileItem::Unknown, KFileItem::Unknown, destination); - DragAndDropHelper::dropUrls(destItem, event); + DragAndDropHelper::dropUrls(KFileItem(), destination, event); } void DolphinViewContainer::redirect(const KUrl& oldUrl, const KUrl& newUrl) diff --git a/src/panels/folders/folderspanel.cpp b/src/panels/folders/folderspanel.cpp index d9c8f71dc..1a61f0141 100644 --- a/src/panels/folders/folderspanel.cpp +++ b/src/panels/folders/folderspanel.cpp @@ -263,11 +263,7 @@ void FoldersPanel::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* eve KFileItemModel* model = fileItemModel(); KFileItem destItem = model->fileItem(index); if (destItem.isNull()) { - destItem = model->rootItem(); - if (destItem.isNull()) { - kWarning() << "No destination item available for drop operation."; - return; - } + return; } QDropEvent dropEvent(event->pos().toPoint(), @@ -276,7 +272,7 @@ void FoldersPanel::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* eve event->buttons(), event->modifiers()); - DragAndDropHelper::dropUrls(destItem, &dropEvent); + DragAndDropHelper::dropUrls(destItem, destItem.url(), &dropEvent); } } diff --git a/src/panels/places/placespanel.cpp b/src/panels/places/placespanel.cpp index 6f522fad2..902c436cf 100644 --- a/src/panels/places/placespanel.cpp +++ b/src/panels/places/placespanel.cpp @@ -48,8 +48,7 @@ void PlacesPanel::mousePressEvent(QMouseEvent* event) void PlacesPanel::slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent) { Q_UNUSED(parent); - const KFileItem destItem(KFileItem::Unknown, KFileItem::Unknown, dest); - DragAndDropHelper::dropUrls(destItem, event); + DragAndDropHelper::dropUrls(KFileItem(), dest, event); } void PlacesPanel::emitExtendedUrlChangedSignal(const KUrl& url) diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 539fcaacc..1e300c5cf 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -809,13 +809,13 @@ void DolphinView::slotItemUnhovered(int index) void DolphinView::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* event) { + KUrl destUrl; KFileItem destItem = fileItemModel()->fileItem(index); if (destItem.isNull()) { destItem = fileItemModel()->rootItem(); - if (destItem.isNull()) { - kWarning() << "No destination item available for drop operation."; - return; - } + destUrl = url(); + } else { + destUrl = destItem.url(); } QDropEvent dropEvent(event->pos().toPoint(), @@ -824,7 +824,7 @@ void DolphinView::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* even event->buttons(), event->modifiers()); - const QString error = DragAndDropHelper::dropUrls(destItem, &dropEvent); + const QString error = DragAndDropHelper::dropUrls(destItem, destUrl, &dropEvent); if (!error.isEmpty()) { emit errorMessage(error); } @@ -959,12 +959,7 @@ bool DolphinView::hasSelection() const KFileItem DolphinView::rootItem() const { - KFileItem item = m_dirLister->rootItem(); - if (item.isNull()) { - // The directory has not been loaded yet - item = KFileItem(KFileItem::Unknown, KFileItem::Unknown, url()); - } - return item; + return m_dirLister->rootItem(); } void DolphinView::observeCreatedItem(const KUrl& url) diff --git a/src/views/draganddrophelper.cpp b/src/views/draganddrophelper.cpp index 91eb4267d..83673ad72 100644 --- a/src/views/draganddrophelper.cpp +++ b/src/views/draganddrophelper.cpp @@ -28,13 +28,10 @@ #include #include -QString DragAndDropHelper::dropUrls(const KFileItem& destItem, QDropEvent* event) +QString DragAndDropHelper::dropUrls(const KFileItem& destItem, const KUrl& destUrl, QDropEvent* event) { - Q_ASSERT(!destItem.isNull()); - - const KUrl destination = destItem.url(); - if (!destItem.isWritable()) { - return i18nc("@info:status", "Access denied. Could not write to %1", destination.pathOrUrl()); + if (!destItem.isNull() && !destItem.isWritable()) { + return i18nc("@info:status", "Access denied. Could not write to %1", destUrl.pathOrUrl()); } const QMimeData* mimeData = event->mimeData(); @@ -42,17 +39,17 @@ QString DragAndDropHelper::dropUrls(const KFileItem& destItem, QDropEvent* event const QString remoteDBusClient = mimeData->data("application/x-kde-dndextract"); QDBusMessage message = QDBusMessage::createMethodCall(remoteDBusClient, "/DndExtract", "org.kde.DndExtract", "extractSelectedFilesTo"); - message.setArguments(QVariantList() << destination.pathOrUrl()); + message.setArguments(QVariantList() << destUrl.pathOrUrl()); QDBusConnection::sessionBus().call(message); } else { const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData()); foreach (const KUrl& url, urls) { - if (url == destination) { + if (url == destUrl) { return i18nc("@info:status", "A folder cannot be dropped into itself"); } } - KonqOperations::doDrop(destItem, destination, event, QApplication::activeWindow()); + KonqOperations::doDrop(destItem, destUrl, event, QApplication::activeWindow()); } return QString(); diff --git a/src/views/draganddrophelper.h b/src/views/draganddrophelper.h index 1998a85a0..8838648a0 100644 --- a/src/views/draganddrophelper.h +++ b/src/views/draganddrophelper.h @@ -38,12 +38,19 @@ public: * destination. A context menu with the options * 'Move Here', 'Copy Here', 'Link Here' and * 'Cancel' is offered to the user. - * @param destItem Item of the destination. + * @param destItem Item of the destination. Can be 0 (KFileItem::isNull()) if + * no file-item is available for the destination. In this case + * destUrl is used as fallback. For performance reasons it is + * recommended to pass a file-item if available. + * @param destUrl URL of the item destination. Is used only if destItem::isNull() + * is true. * @param event Drop event. * @return Error message if dropping is not possible. If an empty string * is returned, the dropping has been successful. */ - static QString dropUrls(const KFileItem& destItem, QDropEvent* event); + static QString dropUrls(const KFileItem& destItem, + const KUrl& destUrl, + QDropEvent* event); }; #endif -- cgit v1.3 From 832b647c537bb520244d1222a4fb6440fe7024a6 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Mon, 30 Jan 2012 12:59:38 +0100 Subject: Further animation optimizations - Assure a proper minimim width in the compact mode. - Don't calculate the old position of hidden items to animate the moving. Just show them directly. --- src/kitemviews/kitemlistview.cpp | 73 +++++----------------------------- src/kitemviews/kitemlistview.h | 11 ----- src/views/dolphinitemlistcontainer.cpp | 4 +- 3 files changed, 13 insertions(+), 75 deletions(-) diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 4b2c742d9..a0820f7e5 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -147,15 +147,10 @@ void KItemListView::setItemSize(const QSizeF& itemSize) m_itemSize = itemSize; - const bool emptySize = itemSize.isEmpty(); - if (emptySize) { + if (itemSize.isEmpty()) { updateVisibleRolesSizes(); } else { - if (itemSize.width() < previousSize.width() || itemSize.height() < previousSize.height()) { - prepareLayoutForIncreasedItemCount(itemSize, ItemSize); - } else { - m_layouter->setItemSize(itemSize); - } + m_layouter->setItemSize(itemSize); } m_sizeHintResolver->clearCache(); @@ -394,12 +389,7 @@ void KItemListView::setGeometry(const QRectF& rect) // The item size is not dynamic and most probably the geometry change results // in animated position changes of the items. Trigger an asynchronous relayout // with m_layoutTimer to prevent performance bottlenecks. - if (m_model->count() > 0) { - prepareLayoutForIncreasedItemCount(newSize, LayouterSize); - } else { - m_layouter->setSize(newSize); - } - + m_layouter->setSize(newSize); if (!m_layoutTimer->isActive()) { m_layoutTimer->start(); } @@ -1462,9 +1452,14 @@ bool KItemListView::moveWidget(KItemListWidget* widget, const QPointF& newPos) // create-animation on the new position will be used instead. This is done // to prevent "irritating" moving-animations. const QPointF oldPos = widget->pos(); - const qreal xDiff = qAbs(oldPos.x() - newPos.x()); - const qreal yDiff = qAbs(oldPos.y() - newPos.y()); - if (xDiff <= m_itemSize.width() || yDiff <= m_itemSize.height()) { + const qreal xMax = m_itemSize.width(); + const qreal yMax = m_itemSize.height(); + + const bool startMovingAnim = xMax <= 0 + || yMax <= 0 + || qAbs(oldPos.x() - newPos.x()) <= xMax + || qAbs(oldPos.y() - newPos.y()) <= yMax; + if (startMovingAnim) { // The moving animation is done inside a column or a row. m_animation->start(widget, KItemListViewAnimation::MovingAnimation, newPos); return true; @@ -1538,52 +1533,6 @@ void KItemListView::setWidgetIndex(KItemListWidget* widget, int index) initializeItemListWidget(widget); } -void KItemListView::prepareLayoutForIncreasedItemCount(const QSizeF& size, SizeType sizeType) -{ - // Calculate the first visible index and last visible index for the current size - const int currentFirst = m_layouter->firstVisibleIndex(); - const int currentLast = m_layouter->lastVisibleIndex(); - - const QSizeF currentSize = (sizeType == LayouterSize) ? m_layouter->size() : m_layouter->itemSize(); - - // Calculate the first visible index and last visible index for the new size - setLayouterSize(size, sizeType); - const int newFirst = m_layouter->firstVisibleIndex(); - const int newLast = m_layouter->lastVisibleIndex(); - - if ((currentFirst != newFirst) || (currentLast != newLast)) { - // At least one index has been changed. Assure that widgets for all possible - // visible items get created so that a move-animation can be started later. - const int maxVisibleItems = m_layouter->maximumVisibleItems(); - int minFirst = qMin(newFirst, currentFirst); - const int maxLast = qMax(newLast, currentLast); - - if (maxLast - minFirst + 1 < maxVisibleItems) { - // Increasing the size might result in a smaller KItemListView::offset(). - // Decrease the first visible index in a way that at least the maximum - // visible items are shown. - minFirst = qMax(0, maxLast - maxVisibleItems + 1); - } - - if (maxLast - minFirst > maxVisibleItems + maxVisibleItems / 2) { - // The creating of widgets is quite expensive. Assure that never more - // than 50 % of the maximum visible items get created for the animations. - return; - } - - setLayouterSize(currentSize, sizeType); - for (int i = minFirst; i <= maxLast; ++i) { - if (!m_visibleItems.contains(i)) { - KItemListWidget* widget = createWidget(i); - const QRectF itemRect = m_layouter->itemRect(i); - widget->setPos(itemRect.topLeft()); - widget->resize(itemRect.size()); - } - } - setLayouterSize(size, sizeType); - } -} - void KItemListView::setLayouterSize(const QSizeF& size, SizeType sizeType) { switch (sizeType) { diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index e4f1cd0d9..e44669936 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -366,17 +366,6 @@ private: void recycleWidget(KItemListWidget* widget); void setWidgetIndex(KItemListWidget* widget, int index); - /** - * Helper method for setGeometry() and setItemSize(): Calling both methods might result - * in a changed number of visible items. To assure that currently invisible items can - * get animated from the old position to the new position prepareLayoutForIncreasedItemCount() - * takes care to create all item widgets that are visible with the old or the new size. - * @param size Size of the layouter or the item dependent on \p sizeType. - * @param sizeType LayouterSize: KItemListLayouter::setSize() is used. - * ItemSize: KItemListLayouter::setItemSize() is used. - */ - void prepareLayoutForIncreasedItemCount(const QSizeF& size, SizeType sizeType); - /** * Helper method for prepareLayoutForIncreasedItemCount(). */ diff --git a/src/views/dolphinitemlistcontainer.cpp b/src/views/dolphinitemlistcontainer.cpp index 38adfde64..7c32f982a 100644 --- a/src/views/dolphinitemlistcontainer.cpp +++ b/src/views/dolphinitemlistcontainer.cpp @@ -209,7 +209,7 @@ void DolphinItemListContainer::updateGridSize() switch (itemLayout()) { case KFileItemListView::IconsLayout: { const int minItemWidth = 64; - itemWidth = minItemWidth + IconsModeSettings::textWidthIndex() * 64; // TODO: + itemWidth = minItemWidth + IconsModeSettings::textWidthIndex() * 64; if (itemWidth < iconSize + innerMargin * 2) { itemWidth = iconSize + innerMargin * 2; } @@ -217,7 +217,7 @@ void DolphinItemListContainer::updateGridSize() break; } case KFileItemListView::CompactLayout: { - itemWidth = innerMargin * 2; + itemWidth = innerMargin * 4 + iconSize + styleOption.fontMetrics.height() * 5; const int textLinesCount = m_fileItemListView->visibleRoles().count(); itemHeight = innerMargin * 2 + qMax(iconSize, textLinesCount * styleOption.fontMetrics.height()); break; -- cgit v1.3 From 670655f448b25a53f075ed1e61e64ab85deaee12 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Mon, 30 Jan 2012 14:06:07 +0100 Subject: Only move the items if at least one direction is within the item size --- src/kitemviews/kitemlistview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index a0820f7e5..263c04461 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -1457,8 +1457,8 @@ bool KItemListView::moveWidget(KItemListWidget* widget, const QPointF& newPos) const bool startMovingAnim = xMax <= 0 || yMax <= 0 - || qAbs(oldPos.x() - newPos.x()) <= xMax - || qAbs(oldPos.y() - newPos.y()) <= yMax; + || qAbs(oldPos.x() - newPos.x()) < xMax + || qAbs(oldPos.y() - newPos.y()) < yMax; if (startMovingAnim) { // The moving animation is done inside a column or a row. m_animation->start(widget, KItemListViewAnimation::MovingAnimation, newPos); -- cgit v1.3 From 60bd873e9f42d22f2d4dae8d1ed43ebbc23c600f Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Mon, 30 Jan 2012 16:36:40 +0100 Subject: Synchronize view-mode settings before the settings dialog gets opened BUG: 292698 FIXED-IN: 4.8.1 --- src/dolphinmainwindow.cpp | 9 ++++++--- src/dolphinpart.cpp | 2 +- src/dolphinviewcontainer.cpp | 6 +++--- src/dolphinviewcontainer.h | 2 +- src/settings/viewmodes/viewsettingstab.cpp | 4 +++- src/statusbar/dolphinstatusbar.cpp | 2 +- src/statusbar/dolphinstatusbar.h | 2 +- src/views/dolphinitemlistcontainer.cpp | 15 ++++++++++----- src/views/dolphinitemlistcontainer.h | 6 ++---- src/views/dolphinview.cpp | 10 ++++++++-- src/views/dolphinview.h | 12 ++++++++---- 11 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 74b751f5a..074185f49 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -1118,7 +1118,10 @@ void DolphinMainWindow::openTerminal() void DolphinMainWindow::editSettings() { if (!m_settingsDialog) { - const KUrl url = activeViewContainer()->url(); + DolphinViewContainer* container = activeViewContainer(); + container->view()->writeSettings(); + + const KUrl url = container->url(); DolphinSettingsDialog* settingsDialog = new DolphinSettingsDialog(url, this); connect(settingsDialog, SIGNAL(settingsChanged()), this, SLOT(refreshViews())); settingsDialog->setAttribute(Qt::WA_DeleteOnClose); @@ -2066,9 +2069,9 @@ void DolphinMainWindow::refreshViews() const int tabCount = m_viewTab.count(); for (int i = 0; i < tabCount; ++i) { - m_viewTab[i].primaryView->refresh(); + m_viewTab[i].primaryView->readSettings(); if (m_viewTab[i].secondaryView) { - m_viewTab[i].secondaryView->refresh(); + m_viewTab[i].secondaryView->readSettings(); } } diff --git a/src/dolphinpart.cpp b/src/dolphinpart.cpp index 6c6683d91..8720e0ce2 100644 --- a/src/dolphinpart.cpp +++ b/src/dolphinpart.cpp @@ -591,7 +591,7 @@ void DolphinPartBrowserExtension::pasteTo(const KUrl&) void DolphinPartBrowserExtension::reparseConfiguration() { - m_part->view()->refresh(); + m_part->view()->readSettings(); } //// diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index 72c943eb4..2d2e20ff6 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -211,7 +211,7 @@ DolphinSearchBox* DolphinViewContainer::searchBox() return m_searchBox; } -void DolphinViewContainer::refresh() +void DolphinViewContainer::readSettings() { if (GeneralSettings::modifiedStartupSettings()) { // The startup settings should only get applied if they have been @@ -222,8 +222,8 @@ void DolphinViewContainer::refresh() setFilterBarVisible(GeneralSettings::filterBar()); } - m_view->refresh(); - m_statusBar->refresh(); + m_view->readSettings(); + m_statusBar->readSettings(); } bool DolphinViewContainer::isFilterBarVisible() const diff --git a/src/dolphinviewcontainer.h b/src/dolphinviewcontainer.h index ee9f83dea..59b3c79ed 100644 --- a/src/dolphinviewcontainer.h +++ b/src/dolphinviewcontainer.h @@ -86,7 +86,7 @@ public: /** * Refreshes the view container to get synchronized with the (updated) Dolphin settings. */ - void refresh(); + void readSettings(); /** Returns true, if the filter bar is visible. */ bool isFilterBarVisible() const; diff --git a/src/settings/viewmodes/viewsettingstab.cpp b/src/settings/viewmodes/viewsettingstab.cpp index b5cacf787..47aad7dd2 100644 --- a/src/settings/viewmodes/viewsettingstab.cpp +++ b/src/settings/viewmodes/viewsettingstab.cpp @@ -155,7 +155,9 @@ void ViewSettingsTab::loadSettings() m_textWidthBox->setCurrentIndex(IconsModeSettings::textWidthIndex()); } - const ViewModeSettings settings(viewMode()); + ViewModeSettings settings(viewMode()); + settings.readConfig(); + const QSize iconSize(settings.iconSize(), settings.iconSize()); m_defaultSizeSlider->setValue(ZoomLevelInfo::zoomLevelForIconSize(iconSize)); diff --git a/src/statusbar/dolphinstatusbar.cpp b/src/statusbar/dolphinstatusbar.cpp index c733ebe02..b01f6042c 100644 --- a/src/statusbar/dolphinstatusbar.cpp +++ b/src/statusbar/dolphinstatusbar.cpp @@ -254,7 +254,7 @@ QString DolphinStatusBar::defaultText() const return m_messageLabel->defaultText(); } -void DolphinStatusBar::refresh() +void DolphinStatusBar::readSettings() { setExtensionsVisible(true); } diff --git a/src/statusbar/dolphinstatusbar.h b/src/statusbar/dolphinstatusbar.h index 32d603ac5..789656b8e 100644 --- a/src/statusbar/dolphinstatusbar.h +++ b/src/statusbar/dolphinstatusbar.h @@ -112,7 +112,7 @@ public: /** * Refreshes the status bar to get synchronized with the (updated) Dolphin settings. */ - void refresh(); + void readSettings(); signals: /** diff --git a/src/views/dolphinitemlistcontainer.cpp b/src/views/dolphinitemlistcontainer.cpp index 7c32f982a..c687ede4d 100644 --- a/src/views/dolphinitemlistcontainer.cpp +++ b/src/views/dolphinitemlistcontainer.cpp @@ -59,10 +59,8 @@ DolphinItemListContainer::DolphinItemListContainer(KDirLister* dirLister, DolphinItemListContainer::~DolphinItemListContainer() { - IconsModeSettings::self()->writeConfig(); - CompactModeSettings::self()->writeConfig(); - DetailsModeSettings::self()->writeConfig(); - + writeSettings(); + controller()->setView(0); delete m_fileItemListView; m_fileItemListView = 0; @@ -170,7 +168,7 @@ void DolphinItemListContainer::endTransaction() m_fileItemListView->endTransaction(); } -void DolphinItemListContainer::refresh() +void DolphinItemListContainer::readSettings() { ViewModeSettings settings(viewMode()); settings.readConfig(); @@ -192,6 +190,13 @@ void DolphinItemListContainer::refresh() endTransaction(); } +void DolphinItemListContainer::writeSettings() +{ + IconsModeSettings::self()->writeConfig(); + CompactModeSettings::self()->writeConfig(); + DetailsModeSettings::self()->writeConfig(); +} + void DolphinItemListContainer::updateGridSize() { const ViewModeSettings settings(viewMode()); diff --git a/src/views/dolphinitemlistcontainer.h b/src/views/dolphinitemlistcontainer.h index 251552cc8..fa816b48c 100644 --- a/src/views/dolphinitemlistcontainer.h +++ b/src/views/dolphinitemlistcontainer.h @@ -64,10 +64,8 @@ public: void beginTransaction(); void endTransaction(); - /** - * Refreshs the view by reapplying the (changed) viewmode settings. - */ - void refresh(); + void readSettings(); + void writeSettings(); private: void updateGridSize(); diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 1e300c5cf..ef39414c9 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -446,13 +446,19 @@ void DolphinView::stopLoading() m_dirLister->stop(); } -void DolphinView::refresh() +void DolphinView::readSettings() { GeneralSettings::self()->readConfig(); - m_container->refresh(); + m_container->readSettings(); applyViewProperties(); } +void DolphinView::writeSettings() +{ + GeneralSettings::self()->writeConfig(); + m_container->writeSettings(); +} + void DolphinView::setNameFilter(const QString& nameFilter) { fileItemModel()->setNameFilter(nameFilter); diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index 197a41046..56ebbe402 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -265,11 +265,15 @@ public: void stopLoading(); /** - * Refreshes the view to get synchronized with the (updated) Dolphin settings. - * This method only needs to get invoked if the view settings for the Icons View, - * Details View or Columns View have been changed. + * Refreshes the view to get synchronized with the settings (e.g. icons size, + * font, ...). */ - void refresh(); + void readSettings(); + + /** + * Saves the current settings (e.g. icons size, font, ..). + */ + void writeSettings(); /** * Filters the currently shown items by \a nameFilter. All items -- cgit v1.3 From a8cb992febc277a4deea11178dd808cfa3b8a6b3 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Tue, 31 Jan 2012 13:29:43 +0100 Subject: Apply changed home-URL to the URL navigator BUG: 291043 FIXED-IN: 4.8.1 --- src/dolphinviewcontainer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index 2d2e20ff6..9809fbaf5 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -219,6 +219,7 @@ void DolphinViewContainer::readSettings() // settings of the URL navigator and the filterbar. m_urlNavigator->setUrlEditable(GeneralSettings::editableUrl()); m_urlNavigator->setShowFullPath(GeneralSettings::showFullPath()); + m_urlNavigator->setHomeUrl(KUrl(GeneralSettings::homeUrl())); setFilterBarVisible(GeneralSettings::filterBar()); } -- cgit v1.3 From 47bff403fa6b23cf69b1452c8ff019728021f5b0 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Tue, 31 Jan 2012 13:43:44 +0100 Subject: Adjust zoom-slider in the statusbar if settings have been changed This fixes the issue that changing the zoom-level in the settings does not update the zoom-slider in the statusbar. --- src/views/dolphinview.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index ef39414c9..661ce101b 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -448,9 +448,16 @@ void DolphinView::stopLoading() void DolphinView::readSettings() { + const int oldZoomLevel = m_container->zoomLevel(); + GeneralSettings::self()->readConfig(); m_container->readSettings(); applyViewProperties(); + + const int newZoomLevel = m_container->zoomLevel(); + if (newZoomLevel != oldZoomLevel) { + emit zoomLevelChanged(newZoomLevel, oldZoomLevel); + } } void DolphinView::writeSettings() -- cgit v1.3 From a8e61fa6ed620bf1230583343bef4a8448f844ba Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Tue, 31 Jan 2012 14:58:25 +0100 Subject: Fix sorting issues For some roles the sorting has not been implemented. BUG: 292941 FIXED-IN: 4.8.1 --- src/kitemviews/kfileitemmodel.cpp | 76 ++++++++++++++++++++++++--------------- src/kitemviews/kfileitemmodel.h | 10 ++++++ 2 files changed, 58 insertions(+), 28 deletions(-) diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index 163db8270..d64954698 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -1125,6 +1125,30 @@ KFileItemModel::Role KFileItemModel::roleIndex(const QByteArray& role) const return rolesHash.value(role, NoRole); } +QByteArray KFileItemModel::roleByteArray(Role role) const +{ + static const char* const roles[RolesCount] = { + 0, // NoRole + "name", + "size", + "date", + "permissions", + "owner", + "group", + "type", + "destination", + "path", + "comment", + "tags", + "rating", + "isDir", + "isExpanded", + "isExpandable", + "expansionLevel" + }; + return roles[role]; +} + QHash KFileItemModel::retrieveData(const KFileItem& item) const { // It is important to insert only roles that are fast to retrieve. E.g. @@ -1274,18 +1298,7 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b) const case NameRole: // The name role is handled as default fallback after the switch break; - - case DateRole: { - const KDateTime dateTimeA = itemA.time(KFileItem::ModificationTime); - const KDateTime dateTimeB = itemB.time(KFileItem::ModificationTime); - if (dateTimeA < dateTimeB) { - result = -1; - } else if (dateTimeA > dateTimeB) { - result = +1; - } - break; - } - + case SizeRole: { if (itemA.isDir()) { Q_ASSERT(itemB.isDir()); // see "if (m_sortFoldersFirst || m_sortRole == SizeRole)" above @@ -1307,29 +1320,36 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b) const break; } - case TypeRole: { - result = QString::compare(a->values.value("type").toString(), - b->values.value("type").toString()); + case DateRole: { + const KDateTime dateTimeA = itemA.time(KFileItem::ModificationTime); + const KDateTime dateTimeB = itemB.time(KFileItem::ModificationTime); + if (dateTimeA < dateTimeB) { + result = -1; + } else if (dateTimeA > dateTimeB) { + result = +1; + } break; } - - case CommentRole: { - result = QString::compare(a->values.value("comment").toString(), - b->values.value("comment").toString()); + + case RatingRole: { + result = a->values.value("rating").toInt() - b->values.value("rating").toInt(); break; } - + + case PermissionsRole: + case OwnerRole: + case GroupRole: + case TypeRole: + case DestinationRole: + case PathRole: + case CommentRole: case TagsRole: { - result = QString::compare(a->values.value("tags").toString(), - b->values.value("tags").toString()); + const QByteArray role = roleByteArray(m_sortRole); + result = QString::compare(a->values.value(role).toString(), + b->values.value(role).toString()); break; } - - case RatingRole: { - result = a->values.value("rating").toInt() - b->values.value("rating").toInt(); - break; - } - + default: break; } diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h index 6276dc229..ff816c85c 100644 --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -237,7 +237,17 @@ private: */ void resetRoles(); + /** + * @return Role-index for the given role byte-array. + * Runtime complexity is O(1). + */ Role roleIndex(const QByteArray& role) const; + + /** + * @return Role-byte-array for the given role-index. + * Runtime complexity is O(1). + */ + QByteArray roleByteArray(Role role) const; QHash retrieveData(const KFileItem& item) const; -- cgit v1.3 From 0222d552811efb7049de2d024247b0b8eaeffe2b Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Tue, 31 Jan 2012 21:04:40 +0100 Subject: SVN_SILENT made messages (.desktop file) --- src/dolphinpart.desktop | 1 + src/settings/kcm/kcmdolphingeneral.desktop | 1 + src/settings/kcm/kcmdolphinnavigation.desktop | 1 + src/settings/kcm/kcmdolphinservices.desktop | 1 + src/settings/kcm/kcmdolphinviewmodes.desktop | 1 + 5 files changed, 5 insertions(+) diff --git a/src/dolphinpart.desktop b/src/dolphinpart.desktop index a8905bcef..18a10fb9d 100644 --- a/src/dolphinpart.desktop +++ b/src/dolphinpart.desktop @@ -218,6 +218,7 @@ Name[pa]=ਸੰਖੇਪ Name[pl]=Kompaktowo Name[pt]=Compacto Name[pt_BR]=Compacto +Name[sk]=Kompaktný Name[sl]=Strnjeno Name[sr]=Сажето Name[sr@ijekavian]=Сажето diff --git a/src/settings/kcm/kcmdolphingeneral.desktop b/src/settings/kcm/kcmdolphingeneral.desktop index fb97413b1..5c00c7620 100644 --- a/src/settings/kcm/kcmdolphingeneral.desktop +++ b/src/settings/kcm/kcmdolphingeneral.desktop @@ -316,6 +316,7 @@ X-KDE-Keywords[pa]=ਫਾਇਲ ਮੈਨੇਜਰ X-KDE-Keywords[pl]=menedżer plików X-KDE-Keywords[pt]=gestor de ficheiros X-KDE-Keywords[pt_BR]=gerenciador de arquivos +X-KDE-Keywords[sk]=správca súborov X-KDE-Keywords[sl]=upravljalnik datotek X-KDE-Keywords[sr]=file manager,менаџер фајлова X-KDE-Keywords[sr@ijekavian]=file manager,менаџер фајлова diff --git a/src/settings/kcm/kcmdolphinnavigation.desktop b/src/settings/kcm/kcmdolphinnavigation.desktop index 8998b64fb..2e4846057 100644 --- a/src/settings/kcm/kcmdolphinnavigation.desktop +++ b/src/settings/kcm/kcmdolphinnavigation.desktop @@ -316,6 +316,7 @@ X-KDE-Keywords[pa]=ਫਾਇਲ ਮੈਨੇਜਰ X-KDE-Keywords[pl]=menedżer plików X-KDE-Keywords[pt]=gestor de ficheiros X-KDE-Keywords[pt_BR]=gerenciador de arquivos +X-KDE-Keywords[sk]=správca súborov X-KDE-Keywords[sl]=upravljalnik datotek X-KDE-Keywords[sr]=file manager,менаџер фајлова X-KDE-Keywords[sr@ijekavian]=file manager,менаџер фајлова diff --git a/src/settings/kcm/kcmdolphinservices.desktop b/src/settings/kcm/kcmdolphinservices.desktop index 4307daa39..2c4de82b1 100644 --- a/src/settings/kcm/kcmdolphinservices.desktop +++ b/src/settings/kcm/kcmdolphinservices.desktop @@ -267,6 +267,7 @@ X-KDE-Keywords[pa]=ਫਾਇਲ ਮੈਨੇਜਰ X-KDE-Keywords[pl]=menedżer plików X-KDE-Keywords[pt]=gestor de ficheiros X-KDE-Keywords[pt_BR]=gerenciador de arquivos +X-KDE-Keywords[sk]=správca súborov X-KDE-Keywords[sl]=upravljalnik datotek X-KDE-Keywords[sr]=file manager,менаџер фајлова X-KDE-Keywords[sr@ijekavian]=file manager,менаџер фајлова diff --git a/src/settings/kcm/kcmdolphinviewmodes.desktop b/src/settings/kcm/kcmdolphinviewmodes.desktop index 6507fa294..5b1ac8943 100644 --- a/src/settings/kcm/kcmdolphinviewmodes.desktop +++ b/src/settings/kcm/kcmdolphinviewmodes.desktop @@ -314,6 +314,7 @@ X-KDE-Keywords[pa]=ਫਾਇਲ ਮੈਨੇਜਰ X-KDE-Keywords[pl]=menedżer plików X-KDE-Keywords[pt]=gestor de ficheiros X-KDE-Keywords[pt_BR]=gerenciador de arquivos +X-KDE-Keywords[sk]=správca súborov X-KDE-Keywords[sl]=upravljalnik datotek X-KDE-Keywords[sr]=file manager,менаџер фајлова X-KDE-Keywords[sr@ijekavian]=file manager,менаџер фајлова -- cgit v1.3 From d80e9db9fb801bb5230c5b80190e5630bd738823 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Tue, 31 Jan 2012 21:23:16 +0100 Subject: Animation optimizations Prevent that the moving-animation crosses other items when zooming or changing the window size. --- src/kitemviews/kitemlistview.cpp | 65 ++++++++++++++++++++++++++++++---------- src/kitemviews/kitemlistview.h | 2 +- 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 263c04461..387c37aea 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -1351,7 +1351,7 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha const bool itemsInserted = (changedCount > 0); if (itemsRemoved && (i >= changedIndex + changedCount + 1)) { // The item is located after the removed items. Animate the moving of the position. - applyNewPos = !moveWidget(widget, newPos); + applyNewPos = !moveWidget(widget, itemBounds); } else if (itemsInserted && i >= changedIndex) { // The item is located after the first inserted item if (i <= changedIndex + changedCount - 1) { @@ -1365,11 +1365,11 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha // The item was already there before, so animate the moving of the position. // No moving animation is done if the item is animated by a create animation: This // prevents a "move animation mess" when inserting several ranges in parallel. - applyNewPos = !moveWidget(widget, newPos); + applyNewPos = !moveWidget(widget, itemBounds); } } else if (!itemsRemoved && !itemsInserted && !wasHidden) { // The size of the view might have been changed. Animate the moving of the position. - applyNewPos = !moveWidget(widget, newPos); + applyNewPos = !moveWidget(widget, itemBounds); } } @@ -1445,22 +1445,57 @@ QList KItemListView::recycleInvisibleItems(int firstVisibleIndex, int lastV return items; } -bool KItemListView::moveWidget(KItemListWidget* widget, const QPointF& newPos) +bool KItemListView::moveWidget(KItemListWidget* widget,const QRectF& itemBounds) { - // The moving-animation should only be started, if it is done within one - // row or one column. Otherwise instead of a moving-animation a - // create-animation on the new position will be used instead. This is done - // to prevent "irritating" moving-animations. const QPointF oldPos = widget->pos(); - const qreal xMax = m_itemSize.width(); - const qreal yMax = m_itemSize.height(); + const QPointF newPos = itemBounds.topLeft(); + if (oldPos == newPos) { + return false; + } - const bool startMovingAnim = xMax <= 0 - || yMax <= 0 - || qAbs(oldPos.x() - newPos.x()) < xMax - || qAbs(oldPos.y() - newPos.y()) < yMax; + bool startMovingAnim = m_itemSize.isEmpty(); + if (!startMovingAnim) { + // When having a grid the moving-animation should only be started, if it is done within + // one row in the vertical scroll-orientation or one column in the horizontal scroll-orientation. + // Otherwise instead of a moving-animation a create-animation on the new position will be used + // instead. This is done to prevent overlapping (and confusing) moving-animations. + + int zoomDiff = 0; + if (widget->size() != itemBounds.size()) { + // The item-size has been increased or decreased + const bool zoomOut = (widget->size().width() >= itemBounds.size().width()) && + (widget->size().height() >= itemBounds.size().height()); + zoomDiff = zoomOut ? -1 : +1; + } + + const qreal xMax = m_itemSize.width(); + const qreal yMax = m_itemSize.height(); + qreal xDiff = oldPos.x() - newPos.x(); + qreal yDiff = oldPos.y() - newPos.y(); + if (scrollOrientation() == Qt::Vertical) { + if (zoomDiff != 0) { + // Skip moving animations that changed the row + startMovingAnim = (zoomDiff > 0 && xDiff < xMax) || + (zoomDiff < 0 && -xDiff < xMax); + } else { + xDiff = qAbs(xDiff); + yDiff = qAbs(yDiff); + startMovingAnim = (xDiff > yDiff && yDiff < yMax); + } + } else { + if (zoomDiff != 0) { + // Skip moving animations that changed the column + startMovingAnim = (zoomDiff > 0 && yDiff < yMax) || + (zoomDiff < 0 && -yDiff < yMax); + } else { + xDiff = qAbs(xDiff); + yDiff = qAbs(yDiff); + startMovingAnim = (yDiff > xDiff && xDiff < xMax); + } + } + } + if (startMovingAnim) { - // The moving animation is done inside a column or a row. m_animation->start(widget, KItemListViewAnimation::MovingAnimation, newPos); return true; } diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index e44669936..4455166dd 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -358,7 +358,7 @@ private: * the same row or column, otherwise the create-animation is used instead. * @return True if the moving-animation has been applied. */ - bool moveWidget(KItemListWidget* widget, const QPointF& newPos); + bool moveWidget(KItemListWidget* widget, const QRectF& itemBounds); void emitOffsetChanges(); -- cgit v1.3 From 17e71420b6eb45c89a768498b38ba6480b30f3d1 Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Tue, 31 Jan 2012 23:12:36 +0100 Subject: Fix keyboard navigation issue when Home or End are pressed The problem was that m_keyboardAnchorIndex and m_keyboardAnchorPos were not updated when Home or End are pressed. This causes the following unexpected behavior in Icons View: Press Home, then Right, then Down, then Home, finally Down. One would expect that the first item in the second row is the current item then, but before this commit, it was the second one because the controller still remembered that the second column was active before Home was pressed. FIXED-IN: 4.8.1 --- src/kitemviews/kitemlistcontroller.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index bd37aa964..e3210dd22 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -216,10 +216,14 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) switch (key) { case Qt::Key_Home: index = 0; + m_keyboardAnchorIndex = index; + m_keyboardAnchorPos = keyboardAnchorPos(index); break; case Qt::Key_End: index = itemCount - 1; + m_keyboardAnchorIndex = index; + m_keyboardAnchorPos = keyboardAnchorPos(index); break; case Qt::Key_Left: -- cgit v1.3 From 33267573709a6b61e33a14ac5b12a740b107602e Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Wed, 1 Feb 2012 13:46:24 +0100 Subject: Don't animate items if the number of grid elements has been changed Having animated items is useful when e.g. deleting or inserting one item or when the size or position slightly changes by increasing the zoom level or the window size. However if the number of rows or columns change, the animation gets obtrusive and in this case lets just apply the final layout. --- src/kitemviews/kitemlistview.cpp | 160 ++++++++++++++++++++++++--------------- src/kitemviews/kitemlistview.h | 22 +++++- 2 files changed, 120 insertions(+), 62 deletions(-) diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 387c37aea..8aa984e4b 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -127,7 +127,7 @@ void KItemListView::setScrollOrientation(Qt::Orientation orientation) } } - doLayout(Animation); + doLayout(NoAnimation); onScrollOrientationChanged(orientation, previousOrientation); emit scrollOrientationChanged(orientation, previousOrientation); @@ -145,6 +145,11 @@ void KItemListView::setItemSize(const QSizeF& itemSize) return; } + // Skip animations when the number of rows or columns + // are changed in the grid layout. Although the animation + // engine can handle this usecase, it looks obtrusive. + const bool animate = !changesItemGridLayout(m_layouter->size(), itemSize); + m_itemSize = itemSize; if (itemSize.isEmpty()) { @@ -154,7 +159,7 @@ void KItemListView::setItemSize(const QSizeF& itemSize) } m_sizeHintResolver->clearCache(); - doLayout(Animation); + doLayout(animate ? Animation : NoAnimation); onItemSizeChanged(itemSize, previousSize); } @@ -244,7 +249,7 @@ void KItemListView::setVisibleRoles(const QList& roles) } updateVisibleRolesSizes(); - doLayout(Animation); + doLayout(NoAnimation); onVisibleRolesChanged(roles, previousRoles); } @@ -386,12 +391,19 @@ void KItemListView::setGeometry(const QRectF& rect) m_layouter->setSize(newSize); doLayout(Animation); } else { - // The item size is not dynamic and most probably the geometry change results - // in animated position changes of the items. Trigger an asynchronous relayout - // with m_layoutTimer to prevent performance bottlenecks. + const bool animate = !changesItemGridLayout(newSize, m_layouter->itemSize()); m_layouter->setSize(newSize); - if (!m_layoutTimer->isActive()) { - m_layoutTimer->start(); + + if (animate) { + // Trigger an asynchronous relayout with m_layoutTimer to prevent + // performance bottlenecks. If the timer is exceeded, an animated layout + // will be triggered. + if (!m_layoutTimer->isActive()) { + m_layoutTimer->start(); + } + } else { + m_layoutTimer->stop(); + doLayout(NoAnimation); } } } @@ -536,7 +548,7 @@ void KItemListView::endTransaction() if (m_activeTransactions == 0) { onTransactionEnd(); - doLayout(Animation); + doLayout(NoAnimation); } } @@ -796,7 +808,7 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges) } if (!hasMultipleRanges) { - doLayout(Animation, index, count); + doLayout(animateChangedItemCount(count) ? Animation : NoAnimation, index, count); } } @@ -848,9 +860,8 @@ void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges) continue; } - if (m_model->count() == 0) { - // For performance reasons no animation is done when all items have - // been removed. + if (m_model->count() == 0 || hasMultipleRanges || !animateChangedItemCount(count)) { + // Remove the widget without animation recycleWidget(widget); } else { // Animate the removing of the items. Special case: When removing an item there @@ -882,7 +893,7 @@ void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges) // geometry update if necessary. const int activeTransactions = m_activeTransactions; m_activeTransactions = 0; - doLayout(Animation, index, -count); + doLayout(animateChangedItemCount(count) ? Animation : NoAnimation, index, -count); m_activeTransactions = activeTransactions; } } @@ -983,7 +994,7 @@ void KItemListView::slotGroupedSortingChanged(bool current) Q_ASSERT(m_visibleGroups.isEmpty()); } - doLayout(Animation); + doLayout(NoAnimation); } void KItemListView::slotSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous) @@ -992,7 +1003,7 @@ void KItemListView::slotSortOrderChanged(Qt::SortOrder current, Qt::SortOrder pr Q_UNUSED(previous); if (m_grouped) { updateVisibleGroupHeaders(); - doLayout(Animation); + doLayout(NoAnimation); } } @@ -1002,7 +1013,7 @@ void KItemListView::slotSortRoleChanged(const QByteArray& current, const QByteAr Q_UNUSED(previous); if (m_grouped) { updateVisibleGroupHeaders(); - doLayout(Animation); + doLayout(NoAnimation); } } @@ -1131,7 +1142,7 @@ void KItemListView::slotVisibleRoleWidthChanged(const QByteArray& role, widget->setVisibleRolesSizes(m_stretchedVisibleRolesSizes); } - doLayout(Animation); + doLayout(NoAnimation); } } @@ -1298,7 +1309,7 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha const int lastVisibleIndex = m_layouter->lastVisibleIndex(); - QList reusableItems = recycleInvisibleItems(firstVisibleIndex, lastVisibleIndex); + QList reusableItems = recycleInvisibleItems(firstVisibleIndex, lastVisibleIndex, hint); // Assure that for each visible item a KItemListWidget is available. KItemListWidget // instances from invisible items are reused. If no reusable items are @@ -1343,7 +1354,11 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha applyNewPos = false; } } else if (m_animation->isStarted(widget, KItemListViewAnimation::MovingAnimation)) { - applyNewPos = false; + if (animate) { + applyNewPos = false; + } else { + m_animation->stop(widget); + } } if (animate) { @@ -1416,28 +1431,40 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha emitOffsetChanges(); } -QList KItemListView::recycleInvisibleItems(int firstVisibleIndex, int lastVisibleIndex) +QList KItemListView::recycleInvisibleItems(int firstVisibleIndex, + int lastVisibleIndex, + LayoutAnimationHint hint) { // Determine all items that are completely invisible and might be - // reused for items that just got (at least partly) visible. - // Items that do e.g. an animated moving of their position are not - // marked as invisible: This assures that a scrolling inside the view - // can be done without breaking an animation. + // reused for items that just got (at least partly) visible. If the + // animation hint is set to 'Animation' items that do e.g. an animated + // moving of their position are not marked as invisible: This assures + // that a scrolling inside the view can be done without breaking an animation. QList items; QHashIterator it(m_visibleItems); while (it.hasNext()) { it.next(); + KItemListWidget* widget = it.value(); const int index = widget->index(); const bool invisible = (index < firstVisibleIndex) || (index > lastVisibleIndex); - if (invisible && !m_animation->isStarted(widget)) { - widget->setVisible(false); - items.append(index); - if (m_grouped) { - recycleGroupHeaderForWidget(widget); + if (invisible) { + if (m_animation->isStarted(widget)) { + if (hint == NoAnimation) { + // Stopping the animation will call KItemListView::slotAnimationFinished() + // and the widget will be recycled if necessary there. + m_animation->stop(widget); + } + } else { + widget->setVisible(false); + items.append(index); + + if (m_grouped) { + recycleGroupHeaderForWidget(widget); + } } } } @@ -1453,45 +1480,20 @@ bool KItemListView::moveWidget(KItemListWidget* widget,const QRectF& itemBounds) return false; } - bool startMovingAnim = m_itemSize.isEmpty(); + bool startMovingAnim = m_itemSize.isEmpty() || widget->size() != itemBounds.size(); if (!startMovingAnim) { // When having a grid the moving-animation should only be started, if it is done within // one row in the vertical scroll-orientation or one column in the horizontal scroll-orientation. // Otherwise instead of a moving-animation a create-animation on the new position will be used // instead. This is done to prevent overlapping (and confusing) moving-animations. - - int zoomDiff = 0; - if (widget->size() != itemBounds.size()) { - // The item-size has been increased or decreased - const bool zoomOut = (widget->size().width() >= itemBounds.size().width()) && - (widget->size().height() >= itemBounds.size().height()); - zoomDiff = zoomOut ? -1 : +1; - } - const qreal xMax = m_itemSize.width(); const qreal yMax = m_itemSize.height(); - qreal xDiff = oldPos.x() - newPos.x(); - qreal yDiff = oldPos.y() - newPos.y(); + qreal xDiff = qAbs(oldPos.x() - newPos.x()); + qreal yDiff = qAbs(oldPos.y() - newPos.y()); if (scrollOrientation() == Qt::Vertical) { - if (zoomDiff != 0) { - // Skip moving animations that changed the row - startMovingAnim = (zoomDiff > 0 && xDiff < xMax) || - (zoomDiff < 0 && -xDiff < xMax); - } else { - xDiff = qAbs(xDiff); - yDiff = qAbs(yDiff); - startMovingAnim = (xDiff > yDiff && yDiff < yMax); - } + startMovingAnim = (xDiff > yDiff && yDiff < yMax); } else { - if (zoomDiff != 0) { - // Skip moving animations that changed the column - startMovingAnim = (zoomDiff > 0 && yDiff < yMax) || - (zoomDiff < 0 && -yDiff < yMax); - } else { - xDiff = qAbs(xDiff); - yDiff = qAbs(yDiff); - startMovingAnim = (yDiff > xDiff && xDiff < xMax); - } + startMovingAnim = (yDiff > xDiff && xDiff < xMax); } } @@ -1840,6 +1842,44 @@ QRectF KItemListView::headerBoundaries() const return m_header ? m_header->geometry() : QRectF(); } +bool KItemListView::changesItemGridLayout(const QSizeF& newGridSize, const QSizeF& newItemSize) const +{ + if (newItemSize.isEmpty() || newGridSize.isEmpty()) { + return false; + } + + if (m_layouter->scrollOrientation() == Qt::Vertical) { + const qreal itemWidth = m_layouter->itemSize().width(); + if (itemWidth > 0) { + const int oldColumnCount = m_layouter->size().width() / itemWidth; + const int newColumnCount = newGridSize.width() / newItemSize.width(); + return oldColumnCount != newColumnCount; + } + } else { + const qreal itemHeight = m_layouter->itemSize().height(); + if (itemHeight > 0) { + const int oldRowCount = m_layouter->size().height() / itemHeight; + const int newRowCount = newGridSize.height() / newItemSize.height(); + return oldRowCount != newRowCount; + } + } + + return false; +} + +bool KItemListView::animateChangedItemCount(int changedItemCount) const +{ + if (m_layouter->size().isEmpty() || m_layouter->itemSize().isEmpty()) { + return false; + } + + const int maximum = (scrollOrientation() == Qt::Vertical) + ? m_layouter->size().width() / m_layouter->itemSize().width() + : m_layouter->size().height() / m_layouter->itemSize().height(); + // Only animate if up to 2/3 of a row or column are inserted or removed + return changedItemCount <= maximum * 2 / 3; +} + int KItemListView::calculateAutoScrollingIncrement(int pos, int range, int oldInc) { int inc = 0; diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index 4455166dd..95215fffd 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -347,10 +347,13 @@ private: /** * Helper method for doLayout: Returns a list of items that can be reused for the visible * area. Invisible group headers get recycled. The reusable items are items that are - * invisible and not animated. Reusing items is faster in comparison to deleting invisible + * invisible. If the animation hint is 'Animation' then items that are currently animated + * won't be reused. Reusing items is faster in comparison to deleting invisible * items and creating a new instance for visible items. */ - QList recycleInvisibleItems(int firstVisibleIndex, int lastVisibleIndex); + QList recycleInvisibleItems(int firstVisibleIndex, + int lastVisibleIndex, + LayoutAnimationHint hint); /** * Helper method for doLayout: Starts a moving-animation for the widget to the given @@ -442,6 +445,21 @@ private: * if no header is shown. */ QRectF headerBoundaries() const; + + /** + * @return True if the number of columns or rows will be changed when applying + * the new grid- and item-size. Used to determine whether an animation + * should be done when applying the new layout. + */ + bool changesItemGridLayout(const QSizeF& newGridSize, const QSizeF& newItemSize) const; + + /** + * @param changedItemCount Number of inserted or removed items. + * @return True if the inserting or removing of items should be animated. + * No animation should be done if the number of items is too large + * to provide a pleasant animation. + */ + bool animateChangedItemCount(int changedItemCount) const; /** * Helper function for triggerAutoScrolling(). -- cgit v1.3 From 43373b3a1650a5834f3d030b61d80b0a4e858588 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Wed, 1 Feb 2012 20:40:57 +0100 Subject: KFileItemModelRolesUpdater: Optimize updates The asynchronous resolving to bypass performance bottlenecks is not necessary anymore as multiple ranges can be inserted in one step now. This solves the issue that e.g. opening a tree resulted in temporary unknown icons for a short period of time. --- src/kitemviews/kfileitemlistview.cpp | 2 - src/kitemviews/kfileitemmodelrolesupdater.cpp | 187 +++++++++++--------------- src/kitemviews/kfileitemmodelrolesupdater.h | 5 +- 3 files changed, 82 insertions(+), 112 deletions(-) diff --git a/src/kitemviews/kfileitemlistview.cpp b/src/kitemviews/kfileitemlistview.cpp index 86db28d3d..4762e8089 100644 --- a/src/kitemviews/kfileitemlistview.cpp +++ b/src/kitemviews/kfileitemlistview.cpp @@ -376,8 +376,6 @@ void KFileItemListView::onScrollOffsetChanged(qreal current, qreal previous) void KFileItemListView::onVisibleRolesChanged(const QList& current, const QList& previous) { - Q_UNUSED(current); - Q_UNUSED(previous); applyRolesToModel(); if (m_itemLayout == DetailsLayout) { diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp index a974094d5..0c204e474 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.cpp +++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp @@ -72,7 +72,6 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO m_pendingVisibleItems(), m_pendingInvisibleItems(), m_previewJobs(), - m_resolvePendingRolesTimer(0), m_changedItemsTimer(0), m_changedItems() { @@ -91,13 +90,6 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO connect(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet)), this, SLOT(slotItemsChanged(KItemRangeList,QSet))); - // A timer with a minimal timeout is used to merge several triggerPendingRolesResolving() calls - // to only one call of resolvePendingRoles(). - m_resolvePendingRolesTimer = new QTimer(this); - m_resolvePendingRolesTimer->setInterval(1); - m_resolvePendingRolesTimer->setSingleShot(true); - connect(m_resolvePendingRolesTimer, SIGNAL(timeout()), this, SLOT(resolvePendingRoles())); - // Use a timer to prevent that each call of slotItemsChanged() results in a synchronous // resolving of the roles. Postpone the resolving until no update has been done for 2 seconds. m_changedItemsTimer = new QTimer(this); @@ -379,84 +371,6 @@ void KFileItemModelRolesUpdater::slotPreviewJobFinished(KJob* job) startPreviewJob(visibleItems + m_pendingInvisibleItems.toList()); } -void KFileItemModelRolesUpdater::resolvePendingRoles() -{ - int resolvedCount = 0; - - const bool hasSlowRoles = m_previewShown - || m_roles.contains("size") - || m_roles.contains("type") - || m_roles.contains("isExpandable"); - const ResolveHint resolveHint = hasSlowRoles ? ResolveFast : ResolveAll; - - // Resolving the MIME type can be expensive. Assure that not more than MaxBlockTimeout ms are - // spend for resolving them synchronously. Usually this is more than enough to determine - // all visible items, but there are corner cases where this limit gets easily exceeded. - QElapsedTimer timer; - timer.start(); - - // Resolve the MIME type of all visible items - QSetIterator visibleIt(m_pendingVisibleItems); - while (visibleIt.hasNext()) { - const KFileItem item = visibleIt.next(); - applyResolvedRoles(item, resolveHint); - if (!hasSlowRoles) { - Q_ASSERT(!m_pendingInvisibleItems.contains(item)); - // All roles have been resolved already by applyResolvedRoles() - m_pendingVisibleItems.remove(item); - } - ++resolvedCount; - - if (timer.elapsed() > MaxBlockTimeout) { - break; - } - } - - // Resolve the MIME type of the invisible items at least until the timeout - // has been exceeded or the maximum number of items has been reached - KFileItemList invisibleItems; - if (m_lastVisibleIndex >= 0) { - // The visible range is valid, don't care about the order how the MIME - // type of invisible items get resolved - invisibleItems = m_pendingInvisibleItems.toList(); - } else { - // The visible range is temporary invalid (e.g. happens when loading - // a directory) so take care to sort the currently invisible items where - // a part will get visible later - invisibleItems = sortedItems(m_pendingInvisibleItems); - } - - int index = 0; - while (resolvedCount < MaxResolveItemsCount && index < invisibleItems.count() && timer.elapsed() <= MaxBlockTimeout) { - const KFileItem item = invisibleItems.at(index); - applyResolvedRoles(item, resolveHint); - - if (!hasSlowRoles) { - // All roles have been resolved already by applyResolvedRoles() - m_pendingInvisibleItems.remove(item); - } - ++index; - ++resolvedCount; - } - - if (m_previewShown) { - KFileItemList items = sortedItems(m_pendingVisibleItems); - items += invisibleItems; - startPreviewJob(items); - } else { - QTimer::singleShot(0, this, SLOT(resolveNextPendingRoles())); - } - -#ifdef KFILEITEMMODELROLESUPDATER_DEBUG - if (timer.elapsed() > MaxBlockTimeout) { - kDebug() << "Maximum time of" << MaxBlockTimeout - << "ms exceeded, skipping items... Remaining visible:" << m_pendingVisibleItems.count() - << "invisible:" << m_pendingInvisibleItems.count(); - } - kDebug() << "[TIME] Resolved pending roles:" << timer.elapsed(); -#endif -} - void KFileItemModelRolesUpdater::resolveNextPendingRoles() { if (m_paused) { @@ -556,7 +470,7 @@ void KFileItemModelRolesUpdater::startUpdating(const KItemRangeList& itemRanges) } } - triggerPendingRolesResolving(rangesCount); + resolvePendingRoles(); } void KFileItemModelRolesUpdater::startPreviewJob(const KFileItemList& items) @@ -612,6 +526,84 @@ bool KFileItemModelRolesUpdater::hasPendingRoles() const return !m_pendingVisibleItems.isEmpty() || !m_pendingInvisibleItems.isEmpty(); } +void KFileItemModelRolesUpdater::resolvePendingRoles() +{ + int resolvedCount = 0; + + const bool hasSlowRoles = m_previewShown + || m_roles.contains("size") + || m_roles.contains("type") + || m_roles.contains("isExpandable"); + const ResolveHint resolveHint = hasSlowRoles ? ResolveFast : ResolveAll; + + // Resolving the MIME type can be expensive. Assure that not more than MaxBlockTimeout ms are + // spend for resolving them synchronously. Usually this is more than enough to determine + // all visible items, but there are corner cases where this limit gets easily exceeded. + QElapsedTimer timer; + timer.start(); + + // Resolve the MIME type of all visible items + QSetIterator visibleIt(m_pendingVisibleItems); + while (visibleIt.hasNext()) { + const KFileItem item = visibleIt.next(); + applyResolvedRoles(item, resolveHint); + if (!hasSlowRoles) { + Q_ASSERT(!m_pendingInvisibleItems.contains(item)); + // All roles have been resolved already by applyResolvedRoles() + m_pendingVisibleItems.remove(item); + } + ++resolvedCount; + + if (timer.elapsed() > MaxBlockTimeout) { + break; + } + } + + // Resolve the MIME type of the invisible items at least until the timeout + // has been exceeded or the maximum number of items has been reached + KFileItemList invisibleItems; + if (m_lastVisibleIndex >= 0) { + // The visible range is valid, don't care about the order how the MIME + // type of invisible items get resolved + invisibleItems = m_pendingInvisibleItems.toList(); + } else { + // The visible range is temporary invalid (e.g. happens when loading + // a directory) so take care to sort the currently invisible items where + // a part will get visible later + invisibleItems = sortedItems(m_pendingInvisibleItems); + } + + int index = 0; + while (resolvedCount < MaxResolveItemsCount && index < invisibleItems.count() && timer.elapsed() <= MaxBlockTimeout) { + const KFileItem item = invisibleItems.at(index); + applyResolvedRoles(item, resolveHint); + + if (!hasSlowRoles) { + // All roles have been resolved already by applyResolvedRoles() + m_pendingInvisibleItems.remove(item); + } + ++index; + ++resolvedCount; + } + + if (m_previewShown) { + KFileItemList items = sortedItems(m_pendingVisibleItems); + items += invisibleItems; + startPreviewJob(items); + } else { + QTimer::singleShot(0, this, SLOT(resolveNextPendingRoles())); + } + +#ifdef KFILEITEMMODELROLESUPDATER_DEBUG + if (timer.elapsed() > MaxBlockTimeout) { + kDebug() << "Maximum time of" << MaxBlockTimeout + << "ms exceeded, skipping items... Remaining visible:" << m_pendingVisibleItems.count() + << "invisible:" << m_pendingInvisibleItems.count(); + } + kDebug() << "[TIME] Resolved pending roles:" << timer.elapsed(); +#endif +} + void KFileItemModelRolesUpdater::resetPendingRoles() { m_pendingVisibleItems.clear(); @@ -623,21 +615,6 @@ void KFileItemModelRolesUpdater::resetPendingRoles() Q_ASSERT(m_previewJobs.isEmpty()); } -void KFileItemModelRolesUpdater::triggerPendingRolesResolving(int count) -{ - if (count == m_model->count()) { - // When initially loading a directory a synchronous resolving prevents a minor - // flickering when opening directories. This is also fine from a performance point - // of view as it is assured in resolvePendingRoles() to never block the event-loop - // for more than 200 ms. - resolvePendingRoles(); - } else { - // Items have been added. This can be done in several small steps within one loop - // because of the sorting and hence may not trigger any expensive operation. - m_resolvePendingRolesTimer->start(); - } -} - void KFileItemModelRolesUpdater::sortAndResolveAllRoles() { if (m_paused) { @@ -675,8 +652,7 @@ void KFileItemModelRolesUpdater::sortAndResolveAllRoles() } } - triggerPendingRolesResolving(m_pendingVisibleItems.count() + - m_pendingInvisibleItems.count()); + resolvePendingRoles(); } void KFileItemModelRolesUpdater::sortAndResolvePendingRoles() @@ -715,8 +691,7 @@ void KFileItemModelRolesUpdater::sortAndResolvePendingRoles() } } - triggerPendingRolesResolving(m_pendingVisibleItems.count() + - m_pendingInvisibleItems.count()); + resolvePendingRoles(); } bool KFileItemModelRolesUpdater::applyResolvedRoles(const KFileItem& item, ResolveHint hint) diff --git a/src/kitemviews/kfileitemmodelrolesupdater.h b/src/kitemviews/kfileitemmodelrolesupdater.h index b3945d14d..4db2dde97 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.h +++ b/src/kitemviews/kfileitemmodelrolesupdater.h @@ -123,7 +123,6 @@ private slots: */ void slotPreviewJobFinished(KJob* job); - void resolvePendingRoles(); void resolveNextPendingRoles(); /** @@ -150,8 +149,8 @@ private: void startPreviewJob(const KFileItemList& items); bool hasPendingRoles() const; + void resolvePendingRoles(); void resetPendingRoles(); - void triggerPendingRolesResolving(int count); void sortAndResolveAllRoles(); void sortAndResolvePendingRoles(); @@ -198,8 +197,6 @@ private: QSet m_pendingInvisibleItems; QList m_previewJobs; - QTimer* m_resolvePendingRolesTimer; - // When downloading or copying large files, the slot slotItemsChanged() // will be called periodically within a quite short delay. To prevent // a high CPU-load by generating e.g. previews for each notification, the update -- cgit v1.3 From 7f4e9d9ed908eaa10659cbd04f53a82e28e8a59b Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Wed, 1 Feb 2012 21:52:50 +0100 Subject: First version of a unit test for KItemListController At the moment, only key press events are tested, and the current item and selection after the event are verified. Moreover, this commit makes sure that KItemListController::keyPressEvent() really does not select anything if the selection mode is NoSelection. --- src/kitemviews/kitemlistcontroller.cpp | 51 ++-- src/kitemviews/kitemlistview.h | 1 + src/kitemviews/kitemlistviewlayouter_p.h | 2 + src/tests/CMakeLists.txt | 12 + src/tests/kitemlistcontrollertest.cpp | 505 +++++++++++++++++++++++++++++++ 5 files changed, 554 insertions(+), 17 deletions(-) create mode 100644 src/tests/kitemlistcontrollertest.cpp diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index e3210dd22..69320247a 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -203,7 +203,8 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) } } - const bool selectSingleItem = itemCount == 1 && + const bool selectSingleItem = m_selectionBehavior != NoSelection && + itemCount == 1 && (key == Qt::Key_Home || key == Qt::Key_End || key == Qt::Key_Up || key == Qt::Key_Down || key == Qt::Key_Left || key == Qt::Key_Right); @@ -322,13 +323,15 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) } case Qt::Key_Space: - if (controlPressed) { - m_selectionManager->endAnchoredSelection(); - m_selectionManager->setSelected(index, 1, KItemListSelectionManager::Toggle); - m_selectionManager->beginAnchoredSelection(index); - } else { - const int current = m_selectionManager->currentItem(); - m_selectionManager->setSelected(current); + if (m_selectionBehavior == MultiSelection) { + if (controlPressed) { + m_selectionManager->endAnchoredSelection(); + m_selectionManager->setSelected(index, 1, KItemListSelectionManager::Toggle); + m_selectionManager->beginAnchoredSelection(index); + } else { + const int current = m_selectionManager->currentItem(); + m_selectionManager->setSelected(current); + } } break; @@ -361,19 +364,33 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) } if (m_selectionManager->currentItem() != index) { - if (controlPressed) { - m_selectionManager->endAnchoredSelection(); - } - - m_selectionManager->setCurrentItem(index); + switch (m_selectionBehavior) { + case NoSelection: + m_selectionManager->setCurrentItem(index); + break; - if (!shiftOrControlPressed || m_selectionBehavior == SingleSelection) { + case SingleSelection: + m_selectionManager->setCurrentItem(index); m_selectionManager->clearSelection(); m_selectionManager->setSelected(index, 1); - } + break; + + case MultiSelection: + if (controlPressed) { + m_selectionManager->endAnchoredSelection(); + } + + m_selectionManager->setCurrentItem(index); + + if (!shiftOrControlPressed) { + m_selectionManager->clearSelection(); + m_selectionManager->setSelected(index, 1); + } - if (!shiftPressed) { - m_selectionManager->beginAnchoredSelection(index); + if (!shiftPressed) { + m_selectionManager->beginAnchoredSelection(index); + } + break; } m_view->scrollToItem(index); diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index 95215fffd..9c34daba3 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -513,6 +513,7 @@ private: bool m_useHeaderWidths; friend class KItemListController; + friend class KItemListControllerTest; }; /** diff --git a/src/kitemviews/kitemlistviewlayouter_p.h b/src/kitemviews/kitemlistviewlayouter_p.h index dec99d054..25f8eb6cd 100644 --- a/src/kitemviews/kitemlistviewlayouter_p.h +++ b/src/kitemviews/kitemlistviewlayouter_p.h @@ -161,6 +161,8 @@ private: qreal m_groupHeaderHeight; QList m_itemRects; + + friend class KItemListControllerTest; }; #endif diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index c3360674c..43d1c9bf7 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -12,6 +12,18 @@ set(kitemlistselectionmanagertest_SRCS kde4_add_unit_test(kitemlistselectionmanagertest TEST ${kitemlistselectionmanagertest_SRCS}) target_link_libraries(kitemlistselectionmanagertest dolphinprivate ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY}) +# KItemListControllerTest +set(kitemlistcontrollertest_SRCS + kitemlistcontrollertest.cpp + testdir.cpp + ../kitemviews/kfileitemmodel.cpp + ../kitemviews/kfileitemlistview.cpp + ../kitemviews/kitemmodelbase.cpp + ../kitemviews/kitemlistview.cpp +) +kde4_add_unit_test(kitemlistcontrollertest TEST ${kitemlistcontrollertest_SRCS}) +target_link_libraries(kitemlistcontrollertest dolphinprivate ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY}) + # KFileItemListViewTest set(kfileitemlistviewtest_SRCS kfileitemlistviewtest.cpp diff --git a/src/tests/kitemlistcontrollertest.cpp b/src/tests/kitemlistcontrollertest.cpp new file mode 100644 index 000000000..443faa35f --- /dev/null +++ b/src/tests/kitemlistcontrollertest.cpp @@ -0,0 +1,505 @@ +/*************************************************************************** + * Copyright (C) 2012 by Frank Reininghaus * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include +#include +#include + +#include +#include "kitemviews/kitemlistcontainer.h" +#include "kitemviews/kfileitemlistview.h" +#include "kitemviews/kfileitemmodel.h" +#include "kitemviews/kitemlistcontroller.h" +#include "kitemviews/kitemlistselectionmanager.h" +#include "kitemviews/kitemlistviewlayouter_p.h" +#include "testdir.h" + +namespace { + const int DefaultTimeout = 2000; +}; + +Q_DECLARE_METATYPE(KFileItemListView::Layout); +Q_DECLARE_METATYPE(Qt::Orientation); +Q_DECLARE_METATYPE(KItemListController::SelectionBehavior); + +class KItemListControllerTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + void testKeyboardNavigation_data(); + void testKeyboardNavigation(); + +private: + /** + * Make sure that the number of columns in the view is equal to \a count + * by changing the geometry of the container. + */ + void adjustGeometryForColumnCount(int count); + +private: + KFileItemListView* m_view; + KItemListController* m_controller; + KItemListSelectionManager* m_selectionManager; + KFileItemModel* m_model; + KDirLister* m_dirLister; + TestDir* m_testDir; + KItemListContainer* m_container; +}; + +/** + * This function initializes the member objects, creates the temporary files, and + * shows the view on the screen on startup. This could also be done before every + * single test, but this would make the time needed to run the test much larger. + */ +void KItemListControllerTest::initTestCase() +{ + m_testDir = new TestDir(); + m_dirLister = new KDirLister(); + m_model = new KFileItemModel(m_dirLister); + m_container = new KItemListContainer(); + m_controller = m_container->controller(); + m_controller->setSelectionBehavior(KItemListController::MultiSelection); + m_selectionManager = m_controller->selectionManager(); + + m_view = new KFileItemListView(); + m_controller->setView(m_view); + m_controller->setModel(m_model); + + QStringList files; + files + << "a1" << "a2" << "a3" + << "b1" + << "c1" << "c2" << "c3" << "c4" << "c5" + << "d1" << "d2" << "d3" << "d4" + << "e1" << "e2" << "e3" << "e4" << "e5" << "e6" << "e7"; + + m_testDir->createFiles(files); + m_dirLister->openUrl(m_testDir->url()); + QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(loadingCompleted()), DefaultTimeout)); + + m_container->show(); + QTest::qWaitForWindowShown(m_container); +} + +void KItemListControllerTest::cleanupTestCase() +{ + delete m_view; + m_view = 0; + + delete m_container; + m_container = 0; + m_controller = 0; + + delete m_model; + m_model = 0; + + delete m_dirLister; + m_dirLister = 0; + + delete m_testDir; + m_testDir = 0; +} + +/** Before each test, the current item, selection, and item size are reset to the defaults. */ +void KItemListControllerTest::init() +{ + m_selectionManager->setCurrentItem(0); + QCOMPARE(m_selectionManager->currentItem(), 0); + + m_selectionManager->clearSelection(); + QVERIFY(!m_selectionManager->hasSelection()); + + const QSizeF itemSize(50, 50); + m_view->setItemSize(itemSize); + QCOMPARE(m_view->itemSize(), itemSize); +} + +void KItemListControllerTest::cleanup() +{ +} + +/** + * \class KeyPress is a small helper struct that represents a key press event, + * including the key and the keyboard modifiers. + */ +struct KeyPress { + + KeyPress(Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier) : + m_key(key), + m_modifier(modifier) + {} + + Qt::Key m_key; + Qt::KeyboardModifiers m_modifier; +}; + +/** + * \class ViewState is a small helper struct that represents a certain state + * of the view, including the current item and the selected items. + */ +struct ViewState { + + ViewState(int current, QSet selection) : + m_current(current), + m_selection(selection) + {} + + int m_current; + QSet m_selection; +}; + +// We have to define a typedef for the pair in order to make the test compile. +typedef QPair keyPressViewStatePair; +Q_DECLARE_METATYPE(QList); + +/** + * This function provides the data for the actual test function + * KItemListControllerTest::testKeyboardNavigation(). + * It tests all possible combinations of view layouts, selection behaviors, + * and enabled/disabled groupings for different column counts, and + * provides a list of key presses and the states that the view should be in + * after the key press event. + */ +void KItemListControllerTest::testKeyboardNavigation_data() +{ + QTest::addColumn("layout"); + QTest::addColumn("scrollOrientation"); + QTest::addColumn("columnCount"); + QTest::addColumn("selectionBehavior"); + QTest::addColumn("groupingEnabled"); + QTest::addColumn > >("testList"); + + static QList layoutList; + static QHash layoutNames; + if (layoutList.isEmpty()) { + layoutList.append(KFileItemListView::IconsLayout); + layoutNames[KFileItemListView::IconsLayout] = "Icons"; + + layoutList.append(KFileItemListView::CompactLayout); + layoutNames[KFileItemListView::CompactLayout] = "Compact"; + + layoutList.append(KFileItemListView::DetailsLayout); + layoutNames[KFileItemListView::DetailsLayout] = "Details"; + } + + static QList selectionBehaviorList; + static QHash selectionBehaviorNames; + if (selectionBehaviorList.isEmpty()) { + selectionBehaviorList.append(KItemListController::NoSelection); + selectionBehaviorNames[KItemListController::NoSelection] = "NoSelection"; + + selectionBehaviorList.append(KItemListController::SingleSelection); + selectionBehaviorNames[KItemListController::SingleSelection] = "SingleSelection"; + + selectionBehaviorList.append(KItemListController::MultiSelection); + selectionBehaviorNames[KItemListController::MultiSelection] = "MultiSelection"; + } + + static QList groupingEnabledList; + static QHash groupingEnabledNames; + if (groupingEnabledList.isEmpty()) { + groupingEnabledList.append(false); + groupingEnabledNames[false] = "ungrouped"; + + groupingEnabledList.append(true); + groupingEnabledNames[true] = "grouping enabled"; + } + + foreach (KFileItemListView::Layout layout, layoutList) { + // The following settings depend on the layout. + // Note that 'columns' are actually 'rows' in + // Compact layout. + Qt::Orientation scrollOrientation; + QList columnCountList; + Qt::Key nextItemKey; + Qt::Key previousItemKey; + Qt::Key nextRowKey; + Qt::Key previousRowKey; + + switch (layout) { + case KFileItemListView::IconsLayout: + scrollOrientation = Qt::Vertical; + columnCountList << 1 << 3 << 5; + nextItemKey = Qt::Key_Right; + previousItemKey = Qt::Key_Left; + nextRowKey = Qt::Key_Down; + previousRowKey = Qt::Key_Up; + break; + case KFileItemListView::CompactLayout: + scrollOrientation = Qt::Horizontal; + columnCountList << 1 << 3 << 5; + nextItemKey = Qt::Key_Down; + previousItemKey = Qt::Key_Up; + nextRowKey = Qt::Key_Right; + previousRowKey = Qt::Key_Left; + break; + case KFileItemListView::DetailsLayout: + scrollOrientation = Qt::Vertical; + columnCountList << 1; + nextItemKey = Qt::Key_Down; + previousItemKey = Qt::Key_Up; + nextRowKey = Qt::Key_Down; + previousRowKey = Qt::Key_Up; + break; + } + + foreach (int columnCount, columnCountList) { + foreach (KItemListController::SelectionBehavior selectionBehavior, selectionBehaviorList) { + foreach (bool groupingEnabled, groupingEnabledList) { + QList > testList; + + // First, key presses which should have the same effect + // for any layout and any number of columns. + testList + << qMakePair(KeyPress(nextItemKey), ViewState(1, QSet() << 1)) + << qMakePair(KeyPress(nextItemKey), ViewState(2, QSet() << 2)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, QSet() << 2 << 3)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(2, QSet() << 2)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, QSet() << 2 << 3)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(4, QSet() << 2 << 3)) + << qMakePair(KeyPress(previousItemKey), ViewState(3, QSet() << 3)) + << qMakePair(KeyPress(Qt::Key_Home, Qt::ShiftModifier), ViewState(0, QSet() << 0 << 1 << 2 << 3)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(1, QSet() << 0 << 1 << 2 << 3)) + << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(1, QSet() << 0 << 2 << 3)) + << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(1, QSet() << 0 << 1 << 2 << 3)) + << qMakePair(KeyPress(Qt::Key_End), ViewState(19, QSet() << 19)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(18, QSet() << 18 << 19)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)); + + // Next, we test combinations of key presses which only work for a + // particular number of columns and either enabled or disabled grouping. + + // One column. + if (columnCount == 1) { + testList + << qMakePair(KeyPress(nextRowKey), ViewState(1, QSet() << 1)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(2, QSet() << 1 << 2)) + << qMakePair(KeyPress(nextRowKey, Qt::ControlModifier), ViewState(3, QSet() << 1 << 2)) + << qMakePair(KeyPress(previousRowKey), ViewState(2, QSet() << 2)) + << qMakePair(KeyPress(previousItemKey), ViewState(1, QSet() << 1)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)); + } + + // Multiple columns: we test both 3 and 5 columns with grouping + // enabled or disabled. For each case, the layout of the items + // in the view is shown (both using file names and indices) to + // make it easier to understand what the tests do. + + if (columnCount == 3 && !groupingEnabled) { + // 3 columns, no grouping: + // + // a1 a2 a3 | 0 1 2 + // b1 c1 c2 | 3 4 5 + // c3 c4 c5 | 6 7 8 + // d1 d2 d3 | 9 10 11 + // d4 e1 e2 | 12 13 14 + // e3 e4 e5 | 15 16 17 + // e6 e7 | 18 19 + testList + << qMakePair(KeyPress(nextRowKey), ViewState(3, QSet() << 3)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(4, QSet() << 3)) + << qMakePair(KeyPress(nextRowKey), ViewState(7, QSet() << 7)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(8, QSet() << 7 << 8)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(9, QSet() << 7 << 8 << 9)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(8, QSet() << 7 << 8)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(7, QSet() << 7)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(6, QSet() << 6 << 7)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(5, QSet() << 5 << 6 << 7)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(6, QSet() << 6 << 7)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(7, QSet() << 7)) + << qMakePair(KeyPress(nextRowKey), ViewState(10, QSet() << 10)) + << qMakePair(KeyPress(nextItemKey), ViewState(11, QSet() << 11)) + << qMakePair(KeyPress(nextRowKey), ViewState(14, QSet() << 14)) + << qMakePair(KeyPress(nextRowKey), ViewState(17, QSet() << 17)) + << qMakePair(KeyPress(nextRowKey), ViewState(19, QSet() << 19)) + << qMakePair(KeyPress(previousRowKey), ViewState(17, QSet() << 17)) + << qMakePair(KeyPress(Qt::Key_End), ViewState(19, QSet() << 19)) + << qMakePair(KeyPress(previousRowKey), ViewState(16, QSet() << 16)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)); + } + + if (columnCount == 5 && !groupingEnabled) { + // 5 columns, no grouping: + // + // a1 a2 a3 b1 c1 | 0 1 2 3 4 + // c2 c3 c4 c5 d1 | 5 6 7 8 9 + // d2 d3 d4 e1 e2 | 10 11 12 13 14 + // e3 e4 e5 e6 e7 | 15 16 17 18 19 + testList + << qMakePair(KeyPress(nextRowKey), ViewState(5, QSet() << 5)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(6, QSet() << 5)) + << qMakePair(KeyPress(nextRowKey), ViewState(11, QSet() << 11)) + << qMakePair(KeyPress(nextItemKey), ViewState(12, QSet() << 12)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(17, QSet() << 12 << 13 << 14 << 15 << 16 << 17)) + << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(12, QSet() << 12)) + << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(7, QSet() << 7 << 8 << 9 << 10 << 11 << 12)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(12, QSet() << 12)) + << qMakePair(KeyPress(Qt::Key_End, Qt::ControlModifier), ViewState(19, QSet() << 12)) + << qMakePair(KeyPress(previousRowKey), ViewState(14, QSet() << 14)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)); + } + + if (columnCount == 3 && groupingEnabled) { + // 3 columns, with grouping: + // + // a1 a2 a3 | 0 1 2 + // b1 | 3 + // c1 c2 c3 | 4 5 6 + // c4 c5 | 7 8 + // d1 d2 d3 | 9 10 11 + // d4 | 12 + // e1 e2 e3 | 13 14 15 + // e4 e5 e6 | 16 17 18 + // e7 | 19 + testList + << qMakePair(KeyPress(nextItemKey), ViewState(1, QSet() << 1)) + << qMakePair(KeyPress(nextItemKey), ViewState(2, QSet() << 2)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(3, QSet() << 2 << 3)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(6, QSet() << 2 << 3 << 4 << 5 << 6)) + << qMakePair(KeyPress(nextRowKey), ViewState(8, QSet() << 8)) + << qMakePair(KeyPress(nextRowKey), ViewState(11, QSet() << 11)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(12, QSet() << 11)) + << qMakePair(KeyPress(nextRowKey), ViewState(13, QSet() << 13)) + << qMakePair(KeyPress(nextRowKey), ViewState(16, QSet() << 16)) + << qMakePair(KeyPress(nextItemKey), ViewState(17, QSet() << 17)) + << qMakePair(KeyPress(nextRowKey), ViewState(19, QSet() << 19)) + << qMakePair(KeyPress(previousRowKey), ViewState(17, QSet() << 17)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)); + } + + if (columnCount == 5 && groupingEnabled) { + // 5 columns, with grouping: + // + // a1 a2 a3 | 0 1 2 + // b1 | 3 + // c1 c2 c3 c4 c5 | 4 5 6 7 8 + // d1 d2 d3 d4 | 9 10 11 12 + // e1 e2 e3 e4 e5 | 13 14 15 16 17 + // e6 e7 | 18 19 + testList + << qMakePair(KeyPress(nextItemKey), ViewState(1, QSet() << 1)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(3, QSet() << 1 << 2 << 3)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(5, QSet() << 1 << 2 << 3 << 4 << 5)) + << qMakePair(KeyPress(nextItemKey), ViewState(6, QSet() << 6)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(7, QSet() << 6)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(8, QSet() << 6)) + << qMakePair(KeyPress(nextRowKey), ViewState(12, QSet() << 12)) + << qMakePair(KeyPress(nextRowKey), ViewState(17, QSet() << 17)) + << qMakePair(KeyPress(nextRowKey), ViewState(19, QSet() << 19)) + << qMakePair(KeyPress(previousRowKey), ViewState(17, QSet() << 17)) + << qMakePair(KeyPress(Qt::Key_End, Qt::ShiftModifier), ViewState(19, QSet() << 17 << 18 << 19)) + << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(14, QSet() << 14 << 15 << 16 << 17)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)); + } + + const QString testName = + layoutNames[layout] + ", " + + QString("%1 columns, ").arg(columnCount) + + selectionBehaviorNames[selectionBehavior] + ", " + + groupingEnabledNames[groupingEnabled]; + + const QByteArray testNameAscii = testName.toAscii(); + + QTest::newRow(testNameAscii.data()) + << layout + << scrollOrientation + << columnCount + << selectionBehavior + << groupingEnabled + << testList; + } + } + } + } +} + +/** + * This function sets the view's properties according to the data provided by + * KItemListControllerTest::testKeyboardNavigation_data(). + * + * The list \a testList contains pairs of key presses, which are sent to the + * container, and expected view states, which are verified then. + */ +void KItemListControllerTest::testKeyboardNavigation() +{ + QFETCH(KFileItemListView::Layout, layout); + QFETCH(Qt::Orientation, scrollOrientation); + QFETCH(int, columnCount); + QFETCH(KItemListController::SelectionBehavior, selectionBehavior); + QFETCH(bool, groupingEnabled); + QFETCH(QList, testList); + + m_view->setItemLayout(layout); + QCOMPARE(m_view->itemLayout(), layout); + + m_view->setScrollOrientation(scrollOrientation); + QCOMPARE(m_view->scrollOrientation(), scrollOrientation); + + adjustGeometryForColumnCount(columnCount); + QCOMPARE(m_view->m_layouter->m_columnCount, columnCount); + + m_controller->setSelectionBehavior(selectionBehavior); + QCOMPARE(m_controller->selectionBehavior(), selectionBehavior); + + m_model->setGroupedSorting(groupingEnabled); + QCOMPARE(m_model->groupedSorting(), groupingEnabled); + + while (!testList.isEmpty()) { + const QPair test = testList.takeFirst(); + const Qt::Key key = test.first.m_key; + const Qt::KeyboardModifiers modifier = test.first.m_modifier; + const int current = test.second.m_current; + const QSet selection = test.second.m_selection; + + QTest::keyClick(m_container, key, modifier); + QCOMPARE(m_selectionManager->currentItem(), current); + switch (selectionBehavior) { + case KItemListController::NoSelection: QVERIFY(m_selectionManager->selectedItems().isEmpty()); break; + case KItemListController::SingleSelection: QCOMPARE(m_selectionManager->selectedItems(), QSet() << current); break; + case KItemListController::MultiSelection: QCOMPARE(m_selectionManager->selectedItems(), selection); break; + } + } +} + +void KItemListControllerTest::adjustGeometryForColumnCount(int count) +{ + const QSize size = m_view->itemSize().toSize(); + + QRect rect = m_container->geometry(); + rect.setSize(size * count); + m_container->setGeometry(rect); + + // Increase the size of the container until the correct column count is reached. + while (m_view->m_layouter->m_columnCount < count) { + rect = m_container->geometry(); + rect.setSize(rect.size() + size); + m_container->setGeometry(rect); + } +} + +QTEST_KDEMAIN(KItemListControllerTest, GUI) + +#include "kitemlistcontrollertest.moc" -- cgit v1.3 From def780c672af2b90e8face3720e1567432b32b8d Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Thu, 2 Feb 2012 09:37:25 +0100 Subject: Fix pending zooming animation If doLayout() is invoked with the 'NoAnimation' hint, it must be assured that any ongoing animations are stopped. --- src/kitemviews/kitemlistview.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 8aa984e4b..d09018474 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -1353,12 +1353,6 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha } applyNewPos = false; } - } else if (m_animation->isStarted(widget, KItemListViewAnimation::MovingAnimation)) { - if (animate) { - applyNewPos = false; - } else { - m_animation->stop(widget); - } } if (animate) { @@ -1386,6 +1380,8 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha // The size of the view might have been changed. Animate the moving of the position. applyNewPos = !moveWidget(widget, itemBounds); } + } else { + m_animation->stop(widget); } if (applyNewPos) { -- cgit v1.3 From 9ef4b489c043a1bdfdb2931959f58e366862fe35 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Thu, 2 Feb 2012 15:10:45 +0100 Subject: Fix crash when opening a tab during a tooltip is shown Thanks a lot to Mathias Tillman for finding a 100 % reliable way how to reproduce the issue and for the initial patch! BUG: 278302 FIXED-IN: 4.8.1 --- src/views/dolphinview.cpp | 6 ++++++ src/views/dolphinview.h | 3 +++ src/views/tooltips/tooltipmanager.cpp | 34 +++++++++++++++------------------- src/views/tooltips/tooltipmanager.h | 6 +----- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 661ce101b..16163c8e9 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -694,6 +694,12 @@ void DolphinView::wheelEvent(QWheelEvent* event) } } +void DolphinView::hideEvent(QHideEvent* event) +{ + hideToolTip(); + QWidget::hideEvent(event); +} + void DolphinView::activate() { setActive(true); diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index 56ebbe402..bc65a8b77 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -549,6 +549,9 @@ protected: /** Changes the zoom level if Control is pressed during a wheel event. */ virtual void wheelEvent(QWheelEvent* event); + /** @reimp */ + virtual void hideEvent(QHideEvent* event); + private slots: /** * Marks the view as active (DolphinView:isActive() will return true) diff --git a/src/views/tooltips/tooltipmanager.cpp b/src/views/tooltips/tooltipmanager.cpp index df89a882e..3c262b749 100644 --- a/src/views/tooltips/tooltipmanager.cpp +++ b/src/views/tooltips/tooltipmanager.cpp @@ -33,16 +33,20 @@ ToolTipManager::ToolTipManager(QWidget* parent) : QObject(parent), - m_parentWidget(parent), m_showToolTipTimer(0), m_contentRetrievalTimer(0), m_fileMetaDataToolTip(0), m_toolTipRequested(false), m_metaDataRequested(false), m_appliedWaitCursor(false), + m_margin(4), m_item(), m_itemRect() { + if (parent) { + m_margin = qMax(m_margin, parent->style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth)); + } + m_showToolTipTimer = new QTimer(this); m_showToolTipTimer->setSingleShot(true); m_showToolTipTimer->setInterval(500); @@ -68,15 +72,14 @@ void ToolTipManager::showToolTip(const KFileItem& item, const QRectF& itemRect) m_itemRect = itemRect.toRect(); - const int margin = toolTipMargin(); - m_itemRect.adjust(-margin, -margin, margin, margin); + m_itemRect.adjust(-m_margin, -m_margin, m_margin, m_margin); m_item = item; // Only start the retrieving of the content, when the mouse has been over this // item for 200 milliseconds. This prevents a lot of useless preview jobs and // meta data retrieval, when passing rapidly over a lot of items. Q_ASSERT(!m_fileMetaDataToolTip); - m_fileMetaDataToolTip = new FileMetaDataToolTip(m_parentWidget); + m_fileMetaDataToolTip = new FileMetaDataToolTip(); connect(m_fileMetaDataToolTip, SIGNAL(metaDataRequestFinished(KFileItemList)), this, SLOT(slotMetaDataRequestFinished())); @@ -216,11 +219,10 @@ void ToolTipManager::showToolTip() // It must be assured that: // - the content is fully visible // - the content is not drawn inside m_itemRect - const int margin = toolTipMargin(); - const bool hasRoomToLeft = (m_itemRect.left() - size.width() - margin >= screen.left()); - const bool hasRoomToRight = (m_itemRect.right() + size.width() + margin <= screen.right()); - const bool hasRoomAbove = (m_itemRect.top() - size.height() - margin >= screen.top()); - const bool hasRoomBelow = (m_itemRect.bottom() + size.height() + margin <= screen.bottom()); + const bool hasRoomToLeft = (m_itemRect.left() - size.width() - m_margin >= screen.left()); + const bool hasRoomToRight = (m_itemRect.right() + size.width() + m_margin <= screen.right()); + const bool hasRoomAbove = (m_itemRect.top() - size.height() - m_margin >= screen.top()); + const bool hasRoomBelow = (m_itemRect.bottom() + size.height() + m_margin <= screen.bottom()); if (!hasRoomAbove && !hasRoomBelow && !hasRoomToLeft && !hasRoomToRight) { return; } @@ -232,16 +234,16 @@ void ToolTipManager::showToolTip() x = screen.right() - size.width() + 1; } if (hasRoomBelow) { - y = m_itemRect.bottom() + margin; + y = m_itemRect.bottom() + m_margin; } else { - y = m_itemRect.top() - size.height() - margin; + y = m_itemRect.top() - size.height() - m_margin; } } else { Q_ASSERT(hasRoomToLeft || hasRoomToRight); if (hasRoomToRight) { - x = m_itemRect.right() + margin; + x = m_itemRect.right() + m_margin; } else { - x = m_itemRect.left() - size.width() - margin; + x = m_itemRect.left() - size.width() - m_margin; } // Put the tooltip at the bottom of the screen. The x-coordinate has already // been adjusted, so that no overlapping with m_itemRect occurs. @@ -257,10 +259,4 @@ void ToolTipManager::showToolTip() m_toolTipRequested = false; } -int ToolTipManager::toolTipMargin() const -{ - const int margin = m_parentWidget->style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth); - return qMax(4, margin); -} - #include "tooltipmanager.moc" diff --git a/src/views/tooltips/tooltipmanager.h b/src/views/tooltips/tooltipmanager.h index b13641109..4fd8f843e 100644 --- a/src/views/tooltips/tooltipmanager.h +++ b/src/views/tooltips/tooltipmanager.h @@ -68,11 +68,6 @@ private slots: void showToolTip(); private: - int toolTipMargin() const; - -private: - QWidget* m_parentWidget; - /// Timeout from requesting a tooltip until the tooltip /// should be shown QTimer* m_showToolTipTimer; @@ -86,6 +81,7 @@ private: bool m_toolTipRequested; bool m_metaDataRequested; bool m_appliedWaitCursor; + int m_margin; KFileItem m_item; QRect m_itemRect; }; -- cgit v1.3 From a55199684898960a25aa9afc730120660087cb5f Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Thu, 2 Feb 2012 15:58:42 +0100 Subject: Fix sorting issue when sorting by "size" Root cause of the issue was an overflow in: result = a - b; where result is 'int' and a and b are 'KIO::filesize_t'. BUG: 293086 FIXED-IN: 4.8.1 --- src/kitemviews/kfileitemmodel.cpp | 26 ++++++++++++++++++++------ src/kitemviews/kfileitemmodel.h | 6 ++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index d64954698..95c960b3d 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -1301,21 +1301,24 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b) const case SizeRole: { if (itemA.isDir()) { - Q_ASSERT(itemB.isDir()); // see "if (m_sortFoldersFirst || m_sortRole == SizeRole)" above + // See "if (m_sortFoldersFirst || m_sortRole == SizeRole)" in KFileItemModel::lessThan(): + Q_ASSERT(itemB.isDir()); const QVariant valueA = a->values.value("size"); const QVariant valueB = b->values.value("size"); - - if (valueA.isNull()) { + if (valueA.isNull() && valueB.isNull()) { + result = 0; + } else if (valueA.isNull()) { result = -1; } else if (valueB.isNull()) { result = +1; } else { - result = valueA.value() - valueB.value(); + result = fileSizeCompare(valueA.value(), valueB.value()); } } else { - Q_ASSERT(!itemB.isDir()); // see "if (m_sortFoldersFirst || m_sortRole == SizeRole)" above - result = itemA.size() - itemB.size(); + // See "if (m_sortFoldersFirst || m_sortRole == SizeRole)" in KFileItemModel::lessThan(): + Q_ASSERT(!itemB.isDir()); + result = fileSizeCompare(itemA.size(), itemB.size()); } break; } @@ -1940,4 +1943,15 @@ KFileItemList KFileItemModel::childItems(const KFileItem& item) const return items; } +int KFileItemModel::fileSizeCompare(KIO::filesize_t a, KIO::filesize_t b) +{ + if (a > b) { + return +1; + } else if (a < b) { + return -1; + } else { + return 0; + } +} + #include "kfileitemmodel.moc" diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h index ff816c85c..d819c3734 100644 --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -330,6 +330,12 @@ private: */ KFileItemList childItems(const KFileItem& item) const; + /** + * Helper method for sortRoleCompare(). + * @return 0 if both sizes are equal, +1 if a > b and -1 if a < b. + */ + static int fileSizeCompare(KIO::filesize_t a, KIO::filesize_t b); + private: QWeakPointer m_dirLister; -- cgit v1.3