• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

libkonq

konq_popupmenu.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002    Copyright (C) 1998-2008 David Faure <faure@kde.org>
00003    Copyright (C) 2001 Holger Freyther <freyther@yahoo.com>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018    Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "konq_popupmenu.h"
00022 #include "konq_popupmenuplugin.h"
00023 #include "konq_popupmenuinformation.h"
00024 #include "konq_copytomenu.h"
00025 #include "konq_menuactions.h"
00026 #include "kpropertiesdialog.h"
00027 #include "knewmenu.h"
00028 #include "konq_operations.h"
00029 
00030 #include <klocale.h>
00031 #include <kbookmarkmanager.h>
00032 #include <kbookmarkdialog.h>
00033 #include <kdebug.h>
00034 #include <krun.h>
00035 #include <kprotocolmanager.h>
00036 #include <kicon.h>
00037 #include <kiconloader.h>
00038 #include <kinputdialog.h>
00039 #include <kglobalsettings.h>
00040 #include <kmimetypetrader.h>
00041 #include <kstandarddirs.h>
00042 #include <kconfiggroup.h>
00043 #include <kdesktopfile.h>
00044 #include <kfileshare.h>
00045 #include <kauthorized.h>
00046 #include <kglobal.h>
00047 #include <kacceleratormanager.h>
00048 
00049 #include <QFileInfo>
00050 
00051 /*
00052  Test cases:
00053   iconview file: background
00054   iconview file: file (with and without servicemenus)
00055   iconview file: directory
00056   iconview remote protocol (e.g. ftp: or fish:)
00057   iconview trash:/
00058   sidebar directory tree
00059   sidebar Devices / Hard Disc
00060   khtml background
00061   khtml link
00062   khtml image (www.kde.org RMB on K logo)
00063   khtmlimage (same as above, then choose View image, then RMB)
00064   selected text in khtml
00065   embedded katepart
00066   folder on the desktop
00067   trash link on the desktop
00068   trashed file or directory
00069   application .desktop file
00070  Then the same after uninstalling kdeaddons/konq-plugins (arkplugin in particular)
00071 */
00072 
00073 class KonqPopupMenuPrivate
00074 {
00075 public:
00076     KonqPopupMenuPrivate(KonqPopupMenu* qq, KActionCollection & actions)
00077         : q(qq),
00078           m_itemFlags(KParts::BrowserExtension::DefaultPopupItems),
00079           m_actions(actions),
00080           m_ownActions(static_cast<QWidget *>(0))
00081     {
00082     }
00083     void addNamedAction(const QString& name);
00084     void addGroup(const QString& name);
00085     void addPlugins();
00086     void init(KonqPopupMenu::Flags kpf, KParts::BrowserExtension::PopupFlags itemFlags);
00087 
00088     void slotPopupNewDir();
00089     void slotPopupNewView();
00090     void slotPopupEmptyTrashBin();
00091     void slotPopupRestoreTrashedItems();
00092     void slotPopupAddToBookmark();
00093     void slotPopupMimeType();
00094     void slotPopupProperties();
00095     void slotOpenShareFileDialog();
00096 
00097     KonqPopupMenu* q;
00098     QString m_urlTitle;
00099     KParts::BrowserExtension::PopupFlags m_itemFlags;
00100     KNewMenu *m_pMenuNew;
00101     KUrl m_sViewURL;
00102     KonqPopupMenuInformation m_popupMenuInfo;
00103     KonqMenuActions m_menuActions;
00104     KonqCopyToMenu m_copyToMenu;
00105     KBookmarkManager* m_bookmarkManager;
00106     KActionCollection &m_actions;
00107     KActionCollection m_ownActions; // TODO connect to statusbar for help on actions
00108     KParts::BrowserExtension::ActionGroupMap m_actionGroups;
00109 };
00110 
00112 
00113 KonqPopupMenu::KonqPopupMenu(const KFileItemList &items,
00114                              const KUrl& viewURL,
00115                              KActionCollection & actions,
00116                              KNewMenu * newMenu,
00117                              Flags kpf,
00118                              KParts::BrowserExtension::PopupFlags flags,
00119                              QWidget * parentWidget,
00120                              KBookmarkManager *mgr,
00121                              const KParts::BrowserExtension::ActionGroupMap& actionGroups)
00122   : QMenu(parentWidget),
00123     d(new KonqPopupMenuPrivate(this, actions))
00124 {
00125     d->m_actionGroups = actionGroups;
00126     d->m_pMenuNew = newMenu;
00127     d->m_sViewURL = viewURL;
00128     d->m_bookmarkManager = mgr;
00129     d->m_popupMenuInfo.setItems(items);
00130     d->m_popupMenuInfo.setParentWidget(parentWidget);
00131     d->init(kpf, flags);
00132 
00133     KAcceleratorManager::manage(this);
00134 }
00135 
00136 void KonqPopupMenuPrivate::addNamedAction(const QString& name)
00137 {
00138     QAction* act = m_actions.action(name);
00139     if (act)
00140         q->addAction(act);
00141 }
00142 
00143 void KonqPopupMenuPrivate::init(KonqPopupMenu::Flags kpf, KParts::BrowserExtension::PopupFlags flags)
00144 {
00145     m_ownActions.setObjectName("KonqPopupMenu::m_ownActions");
00146     m_itemFlags = flags;
00147     q->setFont(KGlobalSettings::menuFont());
00148 
00149     Q_ASSERT(m_popupMenuInfo.items().count() >= 1);
00150 
00151     bool bTrashIncluded = false;
00152 
00153     const KFileItemList lstItems = m_popupMenuInfo.items();
00154     KFileItemList::const_iterator it = lstItems.constBegin();
00155     const KFileItemList::const_iterator kend = lstItems.constEnd();
00156     for ( ; it != kend; ++it )
00157     {
00158         const KUrl url = (*it).url();
00159         if ( !bTrashIncluded && (
00160              ( url.protocol() == "trash" && url.path().length() <= 1 ) ) ) {
00161             bTrashIncluded = true;
00162         }
00163     }
00164 
00165     const bool isDirectory = m_popupMenuInfo.isDirectory();
00166     const bool sReading = m_popupMenuInfo.capabilities().supportsReading();
00167     bool sDeleting = (m_itemFlags & KParts::BrowserExtension::NoDeletion) == 0
00168                      && m_popupMenuInfo.capabilities().supportsDeleting();
00169     const bool sWriting = m_popupMenuInfo.capabilities().supportsWriting();
00170     const bool sMoving = sDeleting && m_popupMenuInfo.capabilities().supportsMoving();
00171     const bool isLocal = m_popupMenuInfo.capabilities().isLocal();
00172 
00173     KUrl url = m_sViewURL;
00174     url.cleanPath();
00175 
00176     bool isTrashLink     = false;
00177     bool isCurrentTrash = false;
00178     bool currentDir     = false;
00179 
00180     //check if url is current directory
00181     if ( lstItems.count() == 1 )
00182     {
00183         KFileItem firstPopupItem( lstItems.first() );
00184         KUrl firstPopupURL( firstPopupItem.url() );
00185         firstPopupURL.cleanPath();
00186         //kDebug(1203) << "View path is " << url.url();
00187         //kDebug(1203) << "First popup path is " << firstPopupURL.url();
00188         currentDir = firstPopupURL.equals( url, KUrl::CompareWithoutTrailingSlash );
00189         if ( firstPopupItem.isDesktopFile() ) {
00190             KDesktopFile desktopFile( firstPopupItem.localPath() );
00191             const KConfigGroup cfg = desktopFile.desktopGroup();
00192             isTrashLink = ( cfg.readEntry("Type") == "Link" && cfg.readEntry("URL") == "trash:/" );
00193         }
00194 
00195         if (isTrashLink) {
00196             sDeleting = false;
00197         }
00198 
00199         // isCurrentTrash: popup on trash:/ itself, or on the trash.desktop link
00200         isCurrentTrash = (firstPopupURL.protocol() == "trash" && firstPopupURL.path().length() <= 1)
00201                          || isTrashLink;
00202     }
00203 
00204     const bool isIntoTrash = (url.protocol() == "trash") && !isCurrentTrash; // trashed file, not trash:/ itself
00205 
00206     const bool bIsLink  = (m_itemFlags & KParts::BrowserExtension::IsLink);
00207 
00208     //kDebug() << "isLocal=" << isLocal << " url=" << url << " isCurrentTrash=" << isCurrentTrash << " isIntoTrash=" << isIntoTrash << " bTrashIncluded=" << bTrashIncluded;
00209 
00211 
00212     addGroup( "topactions" ); // used e.g. for ShowMenuBar. includes a separator at the end
00213 
00214     QAction * act;
00215 
00216     QAction *actNewWindow = 0;
00217 
00218 #if 0 // TODO in the desktop code itself.
00219     if (( flags & KParts::BrowserExtension::ShowProperties ) && isOnDesktop &&
00220         !KAuthorized::authorizeKAction("editable_desktop_icons"))
00221     {
00222         flags &= ~KParts::BrowserExtension::ShowProperties; // remove flag
00223     }
00224 #endif
00225 
00226     // Either 'newview' is in the actions we're given (probably in the tabhandling group)
00227     // or we need to insert it ourselves (e.g. for the desktop).
00228     // In the first case, actNewWindow must remain 0.
00229     if ( ((kpf & KonqPopupMenu::ShowNewWindow) != 0) && sReading )
00230     {
00231         const QString openStr = i18n("&Open");
00232         actNewWindow = m_ownActions.addAction( "newview" );
00233         actNewWindow->setIcon( KIcon("window-new") );
00234         actNewWindow->setText( openStr );
00235         QObject::connect(actNewWindow, SIGNAL(triggered()), q, SLOT(slotPopupNewView()));
00236     }
00237 
00238     if ( isDirectory && sWriting && !isCurrentTrash ) // A dir, and we can create things into it
00239     {
00240         const bool mkdirRequested = m_itemFlags & KParts::BrowserExtension::ShowCreateDirectory;
00241         if ( (currentDir || mkdirRequested) && m_pMenuNew ) // Current dir -> add the "new" menu
00242         {
00243             // As requested by KNewMenu :
00244             m_pMenuNew->slotCheckUpToDate();
00245             m_pMenuNew->setPopupFiles(m_popupMenuInfo.urlList());
00246 
00247             q->addAction( m_pMenuNew );
00248             q->addSeparator();
00249         }
00250         else if (mkdirRequested)
00251         {
00252             KAction *actNewDir = m_ownActions.addAction( "newdir" );
00253             actNewDir->setIcon( KIcon("folder-new") );
00254             actNewDir->setText( i18n( "Create &Folder..." ) );
00255             QObject::connect(actNewDir, SIGNAL(triggered()), q, SLOT(slotPopupNewDir()));
00256             q->addAction( actNewDir );
00257             q->addSeparator();
00258         }
00259     } else if ( isIntoTrash ) {
00260         // Trashed item, offer restoring
00261         act = m_ownActions.addAction( "restore" );
00262         act->setText( i18n( "&Restore" ) );
00263         QObject::connect(act, SIGNAL(triggered()), q, SLOT(slotPopupRestoreTrashedItems()));
00264         q->addAction(act);
00265     }
00266 
00267     if (m_itemFlags & KParts::BrowserExtension::ShowNavigationItems)
00268     {
00269         if (m_itemFlags & KParts::BrowserExtension::ShowUp)
00270             addNamedAction( "go_up" );
00271         addNamedAction( "go_back" );
00272         addNamedAction( "go_forward" );
00273         if (m_itemFlags & KParts::BrowserExtension::ShowReload)
00274             addNamedAction( "reload" );
00275         q->addSeparator();
00276     }
00277 
00278     // "open in new window" is either provided by us, or by the tabhandling group
00279     if (actNewWindow) {
00280         q->addAction(actNewWindow);
00281         q->addSeparator();
00282     }
00283     addGroup( "tabhandling" ); // includes a separator at the end
00284 
00285     if (m_itemFlags & KParts::BrowserExtension::ShowUrlOperations) {
00286         if ( !currentDir && sReading ) {
00287             if ( sDeleting ) {
00288                 addNamedAction( "cut" );
00289             }
00290             addNamedAction( "copy" );
00291         }
00292 
00293         if ( isDirectory && sWriting ) {
00294             if ( currentDir )
00295                 addNamedAction( "paste" );
00296             else
00297                 addNamedAction( "pasteto" );
00298         }
00299     }
00300     if ( isCurrentTrash )
00301     {
00302         act = m_ownActions.addAction( "emptytrash" );
00303         act->setIcon( KIcon("trash-empty") );
00304         act->setText( i18n( "&Empty Trash Bin" ) );
00305         KConfig trashConfig( "trashrc", KConfig::SimpleConfig);
00306         act->setEnabled( !trashConfig.group("Status").readEntry( "Empty", true ) );
00307         QObject::connect(act, SIGNAL(triggered()), q, SLOT(slotPopupEmptyTrashBin()));
00308         q->addAction(act);
00309     }
00310 
00311     // This is used by KHTML, see khtml_popupmenu.rc (copy, selectAll, searchProvider etc.)
00312     // and by DolphinPart (rename, trash, delete)
00313     addGroup( "editactions" );
00314 
00315     if (m_itemFlags & KParts::BrowserExtension::ShowTextSelectionItems) {
00316         // OK, we have to stop here.
00317 
00318         // Anything else that is provided by the part
00319         addGroup( "partactions" );
00320         return;
00321     }
00322 
00323     if ( !isCurrentTrash && !isIntoTrash && (m_itemFlags & KParts::BrowserExtension::ShowBookmark))
00324     {
00325         QString caption;
00326         if (currentDir)
00327         {
00328            const bool httpPage = m_sViewURL.protocol().startsWith("http", Qt::CaseInsensitive);
00329            if (httpPage)
00330               caption = i18n("&Bookmark This Page");
00331            else
00332               caption = i18n("&Bookmark This Location");
00333         }
00334         else if (isDirectory)
00335            caption = i18n("&Bookmark This Folder");
00336         else if (bIsLink)
00337            caption = i18n("&Bookmark This Link");
00338         else
00339            caption = i18n("&Bookmark This File");
00340 
00341         act = m_ownActions.addAction( "bookmark_add" );
00342         act->setIcon( KIcon("bookmark-new") );
00343         act->setText( caption );
00344         QObject::connect(act, SIGNAL(triggered()), q, SLOT(slotPopupAddToBookmark()));
00345         if (lstItems.count() > 1)
00346             act->setEnabled(false);
00347         if (KAuthorized::authorizeKAction("bookmarks"))
00348             q->addAction( act );
00349         if (bIsLink)
00350             addGroup( "linkactions" ); // see khtml
00351     }
00352 
00353     // "Open With" actions
00354 
00355     m_menuActions.setPopupMenuInfo(m_popupMenuInfo);
00356 
00357     if ( sReading ) {
00358         m_menuActions.addOpenWithActionsTo(q, "DesktopEntryName != 'kfmclient' and DesktopEntryName != 'kfmclient_dir' and DesktopEntryName != 'kfmclient_html'");
00359 
00360         QList<QAction *> previewActions = m_actionGroups.value("preview");
00361         if (!previewActions.isEmpty()) {
00362             if (previewActions.count() == 1) {
00363                 q->addAction(previewActions.first());
00364             } else {
00365                 QMenu* subMenu = new QMenu(i18n("Preview In"), q);
00366                 subMenu->menuAction()->setObjectName("preview_submenu"); // for the unittest
00367                 q->addMenu(subMenu);
00368                 subMenu->addActions(previewActions);
00369             }
00370         }
00371     }
00372 
00373     // Second block, builtin + user
00374     m_menuActions.addActionsTo(q);
00375 
00376     q->addSeparator();
00377 
00378     // CopyTo/MoveTo menus
00379     if (m_itemFlags & KParts::BrowserExtension::ShowUrlOperations) {
00380         m_copyToMenu.setItems(lstItems);
00381         m_copyToMenu.setReadOnly(sMoving == false);
00382         m_copyToMenu.addActionsTo(q);
00383         q->addSeparator();
00384     }
00385 
00386     if ( !isCurrentTrash && !isIntoTrash && sReading )
00387         addPlugins(); // now it's time to add plugins
00388 
00389     if ( (m_itemFlags & KParts::BrowserExtension::ShowProperties) && KPropertiesDialog::canDisplay( lstItems ) ) {
00390         act = m_ownActions.addAction( "properties" );
00391         act->setText( i18n( "&Properties" ) );
00392         QObject::connect(act, SIGNAL(triggered()), q, SLOT(slotPopupProperties()));
00393         q->addAction(act);
00394     }
00395 
00396     while ( !q->actions().isEmpty() &&
00397             q->actions().last()->isSeparator() )
00398         delete q->actions().last();
00399 
00400     if ( isDirectory && isLocal ) {
00401         if ( KFileShare::authorization() == KFileShare::Authorized ) {
00402             q->addSeparator();
00403             act = m_ownActions.addAction( "sharefile" );
00404             act->setText( i18n("Share") );
00405             QObject::connect(act, SIGNAL(triggered()), q, SLOT(slotOpenShareFileDialog()));
00406             q->addAction(act);
00407         }
00408     }
00409 
00410     // Anything else that is provided by the part
00411     addGroup( "partactions" );
00412 }
00413 
00414 void KonqPopupMenuPrivate::slotOpenShareFileDialog()
00415 {
00416     KPropertiesDialog* dlg = new KPropertiesDialog( m_popupMenuInfo.items(), m_popupMenuInfo.parentWidget() );
00417     dlg->showFileSharingPage();
00418     dlg->exec();
00419 }
00420 
00421 KonqPopupMenu::~KonqPopupMenu()
00422 {
00423   delete d;
00424   //kDebug(1203) << "~KonqPopupMenu leave";
00425 }
00426 
00427 void KonqPopupMenu::setURLTitle( const QString& urlTitle )
00428 {
00429     d->m_urlTitle = urlTitle;
00430 }
00431 
00432 void KonqPopupMenuPrivate::slotPopupNewView()
00433 {
00434     Q_FOREACH(const KUrl& url, m_popupMenuInfo.urlList()) {
00435         (void) new KRun(url, m_popupMenuInfo.parentWidget());
00436     }
00437 }
00438 
00439 void KonqPopupMenuPrivate::slotPopupNewDir()
00440 {
00441   if (m_popupMenuInfo.urlList().empty())
00442     return;
00443 
00444   KonqOperations::newDir(m_popupMenuInfo.parentWidget(), m_popupMenuInfo.urlList().first());
00445 }
00446 
00447 void KonqPopupMenuPrivate::slotPopupEmptyTrashBin()
00448 {
00449   KonqOperations::emptyTrash(m_popupMenuInfo.parentWidget());
00450 }
00451 
00452 void KonqPopupMenuPrivate::slotPopupRestoreTrashedItems()
00453 {
00454   KonqOperations::restoreTrashedItems(m_popupMenuInfo.urlList(), m_popupMenuInfo.parentWidget());
00455 }
00456 
00457 void KonqPopupMenuPrivate::slotPopupAddToBookmark()
00458 {
00459     KBookmarkGroup root;
00460     if (m_popupMenuInfo.urlList().count() == 1) {
00461         const KUrl url = m_popupMenuInfo.urlList().first();
00462         const QString title = m_urlTitle.isEmpty() ? url.prettyUrl() : m_urlTitle;
00463         KBookmarkDialog dlg(m_bookmarkManager, m_popupMenuInfo.parentWidget());
00464         dlg.addBookmark(title, url.url());
00465     }
00466     else
00467     {
00468         root = m_bookmarkManager->root();
00469         Q_FOREACH(const KUrl& url, m_popupMenuInfo.urlList()) {
00470             root.addBookmark(url.prettyUrl(), url);
00471         }
00472         m_bookmarkManager->emitChanged(root);
00473     }
00474 }
00475 
00476 void KonqPopupMenuPrivate::slotPopupMimeType()
00477 {
00478     KonqOperations::editMimeType(m_popupMenuInfo.mimeType(), m_popupMenuInfo.parentWidget());
00479 }
00480 
00481 void KonqPopupMenuPrivate::slotPopupProperties()
00482 {
00483     KPropertiesDialog::showDialog(m_popupMenuInfo.items(), m_popupMenuInfo.parentWidget(), false);
00484 }
00485 
00486 void KonqPopupMenuPrivate::addGroup(const QString& name)
00487 {
00488     QList<QAction *> actions = m_actionGroups.value(name);
00489     q->addActions(actions);
00490 }
00491 
00492 void KonqPopupMenuPrivate::addPlugins()
00493 {
00494     const QString commonMimeType = m_popupMenuInfo.mimeType();
00495     const KService::List plugin_offers = KMimeTypeTrader::self()->query(commonMimeType.isEmpty() ? QLatin1String("application/octet-stream") : commonMimeType, "KonqPopupMenu/Plugin", "exist Library");
00496 
00497     KService::List::ConstIterator iterator = plugin_offers.begin();
00498     const KService::List::ConstIterator end = plugin_offers.end();
00499     for(; iterator != end; ++iterator) {
00500         //kDebug() << (*iterator)->name() << (*iterator)->library();
00501         KonqPopupMenuPlugin *plugin = (*iterator)->createInstance<KonqPopupMenuPlugin>(q);
00502         if (!plugin)
00503             continue;
00504         plugin->setup(&m_ownActions, m_popupMenuInfo, q);
00505     }
00506 }
00507 
00508 #include "konq_popupmenu.moc"

libkonq

Skip menu "libkonq"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • Konsole
  • Libraries
  •   libkonq
Generated for API Reference by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal