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/dirtree_module | |
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/dirtree_module')
5 files changed, 1059 insertions, 0 deletions
diff --git a/konqueror/sidebar/trees/dirtree_module/Makefile.am b/konqueror/sidebar/trees/dirtree_module/Makefile.am new file mode 100644 index 000000000..eb6cf061c --- /dev/null +++ b/konqueror/sidebar/trees/dirtree_module/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = -I$(top_srcdir)/libkonq -I$(srcdir)/.. -I$(srcdir)/../.. $(all_includes) + +kde_module_LTLIBRARIES = konq_sidebartree_dirtree.la + +METASOURCES = AUTO +konq_sidebartree_dirtree_la_SOURCES = dirtree_module.cpp dirtree_item.cpp +konq_sidebartree_dirtree_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +konq_sidebartree_dirtree_la_LIBADD = ../../libkonqsidebarplugin.la ../libkonq_sidebar_tree.la + + diff --git a/konqueror/sidebar/trees/dirtree_module/dirtree_item.cpp b/konqueror/sidebar/trees/dirtree_module/dirtree_item.cpp new file mode 100644 index 000000000..78132010a --- /dev/null +++ b/konqueror/sidebar/trees/dirtree_module/dirtree_item.cpp @@ -0,0 +1,245 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + Copyright (C) 2003 Waldo Bastian <[email protected]> + + 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_treepart.h" +#include "dirtree_item.h" +#include "dirtree_module.h" +#include <konq_operations.h> +#include <konq_drag.h> +#include <kdebug.h> +#include <kglobalsettings.h> +#include <kuserprofile.h> +#include <qapplication.h> +#include <qclipboard.h> +#include <kio/paste.h> +#include <qfile.h> +#include <qpainter.h> +#include <kiconloader.h> +#include <qcursor.h> + +#define MYMODULE static_cast<KonqSidebarDirTreeModule*>(module()) + +KonqSidebarDirTreeItem::KonqSidebarDirTreeItem( KonqSidebarTreeItem *parentItem, KonqSidebarTreeTopLevelItem *topLevelItem, KFileItem *fileItem ) + : KonqSidebarTreeItem( parentItem, topLevelItem ), m_fileItem( fileItem ) +{ + if ( m_topLevelItem ) + MYMODULE->addSubDir( this ); + reset(); +} + +KonqSidebarDirTreeItem::KonqSidebarDirTreeItem( KonqSidebarTree *parent, KonqSidebarTreeTopLevelItem *topLevelItem, KFileItem *fileItem ) + : KonqSidebarTreeItem( parent, topLevelItem ), m_fileItem( fileItem ) +{ + if ( m_topLevelItem ) + MYMODULE->addSubDir( this ); + reset(); +} + +KonqSidebarDirTreeItem::~KonqSidebarDirTreeItem() +{ +} + +void KonqSidebarDirTreeItem::reset() +{ + bool expandable = true; + // For local dirs, find out if they have no children, to remove the "+" + if ( m_fileItem->isDir() ) + { + KURL url = m_fileItem->url(); + if ( url.isLocalFile() ) + { + QCString path( QFile::encodeName(url.path())); + struct stat buff; + if ( ::stat( path.data(), &buff ) != -1 ) + { + //kdDebug() << "KonqSidebarDirTreeItem::init " << path << " : " << buff.st_nlink << endl; + // The link count for a directory is generally subdir_count + 2. + // One exception is if there are hard links to the directory, in this case + // the link count can be > 2 even if no subdirs exist. + // The other exception are smb (and maybe netware) mounted directories + // of which the link count is always 1. Therefore, we only set the item + // as non-expandable if it's exactly 2 (one link from the parent dir, + // plus one from the '.' entry). + if ( buff.st_nlink == 2 ) + expandable = false; + } + } + } + setExpandable( expandable ); + id = m_fileItem->url().url(-1); +} + +void KonqSidebarDirTreeItem::setOpen( bool open ) +{ + kdDebug(1201) << "KonqSidebarDirTreeItem::setOpen " << open << endl; + if ( open && !childCount() && m_bListable ) + MYMODULE->openSubFolder( this ); + else if ( hasStandardIcon() ) + { + int size = KGlobal::iconLoader()->currentSize( KIcon::Small ); + if ( open ) + setPixmap( 0, DesktopIcon( "folder_open", size ) ); + else + setPixmap( 0, m_fileItem->pixmap( size ) ); + } + KonqSidebarTreeItem::setOpen( open ); +} + +bool KonqSidebarDirTreeItem::hasStandardIcon() +{ + // The reason why we can't use KFileItem::iconName() is that it doesn't + // take custom icons in .directory files into account + return m_fileItem->determineMimeType()->icon( m_fileItem->url(), m_fileItem->isLocalFile() ) == "folder"; +} + +void KonqSidebarDirTreeItem::paintCell( QPainter *_painter, const QColorGroup & _cg, int _column, int _width, int _alignment ) +{ + if (m_fileItem->isLink()) + { + QFont f( _painter->font() ); + f.setItalic( TRUE ); + _painter->setFont( f ); + } + QListViewItem::paintCell( _painter, _cg, _column, _width, _alignment ); +} + +KURL KonqSidebarDirTreeItem::externalURL() const +{ + return m_fileItem->url(); +} + +QString KonqSidebarDirTreeItem::externalMimeType() const +{ + if (m_fileItem->isMimeTypeKnown()) + return m_fileItem->mimetype(); + else + return QString::null; +} + +bool KonqSidebarDirTreeItem::acceptsDrops( const QStrList & formats ) +{ + if ( formats.contains("text/uri-list") ) + return m_fileItem->acceptsDrops(); + return false; +} + +void KonqSidebarDirTreeItem::drop( QDropEvent * ev ) +{ + KonqOperations::doDrop( m_fileItem, externalURL(), ev, tree() ); +} + +QDragObject * KonqSidebarDirTreeItem::dragObject( QWidget * parent, bool move ) +{ + KURL::List lst; + lst.append( m_fileItem->url() ); + + KonqDrag * drag = KonqDrag::newDrag( lst, false, parent ); + drag->setMoveSelection( move ); + + return drag; +} + +void KonqSidebarDirTreeItem::itemSelected() +{ + bool bInTrash = false; + + if ( m_fileItem->url().directory(false) == KGlobalSettings::trashPath() ) + bInTrash = true; + + QMimeSource *data = QApplication::clipboard()->data(); + bool paste = ( data->encodedData( data->format() ).size() != 0 ); + + tree()->enableActions( true, true, paste, true && !bInTrash, true, true ); +} + +void KonqSidebarDirTreeItem::middleButtonClicked() +{ + // Duplicated from KonqDirPart :( + // Optimisation to avoid KRun to call kfmclient that then tells us + // to open a window :-) + KService::Ptr offer = KServiceTypeProfile::preferredService(m_fileItem->mimetype(), "Application"); + if (offer) kdDebug(1201) << "KonqDirPart::mmbClicked: got service " << offer->desktopEntryName() << endl; + if ( offer && offer->desktopEntryName().startsWith("kfmclient") ) + { + kdDebug(1201)<<"Emitting createNewWindow"<<endl; + KParts::URLArgs args; + args.serviceType = m_fileItem->mimetype(); + emit tree()->createNewWindow( m_fileItem->url(), args ); + } + else + m_fileItem->run(); +} + +void KonqSidebarDirTreeItem::rightButtonPressed() +{ + KFileItemList lstItems; + lstItems.append( m_fileItem ); + emit tree()->popupMenu( QCursor::pos(), lstItems ); +} + +void KonqSidebarDirTreeItem::paste() +{ + // move or not move ? + bool move = false; + QMimeSource *data = QApplication::clipboard()->data(); + if ( data->provides( "application/x-kde-cutselection" ) ) { + move = KonqDrag::decodeIsCutSelection( data ); + kdDebug(1201) << "move (from clipboard data) = " << move << endl; + } + + KIO::pasteClipboard( m_fileItem->url(), move ); +} + +void KonqSidebarDirTreeItem::trash() +{ + delOperation( KonqOperations::TRASH ); +} + +void KonqSidebarDirTreeItem::del() +{ + delOperation( KonqOperations::DEL ); +} + +void KonqSidebarDirTreeItem::shred() +{ + delOperation( KonqOperations::SHRED ); +} + +void KonqSidebarDirTreeItem::delOperation( int method ) +{ + KURL::List lst; + lst.append(m_fileItem->url()); + + KonqOperations::del(tree(), method, lst); +} + +QString KonqSidebarDirTreeItem::toolTipText() const +{ + return m_fileItem->url().pathOrURL(); +} + +void KonqSidebarDirTreeItem::rename() +{ + tree()->rename( this, 0 ); +} + +void KonqSidebarDirTreeItem::rename( const QString & name ) +{ + KonqOperations::rename( tree(), m_fileItem->url(), name ); +} diff --git a/konqueror/sidebar/trees/dirtree_module/dirtree_item.h b/konqueror/sidebar/trees/dirtree_module/dirtree_item.h new file mode 100644 index 000000000..fe98595e6 --- /dev/null +++ b/konqueror/sidebar/trees/dirtree_module/dirtree_item.h @@ -0,0 +1,73 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + + 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. +*/ + +#ifndef dirtree_item_h +#define dirtree_item_h + +#include "konq_sidebartreeitem.h" +#include <kurl.h> +#include <qstringlist.h> +class QDropEvent; +class KFileItem; + +class KonqSidebarDirTreeItem : public KonqSidebarTreeItem +{ +public: + KonqSidebarDirTreeItem( KonqSidebarTreeItem *parentItem, KonqSidebarTreeTopLevelItem *topLevelItem, KFileItem *fileItem ); + KonqSidebarDirTreeItem( KonqSidebarTree *parent, KonqSidebarTreeTopLevelItem *topLevelItem, KFileItem *fileItem ); + ~KonqSidebarDirTreeItem(); + + KFileItem *fileItem() const { return m_fileItem; } + + virtual void setOpen( bool open ); + + virtual void paintCell( QPainter *_painter, const QColorGroup & _cg, int _column, int _width, int _alignment ); + + virtual bool acceptsDrops( const QStrList & formats ); + virtual void drop( QDropEvent * ev ); + virtual QDragObject * dragObject( QWidget * parent, bool move = false ); + + virtual void middleButtonClicked(); + virtual void rightButtonPressed(); + + virtual void paste(); + virtual void trash(); + virtual void del(); + virtual void shred(); + virtual void rename(); // start a rename operation + void rename( const QString & name ); // do the actual renaming + + // The URL to open when this link is clicked + virtual KURL externalURL() const; + virtual QString externalMimeType() const; + virtual QString toolTipText() const; + + virtual void itemSelected(); + + void reset(); + + bool hasStandardIcon(); + + QString id; + +private: + void delOperation( int method ); + KFileItem *m_fileItem; +}; + +#endif diff --git a/konqueror/sidebar/trees/dirtree_module/dirtree_module.cpp b/konqueror/sidebar/trees/dirtree_module/dirtree_module.cpp new file mode 100644 index 000000000..725927362 --- /dev/null +++ b/konqueror/sidebar/trees/dirtree_module/dirtree_module.cpp @@ -0,0 +1,649 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + 2002 Michael Brade <[email protected]> + Copyright (C) 2003 Waldo Bastian <[email protected]> + + 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 "dirtree_module.h" +#include "dirtree_item.h" +#include <kdebug.h> +#include <kprotocolinfo.h> +#include <kdesktopfile.h> +#include <kmessagebox.h> +#include <kiconloader.h> +#include <kdirlister.h> +#include "konqsidebariface_p.h" + + +KonqSidebarDirTreeModule::KonqSidebarDirTreeModule( KonqSidebarTree * parentTree , bool showHidden) + : KonqSidebarTreeModule( parentTree, showHidden ), m_dirLister(0L), m_topLevelItem(0L) +{ + bool universalMode=false; + /* Doesn't work reliable :-( + + KonqSidebarPlugin * plugin = parentTree->part(); + // KonqSidebarPlugin::universalMode() is protected :-| + if ( plugin->parent() ) { + KonqSidebarIface * ksi = static_cast<KonqSidebarIface*>( plugin->parent()->qt_cast( "KonqSidebarIface" ) ); + universalMode = ksi ? ksi->universalMode() : false; + } */ + + KConfig * config = new KConfig( universalMode ? "konqsidebartng_kicker.rc" : "konqsidebartng.rc" ); + config->setGroup(""); + m_showArchivesAsFolders = config->readBoolEntry("ShowArchivesAsFolders",true); + delete config; +} + +KonqSidebarDirTreeModule::~KonqSidebarDirTreeModule() +{ + // KDirLister may still emit canceled while being deleted. + if (m_dirLister) + { + disconnect( m_dirLister, SIGNAL( canceled( const KURL & ) ), + this, SLOT( slotListingStopped( const KURL & ) ) ); + delete m_dirLister; + } +} + +KURL::List KonqSidebarDirTreeModule::selectedUrls() +{ + KURL::List lst; + KonqSidebarDirTreeItem *selection = static_cast<KonqSidebarDirTreeItem *>( m_pTree->selectedItem() ); + if( !selection ) + { + kdError() << "KonqSidebarDirTreeModule::selectedUrls: no selection!" << endl; + return lst; + } + lst.append(selection->fileItem()->url()); + return lst; +} + +void KonqSidebarDirTreeModule::addTopLevelItem( KonqSidebarTreeTopLevelItem * item ) +{ + if(m_topLevelItem) // We can handle only one at a time ! + kdError() << "KonqSidebarDirTreeModule::addTopLevelItem: Impossible, we can have only one toplevel item !" << endl; + + KDesktopFile cfg( item->path(), true ); + cfg.setDollarExpansion(true); + + KURL targetURL; + targetURL.setPath(item->path()); + + if ( cfg.hasLinkType() ) + { + targetURL = cfg.readURL(); + // some services might want to make their URL configurable in kcontrol + QString configured = cfg.readEntry("X-KDE-ConfiguredURL"); + if (!configured.isEmpty()) { + QStringList list = QStringList::split(':', configured); + KConfig config(list[0]); + if (list[1] != "noGroup") config.setGroup(list[1]); + QString conf_url = config.readEntry(list[2]); + if (!conf_url.isEmpty()) { + targetURL = conf_url; + } + } + } + else if ( cfg.hasDeviceType() ) + { + // Determine the mountpoint + QString mp = cfg.readEntry("MountPoint"); + if ( mp.isEmpty() ) + return; + + targetURL.setPath(mp); + } + else + return; + + bool bListable = KProtocolInfo::supportsListing( targetURL ); + //kdDebug(1201) << targetURL.prettyURL() << " listable : " << bListable << endl; + + if ( !bListable ) + { + item->setExpandable( false ); + item->setListable( false ); + } + + item->setExternalURL( targetURL ); + addSubDir( item ); + + m_topLevelItem = item; +} + +void KonqSidebarDirTreeModule::openTopLevelItem( KonqSidebarTreeTopLevelItem * item ) +{ + if ( !item->childCount() && item->isListable() ) + openSubFolder( item ); +} + +void KonqSidebarDirTreeModule::addSubDir( KonqSidebarTreeItem *item ) +{ + QString id = item->externalURL().url(-1); + kdDebug(1201) << this << " KonqSidebarDirTreeModule::addSubDir " << id << endl; + m_dictSubDirs.insert(id, item ); + + KonqSidebarDirTreeItem *ditem = dynamic_cast<KonqSidebarDirTreeItem*>(item); + if (ditem) + m_ptrdictSubDirs.insert(ditem->fileItem(), item); +} + +// Remove <key, item> from dict, taking into account that there maybe +// other items with the same key. +static void remove(QDict<KonqSidebarTreeItem> &dict, const QString &key, KonqSidebarTreeItem *item) +{ + QPtrList<KonqSidebarTreeItem> *otherItems = 0; + while(true) { + KonqSidebarTreeItem *takeItem = dict.take(key); + if (!takeItem || (takeItem == item)) + { + if (!otherItems) + return; + + // Insert the otherItems back in + for(KonqSidebarTreeItem *otherItem; (otherItem = otherItems->take(0));) + { + dict.insert(key, otherItem); + } + delete otherItems; + return; + } + // Not the item we are looking for + if (!otherItems) + otherItems = new QPtrList<KonqSidebarTreeItem>(); + + otherItems->prepend(takeItem); + } +} + +// Looks up key in dict and returns it in item, if there are multiple items +// with the same key, additional items are returned in itemList which should +// be deleted by the caller. +static void lookupItems(QDict<KonqSidebarTreeItem> &dict, const QString &key, KonqSidebarTreeItem *&item, QPtrList<KonqSidebarTreeItem> *&itemList) +{ + itemList = 0; + item = dict.take(key); + if (!item) + return; + + while(true) + { + KonqSidebarTreeItem *takeItem = dict.take(key); + if (!takeItem) + { + // + // Insert itemList back in + if (itemList) + { + for(KonqSidebarTreeItem *otherItem = itemList->first(); otherItem; otherItem = itemList->next()) + dict.insert(key, otherItem); + } + dict.insert(key, item); + return; + } + if (!itemList) + itemList = new QPtrList<KonqSidebarTreeItem>(); + + itemList->prepend(takeItem); + } +} + +// Remove <key, item> from dict, taking into account that there maybe +// other items with the same key. +static void remove(QPtrDict<KonqSidebarTreeItem> &dict, void *key, KonqSidebarTreeItem *item) +{ + QPtrList<KonqSidebarTreeItem> *otherItems = 0; + while(true) { + KonqSidebarTreeItem *takeItem = dict.take(key); + if (!takeItem || (takeItem == item)) + { + if (!otherItems) + return; + + // Insert the otherItems back in + for(KonqSidebarTreeItem *otherItem; (otherItem = otherItems->take(0));) + { + dict.insert(key, otherItem); + } + delete otherItems; + return; + } + // Not the item we are looking for + if (!otherItems) + otherItems = new QPtrList<KonqSidebarTreeItem>(); + + otherItems->prepend(takeItem); + } +} + +// Looks up key in dict and returns it in item, if there are multiple items +// with the same key, additional items are returned in itemList which should +// be deleted by the caller. +static void lookupItems(QPtrDict<KonqSidebarTreeItem> &dict, void *key, KonqSidebarTreeItem *&item, QPtrList<KonqSidebarTreeItem> *&itemList) +{ + itemList = 0; + item = dict.take(key); + if (!item) + return; + + while(true) + { + KonqSidebarTreeItem *takeItem = dict.take(key); + if (!takeItem) + { + // + // Insert itemList back in + if (itemList) + { + for(KonqSidebarTreeItem *otherItem = itemList->first(); otherItem; otherItem = itemList->next()) + dict.insert(key, otherItem); + } + dict.insert(key, item); + return; + } + if (!itemList) + itemList = new QPtrList<KonqSidebarTreeItem>(); + + itemList->prepend(takeItem); + } +} + + +void KonqSidebarDirTreeModule::removeSubDir( KonqSidebarTreeItem *item, bool childrenOnly ) +{ + kdDebug(1201) << this << " KonqSidebarDirTreeModule::removeSubDir item=" << item << endl; + if ( item->firstChild() ) + { + KonqSidebarTreeItem * it = static_cast<KonqSidebarTreeItem *>(item->firstChild()); + KonqSidebarTreeItem * next = 0L; + while ( it ) { + next = static_cast<KonqSidebarTreeItem *>(it->nextSibling()); + removeSubDir( it ); + delete it; + it = next; + } + } + + if ( !childrenOnly ) + { + QString id = item->externalURL().url(-1); + remove(m_dictSubDirs, id, item); + while (!(item->alias.isEmpty())) + { + remove(m_dictSubDirs, item->alias.front(), item); + item->alias.pop_front(); + } + + KonqSidebarDirTreeItem *ditem = dynamic_cast<KonqSidebarDirTreeItem*>(item); + if (ditem) + remove(m_ptrdictSubDirs, ditem->fileItem(), item); + } +} + + +void KonqSidebarDirTreeModule::openSubFolder( KonqSidebarTreeItem *item ) +{ + kdDebug(1201) << this << " openSubFolder( " << item->externalURL().prettyURL() << " )" << endl; + + if ( !m_dirLister ) // created on demand + { + m_dirLister = new KDirLister( true ); + //m_dirLister->setDirOnlyMode( true ); +// QStringList mimetypes; +// mimetypes<<QString("inode/directory"); +// m_dirLister->setMimeFilter(mimetypes); + + connect( m_dirLister, SIGNAL( newItems( const KFileItemList & ) ), + this, SLOT( slotNewItems( const KFileItemList & ) ) ); + connect( m_dirLister, SIGNAL( refreshItems( const KFileItemList & ) ), + this, SLOT( slotRefreshItems( const KFileItemList & ) ) ); + connect( m_dirLister, SIGNAL( deleteItem( KFileItem * ) ), + this, SLOT( slotDeleteItem( KFileItem * ) ) ); + connect( m_dirLister, SIGNAL( completed( const KURL & ) ), + this, SLOT( slotListingStopped( const KURL & ) ) ); + connect( m_dirLister, SIGNAL( canceled( const KURL & ) ), + this, SLOT( slotListingStopped( const KURL & ) ) ); + connect( m_dirLister, SIGNAL( redirection( const KURL &, const KURL & ) ), + this, SLOT( slotRedirection( const KURL &, const KURL & ) ) ); + } + + + if ( !item->isTopLevelItem() && + static_cast<KonqSidebarDirTreeItem *>(item)->hasStandardIcon() ) + { + int size = KGlobal::iconLoader()->currentSize( KIcon::Small ); + QPixmap pix = DesktopIcon( "folder_open", size ); + m_pTree->startAnimation( item, "kde", 6, &pix ); + } + else + m_pTree->startAnimation( item ); + + listDirectory( item ); +} + +void KonqSidebarDirTreeModule::listDirectory( KonqSidebarTreeItem *item ) +{ + // This causes a reparsing, but gets rid of the trailing slash + QString strUrl = item->externalURL().url(-1); + KURL url( strUrl ); + + QPtrList<KonqSidebarTreeItem> *itemList; + KonqSidebarTreeItem * openItem; + lookupItems(m_dictSubDirs, strUrl, openItem, itemList); + + while(openItem) + { + if (openItem->childCount()) + break; + + openItem = itemList ? itemList->take(0) : 0; + } + delete itemList; + + if (openItem) + { + // We have this directory listed already, just copy the entries as we + // can't use the dirlister, it would invalidate the old entries + int size = KGlobal::iconLoader()->currentSize( KIcon::Small ); + KonqSidebarTreeItem * parentItem = item; + KonqSidebarDirTreeItem *oldItem = static_cast<KonqSidebarDirTreeItem *> (openItem->firstChild()); + while(oldItem) + { + KFileItem * fileItem = oldItem->fileItem(); + if (! fileItem->isDir() ) + { + KMimeType::Ptr ptr; + + if ( fileItem->url().isLocalFile() && (((ptr=fileItem->determineMimeType())!=0) && (ptr->is("inode/directory") || m_showArchivesAsFolders) && ((!ptr->property("X-KDE-LocalProtocol").toString().isEmpty()) ))) { + kdDebug()<<"Something not really a directory"<<endl; + } else { +// kdError() << "Item " << fileItem->url().prettyURL() << " is not a directory!" << endl; + continue; + } + } + + KonqSidebarDirTreeItem *dirTreeItem = new KonqSidebarDirTreeItem( parentItem, m_topLevelItem, fileItem ); + dirTreeItem->setPixmap( 0, fileItem->pixmap( size ) ); + dirTreeItem->setText( 0, KIO::decodeFileName( fileItem->name() ) ); + + oldItem = static_cast<KonqSidebarDirTreeItem *> (oldItem->nextSibling()); + } + m_pTree->stopAnimation( item ); + + return; + } + + m_dirLister->setShowingDotFiles( showHidden()); + + if (tree()->isOpeningFirstChild()) m_dirLister->setAutoErrorHandlingEnabled(false,0); + else m_dirLister->setAutoErrorHandlingEnabled(true,tree()); + + m_dirLister->openURL( url, true /*keep*/ ); +} + +void KonqSidebarDirTreeModule::slotNewItems( const KFileItemList& entries ) +{ + kdDebug(1201) << this << " KonqSidebarDirTreeModule::slotNewItems " << entries.count() << endl; + + Q_ASSERT(entries.count()); + KFileItem * firstItem = const_cast<KFileItemList&>(entries).first(); // qlist sucks for constness + + // Find parent item - it's the same for all the items + KURL dir( firstItem->url().url(-1) ); + dir.setFileName( "" ); + kdDebug(1201) << this << " KonqSidebarDirTreeModule::slotNewItems dir=" << dir.url(-1) << endl; + + QPtrList<KonqSidebarTreeItem> *parentItemList; + KonqSidebarTreeItem * parentItem; + lookupItems(m_dictSubDirs, dir.url(-1), parentItem, parentItemList); + + if ( !parentItem ) // hack for dnssd://domain/type/service listed in dnssd:/type/ dir + { + dir.setHost( QString::null ); + lookupItems( m_dictSubDirs, dir.url(-1), parentItem, parentItemList ); + } + + if( !parentItem ) + { + KMessageBox::error( tree(), i18n("Cannot find parent item %1 in the tree. Internal error.").arg( dir.url(-1) ) ); + return; + } + + kdDebug()<<"number of additional parent items:"<< (parentItemList?parentItemList->count():0)<<endl; + int size = KGlobal::iconLoader()->currentSize( KIcon::Small ); + do + { + kdDebug()<<"Parent Item URL:"<<parentItem->externalURL()<<endl; + QPtrListIterator<KFileItem> kit ( entries ); + for( ; kit.current(); ++kit ) + { + KFileItem * fileItem = *kit; + + if (! fileItem->isDir() ) + { + KMimeType::Ptr ptr; + + if ( fileItem->url().isLocalFile() && (( (ptr=fileItem->determineMimeType())!=0) && (ptr->is("inode/directory") || m_showArchivesAsFolders) && ((!ptr->property("X-KDE-LocalProtocol").toString().isEmpty()) ))) { + kdDebug()<<"Something really a directory"<<endl; + } else { + //kdError() << "Item " << fileItem->url().prettyURL() << " is not a directory!" << endl; + continue; + } + } + + KonqSidebarDirTreeItem *dirTreeItem = new KonqSidebarDirTreeItem( parentItem, m_topLevelItem, fileItem ); + dirTreeItem->setPixmap( 0, fileItem->pixmap( size ) ); + dirTreeItem->setText( 0, KIO::decodeFileName( fileItem->name() ) ); + } + + } while ((parentItem = parentItemList ? parentItemList->take(0) : 0)); + delete parentItemList; +} + +void KonqSidebarDirTreeModule::slotRefreshItems( const KFileItemList &entries ) +{ + int size = KGlobal::iconLoader()->currentSize( KIcon::Small ); + + QPtrListIterator<KFileItem> kit ( entries ); + kdDebug(1201) << "KonqSidebarDirTreeModule::slotRefreshItems " << entries.count() << " entries. First: " << kit.current()->url().url() << endl; + for( ; kit.current(); ++kit ) + { + KFileItem *fileItem = kit.current(); + + QPtrList<KonqSidebarTreeItem> *itemList; + KonqSidebarTreeItem * item; + lookupItems(m_ptrdictSubDirs, fileItem, item, itemList); + + if (!item) + { + if ( fileItem->isDir() ) // don't warn for files + kdWarning(1201) << "KonqSidebarDirTreeModule::slotRefreshItems can't find old entry for " << kit.current()->url().url(-1) << endl; + continue; + } + + do + { + if ( item->isTopLevelItem() ) // we only have dirs and one toplevel item in the dict + { + kdWarning(1201) << "KonqSidebarDirTreeModule::slotRefreshItems entry for " << kit.current()->url().url(-1) << " matches against toplevel." << endl; + break; + } + + KonqSidebarDirTreeItem * dirTreeItem = static_cast<KonqSidebarDirTreeItem *>(item); + // Item renamed ? + if ( dirTreeItem->id != fileItem->url().url( -1 ) ) + { + // We need to update the URL in m_dictSubDirs, and to get rid of the child items, so remove and add. + // Then remove + delete + removeSubDir( dirTreeItem, true /*children only*/ ); + remove(m_dictSubDirs, dirTreeItem->id, dirTreeItem); + + dirTreeItem->reset(); // Reset id + dirTreeItem->setPixmap( 0, fileItem->pixmap( size ) ); + dirTreeItem->setText( 0, KIO::decodeFileName( fileItem->name() ) ); + + // Make sure the item doesn't get inserted twice! + // dirTreeItem->id points to the new name + remove(m_dictSubDirs, dirTreeItem->id, dirTreeItem); + m_dictSubDirs.insert(dirTreeItem->id, dirTreeItem); + } + else + { + dirTreeItem->setPixmap( 0, fileItem->pixmap( size ) ); + dirTreeItem->setText( 0, KIO::decodeFileName( fileItem->name() ) ); + } + + } while ((item = itemList ? itemList->take(0) : 0)); + delete itemList; + } +} + +void KonqSidebarDirTreeModule::slotDeleteItem( KFileItem *fileItem ) +{ + kdDebug(1201) << "KonqSidebarDirTreeModule::slotDeleteItem( " << fileItem->url().url(-1) << " )" << endl; + + // All items are in m_ptrdictSubDirs, so look it up fast + QPtrList<KonqSidebarTreeItem> *itemList; + KonqSidebarTreeItem * item; + lookupItems(m_ptrdictSubDirs, fileItem, item, itemList); + while(item) + { + removeSubDir( item ); + delete item; + + item = itemList ? itemList->take(0) : 0; + } + delete itemList; +} + +void KonqSidebarDirTreeModule::slotRedirection( const KURL & oldUrl, const KURL & newUrl ) +{ + kdDebug(1201) << "******************************KonqSidebarDirTreeModule::slotRedirection(" << newUrl.prettyURL() << ")" << endl; + + QString oldUrlStr = oldUrl.url(-1); + QString newUrlStr = newUrl.url(-1); + + QPtrList<KonqSidebarTreeItem> *itemList; + KonqSidebarTreeItem * item; + lookupItems(m_dictSubDirs, oldUrlStr, item, itemList); + + if (!item) + { + kdWarning(1201) << "NOT FOUND oldUrl=" << oldUrlStr << endl; + return; + } + + do + { + if (item->alias.contains(newUrlStr)) continue; + kdDebug()<<"Redirectiong element"<<endl; + // We need to update the URL in m_dictSubDirs + m_dictSubDirs.insert( newUrlStr, item ); + item->alias << newUrlStr; + + kdDebug(1201) << "Updating url of " << item << " to " << newUrlStr << endl; + + } while ((item = itemList ? itemList->take(0) : 0)); + delete itemList; +} + +void KonqSidebarDirTreeModule::slotListingStopped( const KURL & url ) +{ + kdDebug(1201) << "KonqSidebarDirTree::slotListingStopped " << url.url(-1) << endl; + + QPtrList<KonqSidebarTreeItem> *itemList; + KonqSidebarTreeItem * item; + lookupItems(m_dictSubDirs, url.url(-1), item, itemList); + + while(item) + { + if ( item->childCount() == 0 ) + { + item->setExpandable( false ); + item->repaint(); + } + m_pTree->stopAnimation( item ); + + item = itemList ? itemList->take(0) : 0; + } + delete itemList; + + kdDebug(1201) << "m_selectAfterOpening " << m_selectAfterOpening.prettyURL() << endl; + if ( !m_selectAfterOpening.isEmpty() && url.isParentOf( m_selectAfterOpening ) ) + { + KURL theURL( m_selectAfterOpening ); + m_selectAfterOpening = KURL(); + followURL( theURL ); + } +} + +void KonqSidebarDirTreeModule::followURL( const KURL & url ) +{ + // Check if we already know this URL + KonqSidebarTreeItem * item = m_dictSubDirs[ url.url(-1) ]; + if (item) // found it -> ensure visible, select, return. + { + m_pTree->ensureItemVisible( item ); + m_pTree->setSelected( item, true ); + return; + } + + KURL uParent( url ); + KonqSidebarTreeItem * parentItem = 0L; + // Go up to the first known parent + do + { + uParent = uParent.upURL(); + parentItem = m_dictSubDirs[ uParent.url(-1) ]; + } while ( !parentItem && !uParent.path().isEmpty() && uParent.path() != "/" ); + + // Not found !?! + if (!parentItem) + { + kdDebug() << "No parent found for url " << url.prettyURL() << endl; + return; + } + kdDebug(1202) << "Found parent " << uParent.prettyURL() << endl; + + // That's the parent directory we found. Open if not open... + if ( !parentItem->isOpen() ) + { + parentItem->setOpen( true ); + if ( parentItem->childCount() && m_dictSubDirs[ url.url(-1) ] ) + { + // Immediate opening, if the dir was already listed + followURL( url ); // equivalent to a goto-beginning-of-method + } else + { + m_selectAfterOpening = url; + kdDebug(1202) << "KonqSidebarDirTreeModule::followURL: m_selectAfterOpening=" << m_selectAfterOpening.url() << endl; + } + } +} + + +extern "C" +{ + KDE_EXPORT KonqSidebarTreeModule *create_konq_sidebartree_dirtree(KonqSidebarTree* par,const bool showHidden) + { + return new KonqSidebarDirTreeModule(par,showHidden); + } +} + + + +#include "dirtree_module.moc" diff --git a/konqueror/sidebar/trees/dirtree_module/dirtree_module.h b/konqueror/sidebar/trees/dirtree_module/dirtree_module.h new file mode 100644 index 000000000..dc46d3b9e --- /dev/null +++ b/konqueror/sidebar/trees/dirtree_module/dirtree_module.h @@ -0,0 +1,82 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure <[email protected]> + + 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. +*/ + +#ifndef dirtree_module_h +#define dirtree_module_h + +#include <konq_sidebartreemodule.h> +#include <kfileitem.h> +#include <qpixmap.h> +#include <qdict.h> +#include <qptrdict.h> + +class KDirLister; +class KonqSidebarTree; +class KonqSidebarTreeItem; +class KonqSidebarDirTreeItem; +class KonqPropsView; + +class KonqSidebarDirTreeModule : public QObject, public KonqSidebarTreeModule +{ + Q_OBJECT +public: + KonqSidebarDirTreeModule( KonqSidebarTree * parentTree, bool ); + virtual ~KonqSidebarDirTreeModule(); + + virtual void addTopLevelItem( KonqSidebarTreeTopLevelItem * item ); + + virtual void openTopLevelItem( KonqSidebarTreeTopLevelItem * item ); + + virtual void followURL( const KURL & url ); + + // Called by KonqSidebarDirTreeItem + void openSubFolder( KonqSidebarTreeItem *item ); + void addSubDir( KonqSidebarTreeItem *item ); + void removeSubDir( KonqSidebarTreeItem *item, bool childrenonly = false ); + +private slots: + void slotNewItems( const KFileItemList & ); + void slotRefreshItems( const KFileItemList & ); + void slotDeleteItem( KFileItem *item ); + void slotRedirection( const KURL & oldUrl, const KURL & newUrl ); + void slotListingStopped( const KURL & url ); + +private: + //KonqSidebarTreeItem * findDir( const KURL &_url ); + void listDirectory( KonqSidebarTreeItem *item ); + KURL::List selectedUrls(); + + // URL -> item + // Each KonqSidebarDirTreeItem is indexed on item->id() and + // all item->alias'es + QDict<KonqSidebarTreeItem> m_dictSubDirs; + + // KFileItem -> item + QPtrDict<KonqSidebarTreeItem> m_ptrdictSubDirs; + + KDirLister * m_dirLister; + + KURL m_selectAfterOpening; + + KonqSidebarTreeTopLevelItem * m_topLevelItem; + + bool m_showArchivesAsFolders; +}; + + +#endif |