diff --git a/ToolTips/tooltipmanager.cpp b/ToolTips/tooltipmanager.cpp index 4264973..84f41d0 100644 --- a/ToolTips/tooltipmanager.cpp +++ b/ToolTips/tooltipmanager.cpp @@ -1,188 +1,207 @@ /******************************************************************************* * Copyright (C) 2008 by Konstantin Heil * * * * 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 "tooltipmanager.h" #include "kcmtreeitem.h" #include "sidepanel.h" #include #include #include #include #include #include #include #include +#include #include #include +class IconLoaderSingleton +{ +public: + IconLoaderSingleton() = default; + + KIconLoader self; +}; + +Q_GLOBAL_STATIC(IconLoaderSingleton, privateIconLoaderSelf) + class ToolTipManager::Private { public: KToolTipWidget *tooltip = nullptr; QAbstractItemView* view = nullptr; QTimer* timer = nullptr; QModelIndex item; QRect itemRect; int delay = 50; }; ToolTipManager::ToolTipManager(QAbstractItemView* parent) : QObject(parent) , d(new ToolTipManager::Private) { d->view = parent; d->tooltip = new KToolTipWidget(d->view); d->tooltip->setHideDelay(0); connect(parent, &QAbstractItemView::viewportEntered, this, &ToolTipManager::hideToolTip); connect(parent, &QAbstractItemView::entered, this, &ToolTipManager::requestToolTip); d->timer = new QTimer(this); d->timer->setSingleShot(true); connect(d->timer, &QTimer::timeout, this, &ToolTipManager::prepareToolTip); // When the mousewheel is used, the items don't get a hovered indication // (Qt-issue #200665). To assure that the tooltip still gets hidden, // the scrollbars are observed. connect(parent->horizontalScrollBar(), &QAbstractSlider::valueChanged, this, &ToolTipManager::hideToolTip); connect(parent->verticalScrollBar(), &QAbstractSlider::valueChanged, this, &ToolTipManager::hideToolTip); d->view->viewport()->installEventFilter(this); } ToolTipManager::~ToolTipManager() { delete d; } bool ToolTipManager::eventFilter(QObject* watched, QEvent* event) { if ( watched == d->view->viewport() ) { switch ( event->type() ) { case QEvent::Leave: case QEvent::MouseButtonPress: hideToolTip(); break; case QEvent::ToolTip: return true; default: break; } } return QObject::eventFilter(watched, event); } void ToolTipManager::requestToolTip(const QModelIndex& index) { // only request a tooltip for the name column and when no selection or // drag & drop operation is done (indicated by the left mouse button) if ( !(QApplication::mouseButtons() & Qt::LeftButton) ) { d->tooltip->hide(); d->itemRect = d->view->visualRect(index); const QPoint pos = d->view->viewport()->mapToGlobal(d->itemRect.topLeft()); d->itemRect.moveTo(pos); d->item = index; d->timer->start(d->delay); } else { hideToolTip(); } } void ToolTipManager::hideToolTip() { d->timer->stop(); d->tooltip->hideLater(); } void ToolTipManager::prepareToolTip() { showToolTip( d->item ); } void ToolTipManager::showToolTip( const QModelIndex& menuItem ) { if (QApplication::mouseButtons() & Qt::LeftButton) { return; } QWidget * tip = createTipContent( menuItem ); connect(d->tooltip, &KToolTipWidget::hidden, tip, &QObject::deleteLater); d->tooltip->showBelow(d->itemRect, tip, d->view->nativeParentWidget()->windowHandle()); } QWidget * ToolTipManager::createTipContent( const QModelIndex& item ) { QWidget * tipContent = new QWidget(); QGridLayout* tipLayout = new QGridLayout(); QLayout * primaryLine = generateToolTipLine( item, tipContent, QSize(32,32), true ); tipLayout->addLayout( primaryLine, 0, 0 ); for ( int done = 0; d->view->model()->rowCount( item ) > done; done = 1 + done ) { QModelIndex childItem = d->view->model()->index( done, 0, item ); QLayout * subLine = generateToolTipLine( childItem, tipContent, QSize(24,24), false ); tipLayout->addLayout( subLine, done + 2, 0 ); } tipLayout->setVerticalSpacing( 0 ); tipContent->setLayout( tipLayout ); if( d->view->model()->rowCount( item ) > 0 ) { QFrame * separatorLine = new QFrame( tipContent ); separatorLine->setFrameStyle( QFrame::HLine ); tipLayout->addWidget( separatorLine, 1, 0 ); } return tipContent; } QLayout * ToolTipManager::generateToolTipLine( const QModelIndex & item, QWidget * toolTip, const QSize& iconSize, bool comment ) { SidePanel *sidePanel = static_cast(d->view); KcmTreeItem *menuItem = static_cast( sidePanel->mapToProxySource(item).internalPointer() ); QString text = menuItem->data(); if ( comment ) { text = QStringLiteral( "%1" ).arg( menuItem->data() ); } QLabel * textLabel = new QLabel( toolTip ); textLabel->setForegroundRole(QPalette::ToolTipText); textLabel->setText( text ); // Get icon - QIcon icon( menuItem->icon() ); + QPalette pal = textLabel->palette(); + for (auto state : { QPalette::Active, QPalette::Inactive, QPalette::Disabled }) { + pal.setBrush(state, QPalette::WindowText, pal.toolTipText()); + pal.setBrush(state, QPalette::Window, pal.toolTipBase()); + } + + privateIconLoaderSelf->self.setCustomPalette(pal); + + QIcon icon = KDE::icon(menuItem->iconName(), &privateIconLoaderSelf->self); QLabel * iconLabel = new QLabel( toolTip ); iconLabel->setPixmap( icon.pixmap(iconSize) ); iconLabel->setMaximumSize( iconSize ); // Generate layout QHBoxLayout * layout = new QHBoxLayout(); layout->addWidget( iconLabel ); layout->addWidget( textLabel ); return layout; } diff --git a/infokcmmodel.cpp b/infokcmmodel.cpp index c01ed20..f9759a0 100644 --- a/infokcmmodel.cpp +++ b/infokcmmodel.cpp @@ -1,233 +1,233 @@ /* * infokcmmodel.h * * Copyright (C) 2010 David Hubner * * 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. * */ //Local #include "infokcmmodel.h" #include "kcmcategoryitem.h" //KDE #include #include #include InfoKcmModel::InfoKcmModel(QObject *parent) : QAbstractItemModel(parent), m_root(new KcmCategoryItem(i18n("Information Modules"))) { createTreeItems(); } InfoKcmModel::~InfoKcmModel() { delete m_root; } void InfoKcmModel::createTreeItems() { const KService::List categoryList = KServiceTypeTrader::self()->query(QStringLiteral("KInfoCenterCategory")); for(const KService::Ptr &categoryModule : categoryList) { m_root->addChild(new KcmCategoryItem(categoryModule,m_root)); } const KService::List moduleList = KServiceTypeTrader::self()->query(QStringLiteral("KCModule"), QStringLiteral("[X-KDE-ParentApp] == 'kinfocenter'")); for (const KService::Ptr &kcmModule : moduleList) { if (kcmModule->isType(KST_KService) == true) { QString category = kcmModule->property(QStringLiteral("X-KDE-KInfoCenter-Category")).toString().trimmed(); if(!category.isEmpty() || !category.isNull()) { KcmTreeItem *item = m_root->containsCategory(category); if(item != nullptr) { item->addChild(new KcmTreeItem(kcmModule,item)); } else { KcmTreeItem *lost = m_root->containsCategory(QStringLiteral("lost_and_found")); if(lost != nullptr) { lost->addChild(new KcmTreeItem(kcmModule,lost)); } else { qWarning() << "Lost and found category not found, unable to display lost Kcontrol modules"; } } } else { m_root->addChild(new KcmTreeItem(kcmModule,m_root)); } } } } QModelIndex InfoKcmModel::index(int row, int column, const QModelIndex &parent) const { KcmTreeItem *parentItem; if (!parent.isValid()) { parentItem = m_root; } else { parentItem = static_cast(parent.internalPointer()); } KcmTreeItem *childItem = parentItem->child(row); if (childItem) { return createIndex(row, column, childItem); } return QModelIndex(); } QModelIndex InfoKcmModel::index(int row, int column, KcmTreeItem *parent) const { KcmTreeItem *childItem = parent->child(row); if (childItem) { return createIndex(row, column, childItem); } return QModelIndex(); } QModelIndex InfoKcmModel::parent(const QModelIndex &index) const { if (!index.isValid()) { return QModelIndex(); } KcmTreeItem *child = static_cast(index.internalPointer()); KcmTreeItem *parent = child->parent(); if (parent == m_root) { return QModelIndex(); } return createIndex(parent->row(), 0, parent); } QModelIndex InfoKcmModel::indexOf(KcmTreeItem *item) { QModelIndex tmpIndex = createIndex(item->row(), 0, item); if(!tmpIndex.isValid()) { return QModelIndex(); } return tmpIndex; } int InfoKcmModel::rowCount(const QModelIndex &parent) const { KcmTreeItem *parentItem; if (!parent.isValid()) { parentItem = m_root; } else { parentItem = static_cast(parent.internalPointer()); } return parentItem->childCount(); } int InfoKcmModel::columnCount(const QModelIndex &parent) const { // Hard coded, menu should never have more than one column Q_UNUSED(parent); return 1; } QVariant InfoKcmModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } KcmTreeItem *item = static_cast(index.internalPointer()); switch(role) { case Qt::DisplayRole: return item->data(); case Qt::UserRole: return item->weight(); case Qt::DecorationRole: - return item->icon(); + return QIcon::fromTheme(item->iconName()); default: return QVariant(); } } QVariant InfoKcmModel::headerData(int section, Qt::Orientation orientation, int role) const { Q_UNUSED(section); if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { return m_root->data(); } return QVariant(); } Qt::ItemFlags InfoKcmModel::flags(const QModelIndex &index) const { if (!index.isValid()) { return Qt::ItemIsEnabled; } return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } QModelIndex InfoKcmModel::firstValid() const { int rows = m_root->childCount(); // Massive large number to max compare unsigned int winner = 0; winner--; QModelIndex winnerIndex = QModelIndex(); for(int i=0;ichild(i); if(item->type() == KcmTreeItem::KCM) { if(winner >= (unsigned int)item->weight()) { winner = item->weight(); winnerIndex = index(item->row(),0,item->parent()); } } } return winnerIndex; } QStringList InfoKcmModel::allChildrenKeywords() { return childrenKeywords(m_root); } QStringList InfoKcmModel::childrenKeywords(KcmTreeItem *kcmItem) { QStringList childKeywords; int rows = kcmItem->childCount(); for(int i=0;ichild(i); if(item->type() == KcmTreeItem::CATEGORY) { childKeywords = childKeywords + childrenKeywords(item); } else { childKeywords = childKeywords + item->keywords(); } } return childKeywords; } diff --git a/kcmcategoryitem.cpp b/kcmcategoryitem.cpp index 4485fbf..9b80356 100644 --- a/kcmcategoryitem.cpp +++ b/kcmcategoryitem.cpp @@ -1,85 +1,85 @@ /* * kcmcategoryitem.cpp * * Copyright (C) 2010 David Hubner * * 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 "kcmcategoryitem.h" KcmCategoryItem::KcmCategoryItem(const KService::Ptr &module, KcmTreeItem *parent) : KcmTreeItem(module, parent) { } KcmCategoryItem::KcmCategoryItem(const QString& categoryName) : KcmTreeItem(), m_category(categoryName) { } QString KcmCategoryItem::data() const { if(m_category.isEmpty()) { return m_moduleInfo->moduleName(); } return category(); } KcmTreeItem::itemType KcmCategoryItem::type() const { return CATEGORY; } QString KcmCategoryItem::category() const { if(m_category.isEmpty()) { return m_module->property(QStringLiteral("X-KDE-KInfoCenter-Category")).toString().trimmed(); } return m_category; } KCModuleInfo KcmCategoryItem::kcm() const { return KCModuleInfo(); } int KcmCategoryItem::weight() const { return (category().count() + 1000); } -QIcon KcmCategoryItem::icon() const +QString KcmCategoryItem::iconName() const { if(m_category.isEmpty()) { - return QIcon::fromTheme(m_moduleInfo->icon()); + return m_moduleInfo->icon(); } - return QIcon(); + return QString(); } QString KcmCategoryItem::whatsThis() const { return QString(); } QStringList KcmCategoryItem::keywords() const { return QStringList(); } diff --git a/kcmcategoryitem.h b/kcmcategoryitem.h index f97bdba..b42b10b 100644 --- a/kcmcategoryitem.h +++ b/kcmcategoryitem.h @@ -1,98 +1,98 @@ /* * kcmcategoryitem.h * * Copyright (C) 2010 David Hubner * * 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 KCMCATEGORYITEM #define KCMCATEGORYITEM #include "kcmtreeitem.h" //KDE #include #include class KcmCategoryItem : public KcmTreeItem { public: /** * Category Tree Item for InfoKcmModel. Holds information about a Category * * @param module pointer to KCM module * @param parent objects parent */ explicit KcmCategoryItem(const KService::Ptr &module, KcmTreeItem *parent=nullptr); /** * Category Tree Item for InfoKcmModel. Holds information about a Category * * @note Used for root folder objects */ explicit KcmCategoryItem(const QString& category); /** * Get data of tree item */ QString data() const override; /** * Get category of tree item. * Set in X-KDE-KInfoCenter-Category */ QString category() const override; /** * Gets the item type. */ itemType type() const override; /** * Get tree item KCMs Data */ KCModuleInfo kcm() const override; /** * Get tree items KCM's weight */ int weight() const override; /** * Get icon tied to KCM */ - QIcon icon() const override; + QString iconName() const override; /** * Get whatsThis information from KCM */ QString whatsThis() const override; /** * Get KCM tree item keywords */ QStringList keywords() const override; private: const QString m_category; }; #endif //KCMCATEGORYITEM diff --git a/kcmtreeitem.cpp b/kcmtreeitem.cpp index eab5def..49dc574 100644 --- a/kcmtreeitem.cpp +++ b/kcmtreeitem.cpp @@ -1,154 +1,154 @@ /* * kcmtreeitem.h * * Copyright (C) 2010 David Hubner * * 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. * */ //Local #include "kcmtreeitem.h" KcmTreeItem::KcmTreeItem(const KService::Ptr &module, KcmTreeItem *parent) : m_parent(parent), m_module(module), m_moduleInfo(new KCModuleInfo(m_module)) { } KcmTreeItem::KcmTreeItem() : m_parent(nullptr), m_moduleInfo(new KCModuleInfo()) { } KcmTreeItem::~KcmTreeItem() { qDeleteAll(m_children); delete m_moduleInfo; } void KcmTreeItem::addChild(KcmTreeItem *child) { m_children.append(child); } KcmTreeItem *KcmTreeItem::child(const int row) { if(childCount() > row) { return m_children.value(row); } return nullptr; } int KcmTreeItem::childCount() const { return m_children.count(); } int KcmTreeItem::columnCount() const { // Hard coded, menu should never have more than one column return 1; } KcmTreeItem *KcmTreeItem::parent() const { return m_parent; } int KcmTreeItem::row() { if (m_parent) { return indexOf(const_cast(this)); } return 0; } int KcmTreeItem::indexOf(KcmTreeItem *item) { if (m_parent) { return m_parent->m_children.indexOf(item); } return 0; } QString KcmTreeItem::data() const { return m_moduleInfo->moduleName(); } QString KcmTreeItem::category() const { return m_module->property(QStringLiteral("X-KDE-KInfoCenter-Category")).toString().trimmed(); } KcmTreeItem::itemType KcmTreeItem::type() const { return KCM; } KcmTreeItem *KcmTreeItem::containsCategory(const QString& category) { foreach(KcmTreeItem *item, m_children) { if(item->type() == CATEGORY) { if(item->category().contains(category)) { return item; } if(item->containsCategory(category)) { return item; } } } return nullptr; } KCModuleInfo KcmTreeItem::kcm() const { return *m_moduleInfo; } int KcmTreeItem::weight() const { return m_moduleInfo->weight(); } -QIcon KcmTreeItem::icon() const +QString KcmTreeItem::iconName() const { - return QIcon::fromTheme(m_moduleInfo->icon()); + return m_moduleInfo->icon(); } QString KcmTreeItem::whatsThis() const { return m_moduleInfo->comment(); } bool KcmTreeItem::childrenRegExp(const QRegExp& pattern) { foreach(KcmTreeItem *item, m_children) { if(item->keywords().filter(pattern).count() > 0) { return true; } } return false; } QStringList KcmTreeItem::keywords() const { if(m_moduleInfo->keywords().isEmpty()) { return QStringList(data()); } return m_moduleInfo->keywords(); } diff --git a/kcmtreeitem.h b/kcmtreeitem.h index a54a686..e5ee1d1 100644 --- a/kcmtreeitem.h +++ b/kcmtreeitem.h @@ -1,165 +1,165 @@ /* * kcmtreeitem.h * * Copyright (C) 2010 David Hubner * * 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 KCMTREEITEM #define KCMTREEITEM //KDE #include #include //QT #include #include class KcmTreeItem { public: /** * KCM Tree Item for InfoKcmModel. Holds information about a KCM * * @param module pointer to KCM module * @param parent objects parent */ explicit KcmTreeItem(const KService::Ptr &module, KcmTreeItem *parent=nullptr); /** * KCM Tree Item for InfoKcmModel. Holds information about a KCM * * @note Used for root folder objects * */ KcmTreeItem(); /** * Enumeration of the possible tree item types * */ enum itemType { KCM=0, CATEGORY }; /** * Destory KcmTreeItem */ virtual ~KcmTreeItem(); /** * Add child tree item to parent */ void addChild(KcmTreeItem *); /** * Get child tree item * * @param row row where child is located */ KcmTreeItem *child(const int row); /** * Get amount of children */ int childCount() const; /** * Get parent of current tree item */ KcmTreeItem *parent() const; /** * Get index of tree item */ int indexOf(KcmTreeItem *); /** * Get amount of columns that tree item contains. * Hardcoded to 1 */ int columnCount() const; /** * Get row of tree item */ int row(); /** * Get data of tree item */ virtual QString data() const; /** * Get category of tree item. * Set in X-KDE-KInfoCenter-Category */ virtual QString category() const; /** * Gets the item type. */ virtual itemType type() const; /** * Check if children of tree item contains a category. * Used in search implementation */ KcmTreeItem *containsCategory(const QString&); /** * Get tree item KCMs Data */ virtual KCModuleInfo kcm() const; /** * Get tree items KCM's weight */ virtual int weight() const; /** * Get icon tied to KCM */ - virtual QIcon icon() const; + virtual QString iconName() const; /** * Get whatsThis information from KCM */ virtual QString whatsThis() const; /** * Check if there are any children tree items keywords that * have a certain regexp pattern */ bool childrenRegExp(const QRegExp& pattern); /** * Get KCM tree item keywords */ virtual QStringList keywords() const; protected: QList m_children; KcmTreeItem *m_parent; const KService::Ptr m_module; const KCModuleInfo *m_moduleInfo; }; #endif // KCMTREEITEM