summaryrefslogtreecommitdiffstats
path: root/konqueror/sidebar/trees/dirtree_module
diff options
context:
space:
mode:
Diffstat (limited to 'konqueror/sidebar/trees/dirtree_module')
-rw-r--r--konqueror/sidebar/trees/dirtree_module/Makefile.am10
-rw-r--r--konqueror/sidebar/trees/dirtree_module/dirtree_item.cpp245
-rw-r--r--konqueror/sidebar/trees/dirtree_module/dirtree_item.h73
-rw-r--r--konqueror/sidebar/trees/dirtree_module/dirtree_module.cpp649
-rw-r--r--konqueror/sidebar/trees/dirtree_module/dirtree_module.h82
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 <faure@kde.org>
+ Copyright (C) 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_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 <faure@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.
+*/
+
+#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 <faure@kde.org>
+ 2002 Michael Brade <brade@kde.org>
+ Copyright (C) 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 "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 <faure@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.
+*/
+
+#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