diff options
Diffstat (limited to 'kftpgrabber/src/widgets/bookmarks/listview.cpp')
-rw-r--r-- | kftpgrabber/src/widgets/bookmarks/listview.cpp | 532 |
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" |