00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qdir.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( QPopupMenu *menu )
00074 : KXMLGUIBuilder( 0 )
00075 {
00076 m_menu = menu;
00077 }
00078 virtual ~KonqPopupMenuGUIBuilder()
00079 {
00080 }
00081
00082 virtual QWidget *createContainer( QWidget *parent, int index,
00083 const QDomElement &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 QPopupMenu *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 QString m_urlTitle;
00103 QWidget *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 QString& priority, const QString& submenuName );
00147
00148 ServiceList builtin;
00149 ServiceList user, userToplevel, userPriority;
00150 QMap<QString, ServiceList> userSubmenus, userToplevelSubmenus, userPrioritySubmenus;
00151 };
00152
00153 ServiceList* PopupServices::selectList( const QString& priority, const QString& 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 : QPopupMenu( 0L, "konq_popupmenu" ),
00191 m_actions( actions ), m_ownActions( static_cast<QWidget *>( 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 QWidget * parentWidget,
00203 bool showProperties )
00204 : QPopupMenu( parentWidget, "konq_popupmenu" ), m_actions( actions ), m_ownActions( static_cast<QWidget *>( 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 QWidget * parentWidget,
00215 KonqPopupFlags kpf,
00216 KParts::BrowserExtension::PopupFlags flags)
00217 : QPopupMenu( parentWidget, "konq_popupmenu" ), m_actions( actions ), m_ownActions( static_cast<QWidget *>( 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 (QWidget * 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 QMap<QString, ServiceList>& submenus,
00231 QDomElement& menu,
00232 bool isBuiltin)
00233 {
00234 int count = 0;
00235 QMap<QString, 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 QDomElement actionSubmenu = m_doc.createElement( "menu" );
00246 actionSubmenu.setAttribute( "name", "actions " + it.key() );
00247 menu.appendChild( actionSubmenu );
00248 QDomElement 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 QDomElement& 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 QDomElement separator = m_doc.createElement( "separator" );
00273 menu.appendChild(separator);
00274 }
00275 continue;
00276 }
00277
00278 if (isBuiltin || (*it).m_display == true)
00279 {
00280 QCString name;
00281 name.setNum( id );
00282 name.prepend( isBuiltin ? "builtinservice_" : "userservice_" );
00283 KAction * act = new KAction( QString((*it).m_strName).replace('&',"&&"), 0,
00284 this, SLOT( slotRunService() ),
00285 &m_ownActions, name );
00286
00287 if ( !(*it).m_strIcon.isEmpty() )
00288 {
00289 QPixmap 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 QStringList list = cfg.readListEntry("X-KDE-AuthorizeAction");
00311 if (kapp && !list.isEmpty())
00312 {
00313 for(QStringList::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 QString 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 isLocal = m_lstItems.first()->isLocalFile()
00347 || m_lstItems.first()->url().protocol()=="media"
00348 || m_lstItems.first()->url().protocol()=="system";
00349 bool isTrashLink = false;
00350 m_lstPopupURLs.clear();
00351 int id = 0;
00352 setFont(KGlobalSettings::menuFont());
00353 m_pluginList.setAutoDelete( true );
00354 m_ownActions.setHighlightingEnabled( true );
00355
00356 attrName = QString::fromLatin1( "name" );
00357
00358 prepareXMLGUIStuff();
00359 m_builder = new KonqPopupMenuGUIBuilder( this );
00360 m_factory = new KXMLGUIFactory( m_builder );
00361
00362 KURL url;
00363 KFileItemListIterator it ( m_lstItems );
00364 QStringList mimeTypeList;
00365
00366 for ( ; it.current(); ++it )
00367 {
00368 url = (*it)->url();
00369
00370
00371 m_lstPopupURLs.append( url );
00372
00373
00374 if ( mode != (*it)->mode() )
00375 mode = 0;
00376
00377
00378 if ( m_sMimeType != (*it)->mimetype() )
00379 {
00380 m_sMimeType = QString::null;
00381
00382 if ( mimeGroup != (*it)->mimetype().left((*it)->mimetype().find('/')))
00383 mimeGroup = QString::null;
00384 }
00385
00386 if ( mimeTypeList.findIndex( (*it)->mimetype() ) == -1 )
00387 mimeTypeList << (*it)->mimetype();
00388
00389 if ( isLocal && !url.isLocalFile() && url.protocol() != "media" && url.protocol() != "system" )
00390 isLocal = false;
00391
00392 if ( !bTrashIncluded && (
00393 ( url.protocol() == "trash" && url.path().length() <= 1 )
00394 || url.url() == "system:/trash" || url.url() == "system:/trash/" ) ) {
00395 bTrashIncluded = true;
00396 isLocal = false;
00397 }
00398
00399 if ( sReading )
00400 sReading = KProtocolInfo::supportsReading( url );
00401
00402 if ( sWriting )
00403 sWriting = KProtocolInfo::supportsWriting( url ) && (*it)->isWritable();
00404
00405 if ( sDeleting )
00406 sDeleting = KProtocolInfo::supportsDeleting( url );
00407
00408 if ( sMoving )
00409 sMoving = KProtocolInfo::supportsMoving( url );
00410 if ( (*it)->mimetype().startsWith("media/") )
00411 mediaFiles = true;
00412 }
00413 url = m_sViewURL;
00414 url.cleanPath();
00415
00416
00417 if ( m_lstItems.count() == 1 )
00418 {
00419 KURL firstPopupURL( m_lstItems.first()->url() );
00420 firstPopupURL.cleanPath();
00421
00422
00423 currentDir = firstPopupURL.equals( url, true );
00424 if ( isLocal && m_sMimeType == "application/x-desktop" ) {
00425 KSimpleConfig cfg( firstPopupURL.path(), true );
00426 cfg.setDesktopGroup();
00427 isTrashLink = ( cfg.readEntry("Type") == "Link" && cfg.readEntry("URL") == "trash:/" );
00428 }
00429
00430 if ( isTrashLink ) {
00431 sDeleting = false;
00432 }
00433 }
00434 const bool isSingleLocal = m_lstItems.count() == 1 && isLocal;
00435
00436 m_info.m_Reading = sReading;
00437 m_info.m_Writing = sWriting;
00438 m_info.m_Deleting = sDeleting;
00439 m_info.m_Moving = sMoving;
00440 m_info.m_TrashIncluded = bTrashIncluded;
00441
00442
00443 bool isCurrentTrash = ( m_lstItems.count() == 1 && bTrashIncluded ) || isTrashLink;
00444 bool isIntoTrash = ( url.protocol() == "trash" || url.url().startsWith( "system:/trash" ) ) && !isCurrentTrash;
00445
00446 bool isSingleMedium = m_lstItems.count() == 1 && mediaFiles;
00447 clear();
00448
00450
00451 KAction * act;
00452
00453 if (!isCurrentTrash)
00454 addMerge( "konqueror" );
00455
00456 bool isKDesktop = QCString( kapp->name() ) == "kdesktop";
00457 KAction *actNewWindow = 0;
00458
00459 if (( kpf & ShowProperties ) && isKDesktop &&
00460 !kapp->authorize("editable_desktop_icons"))
00461 {
00462 kpf &= ~ShowProperties;
00463 }
00464
00465
00466
00467 if ( ((kpf & ShowNewWindow) != 0) && sReading )
00468 {
00469 QString openStr = isKDesktop ? i18n( "&Open" ) : i18n( "Open in New &Window" );
00470 actNewWindow = new KAction( openStr, "window_new", 0, this, SLOT( slotPopupNewView() ), &m_ownActions, "newview" );
00471 }
00472
00473 if ( actNewWindow && !isKDesktop )
00474 {
00475 if (isCurrentTrash)
00476 actNewWindow->setToolTip( i18n( "Open the trash in a new window" ) );
00477 else if (isSingleMedium)
00478 actNewWindow->setToolTip( i18n( "Open the medium in a new window") );
00479 else
00480 actNewWindow->setToolTip( i18n( "Open the document in a new window" ) );
00481 }
00482
00483 if ( S_ISDIR(mode) && sWriting && !isCurrentTrash )
00484 {
00485 if ( currentDir && m_pMenuNew )
00486 {
00487
00488 m_pMenuNew->slotCheckUpToDate();
00489 m_pMenuNew->setPopupFiles( m_lstPopupURLs );
00490
00491 addAction( m_pMenuNew );
00492
00493 addSeparator();
00494 }
00495 else
00496 {
00497 if (d->m_itemFlags & KParts::BrowserExtension::ShowCreateDirectory)
00498 {
00499 KAction *actNewDir = new KAction( i18n( "Create &Folder..." ), "folder_new", 0, this, SLOT( slotPopupNewDir() ), &m_ownActions, "newdir" );
00500 addAction( actNewDir );
00501 addSeparator();
00502 }
00503 }
00504 } else if ( isIntoTrash ) {
00505
00506 act = new KAction( i18n( "&Restore" ), 0, this, SLOT( slotPopupRestoreTrashedItems() ), &m_ownActions, "restore" );
00507 addAction( act );
00508 }
00509
00510 if (d->m_itemFlags & KParts::BrowserExtension::ShowNavigationItems)
00511 {
00512 if (d->m_itemFlags & KParts::BrowserExtension::ShowUp)
00513 addAction( "up" );
00514 addAction( "back" );
00515 addAction( "forward" );
00516 if (d->m_itemFlags & KParts::BrowserExtension::ShowReload)
00517 addAction( "reload" );
00518 addSeparator();
00519 }
00520
00521
00522 if (actNewWindow)
00523 {
00524 addAction( actNewWindow );
00525 addSeparator();
00526 }
00527 addGroup( "tabhandling" );
00528
00529 if ( !bIsLink )
00530 {
00531 if ( !currentDir && sReading ) {
00532 if ( sDeleting ) {
00533 addAction( "cut" );
00534 }
00535 addAction( "copy" );
00536 }
00537
00538 if ( S_ISDIR(mode) && sWriting ) {
00539 if ( currentDir )
00540 addAction( "paste" );
00541 else
00542 addAction( "pasteto" );
00543 }
00544 if ( !currentDir )
00545 {
00546 if ( m_lstItems.count() == 1 && sMoving )
00547 addAction( "rename" );
00548
00549 bool addTrash = false;
00550 bool addDel = false;
00551
00552 if ( sMoving && !isIntoTrash && !isTrashLink )
00553 addTrash = true;
00554
00555 if ( sDeleting ) {
00556 if ( !isLocal )
00557 addDel = true;
00558 else if (KApplication::keyboardMouseState() & Qt::ShiftButton) {
00559 addTrash = false;
00560 addDel = true;
00561 }
00562 else {
00563 KConfigGroup configGroup( kapp->config(), "KDE" );
00564 if ( configGroup.readBoolEntry( "ShowDeleteCommand", false ) )
00565 addDel = true;
00566 }
00567 }
00568
00569 if ( addTrash )
00570 addAction( "trash" );
00571 if ( addDel )
00572 addAction( "del" );
00573 }
00574 }
00575 if ( isCurrentTrash )
00576 {
00577 act = new KAction( i18n( "&Empty Trash Bin" ), "emptytrash", 0, this, SLOT( slotPopupEmptyTrashBin() ), &m_ownActions, "empytrash" );
00578 addAction( act );
00579 }
00580 addGroup( "editactions" );
00581
00582 if (d->m_itemFlags & KParts::BrowserExtension::ShowTextSelectionItems) {
00583 addMerge( 0 );
00584 m_factory->addClient( this );
00585 return;
00586 }
00587
00588 if ( !isCurrentTrash && !isIntoTrash && (d->m_itemFlags & KParts::BrowserExtension::ShowBookmark))
00589 {
00590 addSeparator();
00591 QString caption;
00592 if (currentDir)
00593 {
00594 bool httpPage = (m_sViewURL.protocol().find("http", 0, false) == 0);
00595 if (httpPage)
00596 caption = i18n("&Bookmark This Page");
00597 else
00598 caption = i18n("&Bookmark This Location");
00599 }
00600 else if (S_ISDIR(mode))
00601 caption = i18n("&Bookmark This Folder");
00602 else if (bIsLink)
00603 caption = i18n("&Bookmark This Link");
00604 else
00605 caption = i18n("&Bookmark This File");
00606
00607 act = new KAction( caption, "bookmark_add", 0, this, SLOT( slotPopupAddToBookmark() ), &m_ownActions, "bookmark_add" );
00608 if (m_lstItems.count() > 1)
00609 act->setEnabled(false);
00610 if (kapp->authorizeKAction("bookmarks"))
00611 addAction( act );
00612 if (bIsLink)
00613 addGroup( "linkactions" );
00614 }
00615
00617
00618 PopupServices s;
00619 KURL urlForServiceMenu( m_lstItems.first()->url() );
00620
00621
00622 if ( m_sMimeType == "application/x-desktop" && isSingleLocal )
00623 {
00624
00625 s.builtin = KDEDesktopMimeType::builtinServices( m_lstItems.first()->url() );
00626 const QString path = m_lstItems.first()->url().path();
00627 KSimpleConfig cfg( path, true );
00628 cfg.setDesktopGroup();
00629 const QString priority = cfg.readEntry("X-KDE-Priority");
00630 const QString submenuName = cfg.readEntry( "X-KDE-Submenu" );
00631 if ( cfg.readEntry("Type") == "Link" ) {
00632 urlForServiceMenu = cfg.readEntry("URL");
00633
00634
00635 }
00636 ServiceList* list = s.selectList( priority, submenuName );
00637 (*list) = KDEDesktopMimeType::userDefinedServices( path, cfg, url.isLocalFile() );
00638 }
00639
00640 if ( sReading )
00641 {
00642
00643
00644
00645
00646 if (isDirectory && isSingleLocal)
00647 {
00648 QString dotDirectoryFile = m_lstItems.first()->url().path(1).append(".directory");
00649 KSimpleConfig cfg( dotDirectoryFile, true );
00650 cfg.setDesktopGroup();
00651
00652 if (KIOSKAuthorizedAction(cfg))
00653 {
00654 const QString priority = cfg.readEntry("X-KDE-Priority");
00655 const QString submenuName = cfg.readEntry( "X-KDE-Submenu" );
00656 ServiceList* list = s.selectList( priority, submenuName );
00657 (*list) += KDEDesktopMimeType::userDefinedServices( dotDirectoryFile, cfg, true );
00658 }
00659 }
00660
00661 QStringList dirs = KGlobal::dirs()->findDirs( "data", "konqueror/servicemenus/" );
00662 QStringList::ConstIterator dIt = dirs.begin();
00663 QStringList::ConstIterator dEnd = dirs.end();
00664
00665 for (; dIt != dEnd; ++dIt )
00666 {
00667 QDir dir( *dIt );
00668
00669 QStringList entries = dir.entryList( "*.desktop", QDir::Files );
00670 QStringList::ConstIterator eIt = entries.begin();
00671 QStringList::ConstIterator eEnd = entries.end();
00672
00673 for (; eIt != eEnd; ++eIt )
00674 {
00675 KSimpleConfig cfg( *dIt + *eIt, true );
00676 cfg.setDesktopGroup();
00677
00678 if (!KIOSKAuthorizedAction(cfg))
00679 {
00680 continue;
00681 }
00682
00683 if ( cfg.hasKey( "X-KDE-ShowIfRunning" ) )
00684 {
00685 const QString app = cfg.readEntry( "X-KDE-ShowIfRunning" );
00686 if ( !kapp->dcopClient()->isApplicationRegistered( app.utf8() ) )
00687 continue;
00688 }
00689 if ( cfg.hasKey( "X-KDE-ShowIfDcopCall" ) )
00690 {
00691 QString dcopcall = cfg.readEntry( "X-KDE-ShowIfDcopCall" );
00692 const QCString app = dcopcall.section(' ', 0,0).utf8();
00693
00694
00695
00696
00697 QByteArray dataToSend;
00698 QDataStream dataStream(dataToSend, IO_WriteOnly);
00699 dataStream << m_lstPopupURLs;
00700
00701 QCString replyType;
00702 QByteArray replyData;
00703 QCString object = dcopcall.section(' ', 1,-2).utf8();
00704 QString function = dcopcall.section(' ', -1);
00705 if(!function.endsWith("(KURL::List)")) {
00706 kdWarning() << "Desktop file " << *eIt << " contains an invalid X-KDE-ShowIfDcopCall - the function must take the exact parameter (KURL::List) and must be specified." << endl;
00707 continue;
00708 }
00709
00710 if(!kapp->dcopClient()->call( app, object,
00711 function.utf8(),
00712 dataToSend, replyType, replyData, true, 1000))
00713 continue;
00714 if(replyType != "bool" || !replyData[0])
00715 continue;
00716
00717 }
00718 if ( cfg.hasKey( "X-KDE-Protocol" ) )
00719 {
00720 const QString protocol = cfg.readEntry( "X-KDE-Protocol" );
00721 if ( protocol != urlForServiceMenu.protocol() )
00722 continue;
00723 }
00724 else if ( urlForServiceMenu.protocol() == "trash" || urlForServiceMenu.url().startsWith( "system:/trash" ) )
00725 {
00726
00727
00728
00729 continue;
00730 }
00731
00732 if ( cfg.hasKey( "X-KDE-Require" ) )
00733 {
00734 const QStringList capabilities = cfg.readListEntry( "X-KDE-Require" );
00735 if ( capabilities.contains( "Write" ) && !sWriting )
00736 continue;
00737 }
00738 if ( (cfg.hasKey( "Actions" ) || cfg.hasKey( "X-KDE-GetActionMenu") ) && cfg.hasKey( "ServiceTypes" ) )
00739 {
00740 const QStringList types = cfg.readListEntry( "ServiceTypes" );
00741 const QStringList excludeTypes = cfg.readListEntry( "ExcludeServiceTypes" );
00742 bool ok = false;
00743
00744
00745 for (QStringList::ConstIterator it = types.begin();
00746 it != types.end() && !ok;
00747 ++it)
00748 {
00749
00750 bool checkTheMimetypes = false;
00751 if (*it == "all/all" ||
00752 *it == "allfiles" )
00753 {
00754 checkTheMimetypes = true;
00755 }
00756
00757
00758 if (!ok &&
00759 !isDirectory &&
00760 *it == "all/allfiles")
00761 {
00762 checkTheMimetypes = true;
00763 }
00764
00765
00766 if (!ok &&
00767 (!m_sMimeType.isEmpty() &&
00768 *it == m_sMimeType) ||
00769 (!mimeGroup.isEmpty() &&
00770 ((*it).right(1) == "*" &&
00771 (*it).left((*it).find('/')) == mimeGroup)))
00772 {
00773 checkTheMimetypes = true;
00774 }
00775
00776 if (checkTheMimetypes)
00777 {
00778 ok = true;
00779 for (QStringList::ConstIterator itex = excludeTypes.begin(); itex != excludeTypes.end(); ++itex)
00780 {
00781 if( ((*itex).right(1) == "*" && (*itex).left((*itex).find('/')) == mimeGroup) ||
00782 ((*itex) == m_sMimeType) )
00783 {
00784 ok = false;
00785 break;
00786 }
00787 }
00788 }
00789 }
00790
00791 if ( ok )
00792 {
00793 const QString priority = cfg.readEntry("X-KDE-Priority");
00794 const QString submenuName = cfg.readEntry( "X-KDE-Submenu" );
00795
00796 ServiceList* list = s.selectList( priority, submenuName );
00797 (*list) += KDEDesktopMimeType::userDefinedServices( *dIt + *eIt, cfg, url.isLocalFile(), m_lstPopupURLs );
00798 }
00799
00800 }
00801 }
00802 }
00803
00804 KTrader::OfferList offers;
00805
00806 if (kapp->authorizeKAction("openwith"))
00807 {
00808 QString constraint = "Type == 'Application' and DesktopEntryName != 'kfmclient' and DesktopEntryName != 'kfmclient_dir' and DesktopEntryName != 'kfmclient_html'";
00809 QString subConstraint = " and '%1' in ServiceTypes";
00810
00811 QStringList::ConstIterator it = mimeTypeList.begin();
00812 QStringList::ConstIterator end = mimeTypeList.end();
00813 Q_ASSERT( it != end );
00814 QString first = *it;
00815 ++it;
00816 while ( it != end ) {
00817 constraint += subConstraint.arg( *it );
00818 ++it;
00819 }
00820
00821 offers = KTrader::self()->query( first, constraint );
00822 }
00823
00825
00826 m_mapPopup.clear();
00827 m_mapPopupServices.clear();
00828
00829
00830 if ( !isDirectory || isLocal )
00831 {
00832 if ( hasAction() )
00833 addSeparator();
00834
00835 if ( !offers.isEmpty() )
00836 {
00837
00838 id = 1;
00839
00840 QDomElement menu = m_menuElement;
00841
00842 if ( offers.count() > 1 )
00843 {
00844 menu = m_doc.createElement( "menu" );
00845 menu.setAttribute( "name", "openwith submenu" );
00846 m_menuElement.appendChild( menu );
00847 QDomElement text = m_doc.createElement( "text" );
00848 menu.appendChild( text );
00849 text.appendChild( m_doc.createTextNode( i18n("&Open With") ) );
00850 }
00851
00852 KTrader::OfferList::ConstIterator it = offers.begin();
00853 for( ; it != offers.end(); it++ )
00854 {
00855 if ((*it)->noDisplay())
00856 continue;
00857
00858 QCString nam;
00859 nam.setNum( id );
00860
00861 QString actionName( (*it)->name().replace("&", "&&") );
00862 if ( menu == m_menuElement )
00863 actionName = i18n( "Open with %1" ).arg( actionName );
00864
00865 act = new KAction( actionName, (*it)->pixmap( KIcon::Small ), 0,
00866 this, SLOT( slotRunService() ),
00867 &m_ownActions, nam.prepend( "appservice_" ) );
00868 addAction( act, menu );
00869
00870 m_mapPopup[ id++ ] = *it;
00871 }
00872
00873 QString openWithActionName;
00874 if ( menu != m_menuElement )
00875 {
00876 addSeparator( menu );
00877 openWithActionName = i18n( "&Other..." );
00878 }
00879 else
00880 {
00881 openWithActionName = i18n( "&Open With..." );
00882 }
00883 KAction *openWithAct = new KAction( openWithActionName, 0, this, SLOT( slotPopupOpenWith() ), &m_ownActions, "openwith" );
00884 addAction( openWithAct, menu );
00885 }
00886 else
00887 {
00888 act = new KAction( i18n( "&Open With..." ), 0, this, SLOT( slotPopupOpenWith() ), &m_ownActions, "openwith" );
00889 addAction( act );
00890 }
00891
00892 }
00893 addGroup( "preview" );
00894 }
00895
00896
00897 QDomElement actionMenu = m_menuElement;
00898 int userItemCount = 0;
00899 if (s.user.count() + s.userSubmenus.count() +
00900 s.userPriority.count() + s.userPrioritySubmenus.count() > 1)
00901 {
00902
00903 actionMenu = m_doc.createElement( "menu" );
00904 actionMenu.setAttribute( "name", "actions submenu" );
00905 m_menuElement.appendChild( actionMenu );
00906 QDomElement text = m_doc.createElement( "text" );
00907 actionMenu.appendChild( text );
00908 text.appendChild( m_doc.createTextNode( i18n("Ac&tions") ) );
00909 }
00910
00911 userItemCount += insertServicesSubmenus(s.userPrioritySubmenus, actionMenu, false);
00912 userItemCount += insertServices(s.userPriority, actionMenu, false);
00913
00914
00915 if (userItemCount > 0 &&
00916 (s.user.count() > 0 ||
00917 s.userSubmenus.count() > 0 ||
00918 s.builtin.count() > 0) &&
00919 actionMenu.lastChild().toElement().tagName().lower() != "separator")
00920 {
00921 QDomElement separator = m_doc.createElement( "separator" );
00922 actionMenu.appendChild(separator);
00923 }
00924
00925 userItemCount += insertServicesSubmenus(s.userSubmenus, actionMenu, false);
00926 userItemCount += insertServices(s.user, actionMenu, false);
00927 userItemCount += insertServices(s.builtin, m_menuElement, true);
00928
00929 userItemCount += insertServicesSubmenus(s.userToplevelSubmenus, m_menuElement, false);
00930 userItemCount += insertServices(s.userToplevel, m_menuElement, false);
00931
00932 if ( userItemCount > 0 )
00933 {
00934 addPendingSeparator();
00935 }
00936
00937 if ( !isCurrentTrash && !isIntoTrash && !mediaFiles && sReading )
00938 addPlugins();
00939
00940 if ( KPropertiesDialog::canDisplay( m_lstItems ) && (kpf & ShowProperties) )
00941 {
00942 act = new KAction( i18n( "&Properties" ), 0, this, SLOT( slotPopupProperties() ),
00943 &m_ownActions, "properties" );
00944 addAction( act );
00945 }
00946
00947 while ( !m_menuElement.lastChild().isNull() &&
00948 m_menuElement.lastChild().toElement().tagName().lower() == "separator" )
00949 m_menuElement.removeChild( m_menuElement.lastChild() );
00950
00951 if ( isDirectory && isLocal )
00952 {
00953 if ( KFileShare::authorization() == KFileShare::Authorized )
00954 {
00955 addSeparator();
00956 act = new KAction( i18n("Share"), 0, this, SLOT( slotOpenShareFileDialog() ),
00957 &m_ownActions, "sharefile" );
00958 addAction( act );
00959 }
00960 }
00961
00962 addMerge( 0 );
00963
00964
00965 m_factory->addClient( this );
00966 }
00967
00968 void KonqPopupMenu::slotOpenShareFileDialog()
00969 {
00970 KPropertiesDialog* dlg = showPropertiesDialog();
00971 dlg->showFileSharingPage();
00972 }
00973
00974 KonqPopupMenu::~KonqPopupMenu()
00975 {
00976 m_pluginList.clear();
00977 delete m_factory;
00978 delete m_builder;
00979 delete d;
00980
00981 }
00982
00983 void KonqPopupMenu::setURLTitle( const QString& urlTitle )
00984 {
00985 d->m_urlTitle = urlTitle;
00986 }
00987
00988 void KonqPopupMenu::slotPopupNewView()
00989 {
00990 KURL::List::ConstIterator it = m_lstPopupURLs.begin();
00991 for ( ; it != m_lstPopupURLs.end(); it++ )
00992 (void) new KRun(*it);
00993 }
00994
00995 void KonqPopupMenu::slotPopupNewDir()
00996 {
00997 if (m_lstPopupURLs.empty())
00998 return;
00999
01000 KonqOperations::newDir(d->m_parentWidget, m_lstPopupURLs.first());
01001 }
01002
01003 void KonqPopupMenu::slotPopupEmptyTrashBin()
01004 {
01005 KonqOperations::emptyTrash();
01006 }
01007
01008 void KonqPopupMenu::slotPopupRestoreTrashedItems()
01009 {
01010 KonqOperations::restoreTrashedItems( m_lstPopupURLs );
01011 }
01012
01013 void KonqPopupMenu::slotPopupOpenWith()
01014 {
01015 KRun::displayOpenWithDialog( m_lstPopupURLs );
01016 }
01017
01018 void KonqPopupMenu::slotPopupAddToBookmark()
01019 {
01020 KBookmarkGroup root;
01021 if ( m_lstPopupURLs.count() == 1 ) {
01022 KURL url = m_lstPopupURLs.first();
01023 QString title = d->m_urlTitle.isEmpty() ? url.prettyURL() : d->m_urlTitle;
01024 root = m_pManager->addBookmarkDialog( url.prettyURL(), title );
01025 }
01026 else
01027 {
01028 root = m_pManager->root();
01029 KURL::List::ConstIterator it = m_lstPopupURLs.begin();
01030 for ( ; it != m_lstPopupURLs.end(); it++ )
01031 root.addBookmark( m_pManager, (*it).prettyURL(), (*it) );
01032 }
01033 m_pManager->emitChanged( root );
01034 }
01035
01036 void KonqPopupMenu::slotRunService()
01037 {
01038 QCString senderName = sender()->name();
01039 int id = senderName.mid( senderName.find( '_' ) + 1 ).toInt();
01040
01041
01042 QMap<int,KService::Ptr>::Iterator it = m_mapPopup.find( id );
01043 if ( it != m_mapPopup.end() )
01044 {
01045 KRun::run( **it, m_lstPopupURLs );
01046 return;
01047 }
01048
01049
01050 QMap<int,KDEDesktopMimeType::Service>::Iterator it2 = m_mapPopupServices.find( id );
01051 if ( it2 != m_mapPopupServices.end() )
01052 {
01053 KDEDesktopMimeType::executeService( m_lstPopupURLs, it2.data() );
01054 }
01055
01056 return;
01057 }
01058
01059 void KonqPopupMenu::slotPopupMimeType()
01060 {
01061 KonqOperations::editMimeType( m_sMimeType );
01062 }
01063
01064 void KonqPopupMenu::slotPopupProperties()
01065 {
01066 (void)showPropertiesDialog();
01067 }
01068
01069 KPropertiesDialog* KonqPopupMenu::showPropertiesDialog()
01070 {
01071
01072
01073
01074
01075 if ( m_lstItems.count() == 1 )
01076 {
01077 KFileItem * item = m_lstItems.first();
01078 if (item->entry().count() == 0)
01079 {
01080
01081 return new KPropertiesDialog( item->url(), d->m_parentWidget );
01082 }
01083 }
01084 return new KPropertiesDialog( m_lstItems, d->m_parentWidget );
01085 }
01086
01087 KAction *KonqPopupMenu::action( const QDomElement &element ) const
01088 {
01089 QCString name = element.attribute( attrName ).ascii();
01090 KAction *res = m_ownActions.action( name );
01091
01092 if ( !res )
01093 res = m_actions.action( name );
01094
01095 if ( !res && m_pMenuNew && strcmp( name, m_pMenuNew->name() ) == 0 )
01096 return m_pMenuNew;
01097
01098 return res;
01099 }
01100
01101 KActionCollection *KonqPopupMenu::actionCollection() const
01102 {
01103 return const_cast<KActionCollection *>( &m_ownActions );
01104 }
01105
01106 QString KonqPopupMenu::mimeType() const
01107 {
01108 return m_sMimeType;
01109 }
01110
01111 KonqPopupMenu::ProtocolInfo KonqPopupMenu::protocolInfo() const
01112 {
01113 return m_info;
01114 }
01115
01116 void KonqPopupMenu::addPlugins()
01117 {
01118
01119
01120 KTrader::OfferList plugin_offers;
01121 unsigned int pluginCount = 0;
01122 plugin_offers = KTrader::self()->query( m_sMimeType.isNull() ? QString::fromLatin1( "all/all" ) : m_sMimeType, "'KonqPopupMenu/Plugin' in ServiceTypes");
01123 if ( plugin_offers.isEmpty() )
01124 return;
01125
01126 KTrader::OfferList::ConstIterator iterator = plugin_offers.begin();
01127 KTrader::OfferList::ConstIterator end = plugin_offers.end();
01128
01129 addGroup( "plugins" );
01130
01131 for(; iterator != end; ++iterator, ++pluginCount ) {
01132
01133 KonqPopupMenuPlugin *plugin =
01134 KParts::ComponentFactory::
01135 createInstanceFromLibrary<KonqPopupMenuPlugin>( QFile::encodeName( (*iterator)->library() ),
01136 this,
01137 (*iterator)->name().latin1() );
01138 if ( !plugin )
01139 continue;
01140 QString pluginClientName = QString::fromLatin1( "Plugin%1" ).arg( pluginCount );
01141 addMerge( pluginClientName );
01142 plugin->domDocument().documentElement().setAttribute( "name", pluginClientName );
01143 m_pluginList.append( plugin );
01144 insertChildClient( plugin );
01145 }
01146
01147
01148 addMerge( "plugins" );
01149 }
01150
01151 KURL KonqPopupMenu::url() const
01152 {
01153 return m_sViewURL;
01154 }
01155
01156 KFileItemList KonqPopupMenu::fileItemList() const
01157 {
01158 return m_lstItems;
01159 }
01160
01161 KURL::List KonqPopupMenu::popupURLList() const
01162 {
01163 return m_lstPopupURLs;
01164 }
01165
01170 KonqPopupMenuPlugin::KonqPopupMenuPlugin( KonqPopupMenu *parent, const char *name )
01171 : QObject( parent, name )
01172 {
01173 }
01174
01175 KonqPopupMenuPlugin::~KonqPopupMenuPlugin()
01176 {
01177 }
01178
01179 #include "konq_popupmenu.moc"