summaryrefslogtreecommitdiffstats
path: root/src/sidebar
diff options
context:
space:
mode:
Diffstat (limited to 'src/sidebar')
-rw-r--r--src/sidebar/CMakeLists.txt14
-rw-r--r--src/sidebar/sq_categoriesview.cpp318
-rw-r--r--src/sidebar/sq_categoriesview.h131
-rw-r--r--src/sidebar/sq_categorybrowsermenu.cpp521
-rw-r--r--src/sidebar/sq_categorybrowsermenu.h83
-rw-r--r--src/sidebar/sq_directorybasket.cpp520
-rw-r--r--src/sidebar/sq_directorybasket.h195
-rw-r--r--src/sidebar/sq_imagebasket.cpp291
-rw-r--r--src/sidebar/sq_imagebasket.h62
-rw-r--r--src/sidebar/sq_mountview.cpp247
-rw-r--r--src/sidebar/sq_mountview.h84
-rw-r--r--src/sidebar/sq_mountviewitem.cpp44
-rw-r--r--src/sidebar/sq_mountviewitem.h58
-rw-r--r--src/sidebar/sq_multibar.cpp133
-rw-r--r--src/sidebar/sq_multibar.h111
-rw-r--r--src/sidebar/sq_previewwidget.cpp364
-rw-r--r--src/sidebar/sq_previewwidget.h132
-rw-r--r--src/sidebar/sq_storagefile.cpp76
-rw-r--r--src/sidebar/sq_storagefile.h34
-rw-r--r--src/sidebar/sq_threaddirlister.cpp145
-rw-r--r--src/sidebar/sq_threaddirlister.h153
-rw-r--r--src/sidebar/sq_treeview.cpp678
-rw-r--r--src/sidebar/sq_treeview.h174
-rw-r--r--src/sidebar/sq_treeviewitem.cpp107
-rw-r--r--src/sidebar/sq_treeviewitem.h85
-rw-r--r--src/sidebar/sq_treeviewmenu.cpp196
-rw-r--r--src/sidebar/sq_treeviewmenu.h59
27 files changed, 5015 insertions, 0 deletions
diff --git a/src/sidebar/CMakeLists.txt b/src/sidebar/CMakeLists.txt
new file mode 100644
index 0000000..8e555c2
--- /dev/null
+++ b/src/sidebar/CMakeLists.txt
@@ -0,0 +1,14 @@
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+
+##### sidebar library (static)
+
+tde_add_library( sidebar STATIC_PIC AUTOMOC
+ SOURCES
+ sq_mountviewitem.cpp sq_mountview.cpp sq_imagebasket.cpp sq_directorybasket.cpp
+ sq_categorybrowsermenu.cpp sq_categoriesview.cpp sq_treeviewmenu.cpp sq_previewwidget.cpp
+ sq_storagefile.cpp sq_treeviewitem.cpp sq_threaddirlister.cpp sq_treeview.cpp sq_multibar.cpp
+)
diff --git a/src/sidebar/sq_categoriesview.cpp b/src/sidebar/sq_categoriesview.cpp
new file mode 100644
index 0000000..0508e8d
--- /dev/null
+++ b/src/sidebar/sq_categoriesview.cpp
@@ -0,0 +1,318 @@
+/***************************************************************************
+ sq_categoriesview.cpp - description
+ -------------------
+ begin : ??? June 3 2006
+ copyright : (C) 2006 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tqfile.h>
+#include <tqheader.h>
+
+#include <tdeio/job.h>
+#include <tdetoolbar.h>
+#include <kicontheme.h>
+#include <tdelocale.h>
+#include <kmimetype.h>
+#include <tdefileitem.h>
+#include <kurldrag.h>
+#include <kinputdialog.h>
+#include <kpropertiesdialog.h>
+#include <tdefiletreeviewitem.h>
+#include <tdemessagebox.h>
+
+#include "ksquirrel.h"
+#include "sq_dir.h"
+#include "sq_iconloader.h"
+#include "sq_categoriesview.h"
+#include "sq_libraryhandler.h"
+#include "sq_externaltool.h"
+#include "sq_widgetstack.h"
+#include "sq_categorybrowsermenu.h"
+#include "sq_storagefile.h"
+#include "sq_widgetstack.h"
+#include "sq_diroperator.h"
+#include "sq_treeviewmenu.h"
+
+SQ_CategoriesBox * SQ_CategoriesBox::sing = 0;
+
+/* *************************************************************************************** */
+
+SQ_CategoriesViewBranch::SQ_CategoriesViewBranch(KFileTreeView *parent, const KURL &url, const TQString &name, const TQPixmap &pix)
+ : KFileTreeBranch(parent, url, name, pix)
+{}
+
+SQ_CategoriesViewBranch::~SQ_CategoriesViewBranch()
+{}
+
+KFileTreeViewItem* SQ_CategoriesViewBranch::createTreeViewItem(KFileTreeViewItem *parent, KFileItem *fileItem)
+{
+ KFileTreeViewItem *i = KFileTreeBranch::createTreeViewItem(parent, fileItem);
+
+ /*
+ * In storage there are files with MD5 sum appended to their names.
+ * We should cut off MD5.
+ */
+ if(i)
+ {
+ TQString n = i->fileItem()->name();
+ int ind = n.findRev('.');
+
+ // OOPS
+ if(ind != -1)
+ n.truncate(ind);
+
+ i->setText(0, n);
+ }
+
+ return i;
+}
+
+/* *************************************************************************************** */
+
+SQ_CategoriesView::SQ_CategoriesView(TQWidget *parent, const char *name) : KFileTreeView(parent, name)
+{
+ setAcceptDrops(true);
+
+ m_dir = new SQ_Dir(SQ_Dir::Categories);
+
+ // create custom branch
+ root = new SQ_CategoriesViewBranch(this, m_dir->root(), i18n("Categories"),
+ SQ_IconLoader::instance()->loadIcon("bookmark", TDEIcon::Desktop, TDEIcon::SizeSmall));
+
+ addBranch(root);
+
+ header()->hide();
+ addColumn(i18n("File"));
+ setDirOnlyMode(root, false);
+ setRootIsDecorated(true);
+ setCurrentItem(root->root());
+ root->setChildRecurse(true);
+ root->setOpen(true);
+
+ menu = new SQ_TreeViewMenu(this);
+
+ connect(this, TQ_SIGNAL(spacePressed(TQListViewItem*)), this, TQ_SIGNAL(executed(TQListViewItem*)));
+ connect(this, TQ_SIGNAL(returnPressed(TQListViewItem*)), this, TQ_SIGNAL(executed(TQListViewItem*)));
+ connect(this, TQ_SIGNAL(executed(TQListViewItem*)), this, TQ_SLOT(slotItemExecuted(TQListViewItem*)));
+ connect(this, TQ_SIGNAL(contextMenu(TDEListView*, TQListViewItem*, const TQPoint&)), this, TQ_SLOT(slotContextMenu(TDEListView*, TQListViewItem*, const TQPoint&)));
+}
+
+SQ_CategoriesView::~SQ_CategoriesView()
+{
+ delete m_dir;
+}
+
+void SQ_CategoriesView::slotContextMenu(TDEListView *, TQListViewItem *item, const TQPoint &p)
+{
+ if(item)
+ {
+ KFileTreeViewItem *kfi = static_cast<KFileTreeViewItem*>(item);
+ menu->updateDirActions(kfi->isDir(), (item == root->root()));
+ menu->setURL(kfi->url());
+ menu->exec(p);
+ }
+}
+
+void SQ_CategoriesView::slotItemExecuted(TQListViewItem *item)
+{
+ if(!item) return;
+
+ if(item == root->root())
+ {
+ root->setOpen(true);
+ return;
+ }
+
+ KFileTreeViewItem *cur = static_cast<KFileTreeViewItem *>(item);
+
+ // file item
+ if(cur && !cur->isDir())
+ {
+ KURL inpath = SQ_StorageFile::readStorageFile(cur->path());
+
+ KFileItem fi(KFileItem::Unknown, KFileItem::Unknown, inpath);
+ SQ_WidgetStack::instance()->diroperator()->execute(&fi);
+ }
+}
+
+/* ************************************************************** */
+
+SQ_CategoriesBox::SQ_CategoriesBox(TQWidget *parent, const char *name) : TQVBox(parent, name)
+{
+ sing = this;
+
+ lastdir = i18n("New Category");
+
+ view = new SQ_CategoriesView(this);
+ toolbar = new TDEToolBar(this);
+
+ connect(view, TQ_SIGNAL(dropped(TQDropEvent*, TQListViewItem*, TQListViewItem*)), this, TQ_SLOT(slotDropped(TQDropEvent*, TQListViewItem*, TQListViewItem*)));
+
+ menu = new SQ_CategoryBrowserMenu(view->dir()->root(), 0, "Categories menu");
+
+ toolbar->setIconSize(TDEIcon::SizeSmall);
+
+ toolbar->insertButton("folder-new", 0, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotNewCategory()), true, i18n("New category"));
+ toolbar->insertButton("edittrash", 0, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotDeleteItem()), true, i18n("Delete"));
+ toolbar->insertButton("application-vnd.tde.info", 0, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotItemProperties()), true, i18n("Properties"));
+ toolbar->insertButton("bookmark_add", 0, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotDefaultCategories()), true, i18n("Create default categories"));
+
+ view->popupMenu()->reconnect(SQ_TreeViewMenu::New, this, TQ_SLOT(slotNewCategory()));
+ view->popupMenu()->reconnect(SQ_TreeViewMenu::Delete, this, TQ_SLOT(slotDeleteItem()));
+ view->popupMenu()->reconnect(SQ_TreeViewMenu::Properties, this, TQ_SLOT(slotItemProperties()));
+}
+
+SQ_CategoriesBox::~SQ_CategoriesBox()
+{}
+
+void SQ_CategoriesBox::addToCategory(const TQString &path)
+{
+ KFileItemList *selected = const_cast<KFileItemList *>(SQ_WidgetStack::instance()->selectedItems());
+
+ if(!selected) return;
+
+ KFileItem *item;
+
+ item = selected->first();
+
+ while(item)
+ {
+ if(item->isFile())
+ SQ_StorageFile::writeStorageFile(path + TQDir::separator() + item->name(), item->url().path());
+
+ item = selected->next();
+ }
+}
+
+void SQ_CategoriesBox::slotDefaultCategories()
+{
+ if(KMessageBox::questionYesNo(KSquirrel::app(),
+ i18n("This will create default categories: Concerts, Pets, Home, Friends, Free time, Travelling and Nature. Continue?"),
+ i18n("Create default categories")) == KMessageBox::Yes)
+ {
+ TQStringList list;
+
+ list << "Concerts" << "Pets" << "Home" << "Friends" << "Free time" << "Traveling" << "Nature";
+
+ for(TQStringList::iterator it = list.begin();it != list.end();++it)
+ view->dir()->mkdir(*it);
+ }
+}
+
+void SQ_CategoriesBox::slotNewCategory()
+{
+ bool ok;
+
+ KFileTreeViewItem *cur = view->currentKFileTreeViewItem();
+
+ if(!cur) return;
+
+ if(!cur->isDir())
+ cur = static_cast<KFileTreeViewItem *>(cur->parent());
+
+ if(!cur) return;
+
+ TQString tmp = KInputDialog::getText(i18n("New Category"), i18n("Create new category:"),
+ lastdir, &ok, this);
+ if(ok)
+ {
+ lastdir = tmp;
+ TDEIO::mkdir(cur->path() + TQDir::separator() + lastdir);
+ }
+}
+
+void SQ_CategoriesBox::slotDropped(TQDropEvent *e, TQListViewItem *parent, TQListViewItem *item)
+{
+ if(!item) item = parent;
+
+ KFileTreeViewItem *cur = static_cast<KFileTreeViewItem *>(item);
+
+ if(!cur) return;
+
+ KURL::List list;
+ KURLDrag::decode(e, list);
+ TQString path = cur->path();
+
+ if(list.first().path().startsWith(view->dir()->root()))
+ TDEIO::move(list, cur->url());
+ else
+ {
+ KURL::List::iterator itEnd = list.end();
+ TQString mimeDet;
+
+ for(KURL::List::iterator it = list.begin(); it != itEnd;++it)
+ {
+ mimeDet = KMimeType::findByURL(*it)->name();
+
+ if(mimeDet != "inode/directory")
+ SQ_StorageFile::writeStorageFile(path + TQDir::separator() + (*it).fileName(), (*it));
+ }
+ }
+}
+
+void SQ_CategoriesBox::slotDeleteItem()
+{
+ KFileTreeViewItem *cur = view->currentKFileTreeViewItem();
+
+ if(!cur) return;
+
+ KURL root;
+ root.setPath(view->dir()->root());
+
+ if(cur->url().equals(root, true))
+ return;
+
+ TQListViewItem *next = cur->itemBelow();
+ if(!next) next = cur->itemAbove();
+
+ if(next)
+ {
+ view->setCurrentItem(next);
+ view->setSelected(next, true);
+ }
+
+ TQString tmp = cur->path();
+
+ // remove this item manually
+ delete cur;
+ cur = 0;
+
+ // physically remove file from storage
+ TDEIO::del(tmp, false, false);
+}
+
+void SQ_CategoriesBox::slotItemProperties()
+{
+ KFileTreeViewItem *cur = view->currentKFileTreeViewItem();
+
+ if(!cur) return;
+
+ // directory - just show its properties
+ if(cur->isDir())
+ (void)new KPropertiesDialog(cur->url(), KSquirrel::app());
+
+ // link to real file
+ else
+ {
+ KURL inpath = SQ_StorageFile::readStorageFile(cur->path());
+
+ if(!inpath.isEmpty())
+ (void)new KPropertiesDialog(inpath, KSquirrel::app());
+ }
+}
+
+#include "sq_categoriesview.moc"
diff --git a/src/sidebar/sq_categoriesview.h b/src/sidebar/sq_categoriesview.h
new file mode 100644
index 0000000..4fba48a
--- /dev/null
+++ b/src/sidebar/sq_categoriesview.h
@@ -0,0 +1,131 @@
+/***************************************************************************
+ sq_categoriesview.h - description
+ -------------------
+ begin : ??? June 3 2006
+ copyright : (C) 2006 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SQ_CATEGORIESVIEW_H
+#define SQ_CATEGORIESVIEW_H
+
+#include <tqvbox.h>
+
+#include <tdefiletreeview.h>
+#include <tdefiletreebranch.h>
+
+class TDEToolBar;
+
+class SQ_CategoryBrowserMenu;
+class SQ_TreeViewMenu;
+class SQ_Dir;
+
+/**
+ *@author Baryshev Dmitry
+ */
+
+/* *************************************************** */
+
+class SQ_CategoriesViewBranch : public KFileTreeBranch
+{
+ public:
+ SQ_CategoriesViewBranch(KFileTreeView*, const KURL &url, const TQString &name, const TQPixmap &pix);
+ ~SQ_CategoriesViewBranch();
+
+ protected:
+ virtual KFileTreeViewItem *createTreeViewItem(KFileTreeViewItem *parent, KFileItem *fileItem);
+};
+
+/* *************************************************** */
+
+class SQ_CategoriesView : public KFileTreeView
+{
+ TQ_OBJECT
+
+
+ public:
+ SQ_CategoriesView(TQWidget *parent = 0, const char *name = 0);
+ ~SQ_CategoriesView();
+
+ SQ_TreeViewMenu *popupMenu() const;
+
+ SQ_Dir* dir();
+
+ private slots:
+ void slotItemExecuted(TQListViewItem *item);
+ void slotContextMenu(TDEListView *, TQListViewItem *i, const TQPoint &p);
+
+ private:
+ KFileTreeBranch *root;
+ SQ_TreeViewMenu *menu;
+
+ SQ_Dir *m_dir;
+};
+
+inline
+SQ_TreeViewMenu* SQ_CategoriesView::popupMenu() const
+{
+ return menu;
+}
+
+inline
+SQ_Dir* SQ_CategoriesView::dir()
+{
+ return m_dir;
+}
+
+/* *************************************************** */
+
+class SQ_CategoriesBox : public TQVBox
+{
+ TQ_OBJECT
+
+
+ public:
+ SQ_CategoriesBox(TQWidget *parent = 0, const char *name = 0);
+ ~SQ_CategoriesBox();
+
+ /*
+ * Get current popup menu.
+ */
+ SQ_CategoryBrowserMenu* popupMenu() const;
+
+ /*
+ * Add selected files to some category
+ */
+ void addToCategory(const TQString &);
+
+ static SQ_CategoriesBox* instance() { return sing; };
+
+ private slots:
+ void slotNewCategory();
+ void slotDefaultCategories();
+ void slotDeleteItem();
+ void slotItemProperties();
+ void slotDropped(TQDropEvent *, TQListViewItem *, TQListViewItem *);
+
+ private:
+ SQ_CategoriesView *view;
+ TDEToolBar *toolbar;
+ TQString lastdir, copypath;
+ SQ_CategoryBrowserMenu *menu;
+
+ static SQ_CategoriesBox *sing;
+};
+
+inline
+SQ_CategoryBrowserMenu* SQ_CategoriesBox::popupMenu() const
+{
+ return menu;
+}
+
+#endif
diff --git a/src/sidebar/sq_categorybrowsermenu.cpp b/src/sidebar/sq_categorybrowsermenu.cpp
new file mode 100644
index 0000000..9b74c1d
--- /dev/null
+++ b/src/sidebar/sq_categorybrowsermenu.cpp
@@ -0,0 +1,521 @@
+/*
+ * Copyright (C) 2006 Baryshev Dmitry, KSquirrel project
+ *
+ * Originally based on browser_mnu.cpp by (C) Matthias Elter
+ * from kde-3.2.3
+ */
+
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tqpixmap.h>
+#include <tqdir.h>
+
+#include <tdeglobal.h>
+#include <tdeconfig.h>
+#include <tdelocale.h>
+#include <tdeapplication.h>
+#include <tdeprocess.h>
+#include <kiconloader.h>
+#include <tdesimpleconfig.h>
+#include <tdedesktopfile.h>
+#include <kmimetype.h>
+#include <tdeglobalsettings.h>
+#include <tdeio/global.h>
+#include <krun.h>
+#include <konq_operations.h>
+#include <tdefileitem.h>
+#include <kdirwatch.h>
+#include <kstringhandler.h>
+#include <kurldrag.h>
+
+#include "sq_dir.h"
+#include "sq_categoriesview.h"
+#include "sq_categorybrowsermenu.h"
+
+#define CICON(a) (*_icons)[a]
+
+TQMap<TQString, TQPixmap> *SQ_CategoryBrowserMenu::_icons = 0;
+
+SQ_CategoryBrowserMenu::SQ_CategoryBrowserMenu(TQString path, TQWidget *parent, const char *name, int startid)
+ : KPanelMenu(path, parent, name)
+ , _mimecheckTimer(0)
+ , _startid(startid)
+ , _dirty(false)
+{
+ _subMenus.setAutoDelete(true);
+ _lastpress = TQPoint(-1, -1);
+ setAcceptDrops(true); // Should depend on permissions of path.
+
+ // we are not interested for dirty events on files inside the
+ // directory (see slotClearIfNeeded)
+ connect( &_dirWatch, TQ_SIGNAL(dirty(const TQString&)),
+ this, TQ_SLOT(slotClearIfNeeded(const TQString&)) );
+ connect( &_dirWatch, TQ_SIGNAL(created(const TQString&)),
+ this, TQ_SLOT(slotClear()) );
+ connect( &_dirWatch, TQ_SIGNAL(deleted(const TQString&)),
+ this, TQ_SLOT(slotClear()) );
+}
+
+SQ_CategoryBrowserMenu::~SQ_CategoryBrowserMenu()
+{}
+
+void SQ_CategoryBrowserMenu::slotClearIfNeeded(const TQString& p)
+{
+ if (p == path())
+ slotClear();
+}
+
+
+void SQ_CategoryBrowserMenu::initialize()
+{
+ _lastpress = TQPoint(-1, -1);
+
+ // don't change menu if already visible
+ if (isVisible())
+ return;
+
+ if (_dirty) {
+ // directory content changed while menu was visible
+ slotClear();
+ setInitialized(false);
+ _dirty = false;
+ }
+
+ if (initialized()) return;
+ setInitialized(true);
+
+ // start watching if not already done
+ if (!_dirWatch.contains(path()))
+ _dirWatch.addDir( path() );
+
+ // setup icon map
+ initIconMap();
+
+ // read configuration
+ TDEConfig *c = TDEGlobal::config();
+ c->setGroup("menus");
+ _showhidden = c->readBoolEntry("ShowHiddenFiles", false);
+ _maxentries = c->readNumEntry("MaxEntries2", 30);
+
+ // clear maps
+ _filemap.clear();
+ _mimemap.clear();
+
+ int filter = TQDir::Dirs | TQDir::Files;
+ if(_showhidden)
+ filter |= TQDir::Hidden;
+
+ TQDir dir(path(), TQString(), TQDir::DirsFirst | TQDir::Name | TQDir::IgnoreCase, filter);
+
+ // does the directory exist?
+ if (!dir.exists()) {
+ insertItem(i18n("Failed to Read Folder"));
+ return;
+ }
+
+ // get entry list
+ const TQFileInfoList *list = dir.entryInfoList();
+
+ // no list -> read error
+ if (!list) {
+ insertItem(i18n("Failed to Read Folder"));
+ return;
+ }
+
+ KURL url;
+ url.setPath(path());
+ if (!tdeApp->authorizeURLAction("list", KURL(), url))
+ {
+ insertItem(i18n("Not Authorized to Read Folder"));
+ return;
+ }
+
+ // insert file manager and terminal entries
+ // only the first part menu got them
+ if(_startid == 0)
+ {
+ SQ_Dir dir(SQ_Dir::Categories);
+
+ if(dir.root() != path())
+ {
+ insertTitle(path().right(path().length() - dir.root().length()));
+ insertItem(CICON("bookmark_add"), i18n("Add here"), this, TQ_SLOT(slotAddToCategory()));
+ }
+ }
+
+ bool first_entry = true;
+ bool dirfile_separator = false;
+ int item_count = 0;
+ int run_id = _startid;
+
+ // get list iterator
+ TQFileInfoListIterator it(*list);
+
+ // jump to startid
+ it += _startid;
+
+ // iterate over entry list
+ for (; it.current(); ++it)
+ {
+ // bump id
+ run_id++;
+
+ TQFileInfo *fi = it.current();
+ // handle directories
+ if (fi->isDir())
+ {
+ TQString name = fi->fileName();
+
+ // ignore . and .. entries
+ if (name == "." || name == "..") continue;
+
+ TQPixmap icon;
+ TQString path = fi->absFilePath();
+
+ // parse .directory if it does exist
+ if (TQFile::exists(path + "/.directory")) {
+
+ TDESimpleConfig c(path + "/.directory", true);
+ c.setDesktopGroup();
+ icon = TDEGlobal::iconLoader()->loadIcon(c.readEntry("Icon"),
+ TDEIcon::Small, TDEIcon::SizeSmall,
+ TDEIcon::DefaultState, 0, true);
+ if(icon.isNull())
+ icon = CICON("folder");
+ name = c.readEntry("Name", name);
+ }
+
+ // use cached folder icon for directories without special icon
+ if (icon.isNull())
+ icon = CICON("folder");
+
+ // insert separator if we are the first menu entry
+ if(first_entry) {
+ if (_startid == 0)
+ insertSeparator();
+ first_entry = false;
+ }
+
+ // append menu entry
+ append(icon, KStringHandler::cEmSqueeze( name, fontMetrics(), 20 ),
+ new SQ_CategoryBrowserMenu(path, this));
+
+ // bump item count
+ item_count++;
+
+ dirfile_separator = true;
+ }
+/*
+ // handle files
+ else if(fi->isFile())
+ {
+ TQString name = fi->fileName();
+ TQString title = TDEIO::decodeFileName(name);
+
+ // ignore .directory and .order files
+ if (name == ".directory" || name == ".order") continue;
+
+ TQPixmap icon;
+ TQString path = fi->absFilePath();
+
+ bool mimecheck = false;
+
+ // .desktop files
+ if(TDEDesktopFile::isDesktopFile(path))
+ {
+ TDESimpleConfig c(path, true);
+ c.setDesktopGroup();
+ title = c.readEntry("Name", title);
+
+ TQString s = c.readEntry("Icon");
+ if(!_icons->contains(s)) {
+ icon = TDEGlobal::iconLoader()->loadIcon(s, TDEIcon::Small, TDEIcon::SizeSmall,
+ TDEIcon::DefaultState, 0, true);
+
+ if(icon.isNull()) {
+ TQString type = c.readEntry("Type", "Application");
+ if (type == "Directory")
+ icon = CICON("folder");
+ else if (type == "Mimetype")
+ icon = CICON("txt");
+ else if (type == "FSDevice")
+ icon = CICON("chardevice");
+ else
+ icon = CICON("exec");
+ }
+ else
+ _icons->insert(s, icon);
+ }
+ else
+ icon = CICON(s);
+ }
+ else {
+ // set unknown icon
+ icon = CICON("unknown");
+
+ // mark for delayed mimetime check
+ mimecheck = true;
+ }
+
+ // insert separator if we are the first menu entry
+ if(first_entry) {
+ if(_startid == 0)
+ insertSeparator();
+ first_entry = false;
+ }
+
+ // insert separator if we we first file after at least one directory
+ if (dirfile_separator) {
+ insertSeparator();
+ dirfile_separator = false;
+ }
+
+ // append file entry
+ append(icon, title, name, mimecheck);
+
+ // bump item count
+ item_count++;
+ }
+*/
+ if(item_count == _maxentries) {
+ // Only insert a "More..." item if there are actually more items.
+ ++it;
+ if( it.current() ) {
+ insertSeparator();
+ append(CICON("folder_open"), i18n("More..."), new SQ_CategoryBrowserMenu(path(), this, 0, run_id));
+ }
+ break;
+ }
+ }
+
+#if 0
+ // WABA: tear off handles don't work together with dynamically updated
+ // menus. We can't update the menu while torn off, and we don't know
+ // when it is torn off.
+ if(TDEGlobalSettings::insertTearOffHandle() && item_count > 0)
+ insertTearOffHandle();
+#endif
+
+ adjustSize();
+
+ TQString dirname = path();
+
+ int maxlen = contentsRect().width() - 40;
+ if(item_count == 0)
+ maxlen = fontMetrics().width(dirname);
+
+ if (fontMetrics().width(dirname) > maxlen) {
+ while ((!dirname.isEmpty()) && (fontMetrics().width(dirname) > (maxlen - fontMetrics().width("..."))))
+ dirname = dirname.remove(0, 1);
+ dirname.prepend("...");
+ }
+ setCaption(dirname);
+
+ // setup and start delayed mimetype check timer
+ if(_mimemap.count() > 0) {
+
+ if(!_mimecheckTimer)
+ _mimecheckTimer = new TQTimer(this);
+
+ connect(_mimecheckTimer, TQ_SIGNAL(timeout()), TQ_SLOT(slotMimeCheck()));
+ _mimecheckTimer->start(0);
+ }
+}
+
+void SQ_CategoryBrowserMenu::append(const TQPixmap &pixmap, const TQString &title, const TQString &file, bool mimecheck)
+{
+ // avoid &'s being converted to accelerators
+ TQString newTitle = title;
+ newTitle.replace("&", "&&");
+ newTitle = KStringHandler::cEmSqueeze( newTitle, fontMetrics(), 20 );
+
+ // insert menu item
+ int id = insertItem(pixmap, newTitle);
+
+ // insert into file map
+ _filemap.insert(id, file);
+
+ // insert into mimetype check map
+ if(mimecheck)
+ _mimemap.insert(id, true);
+}
+
+void SQ_CategoryBrowserMenu::append(const TQPixmap &pixmap, const TQString &title, SQ_CategoryBrowserMenu *subMenu)
+{
+ // avoid &'s being converted to accelerators
+ TQString newTitle = title;
+ newTitle.replace("&", "&&");
+ newTitle = KStringHandler::cEmSqueeze( newTitle, fontMetrics(), 20 );
+
+ // insert submenu
+ insertItem(pixmap, newTitle, subMenu);
+ // remember submenu for later deletion
+ _subMenus.append(subMenu);
+}
+
+void SQ_CategoryBrowserMenu::mousePressEvent(TQMouseEvent *e)
+{
+ TQPopupMenu::mousePressEvent(e);
+ _lastpress = e->pos();
+}
+
+void SQ_CategoryBrowserMenu::mouseMoveEvent(TQMouseEvent *e)
+{
+ TQPopupMenu::mouseMoveEvent(e);
+
+ if (!(e->state() & TQt::LeftButton)) return;
+ if(_lastpress == TQPoint(-1, -1)) return;
+
+ // DND delay
+ if((_lastpress - e->pos()).manhattanLength() < 12) return;
+
+ // get id
+ int id = idAt(_lastpress);
+ if(!_filemap.contains(id)) return;
+
+ // reset _lastpress
+ _lastpress = TQPoint(-1, -1);
+
+ // start drag
+ KURL url;
+ url.setPath(path() + '/' + _filemap[id]);
+ KURL::List files(url);
+ KURLDrag *d = new KURLDrag(files, this);
+ d->setPixmap(iconSet(id)->pixmap());
+ d->drag();
+}
+
+void SQ_CategoryBrowserMenu::dragEnterEvent( TQDragEnterEvent *ev )
+{
+ if (KURLDrag::canDecode(ev))
+ ev->accept(rect());
+ KPanelMenu::dragEnterEvent(ev);
+}
+
+void SQ_CategoryBrowserMenu::dropEvent( TQDropEvent *ev )
+{
+ KFileItem item( path(), TQString::fromLatin1( "inode/directory" ), KFileItem::Unknown );
+ KonqOperations::doDrop( &item, path(), ev, this );
+ KPanelMenu::dropEvent(ev);
+ // ### TODO: Update list
+}
+
+void SQ_CategoryBrowserMenu::slotExec(int id)
+{
+ tdeApp->propagateSessionManager();
+
+ if(!_filemap.contains(id)) return;
+
+ KURL url;
+ url.setPath(path() + '/' + _filemap[id]);
+ new KRun(url, 0, true); // will delete itself
+ _lastpress = TQPoint(-1, -1);
+}
+
+void SQ_CategoryBrowserMenu::slotAddToCategory()
+{
+ SQ_CategoriesBox::instance()->addToCategory(path());
+}
+
+void SQ_CategoryBrowserMenu::slotMimeCheck()
+{
+ // get the first map entry
+ TQMap<int, bool>::Iterator it = _mimemap.begin();
+
+ // no mime types left to check -> stop timer
+ if(it == _mimemap.end()) {
+ _mimecheckTimer->stop();
+ return;
+ }
+
+ int id = it.key();
+ TQString file = _filemap[id];
+
+ _mimemap.remove(it);
+
+ KURL url;
+ url.setPath( path() + '/' + file );
+
+// KMimeType::Ptr mt = KMimeType::findByURL(url, 0, true, false);
+// TQString icon(mt->icon(url, true));
+ TQString icon = KMimeType::iconForURL( url );
+// kdDebug() << url.url() << ": " << icon << endl;
+
+ file = KStringHandler::cEmSqueeze( file, fontMetrics(), 20 );
+
+ file.replace("&", "&&");
+ if(!_icons->contains(icon)) {
+ TQPixmap pm = SmallIcon(icon);
+ if( pm.height() > 16 )
+ {
+ TQPixmap cropped( 16, 16 );
+ copyBlt( &cropped, 0, 0, &pm, 0, 0, 16, 16 );
+ pm = cropped;
+ }
+ _icons->insert(icon, pm);
+ changeItem(id, pm, file);
+ }
+ else
+ changeItem(id, CICON(icon), file);
+}
+
+void SQ_CategoryBrowserMenu::slotClear()
+{
+ // no need to watch any further
+ if (_dirWatch.contains(path()))
+ _dirWatch.removeDir( path() );
+
+ // don't change menu if already visible
+ if (isVisible()) {
+ _dirty = true;
+ return;
+ }
+ KPanelMenu::slotClear();
+ _subMenus.clear(); // deletes submenus
+}
+
+void SQ_CategoryBrowserMenu::initIconMap()
+{
+ if(_icons) return;
+
+// kdDebug() << "SQ_CategoryBrowserMenu::initIconMap" << endl;
+
+ _icons = new TQMap<TQString, TQPixmap>;
+
+ _icons->insert("folder", SmallIcon("folder"));
+ _icons->insert("unknown", SmallIcon("unknown"));
+ _icons->insert("folder_open", SmallIcon("folder_open"));
+ _icons->insert("kdisknav", SmallIcon("kdisknav"));
+ _icons->insert("kfm", SmallIcon("kfm"));
+ _icons->insert("terminal", SmallIcon("terminal"));
+ _icons->insert("txt", SmallIcon("text-plain"));
+ _icons->insert("exec", SmallIcon("application-x-executable"));
+ _icons->insert("chardevice", SmallIcon("chardevice"));
+}
+
+#include "sq_categorybrowsermenu.moc"
diff --git a/src/sidebar/sq_categorybrowsermenu.h b/src/sidebar/sq_categorybrowsermenu.h
new file mode 100644
index 0000000..c2e0b77
--- /dev/null
+++ b/src/sidebar/sq_categorybrowsermenu.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2006 Baryshev Dmitry, KSquirrel project
+ *
+ * Originally based on browser_mnu.h by (C) Matthias Elter
+ * from kde-3.2.3
+ */
+
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __browser_mnu_h__
+#define __browser_mnu_h__
+
+#include <tqmap.h>
+#include <tqptrlist.h>
+#include <kpanelmenu.h>
+#include <kdirwatch.h>
+
+class SQ_CategoryBrowserMenu : public KPanelMenu
+{
+ TQ_OBJECT
+
+
+ public:
+ SQ_CategoryBrowserMenu(TQString path, TQWidget *parent = 0, const char *name = 0, int startid = 0);
+ ~SQ_CategoryBrowserMenu();
+
+ void append(const TQPixmap &pixmap, const TQString &title, const TQString &filename, bool mimecheck);
+ void append(const TQPixmap &pixmap, const TQString &title, SQ_CategoryBrowserMenu *subMenu);
+
+ public slots:
+ void initialize();
+
+ protected slots:
+ void slotExec(int id);
+ void slotAddToCategory();
+ void slotMimeCheck();
+ void slotClearIfNeeded(const TQString&);
+ void slotClear();
+
+ protected:
+ void mousePressEvent(TQMouseEvent *);
+ void mouseMoveEvent(TQMouseEvent *);
+ void dropEvent(TQDropEvent *ev);
+ void dragEnterEvent(TQDragEnterEvent *ev);
+ void initIconMap();
+
+ TQPoint _lastpress;
+ TQMap<int, TQString> _filemap;
+ TQMap<int, bool> _mimemap;
+ TQTimer *_mimecheckTimer;
+ KDirWatch _dirWatch;
+ TQPtrList<SQ_CategoryBrowserMenu> _subMenus;
+
+ int _startid;
+ bool _showhidden;
+ int _maxentries;
+ bool _dirty;
+
+ static TQMap<TQString, TQPixmap> *_icons;
+};
+
+#endif
diff --git a/src/sidebar/sq_directorybasket.cpp b/src/sidebar/sq_directorybasket.cpp
new file mode 100644
index 0000000..74ba7e2
--- /dev/null
+++ b/src/sidebar/sq_directorybasket.cpp
@@ -0,0 +1,520 @@
+/***************************************************************************
+ sq_directorybasket.cpp - description
+ -------------------
+ begin : ??? Sep 29 2007
+ copyright : (C) 2007 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <tqvaluevector.h>
+#include <tqstringlist.h>
+#include <tqheader.h>
+#include <tqcursor.h>
+#include <tqtimer.h>
+
+#include <tdeglobal.h>
+#include <tdelocale.h>
+#include <kurldrag.h>
+#include <kmimetype.h>
+#include <tdefiledialog.h>
+#include <kinputdialog.h>
+#include <kicondialog.h>
+#include <kiconloader.h>
+#include <tdeio/netaccess.h>
+#include <tdeio/job.h>
+#include <kprogress.h>
+#include <tdeglobalsettings.h>
+
+#include "ksquirrel.h"
+#include "sq_directorybasket.h"
+#include "sq_storagefile.h"
+#include "sq_iconloader.h"
+#include "sq_treeviewmenu.h"
+#include "sq_widgetstack.h"
+#include "sq_diroperator.h"
+#include "sq_navigatordropmenu.h"
+#include "sq_dir.h"
+
+SQ_DirectoryBasket * SQ_DirectoryBasket::m_inst = 0;
+
+/* ******************************************************************************* */
+
+SQ_DBMenu::SQ_DBMenu(TQWidget *parent, const char *name) : SQ_TreeViewMenu(parent, name), item(0)
+{
+ insertSeparator();
+ id_icon = insertItem(i18n("Change icon"), this, TQ_SLOT(slotChangeIcon()));
+}
+
+SQ_DBMenu::~SQ_DBMenu()
+{}
+
+void SQ_DBMenu::slotChangeIcon()
+{
+ TDEIconDialog dialog(TDEGlobal::iconLoader());
+ dialog.setup(TDEIcon::Desktop, TDEIcon::MimeType, true, TDEIcon::SizeSmall);
+ TQString result = dialog.openDialog();
+
+ if(!result.isEmpty() && item)
+ {
+ item->setIcon(result);
+ item->setPixmap(0, SQ_IconLoader::instance()->loadIcon(result, TDEIcon::Desktop, TDEIcon::SizeSmall));
+ }
+}
+
+void SQ_DBMenu::updateDirActions(bool, bool isroot)
+{
+ setItemEnabled(id_new, isroot);
+ setItemEnabled(id_clear, isroot);
+ setItemEnabled(id_prop, !isroot);
+
+ setItemEnabled(id_delete, !isroot);
+ setItemEnabled(id_rename, !isroot);
+ setItemEnabled(id_icon, !isroot);
+}
+
+void SQ_DBMenu::slotDirectoryRename()
+{
+ if(item)
+ {
+ TQString renameSrc = item->text(0);
+ bool ok;
+
+ TQString mNewFilename = KInputDialog::getText(i18n("Rename Folder"),
+ i18n("<p>Rename item <b>%1</b> to:</p>").arg(renameSrc),
+ renameSrc, &ok, KSquirrel::app());
+
+ if(ok)
+ {
+ item->setName(mNewFilename);
+ item->setText(0, mNewFilename);
+ }
+ }
+}
+
+void SQ_DBMenu::slotDirectoryResult(TDEIO::Job *job)
+{
+ if(job && job->error())
+ job->showErrorDialog(KSquirrel::app());
+}
+
+void SQ_DBMenu::slotDirectoryDelete()
+{
+ if(item)
+ {
+ TDEIO::Job *job = TDEIO::del(item->KFileTreeViewItem::url());
+
+ connect(job, TQ_SIGNAL(result(TDEIO::Job*)), this, TQ_SLOT(slotDirectoryResult(TDEIO::Job *)));
+ }
+}
+
+/* ******************************************************************************* */
+
+SQ_DirectoryItem::SQ_DirectoryItem(KFileTreeViewItem *parentItem, KFileItem *fileItem, KFileTreeBranch *parentBranch)
+ : KFileTreeViewItem(parentItem, fileItem, parentBranch), m_index(0)
+{}
+
+SQ_DirectoryItem::SQ_DirectoryItem(KFileTreeView *parent, KFileItem *fileItem, KFileTreeBranch *parentBranch)
+ : KFileTreeViewItem(parent, fileItem, parentBranch), m_index(0)
+{}
+
+SQ_DirectoryItem::~SQ_DirectoryItem()
+{}
+
+/* ******************************************************************************* */
+
+SQ_DirectoryBasketBranch::SQ_DirectoryBasketBranch(KFileTreeView *parent, const KURL &url, const TQString &name, const TQPixmap &pix)
+ : KFileTreeBranch(parent, url, name, pix)
+{}
+
+SQ_DirectoryBasketBranch::~SQ_DirectoryBasketBranch()
+{}
+
+KFileTreeViewItem* SQ_DirectoryBasketBranch::createTreeViewItem(KFileTreeViewItem *parent, KFileItem *fileItem)
+{
+ if(!parent || !fileItem)
+ return 0;
+
+ // hehe...
+ fileItem->setMimeType("inode/directory");
+
+ SQ_DirectoryItem *i = new SQ_DirectoryItem(parent, fileItem, this);
+
+ if(i)
+ {
+ // inpath = "<URL><name><index>"
+ TQStringList list = TQStringList::split(TQChar('\n'), SQ_StorageFile::readStorageFileAsString(i->path()), true);
+
+ if(list.count() < 4)
+ return i;
+
+ TQStringList::iterator it = list.begin();
+
+ bool ok;
+ TQString name, icon;
+
+ // get url
+ KURL inpath = KURL::fromPathOrURL(*it);
+ ++it;
+
+ // get name
+ name = *it;
+ ++it;
+
+ // get icon
+ icon = *it;
+ ++it;
+
+ // get index
+ int index = (*it).toInt(&ok);
+
+ i->setURL(inpath);
+
+ if(name.isEmpty())
+ i->setText(0, inpath.isLocalFile() ? inpath.path() : inpath.prettyURL());
+ else
+ {
+ i->setText(0, name);
+ i->setName(name);
+ }
+
+ if(!icon.isEmpty())
+ {
+ i->setIcon(icon);
+ i->setPixmap(0, SQ_IconLoader::instance()->loadIcon(icon, TDEIcon::Desktop, TDEIcon::SizeSmall));
+ }
+
+ if(ok) i->setIndex(index);
+ }
+
+ return i;
+}
+
+/* ******************************************************************************* */
+
+SQ_DirectoryBasket::SQ_DirectoryBasket(TQWidget *parent, const char *name) : KFileTreeView(parent, name)
+{
+ m_inst = this;
+
+ progressAdd = new KProgress(0, "progress add", TQt::WStyle_StaysOnTop | TQt::WStyle_Customize | TQt::WStyle_NoBorder | TQt::WX11BypassWM);
+
+ menu = new SQ_DBMenu(this);
+
+ timer = new TQTimer(this);
+ connect(timer, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotSortReal()));
+
+ timerAdd = new TQTimer(this);
+ connect(timerAdd, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotDelayedShowAdd()));
+
+ setSorting(-1);
+ setAcceptDrops(true);
+
+ dir = new SQ_Dir(SQ_Dir::DirectoryBasket);
+
+ // create custom branch
+ root = new SQ_DirectoryBasketBranch(this, dir->root(), TQString(),
+ SQ_IconLoader::instance()->loadIcon("folder", TDEIcon::Desktop, TDEIcon::SizeSmall));
+
+ // some hacks to create our SQ_TreeViewItem as root item
+ SQ_DirectoryItem *ritem = new SQ_DirectoryItem(this,
+ new KFileItem(dir->root(),
+ "inode/directory", S_IFDIR),
+ root);
+
+ ritem->setText(0, i18n("Folders"));
+ ritem->setExpandable(true);
+ ritem->setURL(dir->root());
+ delete root->root();
+ root->setRoot(ritem);
+
+ addBranch(root);
+
+ disconnect(root, TQ_SIGNAL(refreshItems(const KFileItemList &)), 0, 0);
+
+ header()->hide();
+ addColumn(i18n("File"));
+ setDirOnlyMode(root, false);
+ setCurrentItem(root->root());
+ root->setOpen(true);
+ setRootIsDecorated(false);
+
+ menu->reconnect(SQ_TreeViewMenu::New, this, TQ_SLOT(slotNewDirectory()));
+
+ connect(this, TQ_SIGNAL(spacePressed(TQListViewItem*)), this, TQ_SIGNAL(executed(TQListViewItem*)));
+ connect(this, TQ_SIGNAL(returnPressed(TQListViewItem*)), this, TQ_SIGNAL(executed(TQListViewItem*)));
+ connect(this, TQ_SIGNAL(executed(TQListViewItem*)), this, TQ_SLOT(slotItemExecuted(TQListViewItem*)));
+ connect(this, TQ_SIGNAL(contextMenu(TDEListView*, TQListViewItem*, const TQPoint&)), this, TQ_SLOT(slotContextMenu(TDEListView*, TQListViewItem*, const TQPoint&)));
+ connect(this, TQ_SIGNAL(dropped(TQDropEvent*, TQListViewItem*, TQListViewItem*)), this, TQ_SLOT(slotDropped(TQDropEvent*, TQListViewItem*, TQListViewItem*)));
+ connect(this, TQ_SIGNAL(itemRenamed(TQListViewItem *, int, const TQString &)), this, TQ_SLOT(slotItemRenamedMy(TQListViewItem *, int, const TQString &)));
+ connect(this, TQ_SIGNAL(itemAdded(TQListViewItem *)), this, TQ_SLOT(slotSort()));
+ connect(this, TQ_SIGNAL(moved()), this, TQ_SLOT(slotReindex()));
+}
+
+SQ_DirectoryBasket::~SQ_DirectoryBasket()
+{
+ SQ_DirectoryItem *item = static_cast<SQ_DirectoryItem *>(root->root()->firstChild());
+
+ static const TQString &nl = TDEGlobal::staticQString("\n");
+
+ if(item)
+ {
+ TQString url;
+ int index = 0;
+
+ do
+ {
+ url = item->url().prettyURL() + nl + item->name() + nl + item->icon() + nl + TQString::number(index);
+
+ SQ_StorageFile::writeStorageFileAsString(
+ dir->root() + TQDir::separator() + item->url().fileName(),
+ item->url(), url);
+
+ ++index;
+ }
+ while((item = static_cast<SQ_DirectoryItem *>(item->nextSibling())));
+ }
+
+ delete dir;
+ delete progressAdd;
+}
+
+void SQ_DirectoryBasket::slotNewDirectory()
+{
+ static const TQString &nl = TDEGlobal::staticQString("\n");
+
+ KURL url = KFileDialog::getExistingURL(TQString(), KSquirrel::app());
+
+ if(url.isEmpty())
+ return;
+
+ SQ_StorageFile::writeStorageFileAsString(
+ dir->root() + TQDir::separator() + url.fileName(),
+ url,
+ (url.prettyURL() + nl + nl + nl + TQString::number(root->root()->childCount())));
+}
+
+void SQ_DirectoryBasket::slotDropped(TQDropEvent *e, TQListViewItem *_parent, TQListViewItem *_item)
+{
+ if(!_parent) return;
+ if(!_item) _item = _parent;
+
+ SQ_DirectoryItem *item = static_cast<SQ_DirectoryItem *>(_item);
+ SQ_DirectoryItem *parent = static_cast<SQ_DirectoryItem *>(_parent);
+
+ KURL::List list;
+ KURLDrag::decode(e, list);
+
+ // drag'n'drop inside basket
+ if(e->source() == this)
+ {
+ SQ_DirectoryItem *tomove = static_cast<SQ_DirectoryItem *>(root->findTVIByURL(list.first()));
+
+ if(!tomove || tomove == root->root()) return;
+
+ SQ_DirectoryItem *it;
+
+ if(item->index() < tomove->index() && item != root->root())
+ it = static_cast<SQ_DirectoryItem *>(item->itemAbove());
+ else
+ it = static_cast<SQ_DirectoryItem *>(item);
+
+ if(it)
+ {
+ if(it != root->root())
+ moveItem(tomove, parent, it);
+ else
+ moveItem(tomove, parent, 0);
+
+ emit moved();
+
+ setCurrentItem(tomove);
+ setSelected(tomove, true);
+ }
+ }
+ else if(item == root->root()) // some files were dropped from another source
+ {
+ KURL::List::iterator itEnd = list.end();
+ KFileItemList flist;
+ TDEIO::UDSEntry entry;
+
+ progressAdd->setTotalSteps(list.count());
+ timerAdd->start(1000, true);
+
+ for(KURL::List::iterator it = list.begin();it != itEnd;++it)
+ {
+ if(TDEIO::NetAccess::stat(*it, entry, KSquirrel::app()))
+ flist.append(new KFileItem(entry, *it));
+
+ progressAdd->advance(1);
+ }
+
+ timerAdd->stop();
+ progressAdd->hide();
+
+ add(flist);
+ flist.setAutoDelete(true);
+ }
+ else
+ {
+ SQ_NavigatorDropMenu::instance()->setupFiles(list, item->url());
+ SQ_NavigatorDropMenu::instance()->exec(TQCursor::pos(), true);
+ }
+}
+
+void SQ_DirectoryBasket::slotItemExecuted(TQListViewItem *item)
+{
+ if(!item) return;
+
+ if(item == root->root())
+ {
+ root->setOpen(true);
+ return;
+ }
+
+ KFileTreeViewItem *cur = static_cast<KFileTreeViewItem *>(item);
+
+ if(cur && !cur->isDir())
+ {
+ KURL inpath = SQ_StorageFile::readStorageFile(cur->path());
+ SQ_WidgetStack::instance()->diroperator()->setURL(inpath, true);
+ }
+}
+
+void SQ_DirectoryBasket::slotContextMenu(TDEListView *, TQListViewItem *item, const TQPoint &p)
+{
+ if(item)
+ {
+ SQ_DirectoryItem *kfi = static_cast<SQ_DirectoryItem *>(item);
+
+ if(kfi)
+ {
+ menu->updateDirActions(true, item == root->root());
+ menu->setURL(kfi->url());
+ menu->setItem(kfi);
+ menu->exec(p);
+ }
+ }
+}
+
+void SQ_DirectoryBasket::add(const KFileItemList &list)
+{
+ static const TQString &nl = TDEGlobal::staticQString("\n");
+
+ KFileItemListIterator it(list);
+ KFileItem *fi;
+ TQString url;
+
+ while((fi = it.current()))
+ {
+ if(fi->isDir())
+ {
+ url = fi->url().prettyURL() + nl + nl + nl + TQString::number(root->root()->childCount());
+
+ SQ_StorageFile::writeStorageFileAsString(
+ dir->root() + TQDir::separator() + fi->url().fileName(),
+ fi->url(),
+ url);
+ }
+
+ ++it;
+ }
+}
+
+void SQ_DirectoryBasket::slotSort()
+{
+ timer->start(100, true);
+}
+
+void SQ_DirectoryBasket::slotSortReal()
+{
+ sort();
+}
+
+struct SortableItem
+{
+ SortableItem(TQListViewItem *i, int ind) : item(i), index(ind)
+ {}
+
+ SortableItem() : item(0), index(0)
+ {}
+
+ bool operator< (const SortableItem &i)
+ {
+ return index > i.index;
+ }
+
+ TQListViewItem *item;
+ int index;
+};
+
+void SQ_DirectoryBasket::sort()
+{
+ TQListViewItemIterator it(this);
+ SQ_DirectoryItem *item;
+
+ TQValueVector<SortableItem> items;
+ int i = 0;
+ ++it;
+
+ while((item = static_cast<SQ_DirectoryItem *>(it.current())))
+ {
+ items.append(SortableItem(item, item->index()));
+ ++it;
+ }
+
+ const int nChildren = items.count();
+
+ for(i = 0;i < nChildren;i++)
+ root->root()->takeItem(items[i].item);
+
+ qHeapSort(items);
+
+ blockSignals(true);
+ for(i = 0;i < nChildren;i++)
+ root->root()->insertItem(items[i].item);
+ blockSignals(false);
+}
+
+void SQ_DirectoryBasket::slotReindex()
+{
+ SQ_DirectoryItem *item = static_cast<SQ_DirectoryItem *>(root->root()->firstChild());
+
+ if(item)
+ {
+ int index = 0;
+
+ do
+ {
+ item->setIndex(index++);
+ }
+ while((item = static_cast<SQ_DirectoryItem *>(item->nextSibling())));
+ }
+}
+
+void SQ_DirectoryBasket::slotItemRenamedMy(TQListViewItem *_item, int, const TQString &name)
+{
+ SQ_DirectoryItem *item = static_cast<SQ_DirectoryItem *>(_item);
+
+ if(item)
+ item->setName(name);
+}
+
+void SQ_DirectoryBasket::slotDelayedShowAdd()
+{
+ int w = 200, h = 32;
+
+ TQRect rc = TDEGlobalSettings::splashScreenDesktopGeometry();
+
+ progressAdd->setGeometry(rc.center().x() - w/2, rc.center().y() - h/2, w, h);
+ progressAdd->show();
+}
+
+#include "sq_directorybasket.moc"
diff --git a/src/sidebar/sq_directorybasket.h b/src/sidebar/sq_directorybasket.h
new file mode 100644
index 0000000..6f2858d
--- /dev/null
+++ b/src/sidebar/sq_directorybasket.h
@@ -0,0 +1,195 @@
+/***************************************************************************
+ sq_directorybasket.h - description
+ -------------------
+ begin : ??? Sep 29 2007
+ copyright : (C) 2007 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SQ_DIRECTORYBASKET_H
+#define SQ_DIRECTORYBASKET_H
+
+#include <tdefiletreeview.h>
+#include <tdefiletreebranch.h>
+
+#include "sq_treeviewmenu.h"
+
+class TQTimer;
+
+class KProgress;
+
+namespace TDEIO { class Job; }
+
+class SQ_DirectoryItem;
+class SQ_Dir;
+
+class SQ_DBMenu : public SQ_TreeViewMenu
+{
+ TQ_OBJECT
+
+
+ public:
+ SQ_DBMenu(TQWidget *parent = 0, const char *name = 0);
+ ~SQ_DBMenu();
+
+ virtual void updateDirActions(bool, bool isroot = false);
+
+ void setItem(SQ_DirectoryItem *);
+
+ private slots:
+ void slotChangeIcon();
+ void slotDirectoryRename();
+ void slotDirectoryDelete();
+ void slotDirectoryResult(TDEIO::Job *job);
+
+ private:
+ SQ_DirectoryItem *item;
+ int id_icon;
+};
+
+inline
+void SQ_DBMenu::setItem(SQ_DirectoryItem *i)
+{
+ item = i;
+}
+
+class SQ_DirectoryItem : public KFileTreeViewItem
+{
+ public:
+ SQ_DirectoryItem(KFileTreeViewItem *parentItem, KFileItem *fileItem, KFileTreeBranch *parentBranch);
+ SQ_DirectoryItem(KFileTreeView *parent, KFileItem *fileItem, KFileTreeBranch *parentBranch);
+ ~SQ_DirectoryItem();
+
+ int index() const;
+ void setIndex(int ind);
+
+ KURL url() const;
+ void setURL(const KURL &u);
+
+ TQString name() const;
+ void setName(const TQString &n);
+
+ TQString icon() const;
+ void setIcon(const TQString &n);
+
+ bool hasName() const;
+
+ private:
+ int m_index;
+ TQString m_name, m_icon;
+ KURL m_url;
+};
+
+inline
+KURL SQ_DirectoryItem::url() const
+{
+ return m_url;
+}
+
+inline
+void SQ_DirectoryItem::setURL(const KURL &u)
+{
+ m_url = u;
+}
+
+inline
+int SQ_DirectoryItem::index() const
+{
+ return m_index;
+}
+
+inline
+void SQ_DirectoryItem::setIndex(int ind)
+{
+ m_index = ind;
+}
+
+inline
+TQString SQ_DirectoryItem::name() const
+{
+ return m_name;
+}
+
+inline
+void SQ_DirectoryItem::setName(const TQString &n)
+{
+ m_name = n;
+}
+
+inline
+TQString SQ_DirectoryItem::icon() const
+{
+ return m_icon;
+}
+
+inline
+void SQ_DirectoryItem::setIcon(const TQString &n)
+{
+ m_icon = n;
+}
+
+inline
+bool SQ_DirectoryItem::hasName() const
+{
+ return !m_name.isEmpty();
+}
+
+/* ****************************************************************** */
+
+class SQ_DirectoryBasketBranch : public KFileTreeBranch
+{
+ public:
+ SQ_DirectoryBasketBranch(KFileTreeView*, const KURL &url, const TQString &name, const TQPixmap &pix);
+ ~SQ_DirectoryBasketBranch();
+
+ protected:
+ virtual KFileTreeViewItem *createTreeViewItem(KFileTreeViewItem *parent, KFileItem *fileItem);
+};
+
+class SQ_DirectoryBasket : public KFileTreeView
+{
+ TQ_OBJECT
+
+
+ public:
+ SQ_DirectoryBasket(TQWidget *parent = 0, const char *name = 0);
+ ~SQ_DirectoryBasket();
+
+ void add(const KFileItemList &list);
+
+ static SQ_DirectoryBasket* instance() { return m_inst; }
+
+ private:
+ void sort();
+
+ private slots:
+ void slotDropped(TQDropEvent *, TQListViewItem *, TQListViewItem *);
+ void slotItemExecuted(TQListViewItem *item);
+ void slotContextMenu(TDEListView *, TQListViewItem *item, const TQPoint &p);
+ void slotNewDirectory();
+ void slotSortReal();
+ void slotSort();
+ void slotReindex();
+ void slotItemRenamedMy(TQListViewItem *, int, const TQString &);
+ void slotDelayedShowAdd();
+
+ private:
+ KFileTreeBranch *root;
+ SQ_Dir *dir;
+ TQTimer *timer, *timerAdd;
+ SQ_DBMenu *menu;
+ KProgress *progressAdd;
+
+ static SQ_DirectoryBasket *m_inst;
+};
+
+#endif
diff --git a/src/sidebar/sq_imagebasket.cpp b/src/sidebar/sq_imagebasket.cpp
new file mode 100644
index 0000000..eeba95c
--- /dev/null
+++ b/src/sidebar/sq_imagebasket.cpp
@@ -0,0 +1,291 @@
+/***************************************************************************
+ sq_imagebasket.cpp - description
+ -------------------
+ begin : ??? Feb 24 2007
+ copyright : (C) 2004 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <tqfile.h>
+
+#include <kmdcodec.h>
+#include <tdefileview.h>
+#include <tdelocale.h>
+#include <tdeglobal.h>
+#include <tdepopupmenu.h>
+#include <tdefileiconview.h>
+#include <kpropertiesdialog.h>
+#include <tdeio/netaccess.h>
+#include <tdeapplication.h>
+#include <kmimetype.h>
+
+#include "ksquirrel.h"
+#include "sq_config.h"
+#include "sq_imagebasket.h"
+#include "sq_storagefile.h"
+#include "sq_dir.h"
+#include "sq_widgetstack.h"
+#include "sq_diroperator.h"
+
+SQ_ImageBasket * SQ_ImageBasket::m_inst;
+
+SQ_ImageBasket::SQ_ImageBasket(TQWidget *parent, const char *name) : KDirOperator((dir = new SQ_Dir(SQ_Dir::Basket))->root(), parent, name)
+{
+ m_inst = this;
+
+ connect(this, TQ_SIGNAL(dropped(const KFileItem *, TQDropEvent*, const KURL::List&)),
+ this, TQ_SLOT(slotDropped(const KFileItem *, TQDropEvent*, const KURL::List&)));
+
+ disconnect(dirLister(), TQ_SIGNAL(refreshItems(const KFileItemList &)), 0, 0);
+
+ // redirect "Properties" dialog
+ disconnect(actionCollection()->action("properties"), 0, 0, 0);
+ connect(actionCollection()->action("properties"), TQ_SIGNAL(activated()), this, TQ_SLOT(slotBasketProperties()));
+
+ disconnect(dirLister(), TQ_SIGNAL(newItems(const KFileItemList &)), 0, 0);
+ connect(dirLister(), TQ_SIGNAL(newItems(const KFileItemList &)), this, TQ_SLOT(insertNewFiles(const KFileItemList &)));
+
+ connect(this, TQ_SIGNAL(viewChanged(KFileView *)), this, TQ_SLOT(slotViewChanged(KFileView *)));
+ connect(this, TQ_SIGNAL(fileSelected(const KFileItem *)), this, TQ_SLOT(slotExecuted(const KFileItem *)));
+
+ setView(KFile::Simple);
+ setMode(KFile::Files);
+
+ setAcceptDrops(true);
+
+ SQ_Config::instance()->setGroup("Fileview");
+ int sorting = 0;
+
+ if(SQ_Config::instance()->readBoolEntry("basket_sorting_name", true)) sorting |= TQDir::Name;
+ if(SQ_Config::instance()->readBoolEntry("basket_sorting_time", false)) sorting |= TQDir::Time;
+ if(SQ_Config::instance()->readBoolEntry("basket_sorting_size", false)) sorting |= TQDir::Size;
+ if(SQ_Config::instance()->readBoolEntry("basket_sorting_dirs", true)) sorting |= TQDir::DirsFirst;
+ if(SQ_Config::instance()->readBoolEntry("basket_sorting_reverse", false)) sorting |= TQDir::Reversed;
+ if(SQ_Config::instance()->readBoolEntry("basket_sorting_ignore", false)) sorting |= TQDir::IgnoreCase;
+
+ setSorting(static_cast<TQDir::SortSpec>(sorting));
+}
+
+SQ_ImageBasket::~SQ_ImageBasket()
+{
+ delete dir;
+}
+
+void SQ_ImageBasket::insertNewFiles(const KFileItemList &list)
+{
+ TQString n;
+ int ind;
+ KFileItemListIterator it(list);
+ KFileItem *tmp;
+
+ for(; (tmp = it.current()); ++it)
+ {
+ n = tmp->name();
+ ind = n.findRev('.');
+
+ // OOPS
+ if(ind != -1)
+ n.truncate(ind);
+
+ // force determining mimetype
+ (void)tmp->mimetype();
+ tmp->setName(n);
+
+ TQStringList list = TQStringList::split(TQChar('\n'), SQ_StorageFile::readStorageFileAsString(tmp->url().path()), true);
+ TQStringList::iterator it = list.begin();
+
+ if(list.count() > 1)
+ {
+ ++it; // skip url
+ tmp->setMimeType(*it);
+ }
+ else
+ {
+ KURL url = KURL::fromPathOrURL(*it);
+ TQString mime = KMimeType::findByURL(url)->name();
+ tmp->setMimeType(mime);
+
+ static const TQString &nl = TDEGlobal::staticQString("\n");
+
+ TQString inurl = url.prettyURL() + nl + mime;
+
+ SQ_StorageFile::writeStorageFileAsString(
+ dir->root() + TQDir::separator() + url.fileName(),
+ url, inurl);
+ }
+ }
+
+ view()->addItemList(list);
+}
+
+void SQ_ImageBasket::add(const KFileItemList &list)
+{
+ KFileItem *tmp;
+ static const TQString &nl = TDEGlobal::staticQString("\n");
+
+ for(KFileItemListIterator it(list); (tmp = it.current()); ++it)
+ {
+ if(tmp->isFile())
+ {
+ TQString inurl = tmp->url().prettyURL() + nl + tmp->mimetype();
+
+ SQ_StorageFile::writeStorageFileAsString(
+ dir->root() + TQDir::separator() + tmp->name(),
+ tmp->url(), inurl);
+ }
+ }
+}
+
+void SQ_ImageBasket::slotDropped(const KFileItem *, TQDropEvent*, const KURL::List &list)
+{
+ TQString name;
+ KURL::List::const_iterator itEnd = list.end();
+ static const TQString &nl = TDEGlobal::staticQString("\n");
+
+ for(KURL::List::const_iterator it = list.begin();it != itEnd;++it)
+ {
+ TQString inurl = (*it).prettyURL() + nl + KMimeType::findByURL(*it)->name();
+
+ SQ_StorageFile::writeStorageFileAsString(
+ dir->root() + TQDir::separator() + (*it).fileName(),
+ *it, inurl);
+ }
+}
+
+void SQ_ImageBasket::slotBasketProperties()
+{
+ KFileView *fileView = view();
+
+ if(fileView)
+ {
+ KFileItemList newlist;
+ KFileItem *item = 0;
+
+ newlist.setAutoDelete(true);
+
+ for((item = fileView->firstFileItem()); item; item = fileView->nextItem(item))
+ {
+ if(fileView->isSelected(item))
+ {
+ KFileItem *realFile = new KFileItem(KFileItem::Unknown, KFileItem::Unknown,
+ SQ_StorageFile::readStorageFile(item->url().path()));
+
+ newlist.append(realFile);
+ }
+ }
+
+ if (!newlist.isEmpty())
+ (void)new KPropertiesDialog(newlist, KSquirrel::app(), "props dlg", true);
+ }
+}
+
+KFileItemList SQ_ImageBasket::realItems() const
+{
+ KFileView *fileView = view();
+ KFileItemList newlist;
+
+ newlist.setAutoDelete(true);
+
+ if(fileView)
+ {
+ KFileItem *item = 0;
+
+ for((item = fileView->firstFileItem()); item; item = fileView->nextItem(item))
+ {
+ KFileItem *realFile = new KFileItem(KFileItem::Unknown, KFileItem::Unknown,
+ SQ_StorageFile::readStorageFile(item->url().path()));
+
+ newlist.append(realFile);
+ }
+ }
+
+ return newlist;
+}
+
+void SQ_ImageBasket::slotSync()
+{
+ KFileView *fileView = view();
+
+ if(fileView)
+ {
+ KFileItem *item = 0;
+ KURL path;
+ TDEIO::UDSEntry entry;
+
+ for((item = fileView->firstFileItem()); item; item = fileView->nextItem(item))
+ {
+ path = SQ_StorageFile::readStorageFile(item->url().path());
+
+ if(!TDEIO::NetAccess::stat(path, entry, KSquirrel::app()))
+ TQFile::remove(item->url().path());
+ }
+ }
+}
+
+void SQ_ImageBasket::slotViewChanged(KFileView *v)
+{
+ KFileIconView *iv = dynamic_cast<KFileIconView *>(v);
+
+ if(iv)
+ {
+ TDEAction *a;
+
+ a = iv->actionCollection()->action("zoomIn");
+ if(a) a->setShortcut(0);
+
+ a = iv->actionCollection()->action("zoomOut");
+ if(a) a->setShortcut(0);
+
+ a = iv->actionCollection()->action("show previews");
+ if(a) a->setShortcut(0);
+ }
+}
+
+void SQ_ImageBasket::slotExecuted(const KFileItem *fi)
+{
+ if(!fi)
+ return;
+
+ KURL inpath = SQ_StorageFile::readStorageFile(fi->url().path());
+
+ KFileItem f(KFileItem::Unknown, KFileItem::Unknown, inpath);
+
+ SQ_WidgetStack::instance()->diroperator()->execute(&f);
+}
+
+void SQ_ImageBasket::activatedMenu(const KFileItem *, const TQPoint &pos)
+{
+ setupMenu(KDirOperator::AllActions ^ KDirOperator::NavActions ^ KDirOperator::ViewActions);
+ updateSelectionDependentActions();
+
+ TDEActionMenu *pADirOperatorMenu = dynamic_cast<TDEActionMenu *>(actionCollection()->action("popupMenu"));
+ pADirOperatorMenu->popupMenu()->insertItem(i18n("Synchronize"), this, TQ_SLOT(slotSync()), 0, -1, 0);
+ pADirOperatorMenu->popupMenu()->insertSeparator(1);
+
+ pADirOperatorMenu->popup(pos);
+}
+
+void SQ_ImageBasket::saveConfig()
+{
+ TQDir::SortSpec sort = sorting();
+
+ SQ_Config::instance()->writeEntry("basket_sorting_name", KFile::isSortByName(sort));
+ SQ_Config::instance()->writeEntry("basket_sorting_time", KFile::isSortByDate(sort));
+ SQ_Config::instance()->writeEntry("basket_sorting_size", KFile::isSortBySize(sort));
+ SQ_Config::instance()->writeEntry("basket_sorting_dirs", KFile::isSortDirsFirst(sort));
+ SQ_Config::instance()->writeEntry("basket_sorting_reverse", (sort & TQDir::Reversed) == TQDir::Reversed);
+ SQ_Config::instance()->writeEntry("basket_sorting_ignore", KFile::isSortCaseInsensitive(sort));
+
+ SQ_Config::instance()->writeEntry("show hidden", showHiddenFiles());
+}
+
+#include "sq_imagebasket.moc"
diff --git a/src/sidebar/sq_imagebasket.h b/src/sidebar/sq_imagebasket.h
new file mode 100644
index 0000000..406b3c4
--- /dev/null
+++ b/src/sidebar/sq_imagebasket.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+ sq_imagebasket.h - description
+ -------------------
+ begin : ??? Feb 24 2007
+ copyright : (C) 2007 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SQ_IMAGEBASKET_H
+#define SQ_IMAGEBASKET_H
+
+#include <tdediroperator.h>
+
+class SQ_Dir;
+
+/**
+ *@author Baryshev Dmitry
+ */
+
+class SQ_ImageBasket : public KDirOperator
+{
+ TQ_OBJECT
+
+
+ public:
+ SQ_ImageBasket(TQWidget *parent = 0, const char *name = 0);
+ ~SQ_ImageBasket();
+
+ void add(const KFileItemList &);
+
+ KFileItemList realItems() const;
+
+ void saveConfig();
+
+ static SQ_ImageBasket* instance() { return m_inst; }
+
+ private slots:
+ // coming from KDirOperator
+ void insertNewFiles(const KFileItemList &);
+ void slotDropped(const KFileItem *, TQDropEvent*, const KURL::List&);
+ void slotBasketProperties();
+ void slotSync();
+ void slotViewChanged(KFileView *);
+ void slotExecuted(const KFileItem *fi);
+
+ void activatedMenu(const KFileItem *, const TQPoint &pos);
+
+ private:
+ SQ_Dir *dir;
+ static SQ_ImageBasket *m_inst;
+};
+
+#endif
diff --git a/src/sidebar/sq_mountview.cpp b/src/sidebar/sq_mountview.cpp
new file mode 100644
index 0000000..c52b199
--- /dev/null
+++ b/src/sidebar/sq_mountview.cpp
@@ -0,0 +1,247 @@
+/***************************************************************************
+ sq_mountview.cpp - description
+ -------------------
+ begin : ??? Nov 29 2005
+ copyright : (C) 2005 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tdemessagebox.h>
+#include <kmountpoint.h>
+#include <tdeglobal.h>
+#include <tdelocale.h>
+#include <kautomount.h>
+#include <tdepopupmenu.h>
+
+#include "ksquirrel.h"
+#include "sq_mountview.h"
+#include "sq_mountviewitem.h"
+#include "sq_iconloader.h"
+#include "sq_config.h"
+
+SQ_MountView * SQ_MountView::m_inst = 0;
+
+SQ_MountView::SQ_MountView(TQWidget *parent, const char *name) : TDEListView(parent, name), m_columns(-1)
+{
+ m_inst = this;
+
+ popup = new TDEPopupMenu;
+ id_mount = popup->insertItem(SQ_IconLoader::instance()->loadIcon("drive-harddisk-mounted", TDEIcon::Desktop, TDEIcon::SizeSmall),
+ i18n("Mount"), this, TQ_SLOT(slotMount()));
+ id_unmount = popup->insertItem(SQ_IconLoader::instance()->loadIcon("drive-harddisk-unmounted", TDEIcon::Desktop, TDEIcon::SizeSmall),
+ i18n("Unmount"), this, TQ_SLOT(slotUnmount()));
+ popup->insertItem(SQ_IconLoader::instance()->loadIcon("reload", TDEIcon::Desktop, TDEIcon::SizeSmall),
+ i18n("Refresh"), this, TQ_SLOT(slotRefresh()));
+ popup->insertSeparator();
+ popup->insertItem(i18n("Cancel"));
+
+ connect(this, TQ_SIGNAL(contextMenu(TDEListView *, TQListViewItem *, const TQPoint &)),
+ this, TQ_SLOT(slotContextMenu(TDEListView *, TQListViewItem *, const TQPoint &)));
+ setAcceptDrops(false);
+
+ connect(this, TQ_SIGNAL(returnPressed(TQListViewItem*)), this, TQ_SLOT(slotExecuted(TQListViewItem *)));
+ connect(this, TQ_SIGNAL(clicked(TQListViewItem*)), this, TQ_SLOT(slotExecuted(TQListViewItem *)));
+
+ setShowSortIndicator(true);
+ setAllColumnsShowFocus(true);
+ setSelectionMode(TQListView::Single);
+ setItemsMovable(false);
+
+ // "Name" column will always exist
+ addColumn(i18n("Name"));
+
+ setupColumns();
+}
+
+SQ_MountView::~SQ_MountView()
+{}
+
+void SQ_MountView::slotExecuted(TQListViewItem *i)
+{
+ SQ_MountViewItem *mvi = static_cast<SQ_MountViewItem *>(i);
+
+ if(!mvi)
+ return;
+
+ if(mvi->mounted())
+ emit path(mvi->text(0));
+ else
+ {
+ mountItem = mvi;
+ KAutoMount *mounter = new KAutoMount(false, TQString(), mvi->device(), TQString(), TQString(), false);
+ connect(mounter, TQ_SIGNAL(finished()), this, TQ_SLOT(slotMountFinished()));
+ }
+}
+
+void SQ_MountView::slotMountFinished()
+{
+ mountItem->setMounted(true);
+ emit path(mountItem->text(0));
+}
+
+void SQ_MountView::slotMountError()
+{
+ mountItem->setMounted(false);
+}
+
+void SQ_MountView::reload(bool current)
+{
+ // get currently mounted filesystems
+ KMountPoint::List mt = current ?
+ KMountPoint::currentMountPoints(KMountPoint::NeedMountOptions | KMountPoint::NeedRealDeviceName)
+ : KMountPoint::possibleMountPoints(KMountPoint::NeedMountOptions | KMountPoint::NeedRealDeviceName);
+
+ SQ_MountViewItem *fi;
+ int colum;
+
+ for(KMountPoint::List::iterator it = mt.begin();it != mt.end();++it)
+ {
+ colum = 1;
+
+ if(mounted.find((*it)->mountPoint()) == mounted.end())
+ {
+ mounted.append((*it)->mountPoint());
+
+ // filter out /proc, swap etc.
+ if(!(*it)->mountedFrom().startsWith(TQChar('/')) || !(*it)->mountPoint().startsWith(TQChar('/')))
+ continue;
+
+ fi = new SQ_MountViewItem(this, (*it)->mountPoint());
+ fi->setMounted(current);
+ fi->setDevice((*it)->realDeviceName());
+
+ if(m_columns & OPT_COL_DEVICE)
+ fi->setText(colum++, (*it)->realDeviceName());
+
+ if(m_columns & OPT_COL_FSTYPE)
+ fi->setText(colum++, (*it)->mountType());
+
+ if(m_columns & OPT_COL_OPTIONS)
+ fi->setText(colum, (*it)->mountOptions().join(TQString::fromLatin1(", ")));
+ }
+ }
+}
+
+bool SQ_MountView::exists(const TQString &name)
+{
+ TQListViewItemIterator it(this);
+
+ while(it.current())
+ {
+ SQ_MountViewItem *mvi = static_cast<SQ_MountViewItem *>(it.current());
+
+ if(mvi && mvi->text(0) == name)
+ return true;
+
+ ++it;
+ }
+
+ return false;
+}
+
+void SQ_MountView::setColumns(int cols)
+{
+ if(m_columns == cols)
+ return;
+
+ m_columns = cols;
+
+ int cur = columns() - 1;
+
+ // remove old columns, 0 is always "Name"
+ for(int i = 0;i < cur;i++)
+ removeColumn(1);
+
+ // add new
+ if(m_columns & OPT_COL_DEVICE)
+ addColumn(i18n("Device"));
+
+ if(m_columns & OPT_COL_FSTYPE)
+ addColumn(i18n("FS Type"));
+
+ if(m_columns & OPT_COL_OPTIONS)
+ addColumn(i18n("Options"));
+
+ slotRefresh();
+}
+
+void SQ_MountView::setupColumns()
+{
+ SQ_Config::instance()->setGroup("Sidebar");
+ int p = 0;
+
+ if(SQ_Config::instance()->readBoolEntry("mount_options", false))
+ p |= SQ_MountView::OPT_COL_OPTIONS;
+
+ if(SQ_Config::instance()->readBoolEntry("mount_fstype", true))
+ p |= SQ_MountView::OPT_COL_FSTYPE;
+
+ if(SQ_Config::instance()->readBoolEntry("mount_device", false))
+ p |= SQ_MountView::OPT_COL_DEVICE;
+
+ setColumns(p);
+}
+
+void SQ_MountView::slotContextMenu(TDEListView *, TQListViewItem *i, const TQPoint &p)
+{
+ SQ_MountViewItem *mvi = static_cast<SQ_MountViewItem *>(i);
+
+ citem = mvi;
+
+ popup->setItemEnabled(id_mount, !!mvi);
+ popup->setItemEnabled(id_unmount, !!mvi);
+
+ popup->exec(p);
+}
+
+void SQ_MountView::slotUnmount()
+{
+ if(citem)
+ {
+ KAutoUnmount *mounter = new KAutoUnmount(citem->text(0), TQString());
+ connect(mounter, TQ_SIGNAL(finished()), this, TQ_SLOT(slotUnmountFinished()));
+ }
+}
+
+void SQ_MountView::slotMount()
+{
+ if(citem)
+ {
+ KAutoMount *mounter = new KAutoMount(false, TQString(), citem->device(), TQString(), TQString(), false);
+ connect(mounter, TQ_SIGNAL(finished()), this, TQ_SLOT(slotMountFinished2()));
+// connect(mounter, TQ_SIGNAL(error()), this, TQ_SLOT(slotMountError()));
+ }
+}
+
+void SQ_MountView::slotUnmountFinished()
+{
+ citem->setMounted(false);
+}
+
+void SQ_MountView::slotMountFinished2()
+{
+ citem->setMounted(true);
+}
+
+void SQ_MountView::slotRefresh()
+{
+ clear();
+ mounted.clear();
+ reload();
+ reload(false);
+}
+
+#include "sq_mountview.moc"
diff --git a/src/sidebar/sq_mountview.h b/src/sidebar/sq_mountview.h
new file mode 100644
index 0000000..d14aa13
--- /dev/null
+++ b/src/sidebar/sq_mountview.h
@@ -0,0 +1,84 @@
+/***************************************************************************
+ sq_mountview.h - description
+ -------------------
+ begin : ??? Nov 29 2005
+ copyright : (C) 2005 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SQ_MOUNTVIEW_H
+#define SQ_MOUNTVIEW_H
+
+#include <tqstringlist.h>
+
+#include <tdelistview.h>
+
+class TDEPopupMenu;
+
+class SQ_MountViewItem;
+
+/*
+ * SQ_MountView is an detailed view representing mount points.
+ */
+
+class SQ_MountView : public TDEListView
+{
+ TQ_OBJECT
+
+
+ public:
+ SQ_MountView(TQWidget *parent = 0, const char *name = 0);
+ ~SQ_MountView();
+
+ enum { OPT_COL_MOUNTPOINT = 1, OPT_COL_DEVICE = 2, OPT_COL_FSTYPE = 4, OPT_COL_OPTIONS = 8 };
+
+ static SQ_MountView* instance() { return m_inst; }
+
+ void setupColumns();
+
+ void reload(bool current = true);
+
+ private:
+ void setColumns(int cols);
+ bool exists(const TQString &);
+
+ private slots:
+
+ void slotContextMenu(TDEListView *, TQListViewItem *i, const TQPoint &p);
+ /*
+ * Item executed. We should emit path() signal.
+ */
+ void slotExecuted(TQListViewItem *i);
+
+ // for context menu
+ void slotRefresh();
+ void slotMount();
+ void slotUnmount();
+ void slotUnmountFinished();
+ void slotMountFinished();
+ void slotMountFinished2();
+ void slotMountError();
+
+ signals:
+ void path(const TQString &);
+
+ private:
+ int m_columns;
+ SQ_MountViewItem *mountItem, *citem;
+ TQStringList mounted;
+ TDEPopupMenu *popup;
+ int id_mount, id_unmount;
+
+ static SQ_MountView *m_inst;
+};
+
+#endif
diff --git a/src/sidebar/sq_mountviewitem.cpp b/src/sidebar/sq_mountviewitem.cpp
new file mode 100644
index 0000000..532c0c8
--- /dev/null
+++ b/src/sidebar/sq_mountviewitem.cpp
@@ -0,0 +1,44 @@
+/***************************************************************************
+ sq_mountviewitem.cpp - description
+ -------------------
+ begin : ??? Feb 24 2007
+ copyright : (C) 2007 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tqfileinfo.h>
+
+#include "sq_mountviewitem.h"
+#include "sq_iconloader.h"
+
+SQ_MountViewItem::SQ_MountViewItem(TDEListView *parent, const TQString &mpoint)
+ : TDEListViewItem(parent, mpoint), m_mounted(false)
+{}
+
+SQ_MountViewItem::~SQ_MountViewItem()
+{}
+
+void SQ_MountViewItem::setMounted(bool b)
+{
+ m_mounted = b;
+ TQFileInfo inf(text(0));
+
+ if(m_mounted)
+ setPixmap(0, inf.isReadable() ? SQ_IconLoader::instance()->loadIcon("folder", TDEIcon::Desktop, TDEIcon::SizeMedium)
+ : SQ_IconLoader::instance()->loadIcon("folder_locked", TDEIcon::Desktop, TDEIcon::SizeMedium));
+ else
+ setPixmap(0, SQ_IconLoader::instance()->loadIcon("folder_red", TDEIcon::Desktop, TDEIcon::SizeMedium));
+}
diff --git a/src/sidebar/sq_mountviewitem.h b/src/sidebar/sq_mountviewitem.h
new file mode 100644
index 0000000..7056c39
--- /dev/null
+++ b/src/sidebar/sq_mountviewitem.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ sq_mountviewitem.h - description
+ -------------------
+ begin : ??? Feb 24 2007
+ copyright : (C) 2007 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SQ_MOUNTVIEWITEM_H
+#define SQ_MOUNTVIEWITEM_H
+
+#include <tdelistview.h>
+
+class SQ_MountViewItem : public TDEListViewItem
+{
+ public:
+ SQ_MountViewItem(TDEListView *parent, const TQString &mpoint);
+ ~SQ_MountViewItem();
+
+ bool mounted() const;
+ void setMounted(bool b);
+
+ TQString device() const;
+ void setDevice(const TQString &dev);
+
+ private:
+ bool m_mounted;
+ TQString m_device;
+};
+
+inline
+bool SQ_MountViewItem::mounted() const
+{
+ return m_mounted;
+}
+
+inline
+TQString SQ_MountViewItem::device() const
+{
+ return m_device;
+}
+
+inline
+void SQ_MountViewItem::setDevice(const TQString &dev)
+{
+ m_device = dev;
+}
+
+#endif
diff --git a/src/sidebar/sq_multibar.cpp b/src/sidebar/sq_multibar.cpp
new file mode 100644
index 0000000..399929d
--- /dev/null
+++ b/src/sidebar/sq_multibar.cpp
@@ -0,0 +1,133 @@
+/***************************************************************************
+ sq_multibar.cpp - description
+ -------------------
+ begin : ??? Nov 28 2005
+ copyright : (C) 2005 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tqwidgetstack.h>
+#include <tqsignalmapper.h>
+#include <tqsplitter.h>
+
+#include <tdemultitabbar.h>
+#include <tdeglobal.h>
+#include <kiconloader.h>
+
+#include "ksquirrel.h"
+#include "sq_previewwidget.h"
+#include "sq_multibar.h"
+#include "sq_config.h"
+
+SQ_MultiBar * SQ_MultiBar::m_inst = 0;
+
+SQ_MultiBar::SQ_MultiBar(TQWidget *parent, const char *name) : TQHBox(parent, name)
+{
+ m_inst = this;
+ m_id = 0;
+ m_selected = -1;
+
+ SQ_Config::instance()->setGroup("Interface");
+ m_width = SQ_Config::instance()->readNumEntry("splitter", 220);
+
+ mapper = new TQSignalMapper(this);
+
+ connect(mapper, TQ_SIGNAL(mapped(int)), this, TQ_SLOT(raiseWidget(int)));
+
+ mt = new KMultiTabBar(KMultiTabBar::Vertical, this);
+
+ // setup multibar: style = VSNET, show text labels on the left side
+ mt->setStyle(KMultiTabBar::VSNET);
+ mt->setPosition(KMultiTabBar::Left);
+ mt->showActiveTabTexts(true);
+
+ setSpacing(0);
+
+ TQSplitter *ts = new TQSplitter(TQt::Vertical, this);
+ ts->setOpaqueResize(false);
+
+ // TQWigdetStack will contain all widgets
+ stack = new TQWidgetStack(ts);
+
+ new SQ_PreviewWidget(ts);
+
+ TQValueList<int> sz;
+ sz.append(5500);
+ sz.append(4500);
+ ts->setSizes(sz);
+}
+
+SQ_MultiBar::~SQ_MultiBar()
+{}
+
+void SQ_MultiBar::addWidget(TQWidget *new_w, const TQString &text, const TQString &icon)
+{
+ // add widget to stack
+ stack->addWidget(new_w, m_id);
+
+ // add button
+ mt->appendTab(TDEGlobal::iconLoader()->loadIcon(icon, TDEIcon::Desktop, 22), m_id, text);
+
+ // since we cann't determine which tab was clicked,
+ // we should use TQSignalMapper to determine it.
+ mapper->setMapping(mt->tab(m_id), m_id);
+
+ connect(mt->tab(m_id), TQ_SIGNAL(clicked()), mapper, TQ_SLOT(map()));
+
+ m_id++;
+}
+
+void SQ_MultiBar::raiseWidget(int id)
+{
+ if(m_selected != -1)
+ mt->setTab(m_selected, false);
+
+ if(mt->isTabRaised(id))
+ {
+ if(m_selected != -1)
+ m_width = stack->width();
+
+ m_selected = id;
+
+ setMinimumSize(TQSize(0, 0));
+ setMaximumSize(TQSize(10000, 10000));
+ stack->raiseWidget(id);
+ stack->resize(m_width, stack->height());
+ stack->show();
+
+ SQ_PreviewWidget::instance()->ignore(false);
+ SQ_PreviewWidget::instance()->loadPending();
+ }
+ else
+ {
+ SQ_PreviewWidget::instance()->ignore(true);
+
+ KSquirrel::app()->saveLayout();
+
+ m_selected = -1;
+ m_width = stack->width();
+ stack->hide();
+ setFixedWidth(mt->width());
+ }
+}
+
+void SQ_MultiBar::updateLayout()
+{
+ setFixedWidth(mt->sizeHint().width());
+ stack->hide();
+}
+
+#include "sq_multibar.moc"
diff --git a/src/sidebar/sq_multibar.h b/src/sidebar/sq_multibar.h
new file mode 100644
index 0000000..12ce455
--- /dev/null
+++ b/src/sidebar/sq_multibar.h
@@ -0,0 +1,111 @@
+/***************************************************************************
+ sq_multibar.h - description
+ -------------------
+ begin : ??? Nov 28 2005
+ copyright : (C) 2005 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SQ_MULTIBAR_H
+#define SQ_MULTIBAR_H
+
+#include <tqhbox.h>
+
+class KMultiTabBar;
+
+class TQWidgetStack;
+class TQSignalMapper;
+
+/*
+ * Konqueror-like sidebar.
+ *
+ * +----------------------------------> KMultiTabBar, only contains buttons
+ * | +-----------------+
+ * | | |
+ * | | |
+ * +------------------------+ |
+ * | 1 | | +----> TQWidgetStack, contains all widgets
+ * |---| |
+ * | 2 | |
+ * |---| |
+ * | 3 | |
+ * |---| |
+ * | | visible page |
+ * | | |
+ * | 4 | N4 |
+ * | | |
+ * | | |
+ * |---| |
+ * | | |
+ * | | |
+ * | | |
+ * | | |
+ * +------------------------+
+ *
+ */
+
+class SQ_MultiBar : public TQHBox
+{
+ TQ_OBJECT
+
+
+ public:
+ SQ_MultiBar(TQWidget *parent = 0, const char *name = 0);
+ ~SQ_MultiBar();
+
+ /*
+ * Add new widget with text label 'text' and icon 'icon'. SQ_MultiBar
+ * will use SQ_IconLoader to load given icon.
+ */
+ void addWidget(TQWidget *new_w, const TQString &text, const TQString &icon);
+
+ /*
+ * Current page index. 0 means first page.
+ */
+ int currentPage();
+
+ void updateLayout();
+
+ KMultiTabBar* multiBar() const;
+
+ static SQ_MultiBar* instance() { return m_inst; }
+
+ public slots:
+
+ /*
+ * Hide current widget and show a widget with
+ * id 'id'.
+ */
+ void raiseWidget(int id);
+
+ private:
+ KMultiTabBar *mt;
+ TQWidgetStack *stack;
+ int m_id, m_selected, m_width;
+ TQSignalMapper *mapper;
+
+ static SQ_MultiBar *m_inst;
+};
+
+inline
+int SQ_MultiBar::currentPage()
+{
+ return m_selected;
+}
+
+inline
+KMultiTabBar* SQ_MultiBar::multiBar() const
+{
+ return mt;
+}
+
+#endif
diff --git a/src/sidebar/sq_previewwidget.cpp b/src/sidebar/sq_previewwidget.cpp
new file mode 100644
index 0000000..ca9f668
--- /dev/null
+++ b/src/sidebar/sq_previewwidget.cpp
@@ -0,0 +1,364 @@
+/***************************************************************************
+ sq_previewwidget.cpp - description
+ -------------------
+ begin : ??? Mar 13 2007
+ copyright : (C) 2007 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tqsize.h>
+#include <tqimage.h>
+#include <tqpainter.h>
+
+#include <tdelocale.h>
+#include <tdefileitem.h>
+#include <tdepopupmenu.h>
+#include <kcolordialog.h>
+#include <tdeio/global.h>
+
+#include <ksquirrel-libs/fmt_defs.h>
+
+#include "ksquirrel.h"
+#include "sq_previewwidget.h"
+#include "sq_iconloader.h"
+#include "sq_imageloader.h"
+#include "sq_libraryhandler.h"
+#include "sq_config.h"
+#include "sq_downloader.h"
+#include "sq_utils.h"
+
+#ifdef SQ_HAVE_KEXIF
+#include <libkexif/kexifdata.h>
+#include <algorithm>
+#include "sq_utils.h"
+#endif
+
+SQ_PreviewWidget * SQ_PreviewWidget::m_inst = 0;
+
+SQ_PreviewWidget::SQ_PreviewWidget(TQWidget *parent, const char *name)
+ : TQWidget(parent, name, TQt::WNoAutoErase), all(0), small(0), m_ignore(true)
+{
+ m_inst = this;
+
+ rereadColor();
+
+ down = new SQ_Downloader(this);
+ connect(down, TQ_SIGNAL(result(const KURL &)), this, TQ_SLOT(slotDownloadResult(const KURL &)));
+ connect(down, TQ_SIGNAL(percents(int)), this, TQ_SLOT(slotDownloadPercents(int)));
+
+ popup = new TDEPopupMenu;
+ popup->insertItem(i18n("Background color..."), this, TQ_SLOT(slotBackground()));
+ popup->insertItem(i18n("Text color..."), this, TQ_SLOT(slotText()));
+ popup->insertSeparator();
+ popup->insertItem(i18n("Go to first image")+"\tHome", this, TQ_SIGNAL(first()));
+ popup->insertItem(i18n("Next image")+"\tSpace", this, TQ_SIGNAL(next()));
+ popup->insertItem(i18n("Previous image")+"\tBackSpace", this, TQ_SIGNAL(previous()));
+ popup->insertItem(i18n("Go to last image")+"\tEnd", this, TQ_SIGNAL(last()));
+ popup->insertSeparator();
+ popup->insertItem(i18n("Execute")+"\tEnter", this, TQ_SIGNAL(execute()));
+
+ multi_pix = SQ_IconLoader::instance()->loadIcon("application-vnd.tde.tdemultiple", TDEIcon::Desktop, TDEIcon::SizeSmall);
+
+ setMinimumHeight(20);
+ setFocusPolicy(TQWidget::WheelFocus);
+}
+
+SQ_PreviewWidget::~SQ_PreviewWidget()
+{
+ delete popup;
+ delete small;
+ delete all;
+}
+
+void SQ_PreviewWidget::load(const KURL &_url)
+{
+ if(SQ_LibraryHandler::instance()->maybeSupported(_url) == SQ_LibraryHandler::No)
+ return;
+
+ if(!percentString.isEmpty())
+ {
+ percentString = TQString();
+ update();
+ }
+
+ down->kill();
+
+ if(m_forceignore || m_ignore)
+ {
+ pending = m_url = _url;
+ return;
+ }
+ else
+ pending = KURL();
+
+ m_url = _url;
+
+ if(m_url.isLocalFile())
+ slotDownloadResult(m_url);
+ else
+ {
+ KFileItem fi(KFileItem::Unknown, KFileItem::Unknown, m_url);
+ down->start(&fi);
+ }
+}
+
+void SQ_PreviewWidget::fitAndConvert()
+{
+ if(!m_ignore && fit())
+ pixmap.convertFromImage(small?*small:*all);
+}
+
+void SQ_PreviewWidget::resizeEvent(TQResizeEvent *)
+{
+ fitAndConvert();
+}
+
+void SQ_PreviewWidget::paintEvent(TQPaintEvent *)
+{
+ TQPainter p(this);
+
+ p.fillRect(rect(), color);
+
+ int x = 4;
+
+ if(!percentString.isEmpty())
+ {
+ TQFont fnt = p.font();
+ fnt.setBold(true);
+ p.setFont(fnt);
+ p.setPen(colorText);
+ p.drawText(x, 4, width(), height(), TQt::AlignLeft, percentString);
+ }
+
+ if(!m_ignore && !pixmap.isNull())
+ {
+ p.drawPixmap((width() - pixmap.width()) / 2, (height() - pixmap.height()) / 2, pixmap);
+
+ if(multi)
+ {
+ x = x + multi_pix.width() + 4;
+ p.drawPixmap(4, 4, multi_pix);
+ }
+
+ if(dim)
+ {
+ TQFont fnt = p.font();
+ fnt.setBold(true);
+ p.setFont(fnt);
+ p.setPen(colorText);
+ p.drawText(x, 4, width(), height(), TQt::AlignLeft, dimstring);
+ }
+ }
+}
+
+bool SQ_PreviewWidget::fit()
+{
+ if(!all)
+ return false;
+
+ // image is bigger than preview widget -
+ // scale it down
+ if(width() < 2 || height() < 2)
+ return false;
+
+ delete small;
+ small = 0;
+
+ if(all->width() > width() || all->height() > height())
+ {
+ small = new TQImage();
+
+ *small = SQ_Utils::scale(*all, width(), height(), SQ_Utils::SMOOTH_FAST, TQImage::ScaleMin);
+ }
+
+ return true;
+}
+
+void SQ_PreviewWidget::saveValues()
+{
+ SQ_Config::instance()->setGroup("Sidebar");
+ SQ_Config::instance()->writeEntry("preview_background", color.name());
+ SQ_Config::instance()->writeEntry("preview_text", colorText.name());
+}
+
+void SQ_PreviewWidget::rereadColor()
+{
+ SQ_Config::instance()->setGroup("Sidebar");
+ bool b = SQ_Config::instance()->readBoolEntry("preview", true);
+ m_forceignore = !b;
+ setShown(b);
+ color.setNamedColor(SQ_Config::instance()->readEntry("preview_background", "#4e4e4e"));
+ dim = SQ_Config::instance()->readBoolEntry("preview_text_enable", true);
+ colorText.setNamedColor(SQ_Config::instance()->readEntry("preview_text", "#ffffff"));
+ m_delay = SQ_Config::instance()->readNumEntry("preview_delay", 400);
+ m_cancel = SQ_Config::instance()->readBoolEntry("preview_dont", true);
+
+ if(m_delay < 50 || m_delay > 2000)
+ m_delay = 400;
+}
+
+
+void SQ_PreviewWidget::slotBackground()
+{
+ KColorDialog dlg(KSquirrel::app(), 0, true);
+
+ dlg.setColor(color);
+
+ if(dlg.exec() == TQDialog::Accepted)
+ {
+ color = dlg.color();
+ saveValues();
+ update();
+ }
+}
+
+void SQ_PreviewWidget::slotText()
+{
+ KColorDialog dlg(KSquirrel::app(), 0, true);
+
+ dlg.setColor(colorText);
+
+ if(dlg.exec() == TQDialog::Accepted)
+ {
+ colorText = dlg.color();
+ saveValues();
+ update();
+ }
+}
+
+void SQ_PreviewWidget::mousePressEvent(TQMouseEvent *e)
+{
+ e->accept();
+
+ if(e->button() == TQt::RightButton)
+ popup->exec(e->globalPos());
+}
+
+void SQ_PreviewWidget::loadPending()
+{
+ if(pending.isValid())
+ {
+ KURL tmp = pending;
+ load(tmp);
+ }
+}
+
+void SQ_PreviewWidget::slotDownloadResult(const KURL &url)
+{
+ percentString = TQString();
+ TQString path = url.path();
+ fmt_info *finfo;
+ RGBA *bits;
+
+ // load first page
+ bool b = SQ_ImageLoader::instance()->loadImage(path, SQ_CodecSettings::ImageViewer, true, 2);
+
+ finfo = SQ_ImageLoader::instance()->info();
+ bits = SQ_ImageLoader::instance()->bits();
+
+ // memory allocation failed in SQ_ImageLoader::loadImage()
+ if(!b || !bits || !finfo->image.size())
+ return;
+
+ delete small;
+ delete all;
+ all = small = 0;
+ pixmap = TQPixmap();
+
+ int w = finfo->image[0].w;
+ int h = finfo->image[0].h;
+ dimstring = TQString::fromLatin1("%1x%2").arg(w).arg(h);
+
+ const int wh = w * h;
+ unsigned char t;
+
+ for(int i = 0;i < wh;i++)
+ {
+ t = (bits+i)->r;
+ (bits+i)->r = (bits+i)->b;
+ (bits+i)->b = t;
+ }
+
+ all = new TQImage((uchar *)bits, w, h, 32, 0, 0, TQImage::LittleEndian);
+ all->setAlphaBuffer(true);
+
+#ifdef SQ_HAVE_KEXIF
+ KExifData data;
+ data.readFromFile(path);
+ int O = data.getImageQt::Orientation();
+
+ if(O != KExifData::UNSPECIFIED && O != KExifData::NORMAL)
+ {
+ // copy original image
+ TQImage img = *all;
+
+ // rotate image
+ SQ_Utils::exifRotate(TQString(), img, O);
+
+ // transfer back
+ *all = img;
+ }
+ else
+#endif
+ *all = all->copy();
+
+ multi = finfo->image.size() > 1;
+
+ SQ_ImageLoader::instance()->cleanup();
+
+ fitAndConvert();
+ update();
+}
+
+void SQ_PreviewWidget::keyPressEvent(TQKeyEvent *e)
+{
+ e->accept();
+
+ int key = e->key();
+
+ if(key == TQt::Key_PageDown || key == TQt::Key_Space)
+ emit next();
+ else if(key == TQt::Key_PageUp || key == TQt::Key_BackSpace)
+ emit previous();
+ else if(key == TQt::Key_Return || key == TQt::Key_Enter)
+ emit execute();
+ else if(key == TQt::Key_Home)
+ emit first();
+ else if(key == TQt::Key_End)
+ emit last();
+}
+
+void SQ_PreviewWidget::wheelEvent(TQWheelEvent *e)
+{
+ if(e->delta() < 0)
+ emit next();
+ else
+ emit previous();
+}
+
+void SQ_PreviewWidget::mouseDoubleClickEvent(TQMouseEvent *e)
+{
+ e->accept();
+ emit execute();
+}
+
+void SQ_PreviewWidget::slotDownloadPercents(int p)
+{
+ percentString = i18n("Downloading...") + ' ' + TDEIO::convertSize(p);
+ update();
+}
+
+#include "sq_previewwidget.moc"
diff --git a/src/sidebar/sq_previewwidget.h b/src/sidebar/sq_previewwidget.h
new file mode 100644
index 0000000..25e8c37
--- /dev/null
+++ b/src/sidebar/sq_previewwidget.h
@@ -0,0 +1,132 @@
+/***************************************************************************
+ sq_previewwidget.h - description
+ -------------------
+ begin : ??? Mar 13 2007
+ copyright : (C) 2007 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SQ_PREVIEWWIDGET_H
+#define SQ_PREVIEWWIDGET_H
+
+#include <tqwidget.h>
+#include <tqpixmap.h>
+#include <tqcolor.h>
+#include <tqwmatrix.h>
+#include <tqimage.h>
+
+#include <kurl.h>
+
+class TDEPopupMenu;
+
+class SQ_Downloader;
+
+/**
+ *@author Baryshev Dmitry
+ */
+
+class SQ_PreviewWidget : public TQWidget
+{
+ TQ_OBJECT
+
+
+ public:
+ SQ_PreviewWidget(TQWidget *parent = 0, const char *name = 0);
+ ~SQ_PreviewWidget();
+
+ void rereadColor();
+
+ void load(const KURL &url);
+
+ void ignore(bool ign);
+
+ void loadPending();
+
+ static SQ_PreviewWidget* instance() { return m_inst; }
+
+ int delay() const;
+
+ bool cancel() const;
+
+ KURL url() const;
+
+ private:
+ void saveValues();
+
+ signals:
+ void next();
+ void previous();
+ void execute();
+ void first();
+ void last();
+
+ private slots:
+ void slotBackground();
+ void slotText();
+ void slotDownloadResult(const KURL &);
+ void slotDownloadPercents(int);
+
+ protected:
+ virtual void resizeEvent(TQResizeEvent *);
+ virtual void paintEvent(TQPaintEvent *);
+ virtual void mousePressEvent(TQMouseEvent *e);
+ virtual void keyPressEvent(TQKeyEvent *e);
+ virtual void wheelEvent(TQWheelEvent *e);
+ virtual void mouseDoubleClickEvent(TQMouseEvent *e);
+
+ private:
+ bool fit();
+ void fitAndConvert();
+
+ private:
+ TQImage *all, *small;
+ TQPixmap pixmap;
+ bool m_ignore, m_forceignore, m_cancel;
+ TQColor color, colorText;
+ TDEPopupMenu *popup;
+ KURL pending, m_url;
+ int m_delay;
+ TQWMatrix matrix;
+ SQ_Downloader *down;
+ bool multi;
+ TQPixmap multi_pix;
+ TQString dimstring, percentString;
+ bool dim;
+
+ static SQ_PreviewWidget *m_inst;
+};
+
+inline
+void SQ_PreviewWidget::ignore(bool ign)
+{
+ m_ignore = ign;
+}
+
+inline
+int SQ_PreviewWidget::delay() const
+{
+ return m_delay;
+}
+
+inline
+bool SQ_PreviewWidget::cancel() const
+{
+ return m_cancel;
+}
+
+inline
+KURL SQ_PreviewWidget::url() const
+{
+ return m_url;
+}
+
+#endif
diff --git a/src/sidebar/sq_storagefile.cpp b/src/sidebar/sq_storagefile.cpp
new file mode 100644
index 0000000..cf41122
--- /dev/null
+++ b/src/sidebar/sq_storagefile.cpp
@@ -0,0 +1,76 @@
+/***************************************************************************
+ sq_storagefile.cpp - description
+ -------------------
+ begin : Sat Mar 3 2007
+ copyright : (C) 2007 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <tqfile.h>
+#include <tqcstring.h>
+#include <tqstring.h>
+
+#include <kmdcodec.h>
+
+#include "sq_storagefile.h"
+
+void SQ_StorageFile::writeStorageFile(const TQString &path, const KURL &inpath, KURL w)
+{
+ SQ_StorageFile::writeStorageFileAsString(path, inpath, w.prettyURL());
+}
+
+void SQ_StorageFile::writeStorageFileAsString(const TQString &path, const KURL &inpath, TQString content)
+{
+ if(content.isEmpty())
+ content = inpath.prettyURL();
+
+ KMD5 md5(TQFile::encodeName(inpath.prettyURL()).data());
+ TQFile file(path + TQString::fromLatin1(".") + TQString(md5.hexDigest()));
+
+ if(file.open(IO_WriteOnly))
+ {
+ TQCString k = content.local8Bit();
+ file.writeBlock(k, k.length());
+ file.close();
+ }
+}
+
+KURL SQ_StorageFile::readStorageFile(const TQString &path)
+{
+ TQString n = SQ_StorageFile::readStorageFileAsString(path);
+
+ int ind = n.find('\n');
+
+ if(ind != -1)
+ n.truncate(ind);
+
+ return KURL::fromPathOrURL(n);
+}
+
+TQString SQ_StorageFile::readStorageFileAsString(const TQString &path)
+{
+ TQFile file(path);
+ TQString str;
+
+ if(file.open(IO_ReadOnly))
+ {
+ TQByteArray ba = file.readAll();
+ if(file.status() == IO_Ok)
+ {
+ str.append(ba);
+ }
+ }
+
+ file.close();
+
+ return str;
+}
diff --git a/src/sidebar/sq_storagefile.h b/src/sidebar/sq_storagefile.h
new file mode 100644
index 0000000..6e0b8c4
--- /dev/null
+++ b/src/sidebar/sq_storagefile.h
@@ -0,0 +1,34 @@
+/***************************************************************************
+ sq_storagefile.h - description
+ -------------------
+ begin : Sat Mar 3 2007
+ copyright : (C) 2007 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SQ_STORAGEFILE_H
+#define SQ_STORAGEFILE_H
+
+#include <tqstring.h>
+
+#include <kurl.h>
+
+namespace SQ_StorageFile
+{
+ void writeStorageFile(const TQString &path, const KURL &inpath, KURL w = KURL());
+ void writeStorageFileAsString(const TQString &path, const KURL &inpath, TQString content = TQString());
+
+ KURL readStorageFile(const TQString &path);
+ TQString readStorageFileAsString(const TQString &path);
+};
+
+#endif
diff --git a/src/sidebar/sq_threaddirlister.cpp b/src/sidebar/sq_threaddirlister.cpp
new file mode 100644
index 0000000..9c6610f
--- /dev/null
+++ b/src/sidebar/sq_threaddirlister.cpp
@@ -0,0 +1,145 @@
+/***************************************************************************
+ sq_threaddirlister.cpp - description
+ -------------------
+ begin : Feb 10 2007
+ copyright : (C) 2007 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tqfile.h>
+#include <tqdir.h>
+#include <tqobject.h>
+#include <tqfileinfo.h>
+#include <tqdatetime.h>
+#include <tqapplication.h>
+
+#include <tdeconfig.h>
+#include <tdeglobal.h>
+
+#include "sq_threaddirlister.h"
+
+SQ_ThreadDirLister::SQ_ThreadDirLister(TQObject *o)
+ : TQThread(), obj(o)
+{
+ cache = new TDEConfig("ksquirrel-tree-cache");
+ dir = 0;
+}
+
+SQ_ThreadDirLister::~SQ_ThreadDirLister()
+{
+ // sync() & delete
+ delete cache;
+}
+
+void SQ_ThreadDirLister::run()
+{
+ KURL url;
+ TQString path, name, filepath;
+ dirent *file;
+ int count_files, count_dirs;
+ TQDateTime dt, dt_def;
+ TQFileInfo fi;
+ bool b_read;
+
+ static const TQString &dot = TDEGlobal::staticQString(".");
+ static const TQString &dotdot = TDEGlobal::staticQString("..");
+
+ while(true)
+ {
+ waitMutex();
+ count_files = todo.count();
+ unlock();
+
+ if(!count_files) break;
+
+ waitMutex();
+ url = todo.first();
+ unlock();
+
+ path = url.path();
+ count_files = count_dirs = 0;
+ b_read = true;
+ fi.setFile(path);
+
+ if(cache->hasGroup(path))
+ {
+ cache->setGroup(path);
+ dt = cache->readDateTimeEntry("modified", &dt_def);
+
+ // compare cached time and real time
+ if(dt.isValid() && fi.lastModified() == dt)
+ {
+ count_files = cache->readNumEntry("count_files", 0);
+ count_dirs = cache->readNumEntry("count_dirs", 0);
+ b_read = false;
+ }
+ }
+
+ if(b_read)
+ {
+ dir = opendir(TQFile::encodeName(path));
+ dt = fi.lastModified(); // save directory last modified time
+
+ if(dir)
+ {
+ while((file = readdir(dir)))
+ {
+ name = TQFile::decodeName(file->d_name);
+
+ if(name != dot && name != dotdot)
+ {
+ filepath = path + TQDir::separator() + name;
+
+ fi.setFile(filepath);
+
+ if(fi.isDir())
+ count_dirs++;
+ else
+ count_files++;
+ }
+ }
+
+ closeDir();
+ }
+ else // opendir() failed, this value won't be cached
+ b_read = false;
+ }
+
+ waitMutex();
+ todo.pop_front();
+ unlock();
+
+ // cache only new values
+ if(b_read)
+ {
+ cache->setGroup(path);
+ cache->writeEntry("modified", dt);
+ cache->writeEntry("count_files", count_files);
+ cache->writeEntry("count_dirs", count_dirs);
+ }
+
+ TQApplication::postEvent(obj, new SQ_ItemsEvent(url, count_files, count_dirs));
+ }// while
+}
+
+void SQ_ThreadDirLister::closeDir()
+{
+ if(dir)
+ {
+ closedir(dir);
+ dir = 0;
+ }
+}
diff --git a/src/sidebar/sq_threaddirlister.h b/src/sidebar/sq_threaddirlister.h
new file mode 100644
index 0000000..7aa58fc
--- /dev/null
+++ b/src/sidebar/sq_threaddirlister.h
@@ -0,0 +1,153 @@
+/***************************************************************************
+ sq_threaddirlister.h - description
+ -------------------
+ begin : Feb 10 2007
+ copyright : (C) 2007 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#ifndef SQ_THREADDIRLISTER_H
+#define SQ_THREADDIRLISTER_H
+
+#include <tqthread.h>
+#include <tqevent.h>
+#include <tqmutex.h>
+
+#include <kurl.h>
+
+#include <sys/types.h>
+#include <dirent.h>
+
+class TQObject;
+
+class TDEConfig;
+
+/********************************************************/
+
+#define SQ_ItemsEventId (TQEvent::User + 1)
+
+class SQ_ItemsEvent : public TQCustomEvent
+{
+ public:
+ SQ_ItemsEvent(const KURL &parent, int c1, int c2)
+ : TQCustomEvent(SQ_ItemsEventId), m_files(c1), m_dirs(c2), m_url(parent)
+ {}
+
+ int files() const;
+ int dirs() const;
+
+ KURL url() const;
+
+ private:
+ int m_files, m_dirs;
+ KURL m_url;
+};
+
+inline
+KURL SQ_ItemsEvent::url() const
+{
+ return m_url;
+}
+
+inline
+int SQ_ItemsEvent::files() const
+{
+ return m_files;
+}
+
+inline
+int SQ_ItemsEvent::dirs() const
+{
+ return m_dirs;
+}
+
+/********************************************************/
+
+/*
+ * This thread will read directory and determine
+ * number of files in it. Finally
+ * it will post an event to main thread with
+ * calculated count. This function is threaded
+ * due to perfomance reason.
+ */
+class SQ_ThreadDirLister : public TQThread
+{
+ public:
+ SQ_ThreadDirLister(TQObject *o);
+ ~SQ_ThreadDirLister();
+
+ void appendURL(const KURL &url);
+
+ bool hasURL(const KURL &url);
+ bool isCurrent(const KURL &url);
+
+ void lock();
+ void unlock();
+
+ void closeDir();
+
+ protected:
+ virtual void run();
+
+ private:
+ void waitMutex();
+
+ private:
+ // urls to read
+ KURL::List todo;
+
+ // this object will recieve our events
+ TQObject *obj;
+ TQMutex mutex;
+ TDEConfig *cache;
+ DIR *dir;
+};
+
+inline
+void SQ_ThreadDirLister::appendURL(const KURL &url)
+{
+ todo.append(url);
+}
+
+inline
+bool SQ_ThreadDirLister::hasURL(const KURL &url)
+{
+ return todo.find(url) != todo.end();
+}
+
+inline
+bool SQ_ThreadDirLister::isCurrent(const KURL &url)
+{
+ return todo.first().equals(url, true);
+}
+
+inline
+void SQ_ThreadDirLister::lock()
+{
+ mutex.lock();
+}
+
+inline
+void SQ_ThreadDirLister::unlock()
+{
+ mutex.unlock();
+}
+
+inline
+void SQ_ThreadDirLister::waitMutex()
+{
+ while(!mutex.tryLock())
+ TQThread::msleep(1);
+}
+
+#endif
diff --git a/src/sidebar/sq_treeview.cpp b/src/sidebar/sq_treeview.cpp
new file mode 100644
index 0000000..22207a9
--- /dev/null
+++ b/src/sidebar/sq_treeview.cpp
@@ -0,0 +1,678 @@
+/***************************************************************************
+ sq_treeview.cpp - description
+ -------------------
+ begin : Mon Mar 15 2004
+ copyright : (C) 2004 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tqdir.h>
+#include <tqheader.h>
+#include <tqtimer.h>
+#include <tqcursor.h>
+
+#include <tdelocale.h>
+#include <kurldrag.h>
+#include <kurl.h>
+#include <kdirwatch.h>
+
+#include "ksquirrel.h"
+#include "sq_iconloader.h"
+#include "sq_widgetstack.h"
+#include "sq_filethumbview.h"
+#include "sq_config.h"
+#include "sq_treeview.h"
+#include "sq_treeviewitem.h"
+#include "sq_threaddirlister.h"
+#include "sq_navigatordropmenu.h"
+#include "sq_treeviewmenu.h"
+#include "sq_hloptions.h"
+
+#include "sq_directorybasket.h"
+
+SQ_TreeView * SQ_TreeView::m_instance = 0;
+
+SQ_FileTreeViewBranch::SQ_FileTreeViewBranch(KFileTreeView *parent, const KURL &url,
+ const TQString &name, const TQPixmap &pix) : KFileTreeBranch(parent, url, name, pix)
+{}
+
+SQ_FileTreeViewBranch::~SQ_FileTreeViewBranch()
+{}
+
+KFileTreeViewItem* SQ_FileTreeViewBranch::createTreeViewItem(KFileTreeViewItem *parent, KFileItem *fileItem)
+{
+ KFileTreeViewItem *tvi = 0;
+
+ if(parent && fileItem)
+ tvi = new SQ_TreeViewItem(parent, fileItem, this);
+
+ return tvi;
+}
+
+/******************************************************************************************************/
+
+SQ_TreeView::SQ_TreeView(TQWidget *parent, const char *name) : KFileTreeView(parent, name)
+{
+ m_instance = this;
+
+ itemToBeOpened = 0;
+ m_animTimer = new TQTimer(this);
+ scanTimer = new TQTimer(this);
+ m_ignoreClick = false;
+
+ connect(m_animTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotAnimation()));
+ connect(scanTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotDelayedScan()));
+
+ dw = 0;
+ m_recurs = No;
+ lister = new SQ_ThreadDirLister(this);
+ setupRecursion();
+
+ setFrameShape(TQFrame::NoFrame);
+ addColumn("Name");
+ addColumn("Check");
+
+ header()->hide();
+ header()->moveSection(1, 0);
+ setColumnWidthMode(1, TQListView::Manual);
+ setColumnWidth(1, 18);
+
+ root = new SQ_FileTreeViewBranch(this, TQDir::rootDirPath(), TQString(),
+ SQ_IconLoader::instance()->loadIcon("folder_red", TDEIcon::Desktop, TDEIcon::SizeSmall));
+
+ // some hacks to create our SQ_TreeViewItem as root item
+ SQ_TreeViewItem *ritem = new SQ_TreeViewItem(this,
+ new KFileItem(TQDir::rootDirPath(),
+ "inode/directory", S_IFDIR),
+ root);
+
+ ritem->setText(0, i18n("root"));
+ ritem->setExpandable(true);
+
+ // oops :)
+ delete root->root();
+
+ // set new root
+ root->setRoot(ritem);
+
+ addBranch(root);
+
+ // don't show files
+ setDirOnlyMode(root, true);
+
+ // show '+'
+ setRootIsDecorated(true);
+
+ // connect signals
+
+ // Space and Return will open item
+ connect(this, TQ_SIGNAL(spacePressed(TQListViewItem*)), this, TQ_SIGNAL(executed(TQListViewItem*)));
+ connect(this, TQ_SIGNAL(returnPressed(TQListViewItem*)), this, TQ_SIGNAL(executed(TQListViewItem*)));
+ connect(this, TQ_SIGNAL(currentChanged(TQListViewItem *)), this, TQ_SLOT(slotCurrentChanged(TQListViewItem*)));
+
+ connect(this, TQ_SIGNAL(executed(TQListViewItem*)), this, TQ_SLOT(slotItemExecuted(TQListViewItem*)));
+ connect(this, TQ_SIGNAL(newURL(const KURL&)), this, TQ_SLOT(slotNewURL(const KURL&)));
+ connect(root, TQ_SIGNAL(populateFinished(KFileTreeViewItem *)), this, TQ_SLOT(slotOpened(KFileTreeViewItem *)));
+ connect(root, TQ_SIGNAL(deleteItem(KFileItem *)), this, TQ_SLOT(slotDeleteItemMy(KFileItem *)));
+
+ setCurrentItem(root->root());
+ root->setChildRecurse(false);
+
+ SQ_Config::instance()->setGroup("Fileview");
+ int sync_type = SQ_Config::instance()->readNumEntry("sync type", 0);
+
+ // load url, if needed
+ if(sync_type != 1)
+ emitNewURL(SQ_WidgetStack::instance()->url());
+
+ setAcceptDrops(true);
+
+ connect(this, TQ_SIGNAL(dropped(TQDropEvent *, TQListViewItem *, TQListViewItem *)),
+ this, TQ_SLOT(slotDropped(TQDropEvent *, TQListViewItem *, TQListViewItem *)));
+
+ connect(this, TQ_SIGNAL(contextMenu(TDEListView *, TQListViewItem *, const TQPoint &)),
+ this, TQ_SLOT(slotContextMenu(TDEListView *, TQListViewItem *, const TQPoint &)));
+
+ menu = new SQ_TreeViewMenu(this);
+
+ if(SQ_HLOptions::instance()->have_directorybasket)
+ {
+ menu->insertSeparator();
+ menu->insertItem(i18n("Add to Folder Basket"), this, TQ_SLOT(slotAddToFolderBasket()));
+ }
+}
+
+SQ_TreeView::~SQ_TreeView()
+{
+ lister->terminate();
+ lister->wait();
+
+ delete lister;
+}
+
+void SQ_TreeView::slotCurrentChanged(TQListViewItem *item)
+{
+ SQ_TreeViewItem *tvi = static_cast<SQ_TreeViewItem *>(item);
+
+ if(tvi) cURL = tvi->url();
+}
+
+void SQ_TreeView::setRecursion(int b)
+{
+ // avoid duplicate calls
+ if(m_recurs == b)
+ return;
+
+ TQListViewItemIterator it(this);
+ SQ_TreeViewItem *tvi;
+
+ // ignore root item
+ ++it;
+
+ // turn recursion on
+ if(m_recurs == No && b)
+ {
+ dw = new KDirWatch(this);
+ connect(dw, TQ_SIGNAL(dirty(const TQString &)), this, TQ_SLOT(slotDirty(const TQString &)));
+
+ dw->blockSignals(true);
+ lister->lock();
+ while(it.current())
+ {
+ tvi = static_cast<SQ_TreeViewItem *>(it.current());
+
+ if(tvi)
+ {
+ tvi->setParams((m_recurs == Files || m_recurs == FilesDirs),
+ (m_recurs == Dirs || m_recurs == FilesDirs));
+
+ lister->appendURL(tvi->url());
+ dw->addDir(tvi->path());
+ }
+
+ ++it;
+ }
+ lister->unlock();
+ dw->blockSignals(false);
+
+ m_recurs = b;
+
+ if(!lister->running())
+ scanTimer->start(1, true);
+ }
+ // turn recursion off
+ else
+ {
+ delete dw;
+ dw = 0;
+
+ m_recurs = b;
+ while(it.current())
+ {
+ tvi = static_cast<SQ_TreeViewItem *>(it.current());
+
+ // reset item names
+ if(tvi)
+ {
+ tvi->setParams((m_recurs == Files || m_recurs == FilesDirs),
+ (m_recurs == Dirs || m_recurs == FilesDirs));
+ tvi->setCount(tvi->files(), tvi->dirs());
+ }
+
+ ++it;
+ }
+ }
+}
+
+void SQ_TreeView::slotClearChecked()
+{
+ TQListViewItemIterator it(this);
+ SQ_TreeViewItem *tvi;
+
+ while(it.current())
+ {
+ tvi = static_cast<SQ_TreeViewItem *>(it.current());
+
+ if(tvi && tvi->checked())
+ tvi->setChecked(false);
+
+ ++it;
+ }
+}
+
+/*
+ * Item executed. Let's pass its url to SQ_WidgetStack (if needed).
+ */
+void SQ_TreeView::slotItemExecuted(TQListViewItem *item)
+{
+ if(!item) return;
+
+ item->setOpen(true);
+
+ SQ_Config::instance()->setGroup("Fileview");
+ int sync_type = SQ_Config::instance()->readNumEntry("sync type", 0);
+
+ // current sychronization type doesn't require
+ // passing url to SQ_WidgetStack - return
+ if(sync_type == 1)
+ return;
+
+ KFileTreeViewItem *cur = static_cast<KFileTreeViewItem*>(item);
+ KURL Curl = cur->url();
+
+ // pass url to SQ_WidgetStack
+ SQ_WidgetStack::instance()->setURLForCurrent(Curl, false);
+}
+
+void SQ_TreeView::emitNewURL(const KURL &url)
+{
+ // already selected?
+ if(!url.isLocalFile() || url.equals(currentURL(), true) || url.equals(cURL, true))
+ return;
+
+ cURL = url;
+
+ // tree is invisible.
+ // save url for future use
+ if(!isVisible())
+ {
+ pendingURL = url;
+ pendingURL.adjustPath(1);
+ return;
+ }
+ else
+ pendingURL = KURL();
+
+ emit newURL(url);
+}
+
+/*
+ * Set given item visible, current, and populate it.
+ */
+void SQ_TreeView::populateItem(KFileTreeViewItem *item)
+{
+ if(item->url().equals(cURL, true))
+ {
+ setSelected(item, true);
+ setCurrentItem(item);
+
+ // 1/5 of height give above items
+ // 4/5 of height give below items
+ setContentsPos(contentsX(), itemPos(item)-visibleHeight()/5);
+ }
+
+ itemToBeOpened = item;
+ item->setOpen(true);
+}
+
+/*
+ * Load url.
+ */
+void SQ_TreeView::slotNewURL(const KURL &url)
+{
+ KURL k(url);
+ k.adjustPath(1);
+
+ KURL last = k;
+
+ TQString s;
+
+ // divide url to paths.
+ // for example, "/home/krasu/1/2" will be divided to
+ //
+ // "/home/krasu/1/2"
+ // "/home/krasu/1"
+ // "/home/krasu"
+ // "/home"
+ // "/"
+ //
+ while(true)
+ {
+ s = k.path(); // remove "/"
+ s.remove(0, 1);
+
+ paths.prepend(s);
+ k = k.upURL();
+
+ if(k.equals(last, true))
+ break;
+
+ last = k;
+ }
+
+ while(doSearch())
+ {}
+}
+
+/*
+ * New item is opened. Try to continue loading url.
+ */
+void SQ_TreeView::slotOpened(KFileTreeViewItem *item)
+{
+ if(!item) return;
+
+ // continue searhing...
+ if(item == itemToBeOpened)
+ doSearch();
+}
+
+/*
+ * Search first available url in variable 'paths'. Open found item.
+ * If item was found return true.
+ */
+bool SQ_TreeView::doSearch()
+{
+ // all items are opened
+ if(paths.empty())
+ {
+ itemToBeOpened = 0;
+ return false;
+ }
+
+ TQStringList::iterator it = paths.begin();
+
+ KFileTreeViewItem *found = findItem(root, *it);
+
+ // item not found. It means that
+ //
+ // * we loaded all subpaths - nothing to do
+ // * item we needed is not loaded yet. populateItem() _now_ is trying to open
+ // new subpath, and we will continue searching in slotOpened().
+ //
+ if(!found)
+ return false;
+
+ // ok, item is found
+ //
+ // remove first entry from 'paths'
+ // and try to open item
+ paths.erase(it);
+ populateItem(found);
+
+ // done, but subpaths are pending...
+ return true;
+}
+
+/*
+ * On show event load saved url, if any. See emitNewURL().
+ */
+void SQ_TreeView::showEvent(TQShowEvent *)
+{
+ // if pending url is valid
+ if(!pendingURL.isEmpty())
+ {
+ // set pending url to current url
+ KURL url = pendingURL;
+
+ // reset pending url
+ pendingURL = KURL();
+
+ // finally, load url
+ emit newURL(url);
+ }
+}
+
+void SQ_TreeView::slotNewTreeViewItems(KFileTreeBranch *, const KFileTreeViewItemList &list)
+{
+ if(m_recurs == No)
+ return;
+
+// uuuuuuuggggggghhhhhhh :)
+ KFileTreeViewItemListIterator it(list);
+ KFileTreeViewItem *item;
+
+ lister->lock();
+ while((item = it.current()))
+ {
+ lister->appendURL(item->url());
+ dw->addDir(item->path());
+ ++it;
+ }
+ lister->unlock();
+
+ if(!lister->running())
+ scanTimer->start(1, true);
+}
+
+void SQ_TreeView::slotDelayedScan()
+{
+ if(!lister->running())
+ lister->start();
+}
+
+void SQ_TreeView::customEvent(TQCustomEvent *e)
+{
+ if(!e || e->type() != SQ_ItemsEventId)
+ return;
+
+ SQ_ItemsEvent *ie = static_cast<SQ_ItemsEvent *>(e);
+
+ SQ_TreeViewItem *tvi = static_cast<SQ_TreeViewItem *>(root->findTVIByURL(ie->url()));
+
+ if(tvi)
+ {
+ tvi->setParams((m_recurs == Files || m_recurs == FilesDirs),
+ (m_recurs == Dirs || m_recurs == FilesDirs));
+ tvi->setCount(ie->files(), ie->dirs());
+ }
+}
+
+void SQ_TreeView::slotAnimation()
+{
+ KFileTreeViewItem *it = m_mapFolders.first();
+
+ for(;it;it = m_mapFolders.next())
+ it->setPixmap(0, SmallIcon("clock"));
+}
+
+void SQ_TreeView::startAnimation(KFileTreeViewItem *item, const char *, uint)
+{
+ if(!item)
+ return;
+
+ m_mapFolders.append(item);
+
+ if(!m_animTimer->isActive())
+ m_animTimer->start(50, true);
+}
+
+void SQ_TreeView::stopAnimation(KFileTreeViewItem *item)
+{
+ if(!item)
+ return;
+
+ int f = m_mapFolders.find(item);
+
+ if(f != -1)
+ {
+ item->setPixmap(0, itemIcon(item));
+ m_mapFolders.remove(item);
+ }
+
+ m_animTimer->stop();
+}
+
+void SQ_TreeView::viewportResizeEvent(TQResizeEvent *)
+{
+ setColumnWidth(0, viewport()->width() - columnWidth(1));
+ triggerUpdate();
+}
+
+void SQ_TreeView::clearSelection()
+{
+ if(!m_ignoreClick) KFileTreeView::clearSelection();
+}
+
+void SQ_TreeView::setSelected(TQListViewItem *item, bool selected)
+{
+ if(!m_ignoreClick) KFileTreeView::setSelected(item, selected);
+}
+
+void SQ_TreeView::setCurrentItem(TQListViewItem *item)
+{
+ if(!m_ignoreClick) KFileTreeView::setCurrentItem(item);
+}
+
+void SQ_TreeView::setOpen(TQListViewItem *item, bool open)
+{
+ if(!m_ignoreClick) KFileTreeView::setOpen(item, open);
+}
+
+void SQ_TreeView::contentsMousePressEvent(TQMouseEvent *e)
+{
+ TQListViewItem *item;
+
+ TQPoint point = e->pos();
+ point.setY(point.y() - contentsY());
+
+ if(header()->sectionAt(point.x()) && (item = itemAt(point)))
+ {
+ SQ_TreeViewItem *m = static_cast<SQ_TreeViewItem *>(item);
+
+ if(m)
+ {
+ int state = e->state();
+
+ if(!state)
+ toggle(m, true);
+ else
+ {
+ TQListViewItemIterator it(this);
+
+ // toggle parent item
+ if(state == TQt::ShiftButton) toggle(m, true);
+ else if(state == TQt::ControlButton) toggle(m, false, true);
+ else if(state == TQt::AltButton) toggle(m, false, false);
+
+ SQ_TreeViewItem *tvi = static_cast<SQ_TreeViewItem *>(m->firstChild());
+
+ // toggle all child items
+ while(tvi)
+ {
+ if(state == TQt::ShiftButton) toggle(tvi, false, m->checked());
+ else if(state == TQt::ControlButton) toggle(tvi, false, true);
+ else if(state == TQt::AltButton) toggle(tvi, false, false);
+
+ tvi = static_cast<SQ_TreeViewItem *>(tvi->nextSibling());
+ }
+ }
+ }
+
+ m_ignoreClick = true;
+ }
+
+ KFileTreeView::contentsMousePressEvent(e);
+
+ m_ignoreClick = false;
+}
+
+void SQ_TreeView::contentsMouseDoubleClickEvent(TQMouseEvent *e)
+{
+ if(header()->sectionAt(e->x()))
+ m_ignoreClick = true;
+
+ KFileTreeView::contentsMouseDoubleClickEvent(e);
+
+ m_ignoreClick = false;
+}
+
+void SQ_TreeView::setupRecursion()
+{
+ SQ_Config::instance()->setGroup("Sidebar");
+
+ setRecursion(SQ_Config::instance()->readNumEntry("recursion_type", No));
+}
+
+void SQ_TreeView::toggle(SQ_TreeViewItem *item, bool togg, bool set)
+{
+ if(togg)
+ item->setChecked(!item->checked());
+ else
+ item->setChecked(set);
+
+ if(item->checked())
+ emit urlAdded(item->url());
+ else
+ emit urlRemoved(item->url());
+}
+
+void SQ_TreeView::slotDropped(TQDropEvent *e, TQListViewItem *parent, TQListViewItem *item)
+{
+ if(!item) item = parent;
+
+ KFileTreeViewItem *cur = static_cast<KFileTreeViewItem *>(item);
+
+ if(!cur) return;
+
+ KURL::List list;
+ KURLDrag::decode(e, list);
+
+ SQ_NavigatorDropMenu::instance()->setupFiles(list, cur->url());
+ SQ_NavigatorDropMenu::instance()->exec(TQCursor::pos(), true);
+}
+
+void SQ_TreeView::slotContextMenu(TDEListView *, TQListViewItem *item, const TQPoint &point)
+{
+ if(item)
+ {
+ KFileTreeViewItem *kfi = static_cast<KFileTreeViewItem*>(item);
+ menu->updateDirActions(kfi->isDir());
+ menu->setURL(kfi->url());
+ menu->exec(point);
+ }
+}
+
+void SQ_TreeView::slotDirty(const TQString &path)
+{
+ KURL url;
+ url.setPath(path);
+
+ lister->lock();
+
+ // we don't need update urls that are not yet updated
+ // by threaded lister
+ if(!lister->hasURL(url))
+ lister->appendURL(url);
+ else if(lister->isCurrent(url))
+ {
+ lister->terminate();
+ lister->wait();
+ lister->closeDir();
+ }
+
+ lister->unlock();
+
+ if(!lister->running())
+ scanTimer->start(1000, true);
+}
+
+void SQ_TreeView::slotDeleteItemMy(KFileItem *fi)
+{
+ if(m_recurs != No && fi)
+ dw->removeDir(fi->url().path());
+}
+
+void SQ_TreeView::slotAddToFolderBasket()
+{
+ KFileItem fi(KFileItem::Unknown, KFileItem::Unknown, menu->url());
+
+ KFileItemList list;
+ list.append(&fi);
+
+ SQ_DirectoryBasket::instance()->add(list);
+}
+
+#include "sq_treeview.moc"
diff --git a/src/sidebar/sq_treeview.h b/src/sidebar/sq_treeview.h
new file mode 100644
index 0000000..dd39480
--- /dev/null
+++ b/src/sidebar/sq_treeview.h
@@ -0,0 +1,174 @@
+/***************************************************************************
+ sq_treeview.h - description
+ -------------------
+ begin : Mon Mar 15 2004
+ copyright : (C) 2004 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SQ_TREEVIEW_H
+#define SQ_TREEVIEW_H
+
+#include <tqstringlist.h>
+
+#include <tdefiletreeview.h>
+#include <kurl.h>
+
+class KDirWatch;
+
+class SQ_TreeViewItem;
+class SQ_ThreadDirLister;
+class SQ_TreeViewMenu;
+
+/*
+ * We should subclass KFileTreeBranch to let us create
+ * our own items. See SQ_TreeViewitem.
+ */
+class SQ_FileTreeViewBranch : public KFileTreeBranch
+{
+ public:
+ SQ_FileTreeViewBranch(KFileTreeView*, const KURL &url, const TQString &name, const TQPixmap &pix);
+ ~SQ_FileTreeViewBranch();
+
+ protected:
+ virtual KFileTreeViewItem *createTreeViewItem(KFileTreeViewItem *parent, KFileItem *fileItem);
+};
+
+/*
+ * SQ_TreeView represents a file tree.
+ */
+
+class SQ_TreeView : public KFileTreeView
+{
+ TQ_OBJECT
+
+
+ public:
+ SQ_TreeView(TQWidget *parent = 0, const char *name = 0);
+ ~SQ_TreeView();
+
+ enum Recursion { No = 0, Files, Dirs, FilesDirs };
+
+ /*
+ * Recursion settings. If recursion > 0, treeview will
+ * show a number of files/directories in the given directory.
+ * It will look like that:
+ *
+ * + mypictures [8]
+ * | + wallpapers [231]
+ * | + nature [12]
+ * | + pets [43]
+ * | + cats [22]
+ * | + dogs [32]
+ *
+ * This operation is threaded.
+ */
+ void setupRecursion();
+
+ /*
+ * Load new url, if tree is visible. Save url and do nothing
+ * otherwise.
+ */
+ void emitNewURL(const KURL &url);
+
+ virtual void clearSelection();
+ virtual void setSelected(TQListViewItem *item, bool selected);
+ virtual void setCurrentItem(TQListViewItem *item);
+ virtual void setOpen(TQListViewItem *item, bool open);
+
+ static SQ_TreeView* instance() { return m_instance; }
+
+ protected:
+ virtual void customEvent(TQCustomEvent *e);
+ virtual void startAnimation(KFileTreeViewItem* item, const char*, uint);
+ virtual void stopAnimation(KFileTreeViewItem* item);
+ virtual void viewportResizeEvent(TQResizeEvent *);
+ virtual void contentsMousePressEvent(TQMouseEvent *e);
+ virtual void contentsMouseDoubleClickEvent(TQMouseEvent *e);
+
+ /*
+ * On show event load saved url, if any. See emitNewURL().
+ */
+ virtual void showEvent(TQShowEvent *);
+
+ private:
+ void toggle(SQ_TreeViewItem *, bool, bool = false);
+ void setRecursion(int);
+
+ /*
+ * Set given item visible, current, and populate it.
+ */
+ void populateItem(KFileTreeViewItem *);
+
+ /*
+ * Search first available url in variable 'paths'. Open found item.
+ * If item was found return true.
+ */
+ bool doSearch();
+
+ private slots:
+ /*
+ * Load url.
+ */
+ void slotNewURL(const KURL &url);
+
+ void slotCurrentChanged(TQListViewItem *);
+ void slotAddToFolderBasket();
+ void slotClearChecked();
+ void slotDirty(const TQString &);
+ void slotDeleteItemMy(KFileItem *);
+
+ /*
+ * Item executed. Let's pass its url to SQ_WidgetStack (if needed).
+ */
+ void slotItemExecuted(TQListViewItem*);
+
+ /*
+ * New item is opened. Try to continue loading url.
+ */
+ void slotOpened(KFileTreeViewItem *);
+
+ void slotNewTreeViewItems(KFileTreeBranch*, const KFileTreeViewItemList &);
+ void slotDelayedScan();
+ void slotAnimation();
+
+ void slotDropped(TQDropEvent *, TQListViewItem *, TQListViewItem *);
+ void slotContextMenu(TDEListView *, TQListViewItem *, const TQPoint &);
+
+ signals:
+ void newURL(const KURL &url);
+
+ /*
+ * Since 0.7.0 our file manager supports multiple directories.
+ * These signals tell SQ_DirOperator to add or remove some
+ * urls.
+ */
+ void urlAdded(const KURL &);
+ void urlRemoved(const KURL &);
+
+ private:
+ SQ_FileTreeViewBranch *root;
+ TQStringList paths;
+ KURL pendingURL, cURL;
+ SQ_ThreadDirLister *lister;
+ KFileTreeViewItemList m_mapFolders;
+ TQTimer *m_animTimer, *scanTimer;
+ bool m_ignoreClick;
+ int m_recurs;
+ SQ_TreeViewMenu *menu;
+ KDirWatch *dw;
+ KFileTreeViewItem *itemToBeOpened;
+
+ static SQ_TreeView *m_instance;
+};
+
+#endif
diff --git a/src/sidebar/sq_treeviewitem.cpp b/src/sidebar/sq_treeviewitem.cpp
new file mode 100644
index 0000000..cb3c1ab
--- /dev/null
+++ b/src/sidebar/sq_treeviewitem.cpp
@@ -0,0 +1,107 @@
+/***************************************************************************
+ sq_treeviewitem.cpp - description
+ -------------------
+ begin : Feb 22 2007
+ copyright : (C) 2007 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tqpainter.h>
+
+#include "sq_treeviewitem.h"
+
+SQ_TreeViewItem::SQ_TreeViewItem(KFileTreeViewItem *parentItem, KFileItem *fileItem, KFileTreeBranch *parentBranch)
+ : KFileTreeViewItem(parentItem, fileItem, parentBranch),
+ m_checked(false), count_files(0), count_dirs(0), use_c1(false), use_c2(false)
+{}
+
+SQ_TreeViewItem::SQ_TreeViewItem(KFileTreeView *parent, KFileItem *fileItem, KFileTreeBranch *parentBranch)
+ : KFileTreeViewItem(parent, fileItem, parentBranch),
+ m_checked(false), count_files(0), count_dirs(0), use_c1(false), use_c2(false)
+{}
+
+SQ_TreeViewItem::~SQ_TreeViewItem()
+{}
+
+void SQ_TreeViewItem::paintFocus(TQPainter *, const TQColorGroup &, const TQRect &)
+{}
+
+void SQ_TreeViewItem::paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int alignment)
+{
+ TDEListView *klv = static_cast<TDEListView *>(listView());
+
+ // mark item
+ if(column)
+ {
+ int h = height();
+ int w = klv->columnWidth(1);
+ const int m = 6;
+ const int marg = 2;
+
+ p->fillRect(0,0,w,h,cg.base());
+
+ p->setPen(black);
+ p->setBrush(cg.base());
+ p->drawRect(marg, marg, w-marg*2, h-marg*2);
+
+ if(m_checked)
+ p->fillRect((w-m)/2, (h-m)/2, m, m, cg.highlight());
+ }
+ else // file name and pixmap
+ {
+ TQColorGroup cc = cg;
+
+ if(m_checked)
+ {
+ if(klv->viewport()->backgroundMode() == TQt::FixedColor)
+ cc.setColor(TQColorGroup::Background, cg.highlight());
+ else
+ cc.setColor(TQColorGroup::Base, cg.highlight());
+ }
+ else if(isAlternate())
+ {
+ if(klv->viewport()->backgroundMode() == TQt::FixedColor)
+ cc.setColor(TQColorGroup::Background, klv->alternateBackground());
+ else
+ cc.setColor(TQColorGroup::Base, klv->alternateBackground());
+ }
+
+ TQListViewItem::paintCell(p, cc, column, width, alignment);
+ }
+}
+
+void SQ_TreeViewItem::setCount(int c1, int c2)
+{
+ count_files = c1 < 0 ? 0 : c1;
+ count_dirs = c2 < 0 ? 0 : c2;
+
+ setText(0, fileItem()->name());
+}
+
+void SQ_TreeViewItem::setText(int column, const TQString &text)
+{
+ TQString s;
+
+ if(use_c1 && use_c2) // files + dirs: show these two values anyway
+ s = TQString::fromLatin1(" [%1/%2]").arg(count_dirs).arg(count_files);
+ else if(use_c1 && count_files) // files, file count is > 0
+ s = TQString::fromLatin1(" [%1]").arg(count_files);
+ else if(use_c2 && count_dirs) // dirs, dir count is > 0
+ s = TQString::fromLatin1(" [%1]").arg(count_dirs);
+
+ KFileTreeViewItem::setText(column, text + s);
+}
+
diff --git a/src/sidebar/sq_treeviewitem.h b/src/sidebar/sq_treeviewitem.h
new file mode 100644
index 0000000..c51109c
--- /dev/null
+++ b/src/sidebar/sq_treeviewitem.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ sq_treeviewitem.h - description
+ -------------------
+ begin : Feb 22 2007
+ copyright : (C) 2007 by Baryshev Dmitry
+ email : ksquirrel.iv@gmail.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef SQ_TREEVIEWITEM_H
+#define SQ_TREEVIEWITEM_H
+
+#include <tdefiletreeviewitem.h>
+
+class KFileTreeBranch;
+
+class SQ_TreeViewItem : public KFileTreeViewItem
+{
+ public:
+ SQ_TreeViewItem(KFileTreeViewItem *parentItem, KFileItem *fileItem, KFileTreeBranch *parentBranch);
+ SQ_TreeViewItem(KFileTreeView *parent, KFileItem *fileItem, KFileTreeBranch *parentBranch);
+ ~SQ_TreeViewItem();
+
+ bool checked() const;
+ void setChecked(bool c);
+
+ int files() const;
+ int dirs() const;
+
+ void setCount(int c1, int c2);
+ void setParams(bool _use_c1, bool _use_c2);
+
+ virtual void paintFocus(TQPainter *, const TQColorGroup &, const TQRect &);
+ virtual void setText(int column, const TQString &text);
+
+ protected:
+ virtual void paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int alignment);
+
+ private:
+ bool m_checked;
+ int count_files, count_dirs;
+ bool use_c1, use_c2;
+};
+
+inline
+void SQ_TreeViewItem::setParams(bool _use_c1, bool _use_c2)
+{
+ use_c1 = _use_c1;
+ use_c2 = _use_c2;
+}
+
+inline
+bool SQ_TreeViewItem::checked() const
+{
+ return m_checked;
+}
+
+inline
+void SQ_TreeViewItem::setChecked(bool c)
+{
+ m_checked = c;
+ repaint();
+}
+
+inline
+int SQ_TreeViewItem::files() const
+{
+ return count_files;
+}
+
+inline
+int SQ_TreeViewItem::dirs() const
+{
+ return count_dirs;
+}
+
+#endif
diff --git a/src/sidebar/sq_treeviewmenu.cpp b/src/sidebar/sq_treeviewmenu.cpp
new file mode 100644
index 0000000..624c753
--- /dev/null
+++ b/src/sidebar/sq_treeviewmenu.cpp
@@ -0,0 +1,196 @@
+#include <tqpoint.h>
+#include <tqwidget.h>
+#include <tqstylesheet.h>
+
+#include <tdelocale.h>
+#include <kurl.h>
+#include <tdeio/job.h>
+#include <kpropertiesdialog.h>
+#include <kinputdialog.h>
+#include <tdemessagebox.h>
+
+#include "sq_treeviewmenu.h"
+#include "ksquirrel.h"
+#include "sq_iconloader.h"
+
+SQ_TreeViewMenu::SQ_TreeViewMenu(TQWidget *parent, const char *name) : TDEPopupMenu(parent, name)
+{
+ id_new = insertItem(SQ_IconLoader::instance()->loadIcon("folder-new", TDEIcon::Desktop, TDEIcon::SizeSmall), i18n("New folder..."), this, TQ_SLOT(slotDirectoryNew()));
+ insertSeparator();
+ id_rename = insertItem(i18n("Rename"), this, TQ_SLOT(slotDirectoryRename()));
+ id_clear = insertItem(i18n("Clear contents"), this, TQ_SLOT(slotDirectoryClear()));
+ id_delete = insertItem(SQ_IconLoader::instance()->loadIcon("edit-delete", TDEIcon::Desktop, TDEIcon::SizeSmall), i18n("Delete"), this, TQ_SLOT(slotDirectoryDelete()));
+ insertSeparator();
+ id_prop = insertItem(i18n("Properties"), this, TQ_SLOT(slotDirectoryProperties()));
+}
+
+SQ_TreeViewMenu::~SQ_TreeViewMenu()
+{}
+
+void SQ_TreeViewMenu::reconnect(Element elem, TQObject *receiver, const char *member)
+{
+ int id;
+
+ if(elem == SQ_TreeViewMenu::New)
+ id = id_new;
+ else if(elem == SQ_TreeViewMenu::Delete)
+ id = id_delete;
+ else if(elem == SQ_TreeViewMenu::Rename)
+ id = id_rename;
+ else if(elem == SQ_TreeViewMenu::Clear)
+ id = id_clear;
+ else
+ id = id_prop;
+
+ disconnectItem(id, 0, 0);
+ connectItem(id, receiver, member);
+}
+
+void SQ_TreeViewMenu::updateDirActions(bool isdir, bool isroot)
+{
+ setItemEnabled(id_new, isdir);
+ setItemEnabled(id_clear, isdir);
+
+ setItemEnabled(id_delete, !isroot);
+ setItemEnabled(id_rename, isdir && !isroot);
+}
+
+void SQ_TreeViewMenu::slotDirectoryNew()
+{
+ if(!m_url.isEmpty())
+ {
+ bool ok;
+
+ TQString mNewFilename = KInputDialog::getText(i18n("Create Subfolder"),
+ i18n("<p>Create new folder in <b>%1</b>:</p>").arg(TQStyleSheet::escape(m_url.filename())),
+ TQString(), &ok, KSquirrel::app());
+
+ if(ok)
+ {
+ KURL dstURL = m_url;
+ dstURL.addPath(mNewFilename);
+ TDEIO::Job *job = TDEIO::mkdir(dstURL);
+
+ connect(job, TQ_SIGNAL(result(TDEIO::Job*)), this, TQ_SLOT(slotDirectoryResult(TDEIO::Job *)));
+ }
+ }
+}
+
+void SQ_TreeViewMenu::slotDirectoryRename()
+{
+ if(!m_url.isEmpty())
+ {
+ KURL renameSrcURL = m_url;
+ bool ok;
+
+ TQString filename = TQStyleSheet::escape(renameSrcURL.filename());
+
+ TQString mNewFilename = KInputDialog::getText(i18n("Rename Folder"),
+ i18n("<p>Rename folder <b>%1</b> to:</p>").arg(filename),
+ renameSrcURL.filename(), &ok, KSquirrel::app());
+
+ if(ok)
+ {
+ KURL renameDstURL = renameSrcURL;
+ renameDstURL.setFileName(mNewFilename);
+
+ TDEIO::Job *job = TDEIO::rename(renameSrcURL, renameDstURL, true);
+
+ connect(job, TQ_SIGNAL(result(TDEIO::Job*)), this, TQ_SLOT(slotDirectoryResult(TDEIO::Job *)));
+ }
+ }
+}
+
+void SQ_TreeViewMenu::slotDirectoryDelete()
+{
+ if(!m_url.isEmpty())
+ {
+ TQString dir = TQStyleSheet::escape(m_url.path());
+
+ if(KMessageBox::questionYesNo(KSquirrel::app(),
+ "<qt>" + i18n("Are you sure you want to delete <b>%1</b>?").arg(dir) + "</qt>") == KMessageBox::No)
+ return;
+
+ TDEIO::Job *job = TDEIO::del(m_url);
+
+ connect(job, TQ_SIGNAL(result(TDEIO::Job*)), this, TQ_SLOT(slotDirectoryResult(TDEIO::Job *)));
+ }
+}
+
+void SQ_TreeViewMenu::slotDirectoryClear()
+{
+ if(!m_url.isEmpty())
+ {
+ urlstodel.clear();
+
+ if(KMessageBox::questionYesNo(KSquirrel::app(),
+ "<qt>" + i18n("Are you sure you want to delete contents of <b>%1</b>?").arg(m_url.path()) + "</qt>") == KMessageBox::No)
+ return;
+
+ TDEIO::Job *job = TDEIO::listDir(m_url, false, true);
+
+ connect(job, TQ_SIGNAL(entries(TDEIO::Job *, const TDEIO::UDSEntryList &)), this, TQ_SLOT(slotEntries(TDEIO::Job *, const TDEIO::UDSEntryList &)));
+ connect(job, TQ_SIGNAL(result(TDEIO::Job *)), this, TQ_SLOT(slotListResult(TDEIO::Job *)));
+ }
+}
+
+void SQ_TreeViewMenu::slotEntries(TDEIO::Job *, const TDEIO::UDSEntryList &list)
+{
+ TDEIO::UDSEntryListConstIterator itEnd = list.end();
+ TQString suff;
+ KURL u;
+
+ static const TQString &dot = TDEGlobal::staticQString(".");
+ static const TQString &dotdot = TDEGlobal::staticQString("..");
+
+ // go through list of TDEIO::UDSEntrys
+ for(TDEIO::UDSEntryListConstIterator it = list.begin(); it != itEnd; ++it)
+ {
+ TDEIO::UDSEntry entry = *it;
+ TDEIO::UDSEntry::ConstIterator itEnd = entry.end();
+
+ for(TDEIO::UDSEntry::ConstIterator it = entry.begin(); it != itEnd; ++it)
+ {
+ if((*it).m_uds == TDEIO::UDS_NAME)
+ {
+ suff = (*it).m_str;
+
+ if(suff != dot && suff != dotdot)
+ {
+ u = m_url;
+ u.addPath(suff);
+ urlstodel.append(u);
+ }
+
+ break;
+ }
+ }
+ }
+}
+
+void SQ_TreeViewMenu::slotListResult(TDEIO::Job *job)
+{
+ if(!job) return;
+
+ if(job->error())
+ job->showErrorDialog(KSquirrel::app());
+ else if(!urlstodel.isEmpty())
+ {
+ TDEIO::Job *job = TDEIO::del(urlstodel);
+ connect(job, TQ_SIGNAL(result(TDEIO::Job *)), this, TQ_SLOT(slotDirectoryResult(TDEIO::Job *)));
+ }
+}
+
+void SQ_TreeViewMenu::slotDirectoryResult(TDEIO::Job *job)
+{
+ if(job && job->error())
+ job->showErrorDialog(KSquirrel::app());
+}
+
+void SQ_TreeViewMenu::slotDirectoryProperties()
+{
+ if(!m_url.isEmpty())
+ (void)new KPropertiesDialog(m_url, KSquirrel::app());
+}
+
+#include "sq_treeviewmenu.moc"
diff --git a/src/sidebar/sq_treeviewmenu.h b/src/sidebar/sq_treeviewmenu.h
new file mode 100644
index 0000000..72d900a
--- /dev/null
+++ b/src/sidebar/sq_treeviewmenu.h
@@ -0,0 +1,59 @@
+#ifndef SQ_TREEVIEWMENU_H
+#define SQ_TREEVIEWMENU_H
+
+#include <tdepopupmenu.h>
+#include <kurl.h>
+
+class TQPoint;
+
+namespace TDEIO { class Job; }
+
+class SQ_TreeViewMenu : public TDEPopupMenu
+{
+ TQ_OBJECT
+
+
+ public:
+ SQ_TreeViewMenu(TQWidget *parent = 0, const char *name = 0);
+ virtual ~SQ_TreeViewMenu();
+
+ enum Element { New, Rename, Delete, Properties, Clear };
+
+ void setURL(const KURL &_url);
+ KURL url() const;
+
+ void reconnect(Element, TQObject *receiver, const char *member);
+ virtual void updateDirActions(bool isdir, bool isroot = false);
+
+ protected slots:
+ virtual void slotDirectoryNew();
+ virtual void slotDirectoryRename();
+ virtual void slotDirectoryDelete();
+ virtual void slotDirectoryProperties();
+ virtual void slotDirectoryResult(TDEIO::Job *job);
+
+ void slotDirectoryClear();
+ void slotEntries(TDEIO::Job *, const TDEIO::UDSEntryList &);
+ void slotListResult(TDEIO::Job *);
+
+ protected:
+ int id_new, id_rename, id_delete, id_prop, id_clear;
+
+ private:
+ KURL m_url;
+ KURL::List urlstodel;
+};
+
+inline
+void SQ_TreeViewMenu::setURL(const KURL &_url)
+{
+ m_url = _url;
+}
+
+inline
+KURL SQ_TreeViewMenu::url() const
+{
+ return m_url;
+}
+
+#endif