diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 4aed2c8219774f5d797760606b8489a92ddc5163 (patch) | |
tree | 3f8c130f7d269626bf6a9447407ef6c35954426a /konqueror/sidebar/trees/konq_sidebartree.cpp | |
download | tdebase-4aed2c8219774f5d797760606b8489a92ddc5163.tar.gz tdebase-4aed2c8219774f5d797760606b8489a92ddc5163.zip |
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
Diffstat (limited to 'konqueror/sidebar/trees/konq_sidebartree.cpp')
-rw-r--r-- | konqueror/sidebar/trees/konq_sidebartree.cpp | 1048 |
1 files changed, 1048 insertions, 0 deletions
diff --git a/konqueror/sidebar/trees/konq_sidebartree.cpp b/konqueror/sidebar/trees/konq_sidebartree.cpp new file mode 100644 index 000000000..e30e21ac9 --- /dev/null +++ b/konqueror/sidebar/trees/konq_sidebartree.cpp @@ -0,0 +1,1048 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <faure@kde.org> + 2000 Carsten Pfeiffer <pfeiffer@kde.org> + 2003 Waldo Bastian <bastian@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "konq_sidebartreemodule.h" + +#include <qclipboard.h> +#include <qcursor.h> +#include <qdir.h> +#include <qheader.h> +#include <qpopupmenu.h> +#include <qtimer.h> + +#include <dcopclient.h> +#include <dcopref.h> + +#include <kaction.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kdesktopfile.h> +#include <kdirnotify_stub.h> +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <kinputdialog.h> +#include <kio/netaccess.h> +#include <kmimetype.h> +#include <kprocess.h> +#include <kpropertiesdialog.h> +#include <kprotocolinfo.h> +#include <kstandarddirs.h> +#include <kurldrag.h> + +#include <stdlib.h> +#include <assert.h> + + +static const int autoOpenTimeout = 750; + + +getModule KonqSidebarTree::getPluginFactory(QString name) +{ + if (!pluginFactories.contains(name)) + { + KLibLoader *loader = KLibLoader::self(); + QString libName = pluginInfo[name]; + KLibrary *lib = loader->library(QFile::encodeName(libName)); + if (lib) + { + // get the create_ function + QString factory = "create_" + libName; + void *create = lib->symbol(QFile::encodeName(factory)); + if (create) + { + getModule func = (getModule)create; + pluginFactories.insert(name, func); + kdDebug()<<"Added a module"<<endl; + } + else + { + kdWarning()<<"No create function found in"<<libName<<endl; + } + } + else + kdWarning() << "Module " << libName << " can't be loaded!" << endl; + } + + return pluginFactories[name]; +} + +void KonqSidebarTree::loadModuleFactories() +{ + pluginFactories.clear(); + pluginInfo.clear(); + KStandardDirs *dirs=KGlobal::dirs(); + QStringList list=dirs->findAllResources("data","konqsidebartng/dirtree/*.desktop",false,true); + + + for (QStringList::ConstIterator it=list.begin();it!=list.end();++it) + { + KSimpleConfig ksc(*it); + ksc.setGroup("Desktop Entry"); + QString name = ksc.readEntry("X-KDE-TreeModule"); + QString libName = ksc.readEntry("X-KDE-TreeModule-Lib"); + if ((name.isEmpty()) || (libName.isEmpty())) + {kdWarning()<<"Bad Configuration file for a dirtree module "<<*it<<endl; continue;} + + //Register the library info. + pluginInfo[name] = libName; + } +} + + +class KonqSidebarTree_Internal +{ +public: + DropAcceptType m_dropMode; + QStringList m_dropFormats; +}; + + +KonqSidebarTree::KonqSidebarTree( KonqSidebar_Tree *parent, QWidget *parentWidget, int virt, const QString& path ) + : KListView( parentWidget ), + m_currentTopLevelItem( 0 ), + m_toolTip( this ), + m_scrollingLocked( false ), + m_collection( 0 ) +{ + d = new KonqSidebarTree_Internal; + d->m_dropMode = SidebarTreeMode; + + loadModuleFactories(); + + setAcceptDrops( true ); + viewport()->setAcceptDrops( true ); + m_lstModules.setAutoDelete( true ); + + setSelectionMode( QListView::Single ); + setDragEnabled(true); + + m_part = parent; + + m_animationTimer = new QTimer( this ); + connect( m_animationTimer, SIGNAL( timeout() ), + this, SLOT( slotAnimation() ) ); + + m_currentBeforeDropItem = 0; + m_dropItem = 0; + m_bOpeningFirstChild=false; + + addColumn( QString::null ); + header()->hide(); + setTreeStepSize(15); + + m_autoOpenTimer = new QTimer( this ); + connect( m_autoOpenTimer, SIGNAL( timeout() ), + this, SLOT( slotAutoOpenFolder() ) ); + + connect( this, SIGNAL( doubleClicked( QListViewItem * ) ), + this, SLOT( slotDoubleClicked( QListViewItem * ) ) ); + connect( this, SIGNAL( mouseButtonPressed(int, QListViewItem*, const QPoint&, int)), + this, SLOT( slotMouseButtonPressed(int, QListViewItem*, const QPoint&, int)) ); + connect( this, SIGNAL( mouseButtonClicked( int, QListViewItem*, const QPoint&, int ) ), + this, SLOT( slotMouseButtonClicked( int, QListViewItem*, const QPoint&, int ) ) ); + connect( this, SIGNAL( returnPressed( QListViewItem * ) ), + this, SLOT( slotDoubleClicked( QListViewItem * ) ) ); + connect( this, SIGNAL( selectionChanged() ), + this, SLOT( slotSelectionChanged() ) ); + + connect( this, SIGNAL(itemRenamed(QListViewItem*, const QString &, int)), + this, SLOT(slotItemRenamed(QListViewItem*, const QString &, int))); + +/* assert( m_part->getInterfaces()->getInstance()->dirs ); + QString dirtreeDir = m_part->getInterfaces()->getInstance()->dirs()->saveLocation( "data", "konqueror/dirtree/" ); */ + +// assert( KGlobal::dirs() ); +// QString dirtreeDir = part->getInterfaces()->getInstance()->dirs()->saveLocation( "data", "konqueror/dirtree/" ); + + if (virt==VIRT_Folder) + { + m_dirtreeDir.dir.setPath(KGlobal::dirs()->saveLocation("data","konqsidebartng/virtual_folders/"+path+"/")); + m_dirtreeDir.relDir=path; + } + else + m_dirtreeDir.dir.setPath( path ); + kdDebug(1201)<<m_dirtreeDir.dir.path()<<endl; + m_dirtreeDir.type=virt; + // Initial parsing + rescanConfiguration(); + + if (firstChild()) + { + m_bOpeningFirstChild = true; + firstChild()->setOpen(true); + m_bOpeningFirstChild = false; + } + + setFrameStyle( QFrame::ToolBarPanel | QFrame::Raised ); +} + +KonqSidebarTree::~KonqSidebarTree() +{ + clearTree(); + + delete d; +} + +void KonqSidebarTree::itemDestructed( KonqSidebarTreeItem *item ) +{ + stopAnimation(item); + + if (item == m_currentBeforeDropItem) + { + m_currentBeforeDropItem = 0; + } +} + +void KonqSidebarTree::setDropFormats(const QStringList &formats) +{ + d->m_dropFormats = formats; +} + +void KonqSidebarTree::clearTree() +{ + m_lstModules.clear(); + m_topLevelItems.clear(); + m_mapCurrentOpeningFolders.clear(); + m_currentBeforeDropItem = 0; + clear(); + + if (m_dirtreeDir.type==VIRT_Folder) + { + setRootIsDecorated( true ); + } + else + { + setRootIsDecorated( false ); + } +} + +void KonqSidebarTree::followURL( const KURL &url ) +{ + // Maybe we're there already ? + KonqSidebarTreeItem *selection = static_cast<KonqSidebarTreeItem *>( selectedItem() ); + if (selection && selection->externalURL().equals( url, true )) + { + ensureItemVisible( selection ); + return; + } + + kdDebug(1201) << "KonqDirTree::followURL: " << url.url() << endl; + QPtrListIterator<KonqSidebarTreeTopLevelItem> topItem ( m_topLevelItems ); + for (; topItem.current(); ++topItem ) + { + if ( topItem.current()->externalURL().isParentOf( url ) ) + { + topItem.current()->module()->followURL( url ); + return; // done + } + } + kdDebug(1201) << "KonqDirTree::followURL: Not found" << endl; +} + +void KonqSidebarTree::contentsDragEnterEvent( QDragEnterEvent *ev ) +{ + m_dropItem = 0; + m_currentBeforeDropItem = selectedItem(); + // Save the available formats + m_lstDropFormats.clear(); + for( int i = 0; ev->format( i ); i++ ) + if ( *( ev->format( i ) ) ) + m_lstDropFormats.append( ev->format( i ) ); +} + +void KonqSidebarTree::contentsDragMoveEvent( QDragMoveEvent *e ) +{ + QListViewItem *item = itemAt( contentsToViewport( e->pos() ) ); + + // Accept drops on the background, if URLs + if ( !item && m_lstDropFormats.contains("text/uri-list") ) + { + m_dropItem = 0; + e->acceptAction(); + if (selectedItem()) + setSelected( selectedItem(), false ); // no item selected + return; + } + + if (item && static_cast<KonqSidebarTreeItem*>(item)->acceptsDrops( m_lstDropFormats )) { + d->m_dropMode = SidebarTreeMode; + + if ( !item->isSelectable() ) + { + m_dropItem = 0; + m_autoOpenTimer->stop(); + e->ignore(); + return; + } + + e->acceptAction(); + + setSelected( item, true ); + + if ( item != m_dropItem ) + { + m_autoOpenTimer->stop(); + m_dropItem = item; + m_autoOpenTimer->start( autoOpenTimeout ); + } + } else { + d->m_dropMode = KListViewMode; + KListView::contentsDragMoveEvent(e); + } +} + +void KonqSidebarTree::contentsDragLeaveEvent( QDragLeaveEvent *ev ) +{ + // Restore the current item to what it was before the dragging (#17070) + if ( m_currentBeforeDropItem ) + setSelected( m_currentBeforeDropItem, true ); + else + setSelected( m_dropItem, false ); // no item selected + m_currentBeforeDropItem = 0; + m_dropItem = 0; + m_lstDropFormats.clear(); + + if (d->m_dropMode == KListViewMode) { + KListView::contentsDragLeaveEvent(ev); + } +} + +void KonqSidebarTree::contentsDropEvent( QDropEvent *ev ) +{ + if (d->m_dropMode == SidebarTreeMode) { + m_autoOpenTimer->stop(); + + if ( !selectedItem() ) + { + // KonqOperations::doDrop( 0L, m_dirtreeDir.dir, ev, this ); + KURL::List urls; + if ( KURLDrag::decode( ev, urls ) ) + { + for(KURL::List::ConstIterator it = urls.begin(); + it != urls.end(); ++it) + { + addURL(0, *it); + } + } + } + else + { + KonqSidebarTreeItem *selection = static_cast<KonqSidebarTreeItem *>( selectedItem() ); + selection->drop( ev ); + } + } else { + KListView::contentsDropEvent(ev); + } +} + +static QString findUniqueFilename(const QString &path, QString filename) +{ + if (filename.endsWith(".desktop")) + filename.truncate(filename.length()-8); + + QString name = filename; + int n = 2; + while(QFile::exists(path + filename + ".desktop")) + { + filename = QString("%2_%1").arg(n++).arg(name); + } + return path+filename+".desktop"; +} + +void KonqSidebarTree::addURL(KonqSidebarTreeTopLevelItem* item, const KURL & url) +{ + QString path; + if (item) + path = item->path(); + else + path = m_dirtreeDir.dir.path(); + + KURL destUrl; + + if (url.isLocalFile() && url.fileName().endsWith(".desktop")) + { + QString filename = findUniqueFilename(path, url.fileName()); + destUrl.setPath(filename); + KIO::NetAccess::copy(url, destUrl, this); + } + else + { + QString name = url.host(); + if (name.isEmpty()) + name = url.fileName(); + QString filename = findUniqueFilename(path, name); + destUrl.setPath(filename); + + KDesktopFile cfg(filename); + cfg.writeEntry("Encoding", "UTF-8"); + cfg.writeEntry("Type","Link"); + cfg.writeEntry("URL", url.url()); + QString icon = "folder"; + if (!url.isLocalFile()) + icon = KMimeType::favIconForURL(url); + if (icon.isEmpty()) + icon = KProtocolInfo::icon( url.protocol() ); + cfg.writeEntry("Icon", icon); + cfg.writeEntry("Name", name); + cfg.writeEntry("Open", false); + cfg.sync(); + } + + KDirNotify_stub allDirNotify( "*", "KDirNotify*" ); + destUrl.setPath( destUrl.directory() ); + allDirNotify.FilesAdded( destUrl ); + + if (item) + item->setOpen(true); +} + +bool KonqSidebarTree::acceptDrag(QDropEvent* e) const +{ + // for KListViewMode... + for( int i = 0; e->format( i ); i++ ) + if ( d->m_dropFormats.contains(e->format( i ) ) ) + return true; + return false; +} + +QDragObject* KonqSidebarTree::dragObject() +{ + KonqSidebarTreeItem* item = static_cast<KonqSidebarTreeItem *>( selectedItem() ); + if ( !item ) + return 0; + + QDragObject* drag = item->dragObject( viewport(), false ); + if ( !drag ) + return 0; + + const QPixmap *pix = item->pixmap(0); + if ( pix && drag->pixmap().isNull() ) + drag->setPixmap( *pix ); + + return drag; +} + +void KonqSidebarTree::leaveEvent( QEvent *e ) +{ + KListView::leaveEvent( e ); +// emitStatusBarText( QString::null ); +} + + +void KonqSidebarTree::slotDoubleClicked( QListViewItem *item ) +{ + //kdDebug(1201) << "KonqSidebarTree::slotDoubleClicked " << item << endl; + if ( !item ) + return; + + if ( !static_cast<KonqSidebarTreeItem*>(item)->isClickable() ) + return; + + slotExecuted( item ); + item->setOpen( !item->isOpen() ); +} + +void KonqSidebarTree::slotExecuted( QListViewItem *item ) +{ + kdDebug(1201) << "KonqSidebarTree::slotExecuted " << item << endl; + if ( !item ) + return; + + if ( !static_cast<KonqSidebarTreeItem*>(item)->isClickable() ) + return; + + KonqSidebarTreeItem *dItem = static_cast<KonqSidebarTreeItem *>( item ); + + KParts::URLArgs args; + + args.serviceType = dItem->externalMimeType(); + args.trustedSource = true; + KURL externalURL = dItem->externalURL(); + if ( !externalURL.isEmpty() ) + openURLRequest( externalURL, args ); +} + +void KonqSidebarTree::slotMouseButtonPressed( int _button, QListViewItem* _item, const QPoint&, int col ) +{ + KonqSidebarTreeItem * item = static_cast<KonqSidebarTreeItem*>( _item ); + if (_button == RightButton) + { + if ( item && col < 2) + { + item->setSelected( true ); + item->rightButtonPressed(); + } + } +} + +void KonqSidebarTree::slotMouseButtonClicked(int _button, QListViewItem* _item, const QPoint&, int col) +{ + KonqSidebarTreeItem * item = static_cast<KonqSidebarTreeItem*>(_item); + if(_item && col < 2) + { + switch( _button ) { + case LeftButton: + slotExecuted( item ); + break; + case MidButton: + item->middleButtonClicked(); + break; + } + } +} + +void KonqSidebarTree::slotAutoOpenFolder() +{ + m_autoOpenTimer->stop(); + + if ( !m_dropItem || m_dropItem->isOpen() ) + return; + + m_dropItem->setOpen( true ); + m_dropItem->repaint(); +} + +void KonqSidebarTree::rescanConfiguration() +{ + kdDebug(1201) << "KonqSidebarTree::rescanConfiguration()" << endl; + m_autoOpenTimer->stop(); + clearTree(); + if (m_dirtreeDir.type==VIRT_Folder) + { + kdDebug(1201)<<"KonqSidebarTree::rescanConfiguration()-->scanDir"<<endl; + scanDir( 0, m_dirtreeDir.dir.path(), true); + + } + else + { + kdDebug(1201)<<"KonqSidebarTree::rescanConfiguration()-->loadTopLevel"<<endl; + loadTopLevelItem( 0, m_dirtreeDir.dir.path() ); + } +} + +void KonqSidebarTree::slotSelectionChanged() +{ + if ( !m_dropItem ) // don't do this while the dragmove thing + { + KonqSidebarTreeItem * item = static_cast<KonqSidebarTreeItem *>( selectedItem() ); + if ( item ) + item->itemSelected(); + /* else -- doesn't seem to happen + {} */ + } +} + +void KonqSidebarTree::FilesAdded( const KURL & dir ) +{ + kdDebug(1201) << "KonqSidebarTree::FilesAdded " << dir.url() << endl; + if ( m_dirtreeDir.dir.isParentOf( dir ) ) + // We use a timer in case of DCOP re-entrance.. + QTimer::singleShot( 0, this, SLOT( rescanConfiguration() ) ); +} + +void KonqSidebarTree::FilesRemoved( const KURL::List & urls ) +{ + //kdDebug(1201) << "KonqSidebarTree::FilesRemoved " << urls.count() << endl; + for ( KURL::List::ConstIterator it = urls.begin() ; it != urls.end() ; ++it ) + { + //kdDebug(1201) << "KonqSidebarTree::FilesRemoved " << (*it).prettyURL() << endl; + if ( m_dirtreeDir.dir.isParentOf( *it ) ) + { + QTimer::singleShot( 0, this, SLOT( rescanConfiguration() ) ); + kdDebug(1201) << "KonqSidebarTree::FilesRemoved done" << endl; + return; + } + } +} + +void KonqSidebarTree::FilesChanged( const KURL::List & urls ) +{ + //kdDebug(1201) << "KonqSidebarTree::FilesChanged" << endl; + // not same signal, but same implementation + FilesRemoved( urls ); +} + +void KonqSidebarTree::scanDir( KonqSidebarTreeItem *parent, const QString &path, bool isRoot ) +{ + QDir dir( path ); + + if ( !dir.isReadable() ) + return; + + kdDebug(1201) << "scanDir " << path << endl; + + QStringList entries = dir.entryList( QDir::Files ); + QStringList dirEntries = dir.entryList( QDir::Dirs | QDir::NoSymLinks ); + dirEntries.remove( "." ); + dirEntries.remove( ".." ); + + if ( isRoot ) + { + bool copyConfig = ( entries.count() == 0 && dirEntries.count() == 0 ); + if (!copyConfig) + { + // Check version number + // Version 1 was the dirtree of KDE 2.0.x (no versioning at that time, so default) + // Version 2 includes the history + // Version 3 includes the bookmarks + // Version 4 includes lan.desktop and floppy.desktop, Alex + // Version 5 includes the audiocd browser + // Version 6 includes the printmanager and lan browser + const int currentVersion = 6; + QString key = QString::fromLatin1("X-KDE-DirTreeVersionNumber"); + KSimpleConfig versionCfg( path + "/.directory" ); + int versionNumber = versionCfg.readNumEntry( key, 1 ); + kdDebug(1201) << "KonqSidebarTree::scanDir found version " << versionNumber << endl; + if ( versionNumber < currentVersion ) + { + versionCfg.writeEntry( key, currentVersion ); + versionCfg.sync(); + copyConfig = true; + } + } + if (copyConfig) + { + // We will copy over the configuration for the dirtree, from the global directory + QStringList dirtree_dirs = KGlobal::dirs()->findDirs("data","konqsidebartng/virtual_folders/"+m_dirtreeDir.relDir+"/"); + + +// QString dirtree_dir = KGlobal::dirs()->findDirs("data","konqsidebartng/virtual_folders/"+m_dirtreeDir.relDir+"/").last(); // most global +// kdDebug(1201) << "KonqSidebarTree::scanDir dirtree_dir=" << dirtree_dir << endl; + + /* + // debug code + + QStringList blah = m_part->getInterfaces->getInstance()->dirs()->dirs()->findDirs( "data", "konqueror/dirtree" ); + QStringList::ConstIterator eIt = blah.begin(); + QStringList::ConstIterator eEnd = blah.end(); + for (; eIt != eEnd; ++eIt ) + kdDebug(1201) << "KonqSidebarTree::scanDir findDirs got me " << *eIt << endl; + // end debug code + */ + + for (QStringList::const_iterator ddit=dirtree_dirs.begin();ddit!=dirtree_dirs.end();++ddit) { + QString dirtree_dir=*ddit; + if (dirtree_dir==path) continue; + // if ( !dirtree_dir.isEmpty() && dirtree_dir != path ) + { + QDir globalDir( dirtree_dir ); + Q_ASSERT( globalDir.isReadable() ); + // Only copy the entries that don't exist yet in the local dir + QStringList globalDirEntries = globalDir.entryList(); + QStringList::ConstIterator eIt = globalDirEntries.begin(); + QStringList::ConstIterator eEnd = globalDirEntries.end(); + for (; eIt != eEnd; ++eIt ) + { + //kdDebug(1201) << "KonqSidebarTree::scanDir dirtree_dir contains " << *eIt << endl; + if ( *eIt != "." && *eIt != ".." + && !entries.contains( *eIt ) && !dirEntries.contains( *eIt ) ) + { // we don't have that one yet -> copy it. + QString cp("cp -R -- "); + cp += KProcess::quote(dirtree_dir + *eIt); + cp += " "; + cp += KProcess::quote(path); + kdDebug(1201) << "KonqSidebarTree::scanDir executing " << cp << endl; + ::system( QFile::encodeName(cp) ); + } + } + } + } + // hack to make QDir refresh the lists + dir.setPath(path); + entries = dir.entryList( QDir::Files ); + dirEntries = dir.entryList( QDir::Dirs ); + dirEntries.remove( "." ); + dirEntries.remove( ".." ); + } + } + QStringList::ConstIterator eIt = entries.begin(); + QStringList::ConstIterator eEnd = entries.end(); + + for (; eIt != eEnd; ++eIt ) + { + QString filePath = QString( *eIt ).prepend( path ); + KURL u; + u.setPath( filePath ); + if ( KMimeType::findByURL( u, 0, true )->name() == "application/x-desktop" ) + loadTopLevelItem( parent, filePath ); + } + + eIt = dirEntries.begin(); + eEnd = dirEntries.end(); + + for (; eIt != eEnd; eIt++ ) + { + QString newPath = QString( path ).append( *eIt ).append( '/' ); + + if ( newPath == KGlobalSettings::autostartPath() ) + continue; + + loadTopLevelGroup( parent, newPath ); + } +} + +void KonqSidebarTree::loadTopLevelGroup( KonqSidebarTreeItem *parent, const QString &path ) +{ + QDir dir( path ); + QString name = dir.dirName(); + QString icon = "folder"; + bool open = false; + + kdDebug(1201) << "Scanning " << path << endl; + + QString dotDirectoryFile = QString( path ).append( "/.directory" ); + + if ( QFile::exists( dotDirectoryFile ) ) + { + kdDebug(1201) << "Reading the .directory" << endl; + KSimpleConfig cfg( dotDirectoryFile, true ); + cfg.setDesktopGroup(); + name = cfg.readEntry( "Name", name ); + icon = cfg.readEntry( "Icon", icon ); + //stripIcon( icon ); + open = cfg.readBoolEntry( "Open", open ); + } + + KonqSidebarTreeTopLevelItem *item; + if ( parent ) + { + kdDebug(1201) << "KonqSidebarTree::loadTopLevelGroup Inserting new group under parent " << endl; + item = new KonqSidebarTreeTopLevelItem( parent, 0 /* no module */, path ); + } + else + item = new KonqSidebarTreeTopLevelItem( this, 0 /* no module */, path ); + item->setText( 0, name ); + item->setPixmap( 0, SmallIcon( icon ) ); + item->setListable( false ); + item->setClickable( false ); + item->setTopLevelGroup( true ); + item->setOpen( open ); + + m_topLevelItems.append( item ); + + kdDebug(1201) << "Inserting group " << name << " " << path << endl; + + scanDir( item, path ); + + if ( item->childCount() == 0 ) + item->setExpandable( false ); +} + +void KonqSidebarTree::loadTopLevelItem( KonqSidebarTreeItem *parent, const QString &filename ) +{ + KDesktopFile cfg( filename, true ); + cfg.setDollarExpansion(true); + + QFileInfo inf( filename ); + + QString path = filename; + QString name = KIO::decodeFileName( inf.fileName() ); + if ( name.length() > 8 && name.right( 8 ) == ".desktop" ) + name.truncate( name.length() - 8 ); + if ( name.length() > 7 && name.right( 7 ) == ".kdelnk" ) + name.truncate( name.length() - 7 ); + + name = cfg.readEntry( "Name", name ); + KonqSidebarTreeModule * module = 0L; + + // Here's where we need to create the right module... + // ### TODO: make this KTrader/KLibrary based. + QString moduleName = cfg.readEntry( "X-KDE-TreeModule" ); + QString showHidden=cfg.readEntry("X-KDE-TreeModule-ShowHidden"); + + if (moduleName.isEmpty()) moduleName="Directory"; + kdDebug(1201) << "##### Loading module: " << moduleName << " file: " << filename << endl; + + getModule func; + func = getPluginFactory(moduleName); + if (func!=0) + { + kdDebug(1201)<<"showHidden: "<<showHidden<<endl; + module=func(this,showHidden.upper()=="TRUE"); + } + + if (module==0) {kdDebug()<<"No Module loaded"<<endl; return;} + + KonqSidebarTreeTopLevelItem *item; + if ( parent ) + item = new KonqSidebarTreeTopLevelItem( parent, module, path ); + else + item = new KonqSidebarTreeTopLevelItem( this, module, path ); + + item->setText( 0, name ); + item->setPixmap( 0, SmallIcon( cfg.readIcon() )); + + module->addTopLevelItem( item ); + + m_topLevelItems.append( item ); + m_lstModules.append( module ); + + bool open = cfg.readBoolEntry( "Open", false ); + if ( open && item->isExpandable() ) + item->setOpen( true ); +} + +void KonqSidebarTree::slotAnimation() +{ + MapCurrentOpeningFolders::Iterator it = m_mapCurrentOpeningFolders.begin(); + MapCurrentOpeningFolders::Iterator end = m_mapCurrentOpeningFolders.end(); + for (; it != end; ++it ) + { + uint & iconNumber = it.data().iconNumber; + QString icon = QString::fromLatin1( it.data().iconBaseName ).append( QString::number( iconNumber ) ); + it.key()->setPixmap( 0, SmallIcon( icon)); + + iconNumber++; + if ( iconNumber > it.data().iconCount ) + iconNumber = 1; + } +} + + +void KonqSidebarTree::startAnimation( KonqSidebarTreeItem * item, const char * iconBaseName, uint iconCount, const QPixmap * originalPixmap ) +{ + const QPixmap *pix = originalPixmap ? originalPixmap : item->pixmap(0); + if (pix) + { + m_mapCurrentOpeningFolders.insert( item, AnimationInfo( iconBaseName, iconCount, *pix ) ); + if ( !m_animationTimer->isActive() ) + m_animationTimer->start( 50 ); + } +} + +void KonqSidebarTree::stopAnimation( KonqSidebarTreeItem * item ) +{ + MapCurrentOpeningFolders::Iterator it = m_mapCurrentOpeningFolders.find(item); + if ( it != m_mapCurrentOpeningFolders.end() ) + { + item->setPixmap( 0, it.data().originalPixmap ); + m_mapCurrentOpeningFolders.remove( item ); + + if (m_mapCurrentOpeningFolders.isEmpty()) + m_animationTimer->stop(); + } +} + +KonqSidebarTreeItem * KonqSidebarTree::currentItem() const +{ + return static_cast<KonqSidebarTreeItem *>( selectedItem() ); +} + +void KonqSidebarTree::setContentsPos( int x, int y ) +{ + if ( !m_scrollingLocked ) + KListView::setContentsPos( x, y ); +} + +void KonqSidebarTree::slotItemRenamed(QListViewItem* item, const QString &name, int col) +{ + Q_ASSERT(col==0); + if (col != 0) return; + assert(item); + KonqSidebarTreeItem * treeItem = static_cast<KonqSidebarTreeItem *>(item); + treeItem->rename( name ); +} + + +void KonqSidebarTree::enableActions( bool copy, bool cut, bool paste, + bool trash, bool del, bool rename) +{ + enableAction( "copy", copy ); + enableAction( "cut", cut ); + enableAction( "paste", paste ); + enableAction( "trash", trash ); + enableAction( "del", del ); + enableAction( "rename", rename ); +} + +bool KonqSidebarTree::tabSupport() +{ + // see if the newTab() dcop function is available (i.e. the sidebar is embedded into konqueror) + DCOPRef ref(kapp->dcopClient()->appId(), topLevelWidget()->name()); + DCOPReply reply = ref.call("functions()"); + if (reply.isValid()) { + QCStringList funcs; + reply.get(funcs, "QCStringList"); + for (QCStringList::ConstIterator it = funcs.begin(); it != funcs.end(); ++it) { + if ((*it) == "void newTab(QString url)") { + return true; + break; + } + } + } + return false; +} + +void KonqSidebarTree::showToplevelContextMenu() +{ + KonqSidebarTreeTopLevelItem *item = 0; + KonqSidebarTreeItem *treeItem = currentItem(); + if (treeItem && treeItem->isTopLevelItem()) + item = static_cast<KonqSidebarTreeTopLevelItem *>(treeItem); + + if (!m_collection) + { + m_collection = new KActionCollection( this, "bookmark actions" ); + (void) new KAction( i18n("&Create New Folder..."), "folder_new", 0, this, + SLOT( slotCreateFolder() ), m_collection, "create_folder"); + (void) new KAction( i18n("Delete Folder"), "editdelete", 0, this, + SLOT( slotDelete() ), m_collection, "delete_folder"); + (void) new KAction( i18n("Rename"), 0, this, + SLOT( slotRename() ), m_collection, "rename"); + (void) new KAction( i18n("Delete Link"), "editdelete", 0, this, + SLOT( slotDelete() ), m_collection, "delete_link"); + (void) new KAction( i18n("Properties"), "edit", 0, this, + SLOT( slotProperties() ), m_collection, "item_properties"); + (void) new KAction( i18n("Open in New Window"), "window_new", 0, this, + SLOT( slotOpenNewWindow() ), m_collection, "open_window"); + (void) new KAction( i18n("Open in New Tab"), "tab_new", 0, this, + SLOT( slotOpenTab() ), m_collection, "open_tab"); + (void) new KAction( i18n("Copy Link Address"), "editcopy", 0, this, + SLOT( slotCopyLocation() ), m_collection, "copy_location"); + } + + QPopupMenu *menu = new QPopupMenu; + + if (item) { + if (item->isTopLevelGroup()) { + m_collection->action("rename")->plug(menu); + m_collection->action("delete_folder")->plug(menu); + menu->insertSeparator(); + m_collection->action("create_folder")->plug(menu); + } else { + if (tabSupport()) + m_collection->action("open_tab")->plug(menu); + m_collection->action("open_window")->plug(menu); + m_collection->action("copy_location")->plug(menu); + menu->insertSeparator(); + m_collection->action("rename")->plug(menu); + m_collection->action("delete_link")->plug(menu); + } + menu->insertSeparator(); + m_collection->action("item_properties")->plug(menu); + } else { + m_collection->action("create_folder")->plug(menu); + } + + m_currentTopLevelItem = item; + + menu->exec( QCursor::pos() ); + delete menu; + + m_currentTopLevelItem = 0; +} + +void KonqSidebarTree::slotCreateFolder() +{ + QString path; + QString name = i18n("New Folder"); + + while(true) + { + name = KInputDialog::getText(i18n("Create New Folder"), + i18n("Enter folder name:"), name); + if (name.isEmpty()) + return; + + if (m_currentTopLevelItem) + path = m_currentTopLevelItem->path(); + else + path = m_dirtreeDir.dir.path(); + + if (!path.endsWith("/")) + path += "/"; + + path = path + name; + + if (!QFile::exists(path)) + break; + + name = name + "-2"; + } + + KGlobal::dirs()->makeDir(path); + + loadTopLevelGroup(m_currentTopLevelItem, path); +} + +void KonqSidebarTree::slotDelete() +{ + if (!m_currentTopLevelItem) return; + m_currentTopLevelItem->del(); +} + +void KonqSidebarTree::slotRename() +{ + if (!m_currentTopLevelItem) return; + m_currentTopLevelItem->rename(); +} + +void KonqSidebarTree::slotProperties() +{ + if (!m_currentTopLevelItem) return; + + KURL url; + url.setPath(m_currentTopLevelItem->path()); + + KPropertiesDialog *dlg = new KPropertiesDialog( url ); + dlg->setFileNameReadOnly(true); + dlg->exec(); + delete dlg; +} + +void KonqSidebarTree::slotOpenNewWindow() +{ + if (!m_currentTopLevelItem) return; + emit createNewWindow( m_currentTopLevelItem->externalURL() ); +} + +void KonqSidebarTree::slotOpenTab() +{ + if (!m_currentTopLevelItem) return; + DCOPRef ref(kapp->dcopClient()->appId(), topLevelWidget()->name()); + ref.call( "newTab(QString)", m_currentTopLevelItem->externalURL().url() ); +} + +void KonqSidebarTree::slotCopyLocation() +{ + if (!m_currentTopLevelItem) return; + KURL url = m_currentTopLevelItem->externalURL(); + kapp->clipboard()->setData( new KURLDrag(url, 0), QClipboard::Selection ); + kapp->clipboard()->setData( new KURLDrag(url, 0), QClipboard::Clipboard ); +} + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + + +void KonqSidebarTreeToolTip::maybeTip( const QPoint &point ) +{ + QListViewItem *item = m_view->itemAt( point ); + if ( item ) { + QString text = static_cast<KonqSidebarTreeItem*>( item )->toolTipText(); + if ( !text.isEmpty() ) + tip ( m_view->itemRect( item ), text ); + } +} + + + + +#include "konq_sidebartree.moc" |