00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
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
00148
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
00162
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
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 );
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
00373 for ( ; it.current(); ++it )
00374 {
00375 url = (*it)->url();
00376
00377
00378 m_lstPopupURLs.append( url );
00379
00380
00381 if ( mode != (*it)->mode() )
00382 mode = 0;
00383
00384
00385 if ( m_sMimeType != (*it)->mimetype() )
00386 {
00387 m_sMimeType = TQString::null;
00388
00389 if ( mimeGroup != (*it)->mimetype().left((*it)->mimetype().find('/')))
00390 mimeGroup = TQString::null;
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
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
00444 if ( m_lstItems.count() == 1 )
00445 {
00446 KURL firstPopupURL( m_lstItems.first()->url() );
00447 firstPopupURL.cleanPath();
00448
00449
00450 currentDir = firstPopupURL.equals( url, true , true );
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
00475 bool isCurrentTrash = ( m_lstItems.count() == 1 && bTrashIncluded ) || isTrashLink;
00476 bool isIntoTrash = ( url.protocol() == "trash" || url.url().startsWith( "system:/trash" ) ) && !isCurrentTrash;
00477
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;
00495 }
00496
00497
00498
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 )
00516 {
00517 if ( currentDir && m_pMenuNew )
00518 {
00519
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
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
00554 if (actNewWindow)
00555 {
00556 addAction( actNewWindow );
00557 addSeparator();
00558 }
00559 addGroup( "tabhandling" );
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) {
00657 bool dummy;
00658 urlForServiceMenu = m_lstItems.first()->mostLocalURL(dummy);
00659 }
00660
00661
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 )
00669 {
00670
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
00680
00681 }
00682 ServiceList* list = s.selectList( priority, submenuName );
00683 (*list) = KDEDesktopMimeType::userDefinedServices( path, cfg, urlForServiceMenu.isLocalFile() );
00684 }
00685
00686 if ( sReading )
00687 {
00688
00689
00690
00691
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
00708 const TQStringList entries = TDEGlobal::dirs()->findAllResources("data",
00709 "konqueror/servicemenus/*.desktop",
00710 false ,
00711 true );
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
00736
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;
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
00774
00775
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
00792 for (TQStringList::ConstIterator it = types.begin();
00793 it != types.end() && !ok;
00794 ++it)
00795 {
00796
00797 bool checkTheMimetypes = false;
00798 if (*it == "all/all" ||
00799 *it == "allfiles" )
00800 {
00801 checkTheMimetypes = true;
00802 }
00803
00804
00805 if (!ok &&
00806 !isDirectory &&
00807 *it == "all/allfiles")
00808 {
00809 checkTheMimetypes = true;
00810 }
00811
00812
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
00874
00875 if ( !isDirectory || isLocal )
00876 {
00877 if ( hasAction() )
00878 addSeparator();
00879
00880 if ( !offers.isEmpty() )
00881 {
00882
00883 id = 1;
00884
00885 TQDomElement menu = m_menuElement;
00886
00887 if ( offers.count() > 1 )
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
00903
00904
00905
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 )
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 )
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
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
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
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
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();
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
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
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
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
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
01133
01134
01135
01136 if ( m_lstItems.count() == 1 )
01137 {
01138 KFileItem * item = m_lstItems.first();
01139 if (item->entry().count() == 0)
01140 {
01141
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
01180
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;
01186
01187 TDETrader::OfferList::ConstIterator iterator = plugin_offers.begin();
01188 TDETrader::OfferList::ConstIterator end = plugin_offers.end();
01189
01190 addGroup( "plugins" );
01191
01192 for(; iterator != end; ++iterator, ++pluginCount ) {
01193
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
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
01210 addMerge( "plugins" );
01211 }
01212
01213 KURL KonqPopupMenu::url() const
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"