diff options
Diffstat (limited to 'src/sidebar/sq_directorybasket.cpp')
-rw-r--r-- | src/sidebar/sq_directorybasket.cpp | 520 |
1 files changed, 520 insertions, 0 deletions
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 : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * 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" |