From 4aed2c8219774f5d797760606b8489a92ddc5163 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kdesktop/kdiconview.cc | 1668 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1668 insertions(+) create mode 100644 kdesktop/kdiconview.cc (limited to 'kdesktop/kdiconview.cc') diff --git a/kdesktop/kdiconview.cc b/kdesktop/kdiconview.cc new file mode 100644 index 000000000..f9ca6c446 --- /dev/null +++ b/kdesktop/kdiconview.cc @@ -0,0 +1,1668 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + Copyright (C) 2000, 2001 David Faure + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kdiconview.h" +#include "krootwm.h" +#include "desktop.h" +#include "kdesktopsettings.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include "kshadowengine.h" +#include "kdesktopshadowsettings.h" +#include "kfileividesktop.h" + +// for multihead +extern int kdesktop_screen_number; + +// ----------------------------------------------------------------------------- + +QRect KDIconView::desktopRect() +{ + return ( kdesktop_screen_number == 0 ) + ? QApplication::desktop()->geometry() // simple case, or xinerama + : QApplication::desktop()->screenGeometry( kdesktop_screen_number ); // multi-head +} + +// ----------------------------------------------------------------------------- + +void KDIconView::saveIconPosition(KSimpleConfig *config, int x, int y) +{ + // save the icon position in absolute coordinates + config->writeEntry("Xabs", x); + config->writeEntry("Yabs", y); + + // save also mentioning desktop size + QRect desk = desktopRect(); + QString sizeStr = QString( "_%1x%2" ).arg(desk.width()).arg(desk.height()); + + config->writeEntry("Xabs" + sizeStr, x); + config->writeEntry("Yabs" + sizeStr, y); +} + +// ----------------------------------------------------------------------------- + +void KDIconView::readIconPosition(KSimpleConfig *config, int &x, int &y) +{ + // check if we have the position for the current desktop size + QRect desk = desktopRect(); + QString sizeStr = QString( "_%1x%2" ).arg(desk.width()).arg(desk.height()); + + x = config->readNumEntry("Xabs" + sizeStr, -99999); + + if ( x != -99999 ) + y = config->readNumEntry("Yabs" + sizeStr); + else + { + // not found; use the resolution independent position + x = config->readNumEntry("Xabs", -99999); + + if ( x != -99999 ) + y = config->readNumEntry("Yabs"); + else // for compatibility, read the old iconArea-relative-position + { + // problem here: when reading a position before we know the correct + // desktopIconsArea, the relative position do not make sense + // workaround: use desktopRect() as the allowed size + + QRect desk = desktopRect(); + QString X_w = QString("X %1").arg(desk.width() ); + QString Y_h = QString("Y %1").arg(desk.height()); + + x = config->readNumEntry(X_w, -99999); + if ( x != -99999 ) x = config->readNumEntry("X"); + if ( x < 0 ) x += desk.width(); + + y = config->readNumEntry(Y_h, -99999); + if ( y != -99999 ) y = config->readNumEntry("Y"); + if ( y < 0 ) y += desk.height(); + } + } +} + +// ----------------------------------------------------------------------------- + +KDIconView::KDIconView( QWidget *parent, const char* name ) + : KonqIconViewWidget( parent, name, WResizeNoErase, true ), + m_actionCollection( this, "KDIconView::m_actionCollection" ), + m_accel( 0L ), + m_bNeedRepaint( false ), + m_bNeedSave( false ), + m_autoAlign( false ), + m_hasExistingPos( false ), + m_bEditableDesktopIcons( kapp->authorize("editable_desktop_icons") ), + m_bShowDot( false ), + m_bVertAlign( true ), + m_dirLister( 0L ), + m_mergeDirs(), + m_dotDirectory( 0L ), + m_lastDeletedIconPos(), + m_eSortCriterion( NameCaseInsensitive ), + m_bSortDirectoriesFirst( true ), + m_itemsAlwaysFirst(), + m_gotIconsArea(false) +{ + setResizeMode( Fixed ); + setIconArea( desktopRect() ); // the default is the whole desktop + + // Initialise the shadow data objects... + m_shadowEngine = new KShadowEngine(new KDesktopShadowSettings(KGlobal::config())); + + connect( QApplication::clipboard(), SIGNAL(dataChanged()), + this, SLOT(slotClipboardDataChanged()) ); + + setURL( desktopURL() ); // sets m_url + + m_desktopDirs = KGlobal::dirs()->findDirs( "appdata", "Desktop" ); + initDotDirectories(); + + connect( this, SIGNAL( executed( QIconViewItem * ) ), + SLOT( slotExecuted( QIconViewItem * ) ) ); + connect( this, SIGNAL( returnPressed( QIconViewItem * ) ), + SLOT( slotReturnPressed( QIconViewItem * ) ) ); + connect( this, SIGNAL( mouseButtonPressed(int, QIconViewItem*, const QPoint&)), + SLOT( slotMouseButtonPressed(int, QIconViewItem*, const QPoint&)) ); + connect( this, SIGNAL( mouseButtonClicked(int, QIconViewItem*, const QPoint&)), + SLOT( slotMouseButtonClickedKDesktop(int, QIconViewItem*, const QPoint&)) ); + connect( this, SIGNAL( contextMenuRequested(QIconViewItem*, const QPoint&)), + SLOT( slotContextMenuRequested(QIconViewItem*, const QPoint&)) ); + + connect( this, SIGNAL( enableAction( const char * , bool ) ), + SLOT( slotEnableAction( const char * , bool ) ) ); + + // Hack: KonqIconViewWidget::slotItemRenamed is not virtual :-( + disconnect( this, SIGNAL(itemRenamed(QIconViewItem *, const QString &)), + this, SLOT(slotItemRenamed(QIconViewItem *, const QString &)) ); + connect( this, SIGNAL(itemRenamed(QIconViewItem *, const QString &)), + this, SLOT(slotItemRenamed(QIconViewItem *, const QString &)) ); + + if (!m_bEditableDesktopIcons) + { + setItemsMovable(false); + setAcceptDrops(false); + viewport()->setAcceptDrops(false); + } +} + +KDIconView::~KDIconView() +{ + if (m_dotDirectory && !m_bEditableDesktopIcons) + m_dotDirectory->rollback(false); // Don't save positions + + delete m_dotDirectory; + delete m_dirLister; + delete m_shadowEngine; +} + +void KDIconView::initDotDirectories() +{ + QStringList dirs = m_desktopDirs; + KURL u = desktopURL(); + if (u.isLocalFile()) + dirs.prepend(u.path()); + + QString prefix = iconPositionGroupPrefix(); + QString dotFileName = locateLocal("appdata", "IconPositions"); + if (kdesktop_screen_number != 0) + dotFileName += "_Desktop" + QString::number(kdesktop_screen_number); + + if (m_dotDirectory && !m_bEditableDesktopIcons) + m_dotDirectory->rollback(false); // Don't save positions + + delete m_dotDirectory; + + m_dotDirectory = new KSimpleConfig( dotFileName ); + // If we don't allow editable desktop icons, empty m_dotDirectory + if (!m_bEditableDesktopIcons) + { + QStringList groups = m_dotDirectory->groupList(); + QStringList::ConstIterator gIt = groups.begin(); + QStringList::ConstIterator gEnd = groups.end(); + for (; gIt != gEnd; ++gIt ) + { + m_dotDirectory->deleteGroup(*gIt, true); + } + } + QRect desk = desktopRect(); + QString X_w = QString( "X %1" ).arg( desk.width() ); + QString Y_h = QString( "Y %1" ).arg( desk.height() ); + for ( QStringList::ConstIterator it = dirs.begin() ; it != dirs.end() ; ++it ) + { + kdDebug(1204) << "KDIconView::initDotDirectories found dir " << *it << endl; + QString dotFileName = *it + "/.directory"; + + if (QFile::exists(dotFileName)) + { + KSimpleConfig dotDir(dotFileName, true); // Read only + + QStringList groups = dotDir.groupList(); + QStringList::ConstIterator gIt = groups.begin(); + QStringList::ConstIterator gEnd = groups.end(); + for (; gIt != gEnd; ++gIt ) + { + if ( (*gIt).startsWith(prefix) ) + { + dotDir.setGroup( *gIt ); + m_dotDirectory->setGroup( *gIt ); + + if (!m_dotDirectory->hasKey( X_w )) + { + int x,y; + readIconPosition(&dotDir, x, y); + m_dotDirectory->writeEntry( X_w, x ); + m_dotDirectory->writeEntry( Y_h, y ); // Not persistant! + } + } + } + } + } +} + +void KDIconView::initConfig( bool init ) +{ + //kdDebug() << "initConfig " << init << endl; + + if ( !init ) { + KonqFMSettings::reparseConfiguration(); + KDesktopSettings::self()->readConfig(); + } + + KConfig * config = KGlobal::config(); + + if ( !init ) { + KDesktopShadowSettings *shadowSettings = static_cast(m_shadowEngine->shadowSettings()); + shadowSettings->setConfig(config); + } + + setMaySetWallpaper(!config->isImmutable() && !KGlobal::dirs()->isRestrictedResource("wallpaper")); + m_bShowDot = KDesktopSettings::showHidden(); + m_bVertAlign = KDesktopSettings::vertAlign(); + QStringList oldPreview = previewSettings(); + setPreviewSettings( KDesktopSettings::preview() ); + + // read arrange configuration + m_eSortCriterion = (SortCriterion)KDesktopSettings::sortCriterion(); + m_bSortDirectoriesFirst = KDesktopSettings::directoriesFirst(); + m_itemsAlwaysFirst = KDesktopSettings::alwaysFirstItems(); // Distributor plug-in + + if (KProtocolInfo::isKnownProtocol(QString::fromLatin1("media"))) + m_enableMedia=KDesktopSettings::mediaEnabled(); + else + m_enableMedia=false; + QString tmpList=KDesktopSettings::exclude(); + kdDebug(1204)<<"m_excludeList"<setShowingDotFiles( m_bShowDot ); + m_dirLister->emitChanges(); + } + + setArrangement(m_bVertAlign ? TopToBottom : LeftToRight); + + if ( KonqIconViewWidget::initConfig( init ) ) + lineupIcons(); // called if the font changed. + + setAutoArrange( false ); + + if ( previewSettings().count() ) + { + for ( QStringList::ConstIterator it = oldPreview.begin(); it != oldPreview.end(); ++it) + if ( !previewSettings().contains( *it ) ){ + kdDebug(1204) << "Disabling preview for " << *it << endl; + if ( *it == "audio/" ) + disableSoundPreviews(); + else + { + KService::Ptr serv = KService::serviceByDesktopName( *it ); + Q_ASSERT( serv != 0L ); + if ( serv ) + { + setIcons( iconSize( ), serv->property("MimeTypes").toStringList() /* revert no-longer wanted previews to icons */ ); + } + } + } + startImagePreview( QStringList(), true ); + } + else + { + stopImagePreview(); + setIcons( iconSize(), "*" /* stopImagePreview */ ); + } + + if ( !init ) + updateContents(); +} + +void KDIconView::start() +{ + // We can only start once + Q_ASSERT(!m_dirLister); + if (m_dirLister) + return; + + kdDebug(1204) << "KDIconView::start" << endl; + + // Create the directory lister + m_dirLister = new KDirLister(); + + m_bNeedSave = false; + + connect( m_dirLister, SIGNAL( clear() ), this, SLOT( slotClear() ) ); + connect( m_dirLister, SIGNAL( started(const KURL&) ), + this, SLOT( slotStarted(const KURL&) ) ); + connect( m_dirLister, SIGNAL( completed() ), this, SLOT( slotCompleted() ) ); + connect( m_dirLister, SIGNAL( newItems( const KFileItemList & ) ), + this, SLOT( slotNewItems( const KFileItemList & ) ) ); + connect( m_dirLister, SIGNAL( deleteItem( KFileItem * ) ), + this, SLOT( slotDeleteItem( KFileItem * ) ) ); + connect( m_dirLister, SIGNAL( refreshItems( const KFileItemList & ) ), + this, SLOT( slotRefreshItems( const KFileItemList & ) ) ); + + // Start the directory lister ! + m_dirLister->setShowingDotFiles( m_bShowDot ); + kapp->allowURLAction("list", KURL(), url()); + startDirLister(); + createActions(); +} + +void KDIconView::configureMedia() +{ + kdDebug(1204) << "***********KDIconView::configureMedia() " <setMimeExcludeFilter(m_excludedMedia); + m_dirLister->emitChanges(); + updateContents(); + if (m_enableMedia) + { + for (KURL::List::Iterator it1=m_mergeDirs.begin();it1!=m_mergeDirs.end();++it1) + { + if ((*it1).url()=="media:/") return; + } + m_mergeDirs.append(KURL("media:/")); + m_dirLister->openURL(KURL("media:/"),true); + } + else + { + for (KURL::List::Iterator it2=m_mergeDirs.begin();it2!=m_mergeDirs.end();++it2) + { + if ((*it2).url()=="media:/") + { + delete m_dirLister; + m_dirLister=0; + start(); +// m_mergeDirs.remove(it2); +// m_dirLister->stop("media"); + return; + } + + } + return; + } + +} + +void KDIconView::createActions() +{ + if (m_bEditableDesktopIcons) + { + KAction *undo = KStdAction::undo( KonqUndoManager::self(), SLOT( undo() ), &m_actionCollection, "undo" ); + connect( KonqUndoManager::self(), SIGNAL( undoAvailable( bool ) ), + undo, SLOT( setEnabled( bool ) ) ); + connect( KonqUndoManager::self(), SIGNAL( undoTextChanged( const QString & ) ), + undo, SLOT( setText( const QString & ) ) ); + undo->setEnabled( KonqUndoManager::self()->undoAvailable() ); + + KAction* paCut = KStdAction::cut( this, SLOT( slotCut() ), &m_actionCollection, "cut" ); + KShortcut cutShortCut = paCut->shortcut(); + cutShortCut.remove( KKey( SHIFT + Key_Delete ) ); // used for deleting files + paCut->setShortcut( cutShortCut ); + + KStdAction::copy( this, SLOT( slotCopy() ), &m_actionCollection, "copy" ); + KStdAction::paste( this, SLOT( slotPaste() ), &m_actionCollection, "paste" ); + KAction *pasteTo = KStdAction::paste( this, SLOT( slotPopupPasteTo() ), &m_actionCollection, "pasteto" ); + pasteTo->setEnabled( false ); // only enabled during popupMenu() + + KShortcut reloadShortcut = KStdAccel::shortcut(KStdAccel::Reload); + new KAction( i18n( "&Reload" ), "reload", reloadShortcut, this, SLOT( refreshIcons() ), &m_actionCollection, "reload" ); + + (void) new KAction( i18n( "&Rename" ), /*"editrename",*/ Key_F2, this, SLOT( renameSelectedItem() ), &m_actionCollection, "rename" ); + (void) new KAction( i18n( "&Properties" ), ALT+Key_Return, this, SLOT( slotProperties() ), &m_actionCollection, "properties" ); + KAction* trash = new KAction( i18n( "&Move to Trash" ), "edittrash", Key_Delete, &m_actionCollection, "trash" ); + connect( trash, SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState ) ), + this, SLOT( slotTrashActivated( KAction::ActivationReason, Qt::ButtonState ) ) ); + + KConfig config("kdeglobals", true, false); + config.setGroup( "KDE" ); + (void) new KAction( i18n( "&Delete" ), "editdelete", SHIFT+Key_Delete, this, SLOT( slotDelete() ), &m_actionCollection, "del" ); + + // Initial state of the actions (cut/copy/paste/...) + slotSelectionChanged(); + //init paste action + slotClipboardDataChanged(); + } +} + +void KDIconView::rearrangeIcons( SortCriterion sc, bool bSortDirectoriesFirst ) +{ + m_eSortCriterion = sc; + m_bSortDirectoriesFirst = bSortDirectoriesFirst; + rearrangeIcons(); +} + +void KDIconView::rearrangeIcons() +{ + setupSortKeys(); + sort(); // calls arrangeItemsInGrid() which does not honor iconArea() + + if ( m_autoAlign ) + lineupIcons( m_bVertAlign ? QIconView::TopToBottom : QIconView::LeftToRight ); // also saves position + else + { + KonqIconViewWidget::lineupIcons(m_bVertAlign ? QIconView::TopToBottom : QIconView::LeftToRight); + saveIconPositions(); + } +} + +void KDIconView::lineupIcons() +{ + if ( !m_gotIconsArea ) return; + KonqIconViewWidget::lineupIcons(); + saveIconPositions(); +} + +void KDIconView::setAutoAlign( bool b ) +{ + m_autoAlign = b; + + // Auto line-up icons + if ( b ) { + lineupIcons(); + connect( this, SIGNAL( iconMoved() ), + this, SLOT( lineupIcons() ) ); + } + else { + // change maxItemWidth, because when grid-align was active, it changed this for the grid + int sz = iconSize() ? iconSize() : KGlobal::iconLoader()->currentSize( KIcon::Desktop ); + setMaxItemWidth( QMAX( QMAX( sz, previewIconSize( iconSize() ) ), KonqFMSettings::settings()->iconTextWidth() ) ); + setFont( font() ); // Force calcRect() + + disconnect( this, SIGNAL( iconMoved() ), + this, SLOT( lineupIcons() ) ); + } +} + +void KDIconView::startDirLister() +{ + // if desktop is resized before start() is called (XRandr) + if (!m_dirLister) return; + + m_dirLister->openURL( url() ); + + // Gather the list of directories to merge into the desktop + // (the main URL is desktopURL(), no need for it in the m_mergeDirs list) + m_mergeDirs.clear(); + for ( QStringList::ConstIterator it = m_desktopDirs.begin() ; it != m_desktopDirs.end() ; ++it ) + { + kdDebug(1204) << "KDIconView::desktopResized found merge dir " << *it << endl; + KURL u; + u.setPath( *it ); + m_mergeDirs.append( u ); + // And start listing this dir right now + kapp->allowURLAction("list", KURL(), u); + m_dirLister->openURL( u, true ); + } + configureMedia(); +} + +void KDIconView::lineupIcons(QIconView::Arrangement align) +{ + m_bVertAlign = ( align == QIconView::TopToBottom ); + setArrangement( m_bVertAlign ? TopToBottom : LeftToRight ); + + if ( m_autoAlign ) + { + KonqIconViewWidget::lineupIcons( align ); + saveIconPositions(); + } + else + rearrangeIcons(); // also saves the position + + KDesktopSettings::setVertAlign( m_bVertAlign ); + KDesktopSettings::writeConfig(); +} + +// Only used for DCOP +QStringList KDIconView::selectedURLs() +{ + QStringList seq; + + QIconViewItem *it = firstItem(); + for (; it; it = it->nextItem() ) + if ( it->isSelected() ) { + KFileItem *fItem = ((KFileIVI *)it)->item(); + seq.append( fItem->url().url() ); // copy the URL + } + + return seq; +} + +void KDIconView::recheckDesktopURL() +{ + // Did someone change the path to the desktop ? + kdDebug(1204) << desktopURL().url() << endl; + kdDebug(1204) << url().url() << endl; + if ( desktopURL() != url() ) + { + kdDebug(1204) << "Desktop path changed from " << url().url() << + " to " << desktopURL().url() << endl; + setURL( desktopURL() ); // sets m_url + initDotDirectories(); + m_dirLister->openURL( url() ); + } +} + +KURL KDIconView::desktopURL() +{ + // Support both paths and URLs + QString desktopPath = KGlobalSettings::desktopPath(); + if (kdesktop_screen_number != 0) { + QString dn = "Desktop"; + dn += QString::number(kdesktop_screen_number); + desktopPath.replace("Desktop", dn); + } + + KURL desktopURL; + if (desktopPath[0] == '/') + desktopURL.setPath(desktopPath); + else + desktopURL = desktopPath; + + Q_ASSERT( desktopURL.isValid() ); + if ( !desktopURL.isValid() ) { // should never happen + KURL u; + u.setPath( QDir::homeDirPath() + "/" + "Desktop" + "/" ); + return u; + } + + return desktopURL; +} + +void KDIconView::contentsMousePressEvent( QMouseEvent *e ) +{ + if (!m_dirLister) return; + //kdDebug(1204) << "KDIconView::contentsMousePressEvent" << endl; + // QIconView, as of Qt 2.2, doesn't emit mouseButtonPressed for LMB on background + if ( e->button() == LeftButton && KRootWm::self()->hasLeftButtonMenu() ) + { + QIconViewItem *item = findItem( e->pos() ); + if ( !item ) + { + // Left click menu + KRootWm::self()->mousePressed( e->globalPos(), e->button() ); + return; + } + } + KonqIconViewWidget::contentsMousePressEvent( e ); +} + +void KDIconView::mousePressEvent( QMouseEvent *e ) +{ + KRootWm::self()->mousePressed( e->globalPos(), e->button() ); +} + +void KDIconView::wheelEvent( QWheelEvent* e ) +{ + if (!m_dirLister) return; + //kdDebug(1204) << "KDIconView::wheelEvent" << endl; + + QIconViewItem *item = findItem( e->pos() ); + if ( !item ) + { + emit wheelRolled( e->delta() ); + return; + } + + KonqIconViewWidget::wheelEvent( e ); +} + +void KDIconView::slotProperties() +{ + KFileItemList selectedFiles = selectedFileItems(); + + if( selectedFiles.isEmpty() ) + return; + + (void) new KPropertiesDialog( selectedFiles ); +} + +void KDIconView::slotContextMenuRequested(QIconViewItem *_item, const QPoint& _global) +{ + if (_item) + { + ((KFileIVI*)_item)->setSelected( true ); + popupMenu( _global, selectedFileItems() ); + } +} + +void KDIconView::slotMouseButtonPressed(int _button, QIconViewItem* _item, const QPoint& _global) +{ + //kdDebug(1204) << "KDIconView::slotMouseButtonPressed" << endl; + if (!m_dirLister) return; + m_lastDeletedIconPos = QPoint(); // user action -> not renaming an icon + if(!_item) + KRootWm::self()->mousePressed( _global, _button ); +} + +void KDIconView::slotMouseButtonClickedKDesktop(int _button, QIconViewItem* _item, const QPoint&) +{ + if (!m_dirLister) return; + //kdDebug(1204) << "KDIconView::slotMouseButtonClickedKDesktop" << endl; + if ( _item && _button == MidButton ) + slotExecuted(_item); +} + +// ----------------------------------------------------------------------------- + +void KDIconView::slotReturnPressed( QIconViewItem *item ) +{ + if (item && item->isSelected()) + slotExecuted(item); +} + +// ----------------------------------------------------------------------------- + +void KDIconView::slotExecuted( QIconViewItem *item ) +{ + kapp->propagateSessionManager(); + m_lastDeletedIconPos = QPoint(); // user action -> not renaming an icon + if (item) { + visualActivate(item); + ((KFileIVI*)item)->returnPressed(); + } +} + +// ----------------------------------------------------------------------------- + +void KDIconView::slotCut() +{ + cutSelection(); +} + +// ----------------------------------------------------------------------------- + +void KDIconView::slotCopy() +{ + copySelection(); +} + +// ----------------------------------------------------------------------------- + +void KDIconView::slotPaste() +{ + KonqOperations::doPaste(this, url(), KRootWm::self()->desktopMenuPosition()); +} + +void KDIconView::slotPopupPasteTo() +{ + Q_ASSERT( !m_popupURL.isEmpty() ); + if ( !m_popupURL.isEmpty() ) + paste( m_popupURL ); +} + +/** + * The files on the desktop come from a variety of sources. + * If an attempt is made to delete a .desktop file that does + * not originate from the users own Desktop directory then + * a .desktop file with "Hidden=true" is written to the users + * own Desktop directory to hide the file. + * + * Returns true if all selected items have been deleted. + * Returns false if there are selected items remaining that + * still need to be deleted in a regular fashion. + */ +bool KDIconView::deleteGlobalDesktopFiles() +{ + KURL desktop_URL = desktopURL(); + if (!desktop_URL.isLocalFile()) + return false; // Dunno how to do this. + + QString desktopPath = desktop_URL.path(); + + bool itemsLeft = false; + QIconViewItem *it = 0; + QIconViewItem *nextIt = firstItem(); + for (; (it = nextIt); ) + { + nextIt = it->nextItem(); + if ( !it->isSelected() ) + continue; + + KFileItem *fItem = ((KFileIVI *)it)->item(); + if (fItem->url().path().startsWith(desktopPath)) + { + itemsLeft = true; + continue; // File is in users own Desktop directory + } + + if (!isDesktopFile(fItem)) + { + itemsLeft = true; + continue; // Not a .desktop file + } + + KDesktopFile df(desktopPath + fItem->url().fileName()); + df.writeEntry("Hidden", true); + df.sync(); + + delete it; + } + return !itemsLeft; +} + +void KDIconView::slotTrashActivated( KAction::ActivationReason reason, Qt::ButtonState state ) +{ + if (deleteGlobalDesktopFiles()) + return; // All items deleted + + if ( reason == KAction::PopupMenuActivation && ( state & Qt::ShiftButton ) ) + KonqOperations::del(this, KonqOperations::DEL, selectedUrls()); + else + KonqOperations::del(this, KonqOperations::TRASH, selectedUrls()); +} + +void KDIconView::slotDelete() +{ + if (deleteGlobalDesktopFiles()) + return; // All items deleted + KonqOperations::del(this, KonqOperations::DEL, selectedUrls()); +} + +// ----------------------------------------------------------------------------- + +// This method is called when right-clicking over one or more items +// Not to be confused with the global popup-menu, KRootWm, when doing RMB on the desktop +void KDIconView::popupMenu( const QPoint &_global, const KFileItemList& _items ) +{ + if (!kapp->authorize("action/kdesktop_rmb")) return; + if (!m_dirLister) return; + if ( _items.count() == 1 ) + m_popupURL = _items.getFirst()->url(); + + KAction* pasteTo = m_actionCollection.action( "pasteto" ); + if (pasteTo) + pasteTo->setEnabled( m_actionCollection.action( "paste" )->isEnabled() ); + + bool hasMediaFiles = false; + KFileItemListIterator it(_items); + for (; it.current() && !hasMediaFiles; ++it) { + hasMediaFiles = it.current()->url().protocol() == "media"; + } + + KParts::BrowserExtension::PopupFlags itemFlags = KParts::BrowserExtension::DefaultPopupItems; + if ( hasMediaFiles ) + itemFlags |= KParts::BrowserExtension::NoDeletion; + KonqPopupMenu * popupMenu = new KonqPopupMenu( KonqBookmarkManager::self(), _items, + url(), + m_actionCollection, + KRootWm::self()->newMenu(), + this, + KonqPopupMenu::ShowProperties | KonqPopupMenu::ShowNewWindow, + itemFlags ); + + popupMenu->exec( _global ); + delete popupMenu; + m_popupURL = KURL(); + if (pasteTo) + pasteTo->setEnabled( false ); +} + +void KDIconView::slotNewMenuActivated() +{ + //kdDebug(1204) << "KDIconView::slotNewMenuActivated" << endl; + // New /