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
00023 #include <klocale.h>
00024 #include <kapplication.h>
00025 #include <kbookmarkmanager.h>
00026 #include <kdebug.h>
00027 #include <krun.h>
00028 #include <kprotocolinfo.h>
00029 #include <kiconloader.h>
00030 #include <kinputdialog.h>
00031 #include <kglobalsettings.h>
00032 #include <kstandarddirs.h>
00033 #include <kxmlguifactory.h>
00034 #include <kxmlguibuilder.h>
00035 #include <kparts/componentfactory.h>
00036
00037 #include <assert.h>
00038
00039 #include <kfileshare.h>
00040 #include <kprocess.h>
00041
00042 #include "kpropertiesdialog.h"
00043 #include "knewmenu.h"
00044 #include "konq_popupmenu.h"
00045 #include "konq_operations.h"
00046 #include <dcopclient.h>
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 class KonqPopupMenuGUIBuilder : public KXMLGUIBuilder
00071 {
00072 public:
00073 KonqPopupMenuGUIBuilder( TQPopupMenu *menu )
00074 : KXMLGUIBuilder( 0 )
00075 {
00076 m_menu = menu;
00077 }
00078 virtual ~KonqPopupMenuGUIBuilder()
00079 {
00080 }
00081
00082 virtual TQWidget *createContainer( TQWidget *parent, int index,
00083 const TQDomElement &element,
00084 int &id )
00085 {
00086 if ( !parent && element.attribute( "name" ) == "popupmenu" )
00087 return m_menu;
00088
00089 return KXMLGUIBuilder::createContainer( parent, index, element, id );
00090 }
00091
00092 TQPopupMenu *m_menu;
00093 };
00094
00095 class KonqPopupMenu::KonqPopupMenuPrivate
00096 {
00097 public:
00098 KonqPopupMenuPrivate() : m_parentWidget( 0 ),
00099 m_itemFlags( KParts::BrowserExtension::DefaultPopupItems )
00100 {
00101 }
00102 TQString m_urlTitle;
00103 TQWidget *m_parentWidget;
00104 KParts::BrowserExtension::PopupFlags m_itemFlags;
00105 };
00106
00107 KonqPopupMenu::ProtocolInfo::ProtocolInfo()
00108 {
00109 m_Reading = false;
00110 m_Writing = false;
00111 m_Deleting = false;
00112 m_Moving = false;
00113 m_TrashIncluded = false;
00114 }
00115
00116 bool KonqPopupMenu::ProtocolInfo::supportsReading() const
00117 {
00118 return m_Reading;
00119 }
00120
00121 bool KonqPopupMenu::ProtocolInfo::supportsWriting() const
00122 {
00123 return m_Writing;
00124 }
00125
00126 bool KonqPopupMenu::ProtocolInfo::supportsDeleting() const
00127 {
00128 return m_Deleting;
00129 }
00130
00131 bool KonqPopupMenu::ProtocolInfo::supportsMoving() const
00132 {
00133 return m_Moving;
00134 }
00135
00136 bool KonqPopupMenu::ProtocolInfo::trashIncluded() const
00137 {
00138 return m_TrashIncluded;
00139 }
00140
00141
00142
00143 class PopupServices
00144 {
00145 public:
00146 ServiceList* selectList( const TQString& priority, const TQString& submenuName );
00147
00148 ServiceList builtin;
00149 ServiceList user, userToplevel, userPriority;
00150 TQMap<TQString, ServiceList> userSubmenus, userToplevelSubmenus, userPrioritySubmenus;
00151 };
00152
00153 ServiceList* PopupServices::selectList( const TQString& priority, const TQString& submenuName )
00154 {
00155
00156
00157 if (submenuName.isEmpty())
00158 {
00159 if (priority == "TopLevel")
00160 {
00161 return &userToplevel;
00162 }
00163 else if (priority == "Important")
00164 {
00165 return &userPriority;
00166 }
00167 }
00168 else if (priority == "TopLevel")
00169 {
00170 return &(userToplevelSubmenus[submenuName]);
00171 }
00172 else if (priority == "Important")
00173 {
00174 return &(userPrioritySubmenus[submenuName]);
00175 }
00176 else
00177 {
00178 return &(userSubmenus[submenuName]);
00179 }
00180 return &user;
00181 }
00182
00184
00185 KonqPopupMenu::KonqPopupMenu( KBookmarkManager *mgr, const KFileItemList &items,
00186 KURL viewURL,
00187 KActionCollection & actions,
00188 KNewMenu * newMenu,
00189 bool showProperties )
00190 : TQPopupMenu( 0L, "konq_popupmenu" ),
00191 m_actions( actions ), m_ownActions( static_cast<TQWidget *>( 0 ), "KonqPopupMenu::m_ownActions" ),
00192 m_pMenuNew( newMenu ), m_sViewURL(viewURL), m_lstItems(items), m_pManager(mgr)
00193 {
00194 KonqPopupFlags kpf = ( showProperties ? ShowProperties : IsLink ) | ShowNewWindow;
00195 init(0, kpf, KParts::BrowserExtension::DefaultPopupItems);
00196 }
00197
00198 KonqPopupMenu::KonqPopupMenu( KBookmarkManager *mgr, const KFileItemList &items,
00199 KURL viewURL,
00200 KActionCollection & actions,
00201 KNewMenu * newMenu,
00202 TQWidget * parentWidget,
00203 bool showProperties )
00204 : 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)
00205 {
00206 KonqPopupFlags kpf = ( showProperties ? ShowProperties : IsLink ) | ShowNewWindow;
00207 init(parentWidget, kpf, KParts::BrowserExtension::DefaultPopupItems);
00208 }
00209
00210 KonqPopupMenu::KonqPopupMenu( KBookmarkManager *mgr, const KFileItemList &items,
00211 const KURL& viewURL,
00212 KActionCollection & actions,
00213 KNewMenu * newMenu,
00214 TQWidget * parentWidget,
00215 KonqPopupFlags kpf,
00216 KParts::BrowserExtension::PopupFlags flags)
00217 : 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)
00218 {
00219 init(parentWidget, kpf, flags);
00220 }
00221
00222 void KonqPopupMenu::init (TQWidget * parentWidget, KonqPopupFlags kpf, KParts::BrowserExtension::PopupFlags flags)
00223 {
00224 d = new KonqPopupMenuPrivate;
00225 d->m_parentWidget = parentWidget;
00226 d->m_itemFlags = flags;
00227 setup(kpf);
00228 }
00229
00230 int KonqPopupMenu::insertServicesSubmenus(const TQMap<TQString, ServiceList>& submenus,
00231 TQDomElement& menu,
00232 bool isBuiltin)
00233 {
00234 int count = 0;
00235 TQMap<TQString, ServiceList>::ConstIterator it;
00236
00237 for (it = submenus.begin(); it != submenus.end(); ++it)
00238 {
00239 if (it.data().isEmpty())
00240 {
00241
00242 continue;
00243 }
00244
00245 TQDomElement actionSubmenu = m_doc.createElement( "menu" );
00246 actionSubmenu.setAttribute( "name", "actions " + it.key() );
00247 menu.appendChild( actionSubmenu );
00248 TQDomElement subtext = m_doc.createElement( "text" );
00249 actionSubmenu.appendChild( subtext );
00250 subtext.appendChild( m_doc.createTextNode( it.key() ) );
00251 count += insertServices(it.data(), actionSubmenu, isBuiltin);
00252 }
00253
00254 return count;
00255 }
00256
00257 int KonqPopupMenu::insertServices(const ServiceList& list,
00258 TQDomElement& menu,
00259 bool isBuiltin)
00260 {
00261 static int id = 1000;
00262 int count = 0;
00263
00264 ServiceList::const_iterator it = list.begin();
00265 for( ; it != list.end(); ++it )
00266 {
00267 if ((*it).isEmpty())
00268 {
00269 if (!menu.firstChild().isNull() &&
00270 menu.lastChild().toElement().tagName().lower() != "separator")
00271 {
00272 TQDomElement separator = m_doc.createElement( "separator" );
00273 menu.appendChild(separator);
00274 }
00275 continue;
00276 }
00277
00278 if (isBuiltin || (*it).m_display == true)
00279 {
00280 TQCString name;
00281 name.setNum( id );
00282 name.prepend( isBuiltin ? "builtinservice_" : "userservice_" );
00283 KAction * act = new KAction( TQString((*it).m_strName).replace('&',"&&"), 0,
00284 this, TQT_SLOT( slotRunService() ),
00285 &m_ownActions, name );
00286
00287 if ( !(*it).m_strIcon.isEmpty() )
00288 {
00289 TQPixmap pix = SmallIcon( (*it).m_strIcon );
00290 act->setIconSet( pix );
00291 }
00292
00293 addAction( act, menu );
00294
00295 m_mapPopupServices[ id++ ] = *it;
00296 ++count;
00297 }
00298 }
00299
00300 return count;
00301 }
00302
00303 bool KonqPopupMenu::KIOSKAuthorizedAction(KConfig& cfg)
00304 {
00305 if ( !cfg.hasKey( "X-KDE-AuthorizeAction") )
00306 {
00307 return true;
00308 }
00309
00310 TQStringList list = cfg.readListEntry("X-KDE-AuthorizeAction");
00311 if (kapp && !list.isEmpty())
00312 {
00313 for(TQStringList::ConstIterator it = list.begin();
00314 it != list.end();
00315 ++it)
00316 {
00317 if (!kapp->authorize((*it).stripWhiteSpace()))
00318 {
00319 return false;
00320 }
00321 }
00322 }
00323
00324 return true;
00325 }
00326
00327
00328 void KonqPopupMenu::setup(KonqPopupFlags kpf)
00329 {
00330 assert( m_lstItems.count() >= 1 );
00331
00332 m_ownActions.setWidget( this );
00333
00334 const bool bIsLink = (kpf & IsLink);
00335 bool currentDir = false;
00336 bool sReading = true;
00337 bool sDeleting = ( d->m_itemFlags & KParts::BrowserExtension::NoDeletion ) == 0;
00338 bool sMoving = sDeleting;
00339 bool sWriting = sDeleting && m_lstItems.first()->isWritable();
00340 m_sMimeType = m_lstItems.first()->mimetype();
00341 TQString mimeGroup = m_sMimeType.left(m_sMimeType.find('/'));
00342 mode_t mode = m_lstItems.first()->mode();
00343 bool isDirectory = S_ISDIR(mode);
00344 bool bTrashIncluded = false;
00345 bool mediaFiles = false;
00346 bool isReallyLocal = m_lstItems.first()->isLocalFile();
00347 bool isLocal = isReallyLocal
00348 || m_lstItems.first()->url().protocol()=="media"
00349 || m_lstItems.first()->url().protocol()=="system";
00350 bool isTrashLink = false;
00351 m_lstPopupURLs.clear();
00352 int id = 0;
00353 setFont(KGlobalSettings::menuFont());
00354 m_pluginList.setAutoDelete( true );
00355 m_ownActions.setHighlightingEnabled( true );
00356
00357 attrName = TQString::fromLatin1( "name" );
00358
00359 prepareXMLGUIStuff();
00360 m_builder = new KonqPopupMenuGUIBuilder( this );
00361 m_factory = new KXMLGUIFactory( m_builder );
00362
00363 KURL url;
00364 KFileItemListIterator it ( m_lstItems );
00365 TQStringList mimeTypeList;
00366
00367 for ( ; it.current(); ++it )
00368 {
00369 url = (*it)->url();
00370
00371
00372 m_lstPopupURLs.append( url );
00373
00374
00375 if ( mode != (*it)->mode() )
00376 mode = 0;
00377
00378
00379 if ( m_sMimeType != (*it)->mimetype() )
00380 {
00381 m_sMimeType = TQString::null;
00382
00383 if ( mimeGroup != (*it)->mimetype().left((*it)->mimetype().find('/')))
00384 mimeGroup = TQString::null;
00385 }
00386
00387 if ( mimeTypeList.findIndex( (*it)->mimetype() ) == -1 )
00388 mimeTypeList << (*it)->mimetype();
00389
00390 if ( isReallyLocal && !url.isLocalFile() )
00391 isReallyLocal = false;
00392 if ( isLocal && !url.isLocalFile() && url.protocol() != "media" && url.protocol() != "system" )
00393 isLocal = false;
00394
00395 if ( !bTrashIncluded && (
00396 ( url.protocol() == "trash" && url.path().length() <= 1 )
00397 || url.url() == "system:/trash" || url.url() == "system:/trash/" ) ) {
00398 bTrashIncluded = true;
00399 isLocal = false;
00400 }
00401
00402 if ( sReading )
00403 sReading = KProtocolInfo::supportsReading( url );
00404
00405 if ( sWriting )
00406 sWriting = KProtocolInfo::supportsWriting( url ) && (*it)->isWritable();
00407
00408 if ( sDeleting )
00409 sDeleting = KProtocolInfo::supportsDeleting( url );
00410
00411 if ( sMoving )
00412 sMoving = KProtocolInfo::supportsMoving( url );
00413 if ( (*it)->mimetype().startsWith("media/") )
00414 mediaFiles = true;
00415 }
00416 url = m_sViewURL;
00417 url.cleanPath();
00418
00419
00420 if ( m_lstItems.count() == 1 )
00421 {
00422 KURL firstPopupURL( m_lstItems.first()->url() );
00423 firstPopupURL.cleanPath();
00424
00425
00426 currentDir = firstPopupURL.equals( url, true );
00427 if ( isLocal && ((m_sMimeType == "application/x-desktop")
00428 || (m_sMimeType == "media/builtin-mydocuments")
00429 || (m_sMimeType == "media/builtin-mycomputer")
00430 || (m_sMimeType == "media/builtin-mynetworkplaces")
00431 || (m_sMimeType == "media/builtin-printers")
00432 || (m_sMimeType == "media/builtin-trash")
00433 || (m_sMimeType == "media/builtin-webbrowser")) ) {
00434 KSimpleConfig cfg( firstPopupURL.path(), true );
00435 cfg.setDesktopGroup();
00436 isTrashLink = ( cfg.readEntry("Type") == "Link" && cfg.readEntry("URL") == "trash:/" );
00437 }
00438
00439 if ( isTrashLink ) {
00440 sDeleting = false;
00441 }
00442 }
00443
00444 m_info.m_Reading = sReading;
00445 m_info.m_Writing = sWriting;
00446 m_info.m_Deleting = sDeleting;
00447 m_info.m_Moving = sMoving;
00448 m_info.m_TrashIncluded = bTrashIncluded;
00449
00450
00451 bool isCurrentTrash = ( m_lstItems.count() == 1 && bTrashIncluded ) || isTrashLink;
00452 bool isIntoTrash = ( url.protocol() == "trash" || url.url().startsWith( "system:/trash" ) ) && !isCurrentTrash;
00453
00454 bool isSingleMedium = m_lstItems.count() == 1 && mediaFiles;
00455 clear();
00456
00458
00459 KAction * act;
00460
00461 if (!isCurrentTrash)
00462 addMerge( "konqueror" );
00463
00464 bool isKDesktop = TQCString( kapp->name() ) == "kdesktop";
00465 KAction *actNewWindow = 0;
00466
00467 if (( kpf & ShowProperties ) && isKDesktop &&
00468 !kapp->authorize("editable_desktop_icons"))
00469 {
00470 kpf &= ~ShowProperties;
00471 }
00472
00473
00474
00475 if ( ((kpf & ShowNewWindow) != 0) && sReading )
00476 {
00477 TQString openStr = isKDesktop ? i18n( "&Open" ) : i18n( "Open in New &Window" );
00478 actNewWindow = new KAction( openStr, "window_new", 0, this, TQT_SLOT( slotPopupNewView() ), &m_ownActions, "newview" );
00479 }
00480
00481 if ( actNewWindow && !isKDesktop )
00482 {
00483 if (isCurrentTrash)
00484 actNewWindow->setToolTip( i18n( "Open the trash in a new window" ) );
00485 else if (isSingleMedium)
00486 actNewWindow->setToolTip( i18n( "Open the medium in a new window") );
00487 else
00488 actNewWindow->setToolTip( i18n( "Open the document in a new window" ) );
00489 }
00490
00491 if ( S_ISDIR(mode) && sWriting && !isCurrentTrash )
00492 {
00493 if ( currentDir && m_pMenuNew )
00494 {
00495
00496 m_pMenuNew->slotCheckUpToDate();
00497 m_pMenuNew->setPopupFiles( m_lstPopupURLs );
00498
00499 addAction( m_pMenuNew );
00500
00501 addSeparator();
00502 }
00503 else
00504 {
00505 if (d->m_itemFlags & KParts::BrowserExtension::ShowCreateDirectory)
00506 {
00507 KAction *actNewDir = new KAction( i18n( "Create &Folder..." ), "folder_new", 0, this, TQT_SLOT( slotPopupNewDir() ), &m_ownActions, "newdir" );
00508 addAction( actNewDir );
00509 addSeparator();
00510 }
00511 }
00512 } else if ( isIntoTrash ) {
00513
00514 act = new KAction( i18n( "&Restore" ), 0, this, TQT_SLOT( slotPopupRestoreTrashedItems() ), &m_ownActions, "restore" );
00515 addAction( act );
00516 }
00517
00518 if (d->m_itemFlags & KParts::BrowserExtension::ShowNavigationItems)
00519 {
00520 if (d->m_itemFlags & KParts::BrowserExtension::ShowUp)
00521 addAction( "up" );
00522 addAction( "back" );
00523 addAction( "forward" );
00524 if (d->m_itemFlags & KParts::BrowserExtension::ShowReload)
00525 addAction( "reload" );
00526 addSeparator();
00527 }
00528
00529
00530 if (actNewWindow)
00531 {
00532 addAction( actNewWindow );
00533 addSeparator();
00534 }
00535 addGroup( "tabhandling" );
00536
00537 if ( !bIsLink )
00538 {
00539 if ( !currentDir && sReading ) {
00540 if ( sDeleting ) {
00541 addAction( "cut" );
00542 }
00543 addAction( "copy" );
00544 }
00545
00546 if ( S_ISDIR(mode) && sWriting ) {
00547 if ( currentDir )
00548 addAction( "paste" );
00549 else
00550 addAction( "pasteto" );
00551 }
00552 if ( !currentDir )
00553 {
00554 if ( m_lstItems.count() == 1 && sMoving )
00555 addAction( "rename" );
00556
00557 bool addTrash = false;
00558 bool addDel = false;
00559
00560 if ( sMoving && !isIntoTrash && !isTrashLink )
00561 addTrash = true;
00562
00563 if ( sDeleting ) {
00564 if ( !isLocal )
00565 addDel = true;
00566 else if (KApplication::keyboardMouseState() & Qt::ShiftButton) {
00567 addTrash = false;
00568 addDel = true;
00569 }
00570 else {
00571 KConfigGroup configGroup( kapp->config(), "KDE" );
00572 if ( configGroup.readBoolEntry( "ShowDeleteCommand", false ) )
00573 addDel = true;
00574 }
00575 }
00576
00577 if ( addTrash )
00578 addAction( "trash" );
00579 if ( addDel )
00580 addAction( "del" );
00581 }
00582 }
00583 if ( isCurrentTrash )
00584 {
00585 act = new KAction( i18n( "&Empty Trash Bin" ), "emptytrash", 0, this, TQT_SLOT( slotPopupEmptyTrashBin() ), &m_ownActions, "empytrash" );
00586 KSimpleConfig trashConfig( "trashrc", true );
00587 trashConfig.setGroup( "Status" );
00588 act->setEnabled( !trashConfig.readBoolEntry( "Empty", true ) );
00589 addAction( act );
00590 }
00591 addGroup( "editactions" );
00592
00593 if (d->m_itemFlags & KParts::BrowserExtension::ShowTextSelectionItems) {
00594 addMerge( 0 );
00595 m_factory->addClient( this );
00596 return;
00597 }
00598
00599 if ( !isCurrentTrash && !isIntoTrash && (d->m_itemFlags & KParts::BrowserExtension::ShowBookmark))
00600 {
00601 addSeparator();
00602 TQString caption;
00603 if (currentDir)
00604 {
00605 bool httpPage = (m_sViewURL.protocol().find("http", 0, false) == 0);
00606 if (httpPage)
00607 caption = i18n("&Bookmark This Page");
00608 else
00609 caption = i18n("&Bookmark This Location");
00610 }
00611 else if (S_ISDIR(mode))
00612 caption = i18n("&Bookmark This Folder");
00613 else if (bIsLink)
00614 caption = i18n("&Bookmark This Link");
00615 else
00616 caption = i18n("&Bookmark This File");
00617
00618 act = new KAction( caption, "bookmark_add", 0, this, TQT_SLOT( slotPopupAddToBookmark() ), &m_ownActions, "bookmark_add" );
00619 if (m_lstItems.count() > 1)
00620 act->setEnabled(false);
00621 if (kapp->authorizeKAction("bookmarks"))
00622 addAction( act );
00623 if (bIsLink)
00624 addGroup( "linkactions" );
00625 }
00626
00628
00629 const bool isSingleLocal = m_lstItems.count() == 1 && isLocal;
00630 PopupServices s;
00631 KURL urlForServiceMenu( m_lstItems.first()->url() );
00632 if (isLocal && !isReallyLocal) {
00633 bool dummy;
00634 urlForServiceMenu = m_lstItems.first()->mostLocalURL(dummy);
00635 }
00636
00637
00638 if ( ((m_sMimeType == "application/x-desktop")
00639 || (m_sMimeType == "media/builtin-mydocuments")
00640 || (m_sMimeType == "media/builtin-mycomputer")
00641 || (m_sMimeType == "media/builtin-mynetworkplaces")
00642 || (m_sMimeType == "media/builtin-printers")
00643 || (m_sMimeType == "media/builtin-trash")
00644 || (m_sMimeType == "media/builtin-webbrowser")) && isSingleLocal )
00645 {
00646
00647 s.builtin = KDEDesktopMimeType::builtinServices( urlForServiceMenu );
00648 const TQString path = urlForServiceMenu.path();
00649 KSimpleConfig cfg( path, true );
00650 cfg.setDesktopGroup();
00651 const TQString priority = cfg.readEntry("X-KDE-Priority");
00652 const TQString submenuName = cfg.readEntry( "X-KDE-Submenu" );
00653 if ( cfg.readEntry("Type") == "Link" ) {
00654 urlForServiceMenu = cfg.readEntry("URL");
00655
00656
00657 }
00658 ServiceList* list = s.selectList( priority, submenuName );
00659 (*list) = KDEDesktopMimeType::userDefinedServices( path, cfg, urlForServiceMenu.isLocalFile() );
00660 }
00661
00662 if ( sReading )
00663 {
00664
00665
00666
00667
00668 if (isDirectory && isSingleLocal)
00669 {
00670 TQString dotDirectoryFile = urlForServiceMenu.path(1).append(".directory");
00671 KSimpleConfig cfg( dotDirectoryFile, true );
00672 cfg.setDesktopGroup();
00673
00674 if (KIOSKAuthorizedAction(cfg))
00675 {
00676 const TQString priority = cfg.readEntry("X-KDE-Priority");
00677 const TQString submenuName = cfg.readEntry( "X-KDE-Submenu" );
00678 ServiceList* list = s.selectList( priority, submenuName );
00679 (*list) += KDEDesktopMimeType::userDefinedServices( dotDirectoryFile, cfg, true );
00680 }
00681 }
00682
00683
00684 const TQStringList entries = KGlobal::dirs()->findAllResources("data",
00685 "konqueror/servicemenus/*.desktop",
00686 false ,
00687 true );
00688 TQStringList::ConstIterator eIt = entries.begin();
00689 const TQStringList::ConstIterator eEnd = entries.end();
00690 for (; eIt != eEnd; ++eIt )
00691 {
00692 KSimpleConfig cfg( *eIt, true );
00693 cfg.setDesktopGroup();
00694
00695 if (!KIOSKAuthorizedAction(cfg))
00696 {
00697 continue;
00698 }
00699
00700 if ( cfg.hasKey( "X-KDE-ShowIfRunning" ) )
00701 {
00702 const TQString app = cfg.readEntry( "X-KDE-ShowIfRunning" );
00703 if ( !kapp->dcopClient()->isApplicationRegistered( app.utf8() ) )
00704 continue;
00705 }
00706 if ( cfg.hasKey( "X-KDE-ShowIfDcopCall" ) )
00707 {
00708 TQString dcopcall = cfg.readEntry( "X-KDE-ShowIfDcopCall" );
00709 const TQCString app = dcopcall.section(' ', 0,0).utf8();
00710
00711
00712
00713
00714 TQByteArray dataToSend;
00715 TQDataStream dataStream(dataToSend, IO_WriteOnly);
00716 dataStream << m_lstPopupURLs;
00717
00718 TQCString replyType;
00719 TQByteArray replyData;
00720 TQCString object = dcopcall.section(' ', 1,-2).utf8();
00721 TQString function = dcopcall.section(' ', -1);
00722 if(!function.endsWith("(KURL::List)")) {
00723 kdWarning() << "Desktop file " << *eIt << " contains an invalid X-KDE-ShowIfDcopCall - the function must take the exact parameter (KURL::List) and must be specified." << endl;
00724 continue;
00725 }
00726
00727 if(!kapp->dcopClient()->call( app, object,
00728 function.utf8(),
00729 dataToSend, replyType, replyData, true, 1000))
00730 continue;
00731 if(replyType != "bool" || !replyData[0])
00732 continue;
00733
00734 }
00735 if ( cfg.hasKey( "X-KDE-Protocol" ) )
00736 {
00737 const TQString protocol = cfg.readEntry( "X-KDE-Protocol" );
00738 if ( protocol != urlForServiceMenu.protocol() )
00739 continue;
00740 }
00741 else if ( cfg.hasKey( "X-KDE-Protocols" ) )
00742 {
00743 TQStringList protocols = TQStringList::split( "," , cfg.readEntry( "X-KDE-Protocols" ) );
00744 if ( !protocols.contains( urlForServiceMenu.protocol() ) )
00745 continue;
00746 }
00747 else if ( urlForServiceMenu.protocol() == "trash" || urlForServiceMenu.url().startsWith( "system:/trash" ) )
00748 {
00749
00750
00751
00752 continue;
00753 }
00754
00755 if ( cfg.hasKey( "X-KDE-Require" ) )
00756 {
00757 const TQStringList capabilities = cfg.readListEntry( "X-KDE-Require" );
00758 if ( capabilities.contains( "Write" ) && !sWriting )
00759 continue;
00760 }
00761 if ( (cfg.hasKey( "Actions" ) || cfg.hasKey( "X-KDE-GetActionMenu") ) && cfg.hasKey( "ServiceTypes" ) )
00762 {
00763 const TQStringList types = cfg.readListEntry( "ServiceTypes" );
00764 const TQStringList excludeTypes = cfg.readListEntry( "ExcludeServiceTypes" );
00765 bool ok = false;
00766
00767
00768 for (TQStringList::ConstIterator it = types.begin();
00769 it != types.end() && !ok;
00770 ++it)
00771 {
00772
00773 bool checkTheMimetypes = false;
00774 if (*it == "all/all" ||
00775 *it == "allfiles" )
00776 {
00777 checkTheMimetypes = true;
00778 }
00779
00780
00781 if (!ok &&
00782 !isDirectory &&
00783 *it == "all/allfiles")
00784 {
00785 checkTheMimetypes = true;
00786 }
00787
00788
00789 if (!ok &&
00790 (!m_sMimeType.isEmpty() &&
00791 *it == m_sMimeType) ||
00792 (!mimeGroup.isEmpty() &&
00793 ((*it).right(1) == "*" &&
00794 (*it).left((*it).find('/')) == mimeGroup)))
00795 {
00796 checkTheMimetypes = true;
00797 }
00798
00799 if (checkTheMimetypes)
00800 {
00801 ok = true;
00802 for (TQStringList::ConstIterator itex = excludeTypes.begin(); itex != excludeTypes.end(); ++itex)
00803 {
00804 if( ((*itex).right(1) == "*" && (*itex).left((*itex).find('/')) == mimeGroup) ||
00805 ((*itex) == m_sMimeType) )
00806 {
00807 ok = false;
00808 break;
00809 }
00810 }
00811 }
00812 }
00813
00814 if ( ok )
00815 {
00816 const TQString priority = cfg.readEntry("X-KDE-Priority");
00817 const TQString submenuName = cfg.readEntry( "X-KDE-Submenu" );
00818
00819 ServiceList* list = s.selectList( priority, submenuName );
00820 (*list) += KDEDesktopMimeType::userDefinedServices( *eIt, cfg, url.isLocalFile(), m_lstPopupURLs );
00821 }
00822 }
00823 }
00824
00825 KTrader::OfferList offers;
00826
00827 if (kapp->authorizeKAction("openwith"))
00828 {
00829 TQString constraint = "Type == 'Application' and DesktopEntryName != 'kfmclient' and DesktopEntryName != 'kfmclient_dir' and DesktopEntryName != 'kfmclient_html'";
00830 TQString subConstraint = " and '%1' in ServiceTypes";
00831
00832 TQStringList::ConstIterator it = mimeTypeList.begin();
00833 TQStringList::ConstIterator end = mimeTypeList.end();
00834 Q_ASSERT( it != end );
00835 TQString first = *it;
00836 ++it;
00837 while ( it != end ) {
00838 constraint += subConstraint.arg( *it );
00839 ++it;
00840 }
00841
00842 offers = KTrader::self()->query( first, constraint );
00843 }
00844
00846
00847 m_mapPopup.clear();
00848 m_mapPopupServices.clear();
00849
00850
00851 if ( !isDirectory || isLocal )
00852 {
00853 if ( hasAction() )
00854 addSeparator();
00855
00856 if ( !offers.isEmpty() )
00857 {
00858
00859 id = 1;
00860
00861 TQDomElement menu = m_menuElement;
00862
00863 if ( offers.count() > 1 )
00864 {
00865 menu = m_doc.createElement( "menu" );
00866 menu.setAttribute( "name", "openwith submenu" );
00867 m_menuElement.appendChild( menu );
00868 TQDomElement text = m_doc.createElement( "text" );
00869 menu.appendChild( text );
00870 text.appendChild( m_doc.createTextNode( i18n("&Open With") ) );
00871 }
00872
00873 KTrader::OfferList::ConstIterator it = offers.begin();
00874 for( ; it != offers.end(); it++ )
00875 {
00876 KService::Ptr service = (*it);
00877
00878
00879
00880
00881
00882 const TQString onlyShowIn = service->property("OnlyShowIn", TQVariant::String).toString();
00883 if ( !onlyShowIn.isEmpty() ) {
00884 const TQStringList aList = TQStringList::split(';', onlyShowIn);
00885 if (!aList.contains("KDE"))
00886 continue;
00887 }
00888 const TQString notShowIn = service->property("NotShowIn", TQVariant::String).toString();
00889 if ( !notShowIn.isEmpty() ) {
00890 const TQStringList aList = TQStringList::split(';', notShowIn);
00891 if (aList.contains("KDE"))
00892 continue;
00893 }
00894
00895 TQCString nam;
00896 nam.setNum( id );
00897
00898 TQString actionName( (*it)->name().replace("&", "&&") );
00899 if ( menu == m_menuElement )
00900 actionName = i18n( "Open with %1" ).arg( actionName );
00901
00902 act = new KAction( actionName, (*it)->pixmap( KIcon::Small ), 0,
00903 this, TQT_SLOT( slotRunService() ),
00904 &m_ownActions, nam.prepend( "appservice_" ) );
00905 addAction( act, menu );
00906
00907 m_mapPopup[ id++ ] = *it;
00908 }
00909
00910 TQString openWithActionName;
00911 if ( menu != m_menuElement )
00912 {
00913 addSeparator( menu );
00914 openWithActionName = i18n( "&Other..." );
00915 }
00916 else
00917 {
00918 openWithActionName = i18n( "&Open With..." );
00919 }
00920 KAction *openWithAct = new KAction( openWithActionName, 0, this, TQT_SLOT( slotPopupOpenWith() ), &m_ownActions, "openwith" );
00921 addAction( openWithAct, menu );
00922 }
00923 else
00924 {
00925 act = new KAction( i18n( "&Open With..." ), 0, this, TQT_SLOT( slotPopupOpenWith() ), &m_ownActions, "openwith" );
00926 addAction( act );
00927 }
00928
00929 }
00930 addGroup( "preview" );
00931 }
00932
00933
00934 TQDomElement actionMenu = m_menuElement;
00935 int userItemCount = 0;
00936 if (s.user.count() + s.userSubmenus.count() +
00937 s.userPriority.count() + s.userPrioritySubmenus.count() > 1)
00938 {
00939
00940 actionMenu = m_doc.createElement( "menu" );
00941 actionMenu.setAttribute( "name", "actions submenu" );
00942 m_menuElement.appendChild( actionMenu );
00943 TQDomElement text = m_doc.createElement( "text" );
00944 actionMenu.appendChild( text );
00945 text.appendChild( m_doc.createTextNode( i18n("Ac&tions") ) );
00946 }
00947
00948 userItemCount += insertServicesSubmenus(s.userPrioritySubmenus, actionMenu, false);
00949 userItemCount += insertServices(s.userPriority, actionMenu, false);
00950
00951
00952 if (userItemCount > 0 &&
00953 (s.user.count() > 0 ||
00954 s.userSubmenus.count() > 0 ||
00955 s.builtin.count() > 0) &&
00956 actionMenu.lastChild().toElement().tagName().lower() != "separator")
00957 {
00958 TQDomElement separator = m_doc.createElement( "separator" );
00959 actionMenu.appendChild(separator);
00960 }
00961
00962 userItemCount += insertServicesSubmenus(s.userSubmenus, actionMenu, false);
00963 userItemCount += insertServices(s.user, actionMenu, false);
00964 userItemCount += insertServices(s.builtin, m_menuElement, true);
00965
00966 userItemCount += insertServicesSubmenus(s.userToplevelSubmenus, m_menuElement, false);
00967 userItemCount += insertServices(s.userToplevel, m_menuElement, false);
00968
00969 if ( userItemCount > 0 )
00970 {
00971 addPendingSeparator();
00972 }
00973
00974 if ( !isCurrentTrash && !isIntoTrash && !mediaFiles && sReading )
00975 addPlugins();
00976
00977 if ( KPropertiesDialog::canDisplay( m_lstItems ) && (kpf & ShowProperties) )
00978 {
00979 act = new KAction( i18n( "&Properties" ), 0, this, TQT_SLOT( slotPopupProperties() ),
00980 &m_ownActions, "properties" );
00981 addAction( act );
00982 }
00983
00984 while ( !m_menuElement.lastChild().isNull() &&
00985 m_menuElement.lastChild().toElement().tagName().lower() == "separator" )
00986 m_menuElement.removeChild( m_menuElement.lastChild() );
00987
00988 if ( isDirectory && isLocal )
00989 {
00990 if ( KFileShare::authorization() == KFileShare::Authorized )
00991 {
00992 addSeparator();
00993 act = new KAction( i18n("Share"), 0, this, TQT_SLOT( slotOpenShareFileDialog() ),
00994 &m_ownActions, "sharefile" );
00995 addAction( act );
00996 }
00997 }
00998
00999 addMerge( 0 );
01000
01001
01002 m_factory->addClient( this );
01003 }
01004
01005 void KonqPopupMenu::slotOpenShareFileDialog()
01006 {
01007 KPropertiesDialog* dlg = showPropertiesDialog();
01008 dlg->showFileSharingPage();
01009 }
01010
01011 KonqPopupMenu::~KonqPopupMenu()
01012 {
01013 m_pluginList.clear();
01014 delete m_factory;
01015 delete m_builder;
01016 delete d;
01017
01018 }
01019
01020 void KonqPopupMenu::setURLTitle( const TQString& urlTitle )
01021 {
01022 d->m_urlTitle = urlTitle;
01023 }
01024
01025 void KonqPopupMenu::slotPopupNewView()
01026 {
01027 KURL::List::ConstIterator it = m_lstPopupURLs.begin();
01028 for ( ; it != m_lstPopupURLs.end(); it++ )
01029 (void) new KRun(*it);
01030 }
01031
01032 void KonqPopupMenu::slotPopupNewDir()
01033 {
01034 if (m_lstPopupURLs.empty())
01035 return;
01036
01037 KonqOperations::newDir(d->m_parentWidget, m_lstPopupURLs.first());
01038 }
01039
01040 void KonqPopupMenu::slotPopupEmptyTrashBin()
01041 {
01042 KonqOperations::emptyTrash();
01043 }
01044
01045 void KonqPopupMenu::slotPopupRestoreTrashedItems()
01046 {
01047 KonqOperations::restoreTrashedItems( m_lstPopupURLs );
01048 }
01049
01050 void KonqPopupMenu::slotPopupOpenWith()
01051 {
01052 KRun::displayOpenWithDialog( m_lstPopupURLs );
01053 }
01054
01055 void KonqPopupMenu::slotPopupAddToBookmark()
01056 {
01057 KBookmarkGroup root;
01058 if ( m_lstPopupURLs.count() == 1 ) {
01059 KURL url = m_lstPopupURLs.first();
01060 TQString title = d->m_urlTitle.isEmpty() ? url.prettyURL() : d->m_urlTitle;
01061 root = m_pManager->addBookmarkDialog( url.prettyURL(), title );
01062 }
01063 else
01064 {
01065 root = m_pManager->root();
01066 KURL::List::ConstIterator it = m_lstPopupURLs.begin();
01067 for ( ; it != m_lstPopupURLs.end(); it++ )
01068 root.addBookmark( m_pManager, (*it).prettyURL(), (*it) );
01069 }
01070 m_pManager->emitChanged( root );
01071 }
01072
01073 void KonqPopupMenu::slotRunService()
01074 {
01075 TQCString senderName = sender()->name();
01076 int id = senderName.mid( senderName.find( '_' ) + 1 ).toInt();
01077
01078
01079 TQMap<int,KService::Ptr>::Iterator it = m_mapPopup.find( id );
01080 if ( it != m_mapPopup.end() )
01081 {
01082 KRun::run( **it, m_lstPopupURLs );
01083 return;
01084 }
01085
01086
01087 TQMap<int,KDEDesktopMimeType::Service>::Iterator it2 = m_mapPopupServices.find( id );
01088 if ( it2 != m_mapPopupServices.end() )
01089 {
01090 KDEDesktopMimeType::executeService( m_lstPopupURLs, it2.data() );
01091 }
01092
01093 return;
01094 }
01095
01096 void KonqPopupMenu::slotPopupMimeType()
01097 {
01098 KonqOperations::editMimeType( m_sMimeType );
01099 }
01100
01101 void KonqPopupMenu::slotPopupProperties()
01102 {
01103 (void)showPropertiesDialog();
01104 }
01105
01106 KPropertiesDialog* KonqPopupMenu::showPropertiesDialog()
01107 {
01108
01109
01110
01111
01112 if ( m_lstItems.count() == 1 )
01113 {
01114 KFileItem * item = m_lstItems.first();
01115 if (item->entry().count() == 0)
01116 {
01117
01118 return new KPropertiesDialog( item->url(), d->m_parentWidget );
01119 }
01120 }
01121 return new KPropertiesDialog( m_lstItems, d->m_parentWidget );
01122 }
01123
01124 KAction *KonqPopupMenu::action( const TQDomElement &element ) const
01125 {
01126 TQCString name = element.attribute( attrName ).ascii();
01127 KAction *res = m_ownActions.action( name );
01128
01129 if ( !res )
01130 res = m_actions.action( name );
01131
01132 if ( !res && m_pMenuNew && strcmp( name, m_pMenuNew->name() ) == 0 )
01133 return m_pMenuNew;
01134
01135 return res;
01136 }
01137
01138 KActionCollection *KonqPopupMenu::actionCollection() const
01139 {
01140 return const_cast<KActionCollection *>( &m_ownActions );
01141 }
01142
01143 TQString KonqPopupMenu::mimeType() const
01144 {
01145 return m_sMimeType;
01146 }
01147
01148 KonqPopupMenu::ProtocolInfo KonqPopupMenu::protocolInfo() const
01149 {
01150 return m_info;
01151 }
01152
01153 void KonqPopupMenu::addPlugins()
01154 {
01155
01156
01157 KTrader::OfferList plugin_offers;
01158 unsigned int pluginCount = 0;
01159 plugin_offers = KTrader::self()->query( m_sMimeType.isNull() ? TQString::fromLatin1( "all/all" ) : m_sMimeType, "'KonqPopupMenu/Plugin' in ServiceTypes");
01160 if ( plugin_offers.isEmpty() )
01161 return;
01162
01163 KTrader::OfferList::ConstIterator iterator = plugin_offers.begin();
01164 KTrader::OfferList::ConstIterator end = plugin_offers.end();
01165
01166 addGroup( "plugins" );
01167
01168 for(; iterator != end; ++iterator, ++pluginCount ) {
01169
01170 KonqPopupMenuPlugin *plugin =
01171 KParts::ComponentFactory::
01172 createInstanceFromLibrary<KonqPopupMenuPlugin>( TQFile::encodeName( (*iterator)->library() ),
01173 this,
01174 (*iterator)->name().latin1() );
01175 if ( !plugin )
01176 continue;
01177
01178 TQString pluginClientName = TQString::fromLatin1( "Plugin%1" ).arg( pluginCount );
01179 addMerge( pluginClientName );
01180 plugin->domDocument().documentElement().setAttribute( "name", pluginClientName );
01181 m_pluginList.append( plugin );
01182 insertChildClient( plugin );
01183 }
01184
01185
01186 addMerge( "plugins" );
01187 }
01188
01189 KURL KonqPopupMenu::url() const
01190 {
01191 return m_sViewURL;
01192 }
01193
01194 KFileItemList KonqPopupMenu::fileItemList() const
01195 {
01196 return m_lstItems;
01197 }
01198
01199 KURL::List KonqPopupMenu::popupURLList() const
01200 {
01201 return m_lstPopupURLs;
01202 }
01203
01208 KonqPopupMenuPlugin::KonqPopupMenuPlugin( KonqPopupMenu *parent, const char *name )
01209 : TQObject( parent, name )
01210 {
01211 }
01212
01213 KonqPopupMenuPlugin::~KonqPopupMenuPlugin()
01214 {
01215 }
01216
01217 #include "konq_popupmenu.moc"