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