You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ksquirrel/ksquirrel/sidebar/sq_directorybasket.cpp

521 lines
15 KiB

/***************************************************************************
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 <kglobal.h>
#include <klocale.h>
#include <kurldrag.h>
#include <kmimetype.h>
#include <kfiledialog.h>
#include <kinputdialog.h>
#include <kicondialog.h>
#include <kiconloader.h>
#include <kio/netaccess.h>
#include <kio/job.h>
#include <kprogress.h>
#include <kglobalsettings.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"), 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("<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, 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 = "<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, 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<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(KListView *, 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"