/*************************************************************************** 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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"), TQT_TQOBJECT(this), TQT_SLOT(slotChangeIcon())); } SQ_DBMenu::~SQ_DBMenu() {} void SQ_DBMenu::slotChangeIcon() { KIconDialog dialog(TDEGlobal::iconLoader()); dialog.setup(KIcon::Desktop, KIcon::MimeType, true, KIcon::SizeSmall); TQString result = dialog.openDialog(); if(!result.isEmpty() && item) { item->setIcon(result); item->setPixmap(0, SQ_IconLoader::instance()->loadIcon(result, KIcon::Desktop, KIcon::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("

Rename item %1 to:

").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, TQT_SIGNAL(result(TDEIO::Job*)), TQT_TQOBJECT(this), TQT_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 = "" 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, KIcon::Desktop, KIcon::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, TQT_SIGNAL(timeout()), TQT_TQOBJECT(this), TQT_SLOT(slotSortReal())); timerAdd = new TQTimer(this); connect(timerAdd, TQT_SIGNAL(timeout()), TQT_TQOBJECT(this), TQT_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", KIcon::Desktop, KIcon::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, TQT_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, TQT_TQOBJECT(this), TQT_SLOT(slotNewDirectory())); connect(TQT_TQOBJECT(this), TQT_SIGNAL(spacePressed(TQListViewItem*)), TQT_TQOBJECT(this), TQT_SIGNAL(executed(TQListViewItem*))); connect(TQT_TQOBJECT(this), TQT_SIGNAL(returnPressed(TQListViewItem*)), TQT_TQOBJECT(this), TQT_SIGNAL(executed(TQListViewItem*))); connect(TQT_TQOBJECT(this), TQT_SIGNAL(executed(TQListViewItem*)), TQT_TQOBJECT(this), TQT_SLOT(slotItemExecuted(TQListViewItem*))); connect(TQT_TQOBJECT(this), TQT_SIGNAL(contextMenu(KListView*, TQListViewItem*, const TQPoint&)), TQT_TQOBJECT(this), TQT_SLOT(slotContextMenu(KListView*, TQListViewItem*, const TQPoint&))); connect(TQT_TQOBJECT(this), TQT_SIGNAL(dropped(TQDropEvent*, TQListViewItem*, TQListViewItem*)), TQT_TQOBJECT(this), TQT_SLOT(slotDropped(TQDropEvent*, TQListViewItem*, TQListViewItem*))); connect(TQT_TQOBJECT(this), TQT_SIGNAL(itemRenamed(TQListViewItem *, int, const TQString &)), TQT_TQOBJECT(this), TQT_SLOT(slotItemRenamedMy(TQListViewItem *, int, const TQString &))); connect(TQT_TQOBJECT(this), TQT_SIGNAL(itemAdded(TQListViewItem *)), TQT_TQOBJECT(this), TQT_SLOT(slotSort())); connect(TQT_TQOBJECT(this), TQT_SIGNAL(moved()), TQT_TQOBJECT(this), TQT_SLOT(slotReindex())); } SQ_DirectoryBasket::~SQ_DirectoryBasket() { SQ_DirectoryItem *item = static_cast(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(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(_item); SQ_DirectoryItem *parent = static_cast(_parent); KURL::List list; KURLDrag::decode(e, list); // drag'n'drop inside basket if(e->source() == this) { SQ_DirectoryItem *tomove = static_cast(root->findTVIByURL(list.first())); if(!tomove || tomove == root->root()) return; SQ_DirectoryItem *it; if(item->index() < tomove->index() && item != root->root()) it = static_cast(item->itemAbove()); else it = static_cast(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(item); if(cur && !cur->isDir()) { KURL inpath = SQ_StorageFile::readStorageFile(cur->path()); SQ_WidgetStack::instance()->diroperator()->setURL(inpath, true); } } void SQ_DirectoryBasket::slotContextMenu(KListView *, TQListViewItem *item, const TQPoint &p) { if(item) { SQ_DirectoryItem *kfi = static_cast(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 items; int i = 0; ++it; while((item = static_cast(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(root->root()->firstChild()); if(item) { int index = 0; do { item->setIndex(index++); } while((item = static_cast(item->nextSibling()))); } } void SQ_DirectoryBasket::slotItemRenamedMy(TQListViewItem *_item, int, const TQString &name) { SQ_DirectoryItem *item = static_cast(_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"