summaryrefslogtreecommitdiffstats
path: root/kftpgrabber/src/widgets/bookmarks/listview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kftpgrabber/src/widgets/bookmarks/listview.cpp')
-rw-r--r--kftpgrabber/src/widgets/bookmarks/listview.cpp532
1 files changed, 532 insertions, 0 deletions
diff --git a/kftpgrabber/src/widgets/bookmarks/listview.cpp b/kftpgrabber/src/widgets/bookmarks/listview.cpp
new file mode 100644
index 0000000..4349604
--- /dev/null
+++ b/kftpgrabber/src/widgets/bookmarks/listview.cpp
@@ -0,0 +1,532 @@
+/*
+ * 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 <qdragobject.h>
+
+#include <kaction.h>
+#include <kinputdialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <kio/passdlg.h>
+
+using namespace KFTPGrabberBase;
+
+namespace KFTPWidgets {
+
+namespace Bookmarks {
+
+ListViewItem::ListViewItem(QListView *parent, const QString &t1)
+ : KListViewItem(parent, t1)
+{
+}
+
+ListViewItem::ListViewItem(QListViewItem *parent, const QString &t1)
+ : KListViewItem(parent, t1)
+{
+}
+
+int ListViewItem::compare(QListViewItem *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 KListViewItem::compare(i, col, false);
+}
+
+ListView::ListView(KFTPBookmarks::Manager *bookmarks, QWidget *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 QTimer(this);
+
+ connect(this, SIGNAL(dropped(QDropEvent*, QListViewItem*)), this, SLOT(slotDropped(QDropEvent*, QListViewItem*)));
+ connect(this, SIGNAL(clicked(QListViewItem*)), this, SLOT(slotClicked(QListViewItem*)));
+ connect(this, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(slotDoubleClicked(QListViewItem*)));
+ connect(this, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)), this, SLOT(slotContextMenu(QListViewItem*, const QPoint&, int)));
+
+ /* Init the actions */
+ m_newAction = new KAction(i18n("&New..."), "filenew", KShortcut(), this, SLOT(slotNewAction()), actionCollection(), "bookmark_new");
+ m_renameAction = new KAction(i18n("&Rename"), KShortcut(), this, SLOT(slotRenameAction()), actionCollection(), "bookmark_rename");
+ m_deleteAction = new KAction(i18n("&Delete"), "editdelete", KShortcut(), this, SLOT(slotDeleteAction()), actionCollection(), "bookmark_delete");
+ m_subCatAction = new KAction(i18n("&Create Subcategory..."), "folder_new", KShortcut(), this, SLOT(slotSubCatAction()), actionCollection(), "bookmark_subcat");
+ m_copyAction = new KAction(i18n("&Duplicate"), KShortcut(), this, SLOT(slotDuplicateAction()), actionCollection(), "bookmark_duplicate");
+}
+
+KActionCollection *ListView::actionCollection()
+{
+ return KFTPAPI::getInstance()->mainWindow()->actionCollection();
+}
+
+void ListView::setAutoUpdate(bool value)
+{
+ m_autoUpdate = value;
+
+ if (value)
+ connect(m_bookmarks, SIGNAL(update()), this, SLOT(slotAutoUpdate()));
+
+ slotAutoUpdate();
+}
+
+void ListView::setConnectBookmark(bool value)
+{
+ m_connectBookmark = value;
+
+ if (value)
+ connect(this, SIGNAL(executed(QListViewItem*)), this, SLOT(slotBookmarkExecuted(QListViewItem*)));
+}
+
+void ListView::setEditMenuItem(bool value)
+{
+ m_editMenuItem = value;
+}
+
+void ListView::slotBookmarkExecuted(QListViewItem *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") {
+ KIO::PasswordDialog *dlg = new KIO::PasswordDialog(i18n("Please provide your username and password for connecting to this site."), siteUrl.user(), true);
+ dlg->addCommentLine(i18n("Site:"), QString("%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();
+ }
+}
+
+QDragObject *ListView::dragObject()
+{
+ // Determine hotspot and pixmap
+ QPoint hotspot;
+ QPixmap pixmap = *selectedItem()->pixmap(0);
+ hotspot.setX(pixmap.width() / 2);
+ hotspot.setY(pixmap.height() / 2);
+
+ QString id = static_cast<ListViewItem*>(selectedItem())->m_site->id();
+ m_dragObject = new QStoredDrag("application/x-qlistviewitem", this);
+ QByteArray data;
+ QDataStream arg(data, IO_WriteOnly);
+ arg << id;
+
+ // Start the drag
+ static_cast<QStoredDrag*>(m_dragObject)->setEncodedData(data);
+ m_dragObject->setPixmap(pixmap, hotspot);
+
+ return m_dragObject;
+}
+
+bool ListView::acceptDrag(QDropEvent *e) const
+{
+ // If it is a local drag, accept it
+ return e->source() == static_cast<QWidget*>(const_cast<ListView*>(this));
+}
+
+void ListView::contentsDragEnterEvent(QDragEnterEvent *e)
+{
+ if (!acceptDrag(e)) {
+ e->ignore();
+ return;
+ }
+ e->acceptAction();
+
+ m_currentBeforeDropItem = selectedItem();
+ QListViewItem *item = itemAt(contentsToViewport(e->pos()));
+
+ if (item) {
+ m_dropItem = item;
+ m_openTimer->start(750);
+ } else {
+ m_dropItem = 0L;
+ }
+}
+
+void ListView::contentsDragMoveEvent(QDragMoveEvent *e)
+{
+ if (!acceptDrag(e)) {
+ e->ignore();
+ return;
+ }
+ e->acceptAction();
+
+ QListViewItem *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(QDragLeaveEvent*)
+{
+ 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(QDropEvent *e, QListViewItem*)
+{
+ KFTPBookmarks::Site *parentSite = 0L;
+
+ if (selectedItem()) {
+ QListViewItem *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");
+ }
+
+ QString id;
+
+ // Decode the data
+ QDataStream 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(QListViewItem *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(QListViewItem *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;
+ QString 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;
+ QString 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(QListViewItem *item, const QPoint &pos, int)
+{
+ slotClicked(item);
+
+ KPopupMenu *context = new KPopupMenu(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"