/** * Copyright (C) 2005 Benjamin C Meyer (ben+tdecmodulemenu at meyerhome dot net) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "tdecmodulemenu.h" #include #include #include #include class TDECModuleMenuPrivate { public: TDECModuleMenuPrivate(){ } TQMap > menus; TQString basePath; }; TDECModuleMenu::TDECModuleMenu( const TQString &menuName ) : d( new TDECModuleMenuPrivate ) { kdDebug() << "MenuName: \"" << menuName << "\"." << endl; // Make sure we can find the menu KServiceGroup::Ptr serviceGroup = KServiceGroup::baseGroup( menuName ); if( !serviceGroup ){ kdDebug() << "Unable to load menu \"" << menuName << "\" from KServiceGroup." << endl; return; } d->basePath = serviceGroup->relPath(); readMenu( d->basePath ); } TDECModuleMenu::~TDECModuleMenu() { delete d; } void TDECModuleMenu::readMenu( const TQString &pathName ) { KServiceGroup::Ptr group = KServiceGroup::group( pathName ); if ( !group || !group->isValid() ) return; KServiceGroup::List list = group->entries( true, true ); if( list.isEmpty() ) return; caption = group->caption(); TQValueList currentMenu; for( KServiceGroup::List::ConstIterator it = list.begin(); it != list.end(); it++) { KSycocaEntry *entry = (*it); if( addEntry(entry) ) { TDECModuleInfo module((KService*)entry); append(module); MenuItem infoItem(false); infoItem.caption = this->deriveCaptionFromPath(entry->name()); infoItem.item = module; currentMenu.append( infoItem ); } if ( entry->isType(KST_KServiceGroup) ){ MenuItem menuItem(true); menuItem.caption = this->deriveCaptionFromPath(entry->name()); menuItem.subMenu = entry->entryPath(); currentMenu.append( menuItem ); readMenu( entry->entryPath() ); } } d->menus.insert( pathName, currentMenu ); } bool TDECModuleMenu::addEntry( KSycocaEntry *entry ){ if( !entry->isType(KST_KService) ) return false; KService *service = static_cast( entry ); if ( !kapp->authorizeControlModule( service->menuId()) ) return false; TDECModuleInfo module( service ); if ( module.library().isEmpty() ) return false; return true; } TQValueList TDECModuleMenu::modules( const TQString &menuPath ) { TQValueList list; TQValueList subMenu = menuList(menuPath); TQValueList::iterator it; for ( it = subMenu.begin(); it != subMenu.end(); ++it ){ if ( !(*it).menu ) list.append( (*it).item ); } return list; } TQStringList TDECModuleMenu::submenus( const TQString &menuPath ) { TQStringList list; TQValueList subMenu = menuList(menuPath); TQValueList::iterator it; for ( it = subMenu.begin(); it != subMenu.end(); ++it ){ if ( (*it).menu ) list.append( (*it).subMenu ); } return list; } TQValueList TDECModuleMenu::menuList( const TQString &menuPath ) { if( menuPath.isEmpty() ) { if( d->basePath.isEmpty()) return TQValueList(); else return menuList( d->basePath ); } return d->menus[menuPath]; } /* * Okay, I think there could be a much more elegant way of doing * this... but I'm having a hell fo a time figuring it out. * * The purpose of this function is to take a menu path and turn it * into a caption that we can put in a tab. Why do it this way? I * don't know, you tell me. Before I started hacking this we used a * radio control with two buttons (or so it seemed, I could be wrong) * with General and Advanced in a ui.rc file. * * Now that we're using tabs, we no longer have that UI file giving us * the names for the tabs, and since I didn't want to hard-code * anything, and since KSycocaEntry stuff doesn't give you a nice way * (that I noticed anyway) to figure out what your caption should be, * I decided that cleverness is lost on this problem. So screw it, * I'll just parse the stupid path and be done with it. * * This function is certainly nothing short of dull and boring and * routine, but I figured that this might require a bit of explanation * since it just seems kinda silly to do it this way to me. I guess I * never know... I could be doing it the best way. * * "Michael D. Stemle, Jr." */ TQString TDECModuleMenu::deriveCaptionFromPath( const TQString &menuPath ) { TQStringList parts(TQStringList::split("/",menuPath)); TQString result(""); TQStringList::Iterator it = parts.end(); // Start at the end // Find the last non-empty string in the split. for (; it != parts.begin(); --it) { if (!((*it).isNull()) && !((*it).isEmpty())) { result += *it; return result; } } return result; }