--Boundary_(ID_iCQ5hTYyKIZaDAwdDKXAfw) Content-type: Text/Plain; charset=us-ascii Content-transfer-encoding: 7BIT Content-disposition: inline Content-description: clearsigned data -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 hi... attached is a patchto improve the handling of servicemenus in konqueror. it does three things: 1) allows mimetype globs in the form of image/*. it's quite possible to add support for other forms of globbing (e.g. kdedevice/smb-*, or even full on REs) but i thought i'd start with this for now. 2) puts all the actions (including the builtins) into an Actions submenu to help keep the size of the RMB menu down 3) supports submenus in the Action menu. this is achieved by supporting the Categories .desktop field and using the first category (if any) as the submenu. an example servicemenu utilizing the submenu support is attached as well. these things were discussed some time ago on the kde-usability list, but i've only now gotten around to implementing them. comments? =) - -- Aaron J. Seigo GPG Fingerprint: 8B8B 2209 0C6F 7C47 B1EA EE75 D6B7 2EB1 A7F1 DB43 KDE: The 'K' is for 'kick ass' http://www.kde.org http://promo.kde.org/3.1/feature_guide.php -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE+yHI11rcusafx20MRAj3QAJ0ZFAblISXH/P43B8znR2nQTdGWSACePQLw FkkzpHrKRKFCjML8HdI0W1A= =D39x -----END PGP SIGNATURE----- --Boundary_(ID_iCQ5hTYyKIZaDAwdDKXAfw) Content-type: application/x-desktop; name=background.desktop Content-transfer-encoding: 7bit Content-disposition: attachment; filename=background.desktop [Desktop Entry] ServiceTypes=image/* Actions=setAsBackground;tileAsBackground Categories=Set As Background [Desktop Action setAsBackground] Name=Centered Icon=background Exec=dcop kdesktop KBackgroundIface setWallpaper %U 6 [Desktop Action tileAsBackground] Name=Tiled Icon=background Exec=dcop kdesktop KBackgroundIface setWallpaper %U 2 --Boundary_(ID_iCQ5hTYyKIZaDAwdDKXAfw) Content-type: text/x-diff; charset=us-ascii; name=libkonq_servicemenus.diff Content-transfer-encoding: 7BIT Content-disposition: attachment; filename=libkonq_servicemenus.diff Index: konq_popupmenu.cc =================================================================== RCS file: /home/kde/kdebase/libkonq/konq_popupmenu.cc,v retrieving revision 1.143 diff -u -3 -d -p -b -r1.143 konq_popupmenu.cc --- konq_popupmenu.cc 20 Mar 2003 16:27:45 -0000 1.143 +++ konq_popupmenu.cc 19 May 2003 05:46:53 -0000 @@ -44,6 +44,7 @@ #include "konq_popupmenu.h" #include "konq_operations.h" + class KonqPopupMenuGUIBuilder : public KXMLGUIBuilder { public: @@ -132,6 +133,38 @@ KonqPopupMenu::KonqPopupMenu( KBookmarkM setup(showPropertiesAndFileType); } + +void KonqPopupMenu::insertServices(const ServiceList& list, + QDomElement& menu, + bool isBuiltin) +{ + static int id = 1000; + + ServiceList::const_iterator it = list.begin(); + for( ; it != list.end(); ++it ) + { + if (isBuiltin || (*it).m_display == true) + { + QCString name; + name.setNum( id ); + name.prepend( isBuiltin ? "builtinservice_" : "userservice_" ); + KAction * act = new KAction( (*it).m_strName, 0, + this, SLOT( slotRunService() ), + &m_ownActions, name ); + + if ( !(*it).m_strIcon.isEmpty() ) + { + QPixmap pix = SmallIcon( (*it).m_strIcon ); + act->setIconSet( pix ); + } + + addAction( act, menu ); // Add to toplevel menu + + m_mapPopupServices[ id++ ] = *it; + } + } +} + void KonqPopupMenu::setup(bool showPropertiesAndFileType) { assert( m_lstItems.count() >= 1 ); @@ -351,8 +384,9 @@ void KonqPopupMenu::setup(bool showPrope ////////////////////////////////////////////////////// - QValueList builtin; - QValueList user; + ServiceList builtin; + ServiceList user; + QMap userSubmenus; // 1 - Look for builtin and user-defined services if ( m_sMimeType == "application/x-desktop" && m_lstItems.count() == 1 && m_lstItems.first()->url().isLocalFile() ) // .desktop file @@ -405,19 +439,58 @@ void KonqPopupMenu::setup(bool showPrope if ( cfg.hasKey( "Actions" ) && cfg.hasKey( "ServiceTypes" ) ) { QStringList types = cfg.readListEntry( "ServiceTypes" ); - bool ok = !m_sMimeType.isNull() && types.contains( m_sMimeType ); - if ( !ok ) { - ok = (types[0] == "all/all" || - types[0] == "allfiles" /*compat with KDE up to 3.0.3*/); - if ( !ok && types[0] == "all/allfiles" ) + bool ok = false; + QString mimeGroup = m_sMimeType.left(m_sMimeType.find('/')); + + // check for exact matches or a typeglob'd mimetype if we have a mimetype + for (QStringList::iterator it = types.begin(); it != types.end(); ++it) { - ok = (m_sMimeType != "inode/directory"); // ## or inherits from it + // we could cram the following three if statements into + // one gigantic boolean statement but that would be a + // hororr show for readability + + // first check if we have an all mimetype + if (*it == "all/all" || + *it == "allfiles" /*compat with KDE up to 3.0.3*/) + { + ok = true; + break; } + + // next, do we match all files? + if (*it == "all/allfiles" && + m_sMimeType != "inode/directory") // ## or inherits from it + { + ok = true; + break; } + + // if we have a mimetype, see if we have an exact or type + // globbed match + if (!m_sMimeType.isNull() && + (*it == m_sMimeType || + ((*it).right(1) == "*" && + (*it).left((*it).find('/')) == mimeGroup))) + { + ok = true; + break; + } + } + if ( ok ) { + // we use the categories .desktop entry to define submenus + // if none is defined, we just pop it in the main menu + QStringList categories = cfg.readListEntry( "Categories" ); + if (categories.isEmpty()) + { user += KDEDesktopMimeType::userDefinedServices( *dIt + *eIt, url.isLocalFile() ); } + else + { + userSubmenus[categories[0]] += KDEDesktopMimeType::userDefinedServices( *dIt + *eIt, url.isLocalFile() ); + } + } } } } @@ -492,58 +565,40 @@ void KonqPopupMenu::setup(bool showPrope addGroup( "preview" ); - addSeparator(); - // Second block, builtin + user - if ( !user.isEmpty() || !builtin.isEmpty() ) + if ( !user.isEmpty() || !userSubmenus.empty() || !builtin.isEmpty() ) { - bool insertedOffer = false; + QDomElement actionMenu = m_doc.createElement( "menu" ); + actionMenu.setAttribute( "name", "actions submenu" ); + m_menuElement.appendChild( actionMenu ); + QDomElement text = m_doc.createElement( "text" ); + actionMenu.appendChild( text ); + text.appendChild( m_doc.createTextNode( i18n("Ac&tions") ) ); - QValueList::Iterator it2 = user.begin(); - for( ; it2 != user.end(); ++it2 ) - { - if ((*it2).m_display == true) + QMap::Iterator it; + for (it = userSubmenus.begin(); it != userSubmenus.end(); ++it) { - QCString nam; - nam.setNum( id ); - act = new KAction( (*it2).m_strName, 0, this, SLOT( slotRunService() ), &m_ownActions, nam.prepend( "userservice_" ) ); - - if ( !(*it2).m_strIcon.isEmpty() ) + if (it.data().isEmpty()) { - QPixmap pix = SmallIcon( (*it2).m_strIcon ); - act->setIconSet( pix ); - } - - addAction( act, m_menuElement ); // Add to toplevel menu - - m_mapPopupServices[ id++ ] = *it2; - insertedOffer = true; - } + //avoid empty sub-menus + continue; } - it2 = builtin.begin(); - for( ; it2 != builtin.end(); ++it2 ) - { - QCString nam; - nam.setNum( id ); - - act = new KAction( (*it2).m_strName, 0, this, SLOT( slotRunService() ), &m_ownActions, nam.prepend( "builtinservice_" ) ); - - if ( !(*it2).m_strIcon.isEmpty() ) - { - QPixmap pix = SmallIcon( (*it2).m_strIcon ); - act->setIconSet( pix ); + QDomElement actionSubmenu = m_doc.createElement( "menu" ); + actionSubmenu.setAttribute( "name", "actions " + it.key() ); + actionMenu.appendChild( actionSubmenu ); + QDomElement subtext = m_doc.createElement( "text" ); + actionSubmenu.appendChild( subtext ); + subtext.appendChild( m_doc.createTextNode( it.key() ) ); + insertServices(it.data(), actionSubmenu, false); } - addAction( act, m_menuElement ); - - m_mapPopupServices[ id++ ] = *it2; - insertedOffer = true; + insertServices(user, actionMenu, false); + insertServices(builtin, actionMenu, true); } - if ( insertedOffer ) addSeparator(); - } + if ( !isCurrentTrash ) addPlugins( ); // now it's time to add plugins Index: konq_popupmenu.h =================================================================== RCS file: /home/kde/kdebase/libkonq/konq_popupmenu.h,v retrieving revision 1.41 diff -u -3 -d -p -b -r1.41 konq_popupmenu.h --- konq_popupmenu.h 20 Nov 2002 11:35:24 -0000 1.41 +++ konq_popupmenu.h 19 May 2003 05:46:54 -0000 @@ -34,6 +34,8 @@ #include "konq_xmlguiclient.h" +typedef QValueList ServiceList; + class KNewMenu; class KService; class KonqPopupMenuPlugin; @@ -134,6 +136,7 @@ protected: private: void setup(bool showPropertiesAndFileType); void addPlugins( ); + void insertServices(const ServiceList& list, QDomElement& menu, bool isBuiltin); class KonqPopupMenuPrivate; KonqPopupMenuPrivate *d; KNewMenu *m_pMenuNew; --Boundary_(ID_iCQ5hTYyKIZaDAwdDKXAfw)--