diff options
68 files changed, 1222 insertions, 1303 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fb8a30b42..3f584792d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,37 +1,36 @@ -macro_optional_find_package(NepomukCore) -set_package_properties(NepomukCore PROPERTIES DESCRIPTION "Nepomuk Core libraries" +macro_optional_find_package(Baloo) +set_package_properties(Baloo PROPERTIES DESCRIPTION "Baloo Core libraries" URL "http://www.kde.org" TYPE OPTIONAL - PURPOSE "For adding desktop-wide tagging support to dolphin" + PURPOSE "For adding desktop-wide search and tagging support to dolphin" ) -macro_optional_find_package(NepomukWidgets) -set_package_properties(NepomukWidgets PROPERTIES DESCRIPTION "Nepomuk Widgets" +macro_optional_find_package(BalooWidgets) +set_package_properties(BalooWidgets PROPERTIES DESCRIPTION "Baloos Widgets" URL "http://www.kde.org" TYPE OPTIONAL - PURPOSE "For adding desktop-wide tagging support to dolphin" ) -if(NepomukCore_FOUND AND NepomukWidgets_FOUND) - set(HAVE_NEPOMUK TRUE) +macro_optional_find_package(KFileMetaData) +set_package_properties(KFileMetaData PROPERTIES + URL "https://projects.kde.org/kfilemetadata" + TYPE OPTIONAL + PURPOSE "For accessing file metadata labels" + ) + +if (Baloo_FOUND AND BalooWidgets_FOUND AND KFileMetaData_FOUND) + set(HAVE_BALOO TRUE) endif() -configure_file(config-nepomuk.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-nepomuk.h ) +configure_file(config-baloo.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-baloo.h ) macro_bool_to_01(X11_Xrender_FOUND HAVE_XRENDER) configure_file(config-X11.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-X11.h ) -include_directories( ${KACTIVITIES_INCLUDE_DIRS} ) +include_directories( ${KACTIVITIES_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} ) -if(HAVE_NEPOMUK) - find_package(Soprano 2.7.56) - set_package_properties(Soprano PROPERTIES DESCRIPTION "Qt-based RDF storage and parsing solution" - URL "http://soprano.sourceforge.net" - TYPE REQUIRED - PURPOSE "Required for everything (storage and general data management)" - ) - - include_directories( ${SOPRANO_INCLUDE_DIR} ${NEPOMUK_CORE_INCLUDE_DIR} ${NEPOMUK_WIDGETS_INCLUDE_DIR} ) +if(HAVE_BALOO) + include_directories(${BALOO_INCLUDE_DIR} ${BALOO_WIDGETS_INCLUDE_DIR} ${KFILEMETADATA_INCLUDE_DIR}) endif() add_subdirectory(tests) @@ -98,10 +97,10 @@ set(dolphinprivate_LIB_SRCS dolphinnewfilemenu.cpp ) -if(HAVE_NEPOMUK) +if(HAVE_BALOO) set(dolphinprivate_LIB_SRCS ${dolphinprivate_LIB_SRCS} - kitemviews/private/knepomukrolesprovider.cpp + kitemviews/private/kbaloorolesprovider.cpp ) endif() @@ -123,12 +122,12 @@ target_link_libraries( ${KDE4_KNEWSTUFF3_LIBS} ) -if(HAVE_NEPOMUK) +if(HAVE_BALOO) target_link_libraries( dolphinprivate - ${NEPOMUK_CORE_LIBRARY} - ${NEPOMUK_WIDGETS_LIBRARY} - ${SOPRANO_LIBRARIES} + ${BALOO_LIBRARIES} + ${BALOO_WIDGETS_LIBRARY} + ${KFILEMETADATA_LIBRARY} ) endif() @@ -193,7 +192,6 @@ set(dolphin_SRCS panels/folders/folderspanel.cpp search/dolphinfacetswidget.cpp search/dolphinsearchbox.cpp - search/dolphinsearchinformation.cpp settings/general/behaviorsettingspage.cpp settings/general/configurepreviewplugindialog.cpp settings/general/confirmationssettingspage.cpp @@ -249,11 +247,10 @@ target_link_libraries(kdeinit_dolphin ${KDE4_PHONON_LIBS} ) -if(HAVE_NEPOMUK) +if(HAVE_BALOO) target_link_libraries(kdeinit_dolphin - ${NEPOMUK_CORE_LIBRARY} - ${NEPOMUK_WIDGETS_LIBRARY} - ${SOPRANO_LIBRARIES} + ${BALOO_LIBRARIES} + ${BALOO_WIDGETS_LIBRARY} ) endif() @@ -326,12 +323,6 @@ target_link_libraries(kcm_dolphinviewmodes ${KDE4_KDEUI_LIBS} ${KDE4_KFILE_LIBS target_link_libraries(kcm_dolphinnavigation ${KDE4_KDEUI_LIBS} ${KDE4_KFILE_LIBS} dolphinprivate) target_link_libraries(kcm_dolphinservices ${KDE4_KDEUI_LIBS} ${KDE4_KFILE_LIBS} ${KDE4_KIO_LIBS} ${KDE4_KNEWSTUFF3_LIBRARY} dolphinprivate) target_link_libraries(kcm_dolphingeneral ${KDE4_KDEUI_LIBS} ${KDE4_KFILE_LIBS} ${KDE4_KIO_LIBS} dolphinprivate) -if(HAVE_NEPOMUK) - target_link_libraries(kcm_dolphinviewmodes ${NEPOMUK_CORE_LIBRARY} ${NEPOMUK_WIDGETS_LIBRARY}) - target_link_libraries(kcm_dolphinnavigation ${NEPOMUK_CORE_LIBRARY} ${NEPOMUK_WIDGETS_LIBRARY}) - target_link_libraries(kcm_dolphinservices ${NEPOMUK_CORE_LIBRARY} ${NEPOMUK_WIDGETS_LIBRARY}) - target_link_libraries(kcm_dolphingeneral ${NEPOMUK_CORE_LIBRARY} ${NEPOMUK_WIDGETS_LIBRARY}) -endif() install(TARGETS kcm_dolphinviewmodes DESTINATION ${PLUGIN_INSTALL_DIR} ) install(TARGETS kcm_dolphinnavigation DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/src/config-baloo.h.cmake b/src/config-baloo.h.cmake new file mode 100644 index 000000000..ad95b2f07 --- /dev/null +++ b/src/config-baloo.h.cmake @@ -0,0 +1 @@ +#cmakedefine HAVE_BALOO diff --git a/src/config-nepomuk.h.cmake b/src/config-nepomuk.h.cmake deleted file mode 100644 index fe7364f60..000000000 --- a/src/config-nepomuk.h.cmake +++ /dev/null @@ -1 +0,0 @@ -#cmakedefine HAVE_NEPOMUK diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index 6b046c2ea..cb976129f 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -22,7 +22,7 @@ #ifndef DOLPHIN_MAINWINDOW_H #define DOLPHIN_MAINWINDOW_H -#include <config-nepomuk.h> +#include <config-baloo.h> #include <KFileItemDelegate> #include <kio/fileundomanager.h> diff --git a/src/dolphinpart.desktop b/src/dolphinpart.desktop index 10339e4bc..bdc3b929d 100644 --- a/src/dolphinpart.desktop +++ b/src/dolphinpart.desktop @@ -213,6 +213,7 @@ Name[gl]=Compacto Name[he]=מרוכז Name[hu]=Kompakt Name[ia]=Compacte +Name[is]=Þjappað Name[it]=Compatta Name[kk]=Ықшамды Name[km]=តូចល្មម diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index cc26198a0..57452b9e4 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -314,36 +314,18 @@ void DolphinViewContainer::setSearchModeEnabled(bool enabled) m_urlNavigator->setVisible(!enabled); if (enabled) { - KUrl url = m_urlNavigator->locationUrl(); - m_searchBox->setText(QString()); - m_searchBox->setReadOnly(isSearchUrl(url), url); - - // Remember the most recent non-search URL as search path - // of the search-box, so that it can be restored - // when switching back to the URL navigator. - int index = m_urlNavigator->historyIndex(); - const int historySize = m_urlNavigator->historySize(); - while (isSearchUrl(url) && (index < historySize)) { - ++index; - url = m_urlNavigator->locationUrl(index); - } - - if (!isSearchUrl(url)) { - m_searchBox->setSearchPath(url); - } + const KUrl& locationUrl = m_urlNavigator->locationUrl(); + m_searchBox->fromSearchUrl(locationUrl); } else { m_view->setViewPropertiesContext(QString()); // Restore the URL for the URL navigator. If Dolphin has been // started with a search-URL, the home URL is used as fallback. - const KUrl url = m_searchBox->searchPath(); - if (url.isValid() && !url.isEmpty()) { - if (isSearchUrl(url)) { - m_urlNavigator->goHome(); - } else { - m_urlNavigator->setLocationUrl(url); - } + KUrl url = m_searchBox->searchPath(); + if (url.isEmpty() || !url.isValid() || isSearchUrl(url)) { + url = GeneralSettings::self()->homeUrl(); } + m_urlNavigator->setLocationUrl(url); } } @@ -455,7 +437,7 @@ void DolphinViewContainer::slotDirectoryLoadingCompleted() } if (isSearchUrl(url()) && m_view->itemsCount() == 0) { - // The dir lister has been completed on a Nepomuk-URI and no items have been found. Instead + // The dir lister has been completed on a Baloo-URI and no items have been found. Instead // of showing the default status bar information ("0 items") a more helpful information is given: m_statusBar->setText(i18nc("@info:status", "No items found.")); } else { @@ -708,7 +690,7 @@ void DolphinViewContainer::showErrorMessage(const QString& msg) bool DolphinViewContainer::isSearchUrl(const KUrl& url) const { const QString protocol = url.protocol(); - return protocol.contains("search") || (protocol == QLatin1String("nepomuk")); + return protocol.contains("search"); } void DolphinViewContainer::saveViewState() diff --git a/src/dolphinviewcontainer.h b/src/dolphinviewcontainer.h index e5597ccc6..31612f10a 100644 --- a/src/dolphinviewcontainer.h +++ b/src/dolphinviewcontainer.h @@ -317,7 +317,7 @@ private slots: private: /** - * @return True if the URL protocol is a search URL (e. g. nepomuksearch:// or filenamesearch://). + * @return True if the URL protocol is a search URL (e. g. baloosearch:// or filenamesearch://). */ bool isSearchUrl(const KUrl& url) const; diff --git a/src/kitemviews/kfileitemlistwidget.cpp b/src/kitemviews/kfileitemlistwidget.cpp index 688a4da08..fe8c7e997 100644 --- a/src/kitemviews/kfileitemlistwidget.cpp +++ b/src/kitemviews/kfileitemlistwidget.cpp @@ -46,6 +46,15 @@ QString KFileItemListWidgetInformant::itemText(int index, const KItemListView* v return item.text(); } +bool KFileItemListWidgetInformant::itemIsLink(int index, const KItemListView* view) const +{ + Q_ASSERT(qobject_cast<KFileItemModel*>(view->model())); + KFileItemModel* fileItemModel = static_cast<KFileItemModel*>(view->model()); + + const KFileItem item = fileItemModel->fileItem(index); + return item.isLink(); +} + QString KFileItemListWidgetInformant::roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values) const { @@ -81,6 +90,15 @@ QString KFileItemListWidgetInformant::roleText(const QByteArray& role, return text; } +QFont KFileItemListWidgetInformant::customizedFontForLinks(const QFont& baseFont) const +{ + // The customized font should be italic if the file is a symbolic link. + QFont font(baseFont); + font.setItalic(true); + return font; +} + + KFileItemListWidget::KFileItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) : KStandardItemListWidget(informant, parent) { diff --git a/src/kitemviews/kfileitemlistwidget.h b/src/kitemviews/kfileitemlistwidget.h index 1d7bc7f01..8e8958b16 100644 --- a/src/kitemviews/kfileitemlistwidget.h +++ b/src/kitemviews/kfileitemlistwidget.h @@ -32,7 +32,9 @@ public: protected: virtual QString itemText(int index, const KItemListView* view) const; + virtual bool itemIsLink(int index, const KItemListView* view) const; virtual QString roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values) const; + virtual QFont customizedFontForLinks(const QFont& baseFont) const; }; class LIBDOLPHINPRIVATE_EXPORT KFileItemListWidget : public KStandardItemListWidget diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index 87006718a..fd773e1e9 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -21,7 +21,6 @@ #include "kfileitemmodel.h" -#include <KDirModel> #include <KGlobalSettings> #include <KLocale> #include <KStringHandler> @@ -76,7 +75,6 @@ KFileItemModel::KFileItemModel(QObject* parent) : connect(m_dirLister, SIGNAL(itemsDeleted(KFileItemList)), this, SLOT(slotItemsDeleted(KFileItemList))); connect(m_dirLister, SIGNAL(refreshItems(QList<QPair<KFileItem,KFileItem> >)), this, SLOT(slotRefreshItems(QList<QPair<KFileItem,KFileItem> >))); connect(m_dirLister, SIGNAL(clear()), this, SLOT(slotClear())); - connect(m_dirLister, SIGNAL(clear(KUrl)), this, SLOT(slotClear(KUrl))); connect(m_dirLister, SIGNAL(infoMessage(QString)), this, SIGNAL(infoMessage(QString))); connect(m_dirLister, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString))); connect(m_dirLister, SIGNAL(redirection(KUrl,KUrl)), this, SIGNAL(directoryRedirection(KUrl,KUrl))); @@ -247,9 +245,23 @@ QMimeData* KFileItemModel::createMimeData(const KItemSet& indexes) const KUrl::List urls; KUrl::List mostLocalUrls; bool canUseMostLocalUrls = true; + const ItemData* lastAddedItem = 0; foreach (int index, indexes) { - const KFileItem item = fileItem(index); + const ItemData* itemData = m_itemData.at(index); + const ItemData* parent = itemData->parent; + + while (parent && parent != lastAddedItem) { + parent = parent->parent; + } + + if (parent && parent == lastAddedItem) { + // A parent of 'itemData' has been added already. + continue; + } + + lastAddedItem = itemData; + const KFileItem& item = itemData->item; if (!item.isNull()) { urls << item.targetUrl(); @@ -262,9 +274,7 @@ QMimeData* KFileItemModel::createMimeData(const KItemSet& indexes) const } const bool different = canUseMostLocalUrls && mostLocalUrls != urls; - urls = KDirModel::simplifiedUrlList(urls); // TODO: Check if we still need KDirModel for this in KDE 5.0 if (different) { - mostLocalUrls = KDirModel::simplifiedUrlList(mostLocalUrls); urls.populateMimeData(mostLocalUrls, data); } else { urls.populateMimeData(data); @@ -344,27 +354,50 @@ KFileItem KFileItemModel::fileItem(int index) const KFileItem KFileItemModel::fileItem(const KUrl& url) const { - const int index = m_items.value(url, -1); - if (index >= 0) { - return m_itemData.at(index)->item; + const int indexForUrl = index(url); + if (indexForUrl >= 0) { + return m_itemData.at(indexForUrl)->item; } return KFileItem(); } int KFileItemModel::index(const KFileItem& item) const { - if (item.isNull()) { - return -1; - } - - return m_items.value(item.url(), -1); + return index(item.url()); } int KFileItemModel::index(const KUrl& url) const { KUrl urlToFind = url; urlToFind.adjustPath(KUrl::RemoveTrailingSlash); - return m_items.value(urlToFind, -1); + + const int itemCount = m_itemData.count(); + int itemsInHash = m_items.count(); + + int index = m_items.value(urlToFind, -1); + while (index < 0 && itemsInHash < itemCount) { + // Not all URLs are stored yet in m_items. We grow m_items until either + // urlToFind is found, or all URLs have been stored in m_items. + // Note that we do not add the URLs to m_items one by one, but in + // larger blocks. After each block, we check if urlToFind is in + // m_items. We could in principle compare urlToFind with each URL while + // we are going through m_itemData, but comparing two QUrls will, + // unlike calling qHash for the URLs, trigger a parsing of the URLs + // which costs both CPU cycles and memory. + const int blockSize = 1000; + const int currentBlockEnd = qMin(itemsInHash + blockSize, itemCount); + for (int i = itemsInHash; i < currentBlockEnd; ++i) { + const KUrl nextUrl = m_itemData.at(i)->item.url(); + m_items.insert(nextUrl, i); + } + + itemsInHash = currentBlockEnd; + index = m_items.value(urlToFind, -1); + } + + Q_ASSERT(index >= 0 || m_items.count() == m_itemData.count()); + + return index; } KFileItem KFileItemModel::rootItem() const @@ -662,7 +695,7 @@ QList<KFileItemModel::RoleInfo> KFileItemModel::rolesInformation() // menus tries to put the actions into sub menus otherwise. info.group = QString(); } - info.requiresNepomuk = map[i].requiresNepomuk; + info.requiresBaloo = map[i].requiresBaloo; info.requiresIndexer = map[i].requiresIndexer; rolesInfo.append(info); } @@ -725,6 +758,7 @@ void KFileItemModel::resortAllItems() } m_items.clear(); + m_items.reserve(itemCount); // Resort the items sort(m_itemData.begin(), m_itemData.end()); @@ -787,10 +821,10 @@ void KFileItemModel::slotCompleted() // Therefore, some URLs in m_restoredExpandedUrls might not be visible yet // -> we expand the first visible URL we find in m_restoredExpandedUrls. foreach (const KUrl& url, m_urlsToExpand) { - const int index = m_items.value(url, -1); - if (index >= 0) { + const int indexForUrl = index(url); + if (indexForUrl >= 0) { m_urlsToExpand.remove(url); - if (setExpanded(index, true)) { + if (setExpanded(indexForUrl, true)) { // The dir lister has been triggered. This slot will be called // again after the directory has been expanded. return; @@ -827,15 +861,12 @@ void KFileItemModel::slotItemsAdded(const KUrl& directoryUrl, const KFileItemLis } if (m_requestRole[ExpandedParentsCountRole]) { - KFileItem item = items.first(); - // If the expanding of items is enabled, the call // dirLister->openUrl(url, KDirLister::Keep) in KFileItemModel::setExpanded() // might result in emitting the same items twice due to the Keep-parameter. // This case happens if an item gets expanded, collapsed and expanded again // before the items could be loaded for the first expansion. - const int index = m_items.value(item.url(), -1); - if (index >= 0) { + if (index(items.first().url()) >= 0) { // The items are already part of the model. return; } @@ -849,7 +880,7 @@ void KFileItemModel::slotItemsAdded(const KUrl& directoryUrl, const KFileItemLis // KDirLister keeps the children of items that got expanded once even if // they got collapsed again with KFileItemModel::setExpanded(false). So it must be // checked whether the parent for new items is still expanded. - const int parentIndex = m_items.value(parentUrl, -1); + const int parentIndex = index(parentUrl); if (parentIndex >= 0 && !m_itemData[parentIndex]->values.value("isExpanded").toBool()) { // The parent is not expanded. return; @@ -888,10 +919,9 @@ void KFileItemModel::slotItemsDeleted(const KFileItemList& items) indexesToRemove.reserve(items.count()); foreach (const KFileItem& item, items) { - const KUrl url = item.url(); - const int index = m_items.value(url, -1); - if (index >= 0) { - indexesToRemove.append(index); + const int indexForItem = index(item); + if (indexForItem >= 0) { + indexesToRemove.append(indexForItem); } else { // Probably the item has been filtered. QHash<KFileItem, ItemData*>::iterator it = m_filteredItems.find(item); @@ -907,7 +937,7 @@ void KFileItemModel::slotItemsDeleted(const KFileItemList& items) if (m_requestRole[ExpandedParentsCountRole] && !m_expandedDirs.isEmpty()) { // Assure that removing a parent item also results in removing all children QVector<int> indexesToRemoveWithChildren; - indexesToRemoveWithChildren.reserve(m_items.count()); + indexesToRemoveWithChildren.reserve(m_itemData.count()); const int itemCount = m_itemData.count(); foreach (int index, indexesToRemove) { @@ -947,14 +977,14 @@ void KFileItemModel::slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >& const QPair<KFileItem, KFileItem>& itemPair = it.next(); const KFileItem& oldItem = itemPair.first; const KFileItem& newItem = itemPair.second; - const int index = m_items.value(oldItem.url(), -1); - if (index >= 0) { - m_itemData[index]->item = newItem; + const int indexForItem = index(oldItem); + if (indexForItem >= 0) { + m_itemData[indexForItem]->item = newItem; // Keep old values as long as possible if they could not retrieved synchronously yet. // The update of the values will be done asynchronously by KFileItemModelRolesUpdater. - QHashIterator<QByteArray, QVariant> it(retrieveData(newItem, m_itemData.at(index)->parent)); - QHash<QByteArray, QVariant>& values = m_itemData[index]->values; + QHashIterator<QByteArray, QVariant> it(retrieveData(newItem, m_itemData.at(indexForItem)->parent)); + QHash<QByteArray, QVariant>& values = m_itemData[indexForItem]->values; while (it.hasNext()) { it.next(); const QByteArray& role = it.key(); @@ -965,8 +995,8 @@ void KFileItemModel::slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >& } m_items.remove(oldItem.url()); - m_items.insert(newItem.url(), index); - indexes.append(index); + m_items.insert(newItem.url(), indexForItem); + indexes.append(indexForItem); } else { // Check if 'oldItem' is one of the filtered items. QHash<KFileItem, ItemData*>::iterator it = m_filteredItems.find(oldItem); @@ -1023,11 +1053,6 @@ void KFileItemModel::slotClear() m_expandedDirs.clear(); } -void KFileItemModel::slotClear(const KUrl& url) -{ - Q_UNUSED(url); -} - void KFileItemModel::slotNaturalSortingChanged() { m_naturalSorting = KGlobalSettings::naturalSorting(); @@ -1088,7 +1113,7 @@ void KFileItemModel::insertItems(QList<ItemData*>& newItems) m_itemData.append(0); } - // We build the new list m_items in reverse order to minimize + // We build the new list m_itemData in reverse order to minimize // the number of moves and guarantee O(N) complexity. int targetIndex = totalItemCount - 1; int sourceIndexExistingItems = existingItemCount - 1; @@ -1126,11 +1151,9 @@ void KFileItemModel::insertItems(QList<ItemData*>& newItems) std::reverse(itemRanges.begin(), itemRanges.end()); } - // The indexes starting from the first inserted item must be adjusted. - m_items.reserve(totalItemCount); - for (int i = itemRanges.front().index; i < totalItemCount; ++i) { - m_items.insert(m_itemData.at(i)->item.url(), i); - } + // The indexes in m_items are not correct anymore. Therefore, we clear m_items. + // It will be re-populated with the updated indices if index(const KUrl&) is called. + m_items.clear(); emit itemsInserted(itemRanges); @@ -1147,19 +1170,12 @@ void KFileItemModel::removeItems(const KItemRangeList& itemRanges, RemoveItemsBe m_groups.clear(); - // Step 1: Remove the items from the hash m_items, and free the ItemData. + // Step 1: Remove the items from m_itemData, and free the ItemData. int removedItemsCount = 0; foreach (const KItemRange& range, itemRanges) { removedItemsCount += range.count; for (int index = range.index; index < range.index + range.count; ++index) { - const KUrl url = m_itemData.at(index)->item.url(); - - // Prevent repeated expensive rehashing by using QHash::erase(), - // rather than QHash::remove(). - QHash<KUrl, int>::iterator it = m_items.find(url); - m_items.erase(it); - if (behavior == DeleteItemData) { delete m_itemData.at(index); } @@ -1188,12 +1204,9 @@ void KFileItemModel::removeItems(const KItemRangeList& itemRanges, RemoveItemsBe m_itemData.erase(m_itemData.end() - removedItemsCount, m_itemData.end()); - // Step 3: Adjust indexes in the hash m_items, starting from the - // index of the first removed item. - const int newItemDataCount = m_itemData.count(); - for (int i = itemRanges.front().index; i < newItemDataCount; ++i) { - m_items.insert(m_itemData.at(i)->item.url(), i); - } + // The indexes in m_items are not correct anymore. Therefore, we clear m_items. + // It will be re-populated with the updated indices if index(const KUrl&) is called. + m_items.clear(); emit itemsRemoved(itemRanges); } @@ -1207,7 +1220,7 @@ QList<KFileItemModel::ItemData*> KFileItemModel::createItemDataList(const KUrl& determineMimeTypes(items, 200); } - const int parentIndex = m_items.value(parentUrl, -1); + const int parentIndex = index(parentUrl); ItemData* parentItem = parentIndex < 0 ? 0 : m_itemData.at(parentIndex); QList<ItemData*> itemDataList; @@ -2070,7 +2083,7 @@ void KFileItemModel::emitSortProgress(int resolvedCount) const KFileItemModel::RoleInfoMap* KFileItemModel::rolesInfoMap(int& count) { static const RoleInfoMap rolesInfoMap[] = { - // | role | roleType | role translation | group translation | requires Nepomuk | requires indexer + // | role | roleType | role translation | group translation | requires Baloo | requires indexer { 0, NoRole, 0, 0, 0, 0, false, false }, { "text", NameRole, I18N_NOOP2_NOSTRIP("@label", "Name"), 0, 0, false, false }, { "size", SizeRole, I18N_NOOP2_NOSTRIP("@label", "Size"), 0, 0, false, false }, @@ -2136,7 +2149,9 @@ QByteArray KFileItemModel::sharedValue(const QByteArray& value) bool KFileItemModel::isConsistent() const { - if (m_items.count() != m_itemData.count()) { + // m_items may contain less items than m_itemData because m_items + // is populated lazily, see KFileItemModel::index(const KUrl& url). + if (m_items.count() > m_itemData.count()) { return false; } diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h index 022429023..62a283d33 100644 --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -130,14 +130,14 @@ public: /** * @return The index for the file-item \a item. -1 is returned if no file-item - * is found or if the file-item is null. The runtime + * is found or if the file-item is null. The amortized runtime * complexity of this call is O(1). */ int index(const KFileItem& item) const; /** * @return The index for the URL \a url. -1 is returned if no file-item - * is found. The runtime complexity of this call is O(1). + * is found. The amortized runtime complexity of this call is O(1). */ int index(const KUrl& url) const; @@ -187,14 +187,14 @@ public: { QByteArray role; QString translation; QString group; - bool requiresNepomuk; + bool requiresBaloo; bool requiresIndexer; }; /** * @return Provides static information for all available roles that * are supported by KFileItemModel. Some roles can only be - * determined if Nepomuk is enabled and/or the Nepomuk + * determined if Baloo is enabled and/or the Baloo * indexing is enabled. */ static QList<RoleInfo> rolesInformation(); @@ -277,7 +277,6 @@ private slots: void slotItemsDeleted(const KFileItemList& items); void slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >& items); void slotClear(); - void slotClear(const KUrl& url); void slotNaturalSortingChanged(); void dispatchPendingItemsToInsert(); @@ -287,7 +286,7 @@ private: // User visible roles: NoRole, NameRole, SizeRole, DateRole, PermissionsRole, OwnerRole, GroupRole, TypeRole, DestinationRole, PathRole, - // User visible roles available with Nepomuk: + // User visible roles available with Baloo: CommentRole, TagsRole, RatingRole, ImageSizeRole, OrientationRole, WordCountRole, LineCountRole, ArtistRole, AlbumRole, DurationRole, TrackRole, CopiedFromRole, @@ -432,7 +431,7 @@ private: const char* const roleTranslation; const char* const groupTranslationContext; const char* const groupTranslation; - const bool requiresNepomuk; + const bool requiresBaloo; const bool requiresIndexer; }; @@ -470,7 +469,12 @@ private: Qt::CaseSensitivity m_caseSensitivity; QList<ItemData*> m_itemData; - QHash<KUrl, int> m_items; // Allows O(1) access for KFileItemModel::index(const KFileItem& item) + + // m_items is a cache for the method index(const KUrl&). If it contains N + // entries, it is guaranteed that these correspond to the first N items in + // the model, i.e., that (for every i between 0 and N - 1) + // m_items.value(fileItem(i).url()) == i + mutable QHash<KUrl, int> m_items; KFileItemModelFilter m_filter; QHash<KFileItem, ItemData*> m_filteredItems; // Items that got hidden by KFileItemModel::setNameFilter() diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp index d6445c981..0865d40e7 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.cpp +++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp @@ -40,10 +40,11 @@ #include <algorithm> -#ifdef HAVE_NEPOMUK - #include "private/knepomukrolesprovider.h" - #include <Nepomuk2/ResourceWatcher> - #include <Nepomuk2/ResourceManager> +#ifdef HAVE_BALOO + #include "private/kbaloorolesprovider.h" + #include <baloo/file.h> + #include <baloo/filefetchjob.h> + #include <baloo/filemonitor.h> #endif // #define KFILEITEMMODELROLESUPDATER_DEBUG @@ -88,9 +89,8 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO m_recentlyChangedItems(), m_changedItems(), m_directoryContentsCounter(0) - #ifdef HAVE_NEPOMUK - , m_nepomukResourceWatcher(0), - m_nepomukUriItems() + #ifdef HAVE_BALOO + , m_balooFileMonitor(0) #endif { Q_ASSERT(model); @@ -122,8 +122,8 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO m_resolvableRoles.insert("size"); m_resolvableRoles.insert("type"); m_resolvableRoles.insert("isExpandable"); -#ifdef HAVE_NEPOMUK - m_resolvableRoles += KNepomukRolesProvider::instance().roles(); +#ifdef HAVE_BALOO + m_resolvableRoles += KBalooRolesProvider::instance().roles(); #endif m_directoryContentsCounter = new KDirectoryContentsCounter(m_model, this); @@ -262,34 +262,29 @@ void KFileItemModelRolesUpdater::setRoles(const QSet<QByteArray>& roles) if (m_roles != roles) { m_roles = roles; -#ifdef HAVE_NEPOMUK - if (Nepomuk2::ResourceManager::instance()->initialized()) { - // Check whether there is at least one role that must be resolved - // with the help of Nepomuk. If this is the case, a (quite expensive) - // resolving will be done in KFileItemModelRolesUpdater::rolesData() and - // the role gets watched for changes. - const KNepomukRolesProvider& rolesProvider = KNepomukRolesProvider::instance(); - bool hasNepomukRole = false; - QSetIterator<QByteArray> it(roles); - while (it.hasNext()) { - const QByteArray& role = it.next(); - if (rolesProvider.roles().contains(role)) { - hasNepomukRole = true; - break; - } +#ifdef HAVE_BALOO + // Check whether there is at least one role that must be resolved + // with the help of Baloo. If this is the case, a (quite expensive) + // resolving will be done in KFileItemModelRolesUpdater::rolesData() and + // the role gets watched for changes. + const KBalooRolesProvider& rolesProvider = KBalooRolesProvider::instance(); + bool hasBalooRole = false; + QSetIterator<QByteArray> it(roles); + while (it.hasNext()) { + const QByteArray& role = it.next(); + if (rolesProvider.roles().contains(role)) { + hasBalooRole = true; + break; } + } - if (hasNepomukRole && !m_nepomukResourceWatcher) { - Q_ASSERT(m_nepomukUriItems.isEmpty()); - - m_nepomukResourceWatcher = new Nepomuk2::ResourceWatcher(this); - connect(m_nepomukResourceWatcher, SIGNAL(propertyChanged(Nepomuk2::Resource,Nepomuk2::Types::Property,QVariantList,QVariantList)), - this, SLOT(applyChangedNepomukRoles(Nepomuk2::Resource,Nepomuk2::Types::Property))); - } else if (!hasNepomukRole && m_nepomukResourceWatcher) { - delete m_nepomukResourceWatcher; - m_nepomukResourceWatcher = 0; - m_nepomukUriItems.clear(); - } + if (hasBalooRole && !m_balooFileMonitor) { + m_balooFileMonitor = new Baloo::FileMonitor(this); + connect(m_balooFileMonitor, SIGNAL(fileMetaDataChanged(QString)), + this, SLOT(applyChangedBalooRoles(QString))); + } else if (!hasBalooRole && m_balooFileMonitor) { + delete m_balooFileMonitor; + m_balooFileMonitor = 0; } #endif @@ -357,30 +352,19 @@ void KFileItemModelRolesUpdater::slotItemsRemoved(const KItemRangeList& itemRang const bool allItemsRemoved = (m_model->count() == 0); -#ifdef HAVE_NEPOMUK - if (m_nepomukResourceWatcher) { - // Don't let the ResourceWatcher watch for removed items +#ifdef HAVE_BALOO + if (m_balooFileMonitor) { + // Don't let the FileWatcher watch for removed items if (allItemsRemoved) { - m_nepomukResourceWatcher->setResources(QList<Nepomuk2::Resource>()); - m_nepomukResourceWatcher->stop(); - m_nepomukUriItems.clear(); + m_balooFileMonitor->clear(); } else { - QList<Nepomuk2::Resource> newResources; - const QList<Nepomuk2::Resource> oldResources = m_nepomukResourceWatcher->resources(); - foreach (const Nepomuk2::Resource& resource, oldResources) { - const QUrl uri = resource.uri(); - const KUrl itemUrl = m_nepomukUriItems.value(uri); + QStringList newFileList; + foreach (const QString& itemUrl, m_balooFileMonitor->files()) { if (m_model->index(itemUrl) >= 0) { - newResources.append(resource); - } else { - m_nepomukUriItems.remove(uri); + newFileList.append(itemUrl); } } - m_nepomukResourceWatcher->setResources(newResources); - if (newResources.isEmpty()) { - Q_ASSERT(m_nepomukUriItems.isEmpty()); - m_nepomukResourceWatcher->stop(); - } + m_balooFileMonitor->setFiles(newFileList); } } #endif @@ -587,7 +571,7 @@ void KFileItemModelRolesUpdater::slotPreviewFailed(const KFileItem& item) connect(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)), this, SLOT(slotItemsChanged(KItemRangeList,QSet<QByteArray>))); - applyResolvedRoles(item, ResolveAll); + applyResolvedRoles(index, ResolveAll); m_finishedItems.insert(item); } } @@ -664,7 +648,7 @@ void KFileItemModelRolesUpdater::resolveNextPendingRoles() continue; } - applyResolvedRoles(item, ResolveAll); + applyResolvedRoles(index, ResolveAll); m_finishedItems.insert(item); m_changedItems.remove(item); break; @@ -708,14 +692,9 @@ void KFileItemModelRolesUpdater::resolveRecentlyChangedItems() updateChangedItems(); } -void KFileItemModelRolesUpdater::applyChangedNepomukRoles(const Nepomuk2::Resource& resource, const Nepomuk2::Types::Property& property) +void KFileItemModelRolesUpdater::applyChangedBalooRoles(const QString& itemUrl) { -#ifdef HAVE_NEPOMUK - if (!Nepomuk2::ResourceManager::instance()->initialized()) { - return; - } - - const KUrl itemUrl = m_nepomukUriItems.value(resource.uri()); +#ifdef HAVE_BALOO const KFileItem item = m_model->fileItem(itemUrl); if (item.isNull()) { @@ -724,18 +703,34 @@ void KFileItemModelRolesUpdater::applyChangedNepomukRoles(const Nepomuk2::Resour return; } - QHash<QByteArray, QVariant> data = rolesData(item); + Baloo::FileFetchJob* job = new Baloo::FileFetchJob(item.localPath()); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(applyChangedBalooRolesJobFinished(KJob*))); + job->setProperty("item", QVariant::fromValue(item)); + job->start(); +#else +#ifndef Q_CC_MSVC + Q_UNUSED(itemUrl); +#endif +#endif +} - const KNepomukRolesProvider& rolesProvider = KNepomukRolesProvider::instance(); - const QByteArray role = rolesProvider.roleForPropertyUri(property.uri()); - if (!role.isEmpty() && m_roles.contains(role)) { - // Overwrite the changed role value with an empty QVariant, because the roles +void KFileItemModelRolesUpdater::applyChangedBalooRolesJobFinished(KJob* kjob) +{ +#ifdef HAVE_BALOO + const KFileItem item = kjob->property("item").value<KFileItem>(); + + const KBalooRolesProvider& rolesProvider = KBalooRolesProvider::instance(); + QHash<QByteArray, QVariant> data; + + foreach (const QByteArray& role, rolesProvider.roles()) { + // Overwrite all the role values with an empty QVariant, because the roles // provider doesn't overwrite it when the property value list is empty. // See bug 322348 data.insert(role, QVariant()); } - QHashIterator<QByteArray, QVariant> it(rolesProvider.roleValues(resource, m_roles)); + Baloo::FileFetchJob* job = static_cast<Baloo::FileFetchJob*>(kjob); + QHashIterator<QByteArray, QVariant> it(rolesProvider.roleValues(job->file(), m_roles)); while (it.hasNext()) { it.next(); data.insert(it.key(), it.value()); @@ -747,10 +742,6 @@ void KFileItemModelRolesUpdater::applyChangedNepomukRoles(const Nepomuk2::Resour m_model->setData(index, data); connect(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)), this, SLOT(slotItemsChanged(KItemRangeList,QSet<QByteArray>))); -#else -#ifndef Q_CC_MSVC - Q_UNUSED(resource); -#endif #endif } @@ -762,7 +753,6 @@ void KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived(const QStrin if (getSizeRole || getIsExpandableRole) { const int index = m_model->index(KUrl(path)); if (index >= 0) { - QHash<QByteArray, QVariant> data; if (getSizeRole) { @@ -850,8 +840,7 @@ void KFileItemModelRolesUpdater::updateVisibleIcons() // Try to determine the final icons for all visible items. int index; for (index = m_firstVisibleIndex; index <= lastVisibleIndex && timer.elapsed() < MaxBlockTimeout; ++index) { - const KFileItem item = m_model->fileItem(index); - applyResolvedRoles(item, ResolveFast); + applyResolvedRoles(index, ResolveFast); } // KFileItemListView::initializeItemListWidget(KItemListWidget*) will load @@ -1005,7 +994,7 @@ void KFileItemModelRolesUpdater::applySortRole(int index) const QString path = item.localPath(); data.insert("size", m_directoryContentsCounter->countDirectoryContentsSynchronously(path)); } else { - // Probably the sort role is a Nepomuk role - just determine all roles. + // Probably the sort role is a baloo role - just determine all roles. data = rolesData(item); } @@ -1024,27 +1013,20 @@ void KFileItemModelRolesUpdater::applySortProgressToModel() m_model->emitSortProgress(resolvedCount); } -bool KFileItemModelRolesUpdater::applyResolvedRoles(const KFileItem& item, ResolveHint hint) +bool KFileItemModelRolesUpdater::applyResolvedRoles(int index, ResolveHint hint) { - if (item.isNull()) { - return false; - } - + const KFileItem item = m_model->fileItem(index); const bool resolveAll = (hint == ResolveAll); bool iconChanged = false; if (!item.isMimeTypeKnown() || !item.isFinalIconKnown()) { item.determineMimeType(); iconChanged = true; - } else { - const int index = m_model->index(item); - if (!m_model->data(index).contains("iconName")) { - iconChanged = true; - } + } else if (!m_model->data(index).contains("iconName")) { + iconChanged = true; } if (iconChanged || resolveAll || m_clearPreviews) { - const int index = m_model->index(item); if (index < 0) { return false; } @@ -1095,35 +1077,12 @@ QHash<QByteArray, QVariant> KFileItemModelRolesUpdater::rolesData(const KFileIte data.insert("iconOverlays", item.overlays()); -#ifdef HAVE_NEPOMUK - if (m_nepomukResourceWatcher) { - const KNepomukRolesProvider& rolesProvider = KNepomukRolesProvider::instance(); - Nepomuk2::Resource resource(item.nepomukUri()); - QHashIterator<QByteArray, QVariant> it(rolesProvider.roleValues(resource, m_roles)); - while (it.hasNext()) { - it.next(); - data.insert(it.key(), it.value()); - } - - QUrl uri = resource.uri(); - if (uri.isEmpty()) { - // TODO: Is there another way to explicitly create a resource? - // We need a resource to be able to track it for changes. - resource.setRating(0); - uri = resource.uri(); - } - if (!uri.isEmpty() && !m_nepomukUriItems.contains(uri)) { - m_nepomukResourceWatcher->addResource(resource); - - if (m_nepomukUriItems.isEmpty()) { - m_nepomukResourceWatcher->start(); - } - - m_nepomukUriItems.insert(uri, item.url()); - } +#ifdef HAVE_BALOO + if (m_balooFileMonitor) { + m_balooFileMonitor->addFile(item.localPath()); + applyChangedBalooRoles(item.localPath()); } #endif - return data; } diff --git a/src/kitemviews/kfileitemmodelrolesupdater.h b/src/kitemviews/kfileitemmodelrolesupdater.h index fced44a85..a9e979ae1 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.h +++ b/src/kitemviews/kfileitemmodelrolesupdater.h @@ -20,7 +20,7 @@ #ifndef KFILEITEMMODELROLESUPDATER_H #define KFILEITEMMODELROLESUPDATER_H -#include <config-nepomuk.h> +#include <config-baloo.h> #include <KFileItem> #include <kitemviews/kitemmodelbase.h> @@ -38,26 +38,10 @@ class KJob; class QPixmap; class QTimer; -#ifdef HAVE_NEPOMUK - namespace Nepomuk2 +#ifdef HAVE_BALOO + namespace Baloo { - class ResourceWatcher; - class Resource; - namespace Types - { - class Property; - } - } -#else - // Required for the slot applyChangedNepomukRoles() that - // cannot be ifdefined due to moc. - namespace Nepomuk2 - { - class Resource; - namespace Types - { - class Property; - } + class FileMonitor; } #endif @@ -216,7 +200,8 @@ private slots: */ void resolveRecentlyChangedItems(); - void applyChangedNepomukRoles(const Nepomuk2::Resource& resource, const Nepomuk2::Types::Property& property); + void applyChangedBalooRoles(const QString& file); + void applyChangedBalooRolesJobFinished(KJob* job); void slotDirectoryContentsCountReceived(const QString& path, int count); @@ -261,7 +246,7 @@ private: ResolveFast, ResolveAll }; - bool applyResolvedRoles(const KFileItem& item, ResolveHint hint); + bool applyResolvedRoles(int index, ResolveHint hint); QHash<QByteArray, QVariant> rolesData(const KFileItem& item); /** @@ -346,9 +331,8 @@ private: KDirectoryContentsCounter* m_directoryContentsCounter; -#ifdef HAVE_NEPOMUK - Nepomuk2::ResourceWatcher* m_nepomukResourceWatcher; - mutable QHash<QUrl, KUrl> m_nepomukUriItems; +#ifdef HAVE_BALOO + Baloo::FileMonitor* m_balooFileMonitor; #endif }; diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 7344b9960..8e2ef5ef3 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -538,11 +538,10 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const m_pressedIndex = m_view->itemAt(m_pressedMousePos); emit mouseButtonPressed(m_pressedIndex, event->buttons()); - if ((event->buttons() & (Qt::XButton1 | Qt::XButton2)) && m_pressedIndex < 0) { - // Do not select items when clicking the empty part of the view with - // the back/forward buttons, see https://bugs.kde.org/show_bug.cgi?id=327412. - // Note that clicking an item with these buttons selects it, see comment in - // DolphinView::slotMouseButtonPressed(int, Qt::MouseButtons). + // TODO: Qt5: Replace Qt::XButton1 by Qt::BackButton and Qt::XButton2 by Qt::ForwardButton + if (event->buttons() & (Qt::XButton1 | Qt::XButton2)) { + // Do not select items when clicking the back/forward buttons, see + // https://bugs.kde.org/show_bug.cgi?id=327412. return true; } @@ -952,8 +951,13 @@ bool KItemListController::hoverMoveEvent(QGraphicsSceneHoverEvent* event, const if (newHoveredWidget) { newHoveredWidget->setHovered(true); + const QPointF mappedPos = newHoveredWidget->mapFromItem(m_view, pos); + newHoveredWidget->setHoverPosition(mappedPos); emit itemHovered(newHoveredWidget->index()); } + } else if (oldHoveredWidget) { + const QPointF mappedPos = oldHoveredWidget->mapFromItem(m_view, pos); + oldHoveredWidget->setHoverPosition(mappedPos); } return false; diff --git a/src/kitemviews/kitemliststyleoption.cpp b/src/kitemviews/kitemliststyleoption.cpp index ac2587962..edd6363c8 100644 --- a/src/kitemviews/kitemliststyleoption.cpp +++ b/src/kitemviews/kitemliststyleoption.cpp @@ -31,7 +31,8 @@ KItemListStyleOption::KItemListStyleOption() : verticalMargin(-1), iconSize(-1), extendedSelectionRegion(false), - maxTextSize() + maxTextLines(0), + maxTextWidth(0) { } @@ -45,7 +46,8 @@ KItemListStyleOption::KItemListStyleOption(const KItemListStyleOption& other) : verticalMargin(other.verticalMargin), iconSize(other.iconSize), extendedSelectionRegion(other.extendedSelectionRegion), - maxTextSize(other.maxTextSize) + maxTextLines(other.maxTextLines), + maxTextWidth(other.maxTextWidth) { } diff --git a/src/kitemviews/kitemliststyleoption.h b/src/kitemviews/kitemliststyleoption.h index 1a304fc28..782dd0ec2 100644 --- a/src/kitemviews/kitemliststyleoption.h +++ b/src/kitemviews/kitemliststyleoption.h @@ -43,7 +43,8 @@ public: int verticalMargin; int iconSize; bool extendedSelectionRegion; - QSize maxTextSize; + int maxTextLines; + int maxTextWidth; }; #endif diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 7f497210c..f1b35fa53 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -111,8 +111,7 @@ KItemListView::KItemListView(QGraphicsWidget* parent) : m_sizeHintResolver = new KItemListSizeHintResolver(this); - m_layouter = new KItemListViewLayouter(this); - m_layouter->setSizeHintResolver(m_sizeHintResolver); + m_layouter = new KItemListViewLayouter(m_sizeHintResolver, this); m_animation = new KItemListViewAnimation(this); connect(m_animation, SIGNAL(finished(QGraphicsWidget*,KItemListViewAnimation::AnimationType)), @@ -460,9 +459,9 @@ int KItemListView::lastVisibleIndex() const return m_layouter->lastVisibleIndex(); } -QSizeF KItemListView::itemSizeHint(int index) const +void KItemListView::calculateItemSizeHints(QVector<QSizeF>& sizeHints) const { - return widgetCreator()->itemSizeHint(index, this); + widgetCreator()->calculateItemSizeHints(sizeHints, this); } void KItemListView::setSupportsItemExpanding(bool supportsExpanding) @@ -761,7 +760,8 @@ void KItemListView::setStyleOption(const KItemListStyleOption& option) updateGroupHeaderHeight(); } - if (animate && previousOption.maxTextSize != option.maxTextSize) { + if (animate && + (previousOption.maxTextLines != option.maxTextLines || previousOption.maxTextWidth != option.maxTextWidth)) { // Animating a change of the maximum text size just results in expensive // temporary eliding and clipping operations and does not look good visually. animate = false; @@ -894,11 +894,23 @@ void KItemListView::onTransactionEnd() bool KItemListView::event(QEvent* event) { - // Forward all events to the controller and handle them there - if (!m_editingRole && m_controller && m_controller->processEvent(event, transform())) { - event->accept(); - return true; + switch (event->type()) { + case QEvent::PaletteChange: + updatePalette(); + break; + + case QEvent::FontChange: + updateFont(); + break; + + default: + // Forward all other events to the controller and handle them there + if (!m_editingRole && m_controller && m_controller->processEvent(event, transform())) { + event->accept(); + return true; + } } + return QGraphicsWidget::event(event); } @@ -951,6 +963,27 @@ QList<KItemListWidget*> KItemListView::visibleItemListWidgets() const return m_visibleItems.values(); } +void KItemListView::updateFont() +{ + if (scene() && !scene()->views().isEmpty()) { + KItemListStyleOption option = styleOption(); + option.font = scene()->views().first()->font(); + option.fontMetrics = QFontMetrics(option.font); + + setStyleOption(option); + } +} + +void KItemListView::updatePalette() +{ + if (scene() && !scene()->views().isEmpty()) { + KItemListStyleOption option = styleOption(); + option.palette = scene()->views().first()->palette(); + + setStyleOption(option); + } +} + void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges) { if (m_itemSize.isEmpty()) { diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index dbe923086..8a522a686 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -194,12 +194,12 @@ public: int lastVisibleIndex() const; /** - * @return Required size for the item with the index \p index. + * @return Required size for all items in the model. * The returned value might be larger than KItemListView::itemSize(). * In this case the layout grid will be stretched to assure an * unclipped item. */ - QSizeF itemSizeHint(int index) const; + void calculateItemSizeHints(QVector<QSizeF>& sizeHints) const; /** * If set to true, items having child-items can be expanded to show the child-items as @@ -388,6 +388,9 @@ protected: QList<KItemListWidget*> visibleItemListWidgets() const; + virtual void updateFont(); + virtual void updatePalette(); + protected slots: virtual void slotItemsInserted(const KItemRangeList& itemRanges); virtual void slotItemsRemoved(const KItemRangeList& itemRanges); @@ -802,7 +805,7 @@ public: virtual void recycle(KItemListWidget* widget); - virtual QSizeF itemSizeHint(int index, const KItemListView* view) const = 0; + virtual void calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const = 0; virtual qreal preferredRoleColumnWidth(const QByteArray& role, int index, @@ -821,7 +824,7 @@ public: virtual KItemListWidget* create(KItemListView* view); - virtual QSizeF itemSizeHint(int index, const KItemListView* view) const; + virtual void calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const; virtual qreal preferredRoleColumnWidth(const QByteArray& role, int index, @@ -854,9 +857,9 @@ KItemListWidget* KItemListWidgetCreator<T>::create(KItemListView* view) } template<class T> -QSizeF KItemListWidgetCreator<T>::itemSizeHint(int index, const KItemListView* view) const +void KItemListWidgetCreator<T>::calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const { - return m_informant->itemSizeHint(index, view); + return m_informant->calculateItemSizeHints(sizeHints, view); } template<class T> diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index 85cd70c43..44754a694 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -279,6 +279,13 @@ bool KItemListWidget::isHovered() const return m_hovered; } +void KItemListWidget::setHoverPosition(const QPointF& pos) +{ + if (m_selectionToggle) { + m_selectionToggle->setHovered(m_selectionToggle->contains(pos)); + } +} + void KItemListWidget::setAlternateBackground(bool enable) { if (m_alternateBackground != enable) { diff --git a/src/kitemviews/kitemlistwidget.h b/src/kitemviews/kitemlistwidget.h index 55181faa8..cfb9155eb 100644 --- a/src/kitemviews/kitemlistwidget.h +++ b/src/kitemviews/kitemlistwidget.h @@ -49,7 +49,7 @@ public: KItemListWidgetInformant(); virtual ~KItemListWidgetInformant(); - virtual QSizeF itemSizeHint(int index, const KItemListView* view) const = 0; + virtual void calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const = 0; virtual qreal preferredRoleColumnWidth(const QByteArray& role, int index, @@ -108,6 +108,8 @@ public: void setHovered(bool hovered); bool isHovered() const; + void setHoverPosition(const QPointF& pos); + void setAlternateBackground(bool enable); bool alternateBackground() const; diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp index 54546b440..037226997 100644 --- a/src/kitemviews/kstandarditemlistwidget.cpp +++ b/src/kitemviews/kstandarditemlistwidget.cpp @@ -55,84 +55,25 @@ KStandardItemListWidgetInformant::~KStandardItemListWidgetInformant() { } -QSizeF KStandardItemListWidgetInformant::itemSizeHint(int index, const KItemListView* view) const +void KStandardItemListWidgetInformant::calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const { - const KItemListStyleOption& option = view->styleOption(); - const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0); - switch (static_cast<const KStandardItemListView*>(view)->itemLayout()) { - case KStandardItemListWidget::IconsLayout: { - const QString text = KStringHandler::preProcessWrap(itemText(index, view)); - - const qreal itemWidth = view->itemSize().width(); - const qreal maxWidth = itemWidth - 2 * option.padding; - QTextLine line; - - // Calculate the number of lines required for wrapping the name - QTextOption textOption(Qt::AlignHCenter); - textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); - - qreal textHeight = 0; - QTextLayout layout(text, option.font); - layout.setTextOption(textOption); - layout.beginLayout(); - while ((line = layout.createLine()).isValid()) { - line.setLineWidth(maxWidth); - line.naturalTextWidth(); - textHeight += line.height(); - } - layout.endLayout(); - - // Add one line for each additional information - textHeight += additionalRolesCount * option.fontMetrics.lineSpacing(); - - const qreal maxTextHeight = option.maxTextSize.height(); - if (maxTextHeight > 0 && textHeight > maxTextHeight) { - textHeight = maxTextHeight; - } - - return QSizeF(itemWidth, textHeight + option.iconSize + option.padding * 3); - } - - case KStandardItemListWidget::CompactLayout: { - // For each row exactly one role is shown. Calculate the maximum required width that is necessary - // to show all roles without horizontal clipping. - qreal maximumRequiredWidth = 0.0; - - const QList<QByteArray>& visibleRoles = view->visibleRoles(); - const bool showOnlyTextRole = (visibleRoles.count() == 1) && (visibleRoles.first() == "text"); - - if (showOnlyTextRole) { - maximumRequiredWidth = option.fontMetrics.width(itemText(index, view)); - } else { - const QHash<QByteArray, QVariant> values = view->model()->data(index); - foreach (const QByteArray& role, view->visibleRoles()) { - const QString text = roleText(role, values); - const qreal requiredWidth = option.fontMetrics.width(text); - maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth); - } - } + case KStandardItemListWidget::IconsLayout: + calculateIconsLayoutItemSizeHints(sizeHints, view); + break; - qreal width = option.padding * 4 + option.iconSize + maximumRequiredWidth; - const qreal maxWidth = option.maxTextSize.width(); - if (maxWidth > 0 && width > maxWidth) { - width = maxWidth; - } - const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.lineSpacing()); - return QSizeF(width, height); - } + case KStandardItemListWidget::CompactLayout: + calculateCompactLayoutItemSizeHints(sizeHints, view); + break; - case KStandardItemListWidget::DetailsLayout: { - const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height()); - return QSizeF(-1, height); - } + case KStandardItemListWidget::DetailsLayout: + calculateDetailsLayoutItemSizeHints(sizeHints, view); + break; default: Q_ASSERT(false); break; } - - return QSize(); } qreal KStandardItemListWidgetInformant::preferredRoleColumnWidth(const QByteArray& role, @@ -145,16 +86,22 @@ qreal KStandardItemListWidgetInformant::preferredRoleColumnWidth(const QByteArra const QString text = roleText(role, values); qreal width = KStandardItemListWidget::columnPadding(option); + const QFontMetrics& normalFontMetrics = option.fontMetrics; + const QFontMetrics linkFontMetrics(customizedFontForLinks(option.font)); + if (role == "rating") { width += KStandardItemListWidget::preferredRatingSize(option).width(); } else { - width += option.fontMetrics.width(text); + // If current item is a link, we use the customized link font metrics instead of the normal font metrics. + const QFontMetrics& fontMetrics = itemIsLink(index, view) ? linkFontMetrics : normalFontMetrics; + + width += fontMetrics.width(text); if (role == "text") { if (view->supportsItemExpanding()) { // Increase the width by the expansion-toggle and the current expansion level const int expandedParentsCount = values.value("expandedParentsCount", 0).toInt(); - const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height()); + const qreal height = option.padding * 2 + qMax(option.iconSize, fontMetrics.height()); width += (expandedParentsCount + 1) * height; } @@ -171,6 +118,11 @@ QString KStandardItemListWidgetInformant::itemText(int index, const KItemListVie return view->model()->data(index).value("text").toString(); } +bool KStandardItemListWidgetInformant::itemIsLink(int index, const KItemListView* view) const +{ + return false; +} + QString KStandardItemListWidgetInformant::roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values) const { @@ -181,6 +133,123 @@ QString KStandardItemListWidgetInformant::roleText(const QByteArray& role, return values.value(role).toString(); } +QFont KStandardItemListWidgetInformant::customizedFontForLinks(const QFont& baseFont) const +{ + return baseFont; +} + +void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const +{ + const KItemListStyleOption& option = view->styleOption(); + const QFont& normalFont = option.font; + const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0); + + const qreal itemWidth = view->itemSize().width(); + const qreal maxWidth = itemWidth - 2 * option.padding; + const qreal additionalRolesSpacing = additionalRolesCount * option.fontMetrics.lineSpacing(); + const qreal spacingAndIconHeight = option.iconSize + option.padding * 3; + + const QFont linkFont = customizedFontForLinks(normalFont); + + QTextOption textOption(Qt::AlignHCenter); + textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + + for (int index = 0; index < sizeHints.count(); ++index) { + if (!sizeHints.at(index).isEmpty()) { + continue; + } + + // If the current item is a link, we use the customized link font instead of the normal font. + const QFont& font = itemIsLink(index, view) ? linkFont : normalFont; + + const QString& text = KStringHandler::preProcessWrap(itemText(index, view)); + + // Calculate the number of lines required for wrapping the name + qreal textHeight = 0; + QTextLayout layout(text, font); + layout.setTextOption(textOption); + layout.beginLayout(); + QTextLine line; + int lineCount = 0; + while ((line = layout.createLine()).isValid()) { + line.setLineWidth(maxWidth); + line.naturalTextWidth(); + textHeight += line.height(); + + ++lineCount; + if (lineCount == option.maxTextLines) { + break; + } + } + layout.endLayout(); + + // Add one line for each additional information + textHeight += additionalRolesSpacing; + + sizeHints[index] = QSizeF(itemWidth, textHeight + spacingAndIconHeight); + } +} + +void KStandardItemListWidgetInformant::calculateCompactLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const +{ + const KItemListStyleOption& option = view->styleOption(); + const QFontMetrics& normalFontMetrics = option.fontMetrics; + const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0); + + const QList<QByteArray>& visibleRoles = view->visibleRoles(); + const bool showOnlyTextRole = (visibleRoles.count() == 1) && (visibleRoles.first() == "text"); + const qreal maxWidth = option.maxTextWidth; + const qreal paddingAndIconWidth = option.padding * 4 + option.iconSize; + const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * normalFontMetrics.lineSpacing()); + + const QFontMetrics linkFontMetrics(customizedFontForLinks(option.font)); + + for (int index = 0; index < sizeHints.count(); ++index) { + if (!sizeHints.at(index).isEmpty()) { + continue; + } + + // If the current item is a link, we use the customized link font metrics instead of the normal font metrics. + const QFontMetrics& fontMetrics = itemIsLink(index, view) ? linkFontMetrics : normalFontMetrics; + + // For each row exactly one role is shown. Calculate the maximum required width that is necessary + // to show all roles without horizontal clipping. + qreal maximumRequiredWidth = 0.0; + + if (showOnlyTextRole) { + maximumRequiredWidth = fontMetrics.width(itemText(index, view)); + } else { + const QHash<QByteArray, QVariant>& values = view->model()->data(index); + foreach (const QByteArray& role, visibleRoles) { + const QString& text = roleText(role, values); + const qreal requiredWidth = fontMetrics.width(text); + maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth); + } + } + + qreal width = paddingAndIconWidth + maximumRequiredWidth; + if (maxWidth > 0 && width > maxWidth) { + width = maxWidth; + } + + sizeHints[index] = QSizeF(width, height); + } +} + +void KStandardItemListWidgetInformant::calculateDetailsLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const +{ + const KItemListStyleOption& option = view->styleOption(); + const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height()); + + for (int index = 0; index < sizeHints.count(); ++index) { + if (!sizeHints.at(index).isEmpty()) { + continue; + } + + sizeHints[index] = QSizeF(-1, height); + } +} + KStandardItemListWidget::KStandardItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) : KItemListWidget(informant, parent), m_isCut(false), @@ -1030,9 +1099,6 @@ void KStandardItemListWidget::updateIconsLayoutTextCache() qreal nameHeight = 0; QTextLine line; - const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0); - const int maxNameLines = (option.maxTextSize.height() / int(lineSpacing)) - additionalRolesCount; - QTextLayout layout(nameTextInfo->staticText.text(), m_customizedFont); layout.setTextOption(nameTextInfo->staticText.textOption()); layout.beginLayout(); @@ -1043,7 +1109,7 @@ void KStandardItemListWidget::updateIconsLayoutTextCache() nameHeight += line.height(); ++nameLineIndex; - if (nameLineIndex == maxNameLines) { + if (nameLineIndex == option.maxTextLines) { // The maximum number of textlines has been reached. If this is // the case provide an elided text if necessary. const int textLength = line.textStart() + line.textLength(); @@ -1065,6 +1131,7 @@ void KStandardItemListWidget::updateIconsLayoutTextCache() layout.endLayout(); // Use one line for each additional information + const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0); nameTextInfo->staticText.setTextWidth(maxWidth); nameTextInfo->pos = QPointF(padding, widgetHeight - nameHeight - diff --git a/src/kitemviews/kstandarditemlistwidget.h b/src/kitemviews/kstandarditemlistwidget.h index 7dd93b2b8..ba426d054 100644 --- a/src/kitemviews/kstandarditemlistwidget.h +++ b/src/kitemviews/kstandarditemlistwidget.h @@ -38,7 +38,7 @@ public: KStandardItemListWidgetInformant(); virtual ~KStandardItemListWidgetInformant(); - virtual QSizeF itemSizeHint(int index, const KItemListView* view) const; + virtual void calculateItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const; virtual qreal preferredRoleColumnWidth(const QByteArray& role, int index, @@ -54,6 +54,13 @@ protected: virtual QString itemText(int index, const KItemListView* view) const; /** + * @return The value of the "isLink" role. The default implementation returns false. + * The derived class should reimplement this function, when information about + * links is available and in usage. + */ + virtual bool itemIsLink(int index, const KItemListView* view) const; + + /** * @return String representation of the role \a role. The representation of * a role might depend on other roles, so the values of all roles * are passed as parameter. @@ -61,6 +68,15 @@ protected: virtual QString roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values) const; + /** + * @return A font based on baseFont which is customized for symlinks. + */ + virtual QFont customizedFontForLinks(const QFont& baseFont) const; + + void calculateIconsLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const; + void calculateCompactLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const; + void calculateDetailsLayoutItemSizeHints(QVector<QSizeF>& sizeHints, const KItemListView* view) const; + friend class KStandardItemListWidget; // Accesses roleText() }; diff --git a/src/kitemviews/private/kbaloorolesprovider.cpp b/src/kitemviews/private/kbaloorolesprovider.cpp new file mode 100644 index 000000000..c0ae0c544 --- /dev/null +++ b/src/kitemviews/private/kbaloorolesprovider.cpp @@ -0,0 +1,184 @@ +/*************************************************************************** + * Copyright (C) 2012 by Peter Penz <[email protected]> * + * Copyright (C) 2013 by Vishesh Handa <[email protected]> * + * * + * 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 "kbaloorolesprovider.h" + +#include <KDebug> +#include <KGlobal> +#include <KLocale> + +#include <baloo/file.h> +#include <kfilemetadata/propertyinfo.h> + +#include <QTime> +#include <QMap> + +struct KBalooRolesProviderSingleton +{ + KBalooRolesProvider instance; +}; +K_GLOBAL_STATIC(KBalooRolesProviderSingleton, s_balooRolesProvider) + + +KBalooRolesProvider& KBalooRolesProvider::instance() +{ + return s_balooRolesProvider->instance; +} + +KBalooRolesProvider::~KBalooRolesProvider() +{ +} + +QSet<QByteArray> KBalooRolesProvider::roles() const +{ + return m_roles; +} + +QHash<QByteArray, QVariant> KBalooRolesProvider::roleValues(const Baloo::File& file, + const QSet<QByteArray>& roles) const +{ + QHash<QByteArray, QVariant> values; + + int width = -1; + int height = -1; + + QMapIterator<KFileMetaData::Property::Property, QVariant> it(file.properties()); + while (it.hasNext()) { + it.next(); + + const KFileMetaData::PropertyInfo pi(it.key()); + const QString property = pi.name(); + const QByteArray role = roleForProperty(property); + if (role.isEmpty() || !roles.contains(role)) { + continue; + } + + const QVariant value = it.value(); + + if (role == "imageSize") { + // Merge the two properties for width and height + // as one string into the "imageSize" role + if (property == QLatin1String("width")) { + width = value.toInt(); + } + else if (property == QLatin1String("height")) { + height = value.toInt(); + } + + if (width >= 0 && height >= 0) { + QString widthAndHeight = QString::number(width); + widthAndHeight += QLatin1String(" x "); + widthAndHeight += QString::number(height); + values.insert(role, widthAndHeight); + } + } else if (role == "orientation") { + const QString orientation = orientationFromValue(value.toInt()); + values.insert(role, orientation); + } else if (role == "duration") { + const QString duration = durationFromValue(value.toInt()); + values.insert(role, duration); + } else { + values.insert(role, value.toString()); + } + } + + if (roles.contains("tags")) { + values.insert("tags", tagsFromValues(file.tags())); + } + if (roles.contains("rating")) { + values.insert("rating", QString::number(file.rating())); + } + if (roles.contains("comment")) { + values.insert("comment", file.userComment()); + } + + return values; +} + +QByteArray KBalooRolesProvider::roleForProperty(const QString& property) const +{ + return m_roleForProperty.value(property); +} + +KBalooRolesProvider::KBalooRolesProvider() : + m_roles(), + m_roleForProperty() +{ + struct PropertyInfo + { + const char* const property; + const char* const role; + }; + + // Mapping from the URIs to the KFileItemModel roles. Note that this must not be + // a 1:1 mapping: One role may contain several URI-values (e.g. the URIs for height and + // width of an image are mapped to the role "imageSize") + static const PropertyInfo propertyInfoList[] = { + { "rating", "rating" }, + { "tag", "tags" }, + { "comment", "comment" }, + { "wordCount", "wordCount" }, + { "lineCount", "lineCount" }, + { "width", "imageSize" }, + { "height", "imageSize" }, + { "nexif.orientation", "orientation", }, + { "artist", "artist" }, + { "album", "album" }, + { "duration", "duration" }, + { "trackNumber", "track" } + // { "http://www.semanticdesktop.org/ontologies/2010/04/30/ndo#copiedFrom", "copiedFrom" } + }; + + for (unsigned int i = 0; i < sizeof(propertyInfoList) / sizeof(PropertyInfo); ++i) { + m_roleForProperty.insert(propertyInfoList[i].property, propertyInfoList[i].role); + m_roles.insert(propertyInfoList[i].role); + } +} + +QString KBalooRolesProvider::tagsFromValues(const QStringList& values) const +{ + return values.join(", "); +} + +QString KBalooRolesProvider::orientationFromValue(int value) const +{ + QString string; + switch (value) { + case 1: string = i18nc("@item:intable Image orientation", "Unchanged"); break; + case 2: string = i18nc("@item:intable Image orientation", "Horizontally flipped"); break; + case 3: string = i18nc("@item:intable image orientation", "180° rotated"); break; + case 4: string = i18nc("@item:intable image orientation", "Vertically flipped"); break; + case 5: string = i18nc("@item:intable image orientation", "Transposed"); break; + case 6: string = i18nc("@item:intable image orientation", "90° rotated"); break; + case 7: string = i18nc("@item:intable image orientation", "Transversed"); break; + case 8: string = i18nc("@item:intable image orientation", "270° rotated"); break; + default: + break; + } + return string; +} + +QString KBalooRolesProvider::durationFromValue(int value) const +{ + QTime duration; + duration = duration.addSecs(value); + return duration.toString("hh:mm:ss"); +} + diff --git a/src/kitemviews/private/knepomukrolesprovider.h b/src/kitemviews/private/kbaloorolesprovider.h index 68a4027e1..f1ad5c740 100644 --- a/src/kitemviews/private/knepomukrolesprovider.h +++ b/src/kitemviews/private/kbaloorolesprovider.h @@ -1,5 +1,6 @@ /*************************************************************************** * Copyright (C) 2012 by Peter Penz <[email protected]> * + * Copyright (C) 2013 by Vishesh Handa <[email protected]> * * * * 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 * @@ -17,8 +18,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#ifndef KNEPOMUKROLESPROVIDER_H -#define KNEPOMUKROLESPROVIDER_H +#ifndef KBALOO_ROLESPROVIDER_H +#define KBALOO_ROLESPROVIDER_H #include <libdolphin_export.h> @@ -26,25 +27,24 @@ #include <QSet> #include <QUrl> -namespace Nepomuk2 -{ - class Resource; +namespace Baloo { + class File; } /** * @brief Allows accessing metadata of a file by providing KFileItemModel roles. * * Is a helper class for KFileItemModelRolesUpdater to retrieve roles that - * are only accessible with Nepomuk. + * are only accessible with Baloo. */ -class LIBDOLPHINPRIVATE_EXPORT KNepomukRolesProvider +class LIBDOLPHINPRIVATE_EXPORT KBalooRolesProvider { public: - static KNepomukRolesProvider& instance(); - virtual ~KNepomukRolesProvider(); + static KBalooRolesProvider& instance(); + virtual ~KBalooRolesProvider(); /** - * @return Roles that can be provided by KNepomukRolesProvider. + * @return Roles that can be provided by KBalooRolesProvider. */ QSet<QByteArray> roles() const; @@ -52,13 +52,13 @@ public: * @return Values for the roles \a roles that can be determined from the file * with the URL \a url. */ - QHash<QByteArray, QVariant> roleValues(const Nepomuk2::Resource& resource, + QHash<QByteArray, QVariant> roleValues(const Baloo::File& file, const QSet<QByteArray>& roles) const; - QByteArray roleForPropertyUri(const QUrl& uri) const; + QByteArray roleForProperty(const QString& property) const; protected: - KNepomukRolesProvider(); + KBalooRolesProvider(); private: /** @@ -81,9 +81,9 @@ private: private: QSet<QByteArray> m_roles; - QHash<QUrl, QByteArray> m_roleForUri; + QHash<QString, QByteArray> m_roleForProperty; - friend class KNepomukRolesProviderSingleton; + friend class KBalooRolesProviderSingleton; }; #endif diff --git a/src/kitemviews/private/kdirectorycontentscounter.cpp b/src/kitemviews/private/kdirectorycontentscounter.cpp index fd8479feb..7d1e76999 100644 --- a/src/kitemviews/private/kdirectorycontentscounter.cpp +++ b/src/kitemviews/private/kdirectorycontentscounter.cpp @@ -30,7 +30,6 @@ KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel* model, QObj QObject(parent), m_model(model), m_queue(), - m_workerThread(0), m_worker(0), m_workerIsBusy(false), m_dirWatcher(0), @@ -39,27 +38,45 @@ KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel* model, QObj connect(m_model, SIGNAL(itemsRemoved(KItemRangeList)), this, SLOT(slotItemsRemoved())); - m_workerThread = new QThread(this); + if (!m_workerThread) { + m_workerThread = new QThread(); + m_workerThread->start(); + } + m_worker = new KDirectoryContentsCounterWorker(); m_worker->moveToThread(m_workerThread); + ++m_workersCount; connect(this, SIGNAL(requestDirectoryContentsCount(QString,KDirectoryContentsCounterWorker::Options)), m_worker, SLOT(countDirectoryContents(QString,KDirectoryContentsCounterWorker::Options))); connect(m_worker, SIGNAL(result(QString,int)), this, SLOT(slotResult(QString,int))); - m_workerThread->start(); - m_dirWatcher = new KDirWatch(this); connect(m_dirWatcher, SIGNAL(dirty(QString)), this, SLOT(slotDirWatchDirty(QString))); } KDirectoryContentsCounter::~KDirectoryContentsCounter() { - m_workerThread->quit(); - m_workerThread->wait(); + --m_workersCount; - delete m_worker; + if (m_workersCount > 0) { + // The worker thread will continue running. It could even be running + // a method of m_worker at the moment, so we delete it using + // deleteLater() to prevent a crash. + m_worker->deleteLater(); + } else { + // There are no remaining workers -> stop the worker thread. + m_workerThread->quit(); + m_workerThread->wait(); + delete m_workerThread; + m_workerThread = 0; + + // The worker thread has finished running now, so it's safe to delete + // m_worker. deleteLater() would not work at all because the event loop + // which would deliver the event to m_worker is not running any more. + delete m_worker; + } } void KDirectoryContentsCounter::addDirectory(const QString& path) @@ -162,3 +179,6 @@ void KDirectoryContentsCounter::startWorker(const QString& path) m_workerIsBusy = true; } } + +QThread* KDirectoryContentsCounter::m_workerThread = 0; +int KDirectoryContentsCounter::m_workersCount = 0;
\ No newline at end of file diff --git a/src/kitemviews/private/kdirectorycontentscounter.h b/src/kitemviews/private/kdirectorycontentscounter.h index 425c3632a..c03d0249c 100644 --- a/src/kitemviews/private/kdirectorycontentscounter.h +++ b/src/kitemviews/private/kdirectorycontentscounter.h @@ -78,7 +78,9 @@ private: QQueue<QString> m_queue; - QThread* m_workerThread; + static QThread* m_workerThread; + static int m_workersCount; + KDirectoryContentsCounterWorker* m_worker; bool m_workerIsBusy; diff --git a/src/kitemviews/private/kitemlistheaderwidget.cpp b/src/kitemviews/private/kitemlistheaderwidget.cpp index b55ba1eb5..1f210ab5a 100644 --- a/src/kitemviews/private/kitemlistheaderwidget.cpp +++ b/src/kitemviews/private/kitemlistheaderwidget.cpp @@ -327,6 +327,22 @@ void KItemListHeaderWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* event) } } +void KItemListHeaderWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) +{ + QGraphicsItem::mouseDoubleClickEvent(event); + + const int roleIndex = roleIndexAt(event->pos()); + if (roleIndex >= 0 && isAboveRoleGrip(event->pos(), roleIndex)) { + const QByteArray role = m_columns.at(roleIndex); + + qreal previousWidth = columnWidth(role); + setColumnWidth(role, preferredColumnWidth(role)); + qreal currentWidth = columnWidth(role); + + emit columnWidthChanged(role, currentWidth, previousWidth); + } +} + void KItemListHeaderWidget::hoverEnterEvent(QGraphicsSceneHoverEvent* event) { QGraphicsWidget::hoverEnterEvent(event); diff --git a/src/kitemviews/private/kitemlistheaderwidget.h b/src/kitemviews/private/kitemlistheaderwidget.h index f8bba977b..b99f45f35 100644 --- a/src/kitemviews/private/kitemlistheaderwidget.h +++ b/src/kitemviews/private/kitemlistheaderwidget.h @@ -100,6 +100,7 @@ protected: virtual void mousePressEvent(QGraphicsSceneMouseEvent* event); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event); + virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event); virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event); virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event); virtual void hoverMoveEvent(QGraphicsSceneHoverEvent* event); diff --git a/src/kitemviews/private/kitemlistselectiontoggle.cpp b/src/kitemviews/private/kitemlistselectiontoggle.cpp index 6bbf3c2ec..accbe5181 100644 --- a/src/kitemviews/private/kitemlistselectiontoggle.cpp +++ b/src/kitemviews/private/kitemlistselectiontoggle.cpp @@ -30,7 +30,6 @@ KItemListSelectionToggle::KItemListSelectionToggle(QGraphicsItem* parent) : m_checked(false), m_hovered(false) { - setAcceptHoverEvents(true); } KItemListSelectionToggle::~KItemListSelectionToggle() @@ -51,6 +50,15 @@ bool KItemListSelectionToggle::isChecked() const return m_checked; } +void KItemListSelectionToggle::setHovered(bool hovered) +{ + if (m_hovered != hovered) { + m_hovered = hovered; + m_pixmap = QPixmap(); + update(); + } +} + void KItemListSelectionToggle::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { Q_UNUSED(option); @@ -65,20 +73,6 @@ void KItemListSelectionToggle::paint(QPainter* painter, const QStyleOptionGraphi painter->drawPixmap(x, y, m_pixmap); } -void KItemListSelectionToggle::hoverEnterEvent(QGraphicsSceneHoverEvent* event) -{ - QGraphicsWidget::hoverEnterEvent(event); - m_hovered = true; - m_pixmap = QPixmap(); -} - -void KItemListSelectionToggle::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) -{ - QGraphicsWidget::hoverLeaveEvent(event); - m_hovered = false; - m_pixmap = QPixmap(); -} - void KItemListSelectionToggle::resizeEvent(QGraphicsSceneResizeEvent* event) { QGraphicsWidget::resizeEvent(event); @@ -97,12 +91,9 @@ void KItemListSelectionToggle::resizeEvent(QGraphicsSceneResizeEvent* event) void KItemListSelectionToggle::updatePixmap() { - const char* icon = m_checked ? "list-remove" : "list-add"; - m_pixmap = KIconLoader::global()->loadIcon(QLatin1String(icon), KIconLoader::NoGroup, iconSize()); - - if (m_hovered) { - KIconLoader::global()->iconEffect()->apply(m_pixmap, KIconLoader::Desktop, KIconLoader::ActiveState); - } + const QString icon = m_checked ? "list-remove" : "list-add"; + const KIconLoader::States state = m_hovered ? KIconLoader::ActiveState : KIconLoader::DisabledState; + m_pixmap = KIconLoader::global()->loadIcon(icon, KIconLoader::Desktop, iconSize(), state); } int KItemListSelectionToggle::iconSize() const diff --git a/src/kitemviews/private/kitemlistselectiontoggle.h b/src/kitemviews/private/kitemlistselectiontoggle.h index ba29293f6..758dc63bb 100644 --- a/src/kitemviews/private/kitemlistselectiontoggle.h +++ b/src/kitemviews/private/kitemlistselectiontoggle.h @@ -41,11 +41,11 @@ public: void setChecked(bool checked); bool isChecked() const; + void setHovered(bool hovered); + virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); protected: - virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event); - virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event); virtual void resizeEvent(QGraphicsSceneResizeEvent* event); private: diff --git a/src/kitemviews/private/kitemlistsizehintresolver.cpp b/src/kitemviews/private/kitemlistsizehintresolver.cpp index 0e2286b45..029beddf9 100644 --- a/src/kitemviews/private/kitemlistsizehintresolver.cpp +++ b/src/kitemviews/private/kitemlistsizehintresolver.cpp @@ -23,7 +23,8 @@ KItemListSizeHintResolver::KItemListSizeHintResolver(const KItemListView* itemListView) : m_itemListView(itemListView), - m_sizeHintCache() + m_sizeHintCache(), + m_needsResolving(false) { } @@ -31,14 +32,10 @@ KItemListSizeHintResolver::~KItemListSizeHintResolver() { } -QSizeF KItemListSizeHintResolver::sizeHint(int index) const +QSizeF KItemListSizeHintResolver::sizeHint(int index) { - QSizeF size = m_sizeHintCache.at(index); - if (size.isEmpty()) { - size = m_itemListView->itemSizeHint(index); - m_sizeHintCache[index] = size; - } - return size; + updateCache(); + return m_sizeHintCache.at(index); } void KItemListSizeHintResolver::itemsInserted(const KItemRangeList& itemRanges) @@ -77,6 +74,8 @@ void KItemListSizeHintResolver::itemsInserted(const KItemRangeList& itemRanges) } } + m_needsResolving = true; + Q_ASSERT(m_sizeHintCache.count() == m_itemListView->model()->count()); } @@ -135,9 +134,20 @@ void KItemListSizeHintResolver::itemsChanged(int index, int count, const QSet<QB ++index; --count; } + + m_needsResolving = true; } void KItemListSizeHintResolver::clearCache() { m_sizeHintCache.fill(QSizeF()); + m_needsResolving = true; +} + +void KItemListSizeHintResolver::updateCache() +{ + if (m_needsResolving) { + m_itemListView->calculateItemSizeHints(m_sizeHintCache); + m_needsResolving = false; + } } diff --git a/src/kitemviews/private/kitemlistsizehintresolver.h b/src/kitemviews/private/kitemlistsizehintresolver.h index 486f9b631..86580bf7b 100644 --- a/src/kitemviews/private/kitemlistsizehintresolver.h +++ b/src/kitemviews/private/kitemlistsizehintresolver.h @@ -36,7 +36,7 @@ class LIBDOLPHINPRIVATE_EXPORT KItemListSizeHintResolver public: KItemListSizeHintResolver(const KItemListView* itemListView); virtual ~KItemListSizeHintResolver(); - QSizeF sizeHint(int index) const; + QSizeF sizeHint(int index); void itemsInserted(const KItemRangeList& itemRanges); void itemsRemoved(const KItemRangeList& itemRanges); @@ -44,10 +44,12 @@ public: void itemsChanged(int index, int count, const QSet<QByteArray>& roles); void clearCache(); + void updateCache(); private: const KItemListView* m_itemListView; mutable QVector<QSizeF> m_sizeHintCache; + bool m_needsResolving; }; #endif diff --git a/src/kitemviews/private/kitemlistviewanimation.cpp b/src/kitemviews/private/kitemlistviewanimation.cpp index e347c5bb1..5a00c8c3a 100644 --- a/src/kitemviews/private/kitemlistviewanimation.cpp +++ b/src/kitemviews/private/kitemlistviewanimation.cpp @@ -225,13 +225,13 @@ void KItemListViewAnimation::slotFinished() { QPropertyAnimation* finishedAnim = qobject_cast<QPropertyAnimation*>(sender()); for (int type = 0; type < AnimationTypeCount; ++type) { - QHashIterator<QGraphicsWidget*, QPropertyAnimation*> it(m_animation[type]); + QMutableHashIterator<QGraphicsWidget*, QPropertyAnimation*> it(m_animation[type]); while (it.hasNext()) { it.next(); QPropertyAnimation* propertyAnim = it.value(); if (propertyAnim == finishedAnim) { QGraphicsWidget* widget = it.key(); - m_animation[type].remove(widget); + it.remove(); finishedAnim->deleteLater(); emit finished(widget, static_cast<AnimationType>(type)); diff --git a/src/kitemviews/private/kitemlistviewlayouter.cpp b/src/kitemviews/private/kitemlistviewlayouter.cpp index f5f63d5ab..9da5384d4 100644 --- a/src/kitemviews/private/kitemlistviewlayouter.cpp +++ b/src/kitemviews/private/kitemlistviewlayouter.cpp @@ -26,7 +26,7 @@ // #define KITEMLISTVIEWLAYOUTER_DEBUG -KItemListViewLayouter::KItemListViewLayouter(QObject* parent) : +KItemListViewLayouter::KItemListViewLayouter(KItemListSizeHintResolver* sizeHintResolver, QObject* parent) : QObject(parent), m_dirty(true), m_visibleIndexesDirty(true), @@ -36,7 +36,7 @@ KItemListViewLayouter::KItemListViewLayouter(QObject* parent) : m_itemMargin(), m_headerHeight(0), m_model(0), - m_sizeHintResolver(0), + m_sizeHintResolver(sizeHintResolver), m_scrollOffset(0), m_maximumScrollOffset(0), m_itemOffset(0), @@ -46,11 +46,14 @@ KItemListViewLayouter::KItemListViewLayouter(QObject* parent) : m_columnWidth(0), m_xPosInc(0), m_columnCount(0), + m_rowOffsets(), + m_columnOffsets(), m_groupItemIndexes(), m_groupHeaderHeight(0), m_groupHeaderMargin(0), m_itemInfos() { + Q_ASSERT(m_sizeHintResolver); } KItemListViewLayouter::~KItemListViewLayouter() @@ -207,19 +210,6 @@ const KItemModelBase* KItemListViewLayouter::model() const return m_model; } -void KItemListViewLayouter::setSizeHintResolver(const KItemListSizeHintResolver* sizeHintResolver) -{ - if (m_sizeHintResolver != sizeHintResolver) { - m_sizeHintResolver = sizeHintResolver; - m_dirty = true; - } -} - -const KItemListSizeHintResolver* KItemListViewLayouter::sizeHintResolver() const -{ - return m_sizeHintResolver; -} - int KItemListViewLayouter::firstVisibleIndex() const { const_cast<KItemListViewLayouter*>(this)->doLayout(); @@ -239,18 +229,15 @@ QRectF KItemListViewLayouter::itemRect(int index) const return QRectF(); } - QSizeF sizeHint; - if (m_sizeHintResolver) { - sizeHint = m_sizeHintResolver->sizeHint(index); - } else { - sizeHint = m_itemSize; - } + QSizeF sizeHint = m_sizeHintResolver->sizeHint(index); + + const qreal x = m_columnOffsets.at(m_itemInfos.at(index).column); + const qreal y = m_rowOffsets.at(m_itemInfos.at(index).row); if (m_scrollOrientation == Qt::Horizontal) { // Rotate the logical direction which is always vertical by 90° // to get the physical horizontal direction - const QPointF logicalPos = m_itemInfos[index].pos; - QPointF pos(logicalPos.y(), logicalPos.x()); + QPointF pos(y, x); pos.rx() -= m_scrollOffset; return QRectF(pos, sizeHint); } @@ -260,8 +247,7 @@ QRectF KItemListViewLayouter::itemRect(int index) const sizeHint.rwidth() = m_itemSize.width(); } - QPointF pos = m_itemInfos[index].pos; - pos -= QPointF(m_itemOffset, m_scrollOffset); + const QPointF pos(x - m_itemOffset, y - m_scrollOffset); return QRectF(pos, sizeHint); } @@ -284,25 +270,19 @@ QRectF KItemListViewLayouter::groupHeaderRect(int index) const pos.rx() -= m_itemMargin.width(); pos.ry() = 0; - // Determine the maximum width used in the - // current column. As the scroll-direction is - // Qt::Horizontal and m_itemRects is accessed directly, - // the logical height represents the visual width. + // Determine the maximum width used in the current column. As the + // scroll-direction is Qt::Horizontal and m_itemRects is accessed + // directly, the logical height represents the visual width, and + // the logical row represents the column. qreal headerWidth = minimumGroupHeaderWidth(); - const qreal y = m_itemInfos[index].pos.y(); + const int row = m_itemInfos[index].row; const int maxIndex = m_itemInfos.count() - 1; while (index <= maxIndex) { - const QPointF pos = m_itemInfos[index].pos; - if (pos.y() != y) { + if (m_itemInfos[index].row != row) { break; } - qreal itemWidth; - if (m_sizeHintResolver) { - itemWidth = m_sizeHintResolver->sizeHint(index).width(); - } else { - itemWidth = m_itemSize.width(); - } + const qreal itemWidth = m_sizeHintResolver->sizeHint(index).width(); if (itemWidth > headerWidth) { headerWidth = itemWidth; @@ -422,21 +402,40 @@ void KItemListViewLayouter::doLayout() m_itemInfos.resize(itemCount); + // Calculate the offset of each column, i.e., the x-coordinate where the column starts. + m_columnOffsets.resize(m_columnCount); + qreal currentOffset = m_xPosInc; + + if (grouped && horizontalScrolling) { + // All group headers will always be aligned on the top and not + // flipped like the other properties. + currentOffset += m_groupHeaderHeight; + } + + for (int column = 0; column < m_columnCount; ++column) { + m_columnOffsets[column] = currentOffset; + currentOffset += m_columnWidth; + } + + // Prepare the QVector which stores the y-coordinate for each new row. + int numberOfRows = (itemCount + m_columnCount - 1) / m_columnCount; + if (grouped && m_columnCount > 1) { + // In the worst case, a new row will be started for every group. + // We could calculate the exact number of rows now to prevent that we reserve + // too much memory, but the code required to do that might need much more + // memory than it would save in the average case. + numberOfRows += m_groupItemIndexes.count(); + } + m_rowOffsets.resize(numberOfRows); + qreal y = m_headerHeight + itemMargin.height(); int row = 0; int index = 0; while (index < itemCount) { - qreal x = m_xPosInc; qreal maxItemHeight = itemSize.height(); if (grouped) { - if (horizontalScrolling) { - // All group headers will always be aligned on the top and not - // flipped like the other properties - x += m_groupHeaderHeight; - } - if (m_groupItemIndexes.contains(index)) { // The item is the first item of a group. // Increase the y-position to provide space @@ -456,19 +455,18 @@ void KItemListViewLayouter::doLayout() } } + m_rowOffsets[row] = y; + int column = 0; while (index < itemCount && column < m_columnCount) { qreal requiredItemHeight = itemSize.height(); - if (m_sizeHintResolver) { - const QSizeF sizeHint = m_sizeHintResolver->sizeHint(index); - const qreal sizeHintHeight = horizontalScrolling ? sizeHint.width() : sizeHint.height(); - if (sizeHintHeight > requiredItemHeight) { - requiredItemHeight = sizeHintHeight; - } + const QSizeF sizeHint = m_sizeHintResolver->sizeHint(index); + const qreal sizeHintHeight = horizontalScrolling ? sizeHint.width() : sizeHint.height(); + if (sizeHintHeight > requiredItemHeight) { + requiredItemHeight = sizeHintHeight; } ItemInfo& itemInfo = m_itemInfos[index]; - itemInfo.pos = QPointF(x, y); itemInfo.column = column; itemInfo.row = row; @@ -492,7 +490,6 @@ void KItemListViewLayouter::doLayout() } maxItemHeight = qMax(maxItemHeight, requiredItemHeight); - x += m_columnWidth; ++index; ++column; @@ -547,7 +544,7 @@ void KItemListViewLayouter::updateVisibleIndexes() int mid = 0; do { mid = (min + max) / 2; - if (m_itemInfos[mid].pos.y() < m_scrollOffset) { + if (m_rowOffsets.at(m_itemInfos[mid].row) < m_scrollOffset) { min = mid + 1; } else { max = mid - 1; @@ -557,13 +554,13 @@ void KItemListViewLayouter::updateVisibleIndexes() if (mid > 0) { // Include the row before the first fully visible index, as it might // be partly visible - if (m_itemInfos[mid].pos.y() >= m_scrollOffset) { + if (m_rowOffsets.at(m_itemInfos[mid].row) >= m_scrollOffset) { --mid; - Q_ASSERT(m_itemInfos[mid].pos.y() < m_scrollOffset); + Q_ASSERT(m_rowOffsets.at(m_itemInfos[mid].row) < m_scrollOffset); } - const qreal rowTop = m_itemInfos[mid].pos.y(); - while (mid > 0 && m_itemInfos[mid - 1].pos.y() == rowTop) { + const int firstVisibleRow = m_itemInfos[mid].row; + while (mid > 0 && m_itemInfos[mid - 1].row == firstVisibleRow) { --mid; } } @@ -580,14 +577,14 @@ void KItemListViewLayouter::updateVisibleIndexes() max = maxIndex; do { mid = (min + max) / 2; - if (m_itemInfos[mid].pos.y() <= bottom) { + if (m_rowOffsets.at(m_itemInfos[mid].row) <= bottom) { min = mid + 1; } else { max = mid - 1; } } while (min <= max); - while (mid > 0 && m_itemInfos[mid].pos.y() > bottom) { + while (mid > 0 && m_rowOffsets.at(m_itemInfos[mid].row) > bottom) { --mid; } m_lastVisibleIndex = mid; diff --git a/src/kitemviews/private/kitemlistviewlayouter.h b/src/kitemviews/private/kitemlistviewlayouter.h index a3b0893a1..0efcab12b 100644 --- a/src/kitemviews/private/kitemlistviewlayouter.h +++ b/src/kitemviews/private/kitemlistviewlayouter.h @@ -50,7 +50,7 @@ class LIBDOLPHINPRIVATE_EXPORT KItemListViewLayouter : public QObject Q_OBJECT public: - KItemListViewLayouter(QObject* parent = 0); + KItemListViewLayouter(KItemListSizeHintResolver* sizeHintResolver, QObject* parent = 0); virtual ~KItemListViewLayouter(); void setScrollOrientation(Qt::Orientation orientation); @@ -103,9 +103,6 @@ public: void setModel(const KItemModelBase* model); const KItemModelBase* model() const; - void setSizeHintResolver(const KItemListSizeHintResolver* sizeHintResolver); - const KItemListSizeHintResolver* sizeHintResolver() const; - /** * @return The first (at least partly) visible index. -1 is returned * if the item count is 0. @@ -205,7 +202,7 @@ private: QSizeF m_itemMargin; qreal m_headerHeight; const KItemModelBase* m_model; - const KItemListSizeHintResolver* m_sizeHintResolver; + KItemListSizeHintResolver* m_sizeHintResolver; qreal m_scrollOffset; qreal m_maximumScrollOffset; @@ -220,6 +217,9 @@ private: qreal m_xPosInc; int m_columnCount; + QVector<qreal> m_rowOffsets; + QVector<qreal> m_columnOffsets; + // Stores all item indexes that are the first item of a group. // Assures fast access for KItemListViewLayouter::isFirstGroupItem(). QSet<int> m_groupItemIndexes; @@ -227,7 +227,6 @@ private: qreal m_groupHeaderMargin; struct ItemInfo { - QPointF pos; int column; int row; }; diff --git a/src/kitemviews/private/knepomukrolesprovider.cpp b/src/kitemviews/private/knepomukrolesprovider.cpp deleted file mode 100644 index e237f948f..000000000 --- a/src/kitemviews/private/knepomukrolesprovider.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by Peter Penz <[email protected]> * - * * - * 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 "knepomukrolesprovider.h" - -#include <KDebug> -#include <KGlobal> -#include <KLocale> - -#include <Nepomuk2/Resource> -#include <Nepomuk2/Tag> -#include <Nepomuk2/Types/Property> -#include <Nepomuk2/Variant> - -#include <QTime> - -struct KNepomukRolesProviderSingleton -{ - KNepomukRolesProvider instance; -}; -K_GLOBAL_STATIC(KNepomukRolesProviderSingleton, s_nepomukRolesProvider) - - -KNepomukRolesProvider& KNepomukRolesProvider::instance() -{ - return s_nepomukRolesProvider->instance; -} - -KNepomukRolesProvider::~KNepomukRolesProvider() -{ -} - -QSet<QByteArray> KNepomukRolesProvider::roles() const -{ - return m_roles; -} - -QHash<QByteArray, QVariant> KNepomukRolesProvider::roleValues(const Nepomuk2::Resource& resource, - const QSet<QByteArray>& roles) const -{ - if (!resource.isValid()) { - return QHash<QByteArray, QVariant>(); - } - - QHash<QByteArray, QVariant> values; - - int width = -1; - int height = -1; - - QHashIterator<QUrl, Nepomuk2::Variant> it(resource.properties()); - while (it.hasNext()) { - it.next(); - - const Nepomuk2::Types::Property property = it.key(); - const QByteArray role = roleForPropertyUri(property.uri()); - if (role.isEmpty() || !roles.contains(role)) { - continue; - } - - const Nepomuk2::Variant value = it.value(); - - if (role == "imageSize") { - // Merge the two Nepomuk properties for width and height - // as one string into the "imageSize" role - const QString uri = property.uri().toString(); - if (uri.endsWith(QLatin1String("#width"))) { - width = value.toInt(); - } else if (uri.endsWith(QLatin1String("#height"))) { - height = value.toInt(); - } - - if (width >= 0 && height >= 0) { - const QString widthAndHeight = QString::number(width) + - QLatin1String(" x ") + - QString::number(height); - values.insert(role, widthAndHeight); - } - } else if (role == "tags") { - const QString tags = tagsFromValues(value.toStringList()); - values.insert(role, tags); - } else if (role == "orientation") { - const QString orientation = orientationFromValue(value.toInt()); - values.insert(role, orientation); - } else if (role == "duration") { - const QString duration = durationFromValue(value.toInt()); - values.insert(role, duration); - } else if (value.isResource()) { - const Nepomuk2::Resource resource = value.toResource(); - values.insert(role, resource.genericLabel()); - } else if (value.isResourceList()) { - const QList<Nepomuk2::Resource> resList = value.toResourceList(); - QStringList strList; - foreach (const Nepomuk2::Resource& res, resList) { - strList << res.genericLabel(); - } - values.insert(role, strList.join(QLatin1String(", "))); - } else { - values.insert(role, value.toString()); - } - } - - return values; -} - -QByteArray KNepomukRolesProvider::roleForPropertyUri(const QUrl& uri) const -{ - return m_roleForUri.value(uri); -} - -KNepomukRolesProvider::KNepomukRolesProvider() : - m_roles(), - m_roleForUri() -{ - struct UriInfo - { - const char* const uri; - const char* const role; - }; - - // Mapping from the URIs to the KFileItemModel roles. Note that this must not be - // a 1:1 mapping: One role may contain several URI-values (e.g. the URIs for height and - // width of an image are mapped to the role "imageSize") - static const UriInfo uriInfoList[] = { - { "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#numericRating", "rating" }, - { "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#hasTag", "tags" }, - { "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#description", "comment" }, - { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#wordCount", "wordCount" }, - { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#lineCount", "lineCount" }, - { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width", "imageSize" }, - { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height", "imageSize" }, - { "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#orientation", "orientation", }, - { "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#performer", "artist" }, - { "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicAlbum", "album" }, - { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#duration", "duration" }, - { "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#trackNumber", "track" }, - { "http://www.semanticdesktop.org/ontologies/2010/04/30/ndo#copiedFrom", "copiedFrom" } - }; - - for (unsigned int i = 0; i < sizeof(uriInfoList) / sizeof(UriInfo); ++i) { - m_roleForUri.insert(QUrl(uriInfoList[i].uri), uriInfoList[i].role); - m_roles.insert(uriInfoList[i].role); - } -} - -QString KNepomukRolesProvider::tagsFromValues(const QStringList& values) const -{ - QString tags; - - for (int i = 0; i < values.count(); ++i) { - if (i > 0) { - tags.append(QLatin1String(", ")); - } - - const Nepomuk2::Tag tag(values[i]); - tags += tag.genericLabel(); - } - - return tags; -} - -QString KNepomukRolesProvider::orientationFromValue(int value) const -{ - QString string; - switch (value) { - case 1: string = i18nc("@item:intable Image orientation", "Unchanged"); break; - case 2: string = i18nc("@item:intable Image orientation", "Horizontally flipped"); break; - case 3: string = i18nc("@item:intable image orientation", "180° rotated"); break; - case 4: string = i18nc("@item:intable image orientation", "Vertically flipped"); break; - case 5: string = i18nc("@item:intable image orientation", "Transposed"); break; - case 6: string = i18nc("@item:intable image orientation", "90° rotated"); break; - case 7: string = i18nc("@item:intable image orientation", "Transversed"); break; - case 8: string = i18nc("@item:intable image orientation", "270° rotated"); break; - default: - break; - } - return string; -} - -QString KNepomukRolesProvider::durationFromValue(int value) const -{ - QTime duration; - duration = duration.addSecs(value); - return duration.toString("hh:mm:ss"); -} - diff --git a/src/main.cpp b/src/main.cpp index ea889d1e3..a8e785a0d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,7 +36,7 @@ KDE_EXPORT int kdemain(int argc, char **argv) KDE_VERSION_STRING, ki18nc("@title", "File Manager"), KAboutData::License_GPL, - ki18nc("@info:credit", "(C) 2006-2013 Peter Penz and Frank Reininghaus")); + ki18nc("@info:credit", "(C) 2006-2014 Peter Penz and Frank Reininghaus")); about.setHomepage("http://dolphin.kde.org"); about.addAuthor(ki18nc("@info:credit", "Frank Reininghaus"), ki18nc("@info:credit", "Maintainer (since 2012) and developer"), diff --git a/src/panels/information/filemetadataconfigurationdialog.cpp b/src/panels/information/filemetadataconfigurationdialog.cpp index 0d1395b04..4ad9066c4 100644 --- a/src/panels/information/filemetadataconfigurationdialog.cpp +++ b/src/panels/information/filemetadataconfigurationdialog.cpp @@ -19,10 +19,10 @@ #include "filemetadataconfigurationdialog.h" -#ifndef HAVE_NEPOMUK +#ifndef HAVE_BALOO #include <kfilemetadataconfigurationwidget.h> #else -#include <nepomuk2/filemetadataconfigwidget.h> +#include <baloo/filemetadataconfigwidget.h> #endif #include <KLocale> @@ -44,10 +44,10 @@ FileMetaDataConfigurationDialog::FileMetaDataConfigurationDialog(QWidget* parent "be shown:"), this); m_descriptionLabel->setWordWrap(true); -#ifndef HAVE_NEPOMUK +#ifndef HAVE_BALOO m_configWidget = new KFileMetaDataConfigurationWidget(this); #else - m_configWidget = new Nepomuk2::FileMetaDataConfigWidget(this); + m_configWidget = new Baloo::FileMetaDataConfigWidget(this); #endif diff --git a/src/panels/information/filemetadataconfigurationdialog.h b/src/panels/information/filemetadataconfigurationdialog.h index e897d245b..a3ce9548b 100644 --- a/src/panels/information/filemetadataconfigurationdialog.h +++ b/src/panels/information/filemetadataconfigurationdialog.h @@ -22,12 +22,12 @@ #include <KDialog> #include <KFileItem> -#include "config-nepomuk.h" +#include "config-baloo.h" -#ifndef HAVE_NEPOMUK +#ifndef HAVE_BALOO class KFileMetaDataConfigurationWidget; #else -namespace Nepomuk2 { +namespace Baloo { class FileMetaDataConfigWidget; } #endif @@ -71,10 +71,10 @@ protected slots: private: QLabel* m_descriptionLabel; -#ifndef HAVE_NEPOMUK +#ifndef HAVE_BALOO KFileMetaDataConfigurationWidget* m_configWidget; #else - Nepomuk2::FileMetaDataConfigWidget* m_configWidget; + Baloo::FileMetaDataConfigWidget* m_configWidget; #endif }; diff --git a/src/panels/information/informationpanelcontent.cpp b/src/panels/information/informationpanelcontent.cpp index f2f7378d7..4fb0d9442 100644 --- a/src/panels/information/informationpanelcontent.cpp +++ b/src/panels/information/informationpanelcontent.cpp @@ -31,10 +31,10 @@ #include <kseparator.h> #include <KStringHandler> -#ifndef HAVE_NEPOMUK +#ifndef HAVE_BALOO #include <KFileMetaDataWidget> #else -#include <nepomuk2/filemetadatawidget.h> +#include <baloo/filemetadatawidget.h> #endif #include <panels/places/placesitem.h> @@ -112,10 +112,10 @@ InformationPanelContent::InformationPanelContent(QWidget* parent) : const bool previewsShown = InformationPanelSettings::previewsShown(); m_preview->setVisible(previewsShown); -#ifndef HAVE_NEPOMUK +#ifndef HAVE_BALOO m_metaDataWidget = new KFileMetaDataWidget(parent); #else - m_metaDataWidget = new Nepomuk2::FileMetaDataWidget(parent); + m_metaDataWidget = new Baloo::FileMetaDataWidget(parent); #endif m_metaDataWidget->setFont(KGlobalSettings::smallestReadableFont()); m_metaDataWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); @@ -166,7 +166,7 @@ void InformationPanelContent::showItem(const KFileItem& item) } const KUrl itemUrl = item.url(); - const bool isSearchUrl = itemUrl.protocol().contains("search") && item.nepomukUri().isEmpty(); + const bool isSearchUrl = itemUrl.protocol().contains("search") && item.localPath().isEmpty(); if (!applyPlace(itemUrl)) { setNameLabelText(item.text()); if (isSearchUrl) { @@ -271,6 +271,10 @@ bool InformationPanelContent::eventFilter(QObject* obj, QEvent* event) adjustWidgetSizes(parentWidget()->width()); break; + case QEvent::FontChange: + m_metaDataWidget->setFont(KGlobalSettings::smallestReadableFont()); + break; + default: break; } @@ -355,7 +359,7 @@ void InformationPanelContent::slotHasVideoChanged(bool hasVideo) void InformationPanelContent::refreshMetaData() { - if (!m_item.isNull() && m_item.nepomukUri().isValid()) { + if (!m_item.isNull()) { showItem(m_item); } } diff --git a/src/panels/information/informationpanelcontent.h b/src/panels/information/informationpanelcontent.h index cad6b51b0..67fdf6c5a 100644 --- a/src/panels/information/informationpanelcontent.h +++ b/src/panels/information/informationpanelcontent.h @@ -20,7 +20,7 @@ #ifndef INFORMATIONPANELCONTENT_H #define INFORMATIONPANELCONTENT_H -#include "config-nepomuk.h" +#include "config-baloo.h" #include <KConfig> #include <KFileItem> #include <KUrl> @@ -38,13 +38,13 @@ class QLabel; class QScrollArea; namespace KIO { - class PreviewJob; + class PreviewJob; } -#ifndef HAVE_NEPOMUK +#ifndef HAVE_BALOO class KFileMetaDataWidget; #else -namespace Nepomuk2 { +namespace Baloo { class FileMetaDataWidget; } #endif @@ -147,10 +147,10 @@ private: PixmapViewer* m_preview; PhononWidget* m_phononWidget; QLabel* m_nameLabel; -#ifndef HAVE_NEPOMUK +#ifndef HAVE_BALOO KFileMetaDataWidget* m_metaDataWidget; #else - Nepomuk2::FileMetaDataWidget* m_metaDataWidget; + Baloo::FileMetaDataWidget* m_metaDataWidget; #endif QScrollArea* m_metaDataArea; diff --git a/src/panels/places/placesitemmodel.cpp b/src/panels/places/placesitemmodel.cpp index 681479dfb..baa770dfd 100644 --- a/src/panels/places/placesitemmodel.cpp +++ b/src/panels/places/placesitemmodel.cpp @@ -51,22 +51,17 @@ #include <views/dolphinview.h> #include <views/viewproperties.h> -#ifdef HAVE_NEPOMUK - #include <Nepomuk2/ResourceManager> - #include <Nepomuk2/Query/ComparisonTerm> - #include <Nepomuk2/Query/LiteralTerm> - #include <Nepomuk2/Query/FileQuery> - #include <Nepomuk2/Query/ResourceTypeTerm> - #include <Nepomuk2/Vocabulary/NFO> - #include <Nepomuk2/Vocabulary/NIE> +#ifdef HAVE_BALOO + #include <baloo/query.h> + #include <baloo/indexerconfig.h> #endif namespace { // As long as KFilePlacesView from kdelibs is available in parallel, the // system-bookmarks for "Recently Accessed" and "Search For" should be // shown only inside the Places Panel. This is necessary as the stored - // URLs needs to get translated to a Nepomuk-search-URL on-the-fly to - // be independent from changes in the Nepomuk-search-URL-syntax. + // URLs needs to get translated to a Baloo-search-URL on-the-fly to + // be independent from changes in the Baloo-search-URL-syntax. // Hence a prefix to the application-name of the stored bookmarks is // added, which is only read by PlacesItemModel. const char* AppNamePrefix = "-places-panel"; @@ -87,16 +82,9 @@ PlacesItemModel::PlacesItemModel(QObject* parent) : m_updateBookmarksTimer(0), m_storageSetupInProgress() { -#ifdef HAVE_NEPOMUK - Nepomuk2::ResourceManager* rm = Nepomuk2::ResourceManager::instance(); - connect(rm, SIGNAL(nepomukSystemStarted()), this, SLOT(slotNepomukStarted())); - connect(rm, SIGNAL(nepomukSystemStopped()), this, SLOT(slotNepomukStopped())); - - if (rm->initialized()) { - KConfig config("nepomukserverrc"); - m_fileIndexingEnabled = config.group("Service-nepomukfileindexer").readEntry("autostart", true); - } - +#ifdef HAVE_BALOO + Baloo::IndexerConfig config; + m_fileIndexingEnabled = config.fileIndexingEnabled(); #endif const QString file = KStandardDirs::locateLocal("data", "kfileplaces/bookmarks.xml"); m_bookmarkManager = KBookmarkManager::managerForFile(file, "kfilePlaces"); @@ -959,35 +947,6 @@ void PlacesItemModel::clear() { KStandardItemModel::clear(); } -void PlacesItemModel::slotNepomukStarted() -{ - KConfig config("nepomukserverrc"); - m_fileIndexingEnabled = config.group("Service-nepomukfileindexer").readEntry("autostart", true); - if (m_fileIndexingEnabled) { - m_systemBookmarks.clear(); - m_systemBookmarksIndexes.clear(); - createSystemBookmarks(); - - clear(); - loadBookmarks(); - } -} - -void PlacesItemModel::slotNepomukStopped() -{ - if (m_fileIndexingEnabled) { - m_fileIndexingEnabled = false; - - m_systemBookmarks.clear(); - m_systemBookmarksIndexes.clear(); - createSystemBookmarks(); - - clear(); - loadBookmarks(); - } -} - - void PlacesItemModel::initializeAvailableDevices() { QString predicate("[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]" @@ -1145,7 +1104,7 @@ bool PlacesItemModel::equalBookmarkIdentifiers(const KBookmark& b1, const KBookm KUrl PlacesItemModel::createTimelineUrl(const KUrl& url) { - // TODO: Clarify with the Nepomuk-team whether it makes sense + // TODO: Clarify with the Baloo-team whether it makes sense // provide default-timeline-URLs like 'yesterday', 'this month' // and 'last month'. KUrl timelineUrl; @@ -1195,18 +1154,16 @@ KUrl PlacesItemModel::createSearchUrl(const KUrl& url) { KUrl searchUrl; -#ifdef HAVE_NEPOMUK +#ifdef HAVE_BALOO const QString path = url.pathOrUrl(); if (path.endsWith(QLatin1String("documents"))) { - searchUrl = searchUrlForTerm(Nepomuk2::Query::ResourceTypeTerm(Nepomuk2::Vocabulary::NFO::Document())); + searchUrl = searchUrlForType("Document"); } else if (path.endsWith(QLatin1String("images"))) { - searchUrl = searchUrlForTerm(Nepomuk2::Query::ResourceTypeTerm(Nepomuk2::Vocabulary::NFO::Image())); + searchUrl = searchUrlForType("Image"); } else if (path.endsWith(QLatin1String("audio"))) { - searchUrl = searchUrlForTerm(Nepomuk2::Query::ComparisonTerm(Nepomuk2::Vocabulary::NIE::mimeType(), - Nepomuk2::Query::LiteralTerm("audio"))); + searchUrl = searchUrlForType("Audio"); } else if (path.endsWith(QLatin1String("videos"))) { - searchUrl = searchUrlForTerm(Nepomuk2::Query::ComparisonTerm(Nepomuk2::Vocabulary::NIE::mimeType(), - Nepomuk2::Query::LiteralTerm("video"))); + searchUrl = searchUrlForType("Video"); } else { Q_ASSERT(false); } @@ -1217,10 +1174,13 @@ KUrl PlacesItemModel::createSearchUrl(const KUrl& url) return searchUrl; } -#ifdef HAVE_NEPOMUK -KUrl PlacesItemModel::searchUrlForTerm(const Nepomuk2::Query::Term& term) +#ifdef HAVE_BALOO +KUrl PlacesItemModel::searchUrlForType(const QString& type) { - const Nepomuk2::Query::FileQuery query(term); + Baloo::Query query; + query.addType("File"); + query.addType(type); + return query.toSearchUrl(); } #endif diff --git a/src/panels/places/placesitemmodel.h b/src/panels/places/placesitemmodel.h index cd37e7353..4a374e502 100644 --- a/src/panels/places/placesitemmodel.h +++ b/src/panels/places/placesitemmodel.h @@ -20,7 +20,7 @@ #ifndef PLACESITEMMODEL_H #define PLACESITEMMODEL_H -#include <config-nepomuk.h> +#include <config-baloo.h> #include <kitemviews/kstandarditemmodel.h> @@ -37,16 +37,6 @@ class PlacesItem; class QAction; class QTimer; -#ifdef HAVE_NEPOMUK - namespace Nepomuk2 - { - namespace Query - { - class Term; - } - } -#endif - // #define PLACESITEMMODEL_DEBUG /** @@ -127,7 +117,7 @@ public: /** * @return Converts the URL, which contains "virtual" URLs for system-items like - * "search:/documents" into a Nepomuk-Query-URL that will be handled by + * "search:/documents" into a Query-URL that will be handled by * the corresponding IO-slave. Virtual URLs for bookmarks are used to * be independent from internal format changes. */ @@ -163,9 +153,6 @@ private slots: * timeout of m_saveBookmarksTimer to prevent unnecessary savings. */ void saveBookmarks(); - - void slotNepomukStarted(); - void slotNepomukStopped(); private: struct SystemBookmarkData; @@ -252,13 +239,13 @@ private: */ static KUrl createSearchUrl(const KUrl& url); -#ifdef HAVE_NEPOMUK +#ifdef HAVE_BALOO /** - * Helper method for createSearchUrl(). + * Helper method for createSearchUrl() * @return URL that can be listed by KIO and results in searching - * for the given term. + * for the given type */ - static KUrl searchUrlForTerm(const Nepomuk2::Query::Term& term); + static KUrl searchUrlForType(const QString& type); #endif #ifdef PLACESITEMMODEL_DEBUG diff --git a/src/search/dolphinfacetswidget.cpp b/src/search/dolphinfacetswidget.cpp index d786117c9..f20ae68d5 100644 --- a/src/search/dolphinfacetswidget.cpp +++ b/src/search/dolphinfacetswidget.cpp @@ -27,18 +27,6 @@ #include <QHBoxLayout> #include <QVBoxLayout> -#ifdef HAVE_NEPOMUK - #include <Nepomuk2/Query/AndTerm> - #include <Nepomuk2/Query/ComparisonTerm> - #include <Nepomuk2/Query/LiteralTerm> - #include <Nepomuk2/Query/OrTerm> - #include <Nepomuk2/Query/Query> - #include <Nepomuk2/Query/ResourceTypeTerm> - #include <Nepomuk2/Vocabulary/NFO> - #include <Nepomuk2/Vocabulary/NIE> - #include <Soprano/Vocabulary/NAO> -#endif - DolphinFacetsWidget::DolphinFacetsWidget(QWidget* parent) : QWidget(parent), m_documents(0), @@ -58,13 +46,16 @@ DolphinFacetsWidget::DolphinFacetsWidget(QWidget* parent) : m_fourOrMore(0), m_maxRating(0) { - m_documents = createCheckBox(i18nc("@option:check", "Documents")); - m_images = createCheckBox(i18nc("@option:check", "Images")); - m_audio = createCheckBox(i18nc("@option:check", "Audio Files")); - m_videos = createCheckBox(i18nc("@option:check", "Videos")); + QButtonGroup* filetypeGroup = new QButtonGroup(this); + m_anyType = createRadioButton(i18nc("@option:check", "Any"), filetypeGroup); + m_documents = createRadioButton(i18nc("@option:check", "Documents"), filetypeGroup); + m_images = createRadioButton(i18nc("@option:check", "Images"), filetypeGroup); + m_audio = createRadioButton(i18nc("@option:check", "Audio Files"), filetypeGroup); + m_videos = createRadioButton(i18nc("@option:check", "Videos"), filetypeGroup); QVBoxLayout* typeLayout = new QVBoxLayout(); typeLayout->setSpacing(0); + typeLayout->addWidget(m_anyType); typeLayout->addWidget(m_documents); typeLayout->addWidget(m_images); typeLayout->addWidget(m_audio); @@ -112,6 +103,7 @@ DolphinFacetsWidget::DolphinFacetsWidget(QWidget* parent) : topLayout->addLayout(ratingLayout); topLayout->addStretch(); + m_anyType->setChecked(true); m_anytime->setChecked(true); m_anyRating->setChecked(true); } @@ -120,38 +112,11 @@ DolphinFacetsWidget::~DolphinFacetsWidget() { } -#ifdef HAVE_NEPOMUK -Nepomuk2::Query::Term DolphinFacetsWidget::facetsTerm() const +#ifdef HAVE_BALOO +Baloo::Term DolphinFacetsWidget::ratingTerm() const { - Nepomuk2::Query::AndTerm andTerm; - - const bool hasTypeFilter = m_documents->isChecked() || - m_images->isChecked() || - m_audio->isChecked() || - m_videos->isChecked(); - if (hasTypeFilter) { - Nepomuk2::Query::OrTerm orTerm; - - if (m_documents->isChecked()) { - orTerm.addSubTerm(Nepomuk2::Query::ResourceTypeTerm(Nepomuk2::Vocabulary::NFO::Document())); - } - - if (m_images->isChecked()) { - orTerm.addSubTerm(Nepomuk2::Query::ResourceTypeTerm(Nepomuk2::Vocabulary::NFO::Image())); - } - - if (m_audio->isChecked()) { - orTerm.addSubTerm(Nepomuk2::Query::ComparisonTerm(Nepomuk2::Vocabulary::NIE::mimeType(), - Nepomuk2::Query::LiteralTerm("audio"))); - } - - if (m_videos->isChecked()) { - orTerm.addSubTerm(Nepomuk2::Query::ComparisonTerm(Nepomuk2::Vocabulary::NIE::mimeType(), - Nepomuk2::Query::LiteralTerm("video"))); - } - - andTerm.addSubTerm(orTerm); - } + Baloo::Term ratingTerm; + Baloo::Term modifiedTerm; if (!m_anyRating->isChecked()) { int stars = 1; // represents m_oneOrMore @@ -166,10 +131,7 @@ Nepomuk2::Query::Term DolphinFacetsWidget::facetsTerm() const } const int rating = stars * 2; - Nepomuk2::Query::ComparisonTerm term(Soprano::Vocabulary::NAO::numericRating(), - Nepomuk2::Query::LiteralTerm(rating), - Nepomuk2::Query::ComparisonTerm::GreaterOrEqual); - andTerm.addSubTerm(term); + ratingTerm = Baloo::Term("rating", rating, Baloo::Term::GreaterEqual); } if (!m_anytime->isChecked()) { @@ -184,21 +146,149 @@ Nepomuk2::Query::Term DolphinFacetsWidget::facetsTerm() const date = date.addDays(1 - date.dayOfYear()); } - Nepomuk2::Query::ComparisonTerm term(Nepomuk2::Vocabulary::NIE::lastModified(), - Nepomuk2::Query::LiteralTerm(QDateTime(date)), - Nepomuk2::Query::ComparisonTerm::GreaterOrEqual); - andTerm.addSubTerm(term); + modifiedTerm = Baloo::Term("modified", date, Baloo::Term::GreaterEqual); + } + + if (ratingTerm.isValid() && modifiedTerm.isValid()) { + Baloo::Term term(Baloo::Term::And); + term.addSubTerm(ratingTerm); + term.addSubTerm(modifiedTerm); + + return term; + } else if (modifiedTerm.isValid()) { + return modifiedTerm; + } else if (ratingTerm.isValid()) { + return ratingTerm; + } + + return Baloo::Term(); +} + +QString DolphinFacetsWidget::facetType() const +{ + if (m_documents->isChecked()) { + return QLatin1String("Document"); + } else if (m_images->isChecked()) { + return QLatin1String("Image"); + } else if (m_audio->isChecked()) { + return QLatin1String("Audio"); + } else if (m_videos->isChecked()) { + return QLatin1String("Video"); + } + + return QString(); +} + +bool DolphinFacetsWidget::isRatingTerm(const Baloo::Term& term) const +{ + const QList<Baloo::Term> subTerms = term.subTerms(); + if (subTerms.isEmpty()) { + // If term has no sub terms, then the term itself is either a "rating" term + // or a "modified" term. + return term.property() == QLatin1String("modified") || + term.property() == QLatin1String("rating"); + + } else if (subTerms.size() == 2) { + // If term has sub terms, then the sub terms are always "rating" and "modified" terms. + + QStringList properties; + foreach (const Baloo::Term& subTerm, subTerms) { + properties << subTerm.property(); + } + + return properties.contains(QLatin1String("modified")) && + properties.contains(QLatin1String("rating")); + } + + return false; +} + +void DolphinFacetsWidget::setRatingTerm(const Baloo::Term& term) +{ + // If term has sub terms, then the sub terms are always "rating" and "modified" terms. + // If term has no sub terms, then the term itself is either a "rating" term or a "modified" + // term. To avoid code duplication we add term to subTerms list, if the list is empty. + QList<Baloo::Term> subTerms = term.subTerms(); + if (subTerms.isEmpty()) { + subTerms << term; } - return andTerm; + foreach (const Baloo::Term& subTerm, subTerms) { + const QString property = subTerm.property(); + + if (property == QLatin1String("modified")) { + const QDate date = subTerm.value().toDate(); + setTimespan(date); + } else if (property == QLatin1String("rating")) { + const int stars = subTerm.value().toInt() / 2; + setRating(stars); + } + } } + #endif -QCheckBox* DolphinFacetsWidget::createCheckBox(const QString& text) +void DolphinFacetsWidget::setFacetType(const QString& type) { - QCheckBox* checkBox = new QCheckBox(text); - connect(checkBox, SIGNAL(clicked()), this, SIGNAL(facetChanged())); - return checkBox; + if (type == QLatin1String("Document")) { + m_documents->setChecked(true); + } else if (type == QLatin1String("Image")) { + m_images->setChecked(true); + } else if (type == QLatin1String("Audio")) { + m_audio->setChecked(true); + } else if (type == QLatin1String("Video")) { + m_videos->setChecked(true); + } else { + m_anyType->setChecked(true); + } +} + +void DolphinFacetsWidget::setRating(const int stars) +{ + switch (stars) { + case 5: + m_maxRating->setChecked(true); + break; + + case 4: + m_fourOrMore->setChecked(true); + break; + + case 3: + m_threeOrMore->setChecked(true); + break; + + case 2: + m_twoOrMore->setChecked(true); + break; + + case 1: + m_oneOrMore->setChecked(true); + break; + + default: + m_anyRating->setChecked(true); + } +} + +void DolphinFacetsWidget::setTimespan(const QDate& date) +{ + const QDate currentDate = QDate::currentDate(); + const int days = date.daysTo(currentDate); + + if (days <= 0) { + m_today->setChecked(true); + } else if (days <= 1) { + m_yesterday->setChecked(true); + } else if (days <= currentDate.dayOfWeek()) { + m_thisWeek->setChecked(true); + } else if (days <= currentDate.day()) { + m_thisMonth->setChecked(true); + } else if (days <= currentDate.dayOfYear()) { + m_thisYear->setChecked(true); + } else { + m_anytime->setChecked(true); + } } QRadioButton* DolphinFacetsWidget::createRadioButton(const QString& text, diff --git a/src/search/dolphinfacetswidget.h b/src/search/dolphinfacetswidget.h index 57bed9e68..757dcd482 100644 --- a/src/search/dolphinfacetswidget.h +++ b/src/search/dolphinfacetswidget.h @@ -22,13 +22,14 @@ #include <QWidget> -#include <config-nepomuk.h> -#ifdef HAVE_NEPOMUK - #include <Nepomuk2/Query/Term> +#include <config-baloo.h> +#ifdef HAVE_BALOO + #include <baloo/term.h> #endif class QButtonGroup; class QCheckBox; +class QDate; class QRadioButton; /** @@ -55,20 +56,22 @@ public: explicit DolphinFacetsWidget(QWidget* parent = 0); virtual ~DolphinFacetsWidget(); -#ifdef HAVE_NEPOMUK - Nepomuk2::Query::Term facetsTerm() const; +#ifdef HAVE_BALOO + Baloo::Term ratingTerm() const; + QString facetType() const; + + bool isRatingTerm(const Baloo::Term& term) const; + void setRatingTerm(const Baloo::Term& term); #endif + void setFacetType(const QString& type); + signals: void facetChanged(); private: - /** - * @return New checkbox which is connected to the - * slotFacedChanged() slot whenever it has - * been toggled. - */ - QCheckBox* createCheckBox(const QString& text); + void setRating(const int stars); + void setTimespan(const QDate& date); /** * @return New radiobutton which is connected to the @@ -79,10 +82,11 @@ private: QButtonGroup* group); private: - QCheckBox* m_documents; - QCheckBox* m_images; - QCheckBox* m_audio; - QCheckBox* m_videos; + QRadioButton* m_anyType; + QRadioButton* m_documents; + QRadioButton* m_images; + QRadioButton* m_audio; + QRadioButton* m_videos; QRadioButton* m_anytime; QRadioButton* m_today; diff --git a/src/search/dolphinsearchbox.cpp b/src/search/dolphinsearchbox.cpp index cf1f0c8e5..46ca01a4c 100644 --- a/src/search/dolphinsearchbox.cpp +++ b/src/search/dolphinsearchbox.cpp @@ -21,7 +21,6 @@ #include "dolphin_searchsettings.h" #include "dolphinfacetswidget.h" -#include "dolphinsearchinformation.h" #include <KIcon> #include <KLineEdit> @@ -40,24 +39,16 @@ #include <QToolButton> #include <QVBoxLayout> -#include <config-nepomuk.h> -#ifdef HAVE_NEPOMUK - #include <Nepomuk2/Query/AndTerm> - #include <Nepomuk2/Query/FileQuery> - #include <Nepomuk2/Query/LiteralTerm> - #include <Nepomuk2/Query/OrTerm> - #include <Nepomuk2/Query/Query> - #include <Nepomuk2/Query/QueryParser> - #include <Nepomuk2/Query/ResourceTypeTerm> - #include <Nepomuk2/Query/ComparisonTerm> - #include <Nepomuk2/ResourceManager> - #include <Nepomuk2/Vocabulary/NFO> +#include <config-baloo.h> +#ifdef HAVE_BALOO + #include <baloo/query.h> + #include <baloo/term.h> + #include <baloo/indexerconfig.h> #endif DolphinSearchBox::DolphinSearchBox(QWidget* parent) : QWidget(parent), m_startedSearching(false), - m_readOnly(false), m_active(true), m_topLayout(0), m_searchLabel(0), @@ -71,7 +62,6 @@ DolphinSearchBox::DolphinSearchBox(QWidget* parent) : m_facetsToggleButton(0), m_facetsWidget(0), m_searchPath(), - m_readOnlyQuery(), m_startSearchTimer(0) { } @@ -110,13 +100,16 @@ void DolphinSearchBox::setSearchPath(const KUrl& url) const QString elidedLocation = metrics.elidedText(location, Qt::ElideMiddle, maxWidth); m_fromHereButton->setText(i18nc("action:button", "From Here (%1)", elidedLocation)); - const bool showSearchFromButtons = url.isLocalFile() && !m_readOnly; + const bool showSearchFromButtons = url.isLocalFile(); m_separator->setVisible(showSearchFromButtons); m_fromHereButton->setVisible(showSearchFromButtons); m_everywhereButton->setVisible(showSearchFromButtons); - const DolphinSearchInformation& searchInfo = DolphinSearchInformation::instance(); - const bool hasFacetsSupport = searchInfo.isIndexingEnabled() && searchInfo.isPathIndexed(m_searchPath); + bool hasFacetsSupport = false; +#ifdef HAVE_BALOO + const Baloo::IndexerConfig searchInfo; + hasFacetsSupport = searchInfo.fileIndexingEnabled() && searchInfo.shouldBeIndexed(m_searchPath.toLocalFile()); +#endif m_facetsWidget->setEnabled(hasFacetsSupport); } @@ -128,9 +121,13 @@ KUrl DolphinSearchBox::searchPath() const KUrl DolphinSearchBox::urlForSearching() const { KUrl url; - const DolphinSearchInformation& searchInfo = DolphinSearchInformation::instance(); - if (searchInfo.isIndexingEnabled() && searchInfo.isPathIndexed(m_searchPath)) { - url = nepomukUrlForSearching(); + bool useBalooSearch = false; +#ifdef HAVE_BALOO + const Baloo::IndexerConfig searchInfo; + useBalooSearch = searchInfo.fileIndexingEnabled() && searchInfo.shouldBeIndexed(m_searchPath.toLocalFile()); +#endif + if (useBalooSearch) { + url = balooUrlForSearching(); } else { url.setProtocol("filenamesearch"); url.addQueryItem("search", m_searchInput->text()); @@ -153,23 +150,24 @@ KUrl DolphinSearchBox::urlForSearching() const return url; } -void DolphinSearchBox::selectAll() -{ - m_searchInput->selectAll(); -} - -void DolphinSearchBox::setReadOnly(bool readOnly, const KUrl& query) +void DolphinSearchBox::fromSearchUrl(const KUrl& url) { - if (m_readOnly != readOnly || m_readOnlyQuery != query) { - m_readOnly = readOnly; - m_readOnlyQuery = query; - applyReadOnlyState(); + if (url.protocol() == "baloosearch") { + fromBalooSearchUrl(url); + } else if (url.protocol() == "filenamesearch") { + const QMap<QString, QString>& queryItems = url.queryItems(); + setText(queryItems.value("search")); + setSearchPath(queryItems.value("url")); + m_contentButton->setChecked(queryItems.value("checkContent") == "yes"); + } else { + setText(QString()); + setSearchPath(url); } } -bool DolphinSearchBox::isReadOnly() const +void DolphinSearchBox::selectAll() { - return m_readOnly; + m_searchInput->selectAll(); } void DolphinSearchBox::setActive(bool active) @@ -427,80 +425,83 @@ void DolphinSearchBox::init() connect(m_startSearchTimer, SIGNAL(timeout()), this, SLOT(emitSearchRequest())); updateFacetsToggleButton(); - applyReadOnlyState(); } -KUrl DolphinSearchBox::nepomukUrlForSearching() const +KUrl DolphinSearchBox::balooUrlForSearching() const { -#ifdef HAVE_NEPOMUK - // Create the term for the text from the input-field - // dependent on whether a searching for content or - // filename is done +#ifdef HAVE_BALOO const QString text = m_searchInput->text(); - Nepomuk2::Query::Term searchLabelTerm; - if (m_contentButton->isChecked()) { - // Let Nepomuk parse the query - searchLabelTerm = Nepomuk2::Query::QueryParser::parseQuery(text, Nepomuk2::Query::QueryParser::DetectFilenamePattern).term(); - } else { - // Search the text in the filename only - QString regex = QRegExp::escape(text); - regex.replace("\\*", QLatin1String(".*")); - regex.replace("\\?", QLatin1String(".")); - regex.replace("\\", "\\\\"); - searchLabelTerm = Nepomuk2::Query::ComparisonTerm( - Nepomuk2::Vocabulary::NFO::fileName(), - Nepomuk2::Query::LiteralTerm(regex), - Nepomuk2::Query::ComparisonTerm::Regexp); - } - // Get the term from the facets and merge it with the - // created term from the input-field. - Nepomuk2::Query::Term facetsTerm = m_facetsWidget->facetsTerm(); + Baloo::Query query; + query.addType("File"); + query.addType(m_facetsWidget->facetType()); - Nepomuk2::Query::FileQuery fileQuery; - fileQuery.setFileMode(Nepomuk2::Query::FileQuery::QueryFilesAndFolders); - if (facetsTerm.isValid()) { - Nepomuk2::Query::AndTerm andTerm; - andTerm.addSubTerm(searchLabelTerm); - andTerm.addSubTerm(facetsTerm); - fileQuery.setTerm(andTerm); - } else { - fileQuery.setTerm(searchLabelTerm); + Baloo::Term term(Baloo::Term::And); + + Baloo::Term ratingTerm = m_facetsWidget->ratingTerm(); + if (ratingTerm.isValid()) { + term.addSubTerm(ratingTerm); + } + + if (m_contentButton->isChecked()) { + query.setSearchString(text); + } else if (!text.isEmpty()) { + term.addSubTerm(Baloo::Term(QLatin1String("filename"), text)); } if (m_fromHereButton->isChecked()) { - const bool recursive = true; - fileQuery.addIncludeFolder(m_searchPath, recursive); + query.addCustomOption("includeFolder", m_searchPath.toLocalFile()); } - return fileQuery.toSearchUrl(i18nc("@title UDS_DISPLAY_NAME for a KIO directory listing. %1 is the query the user entered.", - "Query Results from '%1'", - text)); + query.setTerm(term); + + return query.toSearchUrl(i18nc("@title UDS_DISPLAY_NAME for a KIO directory listing. %1 is the query the user entered.", + "Query Results from '%1'", text)); #else return KUrl(); #endif } -void DolphinSearchBox::applyReadOnlyState() +void DolphinSearchBox::fromBalooSearchUrl(const KUrl& url) { -#ifdef HAVE_NEPOMUK - if (m_readOnly) { - m_searchLabel->setText(Nepomuk2::Query::Query::titleFromQueryUrl(m_readOnlyQuery)); +#ifdef HAVE_BALOO + const Baloo::Query query = Baloo::Query::fromSearchUrl(url); + const Baloo::Term term = query.term(); + + // Block all signals to avoid unnecessary "searchRequest" signals + // while we adjust the search text and the facet widget. + blockSignals(true); + + const QVariantHash customOptions = query.customOptions(); + if (customOptions.contains("includeFolder")) { + setSearchPath(customOptions.value("includeFolder").toString()); } else { -#else - { -#endif - m_searchLabel->setText(i18nc("@label:textbox", "Find:")); + setSearchPath(QDir::homePath()); + } + + if (!query.searchString().isEmpty()) { + setText(query.searchString()); + } + + QStringList types = query.types(); + types.removeOne("File"); // We are only interested in facet widget types + if (!types.isEmpty()) { + m_facetsWidget->setFacetType(types.first()); } - m_searchInput->setVisible(!m_readOnly); - m_optionsScrollArea->setVisible(!m_readOnly); + foreach (const Baloo::Term& subTerm, term.subTerms()) { + const QString property = subTerm.property(); - if (m_readOnly) { - m_facetsWidget->hide(); - } else { - m_facetsWidget->setVisible(SearchSettings::showFacetsWidget()); + if (property == QLatin1String("filename")) { + setText(subTerm.value().toString()); + } else if (m_facetsWidget->isRatingTerm(subTerm)) { + m_facetsWidget->setRatingTerm(subTerm); + } } + + m_startSearchTimer->stop(); + blockSignals(false); +#endif } void DolphinSearchBox::updateFacetsToggleButton() diff --git a/src/search/dolphinsearchbox.h b/src/search/dolphinsearchbox.h index e4c14b7cb..53b12ffab 100644 --- a/src/search/dolphinsearchbox.h +++ b/src/search/dolphinsearchbox.h @@ -33,13 +33,13 @@ class QLabel; class QVBoxLayout; /** - * @brief Input box for searching files with or without Nepomuk. + * @brief Input box for searching files with or without Baloo. * * The widget allows to specify: * - Where to search: Everywhere or below the current directory * - What to search: Filenames or content * - * If Nepomuk is available and the current folder is indexed, further + * If Baloo is available and the current folder is indexed, further * options are offered. */ class DolphinSearchBox : public QWidget { @@ -72,20 +72,15 @@ public: KUrl urlForSearching() const; /** - * Selects the whole text of the search box. + * Extracts information from the given search \a url to + * initialize the search box properly. */ - void selectAll(); + void fromSearchUrl(const KUrl& url); /** - * @param readOnly If set to true the searchbox cannot be modified - * by the user and acts as visual indicator for - * an externally triggered search query. - * @param query If readOnly is true this URL will be used - * to show a human readable information about the - * query. + * Selects the whole text of the search box. */ - void setReadOnly(bool readOnly, const KUrl& query = KUrl()); - bool isReadOnly() const; + void selectAll(); /** * Set the search box to the active mode, if \a active @@ -151,16 +146,19 @@ private: void init(); /** - * @return URL that represents the Nepomuk query for starting the search. + * @return URL that represents the Baloo query for starting the search. */ - KUrl nepomukUrlForSearching() const; + KUrl balooUrlForSearching() const; - void applyReadOnlyState(); + /** + * Extracts information from the given Baloo search \a url to + * initialize the search box properly. + */ + void fromBalooSearchUrl(const KUrl& url); void updateFacetsToggleButton(); private: bool m_startedSearching; - bool m_readOnly; bool m_active; QVBoxLayout* m_topLayout; @@ -177,7 +175,6 @@ private: DolphinFacetsWidget* m_facetsWidget; KUrl m_searchPath; - KUrl m_readOnlyQuery; QTimer* m_startSearchTimer; }; diff --git a/src/search/dolphinsearchinformation.cpp b/src/search/dolphinsearchinformation.cpp deleted file mode 100644 index b723f1ec0..000000000 --- a/src/search/dolphinsearchinformation.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Peter Penz <[email protected]> * - * * - * 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 "dolphinsearchinformation.h" - -#include <config-nepomuk.h> -#ifdef HAVE_NEPOMUK - #include <KConfig> - #include <KConfigGroup> - #include <Nepomuk2/ResourceManager> -#endif - -#include <KGlobal> -#include <KUrl> -#include <QFileInfo> -#include <QDir> - -struct DolphinSearchInformationSingleton -{ - DolphinSearchInformation instance; -}; -K_GLOBAL_STATIC(DolphinSearchInformationSingleton, s_dolphinSearchInformation) - - -DolphinSearchInformation& DolphinSearchInformation::instance() -{ - return s_dolphinSearchInformation->instance; -} - -DolphinSearchInformation::~DolphinSearchInformation() -{ -} - -bool DolphinSearchInformation::isIndexingEnabled() const -{ - return m_indexingEnabled; -} - -namespace { - /// recursively check if a folder is hidden - bool isDirHidden( QDir& dir ) { - if (QFileInfo(dir.path()).isHidden()) { - return true; - } else if (dir.cdUp()) { - return isDirHidden(dir); - } else { - return false; - } - } - - bool isDirHidden(const QString& path) { - QDir dir(path); - return isDirHidden(dir); - } -} - -bool DolphinSearchInformation::isPathIndexed(const KUrl& url) const -{ -#ifdef HAVE_NEPOMUK - const KConfig strigiConfig("nepomukstrigirc"); - const QStringList indexedFolders = strigiConfig.group("General").readPathEntry("folders", QStringList()); - - // Nepomuk does not index hidden folders - if (isDirHidden(url.toLocalFile())) { - return false; - } - - // Check whether the path is part of an indexed folder - bool isIndexed = false; - foreach (const QString& indexedFolder, indexedFolders) { - const KUrl indexedPath(indexedFolder); - if (indexedPath.isParentOf(url)) { - isIndexed = true; - break; - } - } - - if (isIndexed) { - // The path is part of an indexed folder. Check whether no - // excluded folder is part of the path. - const QStringList excludedFolders = strigiConfig.group("General").readPathEntry("exclude folders", QStringList()); - foreach (const QString& excludedFolder, excludedFolders) { - const KUrl excludedPath(excludedFolder); - if (excludedPath.isParentOf(url)) { - isIndexed = false; - break; - } - } - } - - return isIndexed; -#else - Q_UNUSED(url); - return false; -#endif -} - -DolphinSearchInformation::DolphinSearchInformation() : - m_indexingEnabled(false) -{ -#ifdef HAVE_NEPOMUK - if (Nepomuk2::ResourceManager::instance()->initialized()) { - KConfig config("nepomukserverrc"); - m_indexingEnabled = config.group("Service-nepomukfileindexer").readEntry("autostart", true); - } -#endif -} - diff --git a/src/search/dolphinsearchinformation.h b/src/search/dolphinsearchinformation.h deleted file mode 100644 index 6fb1947ca..000000000 --- a/src/search/dolphinsearchinformation.h +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Peter Penz <[email protected]> * - * * - * 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 * - ***************************************************************************/ - -#ifndef DOLPHINSEARCHINFORMATION_H -#define DOLPHINSEARCHINFORMATION_H - -class KUrl; - -/** - * @brief Allows to access search-engine related information. - */ -class DolphinSearchInformation -{ -public: - static DolphinSearchInformation& instance(); - virtual ~DolphinSearchInformation(); - - /** - * @return True if the Nepomuk indexer is enabled. If Nepomuk is - * disabled, always false is returned. - */ - bool isIndexingEnabled() const; - - /** - * @return True if the complete directory tree specified by path - * is indexed by the Nepomuk indexer. If Nepomuk is disabled, - * always false is returned. - */ - bool isPathIndexed(const KUrl& url) const; - -protected: - DolphinSearchInformation(); - -private: - bool m_indexingEnabled; - - friend class DolphinSearchInformationSingleton; -}; - -#endif - diff --git a/src/settings/additionalinfodialog.cpp b/src/settings/additionalinfodialog.cpp index 0efa8a5fe..e9d5f606d 100644 --- a/src/settings/additionalinfodialog.cpp +++ b/src/settings/additionalinfodialog.cpp @@ -19,7 +19,7 @@ #include "additionalinfodialog.h" -#include <config-nepomuk.h> +#include <config-baloo.h> #include <KLocale> #include "kitemviews/kfileitemmodel.h" @@ -27,8 +27,8 @@ #include <QLabel> #include <QVBoxLayout> -#ifdef HAVE_NEPOMUK - #include <Nepomuk2/ResourceManager> +#ifdef HAVE_BALOO + #include <baloo/indexerconfig.h> #endif AdditionalInfoDialog::AdditionalInfoDialog(QWidget* parent, @@ -50,14 +50,10 @@ AdditionalInfoDialog::AdditionalInfoDialog(QWidget* parent, header->setWordWrap(true); // Add checkboxes - bool nepomukRunning = false; bool indexingEnabled = false; -#ifdef HAVE_NEPOMUK - nepomukRunning = (Nepomuk2::ResourceManager::instance()->initialized()); - if (nepomukRunning) { - KConfig config("nepomukserverrc"); - indexingEnabled = config.group("Service-nepomukfileindexer").readEntry("autostart", true); - } +#ifdef HAVE_BALOO + Baloo::IndexerConfig config; + indexingEnabled = config.fileIndexingEnabled(); #endif m_listWidget = new QListWidget(mainWidget); @@ -67,8 +63,8 @@ AdditionalInfoDialog::AdditionalInfoDialog(QWidget* parent, QListWidgetItem* item = new QListWidgetItem(info.translation, m_listWidget); item->setCheckState(visibleRoles.contains(info.role) ? Qt::Checked : Qt::Unchecked); - const bool enable = (!info.requiresNepomuk && !info.requiresIndexer) || - (info.requiresNepomuk && nepomukRunning) || + const bool enable = (!info.requiresBaloo && !info.requiresIndexer) || + (info.requiresBaloo) || (info.requiresIndexer && indexingEnabled); if (!enable) { diff --git a/src/settings/kcm/kcmdolphingeneral.desktop b/src/settings/kcm/kcmdolphingeneral.desktop index 5a79ad619..b0620ac74 100644 --- a/src/settings/kcm/kcmdolphingeneral.desktop +++ b/src/settings/kcm/kcmdolphingeneral.desktop @@ -314,6 +314,7 @@ X-KDE-Keywords[gl]=xestor de ficheiros X-KDE-Keywords[he]=מנהל קבצים X-KDE-Keywords[hu]=fájlkezelő X-KDE-Keywords[ia]=gerente de file +X-KDE-Keywords[is]=skráastjóri X-KDE-Keywords[it]=gestore dei file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធីគ្រប់គ្រងឯកសារ diff --git a/src/settings/kcm/kcmdolphinnavigation.desktop b/src/settings/kcm/kcmdolphinnavigation.desktop index 4cf793a35..8636058cd 100644 --- a/src/settings/kcm/kcmdolphinnavigation.desktop +++ b/src/settings/kcm/kcmdolphinnavigation.desktop @@ -314,6 +314,7 @@ X-KDE-Keywords[gl]=xestor de ficheiros X-KDE-Keywords[he]=מנהל קבצים X-KDE-Keywords[hu]=fájlkezelő X-KDE-Keywords[ia]=gerente de file +X-KDE-Keywords[is]=skráastjóri X-KDE-Keywords[it]=gestore dei file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធីគ្រប់គ្រងឯកសារ diff --git a/src/settings/kcm/kcmdolphinservices.desktop b/src/settings/kcm/kcmdolphinservices.desktop index aa93e6d28..34867305a 100644 --- a/src/settings/kcm/kcmdolphinservices.desktop +++ b/src/settings/kcm/kcmdolphinservices.desktop @@ -263,6 +263,7 @@ X-KDE-Keywords[gl]=xestor de ficheiros X-KDE-Keywords[he]=מנהל קבצים X-KDE-Keywords[hu]=fájlkezelő X-KDE-Keywords[ia]=gerente de file +X-KDE-Keywords[is]=skráastjóri X-KDE-Keywords[it]=gestore dei file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធីគ្រប់គ្រងឯកសារ diff --git a/src/settings/kcm/kcmdolphinviewmodes.desktop b/src/settings/kcm/kcmdolphinviewmodes.desktop index ce8401228..a4b4e058b 100644 --- a/src/settings/kcm/kcmdolphinviewmodes.desktop +++ b/src/settings/kcm/kcmdolphinviewmodes.desktop @@ -312,6 +312,7 @@ X-KDE-Keywords[gl]=xestor de ficheiros X-KDE-Keywords[he]=מנהל קבצים X-KDE-Keywords[hu]=fájlkezelő X-KDE-Keywords[ia]=gerente de file +X-KDE-Keywords[is]=skráastjóri X-KDE-Keywords[it]=gestore dei file X-KDE-Keywords[kk]=file manager X-KDE-Keywords[km]=កម្មវិធីគ្រប់គ្រងឯកសារ diff --git a/src/settings/viewpropertiesdialog.cpp b/src/settings/viewpropertiesdialog.cpp index c5002ff9f..574f8e18e 100644 --- a/src/settings/viewpropertiesdialog.cpp +++ b/src/settings/viewpropertiesdialog.cpp @@ -27,10 +27,7 @@ #include "dolphin_iconsmodesettings.h" #include "viewpropsprogressinfo.h" -#include <config-nepomuk.h> -#ifdef HAVE_NEPOMUK -#include <Nepomuk2/ResourceManager> -#endif +#include <config-baloo.h> #include <KComponentData> #include <KLocale> diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index fca0819f8..4ba68dd73 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -89,19 +89,18 @@ kde4_add_unit_test(kitemlistkeyboardsearchmanagertest TEST ${kitemlistkeyboardse target_link_libraries(kitemlistkeyboardsearchmanagertest ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY}) # DolphinSearchBox -if (Nepomuk_FOUND) +if (Baloo_FOUND) set(dolphinsearchboxtest_SRCS dolphinsearchboxtest.cpp ../search/dolphinfacetswidget.cpp ../search/dolphinsearchbox.cpp - ../search/dolphinsearchinformation.cpp ) kde4_add_kcfg_files(dolphinsearchboxtest_SRCS ../search/dolphin_searchsettings.kcfgc ) kde4_add_unit_test(dolphinsearchboxtest TEST ${dolphinsearchboxtest_SRCS}) - target_link_libraries(dolphinsearchboxtest ${KDE4_KIO_LIBS} ${SOPRANO_LIBRARIES} ${NEPOMUK_CORE_LIBRARY} nepomukutils ${QT_QTTEST_LIBRARY}) -endif (Nepomuk_FOUND) + target_link_libraries(dolphinsearchboxtest ${KDE4_KIO_LIBS} ${BALOO_LIBRARIES} ${QT_QTTEST_LIBRARY}) +endif (Baloo_FOUND) # KStandardItemModelTest set(kstandarditemmodeltest_SRCS diff --git a/src/views/dolphinitemlistview.cpp b/src/views/dolphinitemlistview.cpp index 4799d7679..db4dadf2f 100644 --- a/src/views/dolphinitemlistview.cpp +++ b/src/views/dolphinitemlistview.cpp @@ -144,6 +144,26 @@ void DolphinItemListView::onVisibleRolesChanged(const QList<QByteArray>& current updateGridSize(); } +void DolphinItemListView::updateFont() +{ + const ViewModeSettings settings(viewMode()); + + if (settings.useSystemFont()) { + KItemListView::updateFont(); + } else { + QFont font(settings.fontFamily(), qRound(settings.fontSize())); + font.setItalic(settings.italicFont()); + font.setWeight(settings.fontWeight()); + font.setPointSizeF(settings.fontSize()); + + KItemListStyleOption option = styleOption(); + option.font = font; + option.fontMetrics = QFontMetrics(font); + + setStyleOption(option); + } +} + void DolphinItemListView::updateGridSize() { const ViewModeSettings settings(viewMode()); @@ -160,7 +180,8 @@ void DolphinItemListView::updateGridSize() // Calculate the item-width and item-height int itemWidth; int itemHeight; - QSize maxTextSize; + int maxTextLines = 0; + int maxTextWidth = 0; switch (itemLayout()) { case KFileItemListView::IconsLayout: { @@ -180,16 +201,10 @@ void DolphinItemListView::updateGridSize() } itemHeight = padding * 3 + iconSize + option.fontMetrics.lineSpacing(); - if (IconsModeSettings::maximumTextLines() > 0) { - // A restriction is given for the maximum number of textlines (0 means - // having no restriction) - const int additionalInfoCount = visibleRoles().count() - 1; - const int maxAdditionalLines = additionalInfoCount + IconsModeSettings::maximumTextLines(); - maxTextSize.rheight() = option.fontMetrics.lineSpacing() * maxAdditionalLines; - } horizontalMargin = 4; verticalMargin = 8; + maxTextLines = IconsModeSettings::maximumTextLines(); break; } case KFileItemListView::CompactLayout: { @@ -200,8 +215,7 @@ void DolphinItemListView::updateGridSize() if (CompactModeSettings::maximumTextWidthIndex() > 0) { // A restriction is given for the maximum width of the text (0 means // having no restriction) - maxTextSize.rwidth() = option.fontMetrics.height() * 10 * - CompactModeSettings::maximumTextWidthIndex(); + maxTextWidth = option.fontMetrics.height() * 10 * CompactModeSettings::maximumTextWidthIndex(); } horizontalMargin = 8; @@ -224,30 +238,14 @@ void DolphinItemListView::updateGridSize() option.horizontalMargin = horizontalMargin; option.verticalMargin = verticalMargin; option.iconSize = iconSize; - option.maxTextSize = maxTextSize; + option.maxTextLines = maxTextLines; + option.maxTextWidth = maxTextWidth; beginTransaction(); setStyleOption(option); setItemSize(QSizeF(itemWidth, itemHeight)); endTransaction(); } -void DolphinItemListView::updateFont() -{ - KItemListStyleOption option = styleOption(); - - const ViewModeSettings settings(viewMode()); - - QFont font(settings.fontFamily(), qRound(settings.fontSize())); - font.setItalic(settings.italicFont()); - font.setWeight(settings.fontWeight()); - font.setPointSizeF(settings.fontSize()); - - option.font = font; - option.fontMetrics = QFontMetrics(font); - - setStyleOption(option); -} - ViewModeSettings::ViewMode DolphinItemListView::viewMode() const { ViewModeSettings::ViewMode mode; diff --git a/src/views/dolphinitemlistview.h b/src/views/dolphinitemlistview.h index 18bb284ac..67302e44d 100644 --- a/src/views/dolphinitemlistview.h +++ b/src/views/dolphinitemlistview.h @@ -56,9 +56,10 @@ protected: virtual void onVisibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous); + virtual void updateFont(); + private: void updateGridSize(); - void updateFont(); ViewModeSettings::ViewMode viewMode() const; diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 71364e045..2769d670d 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -20,7 +20,7 @@ #include "dolphinview.h" -#include <config-nepomuk.h> +#include <config-baloo.h> #include <QAbstractItemView> #include <QApplication> @@ -74,8 +74,8 @@ #include "views/tooltips/tooltipmanager.h" #include "zoomlevelinfo.h" -#ifdef HAVE_NEPOMUK - #include <Nepomuk2/ResourceManager> +#ifdef HAVE_BALOO + #include <baloo/indexerconfig.h> #endif namespace { @@ -870,14 +870,10 @@ void DolphinView::slotHeaderContextMenuRequested(const QPointF& pos) KItemListView* view = m_container->controller()->view(); const QSet<QByteArray> visibleRolesSet = view->visibleRoles().toSet(); - bool nepomukRunning = false; bool indexingEnabled = false; -#ifdef HAVE_NEPOMUK - nepomukRunning = (Nepomuk2::ResourceManager::instance()->initialized()); - if (nepomukRunning) { - KConfig config("nepomukserverrc"); - indexingEnabled = config.group("Service-nepomukfileindexer").readEntry("autostart", true); - } +#ifdef HAVE_BALOO + Baloo::IndexerConfig config; + indexingEnabled = config.fileIndexingEnabled(); #endif QString groupName; @@ -908,8 +904,8 @@ void DolphinView::slotHeaderContextMenuRequested(const QPointF& pos) action->setChecked(visibleRolesSet.contains(info.role)); action->setData(info.role); - const bool enable = (!info.requiresNepomuk && !info.requiresIndexer) || - (info.requiresNepomuk && nepomukRunning) || + const bool enable = (!info.requiresBaloo && !info.requiresIndexer) || + (info.requiresBaloo) || (info.requiresIndexer && indexingEnabled); action->setEnabled(enable); } @@ -1050,6 +1046,7 @@ void DolphinView::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* even if (op && destUrl == url()) { // Mark the dropped urls as selected. m_clearSelectionBeforeSelectingNewItems = true; + m_markFirstNewlySelectedItemAsCurrent = true; connect(op, SIGNAL(aboutToCreate(KUrl::List)), this, SLOT(slotAboutToCreate(KUrl::List))); } @@ -1074,17 +1071,15 @@ void DolphinView::slotModelChanged(KItemModelBase* current, KItemModelBase* prev void DolphinView::slotMouseButtonPressed(int itemIndex, Qt::MouseButtons buttons) { + Q_UNUSED(itemIndex); + hideToolTip(); - if (itemIndex < 0) { - // Trigger the history navigation only when clicking on the viewport: - // Above an item the XButtons provide a simple way to select items in - // the singleClick mode. - if (buttons & Qt::XButton1) { - emit goBackRequested(); - } else if (buttons & Qt::XButton2) { - emit goForwardRequested(); - } + // TODO: Qt5: Replace Qt::XButton1 by Qt::BackButton and Qt::XButton2 by Qt::ForwardButton + if (buttons & Qt::XButton1) { + emit goBackRequested(); + } else if (buttons & Qt::XButton2) { + emit goForwardRequested(); } } diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index b43957f22..3731464a3 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -21,7 +21,7 @@ #ifndef DOLPHINVIEW_H #define DOLPHINVIEW_H -#include <config-nepomuk.h> +#include <config-baloo.h> #include "libdolphin_export.h" diff --git a/src/views/dolphinviewactionhandler.cpp b/src/views/dolphinviewactionhandler.cpp index 051174f6d..48ec95c70 100644 --- a/src/views/dolphinviewactionhandler.cpp +++ b/src/views/dolphinviewactionhandler.cpp @@ -20,7 +20,7 @@ #include "dolphinviewactionhandler.h" -#include <config-nepomuk.h> +#include <config-baloo.h> #include "settings/viewpropertiesdialog.h" #include "views/dolphinview.h" @@ -39,12 +39,12 @@ #include <KPropertiesDialog> #include <KIcon> -#ifdef HAVE_NEPOMUK - #include <Nepomuk2/ResourceManager> -#endif - #include <KDebug> +#ifdef HAVE_BALOO + #include <baloo/indexerconfig.h> +#endif + DolphinViewActionHandler::DolphinViewActionHandler(KActionCollection* collection, QObject* parent) : QObject(parent), m_actionCollection(collection), @@ -237,14 +237,10 @@ QActionGroup* DolphinViewActionHandler::createFileItemRolesActionGroup(const QSt KActionMenu* groupMenu = 0; QActionGroup* groupMenuGroup = 0; - bool nepomukRunning = false; bool indexingEnabled = false; -#ifdef HAVE_NEPOMUK - nepomukRunning = (Nepomuk2::ResourceManager::instance()->initialized()); - if (nepomukRunning) { - KConfig config("nepomukserverrc"); - indexingEnabled = config.group("Service-nepomukfileindexer").readEntry("autostart", true); - } +#ifdef HAVE_BALOO + Baloo::IndexerConfig config; + indexingEnabled = config.fileIndexingEnabled(); #endif const QList<KFileItemModel::RoleInfo> rolesInfo = KFileItemModel::rolesInformation(); @@ -284,8 +280,8 @@ QActionGroup* DolphinViewActionHandler::createFileItemRolesActionGroup(const QSt action->setText(info.translation); action->setData(info.role); - const bool enable = (!info.requiresNepomuk && !info.requiresIndexer) || - (info.requiresNepomuk && nepomukRunning) || + const bool enable = (!info.requiresBaloo && !info.requiresIndexer) || + (info.requiresBaloo) || (info.requiresIndexer && indexingEnabled); action->setEnabled(enable); diff --git a/src/views/tooltips/filemetadatatooltip.cpp b/src/views/tooltips/filemetadatatooltip.cpp index 67911eea2..b72699664 100644 --- a/src/views/tooltips/filemetadatatooltip.cpp +++ b/src/views/tooltips/filemetadatatooltip.cpp @@ -34,10 +34,10 @@ #include <QTextLayout> #include <QTextLine> -#ifndef HAVE_NEPOMUK +#ifndef HAVE_BALOO #include <KFileMetaDataWidget> #else -#include <nepomuk2/filemetadatawidget.h> +#include <baloo/filemetadatawidget.h> #endif // For the blurred tooltip background @@ -70,10 +70,10 @@ FileMetaDataToolTip::FileMetaDataToolTip(QWidget* parent) : m_name->setMaximumWidth(fontMetrics.averageCharWidth() * 40); // Create widget for the meta data -#ifndef HAVE_NEPOMUK +#ifndef HAVE_BALOO m_fileMetaDataWidget = new KFileMetaDataWidget(this); #else - m_fileMetaDataWidget = new Nepomuk2::FileMetaDataWidget(this); + m_fileMetaDataWidget = new Baloo::FileMetaDataWidget(this); #endif m_fileMetaDataWidget->setForegroundRole(QPalette::ToolTipText); m_fileMetaDataWidget->setReadOnly(true); diff --git a/src/views/tooltips/filemetadatatooltip.h b/src/views/tooltips/filemetadatatooltip.h index e7cb3f039..7197871fc 100644 --- a/src/views/tooltips/filemetadatatooltip.h +++ b/src/views/tooltips/filemetadatatooltip.h @@ -23,15 +23,15 @@ #define FILEMETADATATOOLTIP_H #include <QWidget> -#include "config-nepomuk.h" +#include "config-baloo.h" class KFileItemList; class QLabel; -#ifndef HAVE_NEPOMUK +#ifndef HAVE_BALOO class KFileMetaDataWidget; #else -namespace Nepomuk2 { +namespace Baloo { class FileMetaDataWidget; } #endif @@ -76,10 +76,10 @@ protected: private: QLabel* m_preview; QLabel* m_name; -#ifndef HAVE_NEPOMUK +#ifndef HAVE_BALOO KFileMetaDataWidget* m_fileMetaDataWidget; #else - Nepomuk2::FileMetaDataWidget* m_fileMetaDataWidget; + Baloo::FileMetaDataWidget* m_fileMetaDataWidget; #endif }; diff --git a/src/views/versioncontrol/updateitemstatesthread.cpp b/src/views/versioncontrol/updateitemstatesthread.cpp index 6be07d361..6457f607d 100644 --- a/src/views/versioncontrol/updateitemstatesthread.cpp +++ b/src/views/versioncontrol/updateitemstatesthread.cpp @@ -28,7 +28,6 @@ UpdateItemStatesThread::UpdateItemStatesThread(KVersionControlPlugin* plugin, QThread(), m_globalPluginMutex(0), m_plugin(plugin), - m_retrievedItems(false), m_itemStates(itemStates) { // Several threads may share one instance of a plugin. A global @@ -47,12 +46,11 @@ void UpdateItemStatesThread::run() Q_ASSERT(!m_itemStates.isEmpty()); Q_ASSERT(m_plugin); - m_retrievedItems = false; - QMutexLocker pluginLocker(m_globalPluginMutex); - foreach (const QString& directory, m_itemStates.keys()) { - if (m_plugin->beginRetrieval(directory)) { - QVector<VersionControlObserver::ItemState>& items = m_itemStates[directory]; + QMap<QString, QVector<VersionControlObserver::ItemState> >::iterator it = m_itemStates.begin(); + for (; it != m_itemStates.end(); ++it) { + if (m_plugin->beginRetrieval(it.key())) { + QVector<VersionControlObserver::ItemState>& items = it.value(); const int count = items.count(); KVersionControlPlugin2* pluginV2 = qobject_cast<KVersionControlPlugin2*>(m_plugin); @@ -68,29 +66,13 @@ void UpdateItemStatesThread::run() } m_plugin->endRetrieval(); - m_retrievedItems = true; } } } -bool UpdateItemStatesThread::lockPlugin() -{ - return m_globalPluginMutex->tryLock(300); -} - -void UpdateItemStatesThread::unlockPlugin() -{ - m_globalPluginMutex->unlock(); -} - QMap<QString, QVector<VersionControlObserver::ItemState> > UpdateItemStatesThread::itemStates() const { return m_itemStates; } -bool UpdateItemStatesThread::retrievedItems() const -{ - return m_retrievedItems; -} - #include "updateitemstatesthread.moc" diff --git a/src/views/versioncontrol/updateitemstatesthread.h b/src/views/versioncontrol/updateitemstatesthread.h index 2914bc2b7..5c6c6a208 100644 --- a/src/views/versioncontrol/updateitemstatesthread.h +++ b/src/views/versioncontrol/updateitemstatesthread.h @@ -50,23 +50,8 @@ public: const QMap<QString, QVector<VersionControlObserver::ItemState> >& itemStates); virtual ~UpdateItemStatesThread(); - /** - * Whenever the plugin is accessed by the thread creator, lockPlugin() must - * be invoked. True is returned, if the plugin could be locked within 300 - * milliseconds. - */ - bool lockPlugin(); - - /** - * Must be invoked if lockPlugin() returned true and plugin has been accessed - * by the thread creator. - */ - void unlockPlugin(); - QMap<QString, QVector<VersionControlObserver::ItemState> > itemStates() const; - bool retrievedItems() const; - protected: virtual void run(); @@ -74,7 +59,6 @@ private: QMutex* m_globalPluginMutex; // Protects the m_plugin globally KVersionControlPlugin* m_plugin; - bool m_retrievedItems; QMap<QString, QVector<VersionControlObserver::ItemState> > m_itemStates; }; diff --git a/src/views/versioncontrol/versioncontrolobserver.cpp b/src/views/versioncontrol/versioncontrolobserver.cpp index 769c290f9..6affe80d3 100644 --- a/src/views/versioncontrol/versioncontrolobserver.cpp +++ b/src/views/versioncontrol/versioncontrolobserver.cpp @@ -198,20 +198,15 @@ void VersionControlObserver::slotThreadFinished() return; } - if (!thread->retrievedItems()) { - // Ignore m_silentUpdate for an error message - emit errorMessage(i18nc("@info:status", "Update of version information failed.")); - return; - } - const QMap<QString, QVector<ItemState> >& itemStates = thread->itemStates(); - foreach (const QString& directory, itemStates.keys()) { - const QVector<ItemState>& items = itemStates.value(directory); + QMap<QString, QVector<ItemState> >::const_iterator it = itemStates.constBegin(); + for (; it != itemStates.constEnd(); ++it) { + const QVector<ItemState>& items = it.value(); foreach (const ItemState& item, items) { QHash<QByteArray, QVariant> values; values.insert("version", QVariant(item.version)); - m_model->setData(item.index, values); + m_model->setData(m_model->index(item.item), values); } } @@ -270,7 +265,6 @@ int VersionControlObserver::createItemStatesList(QMap<QString, QVector<ItemState if (expansionLevel == currentExpansionLevel) { ItemState itemState; - itemState.index = index; itemState.item = m_model->fileItem(index); itemState.version = KVersionControlPlugin2::UnversionedVersion; diff --git a/src/views/versioncontrol/versioncontrolobserver.h b/src/views/versioncontrol/versioncontrolobserver.h index 980374af9..d12d2cfe0 100644 --- a/src/views/versioncontrol/versioncontrolobserver.h +++ b/src/views/versioncontrol/versioncontrolobserver.h @@ -102,7 +102,6 @@ private slots: private: struct ItemState { - int index; KFileItem item; KVersionControlPlugin2::ItemVersion version; }; diff --git a/src/views/viewproperties.h b/src/views/viewproperties.h index b3d3070ed..69b507f1b 100644 --- a/src/views/viewproperties.h +++ b/src/views/viewproperties.h @@ -160,7 +160,7 @@ private: /** * @return A hash-value for an URL that can be used as directory name. - * Is used to be able to remember view-properties for long nepomuksearch-URLs. + * Is used to be able to remember view-properties for long baloo-URLs. */ static QString directoryHashForUrl(const KUrl& url); |
