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.
533 lines
14 KiB
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"
|