Index: workspace/plasma/applets/kickoff/core/applicationmodel.cpp =================================================================== --- workspace/plasma/applets/kickoff/core/applicationmodel.cpp (revision 842776) +++ workspace/plasma/applets/kickoff/core/applicationmodel.cpp (working copy) @@ -69,7 +69,7 @@ { public: AppNode() - : isDir(false), parent(0), fetched(false) + : subTitleMandatory(false), isDir(false), parent(0), fetched(false) { } ~AppNode() @@ -82,6 +82,7 @@ QString appName; QString relPath; QString desktopEntry; + bool subTitleMandatory; bool isDir; AppNode *parent; @@ -96,9 +97,7 @@ ApplicationModelPrivate(ApplicationModel *qq) : q(qq), root(new AppNode()), - duplicatePolicy(ApplicationModel::ShowDuplicatesPolicy), - sortOrder(Qt::AscendingOrder), - sortColumn(Qt::DisplayRole) + duplicatePolicy(ApplicationModel::ShowDuplicatesPolicy) { systemApplications = Kickoff::systemApplicationList(); } @@ -108,39 +107,27 @@ delete root; } - static bool AppNodeLessThan(AppNode *n1, AppNode *n2); void fillNode(const QString &relPath, AppNode *node); static QHash<QString,QString> iconNameMap(); ApplicationModel *q; AppNode *root; ApplicationModel::DuplicatePolicy duplicatePolicy; - Qt::SortOrder sortOrder; - int sortColumn; QStringList systemApplications; }; -bool ApplicationModelPrivate::AppNodeLessThan(AppNode *n1, AppNode *n2) -{ - if (n1->isDir != n2->isDir) { - return n1->isDir; - } - - const QString s1 = n1->genericName.isEmpty() ? n1->appName : n1->genericName; - const QString s2 = n2->genericName.isEmpty() ? n2->appName : n2->genericName; - - return s1.compare(s2, Qt::CaseInsensitive) < 0; -} - void ApplicationModelPrivate::fillNode(const QString &_relPath, AppNode *node) { KServiceGroup::Ptr root = KServiceGroup::group(_relPath); if (!root || !root->isValid()) return; - KServiceGroup::List list = root->entries(); + KServiceGroup::List list = root->entries(true /*sorted*/, true /*excludeNoDisplay*/, false /*allowSeparators*/, false /*sortByGenericName*/); // application name <-> service map for detecting duplicate entries QHash<QString,KService::Ptr> existingServices; + // generic name <-> node mapping to determinate duplicate generic names + QHash<QString,QList<AppNode*> > genericNames; + for (KServiceGroup::List::ConstIterator it = list.begin(); it != list.end(); ++it) { @@ -207,6 +194,11 @@ appName = serviceGroup->comment(); isDir = true; } + else if (p->isType(KST_KServiceSeparator)) + { + //TODO see kdebase/kicker/kicker/ui/service_mnu.cpp in KDE3 + continue; + } else { kWarning(250) << "KServiceGroup: Unexpected object in list!"; @@ -222,9 +214,32 @@ newnode->isDir = isDir; newnode->parent = node; node->children.append(newnode); + + if (p->isType(KST_KService)) { + // as with Qt 4.4.1 while the documentation says, that if the QHash + // does not contain a value with that key it got inserted using the + // default constructor, it can lead to crashes with a QList. So, we + // need to explicit check here if we need to add a new item or can + // append to an already existing one. + const QString s = genericName.toLower(); // e.g. Opera defines "Web browser" while others use "Web Browser" + if (genericNames.contains(s)) { + genericNames[s].append(newnode); + } else { + genericNames[s] = QList<AppNode*>() << newnode; + } + } } - qStableSort(node->children.begin(), node->children.end(), ApplicationModelPrivate::AppNodeLessThan); + // set the subTitleMandatory field for nodes that do not provide a unique generic + // name what may help us on display to show in such cases also the subtitle to + // provide a hint to the user what the duplicate entries are about. + foreach(QList<AppNode*> list, genericNames.values()) { + if (list.count() >= 2) { + foreach(AppNode* n, list) { + n->subTitleMandatory = true; + } + } + } } ApplicationModel::ApplicationModel(QObject *parent) @@ -280,11 +295,13 @@ break; case Kickoff::UrlRole: return node->desktopEntry; + case Kickoff::SubTitleMandatoryRole: + return node->subTitleMandatory; case Qt::DecorationRole: return node->icon; break; default: - ; + break; } return QVariant(); } @@ -353,11 +370,8 @@ if (id >= 0 && id < node->parent->parent->children.count()) return createIndex(id, 0, node->parent); - else - return QModelIndex(); } - else - return QModelIndex(); + return QModelIndex(); } int ApplicationModel::rowCount(const QModelIndex &parent) const