konq_popupmenu.cc
00001 /* This file is part of the KDE project 00002 Copyright (C) 1998, 1999 David Faure <faure@kde.org> 00003 Copyright (C) 2001 Holger Freyther <freyther@yahoo.com> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include <tqdir.h> 00022 #include <tqeventloop.h> 00023 00024 #include <tdelocale.h> 00025 #include <tdeapplication.h> 00026 #include <kbookmarkmanager.h> 00027 #include <kdebug.h> 00028 #include <krun.h> 00029 #include <kprotocolinfo.h> 00030 #include <kiconloader.h> 00031 #include <kinputdialog.h> 00032 #include <tdeglobalsettings.h> 00033 #include <kstandarddirs.h> 00034 #include <kxmlguifactory.h> 00035 #include <kxmlguibuilder.h> 00036 #include <tdeparts/componentfactory.h> 00037 00038 #include <assert.h> 00039 00040 #include <tdefileshare.h> 00041 #include <kprocess.h> 00042 00043 #include "kpropertiesdialog.h" 00044 #include "knewmenu.h" 00045 #include "konq_popupmenu.h" 00046 #include "konq_operations.h" 00047 #include "konq_xmlguiclient.h" 00048 #include <dcopclient.h> 00049 00050 /* 00051 Test cases: 00052 iconview file: background 00053 iconview file: file (with and without servicemenus) 00054 iconview file: directory 00055 iconview remote protocol (e.g. ftp: or fish:) 00056 iconview trash:/ 00057 sidebar directory tree 00058 sidebar Devices / Hard Disc 00059 tdehtml background 00060 tdehtml link 00061 tdehtml image (www.kde.org RMB on K logo) 00062 tdehtmlimage (same as above, then choose View image, then RMB) 00063 selected text in tdehtml 00064 embedded katepart 00065 kdesktop folder 00066 trash link on desktop 00067 trashed file or directory 00068 application .desktop file 00069 Then the same after uninstalling tdeaddons/konq-plugins (kuick and arkplugin in particular) 00070 */ 00071 00072 class KonqPopupMenuGUIBuilder : public KXMLGUIBuilder 00073 { 00074 public: 00075 KonqPopupMenuGUIBuilder( TQPopupMenu *menu ) 00076 : KXMLGUIBuilder( 0 ) 00077 { 00078 m_menu = menu; 00079 } 00080 virtual ~KonqPopupMenuGUIBuilder() 00081 { 00082 } 00083 00084 virtual TQWidget *createContainer( TQWidget *parent, int index, 00085 const TQDomElement &element, 00086 int &id ) 00087 { 00088 if ( !parent && element.attribute( "name" ) == "popupmenu" ) 00089 return m_menu; 00090 00091 return KXMLGUIBuilder::createContainer( parent, index, element, id ); 00092 } 00093 00094 TQPopupMenu *m_menu; 00095 }; 00096 00097 class KonqPopupMenu::KonqPopupMenuPrivate 00098 { 00099 public: 00100 KonqPopupMenuPrivate() : m_parentWidget( 0 ), 00101 m_itemFlags( KParts::BrowserExtension::DefaultPopupItems ) 00102 { 00103 } 00104 TQString m_urlTitle; 00105 TQWidget *m_parentWidget; 00106 KParts::BrowserExtension::PopupFlags m_itemFlags; 00107 00108 bool localURLSlotFired; 00109 KURL localURLResultURL; 00110 bool localURLResultIsLocal; 00111 }; 00112 00113 KonqPopupMenu::ProtocolInfo::ProtocolInfo() 00114 { 00115 m_Reading = false; 00116 m_Writing = false; 00117 m_Deleting = false; 00118 m_Moving = false; 00119 m_TrashIncluded = false; 00120 } 00121 00122 bool KonqPopupMenu::ProtocolInfo::supportsReading() const 00123 { 00124 return m_Reading; 00125 } 00126 00127 bool KonqPopupMenu::ProtocolInfo::supportsWriting() const 00128 { 00129 return m_Writing; 00130 } 00131 00132 bool KonqPopupMenu::ProtocolInfo::supportsDeleting() const 00133 { 00134 return m_Deleting; 00135 } 00136 00137 bool KonqPopupMenu::ProtocolInfo::supportsMoving() const 00138 { 00139 return m_Moving; 00140 } 00141 00142 bool KonqPopupMenu::ProtocolInfo::trashIncluded() const 00143 { 00144 return m_TrashIncluded; 00145 } 00146 00147 // This helper class stores the .desktop-file actions and the servicemenus 00148 // in order to support X-TDE-Priority and X-TDE-Submenu. 00149 class PopupServices 00150 { 00151 public: 00152 ServiceList* selectList( const TQString& priority, const TQString& submenuName ); 00153 00154 ServiceList builtin; 00155 ServiceList user, userToplevel, userPriority; 00156 TQMap<TQString, ServiceList> userSubmenus, userToplevelSubmenus, userPrioritySubmenus; 00157 }; 00158 00159 ServiceList* PopupServices::selectList( const TQString& priority, const TQString& submenuName ) 00160 { 00161 // we use the categories .desktop entry to define submenus 00162 // if none is defined, we just pop it in the main menu 00163 if (submenuName.isEmpty()) 00164 { 00165 if (priority == "TopLevel") 00166 { 00167 return &userToplevel; 00168 } 00169 else if (priority == "Important") 00170 { 00171 return &userPriority; 00172 } 00173 } 00174 else if (priority == "TopLevel") 00175 { 00176 return &(userToplevelSubmenus[submenuName]); 00177 } 00178 else if (priority == "Important") 00179 { 00180 return &(userPrioritySubmenus[submenuName]); 00181 } 00182 else 00183 { 00184 return &(userSubmenus[submenuName]); 00185 } 00186 return &user; 00187 } 00188 00190 00191 KonqPopupMenu::KonqPopupMenu( KBookmarkManager *mgr, const KFileItemList &items, 00192 KURL viewURL, 00193 TDEActionCollection & actions, 00194 KNewMenu * newMenu, 00195 bool showProperties ) 00196 : TQPopupMenu( 0L, "konq_popupmenu" ), 00197 m_actions( actions ), m_ownActions( static_cast<TQWidget *>( 0 ), "KonqPopupMenu::m_ownActions" ), 00198 m_pMenuNew( newMenu ), m_sViewURL(viewURL), m_lstItems(items), m_pManager(mgr) 00199 { 00200 KonqPopupFlags kpf = ( showProperties ? ShowProperties : IsLink ) | ShowNewWindow; 00201 init(0, kpf, KParts::BrowserExtension::DefaultPopupItems); 00202 } 00203 00204 KonqPopupMenu::KonqPopupMenu( KBookmarkManager *mgr, const KFileItemList &items, 00205 KURL viewURL, 00206 TDEActionCollection & actions, 00207 KNewMenu * newMenu, 00208 TQWidget * parentWidget, 00209 bool showProperties ) 00210 : 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) 00211 { 00212 KonqPopupFlags kpf = ( showProperties ? ShowProperties : IsLink ) | ShowNewWindow; 00213 init(parentWidget, kpf, KParts::BrowserExtension::DefaultPopupItems); 00214 } 00215 00216 KonqPopupMenu::KonqPopupMenu( KBookmarkManager *mgr, const KFileItemList &items, 00217 const KURL& viewURL, 00218 TDEActionCollection & actions, 00219 KNewMenu * newMenu, 00220 TQWidget * parentWidget, 00221 KonqPopupFlags kpf, 00222 KParts::BrowserExtension::PopupFlags flags) 00223 : 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) 00224 { 00225 init(parentWidget, kpf, flags); 00226 } 00227 00228 void KonqPopupMenu::init (TQWidget * parentWidget, KonqPopupFlags kpf, KParts::BrowserExtension::PopupFlags flags) 00229 { 00230 d = new KonqPopupMenuPrivate; 00231 d->m_parentWidget = parentWidget; 00232 d->m_itemFlags = flags; 00233 setup(kpf); 00234 } 00235 00236 int KonqPopupMenu::insertServicesSubmenus(const TQMap<TQString, ServiceList>& submenus, 00237 TQDomElement& menu, 00238 bool isBuiltin) 00239 { 00240 int count = 0; 00241 TQMap<TQString, ServiceList>::ConstIterator it; 00242 00243 for (it = submenus.begin(); it != submenus.end(); ++it) 00244 { 00245 if (it.data().isEmpty()) 00246 { 00247 //avoid empty sub-menus 00248 continue; 00249 } 00250 00251 TQDomElement actionSubmenu = m_doc.createElement( "menu" ); 00252 actionSubmenu.setAttribute( "name", "actions " + it.key() ); 00253 menu.appendChild( actionSubmenu ); 00254 TQDomElement subtext = m_doc.createElement( "text" ); 00255 actionSubmenu.appendChild( subtext ); 00256 subtext.appendChild( m_doc.createTextNode( it.key() ) ); 00257 count += insertServices(it.data(), actionSubmenu, isBuiltin); 00258 } 00259 00260 return count; 00261 } 00262 00263 int KonqPopupMenu::insertServices(const ServiceList& list, 00264 TQDomElement& menu, 00265 bool isBuiltin) 00266 { 00267 static int id = 1000; 00268 int count = 0; 00269 00270 ServiceList::const_iterator it = list.begin(); 00271 for( ; it != list.end(); ++it ) 00272 { 00273 if ((*it).isEmpty()) 00274 { 00275 if (!menu.firstChild().isNull() && 00276 menu.lastChild().toElement().tagName().lower() != "separator") 00277 { 00278 TQDomElement separator = m_doc.createElement( "separator" ); 00279 menu.appendChild(separator); 00280 } 00281 continue; 00282 } 00283 00284 if (isBuiltin || (*it).m_display == true) 00285 { 00286 TQCString name; 00287 name.setNum( id ); 00288 name.prepend( isBuiltin ? "builtinservice_" : "userservice_" ); 00289 TDEAction * act = new TDEAction( TQString((*it).m_strName).replace('&',"&&"), 0, 00290 TQT_TQOBJECT(this), TQT_SLOT( slotRunService() ), 00291 &m_ownActions, name ); 00292 00293 if ( !(*it).m_strIcon.isEmpty() ) 00294 { 00295 TQPixmap pix = SmallIcon( (*it).m_strIcon ); 00296 act->setIconSet( pix ); 00297 } 00298 00299 addAction( act, menu ); // Add to toplevel menu 00300 00301 m_mapPopupServices[ id++ ] = *it; 00302 ++count; 00303 } 00304 } 00305 00306 return count; 00307 } 00308 00309 bool KonqPopupMenu::KIOSKAuthorizedAction(TDEConfig& cfg) 00310 { 00311 if ( !cfg.hasKey( "X-TDE-AuthorizeAction") ) 00312 { 00313 return true; 00314 } 00315 00316 TQStringList list = cfg.readListEntry("X-TDE-AuthorizeAction"); 00317 if (kapp && !list.isEmpty()) 00318 { 00319 for(TQStringList::ConstIterator it = list.begin(); 00320 it != list.end(); 00321 ++it) 00322 { 00323 if (!kapp->authorize((*it).stripWhiteSpace())) 00324 { 00325 return false; 00326 } 00327 } 00328 } 00329 00330 return true; 00331 } 00332 00333 00334 void KonqPopupMenu::setup(KonqPopupFlags kpf) 00335 { 00336 assert( m_lstItems.count() >= 1 ); 00337 00338 m_ownActions.setWidget( this ); 00339 00340 const bool bIsLink = (kpf & IsLink); 00341 bool currentDir = false; 00342 bool sReading = true; 00343 bool sDeleting = ( d->m_itemFlags & KParts::BrowserExtension::NoDeletion ) == 0; 00344 bool sMoving = sDeleting; 00345 bool sWriting = sDeleting && m_lstItems.first()->isWritable(); 00346 m_sMimeType = m_lstItems.first()->mimetype(); 00347 TQString mimeGroup = m_sMimeType.left(m_sMimeType.find('/')); 00348 mode_t mode = m_lstItems.first()->mode(); 00349 bool isDirectory = S_ISDIR(mode); 00350 bool bTrashIncluded = false; 00351 bool mediaFiles = false; 00352 bool isReallyLocal = m_lstItems.first()->isLocalFile(); 00353 bool isLocal = isReallyLocal 00354 || m_lstItems.first()->url().protocol()=="media" 00355 || m_lstItems.first()->url().protocol()=="system"; 00356 bool isTrashLink = false; 00357 m_lstPopupURLs.clear(); 00358 int id = 0; 00359 setFont(TDEGlobalSettings::menuFont()); 00360 m_pluginList.setAutoDelete( true ); 00361 m_ownActions.setHighlightingEnabled( true ); 00362 00363 attrName = TQString::fromLatin1( "name" ); 00364 00365 prepareXMLGUIStuff(); 00366 m_builder = new KonqPopupMenuGUIBuilder( this ); 00367 m_factory = new KXMLGUIFactory( m_builder ); 00368 00369 KURL url; 00370 KFileItemListIterator it ( m_lstItems ); 00371 TQStringList mimeTypeList; 00372 // Check whether all URLs are correct 00373 for ( ; it.current(); ++it ) 00374 { 00375 url = (*it)->url(); 00376 00377 // Build the list of URLs 00378 m_lstPopupURLs.append( url ); 00379 00380 // Determine if common mode among all URLs 00381 if ( mode != (*it)->mode() ) 00382 mode = 0; // modes are different => reset to 0 00383 00384 // Determine if common mimetype among all URLs 00385 if ( m_sMimeType != (*it)->mimetype() ) 00386 { 00387 m_sMimeType = TQString::null; // mimetypes are different => null 00388 00389 if ( mimeGroup != (*it)->mimetype().left((*it)->mimetype().find('/'))) 00390 mimeGroup = TQString::null; // mimetype groups are different as well! 00391 } 00392 00393 if ( mimeTypeList.findIndex( (*it)->mimetype() ) == -1 ) 00394 mimeTypeList << (*it)->mimetype(); 00395 00396 if ( isReallyLocal && !url.isLocalFile() ) 00397 isReallyLocal = false; 00398 if ( isLocal && !url.isLocalFile() && url.protocol() != "media" && url.protocol() != "system" ) 00399 isLocal = false; 00400 00401 if ( !bTrashIncluded && ( 00402 ( url.protocol() == "trash" && url.path().length() <= 1 ) 00403 || url.url() == "system:/trash" || url.url() == "system:/trash/" ) ) { 00404 bTrashIncluded = true; 00405 isLocal = false; 00406 } 00407 00408 if ( sReading ) 00409 sReading = KProtocolInfo::supportsReading( url ); 00410 00411 if ( sWriting ) 00412 sWriting = KProtocolInfo::supportsWriting( url ) && (*it)->isWritable(); 00413 00414 if ( sDeleting ) 00415 sDeleting = KProtocolInfo::supportsDeleting( url ); 00416 00417 if ( sMoving ) 00418 sMoving = KProtocolInfo::supportsMoving( url ); 00419 if ( (*it)->mimetype().startsWith("media/") ) 00420 mediaFiles = true; 00421 } 00422 00423 // If a local path is available, monitor that instead of the given remote URL... 00424 KURL realURL = m_sViewURL; 00425 if (!realURL.isLocalFile()) { 00426 d->localURLSlotFired = false; 00427 TDEIO::LocalURLJob* localURLJob = TDEIO::localURL(m_sViewURL); 00428 if (localURLJob) { 00429 connect(localURLJob, TQT_SIGNAL(localURL(TDEIO::LocalURLJob*, const KURL&, bool)), this, TQT_SLOT(slotLocalURL(TDEIO::LocalURLJob*, const KURL&, bool))); 00430 connect(localURLJob, TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotLocalURLKIODestroyed())); 00431 while (!d->localURLSlotFired) { 00432 kapp->eventLoop()->enterLoop(); 00433 } 00434 if (d->localURLResultIsLocal) { 00435 realURL = d->localURLResultURL; 00436 } 00437 } 00438 } 00439 00440 url = realURL; 00441 url.cleanPath(); 00442 00443 //check if url is current directory 00444 if ( m_lstItems.count() == 1 ) 00445 { 00446 KURL firstPopupURL( m_lstItems.first()->url() ); 00447 firstPopupURL.cleanPath(); 00448 //kdDebug(1203) << "View path is " << url.url() << endl; 00449 //kdDebug(1203) << "First popup path is " << firstPopupURL.url() << endl; 00450 currentDir = firstPopupURL.equals( url, true /* ignore_trailing */, true /* ignore_internalReferenceURLS */ ); 00451 if ( isLocal && ((m_sMimeType == "application/x-desktop") 00452 || (m_sMimeType == "media/builtin-mydocuments") 00453 || (m_sMimeType == "media/builtin-mycomputer") 00454 || (m_sMimeType == "media/builtin-mynetworkplaces") 00455 || (m_sMimeType == "media/builtin-printers") 00456 || (m_sMimeType == "media/builtin-trash") 00457 || (m_sMimeType == "media/builtin-webbrowser")) ) { 00458 KSimpleConfig cfg( firstPopupURL.path(), true ); 00459 cfg.setDesktopGroup(); 00460 isTrashLink = ( cfg.readEntry("Type") == "Link" && cfg.readEntry("URL") == "trash:/" ); 00461 } 00462 00463 if ( isTrashLink ) { 00464 sDeleting = false; 00465 } 00466 } 00467 00468 m_info.m_Reading = sReading; 00469 m_info.m_Writing = sWriting; 00470 m_info.m_Deleting = sDeleting; 00471 m_info.m_Moving = sMoving; 00472 m_info.m_TrashIncluded = bTrashIncluded; 00473 00474 // isCurrentTrash: popup on trash:/ itself, or on the trash.desktop link 00475 bool isCurrentTrash = ( m_lstItems.count() == 1 && bTrashIncluded ) || isTrashLink; 00476 bool isIntoTrash = ( url.protocol() == "trash" || url.url().startsWith( "system:/trash" ) ) && !isCurrentTrash; // trashed file, not trash:/ itself 00477 //kdDebug() << "isLocal=" << isLocal << " url=" << url << " isCurrentTrash=" << isCurrentTrash << " isIntoTrash=" << isIntoTrash << " bTrashIncluded=" << bTrashIncluded << endl; 00478 bool isSingleMedium = m_lstItems.count() == 1 && mediaFiles; 00479 clear(); 00480 00482 00483 TDEAction * act; 00484 00485 if (!isCurrentTrash) 00486 addMerge( "konqueror" ); 00487 00488 bool isKDesktop = TQCString( kapp->name() ) == "kdesktop"; 00489 TDEAction *actNewWindow = 0; 00490 00491 if (( kpf & ShowProperties ) && isKDesktop && 00492 !kapp->authorize("editable_desktop_icons")) 00493 { 00494 kpf &= ~ShowProperties; // remove flag 00495 } 00496 00497 // Either 'newview' is in the actions we're given (probably in the tabhandling group) 00498 // or we need to insert it ourselves (e.g. for kdesktop). In the first case, actNewWindow must remain 0. 00499 if ( ((kpf & ShowNewWindow) != 0) && sReading ) 00500 { 00501 TQString openStr = isKDesktop ? i18n( "&Open" ) : i18n( "Open in New &Window" ); 00502 actNewWindow = new TDEAction( openStr, "window-new", 0, TQT_TQOBJECT(this), TQT_SLOT( slotPopupNewView() ), &m_ownActions, "newview" ); 00503 } 00504 00505 if ( actNewWindow && !isKDesktop ) 00506 { 00507 if (isCurrentTrash) 00508 actNewWindow->setToolTip( i18n( "Open the trash in a new window" ) ); 00509 else if (isSingleMedium) 00510 actNewWindow->setToolTip( i18n( "Open the medium in a new window") ); 00511 else 00512 actNewWindow->setToolTip( i18n( "Open the document in a new window" ) ); 00513 } 00514 00515 if ( S_ISDIR(mode) && sWriting && !isCurrentTrash ) // A dir, and we can create things into it 00516 { 00517 if ( currentDir && m_pMenuNew ) // Current dir -> add the "new" menu 00518 { 00519 // As requested by KNewMenu : 00520 m_pMenuNew->slotCheckUpToDate(); 00521 m_pMenuNew->setPopupFiles( m_lstPopupURLs ); 00522 00523 addAction( m_pMenuNew ); 00524 00525 addSeparator(); 00526 } 00527 else 00528 { 00529 if (d->m_itemFlags & KParts::BrowserExtension::ShowCreateDirectory) 00530 { 00531 TDEAction *actNewDir = new TDEAction( i18n( "Create &Folder..." ), "folder-new", 0, TQT_TQOBJECT(this), TQT_SLOT( slotPopupNewDir() ), &m_ownActions, "newdir" ); 00532 addAction( actNewDir ); 00533 addSeparator(); 00534 } 00535 } 00536 } else if ( isIntoTrash ) { 00537 // Trashed item, offer restoring 00538 act = new TDEAction( i18n( "&Restore" ), 0, TQT_TQOBJECT(this), TQT_SLOT( slotPopupRestoreTrashedItems() ), &m_ownActions, "restore" ); 00539 addAction( act ); 00540 } 00541 00542 if (d->m_itemFlags & KParts::BrowserExtension::ShowNavigationItems) 00543 { 00544 if (d->m_itemFlags & KParts::BrowserExtension::ShowUp) 00545 addAction( "up" ); 00546 addAction( "back" ); 00547 addAction( "forward" ); 00548 if (d->m_itemFlags & KParts::BrowserExtension::ShowReload) 00549 addAction( "reload" ); 00550 addSeparator(); 00551 } 00552 00553 // "open in new window" is either provided by us, or by the tabhandling group 00554 if (actNewWindow) 00555 { 00556 addAction( actNewWindow ); 00557 addSeparator(); 00558 } 00559 addGroup( "tabhandling" ); // includes a separator 00560 00561 if ( !bIsLink ) 00562 { 00563 if ( !currentDir && sReading ) { 00564 if ( sDeleting ) { 00565 addAction( "cut" ); 00566 } 00567 addAction( "copy" ); 00568 } 00569 00570 if ( S_ISDIR(mode) && sWriting ) { 00571 if ( currentDir ) 00572 addAction( "paste" ); 00573 else 00574 addAction( "pasteto" ); 00575 } 00576 if ( !currentDir ) 00577 { 00578 if ( m_lstItems.count() == 1 && sMoving ) 00579 addAction( "rename" ); 00580 00581 bool addTrash = false; 00582 bool addDel = false; 00583 00584 if ( sMoving && !isIntoTrash && !isTrashLink ) 00585 addTrash = true; 00586 00587 if ( sDeleting ) { 00588 if ( !isLocal ) 00589 addDel = true; 00590 else if (TDEApplication::keyboardMouseState() & TQt::ShiftButton) { 00591 addTrash = false; 00592 addDel = true; 00593 } 00594 else { 00595 TDEConfigGroup configGroup( kapp->config(), "KDE" ); 00596 if ( configGroup.readBoolEntry( "ShowDeleteCommand", false ) ) 00597 addDel = true; 00598 } 00599 } 00600 00601 if ( addTrash ) 00602 addAction( "trash" ); 00603 if ( addDel ) 00604 addAction( "del" ); 00605 } 00606 } 00607 if ( isCurrentTrash ) 00608 { 00609 act = new TDEAction( i18n( "&Empty Trash Bin" ), "emptytrash", 0, TQT_TQOBJECT(this), TQT_SLOT( slotPopupEmptyTrashBin() ), &m_ownActions, "empytrash" ); 00610 KSimpleConfig trashConfig( "trashrc", true ); 00611 trashConfig.setGroup( "Status" ); 00612 act->setEnabled( !trashConfig.readBoolEntry( "Empty", true ) ); 00613 addAction( act ); 00614 } 00615 addGroup( "editactions" ); 00616 00617 if (d->m_itemFlags & KParts::BrowserExtension::ShowTextSelectionItems) { 00618 addMerge( 0 ); 00619 m_factory->addClient( this ); 00620 return; 00621 } 00622 00623 if ( !isCurrentTrash && !isIntoTrash && (d->m_itemFlags & KParts::BrowserExtension::ShowBookmark)) 00624 { 00625 addSeparator(); 00626 TQString caption; 00627 if (currentDir) 00628 { 00629 bool httpPage = (m_sViewURL.protocol().find("http", 0, false) == 0); 00630 if (httpPage) 00631 caption = i18n("&Bookmark This Page"); 00632 else 00633 caption = i18n("&Bookmark This Location"); 00634 } 00635 else if (S_ISDIR(mode)) 00636 caption = i18n("&Bookmark This Folder"); 00637 else if (bIsLink) 00638 caption = i18n("&Bookmark This Link"); 00639 else 00640 caption = i18n("&Bookmark This File"); 00641 00642 act = new TDEAction( caption, "bookmark_add", 0, TQT_TQOBJECT(this), TQT_SLOT( slotPopupAddToBookmark() ), &m_ownActions, "bookmark_add" ); 00643 if (m_lstItems.count() > 1) 00644 act->setEnabled(false); 00645 if (kapp->authorizeTDEAction("bookmarks")) 00646 addAction( act ); 00647 if (bIsLink) 00648 addGroup( "linkactions" ); 00649 } 00650 00652 00653 const bool isSingleLocal = m_lstItems.count() == 1 && isLocal; 00654 PopupServices s; 00655 KURL urlForServiceMenu( m_lstItems.first()->url() ); 00656 if (isLocal && !isReallyLocal) { // media or system 00657 bool dummy; 00658 urlForServiceMenu = m_lstItems.first()->mostLocalURL(dummy); 00659 } 00660 00661 // 1 - Look for builtin and user-defined services 00662 if ( ((m_sMimeType == "application/x-desktop") 00663 || (m_sMimeType == "media/builtin-mydocuments") 00664 || (m_sMimeType == "media/builtin-mycomputer") 00665 || (m_sMimeType == "media/builtin-mynetworkplaces") 00666 || (m_sMimeType == "media/builtin-printers") 00667 || (m_sMimeType == "media/builtin-trash") 00668 || (m_sMimeType == "media/builtin-webbrowser")) && isSingleLocal ) // .desktop file 00669 { 00670 // get builtin services, like mount/unmount 00671 s.builtin = KDEDesktopMimeType::builtinServices( urlForServiceMenu ); 00672 const TQString path = urlForServiceMenu.path(); 00673 KSimpleConfig cfg( path, true ); 00674 cfg.setDesktopGroup(); 00675 const TQString priority = cfg.readEntry("X-TDE-Priority"); 00676 const TQString submenuName = cfg.readEntry( "X-TDE-Submenu" ); 00677 if ( cfg.readEntry("Type") == "Link" ) { 00678 urlForServiceMenu = cfg.readEntry("URL"); 00679 // TODO: Do we want to make all the actions apply on the target 00680 // of the .desktop file instead of the .desktop file itself? 00681 } 00682 ServiceList* list = s.selectList( priority, submenuName ); 00683 (*list) = KDEDesktopMimeType::userDefinedServices( path, cfg, urlForServiceMenu.isLocalFile() ); 00684 } 00685 00686 if ( sReading ) 00687 { 00688 00689 // 2 - Look for "servicesmenus" bindings (konqueror-specific user-defined services) 00690 00691 // first check the .directory if this is a directory 00692 if (isDirectory && isSingleLocal) 00693 { 00694 TQString dotDirectoryFile = urlForServiceMenu.path(1).append(".directory"); 00695 KSimpleConfig cfg( dotDirectoryFile, true ); 00696 cfg.setDesktopGroup(); 00697 00698 if (KIOSKAuthorizedAction(cfg)) 00699 { 00700 const TQString priority = cfg.readEntry("X-TDE-Priority"); 00701 const TQString submenuName = cfg.readEntry( "X-TDE-Submenu" ); 00702 ServiceList* list = s.selectList( priority, submenuName ); 00703 (*list) += KDEDesktopMimeType::userDefinedServices( dotDirectoryFile, cfg, true ); 00704 } 00705 } 00706 00707 // findAllResources() also removes duplicates 00708 const TQStringList entries = TDEGlobal::dirs()->findAllResources("data", 00709 "konqueror/servicemenus/*.desktop", 00710 false /* recursive */, 00711 true /* unique */); 00712 TQStringList::ConstIterator eIt = entries.begin(); 00713 const TQStringList::ConstIterator eEnd = entries.end(); 00714 for (; eIt != eEnd; ++eIt ) 00715 { 00716 KSimpleConfig cfg( *eIt, true ); 00717 cfg.setDesktopGroup(); 00718 00719 if (!KIOSKAuthorizedAction(cfg)) 00720 { 00721 continue; 00722 } 00723 00724 if ( cfg.hasKey( "X-TDE-ShowIfRunning" ) ) 00725 { 00726 const TQString app = cfg.readEntry( "X-TDE-ShowIfRunning" ); 00727 if ( !kapp->dcopClient()->isApplicationRegistered( app.utf8() ) ) 00728 continue; 00729 } 00730 if ( cfg.hasKey( "X-TDE-ShowIfDcopCall" ) ) 00731 { 00732 TQString dcopcall = cfg.readEntry( "X-TDE-ShowIfDcopCall" ); 00733 const TQCString app = TQString(dcopcall.section(' ', 0,0)).utf8(); 00734 00735 //if( !kapp->dcopClient()->isApplicationRegistered( app )) 00736 // continue; //app does not exist so cannot send call 00737 00738 TQByteArray dataToSend; 00739 TQDataStream dataStream(dataToSend, IO_WriteOnly); 00740 dataStream << m_lstPopupURLs; 00741 00742 TQCString replyType; 00743 TQByteArray replyData; 00744 TQCString object = TQString(dcopcall.section(' ', 1,-2)).utf8(); 00745 TQString function = TQString(dcopcall.section(' ', -1)); 00746 if(!function.endsWith("(KURL::List)")) { 00747 kdWarning() << "Desktop file " << *eIt << " contains an invalid X-TDE-ShowIfDcopCall - the function must take the exact parameter (KURL::List) and must be specified." << endl; 00748 continue; //Be safe. 00749 } 00750 00751 if(!kapp->dcopClient()->call( app, object, 00752 function.utf8(), 00753 dataToSend, replyType, replyData, true, 1000)) 00754 continue; 00755 if(replyType != "bool" || !replyData[0]) 00756 continue; 00757 00758 } 00759 if ( cfg.hasKey( "X-TDE-Protocol" ) ) 00760 { 00761 const TQString protocol = cfg.readEntry( "X-TDE-Protocol" ); 00762 if ( protocol != urlForServiceMenu.protocol() ) 00763 continue; 00764 } 00765 else if ( cfg.hasKey( "X-TDE-Protocols" ) ) 00766 { 00767 TQStringList protocols = TQStringList::split( "," , cfg.readEntry( "X-TDE-Protocols" ) ); 00768 if ( !protocols.contains( urlForServiceMenu.protocol() ) ) 00769 continue; 00770 } 00771 else if ( urlForServiceMenu.protocol() == "trash" || urlForServiceMenu.url().startsWith( "system:/trash" ) ) 00772 { 00773 // Require servicemenus for the trash to ask for protocol=trash explicitely. 00774 // Trashed files aren't supposed to be available for actions. 00775 // One might want a servicemenu for trash.desktop itself though. 00776 continue; 00777 } 00778 00779 if ( cfg.hasKey( "X-TDE-Require" ) ) 00780 { 00781 const TQStringList capabilities = cfg.readListEntry( "X-TDE-Require" ); 00782 if ( capabilities.contains( "Write" ) && !sWriting ) 00783 continue; 00784 } 00785 if ( (cfg.hasKey( "Actions" ) || cfg.hasKey( "X-TDE-GetActionMenu") ) && cfg.hasKey( "X-TDE-ServiceTypes" ) ) 00786 { 00787 const TQStringList types = cfg.readListEntry( "X-TDE-ServiceTypes" ); 00788 const TQStringList excludeTypes = cfg.readListEntry( "X-TDE-ExcludeServiceTypes" ); 00789 bool ok = false; 00790 00791 // check for exact matches or a typeglob'd mimetype if we have a mimetype 00792 for (TQStringList::ConstIterator it = types.begin(); 00793 it != types.end() && !ok; 00794 ++it) 00795 { 00796 // first check if we have an all mimetype 00797 bool checkTheMimetypes = false; 00798 if (*it == "all/all" || 00799 *it == "allfiles" /*compat with KDE up to 3.0.3*/) 00800 { 00801 checkTheMimetypes = true; 00802 } 00803 00804 // next, do we match all files? 00805 if (!ok && 00806 !isDirectory && 00807 *it == "all/allfiles") 00808 { 00809 checkTheMimetypes = true; 00810 } 00811 00812 // if we have a mimetype, see if we have an exact or a type globbed match 00813 if ((!ok && 00814 (!m_sMimeType.isEmpty() && 00815 *it == m_sMimeType)) || 00816 (!mimeGroup.isEmpty() && 00817 (((*it).right(1) == "*") && 00818 (*it).left((*it).find('/')) == mimeGroup))) 00819 { 00820 checkTheMimetypes = true; 00821 } 00822 00823 if (checkTheMimetypes) 00824 { 00825 ok = true; 00826 for (TQStringList::ConstIterator itex = excludeTypes.begin(); itex != excludeTypes.end(); ++itex) 00827 { 00828 if( ((*itex).right(1) == "*" && (*itex).left((*itex).find('/')) == mimeGroup) || 00829 ((*itex) == m_sMimeType) ) 00830 { 00831 ok = false; 00832 break; 00833 } 00834 } 00835 } 00836 } 00837 00838 if ( ok ) 00839 { 00840 const TQString priority = cfg.readEntry("X-TDE-Priority"); 00841 const TQString submenuName = cfg.readEntry( "X-TDE-Submenu" ); 00842 00843 ServiceList* list = s.selectList( priority, submenuName ); 00844 (*list) += KDEDesktopMimeType::userDefinedServices( *eIt, cfg, url.isLocalFile(), m_lstPopupURLs ); 00845 } 00846 } 00847 } 00848 00849 TDETrader::OfferList offers; 00850 00851 if (kapp->authorizeTDEAction("openwith")) 00852 { 00853 TQString constraint = "Type == 'Application' and DesktopEntryName != 'kfmclient' and DesktopEntryName != 'kfmclient_dir' and DesktopEntryName != 'kfmclient_html'"; 00854 TQString subConstraint = " and '%1' in ServiceTypes"; 00855 00856 TQStringList::ConstIterator it = mimeTypeList.begin(); 00857 TQStringList::ConstIterator end = mimeTypeList.end(); 00858 Q_ASSERT( it != end ); 00859 TQString first = *it; 00860 ++it; 00861 while ( it != end ) { 00862 constraint += subConstraint.arg( *it ); 00863 ++it; 00864 } 00865 00866 offers = TDETrader::self()->query( first, constraint ); 00867 } 00868 00870 00871 m_mapPopup.clear(); 00872 m_mapPopupServices.clear(); 00873 // "Open With..." for folders is really not very useful, especially for remote folders. 00874 // (media:/something, or trash:/, or ftp://...) 00875 if ( !isDirectory || isLocal ) 00876 { 00877 if ( hasAction() ) 00878 addSeparator(); 00879 00880 if ( !offers.isEmpty() ) 00881 { 00882 // First block, app and preview offers 00883 id = 1; 00884 00885 TQDomElement menu = m_menuElement; 00886 00887 if ( offers.count() > 1 ) // submenu 'open with' 00888 { 00889 menu = m_doc.createElement( "menu" ); 00890 menu.setAttribute( "name", "openwith submenu" ); 00891 m_menuElement.appendChild( menu ); 00892 TQDomElement text = m_doc.createElement( "text" ); 00893 menu.appendChild( text ); 00894 text.appendChild( m_doc.createTextNode( i18n("&Open With") ) ); 00895 } 00896 00897 TDETrader::OfferList::ConstIterator it = offers.begin(); 00898 for( ; it != offers.end(); it++ ) 00899 { 00900 KService::Ptr service = (*it); 00901 00902 // Skip OnlyShowIn=Foo and NotShowIn=TDE entries, 00903 // but still offer NoDisplay=true entries, that's the 00904 // whole point of such desktop files. This is why we don't 00905 // use service->noDisplay() here. 00906 const TQString onlyShowIn = service->property("OnlyShowIn", TQVariant::String).toString(); 00907 if ( !onlyShowIn.isEmpty() ) { 00908 const TQStringList aList = TQStringList::split(';', onlyShowIn); 00909 if (!aList.contains("TDE")) 00910 continue; 00911 } 00912 const TQString notShowIn = service->property("NotShowIn", TQVariant::String).toString(); 00913 if ( !notShowIn.isEmpty() ) { 00914 const TQStringList aList = TQStringList::split(';', notShowIn); 00915 if (aList.contains("TDE")) 00916 continue; 00917 } 00918 00919 TQCString nam; 00920 nam.setNum( id ); 00921 00922 TQString actionName( (*it)->name().replace("&", "&&") ); 00923 if ( menu == m_menuElement ) // no submenu -> prefix single offer 00924 actionName = i18n( "Open with %1" ).arg( actionName ); 00925 00926 act = new TDEAction( actionName, (*it)->pixmap( TDEIcon::Small ), 0, 00927 TQT_TQOBJECT(this), TQT_SLOT( slotRunService() ), 00928 &m_ownActions, nam.prepend( "appservice_" ) ); 00929 addAction( act, menu ); 00930 00931 m_mapPopup[ id++ ] = *it; 00932 } 00933 00934 TQString openWithActionName; 00935 if ( menu != m_menuElement ) // submenu 00936 { 00937 addSeparator( menu ); 00938 openWithActionName = i18n( "&Other..." ); 00939 } 00940 else 00941 { 00942 openWithActionName = i18n( "&Open With..." ); 00943 } 00944 TDEAction *openWithAct = new TDEAction( openWithActionName, 0, TQT_TQOBJECT(this), TQT_SLOT( slotPopupOpenWith() ), &m_ownActions, "openwith" ); 00945 addAction( openWithAct, menu ); 00946 } 00947 else // no app offers -> Open With... 00948 { 00949 act = new TDEAction( i18n( "&Open With..." ), 0, TQT_TQOBJECT(this), TQT_SLOT( slotPopupOpenWith() ), &m_ownActions, "openwith" ); 00950 addAction( act ); 00951 } 00952 00953 } 00954 addGroup( "preview" ); 00955 } 00956 00957 // Second block, builtin + user 00958 TQDomElement actionMenu = m_menuElement; 00959 int userItemCount = 0; 00960 if (s.user.count() + s.userSubmenus.count() + 00961 s.userPriority.count() + s.userPrioritySubmenus.count() > 1) 00962 { 00963 // we have more than one item, so let's make a submenu 00964 actionMenu = m_doc.createElement( "menu" ); 00965 actionMenu.setAttribute( "name", "actions submenu" ); 00966 m_menuElement.appendChild( actionMenu ); 00967 TQDomElement text = m_doc.createElement( "text" ); 00968 actionMenu.appendChild( text ); 00969 text.appendChild( m_doc.createTextNode( i18n("Ac&tions") ) ); 00970 } 00971 00972 userItemCount += insertServicesSubmenus(s.userPrioritySubmenus, actionMenu, false); 00973 userItemCount += insertServices(s.userPriority, actionMenu, false); 00974 00975 // see if we need to put a separator between our priority items and our regular items 00976 if (userItemCount > 0 && 00977 (s.user.count() > 0 || 00978 s.userSubmenus.count() > 0 || 00979 s.builtin.count() > 0) && 00980 actionMenu.lastChild().toElement().tagName().lower() != "separator") 00981 { 00982 TQDomElement separator = m_doc.createElement( "separator" ); 00983 actionMenu.appendChild(separator); 00984 } 00985 00986 userItemCount += insertServicesSubmenus(s.userSubmenus, actionMenu, false); 00987 userItemCount += insertServices(s.user, actionMenu, false); 00988 userItemCount += insertServices(s.builtin, m_menuElement, true); 00989 00990 userItemCount += insertServicesSubmenus(s.userToplevelSubmenus, m_menuElement, false); 00991 userItemCount += insertServices(s.userToplevel, m_menuElement, false); 00992 00993 if ( userItemCount > 0 ) 00994 { 00995 addPendingSeparator(); 00996 } 00997 00998 if ( !isCurrentTrash && !isIntoTrash && !mediaFiles && sReading ) 00999 addPlugins(); // now it's time to add plugins 01000 01001 if ( KPropertiesDialog::canDisplay( m_lstItems ) && (kpf & ShowProperties) ) 01002 { 01003 act = new TDEAction( i18n( "&Properties" ), 0, TQT_TQOBJECT(this), TQT_SLOT( slotPopupProperties() ), 01004 &m_ownActions, "properties" ); 01005 addAction( act ); 01006 } 01007 01008 while ( !m_menuElement.lastChild().isNull() && 01009 m_menuElement.lastChild().toElement().tagName().lower() == "separator" ) 01010 m_menuElement.removeChild( m_menuElement.lastChild() ); 01011 01012 if ( isDirectory && isLocal ) 01013 { 01014 if ( KFileShare::authorization() == KFileShare::Authorized ) 01015 { 01016 addSeparator(); 01017 act = new TDEAction( i18n("Share"), 0, TQT_TQOBJECT(this), TQT_SLOT( slotOpenShareFileDialog() ), 01018 &m_ownActions, "sharefile" ); 01019 addAction( act ); 01020 } 01021 } 01022 01023 addMerge( 0 ); 01024 //kdDebug() << k_funcinfo << domDocument().toString() << endl; 01025 01026 m_factory->addClient( this ); 01027 } 01028 01029 void KonqPopupMenu::slotOpenShareFileDialog() 01030 { 01031 KPropertiesDialog* dlg = showPropertiesDialog(); 01032 dlg->showFileSharingPage(); 01033 } 01034 01035 KonqPopupMenu::~KonqPopupMenu() 01036 { 01037 m_pluginList.clear(); 01038 delete m_factory; 01039 delete m_builder; 01040 delete d; 01041 //kdDebug(1203) << "~KonqPopupMenu leave" << endl; 01042 } 01043 01044 void KonqPopupMenu::setURLTitle( const TQString& urlTitle ) 01045 { 01046 d->m_urlTitle = urlTitle; 01047 } 01048 01049 void KonqPopupMenu::slotPopupNewView() 01050 { 01051 KURL::List::ConstIterator it = m_lstPopupURLs.begin(); 01052 for ( ; it != m_lstPopupURLs.end(); it++ ) 01053 (void) new KRun(*it); 01054 } 01055 01056 void KonqPopupMenu::slotPopupNewDir() 01057 { 01058 if (m_lstPopupURLs.empty()) 01059 return; 01060 01061 KonqOperations::newDir(d->m_parentWidget, m_lstPopupURLs.first()); 01062 } 01063 01064 void KonqPopupMenu::slotPopupEmptyTrashBin() 01065 { 01066 KonqOperations::emptyTrash(); 01067 } 01068 01069 void KonqPopupMenu::slotPopupRestoreTrashedItems() 01070 { 01071 KonqOperations::restoreTrashedItems( m_lstPopupURLs ); 01072 } 01073 01074 void KonqPopupMenu::slotPopupOpenWith() 01075 { 01076 KRun::displayOpenWithDialog( m_lstPopupURLs ); 01077 } 01078 01079 void KonqPopupMenu::slotPopupAddToBookmark() 01080 { 01081 KBookmarkGroup root; 01082 if ( m_lstPopupURLs.count() == 1 ) { 01083 KURL url = m_lstPopupURLs.first(); 01084 TQString title = d->m_urlTitle.isEmpty() ? url.prettyURL() : d->m_urlTitle; 01085 root = m_pManager->addBookmarkDialog( url.prettyURL(), title ); 01086 } 01087 else 01088 { 01089 root = m_pManager->root(); 01090 KURL::List::ConstIterator it = m_lstPopupURLs.begin(); 01091 for ( ; it != m_lstPopupURLs.end(); it++ ) 01092 root.addBookmark( m_pManager, (*it).prettyURL(), (*it) ); 01093 } 01094 m_pManager->emitChanged( root ); 01095 } 01096 01097 void KonqPopupMenu::slotRunService() 01098 { 01099 TQCString senderName = TQT_TQOBJECT_CONST(sender())->name(); 01100 int id = senderName.mid( senderName.find( '_' ) + 1 ).toInt(); 01101 01102 // Is it a usual service (application) 01103 TQMap<int,KService::Ptr>::Iterator it = m_mapPopup.find( id ); 01104 if ( it != m_mapPopup.end() ) 01105 { 01106 KRun::run( **it, m_lstPopupURLs ); 01107 return; 01108 } 01109 01110 // Is it a service specific to desktop entry files ? 01111 TQMap<int,KDEDesktopMimeType::Service>::Iterator it2 = m_mapPopupServices.find( id ); 01112 if ( it2 != m_mapPopupServices.end() ) 01113 { 01114 KDEDesktopMimeType::executeService( m_lstPopupURLs, it2.data() ); 01115 } 01116 01117 return; 01118 } 01119 01120 void KonqPopupMenu::slotPopupMimeType() 01121 { 01122 KonqOperations::editMimeType( m_sMimeType ); 01123 } 01124 01125 void KonqPopupMenu::slotPopupProperties() 01126 { 01127 (void)showPropertiesDialog(); 01128 } 01129 01130 KPropertiesDialog* KonqPopupMenu::showPropertiesDialog() 01131 { 01132 // It may be that the tdefileitem was created by hand 01133 // (see KonqKfmIconView::slotMouseButtonPressed) 01134 // In that case, we can get more precise info in the properties 01135 // (like permissions) if we stat the URL. 01136 if ( m_lstItems.count() == 1 ) 01137 { 01138 KFileItem * item = m_lstItems.first(); 01139 if (item->entry().count() == 0) // this item wasn't listed by a slave 01140 { 01141 // KPropertiesDialog will use stat to get more info on the file 01142 return new KPropertiesDialog( item->url(), d->m_parentWidget ); 01143 } 01144 } 01145 return new KPropertiesDialog( m_lstItems, d->m_parentWidget ); 01146 } 01147 01148 TDEAction *KonqPopupMenu::action( const TQDomElement &element ) const 01149 { 01150 TQCString name = element.attribute( attrName ).ascii(); 01151 TDEAction *res = m_ownActions.action( static_cast<const char *>(name) ); 01152 01153 if ( !res ) 01154 res = m_actions.action( static_cast<const char *>(name) ); 01155 01156 if ( !res && m_pMenuNew && strcmp( name, m_pMenuNew->name() ) == 0 ) 01157 return m_pMenuNew; 01158 01159 return res; 01160 } 01161 01162 TDEActionCollection *KonqPopupMenu::actionCollection() const 01163 { 01164 return const_cast<TDEActionCollection *>( &m_ownActions ); 01165 } 01166 01167 TQString KonqPopupMenu::mimeType() const 01168 { 01169 return m_sMimeType; 01170 } 01171 01172 KonqPopupMenu::ProtocolInfo KonqPopupMenu::protocolInfo() const 01173 { 01174 return m_info; 01175 } 01176 01177 void KonqPopupMenu::addPlugins() 01178 { 01179 // search for Konq_PopupMenuPlugins inspired by simons kpropsdlg 01180 //search for a plugin with the right protocol 01181 TDETrader::OfferList plugin_offers; 01182 unsigned int pluginCount = 0; 01183 plugin_offers = TDETrader::self()->query( m_sMimeType.isNull() ? TQString::fromLatin1( "all/all" ) : m_sMimeType, "'KonqPopupMenu/Plugin' in ServiceTypes"); 01184 if ( plugin_offers.isEmpty() ) 01185 return; // no plugins installed do not bother about it 01186 01187 TDETrader::OfferList::ConstIterator iterator = plugin_offers.begin(); 01188 TDETrader::OfferList::ConstIterator end = plugin_offers.end(); 01189 01190 addGroup( "plugins" ); 01191 // travers the offerlist 01192 for(; iterator != end; ++iterator, ++pluginCount ) { 01193 //kdDebug() << (*iterator)->library() << endl; 01194 KonqPopupMenuPlugin *plugin = 01195 KParts::ComponentFactory:: 01196 createInstanceFromLibrary<KonqPopupMenuPlugin>( TQFile::encodeName( (*iterator)->library() ), 01197 TQT_TQOBJECT(this), 01198 (*iterator)->name().latin1() ); 01199 if ( !plugin ) 01200 continue; 01201 // This make the kuick plugin insert its stuff above "Properties" 01202 TQString pluginClientName = TQString::fromLatin1( "Plugin%1" ).arg( pluginCount ); 01203 addMerge( pluginClientName ); 01204 plugin->domDocument().documentElement().setAttribute( "name", pluginClientName ); 01205 m_pluginList.append( plugin ); 01206 insertChildClient( plugin ); 01207 } 01208 01209 // ## Where is this used? 01210 addMerge( "plugins" ); 01211 } 01212 01213 KURL KonqPopupMenu::url() const // ### should be viewURL() 01214 { 01215 return m_sViewURL; 01216 } 01217 01218 KFileItemList KonqPopupMenu::fileItemList() const 01219 { 01220 return m_lstItems; 01221 } 01222 01223 KURL::List KonqPopupMenu::popupURLList() const 01224 { 01225 return m_lstPopupURLs; 01226 } 01227 01228 void KonqPopupMenu::slotLocalURL(TDEIO::LocalURLJob *job, const KURL& url, bool isLocal) 01229 { 01230 d->localURLSlotFired = true; 01231 d->localURLResultURL = url; 01232 d->localURLResultIsLocal = isLocal; 01233 kapp->eventLoop()->exitLoop(); 01234 } 01235 01236 void KonqPopupMenu::slotLocalURLKIODestroyed() 01237 { 01238 if (!d->localURLSlotFired) { 01239 d->localURLSlotFired = true; 01240 d->localURLResultURL = KURL(); 01241 d->localURLResultIsLocal = false; 01242 kapp->eventLoop()->exitLoop(); 01243 } 01244 } 01245 01250 KonqPopupMenuPlugin::KonqPopupMenuPlugin( KonqPopupMenu *parent, const char *name ) 01251 : TQObject( parent, name ) 01252 { 01253 } 01254 01255 KonqPopupMenuPlugin::~KonqPopupMenuPlugin() 01256 { 01257 } 01258 01259 #include "konq_popupmenu.moc"