• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • libkonq
 

libkonq

  • libkonq
konq_popupmenu.cpp
1/* This file is part of the KDE project
2 Copyright (C) 1998, 1999 David Faure <faure@kde.org>
3 Copyright (C) 2001 Holger Freyther <freyther@yahoo.com>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include <tqdir.h>
22#include <tqeventloop.h>
23
24#include <tdelocale.h>
25#include <tdeapplication.h>
26#include <kbookmarkmanager.h>
27#include <kdebug.h>
28#include <krun.h>
29#include <kprotocolinfo.h>
30#include <kiconloader.h>
31#include <kinputdialog.h>
32#include <tdeglobalsettings.h>
33#include <tdestandarddirs.h>
34#include <kxmlguifactory.h>
35#include <kxmlguibuilder.h>
36#include <tdeparts/componentfactory.h>
37
38#include <assert.h>
39
40#include <tdefileshare.h>
41#include <tdeprocess.h>
42
43#include "kpropertiesdialog.h"
44#include "knewmenu.h"
45#include "konq_popupmenu.h"
46#include "konq_operations.h"
47#include "konq_xmlguiclient.h"
48#include <dcopclient.h>
49
50/*
51 Test cases:
52 iconview file: background
53 iconview file: file (with and without servicemenus)
54 iconview file: directory
55 iconview remote protocol (e.g. ftp: or fish:)
56 iconview trash:/
57 sidebar directory tree
58 sidebar Devices / Hard Disc
59 tdehtml background
60 tdehtml link
61 tdehtml image (www.kde.org RMB on K logo)
62 tdehtmlimage (same as above, then choose View image, then RMB)
63 selected text in tdehtml
64 embedded katepart
65 kdesktop folder
66 trash link on desktop
67 trashed file or directory
68 application .desktop file
69 Then the same after uninstalling tdeaddons/konq-plugins (kuick and arkplugin in particular)
70*/
71
72class KonqPopupMenuGUIBuilder : public KXMLGUIBuilder
73{
74public:
75 KonqPopupMenuGUIBuilder( TQPopupMenu *menu )
76 : KXMLGUIBuilder( 0 )
77 {
78 m_menu = menu;
79 }
80 virtual ~KonqPopupMenuGUIBuilder()
81 {
82 }
83
84 virtual TQWidget *createContainer( TQWidget *parent, int index,
85 const TQDomElement &element,
86 int &id )
87 {
88 if ( !parent && element.attribute( "name" ) == "popupmenu" )
89 return m_menu;
90
91 return KXMLGUIBuilder::createContainer( parent, index, element, id );
92 }
93
94 TQPopupMenu *m_menu;
95};
96
97class KonqPopupMenu::KonqPopupMenuPrivate
98{
99public:
100 KonqPopupMenuPrivate() : m_parentWidget( 0 ),
101 m_itemFlags( KParts::BrowserExtension::DefaultPopupItems )
102 {
103 }
104 TQString m_urlTitle;
105 TQWidget *m_parentWidget;
106 KParts::BrowserExtension::PopupFlags m_itemFlags;
107
108 bool localURLSlotFired;
109 KURL localURLResultURL;
110 bool localURLResultIsLocal;
111};
112
113KonqPopupMenu::ProtocolInfo::ProtocolInfo()
114{
115 m_Reading = false;
116 m_Writing = false;
117 m_Deleting = false;
118 m_Moving = false;
119 m_TrashIncluded = false;
120}
121
122bool KonqPopupMenu::ProtocolInfo::supportsReading() const
123{
124 return m_Reading;
125}
126
127bool KonqPopupMenu::ProtocolInfo::supportsWriting() const
128{
129 return m_Writing;
130}
131
132bool KonqPopupMenu::ProtocolInfo::supportsDeleting() const
133{
134 return m_Deleting;
135}
136
137bool KonqPopupMenu::ProtocolInfo::supportsMoving() const
138{
139 return m_Moving;
140}
141
142bool KonqPopupMenu::ProtocolInfo::trashIncluded() const
143{
144 return m_TrashIncluded;
145}
146
147// This helper class stores the .desktop-file actions and the servicemenus
148// in order to support X-TDE-Priority and X-TDE-Submenu.
149class PopupServices
150{
151public:
152 ServiceList* selectList( const TQString& priority, const TQString& submenuName );
153
154 ServiceList builtin;
155 ServiceList user, userToplevel, userPriority;
156 TQMap<TQString, ServiceList> userSubmenus, userToplevelSubmenus, userPrioritySubmenus;
157};
158
159ServiceList* PopupServices::selectList( const TQString& priority, const TQString& submenuName )
160{
161 // we use the categories .desktop entry to define submenus
162 // if none is defined, we just pop it in the main menu
163 if (submenuName.isEmpty())
164 {
165 if (priority == "TopLevel")
166 {
167 return &userToplevel;
168 }
169 else if (priority == "Important")
170 {
171 return &userPriority;
172 }
173 }
174 else if (priority == "TopLevel")
175 {
176 return &(userToplevelSubmenus[submenuName]);
177 }
178 else if (priority == "Important")
179 {
180 return &(userPrioritySubmenus[submenuName]);
181 }
182 else
183 {
184 return &(userSubmenus[submenuName]);
185 }
186 return &user;
187}
188
190
191KonqPopupMenu::KonqPopupMenu( KBookmarkManager *mgr, const KFileItemList &items,
192 KURL viewURL,
193 TDEActionCollection & actions,
194 KNewMenu * newMenu,
195 bool showProperties )
196 : TQPopupMenu( 0L, "konq_popupmenu" ),
197 m_actions( actions ), m_ownActions( static_cast<TQWidget *>( 0 ), "KonqPopupMenu::m_ownActions" ),
198 m_pMenuNew( newMenu ), m_sViewURL(viewURL), m_lstItems(items), m_pManager(mgr)
199{
200 KonqPopupFlags kpf = ( showProperties ? ShowProperties : IsLink ) | ShowNewWindow;
201 init(0, kpf, KParts::BrowserExtension::DefaultPopupItems);
202}
203
204KonqPopupMenu::KonqPopupMenu( KBookmarkManager *mgr, const KFileItemList &items,
205 KURL viewURL,
206 TDEActionCollection & actions,
207 KNewMenu * newMenu,
208 TQWidget * parentWidget,
209 bool showProperties )
210 : TQPopupMenu( parentWidget, "konq_popupmenu" ), m_actions( actions ), m_ownActions( static_cast<TQWidget *>( 0 ), "KonqPopupMenu::m_ownActions" ), m_pMenuNew( newMenu ), m_sViewURL(viewURL), m_lstItems(items), m_pManager(mgr)
211{
212 KonqPopupFlags kpf = ( showProperties ? ShowProperties : IsLink ) | ShowNewWindow;
213 init(parentWidget, kpf, KParts::BrowserExtension::DefaultPopupItems);
214}
215
216KonqPopupMenu::KonqPopupMenu( KBookmarkManager *mgr, const KFileItemList &items,
217 const KURL& viewURL,
218 TDEActionCollection & actions,
219 KNewMenu * newMenu,
220 TQWidget * parentWidget,
221 KonqPopupFlags kpf,
222 KParts::BrowserExtension::PopupFlags flags)
223 : TQPopupMenu( parentWidget, "konq_popupmenu" ), m_actions( actions ), m_ownActions( static_cast<TQWidget *>( 0 ), "KonqPopupMenu::m_ownActions" ), m_pMenuNew( newMenu ), m_sViewURL(viewURL), m_lstItems(items), m_pManager(mgr)
224{
225 init(parentWidget, kpf, flags);
226}
227
228void KonqPopupMenu::init (TQWidget * parentWidget, KonqPopupFlags kpf, KParts::BrowserExtension::PopupFlags flags)
229{
230 d = new KonqPopupMenuPrivate;
231 d->m_parentWidget = parentWidget;
232 d->m_itemFlags = flags;
233 setup(kpf);
234}
235
236int KonqPopupMenu::insertServicesSubmenus(const TQMap<TQString, ServiceList>& submenus,
237 TQDomElement& menu,
238 bool isBuiltin)
239{
240 int count = 0;
241 TQMap<TQString, ServiceList>::ConstIterator it;
242
243 for (it = submenus.begin(); it != submenus.end(); ++it)
244 {
245 if (it.data().isEmpty())
246 {
247 //avoid empty sub-menus
248 continue;
249 }
250
251 TQDomElement actionSubmenu = m_doc.createElement( "menu" );
252 actionSubmenu.setAttribute( "name", "actions " + it.key() );
253 menu.appendChild( actionSubmenu );
254 TQDomElement subtext = m_doc.createElement( "text" );
255 actionSubmenu.appendChild( subtext );
256 subtext.appendChild( m_doc.createTextNode( it.key() ) );
257 count += insertServices(it.data(), actionSubmenu, isBuiltin);
258 }
259
260 return count;
261}
262
263int KonqPopupMenu::insertServices(const ServiceList& list,
264 TQDomElement& menu,
265 bool isBuiltin)
266{
267 static int id = 1000;
268 int count = 0;
269
270 ServiceList::const_iterator it = list.begin();
271 for( ; it != list.end(); ++it )
272 {
273 if ((*it).isEmpty())
274 {
275 if (!menu.firstChild().isNull() &&
276 menu.lastChild().toElement().tagName().lower() != "separator")
277 {
278 TQDomElement separator = m_doc.createElement( "separator" );
279 menu.appendChild(separator);
280 }
281 continue;
282 }
283
284 if (isBuiltin || (*it).m_display == true)
285 {
286 TQCString name;
287 name.setNum( id );
288 name.prepend( isBuiltin ? "builtinservice_" : "userservice_" );
289 TDEAction * act = new TDEAction( TQString((*it).m_strName).replace('&',"&&"), 0,
290 this, TQ_SLOT( slotRunService() ),
291 &m_ownActions, name );
292
293 if ( !(*it).m_strIcon.isEmpty() )
294 {
295 TQPixmap pix = SmallIcon( (*it).m_strIcon );
296 act->setIconSet( pix );
297 }
298
299 addAction( act, menu ); // Add to toplevel menu
300
301 m_mapPopupServices[ id++ ] = *it;
302 ++count;
303 }
304 }
305
306 return count;
307}
308
309bool KonqPopupMenu::KIOSKAuthorizedAction(TDEConfig& cfg)
310{
311 if ( !cfg.hasKey( "X-TDE-AuthorizeAction") )
312 {
313 return true;
314 }
315
316 TQStringList list = cfg.readListEntry("X-TDE-AuthorizeAction");
317 if (tdeApp && !list.isEmpty())
318 {
319 for(TQStringList::ConstIterator it = list.begin();
320 it != list.end();
321 ++it)
322 {
323 if (!tdeApp->authorize((*it).stripWhiteSpace()))
324 {
325 return false;
326 }
327 }
328 }
329
330 return true;
331}
332
333
334void KonqPopupMenu::setup(KonqPopupFlags kpf)
335{
336 assert( m_lstItems.count() >= 1 );
337
338 m_ownActions.setWidget( this );
339
340 const bool bIsLink = (kpf & IsLink);
341 bool currentDir = false;
342 bool sReading = true;
343 bool sDeleting = ( d->m_itemFlags & KParts::BrowserExtension::NoDeletion ) == 0;
344 bool sMoving = sDeleting;
345 bool sWriting = sDeleting && m_lstItems.first()->isWritable();
346 m_sMimeType = m_lstItems.first()->mimetype();
347 TQString mimeGroup = m_sMimeType.left(m_sMimeType.find('/'));
348 mode_t mode = m_lstItems.first()->mode();
349 bool isDirectory = S_ISDIR(mode);
350 bool isMediaFile = false;
351 bool isEncryptedMediaFile = false;
352 bool isReallyLocal = m_lstItems.first()->isLocalFile();
353 bool isLocal = isReallyLocal || m_lstItems.first()->url().protocol()=="media" ||
354 m_lstItems.first()->url().protocol()=="system";
355 bool isTrashIncluded = false;
356 bool isTrashLink = false;
357 m_lstPopupURLs.clear();
358 int id = 0;
359 setFont(TDEGlobalSettings::menuFont());
360 m_pluginList.setAutoDelete( true );
361 m_ownActions.setHighlightingEnabled( true );
362
363 attrName = TQString::fromLatin1( "name" );
364
365 prepareXMLGUIStuff();
366 m_builder = new KonqPopupMenuGUIBuilder( this );
367 m_factory = new KXMLGUIFactory( m_builder );
368
369 KURL url;
370 KFileItemListIterator it ( m_lstItems );
371 TQStringList mimeTypeList;
372 // Check whether all URLs are correct
373 for ( ; it.current(); ++it )
374 {
375 url = (*it)->url();
376
377 // Build the list of URLs
378 m_lstPopupURLs.append( url );
379
380 // Determine if common mode among all URLs
381 if ( mode != (*it)->mode() )
382 mode = 0; // modes are different => reset to 0
383
384 // Determine if common mimetype among all URLs
385 if ( m_sMimeType != (*it)->mimetype() )
386 {
387 m_sMimeType = TQString::null; // mimetypes are different => null
388
389 if ( mimeGroup != (*it)->mimetype().left((*it)->mimetype().find('/')))
390 mimeGroup = TQString::null; // mimetype groups are different as well!
391 }
392
393 if ( mimeTypeList.findIndex( (*it)->mimetype() ) == -1 )
394 mimeTypeList << (*it)->mimetype();
395
396 if ( isReallyLocal && !url.isLocalFile() )
397 isReallyLocal = false;
398 if ( isLocal && !url.isLocalFile() && url.protocol() != "media" && url.protocol() != "system" )
399 isLocal = false;
400
401 if ( !isTrashIncluded && (
402 ( url.protocol() == "trash" && url.path().length() <= 1 )
403 || url.url() == "system:/trash" || url.url() == "system:/trash/" ) ) {
404 isTrashIncluded = true;
405 isLocal = false;
406 }
407
408 if ( sReading )
409 sReading = KProtocolInfo::supportsReading( url );
410
411 if ( sWriting )
412 sWriting = KProtocolInfo::supportsWriting( url ) && (*it)->isWritable();
413
414 if ( sDeleting )
415 sDeleting = KProtocolInfo::supportsDeleting( url );
416
417 if ( sMoving )
418 sMoving = KProtocolInfo::supportsMoving( url );
419 if ( (*it)->mimetype().startsWith("media/") ) {
420 isMediaFile = true;
421 if ( (*it)->mimetype().contains("encrypted")) {
422 isEncryptedMediaFile = true;
423 }
424 }
425 }
426
427 // If a local path is available, monitor that instead of the given remote URL...
428 KURL realURL = m_sViewURL;
429 if (!realURL.isLocalFile()) {
430 d->localURLSlotFired = false;
431 TDEIO::LocalURLJob* localURLJob = TDEIO::localURL(m_sViewURL);
432 if (localURLJob) {
433 connect(localURLJob, TQ_SIGNAL(localURL(TDEIO::LocalURLJob*, const KURL&, bool)), this, TQ_SLOT(slotLocalURL(TDEIO::LocalURLJob*, const KURL&, bool)));
434 connect(localURLJob, TQ_SIGNAL(destroyed()), this, TQ_SLOT(slotLocalURLKIODestroyed()));
435 while (!d->localURLSlotFired) {
436 tdeApp->eventLoop()->enterLoop();
437 }
438 if (d->localURLResultIsLocal) {
439 realURL = d->localURLResultURL;
440 }
441 }
442 }
443
444 url = realURL;
445 url.cleanPath();
446
447 //check if url is current directory
448 if ( m_lstItems.count() == 1 )
449 {
450 KURL firstPopupURL( m_lstItems.first()->url() );
451 firstPopupURL.cleanPath();
452 //kdDebug(1203) << "View path is " << url.url() << endl;
453 //kdDebug(1203) << "First popup path is " << firstPopupURL.url() << endl;
454 currentDir = firstPopupURL.equals( url, true /* ignore_trailing */, true /* ignore_internalReferenceURLS */ );
455 if ( isLocal && ((m_sMimeType == "application/x-desktop")
456 || (m_sMimeType == "media/builtin-mydocuments")
457 || (m_sMimeType == "media/builtin-mycomputer")
458 || (m_sMimeType == "media/builtin-mynetworkplaces")
459 || (m_sMimeType == "media/builtin-printers")
460 || (m_sMimeType == "media/builtin-trash")
461 || (m_sMimeType == "media/builtin-webbrowser")) ) {
462 KSimpleConfig cfg( firstPopupURL.path(), true );
463 cfg.setDesktopGroup();
464 isTrashLink = ( cfg.readEntry("Type") == "Link" && cfg.readEntry("URL") == "trash:/" );
465 }
466
467 if ( isTrashLink ) {
468 sDeleting = false;
469 }
470 }
471
472 m_info.m_Reading = sReading;
473 m_info.m_Writing = sWriting;
474 m_info.m_Deleting = sDeleting;
475 m_info.m_Moving = sMoving;
476 m_info.m_TrashIncluded = isTrashIncluded;
477
478 // isCurrentTrash: popup on trash:/ itself, or on the trash.desktop link
479 bool isCurrentTrash = ( m_lstItems.count() == 1 && isTrashIncluded ) || isTrashLink;
480 bool isIntoTrash = ( url.protocol() == "trash" || url.url().startsWith( "system:/trash" ) ) && !isCurrentTrash; // trashed file, not trash:/ itself
481 //kdDebug() << "isLocal=" << isLocal << " url=" << url << " isCurrentTrash=" << isCurrentTrash << " isIntoTrash=" << isIntoTrash << " isTrashIncluded=" << isTrashIncluded << endl;
482 clear();
483
485
486 TDEAction * act;
487
488 if (!isCurrentTrash)
489 addMerge( "konqueror" );
490
491 bool isKDesktop = TQCString( tdeApp->name() ) == "kdesktop";
492
493 if (( kpf & ShowProperties ) && isKDesktop &&
494 !tdeApp->authorize("editable_desktop_icons"))
495 {
496 kpf &= ~ShowProperties; // remove flag
497 }
498
499 // Either 'newview' is in the actions we're given (probably in the tabhandling group)
500 // or we need to insert it ourselves (e.g. for kdesktop). In the first case, actNewWindow must remain 0.
501 if ( ((kpf & ShowNewWindow) != 0) && sReading && !isEncryptedMediaFile)
502 {
503 TQString openStr = isKDesktop ? i18n( "&Open" ) : i18n( "Open in New &Window" );
504 TDEAction *actNewWindow = new TDEAction( openStr, "window-new", 0, this, TQ_SLOT( slotPopupNewView() ), &m_ownActions, "newview" );
505 actNewWindow->setToolTip( i18n( "Open item in a new window" ) );
506 addAction( actNewWindow );
507 addSeparator();
508 }
509
510 if ( S_ISDIR(mode) && sWriting && !isCurrentTrash ) // A dir, and we can create things into it
511 {
512 if ( currentDir && m_pMenuNew ) // Current dir -> add the "new" menu
513 {
514 // As requested by KNewMenu :
515 m_pMenuNew->slotCheckUpToDate();
516 m_pMenuNew->setPopupFiles( m_lstPopupURLs );
517
518 addAction( m_pMenuNew );
519
520 addSeparator();
521 }
522 else
523 {
524 if (d->m_itemFlags & KParts::BrowserExtension::ShowCreateDirectory)
525 {
526 TDEAction *actNewDir = new TDEAction( i18n( "Create &Folder..." ), "folder-new", 0, this, TQ_SLOT( slotPopupNewDir() ), &m_ownActions, "newdir" );
527 addAction( actNewDir );
528 addSeparator();
529 }
530 }
531 } else if ( isIntoTrash ) {
532 // Trashed item, offer restoring
533 act = new TDEAction( i18n( "&Restore" ), 0, this, TQ_SLOT( slotPopupRestoreTrashedItems() ), &m_ownActions, "restore" );
534 addAction( act );
535 }
536
537 if (d->m_itemFlags & KParts::BrowserExtension::ShowNavigationItems)
538 {
539 if (d->m_itemFlags & KParts::BrowserExtension::ShowUp)
540 addAction( "up" );
541 addAction( "back" );
542 addAction( "forward" );
543 if (d->m_itemFlags & KParts::BrowserExtension::ShowReload)
544 addAction( "reload" );
545 addSeparator();
546 }
547
548 if (!isEncryptedMediaFile)
549 {
550 addGroup( "tabhandling" ); // includes a separator
551 }
552
553 if ( !bIsLink )
554 {
555 if ( !currentDir && sReading ) {
556 if ( sDeleting ) {
557 addAction( "cut" );
558 }
559 addAction( "copy" );
560 }
561
562 if ( S_ISDIR(mode) && sWriting ) {
563 if ( currentDir )
564 addAction( "paste" );
565 else
566 addAction( "pasteto" );
567 }
568 if ( !currentDir )
569 {
570 if ( m_lstItems.count() == 1 && sMoving )
571 addAction( "rename" );
572
573 bool addTrash = false;
574 bool addDel = false;
575
576 if ( sMoving && !isIntoTrash && !isTrashLink )
577 addTrash = true;
578
579 if ( sDeleting ) {
580 if ( !isLocal )
581 addDel = true;
582 else if (TDEApplication::keyboardMouseState() & TQt::ShiftButton) {
583 addTrash = false;
584 addDel = true;
585 }
586 else {
587 TDEConfigGroup configGroup( tdeApp->config(), "KDE" );
588 if ( configGroup.readBoolEntry( "ShowDeleteCommand", false ) )
589 addDel = true;
590 }
591 }
592
593 if ( addTrash )
594 addAction( "trash" );
595 if ( addDel )
596 addAction( "del" );
597 }
598 }
599 if ( isCurrentTrash )
600 {
601 act = new TDEAction( i18n( "&Empty Trash Bin" ), "emptytrash", 0, this, TQ_SLOT( slotPopupEmptyTrashBin() ), &m_ownActions, "empytrash" );
602 KSimpleConfig trashConfig( "trashrc", true );
603 trashConfig.setGroup( "Status" );
604 act->setEnabled( !trashConfig.readBoolEntry( "Empty", true ) );
605 addAction( act );
606 }
607 addGroup( "editactions" );
608
609 if (d->m_itemFlags & KParts::BrowserExtension::ShowTextSelectionItems) {
610 addMerge( 0 );
611 m_factory->addClient( this );
612 return;
613 }
614
615 if ( !isCurrentTrash && !isIntoTrash && (d->m_itemFlags & KParts::BrowserExtension::ShowBookmark))
616 {
617 addSeparator();
618 TQString caption;
619 if (currentDir)
620 {
621 bool httpPage = (m_sViewURL.protocol().find("http", 0, false) == 0);
622 if (httpPage)
623 caption = i18n("&Bookmark This Page");
624 else
625 caption = i18n("&Bookmark This Location");
626 }
627 else if (S_ISDIR(mode))
628 caption = i18n("&Bookmark This Folder");
629 else if (bIsLink)
630 caption = i18n("&Bookmark This Link");
631 else
632 caption = i18n("&Bookmark This File");
633
634 act = new TDEAction( caption, "bookmark_add", 0, this, TQ_SLOT( slotPopupAddToBookmark() ), &m_ownActions, "bookmark_add" );
635 if (m_lstItems.count() > 1)
636 act->setEnabled(false);
637 if (tdeApp->authorizeTDEAction("bookmarks"))
638 addAction( act );
639 if (bIsLink)
640 addGroup( "linkactions" );
641 }
642
644
645 const bool isSingleLocal = m_lstItems.count() == 1 && isLocal;
646 PopupServices s;
647 KURL urlForServiceMenu( m_lstItems.first()->url() );
648 if (isLocal && !isReallyLocal) { // media or system
649 bool dummy;
650 urlForServiceMenu = m_lstItems.first()->mostLocalURL(dummy);
651 }
652
653 // 1 - Look for builtin and user-defined services
654 if ( ((m_sMimeType == "application/x-desktop")
655 || (m_sMimeType == "media/builtin-mydocuments")
656 || (m_sMimeType == "media/builtin-mycomputer")
657 || (m_sMimeType == "media/builtin-mynetworkplaces")
658 || (m_sMimeType == "media/builtin-printers")
659 || (m_sMimeType == "media/builtin-trash")
660 || (m_sMimeType == "media/builtin-webbrowser")) && isSingleLocal ) // .desktop file
661 {
662 // get builtin services, like mount/unmount
663 s.builtin = KDEDesktopMimeType::builtinServices( urlForServiceMenu );
664 const TQString path = urlForServiceMenu.path();
665 KSimpleConfig cfg( path, true );
666 cfg.setDesktopGroup();
667 const TQString priority = cfg.readEntry("X-TDE-Priority");
668 const TQString submenuName = cfg.readEntry( "X-TDE-Submenu" );
669 if ( cfg.readEntry("Type") == "Link" ) {
670 urlForServiceMenu = cfg.readEntry("URL");
671 // TODO: Do we want to make all the actions apply on the target
672 // of the .desktop file instead of the .desktop file itself?
673 }
674 ServiceList* list = s.selectList( priority, submenuName );
675 (*list) = KDEDesktopMimeType::userDefinedServices( path, cfg, urlForServiceMenu.isLocalFile() );
676 }
677
678 if ( sReading )
679 {
680
681 // 2 - Look for "servicesmenus" bindings (konqueror-specific user-defined services)
682
683 // first check the .directory if this is a directory
684 if (isDirectory && isSingleLocal)
685 {
686 TQString dotDirectoryFile = urlForServiceMenu.path(1).append(".directory");
687 KSimpleConfig cfg( dotDirectoryFile, true );
688 cfg.setDesktopGroup();
689
690 if (KIOSKAuthorizedAction(cfg))
691 {
692 const TQString priority = cfg.readEntry("X-TDE-Priority");
693 const TQString submenuName = cfg.readEntry( "X-TDE-Submenu" );
694 ServiceList* list = s.selectList( priority, submenuName );
695 (*list) += KDEDesktopMimeType::userDefinedServices( dotDirectoryFile, cfg, true );
696 }
697 }
698
699 // findAllResources() also removes duplicates
700 TQStringList entries = TDEGlobal::dirs()->findAllResources("data",
701 "konqueror/servicemenus/*.desktop", false, true);
702 entries.sort(); // sort to ensure consistent order in popup menu
703 TQStringList::ConstIterator eIt = entries.begin();
704 const TQStringList::ConstIterator eEnd = entries.end();
705 for (; eIt != eEnd; ++eIt )
706 {
707 KSimpleConfig cfg( *eIt, true );
708 cfg.setDesktopGroup();
709
710 if (!KIOSKAuthorizedAction(cfg))
711 {
712 continue;
713 }
714
715 if ( cfg.hasKey( "X-TDE-ShowIfRunning" ) )
716 {
717 const TQString app = cfg.readEntry( "X-TDE-ShowIfRunning" );
718 if ( !tdeApp->dcopClient()->isApplicationRegistered( app.utf8() ) )
719 continue;
720 }
721 if ( cfg.hasKey( "X-TDE-ShowIfDcopCall" ) )
722 {
723 TQString dcopcall = cfg.readEntry( "X-TDE-ShowIfDcopCall" );
724 const TQCString app = TQString(dcopcall.section(' ', 0,0)).utf8();
725
726 //if( !tdeApp->dcopClient()->isApplicationRegistered( app ))
727 // continue; //app does not exist so cannot send call
728
729 TQByteArray dataToSend;
730 TQDataStream dataStream(dataToSend, IO_WriteOnly);
731 dataStream << m_lstPopupURLs;
732
733 TQCString replyType;
734 TQByteArray replyData;
735 TQCString object = TQString(dcopcall.section(' ', 1,-2)).utf8();
736 TQString function = TQString(dcopcall.section(' ', -1));
737 if(!function.endsWith("(KURL::List)")) {
738 kdWarning() << "Desktop file " << *eIt << " contains an invalid X-TDE-ShowIfDcopCall - the function must take the exact parameter (KURL::List) and must be specified." << endl;
739 continue; //Be safe.
740 }
741
742 if(!tdeApp->dcopClient()->call( app, object,
743 function.utf8(),
744 dataToSend, replyType, replyData, true, 1000))
745 continue;
746 if(replyType != "bool" || !replyData[0])
747 continue;
748
749 }
750 if ( cfg.hasKey( "X-TDE-Protocol" ) )
751 {
752 const TQString protocol = cfg.readEntry( "X-TDE-Protocol" );
753 if ( protocol != urlForServiceMenu.protocol() )
754 continue;
755 }
756 else if ( cfg.hasKey( "X-TDE-Protocols" ) )
757 {
758 TQStringList protocols = TQStringList::split( "," , cfg.readEntry( "X-TDE-Protocols" ) );
759 if ( !protocols.contains( urlForServiceMenu.protocol() ) )
760 continue;
761 }
762 else if ( urlForServiceMenu.protocol() == "trash" || urlForServiceMenu.url().startsWith( "system:/trash" ) )
763 {
764 // Require servicemenus for the trash to ask for protocol=trash explicitely.
765 // Trashed files aren't supposed to be available for actions.
766 // One might want a servicemenu for trash.desktop itself though.
767 continue;
768 }
769
770 if ( cfg.hasKey( "X-TDE-Require" ) )
771 {
772 const TQStringList capabilities = cfg.readListEntry( "X-TDE-Require" );
773 if ( capabilities.contains( "Write" ) && !sWriting )
774 continue;
775 }
776 if ( (cfg.hasKey( "Actions" ) || cfg.hasKey( "X-TDE-GetActionMenu") ) && cfg.hasKey( "X-TDE-ServiceTypes" ) )
777 {
778 const TQStringList types = cfg.readListEntry( "X-TDE-ServiceTypes" );
779 const TQStringList excludeTypes = cfg.readListEntry( "X-TDE-ExcludeServiceTypes" );
780 bool ok = false;
781
782 // check for exact matches or a typeglob'd mimetype if we have a mimetype
783 for (TQStringList::ConstIterator it = types.begin();
784 it != types.end() && !ok;
785 ++it)
786 {
787 // first check if we have an all mimetype
788 bool checkTheMimetypes = false;
789 if (*it == "all/all" ||
790 *it == "allfiles" /*compat with KDE up to 3.0.3*/)
791 {
792 checkTheMimetypes = true;
793 }
794
795 // next, do we match all files?
796 if (!ok &&
797 !isDirectory &&
798 *it == "all/allfiles")
799 {
800 checkTheMimetypes = true;
801 }
802
803 // if we have a mimetype, see if we have an exact or a type globbed match
804 if ((!ok &&
805 (!m_sMimeType.isEmpty() &&
806 *it == m_sMimeType)) ||
807 (!mimeGroup.isEmpty() &&
808 (((*it).right(1) == "*") &&
809 (*it).left((*it).find('/')) == mimeGroup)))
810 {
811 checkTheMimetypes = true;
812 }
813
814 if (checkTheMimetypes)
815 {
816 ok = true;
817 for (TQStringList::ConstIterator itex = excludeTypes.begin(); itex != excludeTypes.end(); ++itex)
818 {
819 if( ((*itex).right(1) == "*" && (*itex).left((*itex).find('/')) == mimeGroup) ||
820 ((*itex) == m_sMimeType) )
821 {
822 ok = false;
823 break;
824 }
825 }
826 }
827 }
828
829 if ( ok )
830 {
831 const TQString priority = cfg.readEntry("X-TDE-Priority");
832 const TQString submenuName = cfg.readEntry( "X-TDE-Submenu" );
833
834 ServiceList *list = s.selectList( priority, submenuName );
835 (*list) += KDEDesktopMimeType::userDefinedServices( *eIt, cfg, url.isLocalFile(), m_lstPopupURLs );
836 }
837 }
838 }
839
840 TDETrader::OfferList offers;
841
842 if (tdeApp->authorizeTDEAction("openwith"))
843 {
844 TQString constraint = "Type == 'Application' and DesktopEntryName != 'kfmclient' and DesktopEntryName != 'kfmclient_dir' and DesktopEntryName != 'kfmclient_html'";
845 TQString subConstraint = " and '%1' in ServiceTypes";
846
847 TQStringList::ConstIterator it = mimeTypeList.begin();
848 TQStringList::ConstIterator end = mimeTypeList.end();
849 Q_ASSERT( it != end );
850 TQString first = *it;
851 ++it;
852 while ( it != end ) {
853 constraint += subConstraint.arg( *it );
854 ++it;
855 }
856
857 offers = TDETrader::self()->query( first, constraint );
858 }
859
861
862 m_mapPopup.clear();
863 m_mapPopupServices.clear();
864 // "Open With..." for folders is really not very useful, especially for remote folders.
865 // (media:/something, or trash:/, or ftp://...)
866 if ( !isDirectory || isLocal )
867 {
868 if ( hasAction() )
869 addSeparator();
870
871 if ( !offers.isEmpty() )
872 {
873 // First block, app and preview offers
874 id = 1;
875
876 TQDomElement menu = m_menuElement;
877
878 if ( offers.count() > 1 ) // submenu 'open with'
879 {
880 menu = m_doc.createElement( "menu" );
881 menu.setAttribute( "name", "openwith submenu" );
882 m_menuElement.appendChild( menu );
883 TQDomElement text = m_doc.createElement( "text" );
884 menu.appendChild( text );
885 text.appendChild( m_doc.createTextNode( i18n("&Open With") ) );
886 }
887
888 TDETrader::OfferList::ConstIterator it = offers.begin();
889 for( ; it != offers.end(); it++ )
890 {
891 KService::Ptr service = (*it);
892
893 // Skip OnlyShowIn=Foo and NotShowIn=TDE entries,
894 // but still offer NoDisplay=true entries, that's the
895 // whole point of such desktop files. This is why we don't
896 // use service->noDisplay() here.
897 const TQString onlyShowIn = service->property("OnlyShowIn", TQVariant::String).toString();
898 if ( !onlyShowIn.isEmpty() ) {
899 const TQStringList aList = TQStringList::split(';', onlyShowIn);
900 if (!aList.contains("TDE"))
901 continue;
902 }
903 const TQString notShowIn = service->property("NotShowIn", TQVariant::String).toString();
904 if ( !notShowIn.isEmpty() ) {
905 const TQStringList aList = TQStringList::split(';', notShowIn);
906 if (aList.contains("TDE"))
907 continue;
908 }
909
910 TQCString nam;
911 nam.setNum( id );
912
913 TQString actionName( (*it)->name().replace("&", "&&") );
914 if ( menu == m_menuElement ) // no submenu -> prefix single offer
915 actionName = i18n( "Open with %1" ).arg( actionName );
916
917 act = new TDEAction( actionName, (*it)->pixmap( TDEIcon::Small ), 0,
918 this, TQ_SLOT( slotRunService() ),
919 &m_ownActions, nam.prepend( "appservice_" ) );
920 addAction( act, menu );
921
922 m_mapPopup[ id++ ] = *it;
923 }
924
925 TQString openWithActionName;
926 if ( menu != m_menuElement ) // submenu
927 {
928 addSeparator( menu );
929 openWithActionName = i18n( "&Other..." );
930 }
931 else
932 {
933 openWithActionName = i18n( "&Open With..." );
934 }
935 TDEAction *openWithAct = new TDEAction( openWithActionName, 0, this, TQ_SLOT( slotPopupOpenWith() ), &m_ownActions, "openwith" );
936 addAction( openWithAct, menu );
937 }
938 else // no app offers -> Open With...
939 {
940 act = new TDEAction( i18n( "&Open With..." ), 0, this, TQ_SLOT( slotPopupOpenWith() ), &m_ownActions, "openwith" );
941 addAction( act );
942 }
943
944 }
945 addGroup( "preview" );
946 }
947
948 // Second block, builtin + user
949 TQDomElement actionMenu = m_menuElement;
950 int userItemCount = 0;
951 if (s.user.count() + s.userSubmenus.count() +
952 s.userPriority.count() + s.userPrioritySubmenus.count() > 1)
953 {
954 // we have more than one item, so let's make a submenu
955 actionMenu = m_doc.createElement( "menu" );
956 actionMenu.setAttribute( "name", "actions submenu" );
957 m_menuElement.appendChild( actionMenu );
958 TQDomElement text = m_doc.createElement( "text" );
959 actionMenu.appendChild( text );
960 text.appendChild( m_doc.createTextNode( i18n("Ac&tions") ) );
961 }
962
963 userItemCount += insertServicesSubmenus(s.userPrioritySubmenus, actionMenu, false);
964 userItemCount += insertServices(s.userPriority, actionMenu, false);
965
966 // see if we need to put a separator between our priority items and our regular items
967 if (userItemCount > 0 &&
968 (s.user.count() > 0 ||
969 s.userSubmenus.count() > 0 ||
970 s.builtin.count() > 0) &&
971 actionMenu.lastChild().toElement().tagName().lower() != "separator")
972 {
973 TQDomElement separator = m_doc.createElement( "separator" );
974 actionMenu.appendChild(separator);
975 }
976
977 userItemCount += insertServicesSubmenus(s.userSubmenus, actionMenu, false);
978 userItemCount += insertServices(s.user, actionMenu, false);
979 userItemCount += insertServices(s.builtin, m_menuElement, true);
980
981 userItemCount += insertServicesSubmenus(s.userToplevelSubmenus, m_menuElement, false);
982 userItemCount += insertServices(s.userToplevel, m_menuElement, false);
983
984 if ( userItemCount > 0 )
985 {
986 addPendingSeparator();
987 }
988
989 if ( !isCurrentTrash && !isIntoTrash && !isMediaFile && sReading )
990 addPlugins(); // now it's time to add plugins
991
992 if ( KPropertiesDialog::canDisplay( m_lstItems ) && (kpf & ShowProperties) )
993 {
994 act = new TDEAction( i18n( "&Properties" ), "edit", 0, this, TQ_SLOT( slotPopupProperties() ),
995 &m_ownActions, "properties" );
996 addAction( act );
997 }
998
999 while ( !m_menuElement.lastChild().isNull() &&
1000 m_menuElement.lastChild().toElement().tagName().lower() == "separator" )
1001 m_menuElement.removeChild( m_menuElement.lastChild() );
1002
1003 if ( isDirectory && isLocal )
1004 {
1005 if ( KFileShare::authorization() == KFileShare::Authorized )
1006 {
1007 addSeparator();
1008 act = new TDEAction( i18n("Share"), 0, this, TQ_SLOT( slotOpenShareFileDialog() ),
1009 &m_ownActions, "sharefile" );
1010 addAction( act );
1011 }
1012 }
1013
1014 addMerge( 0 );
1015 //kdDebug() << k_funcinfo << domDocument().toString() << endl;
1016
1017 m_factory->addClient( this );
1018}
1019
1020void KonqPopupMenu::slotOpenShareFileDialog()
1021{
1022 KPropertiesDialog* dlg = showPropertiesDialog();
1023 dlg->showFileSharingPage();
1024}
1025
1026KonqPopupMenu::~KonqPopupMenu()
1027{
1028 m_pluginList.clear();
1029 delete m_factory;
1030 delete m_builder;
1031 delete d;
1032 //kdDebug(1203) << "~KonqPopupMenu leave" << endl;
1033}
1034
1035void KonqPopupMenu::setURLTitle( const TQString& urlTitle )
1036{
1037 d->m_urlTitle = urlTitle;
1038}
1039
1040void KonqPopupMenu::slotPopupNewView()
1041{
1042 KURL::List::ConstIterator it = m_lstPopupURLs.begin();
1043 for ( ; it != m_lstPopupURLs.end(); it++ )
1044 (void) new KRun(*it);
1045}
1046
1047void KonqPopupMenu::slotPopupNewDir()
1048{
1049 if (m_lstPopupURLs.empty())
1050 return;
1051
1052 KonqOperations::newDir(d->m_parentWidget, m_lstPopupURLs.first());
1053}
1054
1055void KonqPopupMenu::slotPopupEmptyTrashBin()
1056{
1057 KonqOperations::emptyTrash();
1058}
1059
1060void KonqPopupMenu::slotPopupRestoreTrashedItems()
1061{
1062 KonqOperations::restoreTrashedItems( m_lstPopupURLs );
1063}
1064
1065void KonqPopupMenu::slotPopupOpenWith()
1066{
1067 KRun::displayOpenWithDialog( m_lstPopupURLs );
1068}
1069
1070void KonqPopupMenu::slotPopupAddToBookmark()
1071{
1072 KBookmarkGroup root;
1073 if ( m_lstPopupURLs.count() == 1 ) {
1074 KURL url = m_lstPopupURLs.first();
1075 TQString title = d->m_urlTitle.isEmpty() ? url.prettyURL() : d->m_urlTitle;
1076 root = m_pManager->addBookmarkDialog( url.prettyURL(), title );
1077 }
1078 else
1079 {
1080 root = m_pManager->root();
1081 KURL::List::ConstIterator it = m_lstPopupURLs.begin();
1082 for ( ; it != m_lstPopupURLs.end(); it++ )
1083 root.addBookmark( m_pManager, (*it).prettyURL(), (*it) );
1084 }
1085 m_pManager->emitChanged( root );
1086}
1087
1088void KonqPopupMenu::slotRunService()
1089{
1090 TQCString senderName = sender()->name();
1091 int id = senderName.mid( senderName.find( '_' ) + 1 ).toInt();
1092
1093 // Is it a usual service (application)
1094 TQMap<int,KService::Ptr>::Iterator it = m_mapPopup.find( id );
1095 if ( it != m_mapPopup.end() )
1096 {
1097 KRun::run( **it, m_lstPopupURLs );
1098 return;
1099 }
1100
1101 // Is it a service specific to desktop entry files ?
1102 TQMap<int,KDEDesktopMimeType::Service>::Iterator it2 = m_mapPopupServices.find( id );
1103 if ( it2 != m_mapPopupServices.end() )
1104 {
1105 KDEDesktopMimeType::executeService( m_lstPopupURLs, it2.data() );
1106 }
1107
1108 return;
1109}
1110
1111void KonqPopupMenu::slotPopupMimeType()
1112{
1113 KonqOperations::editMimeType( m_sMimeType );
1114}
1115
1116void KonqPopupMenu::slotPopupProperties()
1117{
1118 (void)showPropertiesDialog();
1119}
1120
1121KPropertiesDialog* KonqPopupMenu::showPropertiesDialog()
1122{
1123 // It may be that the tdefileitem was created by hand
1124 // (see KonqKfmIconView::slotMouseButtonPressed)
1125 // In that case, we can get more precise info in the properties
1126 // (like permissions) if we stat the URL.
1127 if ( m_lstItems.count() == 1 )
1128 {
1129 KFileItem * item = m_lstItems.first();
1130 if (item->entry().count() == 0) // this item wasn't listed by a slave
1131 {
1132 // KPropertiesDialog will use stat to get more info on the file
1133 return new KPropertiesDialog( item->url(), d->m_parentWidget );
1134 }
1135 }
1136 return new KPropertiesDialog( m_lstItems, d->m_parentWidget );
1137}
1138
1139TDEAction *KonqPopupMenu::action( const TQDomElement &element ) const
1140{
1141 TQCString name = element.attribute( attrName ).ascii();
1142 TDEAction *res = m_ownActions.action( static_cast<const char *>(name) );
1143
1144 if ( !res )
1145 res = m_actions.action( static_cast<const char *>(name) );
1146
1147 if ( !res && m_pMenuNew && strcmp( name, m_pMenuNew->name() ) == 0 )
1148 return m_pMenuNew;
1149
1150 return res;
1151}
1152
1153TDEActionCollection *KonqPopupMenu::actionCollection() const
1154{
1155 return const_cast<TDEActionCollection *>( &m_ownActions );
1156}
1157
1158TQString KonqPopupMenu::mimeType() const
1159{
1160 return m_sMimeType;
1161}
1162
1163KonqPopupMenu::ProtocolInfo KonqPopupMenu::protocolInfo() const
1164{
1165 return m_info;
1166}
1167
1168void KonqPopupMenu::addPlugins()
1169{
1170 // search for Konq_PopupMenuPlugins inspired by simons kpropsdlg
1171 //search for a plugin with the right protocol
1172 TDETrader::OfferList plugin_offers;
1173 unsigned int pluginCount = 0;
1174 plugin_offers = TDETrader::self()->query( m_sMimeType.isNull() ? TQString::fromLatin1( "all/all" ) : m_sMimeType, "'KonqPopupMenu/Plugin' in ServiceTypes");
1175 if ( plugin_offers.isEmpty() )
1176 return; // no plugins installed do not bother about it
1177
1178 TDETrader::OfferList::ConstIterator iterator = plugin_offers.begin();
1179 TDETrader::OfferList::ConstIterator end = plugin_offers.end();
1180
1181 addGroup( "plugins" );
1182 // travers the offerlist
1183 for(; iterator != end; ++iterator, ++pluginCount ) {
1184 //kdDebug() << (*iterator)->library() << endl;
1185 KonqPopupMenuPlugin *plugin =
1186 KParts::ComponentFactory::
1187 createInstanceFromLibrary<KonqPopupMenuPlugin>( TQFile::encodeName( (*iterator)->library() ),
1188 this,
1189 (*iterator)->name().latin1() );
1190 if ( !plugin )
1191 continue;
1192 // This make the kuick plugin insert its stuff above "Properties"
1193 TQString pluginClientName = TQString::fromLatin1( "Plugin%1" ).arg( pluginCount );
1194 addMerge( pluginClientName );
1195 plugin->domDocument().documentElement().setAttribute( "name", pluginClientName );
1196 m_pluginList.append( plugin );
1197 insertChildClient( plugin );
1198 }
1199
1200 // ## Where is this used?
1201 addMerge( "plugins" );
1202}
1203
1204KURL KonqPopupMenu::url() const // ### should be viewURL()
1205{
1206 return m_sViewURL;
1207}
1208
1209KFileItemList KonqPopupMenu::fileItemList() const
1210{
1211 return m_lstItems;
1212}
1213
1214KURL::List KonqPopupMenu::popupURLList() const
1215{
1216 return m_lstPopupURLs;
1217}
1218
1219void KonqPopupMenu::slotLocalURL(TDEIO::LocalURLJob *job, const KURL& url, bool isLocal)
1220{
1221 d->localURLSlotFired = true;
1222 d->localURLResultURL = url;
1223 d->localURLResultIsLocal = isLocal;
1224 tdeApp->eventLoop()->exitLoop();
1225}
1226
1227void KonqPopupMenu::slotLocalURLKIODestroyed()
1228{
1229 if (!d->localURLSlotFired) {
1230 d->localURLSlotFired = true;
1231 d->localURLResultURL = KURL();
1232 d->localURLResultIsLocal = false;
1233 tdeApp->eventLoop()->exitLoop();
1234 }
1235}
1236
1241KonqPopupMenuPlugin::KonqPopupMenuPlugin( KonqPopupMenu *parent, const char *name )
1242 : TQObject( parent, name )
1243{
1244}
1245
1246KonqPopupMenuPlugin::~KonqPopupMenuPlugin()
1247{
1248}
1249
1250#include "konq_popupmenu.moc"
KNewMenu
The 'New' submenu, both for the File menu and the RMB popup menu.
Definition: knewmenu.h:53
KNewMenu::slotCheckUpToDate
void slotCheckUpToDate()
Checks if updating the list is necessary IMPORTANT : Call this in the slot for aboutToShow.
Definition: knewmenu.cpp:99
KNewMenu::setPopupFiles
void setPopupFiles(KURL::List &_files)
Set the files the popup is shown for Call this before showing up the menu.
Definition: knewmenu.h:68
KonqOperations::newDir
static void newDir(TQWidget *parent, const KURL &baseURL)
Ask for the name of a new directory and create it.
Definition: konq_operations.cpp:733
KonqOperations::editMimeType
static void editMimeType(const TQString &mimeType)
Pop up properties dialog for mimetype mimeType.
Definition: konq_operations.cpp:77
KonqPopupMenu
This class implements the popup menu for URLs in konqueror and kdesktop It's usage is very simple : o...
Definition: konq_popupmenu.h:57
KonqPopupMenu::setURLTitle
void setURLTitle(const TQString &urlTitle)
Set the title of the URL, when the popupmenu is opened for a single URL.
Definition: konq_popupmenu.cpp:1035
KonqPopupMenu::ShowProperties
@ ShowProperties
whether to show the "Properties" menu item
Definition: konq_popupmenu.h:67
KonqPopupMenu::IsLink
@ IsLink
HTML link. If set, we won't have cut/copy/paste, and we'll say "bookmark this link".
Definition: konq_popupmenu.h:68
KonqPopupMenu::~KonqPopupMenu
~KonqPopupMenu()
Don't forget to destroy the object.
Definition: konq_popupmenu.cpp:1026
KonqPopupMenu::action
virtual TDEAction * action(const TQDomElement &element) const
Reimplemented for internal purpose.
Definition: konq_popupmenu.cpp:1139
KonqPopupMenu::KonqPopupFlags
uint KonqPopupFlags
Flags set by the calling application (konqueror/kdesktop), unlike KParts::BrowserExtension::PopupFlag...
Definition: konq_popupmenu.h:65
KonqPopupMenu::KonqPopupMenu
KonqPopupMenu(KBookmarkManager *manager, const KFileItemList &items, KURL viewURL, TDEActionCollection &actions, KNewMenu *newMenu, bool showPropertiesAndFileType=true) TDE_DEPRECATED
Definition: konq_popupmenu.cpp:191
KonqXMLGUIClient::addPendingSeparator
void addPendingSeparator()
only add a separator if an action is added afterwards
Definition: konq_xmlguiclient.cpp:147

libkonq

Skip menu "libkonq"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

libkonq

Skip menu "libkonq"
  • kate
  • libkonq
  • twin
  •   lib
Generated for libkonq by doxygen 1.9.4
This website is maintained by Timothy Pearson.