/* * This file is part of the KFTPGrabber project * * Copyright (C) 2004 by the KFTPGrabber developers * Copyright (C) 2004 Jernej Kos * Copyright (C) 2004 Markus Brueffer * * 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 #include #include #include #include #include #include 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(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, SIGNAL(dropped(TQDropEvent*, TQListViewItem*)), this, SLOT(slotDropped(TQDropEvent*, TQListViewItem*))); connect(this, SIGNAL(clicked(TQListViewItem*)), this, SLOT(slotClicked(TQListViewItem*))); connect(this, SIGNAL(doubleClicked(TQListViewItem*)), this, SLOT(slotDoubleClicked(TQListViewItem*))); connect(this, SIGNAL(contextMenuRequested(TQListViewItem*, const TQPoint&, int)), this, SLOT(slotContextMenu(TQListViewItem*, const TQPoint&, int))); /* Init the actions */ m_newAction = new TDEAction(i18n("&New..."), "document-new", TDEShortcut(), this, SLOT(slotNewAction()), actionCollection(), "bookmark_new"); m_renameAction = new TDEAction(i18n("&Rename"), TDEShortcut(), this, SLOT(slotRenameAction()), actionCollection(), "bookmark_rename"); m_deleteAction = new TDEAction(i18n("&Delete"), "edit-delete", TDEShortcut(), this, SLOT(slotDeleteAction()), actionCollection(), "bookmark_delete"); m_subCatAction = new TDEAction(i18n("&Create Subcategory..."), "folder-new", TDEShortcut(), this, SLOT(slotSubCatAction()), actionCollection(), "bookmark_subcat"); m_copyAction = new TDEAction(i18n("&Duplicate"), TDEShortcut(), this, 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, SIGNAL(update()), this, SLOT(slotAutoUpdate())); slotAutoUpdate(); } void ListView::setConnectBookmark(bool value) { m_connectBookmark = value; if (value) connect(this, SIGNAL(executed(TQListViewItem*)), this, SLOT(slotBookmarkExecuted(TQListViewItem*))); } void ListView::setEditMenuItem(bool value) { m_editMenuItem = value; } void ListView::slotBookmarkExecuted(TQListViewItem *item) { if (!item || !m_connectBookmark || static_cast(item)->m_type == BT_CATEGORY) return; KFTPBookmarks::Site *site = static_cast(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(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(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(const_cast(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(selectedItem())->m_type == 0) newParent = selectedItem(); else newParent = selectedItem()->parent(); if (newParent) parentSite = static_cast(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(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(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(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(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(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(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"