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.
kftpgrabber/kftpgrabber/src/widgets/bookmarks/listview.cpp

533 lines
14 KiB

/*
* This file is part of the KFTPGrabber project
*
* Copyright (C) 2004 by the KFTPGrabber developers
* Copyright (C) 2004 Jernej Kos <kostko@jweb-network.net>
* Copyright (C) 2004 Markus Brueffer <markus@brueffer.de>
*
* 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.
*
* This program is distributed in the hope that it will be useful, but
* is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
* NON-INFRINGEMENT. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
#include "kftpapi.h"
#include "listview.h"
#include "kftpbookmarks.h"
#include "kftpsession.h"
#include "misc.h"
#include <tqdragobject.h>
#include <tdeaction.h>
#include <kinputdialog.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <kdebug.h>
#include <tdeio/passdlg.h>
using namespace KFTPGrabberBase;
namespace KFTPWidgets {
namespace Bookmarks {
ListViewItem::ListViewItem(TQListView *parent, const TQString &t1)
: TDEListViewItem(parent, t1)
{
}
ListViewItem::ListViewItem(TQListViewItem *parent, const TQString &t1)
: TDEListViewItem(parent, t1)
{
}
int ListViewItem::compare(TQListViewItem *i, int col, bool) const
{
if (m_type != static_cast<ListViewItem*>(i)->m_type) {
if (m_type == 0)
return -1; // category
else
return 1; // server
}
return TDEListViewItem::compare(i, col, false);
}
ListView::ListView(KFTPBookmarks::Manager *bookmarks, TQWidget *parent, const char *name)
: KFTPWidgets::ListView(parent, name),
m_autoUpdate(false),
m_connectBookmark(false),
m_editMenuItem(false),
m_bookmarks(bookmarks),
m_activeSite(0),
m_activeCategory(0),
m_activeItem(0)
{
// Set some stuff
setMinimumWidth(150);
setFullWidth(true);
addColumn(i18n("Bookmarks"));
setRootIsDecorated(true);
setEmptyListText(i18n("No bookmarks."));
setItemsRenameable(false);
// Drag & drop
setDragEnabled(true);
setAcceptDrops(true);
setDropVisualizer(false);
// Init auto open timer
m_openTimer = new TQTimer(this);
connect(this, TQ_SIGNAL(dropped(TQDropEvent*, TQListViewItem*)), this, TQ_SLOT(slotDropped(TQDropEvent*, TQListViewItem*)));
connect(this, TQ_SIGNAL(clicked(TQListViewItem*)), this, TQ_SLOT(slotClicked(TQListViewItem*)));
connect(this, TQ_SIGNAL(doubleClicked(TQListViewItem*)), this, TQ_SLOT(slotDoubleClicked(TQListViewItem*)));
connect(this, TQ_SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint&, int)), this, TQ_SLOT(slotContextMenu(TQListViewItem*, const TQPoint&, int)));
/* Init the actions */
m_newAction = new TDEAction(i18n("&New..."), "document-new", TDEShortcut(), this, TQ_SLOT(slotNewAction()), actionCollection(), "bookmark_new");
m_renameAction = new TDEAction(i18n("&Rename"), TDEShortcut(), this, TQ_SLOT(slotRenameAction()), actionCollection(), "bookmark_rename");
m_deleteAction = new TDEAction(i18n("&Delete"), "edit-delete", TDEShortcut(), this, TQ_SLOT(slotDeleteAction()), actionCollection(), "bookmark_delete");
m_subCatAction = new TDEAction(i18n("&Create Subcategory..."), "folder-new", TDEShortcut(), this, TQ_SLOT(slotSubCatAction()), actionCollection(), "bookmark_subcat");
m_copyAction = new TDEAction(i18n("&Duplicate"), TDEShortcut(), this, TQ_SLOT(slotDuplicateAction()), actionCollection(), "bookmark_duplicate");
}
TDEActionCollection *ListView::actionCollection()
{
return KFTPAPI::getInstance()->mainWindow()->actionCollection();
}
void ListView::setAutoUpdate(bool value)
{
m_autoUpdate = value;
if (value)
connect(m_bookmarks, TQ_SIGNAL(update()), this, TQ_SLOT(slotAutoUpdate()));
slotAutoUpdate();
}
void ListView::setConnectBookmark(bool value)
{
m_connectBookmark = value;
if (value)
connect(this, TQ_SIGNAL(executed(TQListViewItem*)), this, TQ_SLOT(slotBookmarkExecuted(TQListViewItem*)));
}
void ListView::setEditMenuItem(bool value)
{
m_editMenuItem = value;
}
void ListView::slotBookmarkExecuted(TQListViewItem *item)
{
if (!item || !m_connectBookmark || static_cast<ListViewItem*>(item)->m_type == BT_CATEGORY)
return;
KFTPBookmarks::Site *site = static_cast<ListViewItem*>(item)->m_site;
KURL siteUrl = site->getUrl();
// Handle empty usernames and passwords for non-anonymous sites
if (!siteUrl.hasUser() || !siteUrl.hasPass() && siteUrl.user() != "anonymous") {
TDEIO::PasswordDialog *dlg = new TDEIO::PasswordDialog(i18n("Please provide your username and password for connecting to this site."), siteUrl.user(), true);
dlg->addCommentLine(i18n("Site:"), TQString("%1:%2").arg(siteUrl.host()).arg(siteUrl.port()));
if (dlg->exec() == KDialogBase::Accepted) {
siteUrl.setUser(dlg->username());
siteUrl.setPass(dlg->password());
if (dlg->keepPassword()) {
// Save password to the bookmarked site
site->setProperty("username", dlg->username());
site->setProperty("password", encodePassword(dlg->password()));
}
delete dlg;
} else {
// Abort connection attempt
delete dlg;
return;
}
}
// Just spawn a new session
KFTPSession::Session *session = KFTPSession::Manager::self()->spawnRemoteSession(KFTPSession::IgnoreSide, siteUrl, site);
m_bookmarks->setupClient(site, session->getClient());
}
void ListView::slotAutoUpdate()
{
if (m_autoUpdate) {
// Update the bookmark list
fillBookmarkData();
}
}
TQDragObject *ListView::dragObject()
{
// Determine hotspot and pixmap
TQPoint hotspot;
TQPixmap pixmap = *selectedItem()->pixmap(0);
hotspot.setX(pixmap.width() / 2);
hotspot.setY(pixmap.height() / 2);
TQString id = static_cast<ListViewItem*>(selectedItem())->m_site->id();
m_dragObject = new TQStoredDrag("application/x-qlistviewitem", this);
TQByteArray data;
TQDataStream arg(data, IO_WriteOnly);
arg << id;
// Start the drag
static_cast<TQStoredDrag*>(m_dragObject)->setEncodedData(data);
m_dragObject->setPixmap(pixmap, hotspot);
return m_dragObject;
}
bool ListView::acceptDrag(TQDropEvent *e) const
{
// If it is a local drag, accept it
return e->source() == static_cast<TQWidget*>(const_cast<ListView*>(this));
}
void ListView::contentsDragEnterEvent(TQDragEnterEvent *e)
{
if (!acceptDrag(e)) {
e->ignore();
return;
}
e->acceptAction();
m_currentBeforeDropItem = selectedItem();
TQListViewItem *item = itemAt(contentsToViewport(e->pos()));
if (item) {
m_dropItem = item;
m_openTimer->start(750);
} else {
m_dropItem = 0L;
}
}
void ListView::contentsDragMoveEvent(TQDragMoveEvent *e)
{
if (!acceptDrag(e)) {
e->ignore();
return;
}
e->acceptAction();
TQListViewItem *item = itemAt(contentsToViewport(e->pos()));
if (item) {
setSelected(item, true);
if (item != m_dropItem) {
m_openTimer->stop();
m_dropItem = item;
m_openTimer->start(750);
}
} else {
if (selectedItem()) {
setSelected(selectedItem(), false);
}
m_openTimer->stop();
m_dropItem = 0L;
}
}
void ListView::contentsDragLeaveEvent(TQDragLeaveEvent*)
{
if (m_currentBeforeDropItem) {
setSelected(m_currentBeforeDropItem, true);
ensureItemVisible(m_currentBeforeDropItem);
} else {
setSelected(m_dropItem, false);
}
m_openTimer->stop();
m_dropItem = 0L;
}
void ListView::slotOpenTimer()
{
m_openTimer->stop();
if (m_dropItem && m_dropItem->isExpandable()) {
// Expand the category
m_dropItem->setOpen(true);
}
}
void ListView::slotDropped(TQDropEvent *e, TQListViewItem*)
{
KFTPBookmarks::Site *parentSite = 0L;
if (selectedItem()) {
TQListViewItem *newParent = 0L;
// Get the new path
if (static_cast<ListViewItem*>(selectedItem())->m_type == 0)
newParent = selectedItem();
else
newParent = selectedItem()->parent();
if (newParent)
parentSite = static_cast<ListViewItem*>(newParent)->m_site;
else
parentSite = m_bookmarks->findCategory("root");
} else {
parentSite = m_bookmarks->findCategory("root");
}
TQString id;
// Decode the data
TQDataStream arg(e->encodedData("application/x-qlistviewitem"), IO_ReadOnly);
arg >> id;
// Move the site
KFTPBookmarks::Site *originalSite = m_bookmarks->findSite(id);
parentSite->reparentSite(originalSite);
emit bookmarkMoved();
// Notify the bookmark manager
m_bookmarks->emitUpdate();
}
void ListView::fillBookmarkData()
{
// Fill the tree with data
m_bookmarks->guiPopulateBookmarksTree(this);
}
void ListView::slotClicked(TQListViewItem *item)
{
m_activeItem = static_cast<ListViewItem*>(item);
if (m_activeItem) {
if (m_activeItem->m_type == BT_CATEGORY) {
// Category
m_activeCategory = m_activeItem->m_site;
m_activeSite = 0L;
} else {
// Server
m_activeSite = m_activeItem->m_site;
m_activeCategory = m_activeSite->getParentSite();
}
}
emit bookmarkClicked(item);
}
void ListView::slotDoubleClicked(TQListViewItem *item)
{
if (!item)
return;
setOpen(item, !item->isOpen());
}
KFTPBookmarks::Manager *ListView::getBookmarks()
{
return m_bookmarks;
}
void ListView::slotRenameAction()
{
// Rename a subcategory
ListViewItem *item = static_cast<ListViewItem*>(selectedItems().at(0));
KFTPBookmarks::Site *site = item->m_site;
bool ok;
TQString newName = KInputDialog::getText(i18n("Category Name"), i18n("Rename category:"), item->text(0), &ok, this);
if (ok) {
// Ok, let's rename it
site->setAttribute("name", newName);
item->setText(0, newName);
}
}
void ListView::slotSubCatAction()
{
// Create a subcategory
ListViewItem *item = static_cast<ListViewItem*>(selectedItems().at(0));
KFTPBookmarks::Site *site = item ? item->m_site : m_bookmarks->findCategory("root");
bool ok;
TQString newName = KInputDialog::getText(i18n("New Category Name"), i18n("New category:"), "", &ok, this);
if (ok) {
// Let's create the sub category
site->addCategory(newName);
emit categoryRenamed();
m_bookmarks->emitUpdate();
}
}
void ListView::slotNewAction()
{
if (!m_activeCategory) {
// Set the starting category to document root
m_activeCategory = m_bookmarks->findCategory("root");
}
// Create the new node
KFTPBookmarks::Site *site = m_activeCategory->addSite();
site->setAttribute("name", i18n("New server"));
site->setProperty("port", 21);
// Create the ListViewItem
ListViewItem *serv = 0L;
if (!m_activeItem || (!m_activeItem->parent() && m_activeItem->m_type == BT_SERVER)) {
serv = new ListViewItem(this, i18n("New Server"));
} else if (m_activeItem->m_type == BT_CATEGORY) {
serv = new ListViewItem(m_activeItem, i18n("New Server"));
m_activeItem->setOpen(true);
} else {
serv = new ListViewItem(m_activeItem->parent(), i18n("New Server"));
}
serv->m_type = BT_SERVER;
serv->m_site = site;
serv->setPixmap(0, loadSmallPixmap("ftp"));
// Set the new ListViewItem as active
setSelected(serv, true);
m_activeItem = serv;
// Display its properties
m_activeSite = site;
emit bookmarkNew(serv, site);
}
void ListView::slotDuplicateAction()
{
// Copy a bookmark
ListViewItem *item = static_cast<ListViewItem*>(selectedItems().at(0));
// Clone the node
KFTPBookmarks::Site *copy = item->m_site->duplicate();
// Create the ListViewItem
ListViewItem *serv = 0L;
if (item->parent())
serv = new ListViewItem(item->parent(), copy->getAttribute("name"));
else
serv = new ListViewItem(this, copy->getAttribute("name"));
serv->m_type = BT_SERVER;
serv->m_site = copy;
serv->setPixmap(0, loadSmallPixmap("ftp"));
// Set the new ListViewItem as active
setSelected(serv, true);
m_activeItem = serv;
// Display its properties
m_activeSite = copy;
emit bookmarkDuplicated(serv, copy);
// Update the bookmarks
m_bookmarks->emitUpdate();
}
void ListView::slotDeleteAction()
{
// Delete a server or a category
ListViewItem *item = static_cast<ListViewItem*>(selectedItems().at(0));
// What do we have here ?
if (item->m_type == BT_CATEGORY) {
// Category
if (KMessageBox::questionYesNo(this, i18n("Are you sure you want to remove this category?")) == KMessageBox::Yes) {
m_bookmarks->delSite(item->m_site);
} else {
return;
}
} else {
// Server
if (KMessageBox::questionYesNo(this, i18n("Are you sure you want to remove this server?")) == KMessageBox::Yes) {
m_bookmarks->delSite(item->m_site);
} else {
return;
}
}
if ( !m_autoUpdate )
delete item;
m_activeItem = 0L;
emit bookmarkDeleted();
}
void ListView::slotContextMenu(TQListViewItem *item, const TQPoint &pos, int)
{
slotClicked(item);
TDEPopupMenu *context = new TDEPopupMenu(this);
if (item) {
context->insertTitle(item->text(0));
// Server or category
if (static_cast<ListViewItem*>(item)->m_type == BT_CATEGORY) {
m_newAction->plug(context);
m_deleteAction->plug(context);
m_subCatAction->plug(context);
m_renameAction->plug(context);
} else {
if (m_editMenuItem)
actionCollection()->action("bookmark_edit2")->plug(context);
m_newAction->plug(context);
m_copyAction->plug(context);
m_deleteAction->plug(context);
}
} else {
// Nothing selected
m_newAction->plug(context);
m_subCatAction->plug(context);
}
context->exec(pos);
delete context;
}
}
}
#include "listview.moc"