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