summaryrefslogtreecommitdiffstats
path: root/kftpgrabber/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'kftpgrabber/src/widgets')
-rw-r--r--kftpgrabber/src/widgets/Makefile.am28
-rw-r--r--kftpgrabber/src/widgets/balloon.cpp145
-rw-r--r--kftpgrabber/src/widgets/balloon.h86
-rw-r--r--kftpgrabber/src/widgets/bookmarks/Makefile.am13
-rw-r--r--kftpgrabber/src/widgets/bookmarks/editor.cpp492
-rw-r--r--kftpgrabber/src/widgets/bookmarks/editor.h133
-rw-r--r--kftpgrabber/src/widgets/bookmarks/editortls.cpp115
-rw-r--r--kftpgrabber/src/widgets/bookmarks/editortls.h85
-rw-r--r--kftpgrabber/src/widgets/bookmarks/importwizard.cpp167
-rw-r--r--kftpgrabber/src/widgets/bookmarks/importwizard.h85
-rw-r--r--kftpgrabber/src/widgets/bookmarks/listview.cpp532
-rw-r--r--kftpgrabber/src/widgets/bookmarks/listview.h193
-rw-r--r--kftpgrabber/src/widgets/bookmarks/sidebar.cpp158
-rw-r--r--kftpgrabber/src/widgets/bookmarks/sidebar.h88
-rw-r--r--kftpgrabber/src/widgets/browser/Makefile.am13
-rw-r--r--kftpgrabber/src/widgets/browser/actions.cpp764
-rw-r--r--kftpgrabber/src/widgets/browser/actions.h189
-rw-r--r--kftpgrabber/src/widgets/browser/detailsview.cpp596
-rw-r--r--kftpgrabber/src/widgets/browser/detailsview.h374
-rw-r--r--kftpgrabber/src/widgets/browser/dirlister.cpp169
-rw-r--r--kftpgrabber/src/widgets/browser/dirlister.h157
-rw-r--r--kftpgrabber/src/widgets/browser/filterwidget.cpp118
-rw-r--r--kftpgrabber/src/widgets/browser/filterwidget.h97
-rw-r--r--kftpgrabber/src/widgets/browser/locationnavigator.cpp173
-rw-r--r--kftpgrabber/src/widgets/browser/locationnavigator.h210
-rw-r--r--kftpgrabber/src/widgets/browser/propsplugin.cpp360
-rw-r--r--kftpgrabber/src/widgets/browser/propsplugin.h98
-rw-r--r--kftpgrabber/src/widgets/browser/treeview.cpp520
-rw-r--r--kftpgrabber/src/widgets/browser/treeview.h189
-rw-r--r--kftpgrabber/src/widgets/browser/view.cpp456
-rw-r--r--kftpgrabber/src/widgets/browser/view.h258
-rw-r--r--kftpgrabber/src/widgets/configdialog.cpp187
-rw-r--r--kftpgrabber/src/widgets/configdialog.h71
-rw-r--r--kftpgrabber/src/widgets/configfilter.cpp137
-rw-r--r--kftpgrabber/src/widgets/configfilter.h79
-rw-r--r--kftpgrabber/src/widgets/failedtransfers.cpp213
-rw-r--r--kftpgrabber/src/widgets/failedtransfers.h111
-rw-r--r--kftpgrabber/src/widgets/filtereditor.cpp625
-rw-r--r--kftpgrabber/src/widgets/filtereditor.h375
-rw-r--r--kftpgrabber/src/widgets/kftpfilteraddpatternlayout.cpp92
-rw-r--r--kftpgrabber/src/widgets/kftpfiltereditorlayout.cpp115
-rw-r--r--kftpgrabber/src/widgets/kftpselectserverdialog.cpp79
-rw-r--r--kftpgrabber/src/widgets/kftpselectserverdialog.h70
-rw-r--r--kftpgrabber/src/widgets/kftpserverlineedit.cpp105
-rw-r--r--kftpgrabber/src/widgets/kftpserverlineedit.h71
-rw-r--r--kftpgrabber/src/widgets/kftptabwidget.cpp53
-rw-r--r--kftpgrabber/src/widgets/kftptabwidget.h60
-rw-r--r--kftpgrabber/src/widgets/kftpzeroconflistview.cpp98
-rw-r--r--kftpgrabber/src/widgets/kftpzeroconflistview.h56
-rw-r--r--kftpgrabber/src/widgets/listview.cpp85
-rw-r--r--kftpgrabber/src/widgets/listview.h63
-rw-r--r--kftpgrabber/src/widgets/listviewitem.cpp96
-rw-r--r--kftpgrabber/src/widgets/listviewitem.h71
-rw-r--r--kftpgrabber/src/widgets/logview.cpp143
-rw-r--r--kftpgrabber/src/widgets/logview.h73
-rw-r--r--kftpgrabber/src/widgets/multitabbar.cpp1160
-rw-r--r--kftpgrabber/src/widgets/multitabbar.h281
-rw-r--r--kftpgrabber/src/widgets/multitabbar_p.h85
-rw-r--r--kftpgrabber/src/widgets/overlaywidget.cpp83
-rw-r--r--kftpgrabber/src/widgets/overlaywidget.h60
-rw-r--r--kftpgrabber/src/widgets/popupmessage.cpp314
-rw-r--r--kftpgrabber/src/widgets/popupmessage.h113
-rw-r--r--kftpgrabber/src/widgets/queueview/Makefile.am13
-rw-r--r--kftpgrabber/src/widgets/queueview/queueeditor.cpp323
-rw-r--r--kftpgrabber/src/widgets/queueview/queueeditor.h82
-rw-r--r--kftpgrabber/src/widgets/queueview/queueview.cpp888
-rw-r--r--kftpgrabber/src/widgets/queueview/queueview.h296
-rw-r--r--kftpgrabber/src/widgets/queueview/threadview.cpp202
-rw-r--r--kftpgrabber/src/widgets/queueview/threadview.h93
-rw-r--r--kftpgrabber/src/widgets/quickconnect.cpp476
-rw-r--r--kftpgrabber/src/widgets/quickconnect.h162
-rw-r--r--kftpgrabber/src/widgets/searchdialog.cpp165
-rw-r--r--kftpgrabber/src/widgets/searchdialog.h85
-rw-r--r--kftpgrabber/src/widgets/sidebar.cpp393
-rw-r--r--kftpgrabber/src/widgets/sidebar.h157
-rw-r--r--kftpgrabber/src/widgets/systemtray.cpp123
-rw-r--r--kftpgrabber/src/widgets/systemtray.h93
-rw-r--r--kftpgrabber/src/widgets/trafficgraph.cpp628
-rw-r--r--kftpgrabber/src/widgets/trafficgraph.h155
-rw-r--r--kftpgrabber/src/widgets/verifier.cpp148
-rw-r--r--kftpgrabber/src/widgets/verifier.h74
-rw-r--r--kftpgrabber/src/widgets/widgetlister.cpp172
-rw-r--r--kftpgrabber/src/widgets/widgetlister.h177
83 files changed, 17190 insertions, 0 deletions
diff --git a/kftpgrabber/src/widgets/Makefile.am b/kftpgrabber/src/widgets/Makefile.am
new file mode 100644
index 0000000..fa99f84
--- /dev/null
+++ b/kftpgrabber/src/widgets/Makefile.am
@@ -0,0 +1,28 @@
+INCLUDES = -I$(srcdir)/.. \
+ -I$(srcdir)/../engine \
+ -I$(srcdir)/../misc \
+ -I$(srcdir)/../widgets/browser \
+ -I.. \
+ -I../ui \
+ $(all_includes)
+
+METASOURCES = AUTO
+
+noinst_LTLIBRARIES =
+noinst_LIBRARIES = libwidgets.a
+libwidgets_a_SOURCES = logview.cpp kftpselectserverdialog.cpp \
+ kftpselectserverdialog.h kftpserverlineedit.cpp kftpserverlineedit.h listview.cpp \
+ quickconnect.cpp systemtray.cpp balloon.cpp searchdialog.cpp \
+ kftpzeroconflistview.cpp trafficgraph.cpp kftptabwidget.cpp failedtransfers.cpp \
+ listviewitem.cpp sidebar.cpp multitabbar.cpp configdialog.cpp \
+ configfilter.cpp verifier.cpp filtereditor.cpp widgetlister.cpp overlaywidget.cpp \
+ popupmessage.cpp
+
+SUBDIRS = queueview browser bookmarks
+
+noinst_HEADERS = listview.h quickconnect.h systemtray.h searchdialog.h \
+ kftpzeroconflistview.h trafficgraph.h kftptabwidget.h \
+ logview.h failedtransfers.h listviewitem.h sidebar.h multitabbar.h \
+ multitabbar_p.h configdialog.h configfilter.h verifier.h balloon.h filtereditor.h \
+ widgetlister.h overlaywidget.h popupmessage.h
+
diff --git a/kftpgrabber/src/widgets/balloon.cpp b/kftpgrabber/src/widgets/balloon.cpp
new file mode 100644
index 0000000..eb10432
--- /dev/null
+++ b/kftpgrabber/src/widgets/balloon.cpp
@@ -0,0 +1,145 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 <qpointarray.h>
+#include <qpushbutton.h>
+#include <qtooltip.h>
+#include <qlayout.h>
+#include <qlabel.h>
+
+#include <kapplication.h>
+#include <kdialog.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kactivelabel.h>
+#include <kglobalsettings.h>
+
+#include "widgets/balloon.h"
+#include "misc.h"
+
+using namespace KFTPGrabberBase;
+
+namespace KFTPWidgets {
+
+Balloon::Balloon(const QString &text, const QString &pix)
+ : QWidget(0L, "KFTPBalloon", WStyle_StaysOnTop | WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WX11BypassWM)
+{
+ setCaption("");
+
+ QVBoxLayout *BalloonLayout = new QVBoxLayout(this, 22, KDialog::spacingHint(), "BalloonLayout");
+
+ // BEGIN Layout1
+ QHBoxLayout *Layout1 = new QHBoxLayout(BalloonLayout, KDialog::spacingHint(), "Layout1");
+ KActiveLabel *caption = new KActiveLabel(text, this, "caption");
+ caption->setPalette(QToolTip::palette());
+ caption->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+
+ if (!pix.isEmpty()) {
+ QLabel *image = new QLabel(this, "mImage");
+ image->setScaledContents(FALSE);
+ image->setPixmap(loadSmallPixmap(pix));
+
+ Layout1->addWidget(image);
+ }
+
+ Layout1->addWidget(caption);
+ // END Layout1
+
+ setPalette(QToolTip::palette());
+ setAutoMask(true);
+
+ connect(caption, SIGNAL(clicked(int, int)), this, SIGNAL(signalBalloonClicked()));
+ connect(caption, SIGNAL(linkClicked(const QString &)), this, SIGNAL(signalIgnoreButtonClicked()));
+ connect(caption, SIGNAL(linkClicked(const QString &)), this, SLOT(deleteLater()));
+}
+
+void Balloon::mousePressEvent(QMouseEvent *e)
+{
+ emit signalBalloonClicked();
+ e->accept();
+}
+
+void Balloon::setAnchor(const QPoint &anchor)
+{
+ m_anchor = anchor;
+ updateMask();
+}
+
+void Balloon::updateMask()
+{
+ QRegion mask(10, 10, width() - 20, height() - 20);
+
+ QPoint corners[8] = {
+ QPoint(width() - 50, 10),
+ QPoint(10, 10),
+ QPoint(10, height() - 50),
+ QPoint(width() - 50, height() - 50),
+ QPoint(width() - 10, 10),
+ QPoint(10, 10),
+ QPoint(10, height() - 10),
+ QPoint(width() - 10, height() - 10)
+ };
+
+ for (int i = 0; i < 4; ++i) {
+ QPointArray corner;
+ corner.makeArc(corners[i].x(), corners[i].y(), 40, 40, i * 16 * 90, 16 * 90);
+ corner.resize(corner.size() + 1);
+ corner.setPoint(corner.size() - 1, corners[i + 4]);
+ mask -= corner;
+ }
+
+ // get screen-geometry for screen our anchor is on
+ // (geometry can differ from screen to screen!)
+ QRect deskRect = KGlobalSettings::desktopGeometry(m_anchor);
+
+ bool bottom = (m_anchor.y() + height()) > (deskRect.height() - 48);
+ bool right = (m_anchor.x() + width()) > (deskRect.width() - 48);
+
+ QPointArray arrow(4);
+ arrow.setPoint(0, QPoint(right ? width() : 0, bottom ? height() : 0));
+ arrow.setPoint(1, QPoint(right ? width() - 10 : 10, bottom ? height() - 30 : 30));
+ arrow.setPoint(2, QPoint(right ? width() - 30 : 30, bottom ? height() - 10 : 10));
+ arrow.setPoint(3, arrow[0]);
+ mask += arrow;
+ setMask(mask);
+
+ move(right ? m_anchor.x() - width() : m_anchor.x(), bottom ? m_anchor.y() - height() : m_anchor.y());
+}
+
+}
+
+#include "balloon.moc"
+
diff --git a/kftpgrabber/src/widgets/balloon.h b/kftpgrabber/src/widgets/balloon.h
new file mode 100644
index 0000000..c123ae7
--- /dev/null
+++ b/kftpgrabber/src/widgets/balloon.h
@@ -0,0 +1,86 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPWIDGETSBALLOON_H
+#define KFTPWIDGETSBALLOON_H
+
+#include <qwidget.h>
+
+namespace KFTPWidgets {
+
+/**
+ * A little balloon for notifications taken from Kopete with some modifications
+ * for KFTPGrabber.
+ *
+ * @author Malte Starostik <malte@kde.org>
+ * @author Duncan Mac-Vicar Prett <duncan@kde.org>
+ */
+class Balloon : public QWidget
+{
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ *
+ * @param text The text to display inside the balloon
+ * @param pic Name of the pixmap to display inside the balloon
+ */
+ Balloon(const QString &text, const QString &pic);
+
+ /**
+ * Set widget anchor.
+ *
+ * @param anchor Anchor coordinates
+ */
+ void setAnchor(const QPoint &anchor);
+
+ /**
+ * Intercept mouse press events.
+ */
+ void mousePressEvent(QMouseEvent *e);
+signals:
+ void signalButtonClicked();
+ void signalIgnoreButtonClicked();
+ void signalBalloonClicked();
+protected:
+ void updateMask();
+private:
+ QPoint m_anchor;
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/bookmarks/Makefile.am b/kftpgrabber/src/widgets/bookmarks/Makefile.am
new file mode 100644
index 0000000..d735a01
--- /dev/null
+++ b/kftpgrabber/src/widgets/bookmarks/Makefile.am
@@ -0,0 +1,13 @@
+INCLUDES = -I$(top_builddir)/kftpgrabber/src \
+ -I$(srcdir)/../.. \
+ -I$(srcdir)/../../engine \
+ -I$(srcdir)/../../misc \
+ -I$(srcdir)/../../widgets \
+ -I$(srcdir)/../../widgets/browser \
+ -I$(srcdir)/../../ui \
+ -I$(top_builddir)/kftpgrabber/src/ui \
+ $(all_includes)
+METASOURCES = AUTO
+noinst_LIBRARIES = libbookmarkwidgets.a
+noinst_HEADERS = editor.h editortls.h listview.h importwizard.h sidebar.h
+libbookmarkwidgets_a_SOURCES = editor.cpp editortls.cpp listview.cpp importwizard.cpp sidebar.cpp
diff --git a/kftpgrabber/src/widgets/bookmarks/editor.cpp b/kftpgrabber/src/widgets/bookmarks/editor.cpp
new file mode 100644
index 0000000..88ba05c
--- /dev/null
+++ b/kftpgrabber/src/widgets/bookmarks/editor.cpp
@@ -0,0 +1,492 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-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 <qlayout.h>
+#include <qpushbutton.h>
+#include <qcheckbox.h>
+#include <qgroupbox.h>
+#include <qspinbox.h>
+#include <qsplitter.h>
+#include <qtextedit.h>
+#include <qtabwidget.h>
+
+#include <kglobal.h>
+#include <kcharsets.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <klineedit.h>
+#include <kpassdlg.h>
+#include <kmessagebox.h>
+#include <kpopupmenu.h>
+#include <kcombobox.h>
+#include <kurlrequester.h>
+#include <kguiitem.h>
+#include <kfiledialog.h>
+#include <kio/job.h>
+
+#include "kftpapi.h"
+#include "kftpbookmarks.h"
+#include "misc/config.h"
+#include "misc.h"
+
+#include "editor.h"
+#include "listview.h"
+#include "importwizard.h"
+#include "editortls.h"
+
+using namespace KFTPGrabberBase;
+
+namespace KFTPWidgets {
+
+namespace Bookmarks {
+
+KActionCollection *BookmarkEditor::actionCollection()
+{
+ return KFTPAPI::getInstance()->mainWindow()->actionCollection();
+}
+
+BookmarkEditor::BookmarkEditor(QWidget *parent, const char *name)
+ : KDialogBase(parent, name, true, "FTP Bookmark Editor", User2|User1|Ok|Apply|Cancel, Ok, true, KGuiItem(i18n("Import...")), KGuiItem(i18n("Export..."))),
+ m_activeSite(0),
+ m_activeItem(0L),
+ m_portChanged(false)
+{
+ // We operate on a copy of the bookmarks
+ m_bookmarks = new KFTPBookmarks::Manager(*KFTPBookmarks::Manager::self());
+
+ QHBoxLayout *winLayout = new QHBoxLayout(this, 0, KDialog::spacingHint());
+
+ QSplitter *splitter = new QSplitter(this);
+ setMainWidget(splitter);
+ winLayout->addWidget(splitter);
+
+ // Create the list view for editing bookmarks
+ m_tree = new ListView(m_bookmarks, splitter);
+
+ m_properties = new BookmarkProperties(splitter);
+
+ initDialog();
+
+ connect(this, SIGNAL(user1Clicked()), this, SLOT(slotImportWizard()));
+ connect(this, SIGNAL(user2Clicked()), this, SLOT(slotExportWizard()));
+
+ connect(m_tree, SIGNAL(bookmarkClicked(QListViewItem*)), this, SLOT(slotTreeClicked(QListViewItem*)));
+ connect(m_tree, SIGNAL(bookmarkNew(ListViewItem*, KFTPBookmarks::Site*)), this, SLOT(slotNewAction(ListViewItem*, KFTPBookmarks::Site*)));
+ connect(m_tree, SIGNAL(bookmarkDuplicated(ListViewItem*, KFTPBookmarks::Site*)), this, SLOT(slotDuplicateAction(ListViewItem*, KFTPBookmarks::Site*)));
+ connect(m_tree, SIGNAL(bookmarkDeleted()), this, SLOT(slotDeleteAction()));
+ connect(m_tree, SIGNAL(bookmarkMoved()), this, SLOT(refresh()));
+ connect(m_tree, SIGNAL(categoryRenamed()), this, SLOT(refresh()));
+
+ // Get the new bookmark data
+ m_tree->fillBookmarkData();
+}
+
+BookmarkEditor::BookmarkEditor(ListViewItem *item, QWidget *parent, const char *name)
+ : KDialogBase(parent, name, true, i18n("FTP Bookmark Editor"), Ok|Apply|Cancel, Ok, true),
+ m_activeSite(0),
+ m_activeItem(item),
+ m_tree(0L),
+ m_portChanged(false)
+{
+ setCaption(m_activeItem->text(0));
+
+ // We operate on a copy of the bookmarks
+ m_bookmarks = new KFTPBookmarks::Manager(*KFTPBookmarks::Manager::self());
+
+ QHBoxLayout *winLayout = new QHBoxLayout(this, 0, KDialog::spacingHint());
+
+ m_properties = new BookmarkProperties(this);
+ setMainWidget(m_properties);
+ winLayout->addWidget(m_properties);
+
+ initDialog();
+
+ m_activeSite = m_activeItem->m_site;
+
+ showActiveNode();
+}
+
+BookmarkEditor::~BookmarkEditor()
+{
+ delete m_bookmarks;
+}
+
+void BookmarkEditor::initDialog()
+{
+ m_properties->tabList->setTabIconSet(m_properties->general, loadSmallIcon("kfm"));
+ m_properties->tabList->setTabIconSet(m_properties->advanced, loadSmallIcon("contents"));
+ m_properties->tabList->setTabIconSet(m_properties->keepalive, loadSmallIcon("clock"));
+ m_properties->protoAdvanced->setIconSet(loadSmallIcon("configure"));
+ m_properties->retryGroup->setEnabled(false);
+ m_properties->defLocalDir->setMode(KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly );
+
+ connect(m_properties->anonLogin, SIGNAL(clicked()), this, SLOT(slotChangeAnonLogin()));
+ connect(m_properties->doRetry, SIGNAL(clicked()), this, SLOT(slotChangeActiveRetryGroup()));
+ connect(m_properties->doKeepalive, SIGNAL(clicked()), this, SLOT(slotChangeActiveKeepaliveGroup()));
+ connect(m_properties->protoAdvanced, SIGNAL(clicked()), this, SLOT(slotProtoAdvancedClicked()));
+ connect(m_properties->serverProtocol, SIGNAL(activated(int)), this, SLOT(slotChangeServerProtocol(int)));
+ connect(m_properties->serverPort, SIGNAL(valueChanged(int)), this, SLOT(slotPortChanged()));
+
+ connect(this, SIGNAL(applyClicked()), this, SLOT(slotSaveActiveNode()));
+ connect(this, SIGNAL(okClicked()), this, SLOT(slotSaveActiveNode()));
+
+ // Populate charsets
+ QStringList charsets = KGlobal::charsets()->descriptiveEncodingNames();
+ m_properties->serverEncoding->insertStringList(charsets);
+
+ // Deactivate everything until an item gets selected
+ m_properties->setEnabled(false);
+}
+
+void BookmarkEditor::refresh()
+{
+ m_tree->clear();
+ m_tree->fillBookmarkData();
+}
+
+void BookmarkEditor::slotImportWizard()
+{
+ ImportWizard *wizard = new ImportWizard(this);
+
+ if (wizard->exec() == QDialog::Accepted) {
+ // Refresh bookmarks
+ m_bookmarks->setBookmarks(KFTPBookmarks::Manager::self());
+
+ m_tree->clear();
+ m_tree->fillBookmarkData();
+ }
+
+ delete wizard;
+}
+
+void BookmarkEditor::slotExportWizard()
+{
+ if (KMessageBox::questionYesNo(0, i18n("<qt>You are about to export your KFTPGrabber bookmarks. They may contain passwords or sensitive X509 certificates; exporting your bookmarks may compromise their safety.<br><br>Are you sure?</qt>"), i18n("Export Bookmarks")) == KMessageBox::No) {
+ return;
+ }
+
+ QString savePath = KFileDialog::getSaveFileName(QString::null, "*.xml|KFTPGrabber Bookmarks", 0, i18n("Export Bookmarks"));
+
+ if (!savePath.isEmpty()) {
+ // Save and copy the bookmarks
+ KFTPBookmarks::Manager::self()->save();
+ KIO::copy(KURL(getStoreDir("bookmarks.xml")), KURL(savePath), false);
+ }
+}
+
+void BookmarkEditor::slotNewAction(ListViewItem *item, KFTPBookmarks::Site *site)
+{
+ // Display the new server's properties
+ m_activeItem = item;
+ m_activeSite = site;
+
+ showActiveNode();
+
+ // Set Focus to servername
+ m_properties->serverName->selectAll();
+ m_properties->serverName->setFocus();
+}
+
+void BookmarkEditor::slotDuplicateAction(ListViewItem *item, KFTPBookmarks::Site *site)
+{
+ m_activeItem = item;
+
+ // Display its properties
+ m_activeSite = site;
+
+ showActiveNode();
+}
+
+void BookmarkEditor::slotDeleteAction()
+{
+ m_activeItem = 0L;
+ m_properties->setEnabled(false);
+}
+
+void BookmarkEditor::slotSaveActiveNode()
+{
+ if (!m_activeItem) {
+ KFTPBookmarks::Manager::self()->setBookmarks(m_bookmarks);
+ return;
+ }
+
+ m_activeSite->setAttribute("name", m_properties->serverName->text());
+ m_activeSite->setProperty("host", m_properties->serverAddress->text());
+ m_activeSite->setProperty("port", m_properties->serverPort->value());
+ m_activeSite->setProperty("protocol", m_properties->serverProtocol->currentItem() == SP_SFTP ? "sftp" : "ftp");
+ m_activeSite->setProperty("use_tls", m_properties->serverProtocol->currentItem() == SP_SSL_EXPLICIT);
+ m_activeSite->setProperty("use_implicit", m_properties->serverProtocol->currentItem() == SP_SSL_IMPLICIT);
+ m_activeSite->setProperty("anonlogin", m_properties->anonLogin->isChecked());
+
+ m_activeSite->setProperty("username", m_properties->downUser->text());
+ m_activeSite->setProperty("password", encodePassword(m_properties->downPass->password()));
+
+ m_activeSite->setProperty("encoding", KGlobal::charsets()->encodingForName(m_properties->serverEncoding->currentText()));
+
+ // Only save the local dir if it differs from the default one
+ if (m_properties->defLocalDir->url() != KFTPCore::Config::defLocalDir())
+ m_activeSite->setProperty("deflocalpath", m_properties->defLocalDir->url());
+
+ m_activeSite->setProperty("defremotepath", m_properties->defRemoteDir->text());
+ m_activeSite->setProperty("description", m_properties->description->text());
+
+ m_activeSite->setProperty("doRetry", m_properties->doRetry->isChecked());
+ m_activeSite->setProperty("retrytime", m_properties->retryDelay->value());
+ m_activeSite->setProperty("retrycount", m_properties->retryCount->value());
+
+ m_activeSite->setProperty("doKeepalive", m_properties->doKeepalive->isChecked());
+ m_activeSite->setProperty("keepaliveTimeout", m_properties->keepaliveTimeout->value());
+
+ m_activeSite->setProperty("disablePASV", m_properties->disablePASV->isChecked());
+ m_activeSite->setProperty("disableEPSV", m_properties->disableEPSV->isChecked());
+ m_activeSite->setProperty("pasvSiteIp", m_properties->pasvSiteIp->isChecked());
+ m_activeSite->setProperty("disableForceIp", m_properties->disableForceIp->isChecked());
+ m_activeSite->setProperty("disableThreads", m_properties->threadsDisable->isChecked());
+ m_activeSite->setProperty("statListings", m_properties->statListings->isChecked());
+
+ // Update the ListView node
+ m_activeItem->setText(0, m_properties->serverName->text());
+
+ if (m_tree)
+ KFTPBookmarks::Manager::self()->setBookmarks(m_bookmarks);
+
+ showActiveNode();
+
+ // Save the bookmarks
+ KFTPBookmarks::Manager::self()->save();
+}
+
+void BookmarkEditor::showActiveNode()
+{
+ if (m_activeItem->m_type == BT_CATEGORY || !m_activeSite) {
+ m_properties->setEnabled(false);
+ return;
+ }
+
+ m_properties->setEnabled(true);
+
+ // Show all the data for the active node
+ m_properties->serverName->setText(m_activeSite->getAttribute("name"));
+ m_properties->serverAddress->setText(m_activeSite->getProperty("host"));
+
+ if (m_activeSite->getProperty("protocol") == "sftp") m_properties->serverProtocol->setCurrentItem(SP_SFTP);
+ else if (m_activeSite->getIntProperty("use_tls")) m_properties->serverProtocol->setCurrentItem(SP_SSL_EXPLICIT);
+ else if (m_activeSite->getIntProperty("use_implicit")) m_properties->serverProtocol->setCurrentItem(SP_SSL_IMPLICIT);
+ else m_properties->serverProtocol->setCurrentItem(SP_FTP);
+
+ slotChangeServerProtocol(m_properties->serverProtocol->currentItem());
+
+
+ m_properties->serverPort->setValue(m_activeSite->getIntProperty("port"));
+ m_portChanged = false;
+
+ m_properties->downUser->erase();
+ m_properties->downPass->erase();
+ m_properties->anonLogin->setChecked(m_activeSite->getIntProperty("anonlogin"));
+
+ slotChangeAnonLogin();
+
+ m_properties->downUser->setText(m_activeSite->getProperty("username"));
+ m_properties->downPass->insert(m_activeSite->getProperty("password"));
+
+ QString defLocalPath = m_activeSite->getProperty("deflocalpath");
+ if (defLocalPath.isEmpty())
+ defLocalPath = KFTPCore::Config::defLocalDir();
+
+ m_properties->defLocalDir->setURL(defLocalPath);
+ m_properties->defRemoteDir->setText(m_activeSite->getProperty("defremotepath"));
+ m_properties->description->setText(m_activeSite->getProperty("description"));
+
+ int retryTime = m_activeSite->getIntProperty("retrytime");
+ int retryCount = m_activeSite->getIntProperty("retrycount");
+
+ m_properties->doRetry->setChecked(m_activeSite->getIntProperty("doRetry"));
+
+ if (m_properties->doRetry->isChecked()) {
+ m_properties->retryGroup->setEnabled(true);
+ m_properties->retryDelay->setValue(retryTime);
+ m_properties->retryCount->setValue(retryCount);
+ } else {
+ m_properties->retryGroup->setEnabled(false);
+ m_properties->retryDelay->setValue(KFTPCore::Config::retryTime());
+ m_properties->retryCount->setValue(KFTPCore::Config::retryCount());
+ }
+
+ m_properties->doKeepalive->setChecked(m_activeSite->getIntProperty("doKeepalive"));
+
+ if (m_properties->doKeepalive->isChecked()) {
+ m_properties->keepaliveGroup->setEnabled(true);
+ m_properties->keepaliveTimeout->setValue(m_activeSite->getIntProperty("keepaliveTimeout"));
+ } else {
+ m_properties->keepaliveGroup->setEnabled(false);
+ m_properties->keepaliveTimeout->setValue(60);
+ }
+
+ QString serverEncoding = m_activeSite->getProperty("encoding");
+ if (serverEncoding.isEmpty())
+ serverEncoding = KFTPCore::Config::defEncoding();
+
+ serverEncoding = QString("%1 ( %2 )").arg(KGlobal::charsets()->languageForEncoding(serverEncoding)).arg(serverEncoding);
+ m_properties->serverEncoding->setCurrentText(serverEncoding);
+
+ m_properties->disablePASV->setChecked(m_activeSite->getIntProperty("disablePASV"));
+ m_properties->disableEPSV->setChecked(m_activeSite->getIntProperty("disableEPSV"));
+ m_properties->pasvSiteIp->setChecked(m_activeSite->getIntProperty("pasvSiteIp"));
+ m_properties->disableForceIp->setChecked(m_activeSite->getIntProperty("disableForceIp"));
+ m_properties->threadsDisable->setChecked(m_activeSite->getIntProperty("disableThreads"));
+ m_properties->statListings->setChecked(m_activeSite->getIntProperty("statListings"));
+}
+
+void BookmarkEditor::slotTreeClicked(QListViewItem *item)
+{
+ m_activeItem = static_cast<ListViewItem*>(item);
+
+ if ( !m_activeItem || m_activeItem->m_type == BT_CATEGORY ) {
+ // Deactivate all controls
+ m_properties->setEnabled(false);
+ return;
+ }
+
+ // Find the node and set it active
+ if (m_activeItem->m_type == BT_CATEGORY) {
+ // Category
+ m_activeSite = 0L;
+ } else {
+ // Server
+ m_activeSite = m_activeItem->m_site;
+ }
+
+ // Show the active node (if any)
+ showActiveNode();
+}
+
+void BookmarkEditor::slotChangeActiveRetryGroup()
+{
+ m_properties->retryGroup->setEnabled(m_properties->doRetry->isChecked());
+}
+
+void BookmarkEditor::slotChangeActiveKeepaliveGroup()
+{
+ m_properties->keepaliveGroup->setEnabled(m_properties->doKeepalive->isChecked());
+}
+
+void BookmarkEditor::slotChangeAnonLogin()
+{
+ static QString tmpUser, tmpPass;
+
+ if (m_properties->anonLogin->isChecked()) {
+ m_properties->downUser->setEnabled(false);
+ m_properties->downPass->setEnabled(false);
+ tmpUser = m_properties->downUser->text();
+ tmpPass = m_properties->downPass->text();
+ m_properties->downUser->setText("anonymous");
+
+ // Use the appropriate e-mail address for anonymous accounts
+ if (!KFTPCore::Config::anonMail().isEmpty())
+ m_properties->downPass->setText(KFTPCore::Config::anonMail());
+ else
+ m_properties->downPass->setText("userlogin@anonymo.us");
+ } else {
+ m_properties->downUser->setEnabled(true);
+ m_properties->downPass->setEnabled(true);
+ m_properties->downUser->setText(tmpUser);
+ m_properties->downPass->setText(tmpPass);
+ }
+}
+
+void BookmarkEditor::slotProtoAdvancedClicked()
+{
+ BookmarkEditorTLS *tlsDialog = new BookmarkEditorTLS(this);
+
+ // Initialize dialog
+ int mode = m_activeSite->getIntProperty("tls_data_mode");
+ bool useCert = m_activeSite->getIntProperty("use_cert");
+ QString certPath = m_activeSite->getProperty("tls_cert_path");
+
+ tlsDialog->setTLSMode(mode);
+ tlsDialog->setCertChecked(useCert);
+ if (useCert)
+ tlsDialog->setCertPath(certPath);
+ tlsDialog->slotChangeActiveX509Group();
+
+ if (tlsDialog->exec()) {
+ // Save the modifications
+ m_activeSite->setProperty("tls_data_mode", tlsDialog->getTLSMode());
+ m_activeSite->setProperty("use_cert", tlsDialog->isCertChecked());
+
+ if (tlsDialog->isCertChecked())
+ m_activeSite->setProperty("tls_cert_path", tlsDialog->getCertPath());
+ }
+
+ delete tlsDialog;
+}
+
+void BookmarkEditor::slotPortChanged()
+{
+ m_portChanged = true;
+}
+
+void BookmarkEditor::slotChangeServerProtocol(int item)
+{
+ // Enable/Disable the SSL/TLS settings if needed
+ m_properties->protoAdvanced->setEnabled( item == 1 || item == 2 );
+
+ // Set the default port
+ if (!m_portChanged) {
+ switch (item) {
+ case SP_SSL_IMPLICIT:
+ if (m_properties->serverPort->value() == 21 || m_properties->serverPort->value() == 22)
+ m_properties->serverPort->setValue(993);
+ break;
+ case SP_SFTP:
+ if (m_properties->serverPort->value() == 21 || m_properties->serverPort->value() == 993)
+ m_properties->serverPort->setValue(22);
+ break;
+ default:
+ if (m_properties->serverPort->value() == 22 || m_properties->serverPort->value() == 993)
+ m_properties->serverPort->setValue(21);
+ break;
+ }
+
+ m_portChanged = false;
+ }
+}
+
+}
+
+}
+
+#include "editor.moc"
diff --git a/kftpgrabber/src/widgets/bookmarks/editor.h b/kftpgrabber/src/widgets/bookmarks/editor.h
new file mode 100644
index 0000000..50b04aa
--- /dev/null
+++ b/kftpgrabber/src/widgets/bookmarks/editor.h
@@ -0,0 +1,133 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-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.
+ */
+
+#ifndef KFTPBOOKMARKEDITOR_H
+#define KFTPBOOKMARKEDITOR_H
+
+#include "ui/bookmark_properties.h"
+
+#include <kaction.h>
+#include <kdialogbase.h>
+
+#include <qlistview.h>
+#include <qdom.h>
+
+namespace KFTPBookmarks {
+ class Manager;
+ class Site;
+}
+
+namespace KFTPWidgets {
+
+namespace Bookmarks {
+
+class ListViewItem;
+class ListView;
+
+/**
+@author Jernej Kos
+*/
+class BookmarkEditor : public KDialogBase
+{
+Q_OBJECT
+public:
+ BookmarkEditor(QWidget *parent = 0, const char *name = 0);
+ BookmarkEditor(ListViewItem *item, QWidget *parent = 0, const char *name = 0);
+ ~BookmarkEditor();
+private:
+ enum BookmarkType {
+ BT_CATEGORY = 0,
+ BT_SERVER
+ };
+
+ enum ServerProtocol {
+ SP_FTP = 0,
+ SP_SSL_EXPLICIT,
+ SP_SSL_IMPLICIT,
+ SP_SFTP
+ };
+
+ KFTPBookmarks::Manager *m_bookmarks;
+ KFTPBookmarks::Site *m_activeSite;
+
+ ListViewItem *m_activeItem;
+
+ BookmarkProperties *m_properties;
+ ListView *m_tree;
+
+ bool m_portChanged;
+
+ /* Actions */
+ KAction *m_newAction;
+ KAction *m_renameAction;
+ KAction *m_deleteAction;
+ KAction *m_subCatAction;
+ KAction *m_copyAction;
+ KActionCollection *actionCollection();
+
+ // Some common stuff for the constructors
+ void initDialog();
+
+ void showActiveNode();
+public slots:
+ void refresh();
+private slots:
+ /* Action slots */
+ void slotNewAction(ListViewItem *item, KFTPBookmarks::Site *site);
+ void slotDeleteAction();
+ void slotDuplicateAction(ListViewItem *item, KFTPBookmarks::Site *site);
+
+ /* Other slots */
+ void slotChangeAnonLogin();
+ void slotProtoAdvancedClicked();
+ void slotChangeActiveRetryGroup();
+ void slotChangeActiveKeepaliveGroup();
+ void slotChangeServerProtocol(int item);
+ void slotPortChanged();
+
+ void slotTreeClicked(QListViewItem *item);
+
+ void slotImportWizard();
+ void slotExportWizard();
+
+ void slotSaveActiveNode();
+};
+
+}
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/bookmarks/editortls.cpp b/kftpgrabber/src/widgets/bookmarks/editortls.cpp
new file mode 100644
index 0000000..c299288
--- /dev/null
+++ b/kftpgrabber/src/widgets/bookmarks/editortls.cpp
@@ -0,0 +1,115 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-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 <qcheckbox.h>
+
+#include <kcombobox.h>
+#include <klocale.h>
+#include <kurlrequester.h>
+
+#include "kftpapi.h"
+#include "editortls.h"
+#include "kftpbookmarkeditortlswidget.h"
+#include "misc.h"
+
+using namespace KFTPGrabberBase;
+
+namespace KFTPWidgets {
+
+namespace Bookmarks {
+
+KActionCollection *BookmarkEditorTLS::actionCollection()
+{
+ return KFTPAPI::getInstance()->mainWindow()->actionCollection();
+}
+
+BookmarkEditorTLS::BookmarkEditorTLS(QWidget *parent, const char *name)
+ : KDialogBase(parent, name)
+{
+ m_mainWidget = new KFTPBookmarkEditorTLSWidget(this);
+ setMainWidget(m_mainWidget);
+
+ setCaption(i18n("SSL/TLS Settings"));
+ showButtonApply(false);
+
+ connect(m_mainWidget->useCert, SIGNAL(clicked()), this, SLOT(slotChangeActiveX509Group()));
+}
+
+BookmarkEditorTLS::~BookmarkEditorTLS()
+{
+ delete m_mainWidget;
+}
+
+void BookmarkEditorTLS::slotChangeActiveX509Group()
+{
+ m_mainWidget->certPath->setEnabled(m_mainWidget->useCert->isChecked());
+}
+
+int BookmarkEditorTLS::getTLSMode()
+{
+ return m_mainWidget->tlsMode->currentItem();
+}
+
+bool BookmarkEditorTLS::isCertChecked()
+{
+ return m_mainWidget->useCert->isChecked();
+}
+
+QString BookmarkEditorTLS::getCertPath()
+{
+ return m_mainWidget->certPath->url();
+}
+
+void BookmarkEditorTLS::setTLSMode(int mode)
+{
+ m_mainWidget->tlsMode->setCurrentItem(mode);
+}
+
+void BookmarkEditorTLS::setCertChecked(const bool checked)
+{
+ m_mainWidget->useCert->setChecked(checked);
+}
+
+void BookmarkEditorTLS::setCertPath(const QString &path)
+{
+ m_mainWidget->certPath->setURL(path);
+}
+
+}
+
+}
+
+#include "editortls.moc"
diff --git a/kftpgrabber/src/widgets/bookmarks/editortls.h b/kftpgrabber/src/widgets/bookmarks/editortls.h
new file mode 100644
index 0000000..3325946
--- /dev/null
+++ b/kftpgrabber/src/widgets/bookmarks/editortls.h
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-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.
+ */
+
+#ifndef KFTPBOOKMARKEDITORTLS_H
+#define KFTPBOOKMARKEDITORTLS_H
+
+#include "editor.h"
+#include "kftpbookmarkeditortlswidget.h"
+
+#include <kaction.h>
+#include <kdialogbase.h>
+
+#include <qlistview.h>
+#include <qdom.h>
+
+namespace KFTPWidgets {
+
+namespace Bookmarks {
+
+/**
+@author Jernej Kos
+*/
+class BookmarkEditorTLS : public KDialogBase
+{
+Q_OBJECT
+public:
+ BookmarkEditorTLS(QWidget *parent = 0, const char *name = 0);
+ ~BookmarkEditorTLS();
+
+ int getTLSMode();
+ bool isCertChecked();
+ QString getCertPath();
+
+ void setTLSMode(int mode);
+ void setCertChecked(const bool checked);
+ void setCertPath(const QString &path);
+private:
+ QDomNode m_activeNode;
+ QDomNode m_activeCategory;
+
+ KFTPBookmarkEditorTLSWidget *m_mainWidget;
+
+ KActionCollection *actionCollection();
+public slots:
+ void slotChangeActiveX509Group();
+};
+
+}
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/bookmarks/importwizard.cpp b/kftpgrabber/src/widgets/bookmarks/importwizard.cpp
new file mode 100644
index 0000000..aa30bee
--- /dev/null
+++ b/kftpgrabber/src/widgets/bookmarks/importwizard.cpp
@@ -0,0 +1,167 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "importwizard.h"
+#include "kftpapi.h"
+#include "kftppluginmanager.h"
+#include "interfaces/kftpbookmarkimportplugin.h"
+#include "misc.h"
+#include "kftpbookmarks.h"
+
+#include <qfileinfo.h>
+#include <qlabel.h>
+
+#include <kurlrequester.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kprogress.h>
+#include <kstandarddirs.h>
+
+using namespace KFTPGrabberBase;
+
+namespace KFTPWidgets {
+
+namespace Bookmarks {
+
+PluginListItem::PluginListItem(KListView *parent, KService::Ptr service)
+ : KListViewItem(parent, service->name(), service->comment()), m_service(service)
+{
+ setPixmap(0, loadSmallPixmap("filter"));
+}
+
+ImportWizard::ImportWizard(QWidget *parent, const char *name)
+ : KFTPBookmarkImportLayout(parent, name)
+{
+ m_pluginList->setFullWidth(true);
+ m_pluginList->setAllColumnsShowFocus(true);
+
+ connect(m_pluginList, SIGNAL(clicked(QListViewItem*)), this, SLOT(slotPluginsSelectionChanged(QListViewItem*)));
+
+ setNextEnabled(Step1, false);
+
+ // Set pixmap
+ QString pixmapPath = locate("appdata", "kftpgrabber-bi-wizard.png");
+ if (!pixmapPath.isNull()) {
+ QPixmap pix(pixmapPath);
+
+ m_wizardPixmap->setPixmap(pix);
+ m_wizardPixmap_2->setPixmap(pix);
+ m_wizardPixmap_3->setPixmap(pix);
+ }
+
+ // Disable useless help buttons
+ setHelpEnabled(Step1, false);
+ setHelpEnabled(Step2, false);
+ setHelpEnabled(Step3, false);
+
+ displayPluginList();
+}
+
+void ImportWizard::next()
+{
+ if (currentPage() == Step1) {
+ // Load the plugin
+ m_plugin = KFTPAPI::getInstance()->pluginManager()->loadImportPlugin(m_service);
+
+ if (!m_plugin) {
+ KMessageBox::error(0, i18n("Unable to load the selected import plugin."));
+ return;
+ } else {
+ // Get the default plugin path
+ m_importUrl->setURL("~/" + m_plugin->getDefaultPath());
+ }
+ } else if (currentPage() == Step2) {
+ // Check if the file exists
+ if (!QFileInfo(m_importUrl->url()).exists() || !QFileInfo(m_importUrl->url()).isReadable()) {
+ KMessageBox::error(0, i18n("The selected file does not exist or is not readable."));
+ return;
+ }
+ }
+
+ QWizard::next();
+
+ if (currentPage() == Step3) {
+ // Start the import
+ setBackEnabled(Step3, false);
+
+ connect(m_plugin, SIGNAL(progress(int)), this, SLOT(slotImportProgress(int)));
+ m_plugin->import(m_importUrl->url());
+ }
+}
+
+void ImportWizard::slotImportProgress(int progress)
+{
+ m_progressBar->setProgress(progress);
+
+ if (progress == 100) {
+ // Import complete
+ KMessageBox::information(0, i18n("Bookmark importing is complete."));
+
+ // Add the imported stuff to the current bookmarks
+ KFTPBookmarks::Manager::self()->importSites(m_plugin->getImportedXml().documentElement());
+
+ accept();
+ }
+}
+
+void ImportWizard::displayPluginList()
+{
+ KTrader::OfferList plugins = KFTPAPI::getInstance()->pluginManager()->getImportPlugins();
+
+ KTrader::OfferList::ConstIterator end(plugins.end());
+ for (KTrader::OfferList::ConstIterator i(plugins.begin()); i != end; ++i) {
+ KService::Ptr service = *i;
+
+ new PluginListItem(m_pluginList, service);
+ }
+}
+
+void ImportWizard::slotPluginsSelectionChanged(QListViewItem *i)
+{
+ if (i) {
+ PluginListItem *item = static_cast<PluginListItem*>(i);
+ m_service = item->m_service;
+
+ setNextEnabled(Step1, true);
+ } else {
+ setNextEnabled(Step1, false);
+ }
+}
+
+}
+
+}
+
+#include "importwizard.moc"
diff --git a/kftpgrabber/src/widgets/bookmarks/importwizard.h b/kftpgrabber/src/widgets/bookmarks/importwizard.h
new file mode 100644
index 0000000..9b74dd3
--- /dev/null
+++ b/kftpgrabber/src/widgets/bookmarks/importwizard.h
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPBOOKMARKIMPORTWIZARD_H
+#define KFTPBOOKMARKIMPORTWIZARD_H
+
+#include "kftpbookmarkimportlayout.h"
+
+#include <kparts/componentfactory.h>
+#include <klistview.h>
+
+class KFTPBookmarkImportPlugin;
+
+namespace KFTPWidgets {
+
+namespace Bookmarks {
+
+class PluginListItem : public KListViewItem
+{
+friend class ImportWizard;
+public:
+ PluginListItem(KListView *parent, KService::Ptr service);
+private:
+ KService::Ptr m_service;
+};
+
+/**
+ * This is a wizard used to import bookmarks via detected KParts plugins.
+ *
+ * @author Jernej Kos
+ */
+class ImportWizard : public KFTPBookmarkImportLayout
+{
+Q_OBJECT
+public:
+ ImportWizard(QWidget *parent = 0, const char *name = 0);
+private:
+ KService::Ptr m_service;
+ KFTPBookmarkImportPlugin *m_plugin;
+
+ void displayPluginList();
+private slots:
+ virtual void next();
+
+ void slotImportProgress(int progress);
+ void slotPluginsSelectionChanged(QListViewItem *i);
+};
+
+}
+
+}
+
+#endif
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"
diff --git a/kftpgrabber/src/widgets/bookmarks/listview.h b/kftpgrabber/src/widgets/bookmarks/listview.h
new file mode 100644
index 0000000..213ec03
--- /dev/null
+++ b/kftpgrabber/src/widgets/bookmarks/listview.h
@@ -0,0 +1,193 @@
+/*
+ * 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.
+ */
+
+#ifndef KFTPBOOKMARKEDITORLISTVIEW_H
+#define KFTPBOOKMARKEDITORLISTVIEW_H
+
+#include <qdom.h>
+#include <qtimer.h>
+
+#include "../listview.h"
+
+class KAction;
+class KActionCollection;
+class Sidebar;
+class KFTPSelectServerDialog;
+
+namespace KFTPBookmarks {
+ class Site;
+ class Manager;
+ class BookmarkEditor;
+ class Sidebar;
+}
+
+namespace KFTPWidgets {
+
+namespace Bookmarks {
+
+class ListView;
+
+class ListViewItem : public KListViewItem
+{
+friend class BookmarkEditor;
+friend class KFTPWidgets::Bookmarks::ListView;
+friend class Sidebar;
+friend class ::KFTPSelectServerDialog;
+public:
+ ListViewItem(QListView *parent, const QString &t1);
+ ListViewItem(QListViewItem *parent, const QString &t1);
+
+ int compare(QListViewItem *i, int col, bool) const;
+
+ void setSite(KFTPBookmarks::Site *site) { m_site = site; }
+ void setType(int type) { m_type = type; }
+private:
+ int m_type;
+ KFTPBookmarks::Site *m_site;
+};
+
+/**
+@author Jernej Kos
+*/
+class ListView : public KFTPWidgets::ListView
+{
+Q_OBJECT
+public:
+ ListView(KFTPBookmarks::Manager *bookmarks, QWidget *parent = 0, const char *name = 0);
+
+ /**
+ * Fill current treeview with all the bookmarks.
+ */
+ void fillBookmarkData();
+
+ /**
+ * This changes the auto-update behaviour of the ListView. If set to true, this
+ * list view will automaticly update when bookmarks are changed. Defaults
+ * to false.
+ *
+ * @param value True to enable auto update, false otherwise
+ */
+ void setAutoUpdate(bool value);
+
+ /**
+ * This changes the connect-on-click behaviour of the ListView. If set to true,
+ * a new remote session will be spawned whenever the users double clicks the
+ * bookmark.
+ *
+ * @param value True to enable connect on click, false otherwise
+ */
+ void setConnectBookmark(bool value);
+
+ /**
+ * Get the bookmarks, the listview operates on
+ */
+ KFTPBookmarks::Manager *getBookmarks();
+
+ /**
+ * Specifiy, whether an edit menuitem should be placed in the contextmenu
+ *
+ * @param value True to enable the edit menuitem, false otherwise
+ */
+ void setEditMenuItem(bool value);
+
+private:
+ enum BookmarkType {
+ BT_CATEGORY = 0,
+ BT_SERVER
+ };
+
+ bool m_autoUpdate;
+ bool m_connectBookmark;
+ bool m_editMenuItem;
+ QDragObject *m_dragObject;
+
+ /* Actions */
+ KAction *m_newAction;
+ KAction *m_renameAction;
+ KAction *m_deleteAction;
+ KAction *m_subCatAction;
+ KAction *m_copyAction;
+
+ /* Auto open categories support */
+ QListViewItem *m_dropItem;
+ QListViewItem* m_currentBeforeDropItem;
+ QTimer *m_openTimer;
+
+ /* Specifies, on which bookmarks we operate */
+ KFTPBookmarks::Manager *m_bookmarks;
+
+ KFTPBookmarks::Site *m_activeSite;
+ KFTPBookmarks::Site *m_activeCategory;
+ KFTPWidgets::Bookmarks::ListViewItem *m_activeItem;
+
+ KActionCollection *actionCollection();
+
+ /* Drag & drop support */
+ QDragObject *dragObject();
+ bool acceptDrag(QDropEvent *e) const;
+ void contentsDragEnterEvent(QDragEnterEvent *e);
+ void contentsDragMoveEvent(QDragMoveEvent *e);
+ void contentsDragLeaveEvent(QDragLeaveEvent*);
+private slots:
+ void slotDropped(QDropEvent *e, QListViewItem*);
+ void slotDoubleClicked(QListViewItem *item);
+ void slotOpenTimer();
+
+ void slotClicked(QListViewItem*);
+ void slotNewAction();
+ void slotRenameAction();
+ void slotDeleteAction();
+ void slotSubCatAction();
+ void slotDuplicateAction();
+ void slotContextMenu(QListViewItem*, const QPoint&, int col);
+
+ void slotAutoUpdate();
+ void slotBookmarkExecuted(QListViewItem*);
+signals:
+ void bookmarkMoved();
+ void bookmarkNew(ListViewItem*, KFTPBookmarks::Site*);
+ void bookmarkDeleted();
+ void bookmarkDuplicated(ListViewItem*, KFTPBookmarks::Site*);
+ void bookmarkClicked(QListViewItem*);
+
+ void categoryRenamed();
+};
+
+}
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/bookmarks/sidebar.cpp b/kftpgrabber/src/widgets/bookmarks/sidebar.cpp
new file mode 100644
index 0000000..21ee0d9
--- /dev/null
+++ b/kftpgrabber/src/widgets/bookmarks/sidebar.cpp
@@ -0,0 +1,158 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2004 by the KFTPGrabber developers
+ * 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 <qlayout.h>
+#include <qsplitter.h>
+#include <qvbox.h>
+
+#include <kaction.h>
+#include <klocale.h>
+#include <ktoolbar.h>
+
+#include "kftpapi.h"
+#include "kftpbookmarks.h"
+#include "editor.h"
+#include "listview.h"
+#include "misc.h"
+
+#include "sidebar.h"
+
+using namespace KFTPGrabberBase;
+
+namespace KFTPWidgets {
+
+namespace Bookmarks {
+
+KActionCollection *Sidebar::actionCollection()
+{
+ return KFTPAPI::getInstance()->mainWindow()->actionCollection();
+}
+
+Sidebar::Sidebar(QWidget *parent, const char *name)
+ : QWidget(parent, name)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+
+ m_toolBar = new KToolBar(this, "bookmarkToolBar");
+ m_toolBar->setIconSize(16);
+ layout->addWidget(m_toolBar);
+
+ // Create the list view for editing bookmarks
+ m_tree = new ListView(KFTPBookmarks::Manager::self(), this);
+ m_tree->setAutoUpdate(true);
+ m_tree->setConnectBookmark(true);
+ m_tree->setEditMenuItem(true);
+
+ layout->addWidget(m_tree);
+
+ m_editAction = new KAction(i18n("&Edit..."), "edit", KShortcut(), this, SLOT(slotEditAction()), actionCollection(), "bookmark_edit2");
+ connect(m_tree, SIGNAL(bookmarkClicked(QListViewItem*)), this, SLOT(slotClicked(QListViewItem*)));
+ connect(m_tree, SIGNAL(bookmarkNew(ListViewItem*, KFTPBookmarks::Site*)), this, SLOT(slotNewAction(ListViewItem*, KFTPBookmarks::Site*)));
+
+ // Get the new bookmark data
+ m_tree->fillBookmarkData();
+
+ // Init the Actions
+ slotClicked(0L);
+
+ setMinimumWidth(200);
+}
+
+Sidebar::~Sidebar()
+{
+}
+
+void Sidebar::refresh()
+{
+ m_tree->clear();
+ m_tree->fillBookmarkData();
+}
+
+void Sidebar::slotEditAction()
+{
+ ListViewItem* item = static_cast<ListViewItem*>(m_tree->selectedItems().at(0));
+
+ if (item) {
+ BookmarkEditor *editor = new BookmarkEditor(item, this);
+
+ editor->exec();
+ delete editor;
+
+ // Update the bookmarks globaly
+ KFTPBookmarks::Manager::self()->emitUpdate();
+ }
+}
+
+void Sidebar::slotNewAction(ListViewItem*, KFTPBookmarks::Site *site)
+{
+ BookmarkEditor *editor = new BookmarkEditor(static_cast<ListViewItem*>(m_tree->selectedItems().at(0)), this);
+
+ if (!editor->exec()) {
+ // If the user clicks Abort, remove the newly created server
+ KFTPBookmarks::Manager::self()->delSite(site);
+ }
+
+ delete editor;
+}
+
+void Sidebar::slotClicked(QListViewItem *item)
+{
+ // When nodes are expanded, item is 0, although an item is still selected, so grab it here
+ item = m_tree->selectedItems().at(0);
+
+ // Enable/Disable actions for the toolbar
+ if (!item) {
+ actionCollection()->action("bookmark_delete")->setEnabled(false);
+ actionCollection()->action("bookmark_subcat")->setEnabled(true);
+ m_editAction->setEnabled(false);
+ return;
+ }
+
+ actionCollection()->action("bookmark_delete")->setEnabled(true);
+
+ if (static_cast<ListViewItem*>(item)->m_type == BT_CATEGORY) {
+ m_editAction->setEnabled(false);
+ actionCollection()->action("bookmark_subcat")->setEnabled(true);
+ } else {
+ m_editAction->setEnabled(true);
+ actionCollection()->action("bookmark_subcat")->setEnabled(false);
+ }
+}
+
+}
+
+}
+
+#include "sidebar.moc"
diff --git a/kftpgrabber/src/widgets/bookmarks/sidebar.h b/kftpgrabber/src/widgets/bookmarks/sidebar.h
new file mode 100644
index 0000000..ef08d3e
--- /dev/null
+++ b/kftpgrabber/src/widgets/bookmarks/sidebar.h
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2004 by the KFTPGrabber developers
+ * 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.
+ */
+
+#ifndef KFTPBOOKMARKSIDEBAR_H
+#define KFTPBOOKMARKSIDEBAR_H
+
+namespace KFTPBookmarks {
+ class Site;
+}
+
+class KAction;
+class KToolBar;
+
+namespace KFTPWidgets {
+
+namespace Bookmarks {
+
+class ListViewItem;
+class ListView;
+
+/**
+@author Markus Brueffer
+*/
+class Sidebar : public QWidget
+{
+Q_OBJECT
+public:
+ Sidebar(QWidget *parent = 0, const char *name = 0);
+ ~Sidebar();
+
+private:
+ enum BookmarkType {
+ BT_CATEGORY = 0,
+ BT_SERVER
+ };
+
+ KToolBar *m_toolBar;
+ ListView *m_tree;
+
+ KAction *m_editAction;
+ KActionCollection *actionCollection();
+public slots:
+ void refresh();
+private slots:
+ void slotClicked(QListViewItem*);
+
+ /* Action slots */
+ void slotEditAction();
+ void slotNewAction(ListViewItem *item, KFTPBookmarks::Site *site);
+};
+
+}
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/browser/Makefile.am b/kftpgrabber/src/widgets/browser/Makefile.am
new file mode 100644
index 0000000..2b9c987
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/Makefile.am
@@ -0,0 +1,13 @@
+INCLUDES = -I$(srcdir)/../.. -I../.. \
+ -I$(srcdir)/../../engine \
+ -I$(srcdir)/../../misc \
+ -I$(srcdir)/.. \
+ -I$(srcdir)/../../ui -I../../ui \
+ $(all_includes)
+
+METASOURCES = AUTO
+noinst_LIBRARIES = libbrowser.a
+noinst_HEADERS = view.h actions.h treeview.h propsplugin.h \
+ filterwidget.h detailsview.h locationnavigator.h dirlister.h
+libbrowser_a_SOURCES = view.cpp actions.cpp treeview.cpp \
+ propsplugin.cpp filterwidget.cpp detailsview.cpp locationnavigator.cpp dirlister.cpp
diff --git a/kftpgrabber/src/widgets/browser/actions.cpp b/kftpgrabber/src/widgets/browser/actions.cpp
new file mode 100644
index 0000000..cc9fc8c
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/actions.cpp
@@ -0,0 +1,764 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "browser/actions.h"
+#include "browser/view.h"
+#include "browser/detailsview.h"
+#include "browser/propsplugin.h"
+#include "browser/filterwidget.h"
+
+#include "widgets/quickconnect.h"
+#include "widgets/popupmessage.h"
+
+#include "kftpbookmarks.h"
+#include "kftpqueue.h"
+#include "kftpapi.h"
+#include "kftpsession.h"
+#include "verifier.h"
+#include "mainactions.h"
+
+#include "misc.h"
+#include "misc/config.h"
+#include "misc/filter.h"
+#include "misc/customcommands/manager.h"
+
+#include <kglobal.h>
+#include <kcharsets.h>
+#include <kapplication.h>
+#include <kmainwindow.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kpopupmenu.h>
+#include <kinputdialog.h>
+#include <kpropertiesdialog.h>
+#include <kio/job.h>
+#include <kshred.h>
+#include <klineedit.h>
+#include <kfiledialog.h>
+#include <kstandarddirs.h>
+
+#include <qdir.h>
+#include <qclipboard.h>
+
+using namespace KFTPGrabberBase;
+using namespace KFTPEngine;
+using namespace KFTPCore;
+using namespace KFTPCore::Filter;
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+Actions::Actions(View *parent)
+ : QObject(parent),
+ m_view(parent)
+{
+}
+
+void Actions::initActions()
+{
+ m_actionCollection = new KActionCollection(m_view, this);
+
+ // Create all the actions
+ m_goUpAction = KStdAction::up(this, SLOT(slotGoUp()), m_actionCollection, "go_up");
+ m_goBackAction = KStdAction::back(this, SLOT(slotGoBack()), m_actionCollection, "go_back");
+ m_goForwardAction = KStdAction::forward(this, SLOT(slotGoForward()), m_actionCollection, "go_forward");
+ m_goHomeAction = KStdAction::home(this, SLOT(slotGoHome()), m_actionCollection, "go_home");
+
+ m_reloadAction = KStdAction::redisplay(this, SLOT(slotReload()), m_actionCollection, "reload");
+ m_reloadAction->setText(i18n("&Reload"));
+ m_reloadAction->setShortcut(KShortcut(Qt::Key_F5));
+
+ m_abortAction = new KAction(i18n("&Abort"), "stop", KShortcut(), this, SLOT(slotAbort()), m_actionCollection, "abort");
+ m_toggleTreeViewAction = new KToggleAction(i18n("&Show Tree View"), "view_tree", KShortcut(), this, SLOT(slotShowHideTree()), m_actionCollection, "toggle_tree_view");
+ m_toggleFilterAction = new KToggleAction(i18n("Show &Filter"), "filter", KShortcut(), this, SLOT(slotShowHideFilter()), m_actionCollection, "toggle_filter");
+
+ m_renameAction = new KAction(i18n("&Rename"), KShortcut(Qt::Key_F2), this, SLOT(slotRename()), m_actionCollection, "edit_rename");
+ m_deleteAction = new KAction(i18n("&Delete"), "editdelete", KShortcut(Qt::Key_Delete), this, SLOT(slotDelete()), m_actionCollection, "edit_delete");
+ m_propsAction = new KAction(i18n("&Properties"), KShortcut(), this, SLOT(slotProps()), m_actionCollection, "edit_properties");
+ m_shredAction = new KAction(i18n("&Shred"), "editshred", KShortcut(), this, SLOT(slotShred()), m_actionCollection, "edit_shred");
+
+ m_copyAction = KStdAction::copy(this, SLOT(slotCopy()), m_actionCollection, "edit_copy");
+ m_pasteAction = KStdAction::paste(this, SLOT(slotPaste()), m_actionCollection, "edit_paste");
+
+ m_filterActions = new KActionMenu(i18n("&Filter Options"), "", m_actionCollection, "edit_filter_options");
+ m_alwaysSkipAction = new KAction(i18n("Always &skip this file when queuing"), KShortcut(), this, SLOT(slotAlwaysSkip()), m_actionCollection);
+ m_topPriorityAction = new KAction(i18n("Make this file &top priority"), KShortcut(), this, SLOT(slotTopPriority()), m_actionCollection);
+ m_lowPriorityAction = new KAction(i18n("Make this file &lowest priority"), KShortcut(), this, SLOT(slotLowPriority()), m_actionCollection);
+
+ m_filterActions->insert(m_alwaysSkipAction);
+ m_filterActions->insert(m_topPriorityAction);
+ m_filterActions->insert(m_lowPriorityAction);
+
+ m_transferAction = new KAction(i18n("&Transfer"), KShortcut(), this, SLOT(slotTransfer()), m_actionCollection, "transfer");
+ m_queueTransferAction = new KAction(i18n("&Queue Transfer"), "queue", KShortcut(), this, SLOT(slotQueueTransfer()), m_actionCollection, "queue_transfer");
+ m_createDirAction = new KAction(i18n("&Create Directory..."), "folder_new", KShortcut(), this, SLOT(slotCreateDir()), m_actionCollection, "create_dir");
+ m_fileEditAction = new KAction(i18n("&Open file"), "fileopen", KShortcut(), this, SLOT(slotFileEdit()), m_actionCollection, "open_file");
+ m_verifyAction = new KAction(i18n("&Verify..."), "ok", KShortcut(), this, SLOT(slotVerify()), m_actionCollection, "verify");
+
+ populateEncodings();
+
+ m_moreActions = new KActionMenu(i18n("&More Actions"), "configure", this);
+ m_rawCmdAction = new KAction(i18n("&Manual Command Entry..."), "openterm", KShortcut(), this, SLOT(slotRawCmd()), m_actionCollection, "send_raw_cmd");
+ m_exportListingAction = new KAction(i18n("&Export Directory Listing..."), "", KShortcut(), this, SLOT(slotExportListing()), m_actionCollection, "export_listing");
+ m_showHiddenFilesAction = new KToggleAction(i18n("Show &Hidden Files && Directories"), KShortcut(), this, SLOT(slotShowHiddenFiles()), m_actionCollection, "show_hidden");
+ m_openExternalAction = new KAction(i18n("Open current directory in &Konqueror..."), "konqueror", KShortcut(), this, SLOT(slotOpenExternal()), m_actionCollection, "open_konqi");
+
+ m_markItemsAction = new KAction(i18n("Compare &selected items"), "", KShortcut(Qt::Key_Space), this, SLOT(slotMarkItems()), m_actionCollection, "compare_selected");
+ m_compareAction = new KAction(i18n("Compare &directories"), "", KShortcut(), this, SLOT(slotCompare()), m_actionCollection, "compare_dirs");
+
+ m_showHiddenFilesAction->setChecked(KFTPCore::Config::showHiddenFiles());
+
+ m_rawCommandsMenu = CustomCommands::Manager::self()->categories(i18n("Send &Raw Command"), m_view->getSession());
+ m_rawCommandsMenu->insert(m_rawCmdAction, 0);
+ m_rawCommandsMenu->popupMenu()->insertSeparator(1);
+
+ m_moreActions->insert(m_rawCommandsMenu);
+ m_moreActions->insert(m_changeEncodingAction);
+ m_moreActions->popupMenu()->insertSeparator();
+ m_moreActions->insert(m_exportListingAction);
+ m_moreActions->insert(m_openExternalAction);
+ m_moreActions->insert(m_markItemsAction);
+ m_moreActions->insert(m_compareAction);
+ m_moreActions->popupMenu()->insertSeparator();
+ m_moreActions->insert(m_showHiddenFilesAction);
+
+ m_moreActions->setStickyMenu(true);
+ m_moreActions->setDelayed(false);
+
+ m_siteChangeAction = new KActionMenu(i18n("&Change Site"), "goto", this);
+ m_quickConnectAction = new KAction(i18n("&Quick Connect..."), "connect_creating", KShortcut(), this, SLOT(slotQuickConnect()), m_actionCollection, "quick_connect");
+ m_connectAction = new KActionMenu(i18n("&Connect To"), this);
+ m_disconnectAction = new KAction(i18n("&Disconnect"), "connect_no", KShortcut(), this, SLOT(slotDisconnect()), m_actionCollection, "disconnect");
+
+ m_siteChangeAction->insert(m_quickConnectAction);
+ m_siteChangeAction->insert(m_connectAction);
+ m_siteChangeAction->insert(m_disconnectAction);
+ m_siteChangeAction->setStickyMenu(true);
+ m_siteChangeAction->setDelayed(false);
+
+ // Populate bookmarks
+ KFTPBookmarks::Manager::self()->guiPopulateBookmarksMenu(m_connectAction, QDomNode(), false, m_view->m_session);
+}
+
+void Actions::populateEncodings()
+{
+ // Charsets
+ m_changeEncodingAction = new KActionMenu(i18n("Change Remote &Encoding"), "charset", m_actionCollection, "changeremoteencoding");
+ m_changeEncodingAction->setDelayed(false);
+
+ KPopupMenu *menu = m_changeEncodingAction->popupMenu();
+ menu->clear();
+
+ QStringList charsets = KGlobal::charsets()->descriptiveEncodingNames();
+ int count = 0;
+ for (QStringList::iterator i = charsets.begin(); i != charsets.end(); ++i)
+ menu->insertItem(*i, this, SLOT(slotCharsetChanged(int)), 0, ++count);
+
+ menu->insertSeparator();
+ menu->insertItem(i18n("Default"), this, SLOT(slotCharsetReset(int)), 0, ++count);
+ menu->setItemChecked(count, true);
+
+ m_defaultCharsetOption = count;
+ m_curCharsetOption = count;
+}
+
+void Actions::updateActions()
+{
+ m_goUpAction->setEnabled(m_view->url().upURL() != m_view->url());
+
+ // History
+ int index = 0;
+ const QValueList<LocationNavigator::Element> list = m_view->history(index);
+
+ m_goBackAction->setEnabled(index < static_cast<int>(list.count()) - 1);
+ m_goForwardAction->setEnabled(index > 0);
+
+ m_abortAction->setEnabled(m_view->m_ftpClient->socket()->isBusy());
+ m_toggleTreeViewAction->setEnabled(true);
+ m_toggleFilterAction->setEnabled(true);
+
+ m_quickConnectAction->setEnabled(m_view->url().isLocalFile());
+ m_connectAction->setEnabled(true);
+ m_disconnectAction->setEnabled(m_view->m_ftpClient->socket()->isConnected());
+
+ const KFileItemList *selectedItems = m_view->selectedItems();
+
+ if (selectedItems->count() == 1) {
+ m_fileEditAction->setEnabled(!selectedItems->getFirst()->isDir());
+ m_verifyAction->setEnabled(selectedItems->getFirst()->isLocalFile() && selectedItems->getFirst()->name(true).right(3) == "sfv");
+ } else {
+ m_fileEditAction->setEnabled(false);
+ m_verifyAction->setEnabled(false);
+ }
+
+ // Check if we can transfer anything
+ KFTPSession::Session *session = m_view->m_session;
+ KFTPSession::Session *opposite = KFTPSession::Manager::self()->getActive(oppositeSide(m_view->m_session->getSide()));
+
+ m_renameAction->setEnabled(session->isConnected());
+ m_deleteAction->setEnabled(session->isConnected());
+ m_propsAction->setEnabled(true);
+ m_shredAction->setEnabled(!session->isRemote());
+ m_copyAction->setEnabled(true);
+ m_pasteAction->setEnabled(true);
+
+ if ((!session->isRemote() && !opposite->isRemote()) ||
+ (
+ (session->isRemote() && opposite->isRemote()) &&
+ (
+ session->getClient()->socket()->protocolName() != opposite->getClient()->socket()->protocolName() ||
+ !(session->getClient()->socket()->features() & SF_FXP_TRANSFER)
+ )
+ )
+ ) {
+ m_queueTransferAction->setEnabled(false);
+ m_transferAction->setEnabled(false);
+ } else {
+ m_queueTransferAction->setEnabled(true);
+ m_transferAction->setEnabled(true);
+ }
+
+ if (!session->isRemote() || session->getClient()->socket()->isConnected())
+ m_createDirAction->setEnabled(true);
+ else
+ m_createDirAction->setEnabled(false);
+
+ m_changeEncodingAction->setEnabled(session->isRemote());
+ m_rawCmdAction->setEnabled(!m_view->url().isLocalFile() && m_view->m_ftpClient->socket()->features() & SF_RAW_COMMAND);
+ m_rawCommandsMenu->setEnabled(m_rawCmdAction->isEnabled());
+ m_openExternalAction->setEnabled(!session->isRemote());
+}
+
+void Actions::slotGoUp()
+{
+ m_view->goUp();
+}
+
+void Actions::slotGoBack()
+{
+ m_view->goBack();
+}
+
+void Actions::slotGoForward()
+{
+ m_view->goForward();
+}
+
+void Actions::slotReload()
+{
+ m_view->reload();
+}
+
+void Actions::slotGoHome()
+{
+ m_view->goHome();
+}
+
+void Actions::slotQuickConnect()
+{
+ // Create/get the new dialog
+ QuickConnectDialog *quickConnect = new QuickConnectDialog(m_view);
+
+ if (quickConnect->exec() == KDialogBase::Accepted) {
+ // Get the url and connect
+ if (m_view->m_ftpClient->socket()->isConnected()) {
+ if (KFTPCore::Config::confirmDisconnects() && KMessageBox::warningYesNo(0, i18n("Do you want to drop current connection?")) == KMessageBox::No)
+ return;
+
+ m_view->m_session->disconnectAllConnections();
+ }
+
+ m_view->m_session->setSite(0);
+
+ quickConnect->setupClient(m_view->m_ftpClient);
+ m_view->m_ftpClient->connect(quickConnect->getUrl());
+ }
+
+ delete quickConnect;
+}
+
+void Actions::slotDisconnect()
+{
+ if (m_view->m_ftpClient->socket()->isConnected()) {
+ if (KFTPCore::Config::confirmDisconnects() && KMessageBox::warningYesNo(0, i18n("Do you want to drop current connection?")) == KMessageBox::No)
+ return;
+
+ m_view->m_session->disconnectAllConnections();
+ }
+}
+
+void Actions::slotShred()
+{
+ // Shred the file
+ if (KMessageBox::warningContinueCancel(0, i18n("Are you sure you want to SHRED this file?"), i18n("Shred File"),KGuiItem(i18n("&Shred"), "editshred")) == KMessageBox::Cancel)
+ return;
+
+ KShred::shred(m_view->selectedItems()->getFirst()->url().path());
+}
+
+void Actions::slotRename()
+{
+ KFTPWidgets::Browser::DetailsView *view = m_view->getDetailsView();
+
+ // Rename the first file in the current selection
+ view->rename(view->KListView::selectedItems().at(0), 0);
+
+ // Enhanced rename: Don't highlight the file extension. (from Konqueror)
+ KLineEdit *le = view->renameLineEdit();
+
+ if (le) {
+ const QString txt = le->text();
+ QString pattern;
+ KMimeType::diagnoseFileName(txt, pattern);
+
+ if (!pattern.isEmpty() && pattern.at(0) == '*' && pattern.find('*',1) == -1)
+ le->setSelection(0, txt.length()-pattern.stripWhiteSpace().length()+1);
+ else {
+ int lastDot = txt.findRev('.');
+
+ if (lastDot > 0)
+ le->setSelection(0, lastDot);
+ }
+ }
+}
+
+void Actions::slotDelete()
+{
+ KFTPSession::Session *session = m_view->getSession();
+
+ // Delete a file or directory
+ KURL::List selection = m_view->selectedURLs();
+ KURL::List::ConstIterator i = selection.begin();
+ QStringList prettyList;
+ for (; i != selection.end(); ++i) {
+ prettyList.append((*i).pathOrURL());
+ }
+
+ if (KMessageBox::warningContinueCancelList(0,
+ i18n("Do you really want to delete this item?", "Do you really want to delete these %n items?", prettyList.count()),
+ prettyList,
+ i18n("Delete Files"),
+ KStdGuiItem::del(),
+ QString::null,
+ KMessageBox::Dangerous) == KMessageBox::Cancel)
+ return;
+
+ // Go trough all files and delete them
+ if (!session->isRemote()) {
+ KIO::del(selection);
+ } else {
+ KURL::List::Iterator end(selection.end());
+
+ for (KURL::List::Iterator i(selection.begin()); i != end; ++i) {
+ if (!(*i).isLocalFile())
+ session->getClient()->remove(KURL((*i).url()));
+ }
+ }
+}
+
+void Actions::slotCopy()
+{
+ QClipboard *cb = QApplication::clipboard();
+ cb->setData(m_view->getDetailsView()->dragObject(), QClipboard::Clipboard);
+}
+
+void Actions::slotPaste()
+{
+ // Decode the data and try to init transfer
+ KIO::MetaData p_meta;
+ KURL::List p_urls;
+
+ if (KURLDrag::decode(QApplication::clipboard()->data(), p_urls, p_meta)) {
+ // Add destination url and call the QueueManager
+ p_meta.insert("DestURL", m_view->url().url());
+ KURLDrag *drag = new KURLDrag(p_urls, p_meta, m_view, name());
+ KFTPQueue::Manager::self()->insertTransfer(drag);
+ }
+}
+
+void Actions::slotProps()
+{
+ // Show file properties
+ const KFileItemList *selectedItems = m_view->selectedItems();
+ KFileItem *item = selectedItems->getFirst();
+
+ if (selectedItems->count() == 0) {
+ if (m_view->url().isLocalFile())
+ item = new KFileItem(m_view->url(), 0, 0);
+ else
+ return;
+ }
+
+ // Show the dialog
+ KPropertiesDialog *propsDialog;
+
+ if (item->isLocalFile()) {
+ if (selectedItems->count() == 0)
+ propsDialog = new KPropertiesDialog(item);
+ else
+ propsDialog = new KPropertiesDialog(*selectedItems);
+ } else {
+ propsDialog = new KPropertiesDialog(item->name());
+ propsDialog->insertPlugin(new KFTPWidgets::Browser::PropsPlugin(propsDialog, *selectedItems));
+ propsDialog->insertPlugin(new KFTPWidgets::Browser::PermissionsPropsPlugin(propsDialog, *selectedItems, m_view->getSession()));
+ }
+
+ propsDialog->exec();
+}
+
+void Actions::addPriorityItems(int priority)
+{
+ // Add the files to skiplist
+ KURL::List selection = m_view->selectedURLs();
+ KURL::List::Iterator end(selection.end());
+
+ for (KURL::List::Iterator i(selection.begin()); i != end; ++i) {
+ Rule *rule = new Rule();
+
+ if (priority == 0) {
+ rule->setName(i18n("Skip '%1'").arg((*i).filename()));
+ const_cast<ConditionChain*>(rule->conditions())->append(new Condition(Filename, Condition::Is, (*i).filename()));
+ const_cast<ActionChain*>(rule->actions())->append(new Action(Action::Skip, QVariant()));
+ } else {
+ rule->setName(i18n("Priority '%1'").arg((*i).filename()));
+ const_cast<ConditionChain*>(rule->conditions())->append(new Condition(Filename, Condition::Is, (*i).filename()));
+ const_cast<ActionChain*>(rule->actions())->append(new Action(Action::Priority, priority));
+ }
+
+ Filters::self()->append(rule);
+ }
+}
+
+void Actions::slotAlwaysSkip()
+{
+ addPriorityItems(0);
+}
+
+void Actions::slotTopPriority()
+{
+ addPriorityItems(1);
+}
+
+void Actions::slotLowPriority()
+{
+ addPriorityItems(-1);
+}
+
+void Actions::slotTransfer()
+{
+ // Queue a transfer
+ KFileItemList list(*m_view->selectedItems());
+ KFileItemListIterator i(list);
+ KFileItem *item;
+ KFTPSession::Session *opposite = KFTPSession::Manager::self()->getActive(oppositeSide(m_view->m_session->getSide()));
+ KFTPQueue::Transfer *transfer = 0L;
+
+ while ((item = i.current()) != 0) {
+ KURL destinationUrl = opposite->getFileView()->url();
+ destinationUrl.addPath(item->name());
+
+ transfer = KFTPQueue::Manager::self()->spawnTransfer(
+ item->url(),
+ destinationUrl,
+ item->size(),
+ item->isDir(),
+ list.count() == 1,
+ true,
+ 0L,
+ true
+ );
+
+ ++i;
+ }
+
+ // Execute transfer
+ if (transfer)
+ static_cast<KFTPQueue::Site*>(transfer->parentObject())->delayedExecute();
+}
+
+void Actions::slotQueueTransfer()
+{
+ // Queue a transfer
+ KFileItemList list(*m_view->selectedItems());
+ KFileItemListIterator i(list);
+ KFileItem *item;
+ KFTPSession::Session *opposite = KFTPSession::Manager::self()->getActive(oppositeSide(m_view->m_session->getSide()));
+
+ while ((item = i.current()) != 0) {
+ KURL destinationUrl = opposite->getFileView()->url();
+ destinationUrl.addPath(item->name());
+
+ KFTPQueue::Manager::self()->spawnTransfer(
+ item->url(),
+ destinationUrl,
+ item->size(),
+ item->isDir(),
+ list.count() == 1,
+ true,
+ 0L,
+ list.count() > 1
+ );
+
+ ++i;
+ }
+}
+
+void Actions::slotCreateDir()
+{
+ // Create new directory
+ bool ok;
+ QString newDirName = KInputDialog::getText(i18n("Create Directory"), i18n("Directory name:"), "", &ok);
+
+ if (ok) {
+ KURL url = m_view->url();
+ url.addPath(newDirName);
+
+ if (url.isLocalFile())
+ KIO::mkdir(url);
+ else
+ m_view->m_ftpClient->mkdir(url);
+ }
+}
+
+void Actions::slotFileEdit()
+{
+ KFileItem *item = m_view->selectedItems()->getFirst();
+
+ if (!item->isDir()) {
+ if (item->isLocalFile()) {
+ item->run();
+ } else {
+ // Create a new transfer to download the file and open it
+ KFTPQueue::TransferFile *transfer = new KFTPQueue::TransferFile(KFTPQueue::Manager::self());
+ transfer->setSourceUrl(item->url());
+ transfer->setDestUrl(KURL(KGlobal::dirs()->saveLocation("tmp") + QString("%1-%2").arg(KApplication::randomString(7)).arg(item->name())));
+ transfer->addSize(item->size());
+ transfer->setTransferType(KFTPQueue::Download);
+ transfer->setOpenAfterTransfer(true);
+ KFTPQueue::Manager::self()->insertTransfer(transfer);
+
+ // Execute the transfer
+ transfer->delayedExecute();
+ }
+ }
+}
+
+void Actions::slotAbort()
+{
+ KFTPSession::Session *session = KFTPSession::Manager::self()->find(m_view);
+
+ // Abort the session
+ if (session)
+ session->abort();
+}
+
+void Actions::slotRawCmd()
+{
+ bool ok;
+ QString rawCmd = KInputDialog::getText(i18n("Send Raw Command"), i18n("Command:"), "", &ok);
+
+ if (ok)
+ m_view->m_ftpClient->raw(rawCmd);
+}
+
+void Actions::slotShowHideTree()
+{
+ m_view->setTreeVisible(m_toggleTreeViewAction->isChecked());
+}
+
+void Actions::slotShowHideFilter()
+{
+ if (m_toggleFilterAction->isChecked()) {
+ m_view->m_searchToolBar->show();
+ m_view->m_searchFilter->clear();
+ m_view->m_searchFilter->setFocus();
+ } else {
+ m_view->m_searchFilter->clear();
+ m_view->m_searchToolBar->hide();
+ }
+}
+
+void Actions::slotCharsetChanged(int id)
+{
+ if (!m_changeEncodingAction->popupMenu()->isItemChecked(id)) {
+ QStringList charsets = KGlobal::charsets()->descriptiveEncodingNames();
+ QString charset = KGlobal::charsets()->encodingForName(charsets[id - 1]);
+
+ // Set the current socket's charset
+ m_view->m_ftpClient->socket()->changeEncoding(charset);
+
+ // Update checked items
+ m_changeEncodingAction->popupMenu()->setItemChecked(id, true);
+ m_changeEncodingAction->popupMenu()->setItemChecked(m_curCharsetOption, false);
+ m_curCharsetOption = id;
+ }
+}
+
+void Actions::slotCharsetReset(int id)
+{
+ // Revert to default charset if possible
+ KFTPBookmarks::Site *site = m_view->m_session->getSite();
+
+ if (site) {
+ // Set the current socket's charset
+ m_view->m_ftpClient->socket()->changeEncoding(site->getProperty("encoding"));
+
+ // Update checked items
+ m_changeEncodingAction->popupMenu()->setItemChecked(id, true);
+ m_changeEncodingAction->popupMenu()->setItemChecked(m_curCharsetOption, false);
+ m_curCharsetOption = id;
+ }
+}
+
+void Actions::slotExportListing()
+{
+ QString savePath = KFileDialog::getSaveFileName(QString::null, "*.txt|Directory Dump", 0, i18n("Export Directory Listing"));
+
+ if (!savePath.isEmpty()) {
+ QFile file(savePath);
+
+ if (!file.open(IO_WriteOnly))
+ return;
+
+ QTextStream stream(&file);
+
+ KFileItemList list(*m_view->items());
+ KFileItemListIterator i(list);
+ KFileItem *item;
+
+ while ((item = i.current()) != 0) {
+ stream << item->permissionsString() << "\t";
+ stream << item->user() << "\t" << item->group() << "\t";
+ stream << item->timeString() << "\t";
+ stream << item->name() << "\t";
+ stream << "\n";
+
+ ++i;
+ }
+
+ file.flush();
+ file.close();
+ }
+}
+
+void Actions::slotVerify()
+{
+ KFTPWidgets::Verifier *verifier = new KFTPWidgets::Verifier();
+ verifier->setFile(m_view->selectedItems()->getFirst()->url().path());
+ verifier->exec();
+
+ delete verifier;
+}
+
+void Actions::slotShowHiddenFiles()
+{
+ m_view->setShowHidden(m_showHiddenFilesAction->isChecked());
+ m_view->reload();
+}
+
+void Actions::slotOpenExternal()
+{
+ KFileItem *folder = new KFileItem(m_view->url(), "inode/directory", S_IFDIR);
+ folder->run();
+}
+
+void Actions::slotMarkItems()
+{
+ KFileItemList list(*m_view->selectedItems());
+ KFileItemListIterator i(list);
+ KFileItem *item;
+ KFTPSession::Session *opposite = KFTPSession::Manager::self()->getActive(oppositeSide(m_view->m_session->getSide()));
+
+ DetailsView *tView = m_view->getDetailsView();
+ DetailsView *oView = opposite->getFileView()->getDetailsView();
+
+ while ((item = i.current()) != 0) {
+ tView->markItem(item);
+ oView->markItem(item->name());
+ ++i;
+ }
+}
+
+void Actions::slotCompare()
+{
+ KFTPSession::Session *opposite = KFTPSession::Manager::self()->getActive(oppositeSide(m_view->m_session->getSide()));
+
+ DetailsView *tView = m_view->getDetailsView();
+ DetailsView *oView = opposite->getFileView()->getDetailsView();
+
+ // All items in the other list view should be visible by default
+ QListViewItemIterator j(oView);
+ while (j.current()) {
+ KFileItem *oItem = static_cast<KFileListViewItem*>(*j)->fileInfo();
+ oView->setItemVisibility(oItem, true);
+
+ ++j;
+ }
+
+ // Compare the two listviews
+ QListViewItemIterator i(tView);
+ while (i.current()) {
+ KFileItem *tItem = static_cast<KFileListViewItem*>(*i)->fileInfo();
+
+ if (tItem) {
+ KFileItem *oItem = oView->fileItem(tItem->name());
+
+ if (oItem && (oItem->size() == tItem->size() || oItem->isDir())) {
+ tView->setItemVisibility(tItem, false);
+ oView->setItemVisibility(oItem, false);
+ } else {
+ tView->setItemVisibility(tItem, true);
+ }
+ }
+
+ ++i;
+ }
+
+ PopupMessage *popup = new PopupMessage(m_view->getStatusLabel(), m_view);
+ popup->setText(i18n("Identical files on both sides have been hidden. Only <b>different files</b> are now visible."));
+ popup->setImage(SmallIcon("info"));
+ popup->setShowCloseButton(false);
+ popup->setShowCounter(false);
+
+ popup->reposition();
+ popup->display();
+}
+
+}
+
+}
+
+#include "actions.moc"
diff --git a/kftpgrabber/src/widgets/browser/actions.h b/kftpgrabber/src/widgets/browser/actions.h
new file mode 100644
index 0000000..69434e4
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/actions.h
@@ -0,0 +1,189 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPFILEDIRVIEWACTIONS_H
+#define KFTPFILEDIRVIEWACTIONS_H
+
+#include <qobject.h>
+#include <kaction.h>
+#include <krun.h>
+#include <kservice.h>
+#include <kuserprofile.h>
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+class View;
+
+/**
+ * This class contains all per-view actions.
+ *
+ * @author Jernej Kos
+ */
+class Actions : public QObject
+{
+Q_OBJECT
+friend class View;
+friend class DetailsView;
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent Parent view widget
+ */
+ Actions(View *parent);
+
+ /**
+ * Initialize view's action collection and it's actions.
+ */
+ void initActions();
+
+ /**
+ * Properly enable/disable the available actions.
+ */
+ void updateActions();
+private:
+ KActionCollection *m_actionCollection;
+ View *m_view;
+
+ int m_curCharsetOption;
+ int m_defaultCharsetOption;
+
+ KAction *m_goUpAction;
+ KAction *m_goBackAction;
+ KAction *m_goForwardAction;
+ KAction *m_goHomeAction;
+ KAction *m_reloadAction;
+
+ KAction *m_abortAction;
+ KToggleAction *m_toggleTreeViewAction;
+ KToggleAction *m_toggleFilterAction;
+
+ KAction *m_renameAction;
+ KAction *m_deleteAction;
+ KAction *m_propsAction;
+ KAction *m_shredAction;
+
+ KAction *m_copyAction;
+ KAction *m_pasteAction;
+
+ KActionMenu *m_filterActions;
+ KAction *m_alwaysSkipAction;
+ KAction *m_topPriorityAction;
+ KAction *m_lowPriorityAction;
+
+ KAction *m_transferAction;
+ KAction *m_queueTransferAction;
+ KAction *m_createDirAction;
+ KAction *m_fileEditAction;
+ KAction *m_verifyAction;
+
+ KActionMenu *m_moreActions;
+ KActionMenu *m_rawCommandsMenu;
+ KAction *m_rawCmdAction;
+ KActionMenu *m_changeEncodingAction;
+ KAction *m_exportListingAction;
+ KToggleAction *m_showHiddenFilesAction;
+ KAction *m_openExternalAction;
+
+ KAction *m_markItemsAction;
+ KAction *m_compareAction;
+
+ KActionMenu *m_siteChangeAction;
+ KAction *m_quickConnectAction;
+ KActionMenu *m_connectAction;
+ KAction *m_disconnectAction;
+private:
+ /**
+ * Populates the encodings list.
+ */
+ void populateEncodings();
+
+ /**
+ * A helper function to add the currently selected item(s) to the
+ * priority list with the given priority.
+ *
+ * @param priority The priority to use
+ */
+ void addPriorityItems(int priority);
+private slots:
+ void slotGoUp();
+ void slotGoBack();
+ void slotGoForward();
+ void slotGoHome();
+ void slotReload();
+
+ void slotAbort();
+ void slotShowHideTree();
+ void slotShowHideFilter();
+
+ void slotRename();
+ void slotDelete();
+ void slotProps();
+ void slotShred();
+
+ void slotCopy();
+ void slotPaste();
+
+ void slotAlwaysSkip();
+ void slotTopPriority();
+ void slotLowPriority();
+
+ void slotTransfer();
+ void slotQueueTransfer();
+ void slotCreateDir();
+ void slotFileEdit();
+ void slotVerify();
+
+ void slotRawCmd();
+ void slotCharsetChanged(int);
+ void slotCharsetReset(int);
+ void slotExportListing();
+ void slotShowHiddenFiles();
+ void slotOpenExternal();
+
+ void slotMarkItems();
+ void slotCompare();
+
+ void slotQuickConnect();
+ void slotDisconnect();
+};
+
+}
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/browser/detailsview.cpp b/kftpgrabber/src/widgets/browser/detailsview.cpp
new file mode 100644
index 0000000..5206d3d
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/detailsview.cpp
@@ -0,0 +1,596 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "browser/detailsview.h"
+#include "browser/treeview.h"
+#include "browser/view.h"
+#include "browser/locationnavigator.h"
+#include "browser/dirlister.h"
+#include "browser/actions.h"
+
+#include "misc/config.h"
+#include "misc/kftpapi.h"
+#include "misc/filter.h"
+
+#include "kftpqueue.h"
+
+#include <qheader.h>
+#include <qpainter.h>
+
+#include <kpopupmenu.h>
+#include <kurldrag.h>
+
+using namespace KFTPCore::Filter;
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+DetailsView::DetailsView(QWidget *parent, View *view, KFTPSession::Session *session)
+ : KFileDetailView(parent, 0),
+ m_view(view),
+ m_treeView(0),
+ m_refreshing(false),
+ m_shouldDisableResize(true),
+ m_autoResizeEnabled(true)
+{
+ m_resizeTimer = new QTimer(this);
+ connect(m_resizeTimer, SIGNAL(timeout()), this, SLOT(updateColumnWidths()));
+
+ m_dirLister = new DirLister(this);
+ m_dirLister->setSession(session);
+
+ connect(m_dirLister, SIGNAL(clear()), this, SLOT(slotClear()));
+ connect(m_dirLister, SIGNAL(completed()), this, SLOT(slotCompleted()));
+ connect(m_dirLister, SIGNAL(deleteItem(KFileItem*)), this, SLOT(slotDeleteItem(KFileItem*)));
+ connect(m_dirLister, SIGNAL(refreshItems()), this, SLOT(slotRefreshItems()));
+ connect(m_dirLister, SIGNAL(siteChanged(const KURL&)), this, SLOT(slotSiteChanged(const KURL&)));
+
+ m_navigator = new LocationNavigator(this);
+
+ connect(m_navigator, SIGNAL(urlChanged(const KURL&)), this, SLOT(slotUrlChanged(const KURL&)));
+
+ connect(this, SIGNAL(executed(QListViewItem*)), this, SLOT(slotItemExecuted()));
+ connect(this, SIGNAL(returnPressed(QListViewItem*)), this, SLOT(slotItemExecuted()));
+ connect(this, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)), this, SLOT(slotContextMenu(KListView*, QListViewItem*, const QPoint&)));
+ connect(this, SIGNAL(itemRenamed(QListViewItem*, const QString&, int)), this, SLOT(slotItemRenamed(QListViewItem*, const QString&)));
+
+ // Setup the header
+ QHeader *viewHeader = header();
+ viewHeader->setResizeEnabled(true);
+ viewHeader->setMovingEnabled(false);
+
+ connect(viewHeader, SIGNAL(sizeChange(int, int, int)), this, SLOT(slotHeaderResized(int)));
+
+ // Set column width
+ setColumnWidthMode(NameColumn, QListView::Manual);
+ setColumnWidthMode(SizeColumn, QListView::Manual);
+ setColumnWidthMode(DateColumn, QListView::Manual);
+ setColumnWidthMode(PermissionsColumn, QListView::Manual);
+
+ // Set column alignments
+ setColumnAlignment(SizeColumn, Qt::AlignRight);
+ setColumnAlignment(DateColumn, Qt::AlignHCenter);
+ setColumnAlignment(PermissionsColumn, Qt::AlignHCenter);
+
+ if (KFTPCore::Config::showOwnerGroup()) {
+ setColumnAlignment(OwnerColumn, Qt::AlignHCenter);
+ setColumnAlignment(GroupColumn, Qt::AlignHCenter);
+ } else {
+ // Only show owner/group if set in the config
+ removeColumn(4);
+ removeColumn(4);
+ }
+
+ setColumnWidth(NameColumn, 140);
+ setColumnWidth(DateColumn, 100);
+
+ setAcceptDrops(true);
+ setSelectionMode(KFile::Extended);
+ setHScrollBarMode(QScrollView::AlwaysOff);
+
+ // Set the defaults
+ setHomeUrl(KURL(KFTPCore::Config::defLocalDir()));
+ setShowHidden(KFTPCore::Config::showHiddenFiles());
+}
+
+DetailsView::~DetailsView()
+{
+}
+
+const KURL &DetailsView::url() const
+{
+ return m_navigator->url();
+}
+
+const QValueList<LocationNavigator::Element> DetailsView::history(int &index) const
+{
+ return m_navigator->history(index);
+}
+
+bool DetailsView::isSelected(const KFileItem *i) const
+{
+ if (!i)
+ return false;
+
+ const KFileListViewItem *item = static_cast<const KFileListViewItem*>(i->extraData(this));
+ return (item && item->isSelected() && item->isVisible());
+}
+
+void DetailsView::setTreeView(TreeView *tree)
+{
+ m_treeView = tree;
+
+ connect(m_treeView, SIGNAL(pathChanged(const KURL&)), this, SLOT(openUrl(const KURL&)));
+}
+
+void DetailsView::setHomeUrl(const KURL &url)
+{
+ m_navigator->setHomeUrl(url);
+}
+
+void DetailsView::goBack()
+{
+ m_navigator->goBack();
+}
+
+void DetailsView::goForward()
+{
+ m_navigator->goForward();
+}
+
+void DetailsView::goUp()
+{
+ m_navigator->goUp();
+}
+
+void DetailsView::goHome()
+{
+ m_navigator->goHome();
+}
+
+void DetailsView::endItemUpdates()
+{
+ const KFileListViewItem *item = static_cast<const KFileListViewItem*>(firstChild());
+ if (item)
+ setCurrentItem(item->fileInfo());
+
+ int index = 0;
+ const QValueList<LocationNavigator::Element> history = m_navigator->history(index);
+ if (!history.isEmpty()) {
+ KFileView::setCurrentItem(history[index].currentFilename());
+ KFileDetailView::setSelected(currentFileItem(), true);
+
+ // Scroll the contents to last known coordinates
+ setContentsPos(history[index].contentsX(), history[index].contentsY());
+ }
+
+ m_treeView->openUrl(m_navigator->url());
+ m_treeView->endUpdate(m_navigator->url());
+ setFocus();
+}
+
+void DetailsView::openUrl(const KURL &url)
+{
+ m_navigator->setUrl(url);
+}
+
+void DetailsView::slotClear()
+{
+ clearView();
+}
+
+void DetailsView::slotDeleteItem(KFileItem *item)
+{
+ removeItem(item);
+
+ if (item->isDir())
+ m_treeView->removeFolder(item->url());
+}
+
+void DetailsView::slotCompleted()
+{
+ m_refreshing = true;
+
+ clearView();
+
+ KFileItemList items(m_dirLister->items());
+ KFileItemListIterator i(items);
+
+ KFileItem *item = 0;
+ while ((item = i.current()) != 0) {
+ insertItem(item);
+
+ if (item->isDir())
+ m_treeView->createFolder(item->url(), item->pixmap(16));
+
+ ++i;
+ }
+
+ endItemUpdates();
+ m_refreshing = false;
+
+ m_view->updateActions();
+}
+
+void DetailsView::slotRefreshItems()
+{
+ QTimer::singleShot(0, this, SLOT(reload()));
+}
+
+void DetailsView::reload()
+{
+ fetchLocation(m_navigator->url(), true);
+}
+
+void DetailsView::slotUrlChanged(const KURL &url)
+{
+ fetchLocation(url);
+}
+
+void DetailsView::slotSiteChanged(const KURL &url)
+{
+ m_navigator->clear();
+ m_treeView->resetView(url);
+}
+
+void DetailsView::fetchLocation(const KURL &url, bool reload)
+{
+ m_dirLister->setShowingDotFiles(m_showHidden);
+ m_dirLister->fetchLocation(url, reload);
+}
+
+void DetailsView::slotContentsMoving(int x, int y)
+{
+ if (!m_refreshing)
+ emit contentsMoved(x, y);
+}
+
+void DetailsView::slotItemExecuted()
+{
+ KFileItem *item = currentFileItem();
+
+ if (item) {
+ if (item->isDir())
+ openUrl(item->url());
+ }
+}
+
+void DetailsView::slotHeaderResized(int section)
+{
+ if (m_autoResizeEnabled && m_shouldDisableResize && section == 0) {
+ setHScrollBarMode(QScrollView::Auto);
+ m_autoResizeEnabled = false;
+ }
+}
+
+void DetailsView::resizeContents(int width, int height)
+{
+ m_shouldDisableResize = false;
+
+ KFileDetailView::resizeContents(width, height);
+
+ // Update the column widths
+ if (m_autoResizeEnabled) {
+ m_resizeTimer->stop();
+ m_resizeTimer->start(50, true);
+ }
+}
+
+void DetailsView::resizeEvent(QResizeEvent *event)
+{
+ m_shouldDisableResize = false;
+
+ KFileDetailView::resizeEvent(event);
+
+ // Update the column widths
+ if (m_autoResizeEnabled) {
+ m_resizeTimer->stop();
+ m_resizeTimer->start(50, true);
+ }
+}
+
+void DetailsView::updateColumnWidths()
+{
+ // The code below is based on Dolphin, Copyright (C) 2006 by Peter Penz
+ const int columnCount = columns();
+ int requiredWidth = 0;
+
+ for (int i = 1; i < columnCount; ++i) {
+ // When a directory contains no items, a minimum width for
+ // the column must be available, so that the header is readable.
+ int columnWidth = 64;
+ QFontMetrics fontMetrics(font());
+
+ for (QListViewItem* item = firstChild(); item != 0; item = item->nextSibling()) {
+ const int width = item->width(fontMetrics, this, i);
+
+ if (width > columnWidth) {
+ columnWidth = width;
+ }
+ }
+
+ // Add custom margin
+ columnWidth += 16;
+ setColumnWidth(i, columnWidth);
+ requiredWidth += columnWidth;
+ }
+
+ // Resize the first column in a way that the whole available width is used
+ int firstColumnWidth = visibleWidth() - requiredWidth;
+ if (firstColumnWidth < 128) {
+ firstColumnWidth = 128;
+ }
+
+ setColumnWidth(0, firstColumnWidth);
+ m_shouldDisableResize = true;
+}
+
+void DetailsView::insertItem(KFileItem *fileItem)
+{
+ const ActionChain *actionChain = Filters::self()->process(fileItem->url(), fileItem->size(), fileItem->isDir());
+ const Action *action;
+
+ if ((actionChain && actionChain->getAction(Action::Hide)))
+ return;
+
+ KFileView::insertItem(fileItem);
+
+ ListViewItem *item = new ListViewItem(this, fileItem);
+
+ if (actionChain && (action = actionChain->getAction(Action::Colorize)))
+ item->setColor(action->value().toColor());
+
+ QDir::SortSpec spec = KFileView::sorting();
+ if (spec & QDir::Time) {
+ item->setKey(sortingKey(fileItem->time(KIO::UDS_MODIFICATION_TIME), fileItem->isDir(), spec));
+ } else if (spec & QDir::Size) {
+ item->setKey(sortingKey(fileItem->size(), fileItem->isDir(), spec));
+ } else {
+ item->setKey(sortingKey(fileItem->text(), fileItem->isDir(), spec));
+ }
+
+ fileItem->setExtraData(this, item);
+}
+
+void DetailsView::slotContextMenu(KListView*, QListViewItem *i, const QPoint &p)
+{
+ m_view->updateActions();
+
+ // Create the popup menu
+ KPopupMenu *menu = new KPopupMenu(this);
+
+ Actions *actions = m_view->m_actions;
+
+ // Always show create directory
+ actions->m_createDirAction->plug(menu);
+ menu->insertSeparator();
+
+ // If nothing is selected, show the navigation menus
+ if (!i) {
+ actions->m_goUpAction->plug(menu);
+ actions->m_goBackAction->plug(menu);
+ actions->m_goForwardAction->plug(menu);
+ actions->m_reloadAction->plug(menu);
+ } else {
+ actions->m_transferAction->plug(menu);
+ actions->m_queueTransferAction->plug(menu);
+ actions->m_renameAction->plug(menu);
+ actions->m_deleteAction->plug(menu);
+ actions->m_shredAction->plug(menu);
+ actions->m_fileEditAction->plug(menu);
+ actions->m_verifyAction->plug(menu);
+ menu->insertSeparator();
+ actions->m_copyAction->plug(menu);
+ actions->m_pasteAction->plug(menu);
+ menu->insertSeparator();
+ actions->m_filterActions->plug(menu);
+ }
+
+ // Always show properties
+ menu->insertSeparator();
+ actions->m_propsAction->plug(menu);
+
+ menu->exec(p);
+}
+
+void DetailsView::slotItemRenamed(QListViewItem *item, const QString &name)
+{
+ KFileItem *fileItem = static_cast<KFileListViewItem*>(item)->fileInfo();
+ m_view->rename(fileItem->url(), name);
+}
+
+QDragObject *DetailsView::dragObject()
+{
+ KURLDrag *object = static_cast<KURLDrag*>(KFileDetailView::dragObject());
+
+ // Add some metadata
+ const KFileItemList *list = KFileView::selectedItems();
+
+ if (list) {
+ KFileItemListIterator i(*list);
+ KFileItem *item;
+
+ while ((item = i.current()) != 0) {
+ QString type = item->isDir() ? "D" : "F";
+ object->metaData().insert(item->url().htmlURL().local8Bit(), type + ":" + KIO::number(item->size()));
+ ++i;
+ }
+ }
+
+ return object;
+}
+
+bool DetailsView::acceptDrag(QDropEvent *event) const
+{
+ return KURLDrag::canDecode(event) &&
+ (event->action() == QDropEvent::Copy ||
+ event->action() == QDropEvent::Move ||
+ event->action() == QDropEvent::Link) &&
+ event->source() != this;
+}
+
+void DetailsView::contentsDropEvent(QDropEvent *event)
+{
+ if (!acceptDrag(event))
+ return;
+
+ KIO::MetaData meta;
+ KURL::List urls;
+ KURLDrag::decode(event, urls, meta);
+
+ meta.insert("DestURL", url().url());
+ KFTPQueue::Manager::self()->insertTransfer(new KURLDrag(urls, meta, this, name()));
+}
+
+KFileItem *DetailsView::fileItem(const QString &filename)
+{
+ if (!filename.isNull()) {
+ KFileItem *item;
+
+ for (item = firstFileItem(); item; item = nextItem(item)) {
+ if (item->name() == filename)
+ return item;
+ }
+ }
+
+ return 0;
+}
+
+void DetailsView::setItemVisibility(KFileItem *item, int visibility)
+{
+ ListViewItem *i = static_cast<ListViewItem*>(item->extraData(this));
+
+ if (i) {
+ if (visibility != 0 && visibility != 1)
+ visibility = !i->isVisible();
+
+ i->setVisible(visibility);
+ }
+}
+
+void DetailsView::setItemColor(KFileItem *item, const QColor &text, const QColor &background)
+{
+ ListViewItem *i = static_cast<ListViewItem*>(item->extraData(this));
+
+ if (i) {
+ i->setColor(text);
+ i->setBackground(background);
+ i->repaint();
+ }
+}
+
+void DetailsView::markItem(KFileItem *item)
+{
+ ListViewItem *i = static_cast<ListViewItem*>(item->extraData(this));
+
+ if (i) {
+ i->markItem(!i->marked());
+ }
+}
+
+void DetailsView::markItem(const QString &filename)
+{
+ if (KFileItem *item = fileItem(filename))
+ markItem(item);
+}
+
+void DetailsView::unmarkItems()
+{
+ KFileItem *item;
+
+ for (item = firstFileItem(); item; item = nextItem(item)) {
+ static_cast<ListViewItem*>(item->extraData(this))->markItem(false);
+ }
+}
+
+DetailsView::ListViewItem::ListViewItem(QListView *parent, KFileItem *fileItem)
+ : KFileListViewItem(parent, fileItem),
+ m_marked(false)
+{
+ if (fileItem->isDir() && !KFTPCore::Config::showDirectorySize()) {
+ setText(SizeColumn, " - ");
+ } else {
+ QString sizeText;
+ sizeText = KFTPCore::Config::showSizeInBytes() ? KIO::number(fileItem->size()) : KIO::convertSize(fileItem->size());
+ sizeText.append(" ");
+
+ setText(SizeColumn, sizeText);
+ }
+}
+
+void DetailsView::ListViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment)
+{
+ QColorGroup colorGroup(cg);
+ QColor textColor = colorGroup.text();
+
+ // Set custom file item color if set
+ if (m_textColor.isValid())
+ colorGroup.setColor(QColorGroup::Text, m_textColor);
+
+ // Set custom file item font
+ QFont font = p->font();
+ font.setBold(m_marked);
+ p->setFont(font);
+
+ if (m_backgroundColor.isValid()) {
+ colorGroup.setColor(QColorGroup::Base, m_backgroundColor);
+
+ // Override the KListViewItem since it resets the background color
+ QListViewItem::paintCell(p, colorGroup, column, width, alignment);
+ } else {
+ KFileListViewItem::paintCell(p, colorGroup, column, width, alignment);
+ }
+
+ if (column < listView()->columns() - 1) {
+ // Draw a separator between columns
+ p->setPen(KGlobalSettings::buttonBackground());
+ p->drawLine(width - 1, 0, width - 1, height() - 1);
+ }
+}
+
+void DetailsView::ListViewItem::markItem(bool marked)
+{
+ if (m_marked != marked) {
+ m_marked = marked;
+ repaint();
+ }
+}
+
+}
+
+}
+
+#include "detailsview.moc"
diff --git a/kftpgrabber/src/widgets/browser/detailsview.h b/kftpgrabber/src/widgets/browser/detailsview.h
new file mode 100644
index 0000000..eb60b70
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/detailsview.h
@@ -0,0 +1,374 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+#ifndef KFTPWIDGETS_BROWSERDETAILSVIEW_H
+#define KFTPWIDGETS_BROWSERDETAILSVIEW_H
+
+#include "browser/locationnavigator.h"
+
+#include <kfiledetailview.h>
+#include <kdirlister.h>
+
+namespace KFTPSession {
+ class Session;
+}
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+class DirLister;
+class TreeView;
+class View;
+
+/**
+ * This class represents a detailed list view for displaying local and
+ * remote directory contents. It is based upon KFileDetailView but uses
+ * a custom (wrapped) DirLister for actual listings.
+ *
+ * @author Jernej Kos
+ */
+class DetailsView : public KFileDetailView {
+Q_OBJECT
+public:
+ /**
+ * Maps the column indices of KFileDetailView to a
+ * descriptive column name.
+ */
+ enum ColumnName {
+ NameColumn = 0,
+ SizeColumn = 1,
+ DateColumn = 2,
+ PermissionsColumn = 3,
+ OwnerColumn = 4,
+ GroupColumn = 5
+ };
+
+ /**
+ * Class constructor.
+ *
+ * @param parent Parent widget
+ * @param view Main view container
+ * @param session Current session
+ */
+ DetailsView(QWidget *parent, View *view, KFTPSession::Session *session);
+
+ /**
+ * Class destructor.
+ */
+ ~DetailsView();
+
+ /**
+ * Returns the navigator object for navigating this view.
+ */
+ const LocationNavigator *locationNavigator() const { return m_navigator; }
+
+ /**
+ * Returns the current URL.
+ */
+ const KURL &url() const;
+
+ /**
+ * Returns the current history elements.
+ *
+ * @param index Variable to save the current history position to
+ * @return Current history element list
+ */
+ const QValueList<LocationNavigator::Element> history(int &index) const;
+
+ /**
+ * @overload
+ * Reimplemented from KFileView to support filtered views.
+ */
+ bool isSelected(const KFileItem *i) const;
+
+ /**
+ * Set the tree view widget to use for the tree.
+ *
+ * @param tree A valid tree view widget
+ */
+ void setTreeView(TreeView *tree);
+
+ /**
+ * Set the home URL.
+ *
+ * @param url URL to use as home URL
+ */
+ void setHomeUrl(const KURL &url);
+
+ /**
+ * Changes the "show hidden files" setting.
+ *
+ * @param value True to enable showing hidden files, false otherwise
+ */
+ void setShowHidden(bool value) { m_showHidden = value; }
+
+ /**
+ * Go one history hop back.
+ */
+ void goBack();
+
+ /**
+ * Go one history hop forward.
+ */
+ void goForward();
+
+ /**
+ * Go up in the directory structure.
+ */
+ void goUp();
+
+ /**
+ * Go the the predefined home URL.
+ */
+ void goHome();
+
+ /**
+ * Do item post-processing.
+ */
+ void endItemUpdates();
+
+ /**
+ * @overload
+ * Reimplemented from KFileDetailView.
+ */
+ void insertItem(KFileItem *fileItem);
+
+ /**
+ * Fetch a file item by its filename.
+ *
+ * @param file Item's filename
+ */
+ KFileItem *fileItem(const QString &filename);
+
+ /**
+ * Changes item's colors in the list view. Note that this overrides any
+ * highlight colors predefined by user filters.
+ *
+ * @param item The item to change colors for
+ * @param text Text color
+ * @param background Background color
+ */
+ void setItemColor(KFileItem *item, const QColor &text, const QColor &background);
+
+ /**
+ * Changes item's visibility in the list view.
+ *
+ * @param item The item tho change visiblity for
+ * @param visibility 1 if the item should be visible, 0 if it should be hidden, reverse otherwise
+ */
+ void setItemVisibility(KFileItem *item, int visibility = -1);
+
+ /**
+ * Mark or unmark the item. If the item is already marked it will be
+ * unmarked and vice-versa.
+ *
+ * @param item The item to mark
+ */
+ void markItem(KFileItem *item);
+
+ /**
+ * Mark or unmark the item identified by its filename. If the item is
+ * already marked it will be unmarked and vice-versa.
+ *
+ * @param filename Item's filename
+ */
+ void markItem(const QString &filename);
+
+ /**
+ * Unmark all items.
+ */
+ void unmarkItems();
+public slots:
+ /**
+ * Open an URL. Note that if a remote URL is specified the session needs to
+ * be connected to the specified host!
+ *
+ * @param url URL to open
+ */
+ void openUrl(const KURL &url);
+
+ /**
+ * Reload the current directory listing.
+ */
+ void reload();
+
+ /**
+ * Calculates new widths for all the columns.
+ */
+ void updateColumnWidths();
+
+ /**
+ * This method gets called when the widget is resized. It is used for automatic
+ * resize handling.
+ *
+ * @param width The new width
+ * @param height The new height
+ */
+ void resizeContents(int width, int height);
+
+ /**
+ * Returns the drag object to use for copy/paste and "drag and drop".
+ */
+ QDragObject *dragObject();
+protected:
+ /**
+ * Instruct the directory lister object to fetch the specified URL.
+ *
+ * @param url URL to fetch
+ * @param reload Should the cache be invalidated
+ */
+ void fetchLocation(const KURL &url, bool reload = false);
+
+ /**
+ * This method gets called when the widget is resized. It is used for automatic
+ * resize handling.
+ */
+ void resizeEvent(QResizeEvent *event);
+
+ /**
+ * Returns true if the drop event should be accepted.
+ */
+ bool acceptDrag(QDropEvent *event) const;
+
+ /**
+ * Called when something acceptable gets dropped on us.
+ */
+ void contentsDropEvent(QDropEvent *event);
+private:
+ class ListViewItem : public KFileListViewItem {
+ public:
+ ListViewItem(QListView *parent, KFileItem *fileItem);
+
+ /**
+ * @overload
+ * Reimplemented from KListView to implement nicer items.
+ */
+ void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment);
+
+ /**
+ * Set a text color for this item.
+ *
+ * @param color Text color
+ */
+ void setColor(QColor color) { m_textColor = color; }
+
+ /**
+ * Set a background color for this item.
+ *
+ * @param color Background color
+ */
+ void setBackground(QColor color) { m_backgroundColor = color; }
+
+ /**
+ * Set marked state for this item.
+ *
+ * @param marked True if this item should be marked, false otherwise
+ */
+ void markItem(bool marked);
+
+ /**
+ * Returns true if this item is marked.
+ */
+ bool marked() const { return m_marked; }
+ private:
+ QColor m_textColor;
+ QColor m_backgroundColor;
+ bool m_marked;
+ };
+
+ View *m_view;
+ DirLister *m_dirLister;
+ LocationNavigator *m_navigator;
+ TreeView *m_treeView;
+ QTimer *m_resizeTimer;
+
+ bool m_refreshing;
+ bool m_showHidden;
+ bool m_shouldDisableResize;
+ bool m_autoResizeEnabled;
+protected slots:
+ void slotClear();
+ void slotCompleted();
+ void slotDeleteItem(KFileItem *item);
+ void slotRefreshItems();
+ void slotSiteChanged(const KURL &url);
+
+ void slotUrlChanged(const KURL &url);
+
+ /**
+ * This slot gets called when an item has been renamed.
+ */
+ void slotItemRenamed(QListViewItem *item, const QString &name);
+
+ void slotContentsMoving(int x, int y);
+
+ /**
+ * This slot gets called when a context menu should be displayed.
+ */
+ void slotContextMenu(KListView*, QListViewItem *i, const QPoint &p);
+
+ /**
+ * This slot gets called when an item has been clicked.
+ */
+ void slotItemExecuted();
+
+ /**
+ * This slot gets called when a section in listview's header is resized. This
+ * is needed for proper automatic resize handling.
+ *
+ * @param section The section that was resized
+ */
+ void slotHeaderResized(int section);
+signals:
+ /**
+ * This signals gets emitted when user scrolls the widget.
+ *
+ * @param x New X position
+ * @param y New Y position
+ */
+ void contentsMoved(int x, int y);
+
+ /**
+ * This signal is emitted when items change.
+ */
+ void itemsChanged();
+};
+
+}
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/browser/dirlister.cpp b/kftpgrabber/src/widgets/browser/dirlister.cpp
new file mode 100644
index 0000000..4d539e4
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/dirlister.cpp
@@ -0,0 +1,169 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "dirlister.h"
+
+#include "engine/thread.h"
+#include "engine/cache.h"
+
+#include "kftpsession.h"
+
+#include <kmessagebox.h>
+#include <klocale.h>
+
+using namespace KFTPEngine;
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+DirLister::DirLister(QObject *parent)
+ : QObject(parent)
+{
+ m_localLister = new KDirLister();
+ m_localLister->setAutoUpdate(true);
+
+ enableLocal();
+}
+
+DirLister::~DirLister()
+{
+ delete m_localLister;
+}
+
+void DirLister::setSession(KFTPSession::Session *session)
+{
+ m_remoteSession = session;
+}
+
+void DirLister::fetchLocation(const KURL &url, bool reload)
+{
+ if (m_url.isLocalFile() != url.isLocalFile())
+ emit siteChanged(url);
+
+ m_url = url;
+
+ if (url.isLocalFile()) {
+ enableLocal();
+
+ m_localLister->stop();
+ m_localLister->setShowingDotFiles(m_showHidden);
+ m_localLister->openURL(url, false, reload);
+ } else {
+ enableRemote();
+
+ if (reload) {
+ KURL tmp = url;
+ Cache::self()->invalidateEntry(tmp);
+ }
+
+ emit clear();
+ m_remoteSession->getClient()->list(url);
+ }
+}
+
+void DirLister::enableLocal()
+{
+ m_localLister->stop();
+ m_localLister->QObject::disconnect(this);
+
+ connect(m_localLister, SIGNAL(clear()), this, SIGNAL(clear()));
+ connect(m_localLister, SIGNAL(completed()), this, SIGNAL(completed()));
+ connect(m_localLister, SIGNAL(deleteItem(KFileItem*)), this, SIGNAL(deleteItem(KFileItem*)));
+ connect(m_localLister, SIGNAL(refreshItems(const KFileItemList&)), this, SIGNAL(refreshItems()));
+}
+
+void DirLister::enableRemote()
+{
+ m_localLister->stop();
+ m_localLister->QObject::disconnect(this);
+ m_remoteSession->getClient()->eventHandler()->QObject::disconnect(this);
+
+ connect(m_remoteSession->getClient()->eventHandler(), SIGNAL(engineEvent(KFTPEngine::Event*)), this, SLOT(slotRemoteEngineEvent(KFTPEngine::Event*)));
+}
+
+void DirLister::disableRemote()
+{
+ m_remoteSession->getClient()->eventHandler()->QObject::disconnect(this);
+}
+
+void DirLister::stop()
+{
+ if (m_url.isLocalFile())
+ m_localLister->stop();
+}
+
+KFileItemList DirLister::items() const
+{
+ if (m_url.isLocalFile())
+ return m_localLister->items();
+ else
+ return m_items;
+}
+
+void DirLister::slotRemoteEngineEvent(KFTPEngine::Event *event)
+{
+ switch (event->type()) {
+ case Event::EventError: {
+ KMessageBox::error(0, i18n("Could not enter folder %1.").arg(m_url.path()), i18n("Error"));
+ disableRemote();
+ break;
+ }
+ case Event::EventDirectoryListing: {
+ m_items.clear();
+
+ // Populate the item list
+ QValueList<DirectoryEntry> list = event->getParameter(0).asDirectoryListing().list();
+ QValueList<DirectoryEntry>::ConstIterator end(list.end());
+ for (QValueList<DirectoryEntry>::ConstIterator i(list.begin()); i != end; ++i) {
+ if (!m_showHidden && (*i).filename().at(0) == '.')
+ continue;
+
+ m_items.append(new KFileItem((*i).toUdsEntry(), m_url, false, true));
+ }
+
+ disableRemote();
+ emit completed();
+ break;
+ }
+ default: break;
+ }
+}
+
+}
+
+}
+
+#include "dirlister.moc"
diff --git a/kftpgrabber/src/widgets/browser/dirlister.h b/kftpgrabber/src/widgets/browser/dirlister.h
new file mode 100644
index 0000000..730704f
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/dirlister.h
@@ -0,0 +1,157 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+#ifndef KFTPWIDGETS_BROWSERDIRLISTER_H
+#define KFTPWIDGETS_BROWSERDIRLISTER_H
+
+#include <qobject.h>
+
+#include <kurl.h>
+#include <kdirlister.h>
+
+namespace KFTPSession {
+ class Session;
+}
+
+namespace KFTPEngine {
+ class Event;
+}
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+/**
+ * This class is a wrapper around KDirLister to support remote listings
+ * via engine sockets.
+ *
+ * @author Jernej Kos
+ */
+class DirLister : public QObject {
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent Parent object
+ */
+ DirLister(QObject *parent);
+
+ /**
+ * Class destructor.
+ */
+ ~DirLister();
+
+ /**
+ * Set the remote session. You have to call this method before anything else
+ * in this class!
+ *
+ * @param session A valid session
+ */
+ void setSession(KFTPSession::Session *session);
+
+ /**
+ * Changes the "show hidden files" setting.
+ *
+ * @param value True to enable showing hidden files, false otherwise
+ */
+ void setShowingDotFiles(bool value) { m_showHidden = value; }
+
+ /**
+ * Fetch a specific location.
+ *
+ * @param url The URL to fetch (can be local or remote)
+ * @param reload If set to true listing cache will be invalidated
+ */
+ void fetchLocation(const KURL &url, bool reload);
+
+ /**
+ * Stop the current listing operation.
+ */
+ void stop();
+
+ /**
+ * Returns the items listed for the current URL. You should call this when receiving
+ * the finished() signal.
+ *
+ * @return The items listed for the current URL
+ */
+ KFileItemList items() const;
+protected:
+ void enableLocal();
+ void enableRemote();
+ void disableRemote();
+private:
+ KDirLister *m_localLister;
+ KFTPSession::Session *m_remoteSession;
+ KFileItemList m_items;
+ KURL m_url;
+ bool m_showHidden;
+private slots:
+ void slotRemoteEngineEvent(KFTPEngine::Event *event);
+signals:
+ /**
+ * Emitted when all items should be cleared.
+ */
+ void clear();
+
+ /**
+ * Emitted when the listing operation has been completed.
+ */
+ void completed();
+
+ /**
+ * Emitted when an item has to be removed.
+ */
+ void deleteItem(KFileItem *item);
+
+ /**
+ * Emitted when items should be refreshed.
+ */
+ void refreshItems();
+
+ /**
+ * Emitted when site changes from local to remote or vice-versa.
+ *
+ * @param url New site URL
+ */
+ void siteChanged(const KURL &url);
+};
+
+}
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/browser/filterwidget.cpp b/kftpgrabber/src/widgets/browser/filterwidget.cpp
new file mode 100644
index 0000000..47f88d9
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/filterwidget.cpp
@@ -0,0 +1,118 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "browser/filterwidget.h"
+#include "browser/detailsview.h"
+
+#include <qlistview.h>
+#include <qregexp.h>
+#include <qpopupmenu.h>
+
+#include <klocale.h>
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+FilterWidget::FilterWidget(QWidget *parent, DetailsView *view)
+ : KListViewSearchLine(parent, view),
+ m_filterDirectories(true),
+ m_filterSymlinks(true),
+ m_caseSensitive(false)
+{
+ connect(view, SIGNAL(itemsChanged()), this, SLOT(updateSearch()));
+}
+
+bool FilterWidget::itemMatches(const QListViewItem *item, const QString &pattern) const
+{
+ if (!pattern.isEmpty()) {
+ const KFileListViewItem *i = dynamic_cast<const KFileListViewItem*>(item);
+
+ if (i) {
+ if (i->fileInfo()->isDir() && !m_filterDirectories)
+ return true;
+ else if (i->fileInfo()->isLink() && !m_filterSymlinks)
+ return true;
+ }
+
+ QRegExp filter(pattern);
+ filter.setCaseSensitive(m_caseSensitive);
+ filter.setWildcard(true);
+
+ return filter.search(item->text(0)) > -1;
+ }
+
+ return true;
+}
+
+QPopupMenu *FilterWidget::createPopupMenu()
+{
+ QPopupMenu *popup = KLineEdit::createPopupMenu();
+
+ QPopupMenu *subMenu = new QPopupMenu(popup);
+ connect(subMenu, SIGNAL(activated(int)), this, SLOT(slotOptionsMenuActivated(int)));
+
+ popup->insertSeparator();
+ popup->insertItem(i18n("Filter Options"), subMenu);
+
+ subMenu->insertItem(i18n("Filter Directories"), FilterWidget::FilterDirectories);
+ subMenu->setItemChecked(FilterWidget::FilterDirectories, m_filterDirectories);
+
+ subMenu->insertItem(i18n("Filter Symlinks"), FilterWidget::FilterSymlinks);
+ subMenu->setItemChecked(FilterWidget::FilterSymlinks, m_filterSymlinks);
+
+ subMenu->insertItem(i18n("Case Sensitive"), FilterWidget::CaseSensitive);
+ subMenu->setItemChecked(FilterWidget::CaseSensitive, m_caseSensitive);
+
+ return popup;
+}
+
+void FilterWidget::slotOptionsMenuActivated(int id)
+{
+ switch (id) {
+ case FilterDirectories: m_filterDirectories = !m_filterDirectories; break;
+ case FilterSymlinks: m_filterSymlinks = !m_filterSymlinks; break;
+ case CaseSensitive: m_caseSensitive = !m_caseSensitive; break;
+ default: break;
+ }
+
+ updateSearch();
+}
+
+}
+
+}
+
+#include "filterwidget.moc"
diff --git a/kftpgrabber/src/widgets/browser/filterwidget.h b/kftpgrabber/src/widgets/browser/filterwidget.h
new file mode 100644
index 0000000..f5429cf
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/filterwidget.h
@@ -0,0 +1,97 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+#ifndef KFTPWIDGETS_BROWSERFILTERWIDGET_H
+#define KFTPWIDGETS_BROWSERFILTERWIDGET_H
+
+#include <klistviewsearchline.h>
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+class DetailsView;
+
+/**
+ * This class is a simple filtering widget that accepts wildcard
+ * patterns and filters listviews. Note that this widget only
+ * filters on the first column.
+ *
+ * @author Jernej Kos <kostko@jweb-network.net>
+ */
+class FilterWidget : public KListViewSearchLine {
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent The parent widget
+ * @param view The view you want to filter
+ */
+ FilterWidget(QWidget *parent, DetailsView *view);
+protected:
+ enum {
+ FilterDirectories = 1,
+ FilterSymlinks = 2,
+ CaseSensitive = 3
+ };
+
+ /**
+ * @overload
+ * Reimplemented from KListViewSearchLine to support wildcard
+ * matching schemes.
+ */
+ bool itemMatches(const QListViewItem *item, const QString &pattern) const;
+
+ /**
+ * @overload
+ * Reimplemented from KListViewSearchLine to remove multiple
+ * columns selection, since this widget only operates on the
+ * first column.
+ */
+ QPopupMenu *createPopupMenu();
+private:
+ bool m_filterDirectories;
+ bool m_filterSymlinks;
+ bool m_caseSensitive;
+private slots:
+ void slotOptionsMenuActivated(int id);
+};
+
+}
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/browser/locationnavigator.cpp b/kftpgrabber/src/widgets/browser/locationnavigator.cpp
new file mode 100644
index 0000000..5be8004
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/locationnavigator.cpp
@@ -0,0 +1,173 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "locationnavigator.h"
+#include "detailsview.h"
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+LocationNavigator::Element::Element()
+ : m_url(),
+ m_currentFilename(),
+ m_contentsX(0),
+ m_contentsY(0)
+{
+}
+
+LocationNavigator::Element::Element(const KURL &url)
+ : m_url(url),
+ m_currentFilename(),
+ m_contentsX(0),
+ m_contentsY(0)
+{
+}
+
+LocationNavigator::LocationNavigator(DetailsView *view)
+ : m_view(view),
+ m_historyIndex(0)
+{
+ connect(view, SIGNAL(contentsMoved(int, int)), this, SLOT(slotContentsMoved(int, int)));
+}
+
+void LocationNavigator::setUrl(const KURL &url)
+{
+ if (m_historyIndex > 0) {
+ const KURL &nextUrl = m_history[m_historyIndex - 1].url();
+
+ if (url == nextUrl) {
+ goForward();
+ return;
+ }
+ }
+
+ // Check for duplicates
+ const KURL &currentUrl = m_history[m_historyIndex].url();
+ if (currentUrl == url)
+ return;
+
+ updateCurrentElement();
+
+ const QValueListIterator<LocationNavigator::Element> i = m_history.at(m_historyIndex);
+ m_history.insert(i, Element(url));
+
+ emit urlChanged(url);
+ emit historyChanged();
+
+ // Cleanup history when it becomes too big
+ if (m_historyIndex > 100) {
+ m_history.erase(m_history.begin());
+ m_historyIndex--;
+ }
+}
+
+const KURL& LocationNavigator::url() const
+{
+ return m_history[m_historyIndex].url();
+}
+
+const QValueList<LocationNavigator::Element> LocationNavigator::history(int &index) const
+{
+ index = m_historyIndex;
+ return m_history;
+}
+
+void LocationNavigator::goBack()
+{
+ updateCurrentElement();
+ const int count = m_history.count();
+
+ if (m_historyIndex < count - 1) {
+ m_historyIndex++;
+
+ emit urlChanged(url());
+ emit historyChanged();
+ }
+}
+
+void LocationNavigator::goForward()
+{
+ if (m_historyIndex > 0) {
+ m_historyIndex--;
+
+ emit urlChanged(url());
+ emit historyChanged();
+ }
+}
+
+void LocationNavigator::goUp()
+{
+ setUrl(url().upURL());
+}
+
+void LocationNavigator::goHome()
+{
+ setUrl(m_homeUrl);
+}
+
+void LocationNavigator::clear()
+{
+ Element element = m_history[m_historyIndex];
+
+ m_history.clear();
+ m_historyIndex = 0;
+
+ m_history.append(element);
+}
+
+void LocationNavigator::slotContentsMoved(int x, int y)
+{
+ m_history[m_historyIndex].setContentsX(x);
+ m_history[m_historyIndex].setContentsY(y);
+}
+
+void LocationNavigator::updateCurrentElement()
+{
+ const KFileItem *item = m_view->currentFileItem();
+
+ if (item)
+ m_history[m_historyIndex].setCurrentFilename(item->name());
+
+ m_history[m_historyIndex].setContentsX(m_view->contentsX());
+ m_history[m_historyIndex].setContentsY(m_view->contentsY());
+}
+
+}
+
+}
+
+#include "locationnavigator.moc"
+
diff --git a/kftpgrabber/src/widgets/browser/locationnavigator.h b/kftpgrabber/src/widgets/browser/locationnavigator.h
new file mode 100644
index 0000000..475a3af
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/locationnavigator.h
@@ -0,0 +1,210 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+#ifndef KFTPWIDGETS_BROWSERLOCATIONNAVIGATOR_H
+#define KFTPWIDGETS_BROWSERLOCATIONNAVIGATOR_H
+
+#include <qobject.h>
+#include <qvaluelist.h>
+
+#include <kurl.h>
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+class DetailsView;
+
+/**
+ * This class contains the current navigational history and enables
+ * moving through it.
+ *
+ * @author Jernej Kos
+ */
+class LocationNavigator : public QObject {
+Q_OBJECT
+public:
+ /**
+ * An Element instance represents one history element. The class contains
+ * information about the URL, the selected item and the contents position.
+ */
+ class Element {
+ public:
+ /**
+ * Class constructor.
+ */
+ Element();
+
+ /**
+ * Class constructor.
+ *
+ * @param url Element's URL
+ */
+ Element(const KURL &url);
+
+ /**
+ * Returns the element's URL.
+ */
+ const KURL &url() const { return m_url; }
+
+ /**
+ * Set currently selected filename.
+ *
+ * @param filename The filename of the currently selected item
+ */
+ void setCurrentFilename(const QString &filename) { m_currentFilename = filename; }
+
+ /**
+ * Returns the selected filename.
+ */
+ const QString &currentFilename() const { return m_currentFilename; }
+
+ /**
+ * Set current contents X position.
+ *
+ * @param x Contents X position
+ */
+ void setContentsX(int x) { m_contentsX = x; }
+
+ /**
+ * Returns the saved contents X position.
+ */
+ int contentsX() const { return m_contentsX; }
+
+ /**
+ * Set current contents Y position.
+ *
+ * @param y Contents Y position
+ */
+ void setContentsY(int y) { m_contentsY = y; }
+
+ /**
+ * Returns the saved contents Y position.
+ */
+ int contentsY() const { return m_contentsY; }
+ private:
+ KURL m_url;
+ QString m_currentFilename;
+
+ int m_contentsX;
+ int m_contentsY;
+ };
+
+ /**
+ * Class constructor.
+ *
+ * @param view Parent view
+ */
+ LocationNavigator(DetailsView *view);
+
+ /**
+ * Set a new current URL. Calling this will emit the urlChanged signal.
+ *
+ * @param url Wanted URL
+ */
+ void setUrl(const KURL &url);
+
+ /**
+ * Returns the current URL.
+ */
+ const KURL &url() const;
+
+ /**
+ * Returns the current history elements.
+ *
+ * @param index Variable to save the current history position to
+ * @return Current history element list
+ */
+ const QValueList<Element> history(int &index) const;
+
+ /**
+ * Go one history hop back.
+ */
+ void goBack();
+
+ /**
+ * Go one history hop forward.
+ */
+ void goForward();
+
+ /**
+ * Go up in the directory structure.
+ */
+ void goUp();
+
+ /**
+ * Go the the predefined home URL.
+ */
+ void goHome();
+
+ /**
+ * Set the home URL.
+ *
+ * @param url URL to use as home URL
+ */
+ void setHomeUrl(const KURL &url) { m_homeUrl = url; }
+
+ /**
+ * Clear current history.
+ */
+ void clear();
+signals:
+ /**
+ * This signal is emitted whenever the current URL changes.
+ *
+ * @param url The new URL
+ */
+ void urlChanged(const KURL &url);
+
+ /**
+ * This signal is emitted whenever the history is updated.
+ */
+ void historyChanged();
+private slots:
+ void slotContentsMoved(int x, int y);
+private:
+ DetailsView *m_view;
+ int m_historyIndex;
+ QValueList<Element> m_history;
+ KURL m_homeUrl;
+
+ void updateCurrentElement();
+};
+
+}
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/browser/propsplugin.cpp b/kftpgrabber/src/widgets/browser/propsplugin.cpp
new file mode 100644
index 0000000..b6e688d
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/propsplugin.cpp
@@ -0,0 +1,360 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2004 by the KFTPGrabber developers
+ * Copyright (C) 2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "browser/propsplugin.h"
+#include "kftpsession.h"
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qstyle.h>
+#include <qgroupbox.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kseparator.h>
+#include <ksqueezedtextlabel.h>
+
+using namespace KFTPEngine;
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+PropsPlugin::PropsPlugin(KPropertiesDialog *props, KFileItemList items)
+ : KPropsDlgPlugin(props)
+{
+ QFrame *frame = properties->addPage(i18n("&General"));
+ frame->setMinimumWidth(320);
+ frame->setMinimumHeight(300);
+
+ // Some differences between a single file and multiple files
+ KFileItem *item = items.at(0);
+ KURL fileUrl = item->url();
+ filesize_t fileSize = item->size();
+ QString nameText;
+ QString iconText;
+ QString mimeComment;
+
+ if (items.count() == 1) {
+ bool isDir = false;
+
+ // Guess file type
+ if (item->isDir()) {
+ iconText = "folder";
+ isDir = true;
+ mimeComment = i18n("Remote folder");
+ } else if (item->isLink()) {
+ // We can't know if the sym-linked file is realy a directory, but most of
+ // the time it is. So if we can't determine the MIME type, set it to directory.
+ KMimeType::Ptr mimeType = KMimeType::findByURL(fileUrl, 0, false, true);
+
+ if (mimeType->name() == KMimeType::defaultMimeType()) {
+ iconText = "folder";
+ isDir = true;
+ mimeComment = i18n("Remote folder");
+ } else {
+ iconText = mimeType->icon(QString::null, false);
+ mimeComment = mimeType->comment();
+ }
+ } else {
+ KMimeType::Ptr mimeType = KMimeType::findByURL(fileUrl, 0, false, true);
+ iconText = mimeType->icon(QString::null, false);
+ mimeComment = mimeType->comment();
+ }
+
+ if (mimeComment.isEmpty()) {
+ mimeComment = i18n("Unknown");
+ }
+
+ nameText = item->name();
+ } else {
+ // Count files and folders selected
+ int countFiles = 0;
+ int countFolders = 0;
+ fileSize = 0;
+
+ KFileItemListIterator i(items);
+ for (; i.current(); ++i) {
+ if ((*i)->isDir())
+ countFolders++;
+ else
+ countFiles++;
+
+ fileSize += (*i)->size();
+ }
+
+ iconText = "kmultiple";
+ nameText = KIO::itemsSummaryString(countFiles + countFolders, countFiles, countFolders, 0, false);
+ }
+
+ QVBoxLayout *vbl = new QVBoxLayout(frame, 0, KDialog::spacingHint(), "vbl");
+ QGridLayout *grid = new QGridLayout(0, 3);
+ grid->setColStretch(0, 0);
+ grid->setColStretch(1, 0);
+ grid->setColStretch(2, 1);
+ grid->addColSpacing(1, KDialog::spacingHint());
+ vbl->addLayout(grid);
+
+ // Display file name and icon
+ QLabel *iconLabel = new QLabel(frame);
+ int bsize = 66 + 2 * iconLabel->style().pixelMetric(QStyle::PM_ButtonMargin);
+ iconLabel->setFixedSize(bsize, bsize);
+ iconLabel->setPixmap(DesktopIcon(iconText));
+ grid->addWidget(iconLabel, 0, 0, AlignLeft);
+
+ QLabel *nameLabel = new QLabel(frame);
+ nameLabel->setText(nameText);
+ grid->addWidget(nameLabel, 0, 2);
+
+ KSeparator *sep = new KSeparator(KSeparator::HLine, frame);
+ grid->addMultiCellWidget(sep, 2, 2, 0, 2);
+
+ // Display file information
+ QLabel *l;
+ int currentRow = 3;
+
+ if (items.count() == 1) {
+ l = new QLabel(i18n("Type:"), frame);
+ grid->addWidget(l, currentRow, 0);
+
+ l = new QLabel(mimeComment, frame);
+ grid->addWidget(l, currentRow++, 2);
+ }
+
+ l = new QLabel(i18n("Location:"), frame);
+ grid->addWidget(l, currentRow, 0);
+
+ l = new KSqueezedTextLabel(frame);
+ l->setText(fileUrl.directory());
+ grid->addWidget(l, currentRow++, 2);
+
+ l = new QLabel(i18n("Size:"), frame);
+ grid->addWidget(l, currentRow, 0);
+
+ l = new QLabel(frame);
+ grid->addWidget(l, currentRow++, 2);
+
+ l->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(fileSize))
+ .arg(KGlobal::locale()->formatNumber(fileSize, 0)));
+
+ sep = new KSeparator(KSeparator::HLine, frame);
+ grid->addMultiCellWidget(sep, currentRow, currentRow, 0, 2);
+ currentRow++;
+
+ // Display modification time
+ if (items.count() == 1) {
+ l = new QLabel(i18n("Created:"), frame);
+ grid->addWidget(l, currentRow, 0);
+
+ QDateTime dt;
+ dt.setTime_t(item->time(KIO::UDS_MODIFICATION_TIME));
+ l = new QLabel(KGlobal::locale()->formatDateTime(dt), frame);
+ grid->addWidget(l, currentRow++, 2);
+ }
+
+ vbl->addStretch(1);
+}
+
+void PropsPlugin::applyChanges()
+{
+}
+
+mode_t PermissionsPropsPlugin::fperm[3][4] = {
+ {S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID},
+ {S_IRGRP, S_IWGRP, S_IXGRP, S_ISGID},
+ {S_IROTH, S_IWOTH, S_IXOTH, S_ISVTX}
+};
+
+PermissionsPropsPlugin::PermissionsPropsPlugin(KPropertiesDialog *_props, KFileItemList items, KFTPSession::Session *session)
+ : KPropsDlgPlugin(_props),
+ m_items(items),
+ m_session(session),
+ m_cbRecursive(0)
+{
+ QFrame *frame = properties->addPage(i18n("&Permissions"));
+ frame->setMinimumWidth(320);
+ frame->setMinimumHeight(300);
+
+ // Some differences between a single file and multiple files
+ KFileItem *item = items.at(0);
+ KURL fileUrl = item->url();
+ bool isDir = false;
+
+ if (items.count() == 1) {
+ // Guess file type
+ if (item->isDir()) {
+ isDir = true;
+ } else if (item->isLink()) {
+ // We can't know if the sym-linked file is realy a directory, but most of
+ // the time it is. So if we can't determine the MIME type, set it to directory.
+ KMimeType::Ptr mimeType = KMimeType::findByURL(fileUrl, 0, false, true);
+
+ if (mimeType->name() == KMimeType::defaultMimeType())
+ isDir = true;
+ }
+ } else {
+ // Check for directories
+ KFileItemListIterator i(items);
+ for (; i.current(); ++i) {
+ if ((*i)->isDir()) {
+ isDir = true;
+ break;
+ }
+ }
+ }
+
+ QBoxLayout *box = new QVBoxLayout(frame, 0, KDialog::spacingHint());
+
+ QGroupBox *gb = new QGroupBox(0, Qt::Vertical, i18n("Access Permissions"), frame);
+ gb->layout()->setSpacing(KDialog::spacingHint());
+ gb->layout()->setMargin(KDialog::marginHint());
+ box->addWidget(gb);
+
+ QGridLayout *gl = new QGridLayout(gb->layout(), 6, 6, 15);
+
+ QLabel *l = new QLabel(i18n("Class"), gb);
+ gl->addWidget(l, 1, 0);
+
+ if (isDir)
+ l = new QLabel(i18n("Show\nEntries"), gb);
+ else
+ l = new QLabel(i18n("Read"), gb);
+ gl->addWidget(l, 1, 1);
+
+ if (isDir)
+ l = new QLabel(i18n("Write\nEntries"), gb);
+ else
+ l = new QLabel(i18n("Write"), gb);
+ gl->addWidget(l, 1, 2);
+
+ if (isDir)
+ l = new QLabel(i18n("Enter folder", "Enter"), gb);
+ else
+ l = new QLabel(i18n("Exec"), gb);
+
+ QSize size = l->sizeHint();
+ size.setWidth(size.width() + 15);
+ l->setFixedSize(size);
+ gl->addWidget(l, 1, 3);
+
+ l = new QLabel(i18n("Special"), gb);
+ gl->addMultiCellWidget(l, 1, 1, 4, 5);
+
+ l = new QLabel(i18n("User"), gb);
+ gl->addWidget(l, 2, 0);
+
+ l = new QLabel(i18n("Group"), gb);
+ gl->addWidget(l, 3, 0);
+
+ l = new QLabel(i18n("Others"), gb);
+ gl->addWidget(l, 4, 0);
+
+ l = new QLabel(i18n("Set UID"), gb);
+ gl->addWidget(l, 2, 5);
+
+ l = new QLabel(i18n("Set GID"), gb);
+ gl->addWidget(l, 3, 5);
+
+ l = new QLabel(i18n("Sticky"), gb);
+ gl->addWidget(l, 4, 5);
+
+ mode_t permissions = item->permissions();
+
+ // Display checkboxes
+ for (int row = 0; row < 3; ++row) {
+ for (int col = 0; col < 4; ++col) {
+ QCheckBox *cb = new QCheckBox(gb);
+ connect(cb, SIGNAL(clicked()), this, SLOT(setDirty()));
+ m_permsCheck[row][col] = cb;
+ cb->setChecked(permissions & fperm[row][col]);
+
+ gl->addWidget(cb, row + 2, col + 1);
+ }
+ }
+
+ gl->setColStretch(6, 10);
+ box->addStretch(10);
+
+ if (isDir) {
+ m_cbRecursive = new QCheckBox(i18n("Apply changes to all subfolders and their contents"), frame);
+ connect(m_cbRecursive, SIGNAL(clicked()), this, SLOT(changed()));
+ box->addWidget(m_cbRecursive);
+ }
+}
+
+void PermissionsPropsPlugin::applyChanges()
+{
+ // Generate new permissions =)
+ int newPerms[4] = {0,};
+
+ for (int row = 0; row < 3; ++row) {
+ for (int col = 0; col < 4; ++col) {
+ if (!m_permsCheck[row][col]->isChecked()) continue;
+
+ int x = col < 3 ? col : row;
+ int c = 0;
+
+ switch (x) {
+ case 0: c = 4; break;
+ case 1: c = 2; break;
+ case 2: c = 1; break;
+ }
+
+ if (col < 3) {
+ newPerms[row + 1] += c;
+ } else {
+ newPerms[0] += c;
+ }
+ }
+ }
+
+ // Actually do a chmod
+ int mode = newPerms[0] * 1000 + newPerms[1] * 100 + newPerms[2] * 10 + newPerms[3];
+ bool recursive = m_cbRecursive && m_cbRecursive->isChecked();
+
+ KFileItemListIterator i(m_items);
+ for (; i.current(); ++i) {
+ if ((*i)->isDir())
+ m_session->getClient()->chmod((*i)->url(), mode, recursive);
+ else
+ m_session->getClient()->chmod((*i)->url(), mode);
+ }
+}
+
+}
+
+}
+
+#include "propsplugin.moc"
diff --git a/kftpgrabber/src/widgets/browser/propsplugin.h b/kftpgrabber/src/widgets/browser/propsplugin.h
new file mode 100644
index 0000000..9283f85
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/propsplugin.h
@@ -0,0 +1,98 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2004 by the KFTPGrabber developers
+ * Copyright (C) 2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPFILEPROPSPLUGIN_H
+#define KFTPFILEPROPSPLUGIN_H
+
+#include "engine/directorylisting.h"
+
+#include <qcheckbox.h>
+#include <kpropertiesdialog.h>
+
+namespace KFTPSession {
+ class Session;
+}
+
+namespace KFTPEngine {
+ class Thread;
+}
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+/**
+ * This is a plugin for displaying remote file properties using the
+ * standard KDE file properties dialog.
+ *
+ * @author Jernej Kos
+ */
+class PropsPlugin : public KPropsDlgPlugin
+{
+Q_OBJECT
+public:
+ PropsPlugin(KPropertiesDialog *props, KFileItemList items);
+
+ void applyChanges();
+};
+
+/**
+ * This is a plugin for displaying remote file permissions and their
+ * changing using the standard KDE file properties dialog.
+ *
+ * @author Jernej Kos
+ */
+class PermissionsPropsPlugin : public KPropsDlgPlugin
+{
+Q_OBJECT
+public:
+ PermissionsPropsPlugin(KPropertiesDialog *props, KFileItemList items, KFTPSession::Session *session);
+
+ void applyChanges();
+private:
+ KFileItemList m_items;
+ KFTPSession::Session *m_session;
+
+ static mode_t fperm[3][4];
+ QString m_perms[3];
+ QCheckBox *m_permsCheck[3][4];
+ QCheckBox *m_cbRecursive;
+};
+
+}
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/browser/treeview.cpp b/kftpgrabber/src/widgets/browser/treeview.cpp
new file mode 100644
index 0000000..0f2a824
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/treeview.cpp
@@ -0,0 +1,520 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "browser/treeview.h"
+#include "browser/view.h"
+
+#include "engine/thread.h"
+
+#include "misc.h"
+
+#include <qheader.h>
+#include <qtimer.h>
+
+#include <kio/job.h>
+#include <kurl.h>
+#include <kurldrag.h>
+
+using namespace KFTPGrabberBase;
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+/*
+ * TreeViewItem class
+ */
+
+TreeViewItem::TreeViewItem(TreeView *parent, const KURL &url)
+ : QListViewItem(parent),
+ m_tree(parent),
+ m_url(url),
+ m_dirty(false)
+{
+ // Set the name
+ setText(0, path2Name(url.path(-1)));
+}
+
+TreeViewItem::TreeViewItem(TreeView *tree, QListViewItem *parent, const KURL &url)
+ : QListViewItem(parent),
+ m_tree(tree),
+ m_url(url),
+ m_dirty(false)
+{
+ // Set the name
+ setText(0, path2Name(url.path(-1)));
+}
+
+TreeViewItem::~TreeViewItem()
+{
+ // The item should be removed from the list as well
+ m_tree->m_treeItems.remove(m_url.path());
+}
+
+int TreeViewItem::compare(QListViewItem *i, int col, bool) const
+{
+ // Hidden files must be on top
+ if (m_url.fileName().at(0) == '.')
+ return -1;
+
+ return QListViewItem::compare(i, col, false);
+}
+
+/*
+ * TreeView class
+ */
+
+TreeView::TreeView(QWidget *parent)
+ : KListView(parent)
+{
+ // Create the columns
+ addColumn(i18n("Directory"));
+
+ // General tree settings
+ setDragEnabled(true);
+ setAcceptDrops(true);
+ setMinimumWidth(150);
+ setRootIsDecorated(false);
+ header()->hide();
+
+ // Reset the view
+ resetView(KURL("/"));
+ m_noItemOpen = false;
+
+ // Connect signals
+ connect(this, SIGNAL(clicked(QListViewItem*)), this, SLOT(slotClicked(QListViewItem*)));
+ connect(this, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(slotDoubleClicked(QListViewItem*)));
+
+ // Drag and drop
+ m_dropItem = 0L;
+}
+
+
+TreeView::~TreeView()
+{
+ // Free the item index
+ m_treeItems.clear();
+}
+
+void TreeView::resetView(const KURL &url)
+{
+ // Free the item index
+ m_treeItems.clear();
+
+ // Clear the view
+ clear();
+ header()->resizeSection(0, 0);
+
+ // Create the root item
+ TreeViewItem *rootItem = new TreeViewItem(this, remoteUrl("/", url));
+ rootItem->setText(0, url.isLocalFile() ? i18n("Root directory") : url.host());
+ rootItem->setPixmap(0, loadSmallPixmap("folder_red"));
+ setOpen(rootItem, true);
+}
+
+int TreeView::openUrl(const KURL &url, QListViewItem *parent)
+{
+ // Root item should always be open
+ setOpen(firstChild(), true);
+
+ // Go trough all items in the list and try to find the url
+ QListViewItem *item;
+ if (!parent)
+ item = firstChild();
+ else
+ item = parent;
+
+ while (item) {
+ // Check if the item is correct
+ if (static_cast<TreeViewItem*>(item)->m_url.path(-1) == url.path(-1)) {
+ // We have found it
+ ensureItemVisible(item);
+ setCurrentItem(item);
+ setSelected(item, true);
+
+ // Change viewport
+ QRect r = itemRect(item);
+ if (r.isValid()) {
+ int x, y;
+ viewportToContents(contentsX(), r.y(), x, y);
+ setContentsPos(x, y);
+ }
+
+ return 1;
+ }
+
+ if (item->firstChild()) {
+ // If item has children, go after them
+ if (openUrl(url, item->firstChild()) == 1)
+ return 1;
+ }
+
+ item = item->nextSibling();
+ }
+
+ return 0;
+}
+
+QListViewItem *TreeView::findItem(QListViewItem *parent, const QString &name)
+{
+ QListViewItem *item = parent->firstChild();
+
+ while (item) {
+ if (item->text(0) == name)
+ return item;
+
+ item = item->nextSibling();
+ }
+
+ // If nothing is found, parent should be returned
+ return parent;
+}
+
+void TreeView::createFolder(const KURL &url, QPixmap icon)
+{
+ int numDirs = url.path(1).contains('/', false);
+ QListViewItem *item = firstChild();
+
+ for (int i = 1; i < numDirs; i++) {
+ QString itemUrl = url.path().section('/', 0, i);
+
+ if (m_treeItems[itemUrl]) {
+ // Item exists for this URL
+ item = m_treeItems[itemUrl];
+ } else {
+ // Item not yet created
+ KURL tmp = url;
+ tmp.setPath(itemUrl);
+
+ item = new TreeViewItem(this, item, tmp);
+ if (i == numDirs - 1)
+ item->setPixmap(0, icon);
+ else
+ item->setPixmap(0, loadSmallPixmap("folder"));
+
+ m_treeItems.insert(itemUrl, static_cast<TreeViewItem*>(item));
+ }
+
+ // Mark it as dirty
+ static_cast<TreeViewItem*>(item)->m_dirty = true;
+
+ // Open it
+ if (!m_noItemOpen)
+ setOpen(item, true);
+ }
+
+ // Root item should always be open
+ setOpen(firstChild(), true);
+}
+
+void TreeView::endUpdate(const KURL &url)
+{
+ // Remove all items in the selected dir, not marked as dirty
+ TreeViewItem *top = static_cast<TreeViewItem*>(firstChild());
+ TreeViewItem *tmp = 0L;
+ int numDirs = url.path(1).contains('/', false);
+
+ if (url.path() == "/") {
+ TreeViewItem *i = static_cast<TreeViewItem*>(top->firstChild());
+
+ while (i) {
+ tmp = static_cast<TreeViewItem*>(i->nextSibling());
+
+ if (!i->m_dirty) {
+ // Remove item from the index
+ delete i;
+ } else {
+ i->m_dirty = false;
+ }
+
+ i = tmp;
+ }
+
+ return;
+ }
+
+ // URL for items
+ KURL itemURL = url;
+ itemURL.setPath("/");
+
+ for (int i = 1; i < numDirs; i++) {
+ QString sect = url.path().section('/', i, i);
+ itemURL.setPath(url.path().section('/', 0, i));
+
+ if (!m_treeItems[itemURL.path()]) {
+ // Item not yet created
+ return;
+ } else {
+ // Item is already present
+ top = m_treeItems[itemURL.path()];
+
+ // Check for URL match
+ if (itemURL.path(-1) == url.path(-1)) {
+ // URL match, delete the item's children
+ TreeViewItem *i = static_cast<TreeViewItem*>(top->firstChild());
+
+ while (i) {
+ tmp = static_cast<TreeViewItem*>(i->nextSibling());
+
+ if (!i->m_dirty) {
+ // Remove item from the index
+ delete i;
+ } else {
+ i->m_dirty = false;
+ }
+
+ i = tmp;
+ }
+ return;
+ }
+ }
+ }
+}
+
+void TreeView::clearFolder(const KURL &url)
+{
+ // Remove url's children
+ QListViewItem *top = firstChild();
+ int numDirs = url.path(1).contains('/', false);
+
+ if (url.path() == "/") {
+ QListViewItem *i = top->firstChild();
+
+ while (i) {
+ // Remove item from the index
+ delete i;
+
+ i = top->firstChild();
+ }
+
+ return;
+ }
+
+ // URL for items
+ KURL itemURL = url;
+ itemURL.setPath("/");
+
+ for (int i = 1; i < numDirs; i++) {
+ QString sect = url.path().section('/', i, i);
+ itemURL.setPath(url.path().section('/', 0, i));
+
+ if (!m_treeItems[itemURL.path()]) {
+ // Item not yet created
+ return;
+ } else {
+ // Item is already present
+ top = m_treeItems[itemURL.path()];
+
+ // Check for URL match
+ if (itemURL.path(-1) == url.path(-1)) {
+ // URL match, delete the item's children
+ QListViewItem *i = top->firstChild();
+
+ while (i) {
+ // Remove item from the index
+ delete i;
+
+ i = top->firstChild();
+ }
+ return;
+ }
+ }
+ }
+}
+
+void TreeView::removeFolder(const KURL &url)
+{
+ // Removes a folder at url
+ QListViewItem *top = firstChild();
+ int numDirs = url.path(1).contains('/', false);
+
+ // URL for items
+ KURL itemURL = url;
+ itemURL.setPath("/");
+
+ for (int i = 1; i < numDirs; i++) {
+ QString sect = url.path().section('/', i, i);
+ itemURL.setPath(url.path().section('/', 0, i));
+
+ if (!m_treeItems[itemURL.path()]) {
+ // Item not yet created
+ return;
+ } else {
+ // Item is already present
+ top = m_treeItems[itemURL.path()];
+
+ // Check for URL match
+ if (itemURL.path(-1) == url.path(-1)) {
+ // Remove item from the index
+ delete top;
+
+ return;
+ }
+ }
+ }
+}
+
+void TreeView::slotClicked(QListViewItem *item)
+{
+ if (!item)
+ return;
+
+ m_noItemOpen = true;
+ emit pathChanged(static_cast<TreeViewItem*>(item)->m_url);
+ m_noItemOpen = false;
+}
+
+void TreeView::slotDoubleClicked(QListViewItem *item)
+{
+ if (!item)
+ return;
+
+ setOpen(item, !item->isOpen());
+}
+
+void TreeView::startDrag()
+{
+ dragObject()->drag();
+}
+
+bool TreeView::acceptDrag(QDropEvent *e)
+{
+ return KURLDrag::canDecode(e) &&
+ ( e->action() == QDropEvent::Copy
+ || e->action() == QDropEvent::Move
+ || e->action() == QDropEvent::Link )
+ && acceptDrops()
+ && dragEnabled();
+}
+
+QDragObject *TreeView::dragObject()
+{
+ TreeViewItem *item = static_cast<TreeViewItem*>(selectedItem());
+
+ // Set the correct pixmap
+ QPixmap pix = *item->pixmap(0);
+
+ KURL::List urls;
+ urls.append(item->m_url);
+
+ KIO::MetaData meta;
+ meta.insert(item->m_url.htmlURL().local8Bit(), "D:0");
+
+ m_dragObject = new KURLDrag(urls, meta, this, name());
+ m_dragObject->setPixmap(pix, QPoint(pix.width() / 2, pix.height() / 2));
+
+ return m_dragObject;
+}
+
+void TreeView::contentsDragEnterEvent(QDragEnterEvent *e)
+{
+ if (!acceptDrag(e)) {
+ e->accept(false);
+ return;
+ }
+
+ e->acceptAction();
+ QListViewItem *i = itemAt(contentsToViewport(e->pos()));
+ if (i)
+ m_dropItem = i;
+}
+
+void TreeView::contentsDragMoveEvent(QDragMoveEvent *e)
+{
+ if (!acceptDrag(e)) {
+ e->accept(false);
+ return;
+ }
+
+ e->acceptAction();
+ QListViewItem *i = itemAt(contentsToViewport(e->pos()));
+
+ if (i && i != m_dropItem)
+ m_dropItem = i;
+}
+
+void TreeView::contentsDragLeaveEvent(QDragLeaveEvent*)
+{
+ m_dropItem = 0L;
+}
+
+void TreeView::contentsDropEvent(QDropEvent *e)
+{
+ if (!m_dropItem)
+ return;
+
+ if (!acceptDrag(e)) {
+ e->acceptAction(false);
+ return;
+ }
+ e->acceptAction();
+
+ // Decode the data and try to init transfer
+ KIO::MetaData meta;
+ KURL::List urls;
+ KURLDrag::decode(e, urls, meta);
+
+ // Move the specified file(s)
+ for (KURL::List::iterator i = urls.begin(); i != urls.end(); ++i) {
+ KURL destUrl = static_cast<TreeViewItem*>(m_dropItem)->m_url;
+
+ if (destUrl != (*i)) {
+ if (destUrl.isLocalFile() != (*i).isLocalFile()) {
+ // TODO Queue up a transfer
+ } else {
+ // Rename/move the file
+ destUrl.addPath((*i).fileName());
+
+ if ((*i).isLocalFile()) {
+ KIO::move((*i), destUrl, false);
+
+ // Reload the listing
+ static_cast<View*>(parent()->parent())->reload();
+ } else {
+ static_cast<View*>(parent()->parent())->m_ftpClient->rename((*i), destUrl);
+ }
+ }
+ }
+ }
+
+ // Invalidate the drop item
+ m_dropItem = 0L;
+}
+
+}
+
+}
+
+#include "treeview.moc"
diff --git a/kftpgrabber/src/widgets/browser/treeview.h b/kftpgrabber/src/widgets/browser/treeview.h
new file mode 100644
index 0000000..220ac88
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/treeview.h
@@ -0,0 +1,189 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPFILEDIRTREEVIEW_H
+#define KFTPFILEDIRTREEVIEW_H
+
+#include <klistview.h>
+#include <klocale.h>
+#include <kurl.h>
+
+#include <qpixmap.h>
+#include <qdict.h>
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+class TreeViewItem;
+
+/**
+ * This class represents a tree view showing the directory structure. It
+ * should usually be used together with a ListView.
+ *
+ * @author Jernej Kos
+ */
+class TreeView : public KListView
+{
+Q_OBJECT
+friend class ListView;
+friend class TreeViewItem;
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent The parent widget
+ */
+ TreeView(QWidget *parent);
+
+ /**
+ * Class destructor.
+ */
+ ~TreeView();
+
+ /**
+ * Open an URL.
+ *
+ * @param url The url to open
+ */
+ int openUrl(const KURL &url, QListViewItem *parent = 0);
+
+ /**
+ * Remove the folder's child items.
+ *
+ * @param url The folder's URL
+ */
+ void clearFolder(const KURL &url);
+
+ /**
+ * Remove the folder and it's child items.
+ *
+ * @param url The folder's URL
+ */
+ void removeFolder(const KURL &url);
+
+ /**
+ * Create a new folder identified by it's URL and any folders missing
+ * in the hierarchy.
+ *
+ * @param url The folder's URL
+ * @param icon The icon to use
+ */
+ void createFolder(const KURL &url, QPixmap icon);
+
+ /**
+ * Clear all items in the view and create a new root item.
+ *
+ * @param url The root's new URL
+ */
+ void resetView(const KURL &url);
+
+ /**
+ * End item update and clear all non-dirty items.
+ *
+ * @param url The url to purge
+ */
+ void endUpdate(const KURL &url);
+private:
+ QDict<TreeViewItem> m_treeItems;
+ bool m_noItemOpen;
+
+ /* Drag & drop support */
+ QListViewItem *m_dropItem;
+ QDragObject *m_dragObject;
+
+ QDragObject *dragObject();
+ void startDrag();
+ bool acceptDrag(QDropEvent *e);
+ void contentsDragEnterEvent(QDragEnterEvent *e);
+ void contentsDragMoveEvent(QDragMoveEvent *e);
+ void contentsDragLeaveEvent(QDragLeaveEvent*);
+ void contentsDropEvent(QDropEvent *e);
+protected:
+ QListViewItem *findItem(QListViewItem *parent, const QString &name);
+private slots:
+ void slotClicked(QListViewItem *item);
+ void slotDoubleClicked(QListViewItem *item);
+signals:
+ void pathChanged(const KURL &url);
+};
+
+/**
+ * This class represents an item in the tree view.
+ *
+ * @author Jernej Kos
+ */
+class TreeViewItem : public QListViewItem
+{
+friend class TreeView;
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent The parent tree view
+ * @param url This item's URL
+ */
+ TreeViewItem(TreeView *parent, const KURL &url);
+
+ /**
+ * Class constructor.
+ *
+ * @param tree The tree view instance
+ * @param parent The parent list view item
+ * @param url This item's URL
+ */
+ TreeViewItem(TreeView *tree, QListViewItem *parent, const KURL &url);
+
+ /**
+ * Class destructor.
+ */
+ ~TreeViewItem();
+protected:
+ /**
+ * @overload
+ * Reimplemented from QListViewItem to provide proper comparation.
+ */
+ int compare(QListViewItem *i, int col, bool) const;
+private:
+ TreeView *m_tree;
+ KURL m_url;
+ bool m_dirty;
+};
+
+}
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/browser/view.cpp b/kftpgrabber/src/widgets/browser/view.cpp
new file mode 100644
index 0000000..4b3b0e5
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/view.cpp
@@ -0,0 +1,456 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "browser/view.h"
+#include "browser/detailsview.h"
+#include "browser/treeview.h"
+#include "browser/actions.h"
+#include "browser/filterwidget.h"
+
+#include "kftpbookmarks.h"
+#include "misc/config.h"
+#include "kftpsession.h"
+#include "ftpsocket.h"
+
+#include "misc.h"
+
+#include <klocale.h>
+#include <ktoolbar.h>
+#include <kstatusbar.h>
+#include <kcombobox.h>
+#include <kaction.h>
+#include <kmessagebox.h>
+#include <ksslinfodlg.h>
+#include <klineedit.h>
+#include <kpixmapprovider.h>
+
+#include <kio/job.h>
+
+#include <qdir.h>
+#include <qlabel.h>
+#include <qlayout.h>
+
+using namespace KFTPGrabberBase;
+using namespace KFTPEngine;
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+class HistoryPixmapProvider : public KPixmapProvider
+{
+public:
+ QPixmap pixmapFor(const QString&, int)
+ {
+ return loadSmallPixmap("folder");
+ }
+};
+
+View::View(QWidget *parent, const char *name, KFTPEngine::Thread *client, KFTPSession::Session *session)
+ : QWidget(parent, name),
+ m_session(session),
+ m_ftpClient(client)
+{
+ m_connTimer = new QTimer(this);
+
+ // Create the GUI
+ init();
+ populateToolbar();
+
+ // Hide/show the tree acoording to configuration
+ setTreeVisible(KFTPCore::Config::showTree());
+
+ // Let us be up to date with bookmark changes
+ connect(KFTPBookmarks::Manager::self(), SIGNAL(update()), this, SLOT(updateBookmarks()));
+
+ // Some other stuff
+ connect(m_ftpClient->eventHandler(), SIGNAL(engineEvent(KFTPEngine::Event*)), this, SLOT(slotEngineEvent(KFTPEngine::Event*)));
+ connect(m_connTimer, SIGNAL(timeout()), this, SLOT(slotDurationUpdate()));
+
+ // Config updates to hide/show the tree
+ connect(KFTPCore::Config::self(), SIGNAL(configChanged()), this, SLOT(slotConfigUpdate()));
+}
+
+View::~View()
+{
+}
+
+void View::init()
+{
+ // Init actions
+ m_actions = new Actions(this);
+ m_actions->initActions();
+
+ // Layout
+ QVBoxLayout *layout = new QVBoxLayout(this);
+
+ // Create the toolbars
+ m_toolBarFirst = new KToolBar(this, "first toolbar", false, false);
+ m_toolBarSecond = new KToolBar(this, "second toolbar", false, false);
+ m_searchToolBar = new KToolBar(this, "search toolbar", false, false);
+
+ m_toolBarFirst->setEnableContextMenu(false);
+ m_toolBarFirst->setMovingEnabled(false);
+ m_toolBarFirst->setFullSize(true);
+
+ m_toolBarSecond->setEnableContextMenu(false);
+ m_toolBarSecond->setMovingEnabled(false);
+ m_toolBarSecond->setFullSize(true);
+
+ m_searchToolBar->setEnableContextMenu(false);
+ m_searchToolBar->setMovingEnabled(false);
+ m_searchToolBar->setFullSize(true);
+
+ QLabel *filterLabel = new QLabel(i18n("Filter: "), m_searchToolBar);
+ m_searchToolBar->insertWidget(1, 35, filterLabel);
+
+ // Create the erase button
+ m_toolBarSecond->insertButton(QApplication::reverseLayout() ? "clear_left" :"locationbar_erase", 0, SIGNAL(clicked()), this, SLOT(slotHistoryEraseClicked()), true);
+
+ // Create the labels
+ QLabel *pathLabel = new QLabel(i18n("Path: "), m_toolBarSecond);
+ m_toolBarSecond->insertWidget(1, 35, pathLabel);
+
+ // Create the history combo
+ m_historyCombo = new KHistoryCombo(true, m_toolBarSecond);
+ m_toolBarSecond->insertWidget(2, 0, m_historyCombo);
+ m_historyCombo->setPixmapProvider(new HistoryPixmapProvider());
+ m_historyCombo->setMaxCount(25);
+ m_historyCombo->setSizeLimit(25);
+ m_historyCombo->setDuplicatesEnabled(false);
+ m_historyCombo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+
+ connect(m_historyCombo, SIGNAL(activated(const QString&)), this, SLOT(slotHistoryActivated(const QString&)));
+
+ // Do some more stuff
+ m_toolBarSecond->setItemAutoSized(1, true);
+ m_toolBarSecond->setStretchableWidget(m_historyCombo);
+ m_toolBarSecond->updateRects(true);
+ m_toolBarFirst->updateRects(true);
+
+ // Create a splitter
+ m_splitter = new QSplitter(this);
+ m_splitter->setOpaqueResize(true);
+ m_splitter->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
+
+ // Create a status bar
+ QHBoxLayout *statusLayout = new QHBoxLayout(this);
+
+ m_connDurationMsg = new QLabel(this);
+ m_connDurationMsg->setAlignment(AlignAuto | AlignVCenter | AlignHCenter | ExpandTabs);
+ m_connDurationMsg->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
+ m_connDurationMsg->setMinimumWidth(100);
+
+ m_sslIcon = new QPushButton(this);
+ m_sslIcon->setFlat(true);
+ m_sslIcon->setIconSet(SmallIconSet("decrypted"));
+ m_sslIcon->setEnabled(false);
+
+ connect(m_sslIcon, SIGNAL(clicked()), this, SLOT(slotDisplayCertInfo()));
+
+ m_statusMsg = new QLabel(this);
+ m_statusMsg->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
+ m_statusMsg->setText(i18n("Idle."));
+
+ statusLayout->addWidget(m_statusMsg, 1);
+ statusLayout->addWidget(m_connDurationMsg);
+ statusLayout->addWidget(m_sslIcon);
+
+ // Add toolbars to the layout
+ layout->addWidget(m_toolBarFirst);
+ layout->addWidget(m_toolBarSecond);
+ layout->addWidget(m_splitter, 10);
+ layout->addWidget(m_searchToolBar);
+ layout->addLayout(statusLayout);
+
+ // Now add some stuff to the splitter
+ m_detailsView = new DetailsView(m_splitter, this, m_session);
+ m_splitter->moveToLast(m_detailsView);
+
+ connect(m_detailsView->locationNavigator(), SIGNAL(historyChanged()), this, SLOT(slotHistoryChanged()));
+
+ // Create the tree view
+ m_tree = new TreeView(m_splitter);
+ m_splitter->moveToFirst(m_tree);
+
+ m_detailsView->setTreeView(m_tree);
+ m_detailsView->openUrl(KURL(KFTPCore::Config::defLocalDir()));
+
+ // Create the filter widget
+ m_searchFilter = new FilterWidget(m_searchToolBar, m_detailsView);
+ m_searchToolBar->setItemAutoSized(2, true);
+ m_searchToolBar->setStretchableWidget(m_searchFilter);
+
+ m_searchToolBar->updateRects(true);
+ m_searchToolBar->hide();
+}
+
+const KURL &View::url() const
+{
+ return m_detailsView->url();
+}
+
+const QValueList<LocationNavigator::Element> View::history(int &index) const
+{
+ return m_detailsView->history(index);
+}
+
+const KFileItemList *View::selectedItems() const
+{
+ return m_detailsView->KFileView::selectedItems();
+}
+
+KURL::List View::selectedURLs() const
+{
+ KURL::List urls;
+ const KFileItemList *list = selectedItems();
+
+ if (list) {
+ KFileItemListIterator i(*list);
+ KFileItem *item;
+
+ while ((item = i.current()) != 0) {
+ urls.append(item->url());
+ ++i;
+ }
+ }
+
+ return urls;
+}
+
+const KFileItemList *View::items() const
+{
+ return m_detailsView->KFileView::items();
+}
+
+void View::openUrl(const KURL &url)
+{
+ m_detailsView->openUrl(url);
+}
+
+void View::setShowHidden(bool value)
+{
+ m_detailsView->setShowHidden(value);
+}
+
+void View::setHomeUrl(const KURL &url)
+{
+ m_detailsView->setHomeUrl(url);
+}
+
+void View::goBack()
+{
+ m_detailsView->goBack();
+}
+
+void View::goForward()
+{
+ m_detailsView->goForward();
+}
+
+void View::goUp()
+{
+ m_detailsView->goUp();
+}
+
+void View::goHome()
+{
+ m_detailsView->goHome();
+}
+
+void View::reload()
+{
+ m_detailsView->reload();
+}
+
+void View::rename(const KURL &source, const QString &name)
+{
+ KURL dest(source.upURL());
+ dest.addPath(name);
+
+ if (source.isLocalFile())
+ KIO::rename(source, dest, false);
+ else
+ m_session->getClient()->rename(source, dest);
+}
+
+void View::slotConfigUpdate()
+{
+ setTreeVisible(KFTPCore::Config::showTree());
+}
+
+void View::setTreeVisible(bool visible)
+{
+ if (visible)
+ m_tree->show();
+ else
+ m_tree->hide();
+
+ m_actions->m_toggleTreeViewAction->setChecked(visible);
+}
+
+void View::populateToolbar()
+{
+ // Add the actions to the toolbar
+ m_actions->m_siteChangeAction->plug(m_toolBarFirst);
+
+ m_toolBarFirst->insertSeparator();
+
+ m_actions->m_goUpAction->plug(m_toolBarFirst);
+ m_actions->m_goBackAction->plug(m_toolBarFirst);
+ m_actions->m_goForwardAction->plug(m_toolBarFirst);
+ m_actions->m_reloadAction->plug(m_toolBarFirst);
+
+ m_toolBarFirst->insertSeparator();
+
+ m_actions->m_goHomeAction->plug(m_toolBarFirst);
+ m_actions->m_createDirAction->plug(m_toolBarFirst);
+
+ m_toolBarFirst->insertSeparator();
+
+ m_actions->m_abortAction->plug(m_toolBarFirst);
+ m_actions->m_toggleTreeViewAction->plug(m_toolBarFirst);
+ m_actions->m_toggleFilterAction->plug(m_toolBarFirst);
+
+ m_toolBarFirst->insertSeparator();
+
+ m_actions->m_moreActions->plug(m_toolBarFirst);
+}
+
+void View::updateActions()
+{
+ // Force action update
+ m_actions->updateActions();
+}
+
+void View::updateBookmarks()
+{
+ // Repopulate bookmarks menu on updates
+ m_actions->m_connectAction->popupMenu()->clear();
+ KFTPBookmarks::Manager::self()->guiPopulateBookmarksMenu(m_actions->m_connectAction, QDomNode(), false, m_session);
+}
+
+void View::slotHistoryActivated(const QString &text)
+{
+ KURL dest = url();
+ dest.setPath(text);
+
+ openUrl(dest);
+}
+
+void View::slotHistoryEraseClicked()
+{
+ m_historyCombo->setCurrentText(QString::null);
+ m_historyCombo->setFocus();
+}
+
+void View::slotHistoryChanged()
+{
+ /*m_historyCombo->insertItem(loadSmallPixmap("folder"), url().path(-1), 0);
+ m_historyCombo->setCurrentItem(0);*/
+ m_historyCombo->addToHistory(url().path(-1));
+}
+
+void View::slotDisplayCertInfo()
+{
+ if (m_ftpClient->socket()->protocolName() == "ftp" && m_ftpClient->socket()->isEncrypted()) {
+ KSSLInfoDlg *sslInfo = new KSSLInfoDlg(true, this);
+ sslInfo->exec();
+ } else if (m_ftpClient->socket()->protocolName() == "sftp") {
+ KMessageBox::information(this, i18n("This is a SSH encrypted connection. No certificate info is currently available."));
+ } else {
+ KSSLInfoDlg *sslInfo = new KSSLInfoDlg(false, this);
+ sslInfo->exec();
+ }
+}
+
+void View::slotDurationUpdate()
+{
+ m_connDuration = m_connDuration.addSecs(1);
+ m_connDurationMsg->setText(m_connDuration.toString("hh:mm:ss"));
+}
+
+void View::slotEngineEvent(KFTPEngine::Event *event)
+{
+ switch (event->type()) {
+ case Event::EventState: {
+ // Set new state
+ m_statusMsg->setText(event->getParameter(0).asString());
+ break;
+ }
+ case Event::EventConnect:
+ case Event::EventDisconnect: {
+ // Change encryption icon
+ m_sslIcon->setIconSet(SmallIconSet(m_ftpClient->socket()->isEncrypted() ? "encrypted" : "decrypted"));
+ m_sslIcon->setEnabled(m_ftpClient->socket()->isConnected());
+
+ // Start or stop the duration timer
+ if (m_ftpClient->socket()->isConnected()) {
+ m_connTimer->start(1000);
+ m_connDuration.setHMS(0, 0, 0);
+ } else {
+ m_connTimer->stop();
+ m_connDurationMsg->setText("");
+ }
+
+ // Reset selected charset to default
+ KPopupMenu *menu = m_actions->m_changeEncodingAction->popupMenu();
+ menu->setItemChecked(m_actions->m_defaultCharsetOption, true);
+ menu->setItemChecked(m_actions->m_curCharsetOption, false);
+ m_actions->m_curCharsetOption = m_actions->m_defaultCharsetOption;
+ break;
+ }
+ default: break;
+ }
+
+ if (m_ftpClient->socket()->isBusy()) {
+ m_tree->setEnabled(false);
+ m_detailsView->setEnabled(false);
+ m_toolBarSecond->setEnabled(false);
+ } else if (KFTPQueue::Manager::self()->getNumRunning(m_ftpClient->socket()->getCurrentUrl()) == 0) {
+ m_tree->setEnabled(true);
+ m_detailsView->setEnabled(true);
+ m_toolBarSecond->setEnabled(true);
+ }
+
+ // Update actions
+ updateActions();
+}
+
+}
+
+}
+
+#include "view.moc"
diff --git a/kftpgrabber/src/widgets/browser/view.h b/kftpgrabber/src/widgets/browser/view.h
new file mode 100644
index 0000000..67dffa6
--- /dev/null
+++ b/kftpgrabber/src/widgets/browser/view.h
@@ -0,0 +1,258 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPFILEDIRVIEW_H
+#define KFTPFILEDIRVIEW_H
+
+#include "browser/locationnavigator.h"
+
+#include <qwidget.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qtimer.h>
+#include <qdatetime.h>
+#include <qsplitter.h>
+
+#include <kurl.h>
+#include <kfileitem.h>
+
+namespace KFTPSession {
+ class Session;
+ class Manager;
+}
+
+class KToolBar;
+class KHistoryCombo;
+class KAction;
+class KLineEdit;
+
+namespace KFTPEngine {
+ class Thread;
+ class Event;
+}
+
+namespace KFTPWidgets {
+
+namespace Browser {
+
+class DetailsView;
+class ListView;
+class TreeView;
+class Actions;
+class FilterWidget;
+
+/**
+ * @author Jernej Kos
+ */
+class View : public QWidget
+{
+Q_OBJECT
+friend class Actions;
+friend class DetailsView;
+friend class ListView;
+friend class TreeView;
+friend class KFTPSession::Manager;
+friend class KFTPSession::Session;
+public:
+ /**
+ * Class constructor.
+ */
+ View(QWidget *parent, const char *name, KFTPEngine::Thread *client, KFTPSession::Session *session);
+
+ /**
+ * Class destructor.
+ */
+ ~View();
+
+ /**
+ * Returns the current URL.
+ */
+ const KURL &url() const;
+
+ /**
+ * Returns the current history elements.
+ *
+ * @param index Variable to save the current history position to
+ * @return Current history element list
+ */
+ const QValueList<LocationNavigator::Element> history(int &index) const;
+
+ /**
+ * Returns all currenty selected items.
+ */
+ const KFileItemList *selectedItems() const;
+
+ /**
+ * Returns all currently selected URLs.
+ */
+ KURL::List selectedURLs() const;
+
+ /**
+ * Returns all items in the current sort order.
+ */
+ const KFileItemList *items() const;
+
+ /**
+ * Open an URL. Note that if a remote URL is specified the session needs to
+ * be connected to the specified host!
+ *
+ * @param url URL to open
+ */
+ void openUrl(const KURL &url);
+
+ /**
+ * Changes the visibility of tree widget.
+ *
+ * @param visible True to display the tree widget, false to hide it
+ */
+ void setTreeVisible(bool visible);
+
+ /**
+ * Changes the "show hidden files" setting.
+ *
+ * @param value True to enable showing hidden files, false otherwise
+ */
+ void setShowHidden(bool value);
+
+ /**
+ * Set the home URL.
+ *
+ * @param url URL to use as home URL
+ */
+ void setHomeUrl(const KURL &url);
+
+ /**
+ * Go one history hop back.
+ */
+ void goBack();
+
+ /**
+ * Go one history hop forward.
+ */
+ void goForward();
+
+ /**
+ * Go up in the directory structure.
+ */
+ void goUp();
+
+ /**
+ * Go the the predefined home URL.
+ */
+ void goHome();
+
+ /**
+ * Reload the current directory listing.
+ */
+ void reload();
+
+ /**
+ * Renames the provided source file to a new name.
+ */
+ void rename(const KURL &source, const QString &name);
+
+ /**
+ * Returns the details view widget.
+ */
+ DetailsView *getDetailsView() const { return m_detailsView; }
+
+ /**
+ * Returns the tree view widget.
+ */
+ TreeView *getTreeView() const { return m_tree; }
+
+ /**
+ * Returns the status label widget.
+ */
+ QLabel *getStatusLabel() const { return m_statusMsg; }
+
+ /**
+ * Returns the associated session.
+ */
+ KFTPSession::Session *getSession() const { return m_session; }
+protected:
+ /**
+ * Initialize the widget.
+ */
+ void init();
+
+ /**
+ * Populate the toolbar.
+ */
+ void populateToolbar();
+private:
+ KFTPSession::Session *m_session;
+ KFTPEngine::Thread *m_ftpClient;
+
+ DetailsView *m_detailsView;
+ TreeView *m_tree;
+
+ Actions *m_actions;
+
+ KToolBar *m_toolBarFirst; /* Upper toolbar */
+ KToolBar *m_toolBarSecond; /* Lower toolbar */
+ KToolBar *m_searchToolBar;
+
+ QLabel *m_statusMsg;
+ QLabel *m_connDurationMsg;
+ QPushButton *m_sslIcon;
+ QSplitter *m_splitter;
+
+ QTimer *m_connTimer;
+ QTime m_connDuration;
+
+ KHistoryCombo *m_historyCombo;
+ FilterWidget *m_searchFilter;
+public slots:
+ void updateActions();
+ void updateBookmarks();
+private slots:
+ void slotHistoryEraseClicked();
+ void slotHistoryActivated(const QString &text);
+ void slotHistoryChanged();
+
+ void slotDisplayCertInfo();
+ void slotDurationUpdate();
+
+ void slotEngineEvent(KFTPEngine::Event *event);
+
+ void slotConfigUpdate();
+};
+
+}
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/configdialog.cpp b/kftpgrabber/src/widgets/configdialog.cpp
new file mode 100644
index 0000000..49d0d16
--- /dev/null
+++ b/kftpgrabber/src/widgets/configdialog.cpp
@@ -0,0 +1,187 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "configdialog.h"
+#include "misc.h"
+#include "misc/config.h"
+#include "widgets/systemtray.h"
+
+#include <klocale.h>
+#include <kfontdialog.h>
+#include <kcolorbutton.h>
+#include <kurlrequester.h>
+#include <klineedit.h>
+#include <knuminput.h>
+#include <kglobal.h>
+#include <kcharsets.h>
+#include <kcombobox.h>
+
+#include <qframe.h>
+#include <qlayout.h>
+#include <qcheckbox.h>
+
+// Config layouts
+#include "ui/config_general.h"
+#include "ui/config_transfers.h"
+#include "ui/config_log.h"
+#include "ui/config_display.h"
+
+#include "configfilter.h"
+
+namespace KFTPWidgets {
+
+ConfigDialog::ConfigDialog(QWidget *parent, const char *name)
+ : KConfigDialog(parent, name, KFTPCore::Config::self(), KDialogBase::TreeList, Ok|Apply|Cancel, Ok, true)
+{
+ // Add all standard pages
+ addPage(new GeneralSettings(0, "General"), i18n("General"), "kfm");
+ addPage(new TransferSettings(0, "Transfers"), i18n("Transfers"), "queue");
+ addPage(new LogSettings(0, "Log"), i18n("Log"), "log");
+ addPage(new DisplaySettings(0, "Display"), i18n("Display"), "display");
+
+ // Add the actions page
+ QFrame *aFrame = new QFrame();
+ QVBoxLayout *aLayout = new QVBoxLayout(aFrame, 0, 0);
+ aLayout->addWidget(KFTPCore::Config::self()->dActions()->getConfigWidget(aFrame));
+ aLayout->addSpacing(KDialog::spacingHint());
+ aLayout->addWidget(KFTPCore::Config::self()->uActions()->getConfigWidget(aFrame));
+ aLayout->addSpacing(KDialog::spacingHint());
+ aLayout->addWidget(KFTPCore::Config::self()->fActions()->getConfigWidget(aFrame));
+ aLayout->addStretch(1);
+ addPage(aFrame, i18n("Actions"), "kfm");
+
+ // Add the filter page
+ aFrame = new QFrame();
+ aLayout = new QVBoxLayout(aFrame, 0, 0);
+ m_configFilter = new ConfigFilter(aFrame);
+ aLayout->addWidget(m_configFilter);
+ addPage(aFrame, i18n("Filters"), "kfm");
+
+ // Setup some stuff
+ static_cast<KURLRequester*>(child("kcfg_defLocalDir"))->setMode(KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly);
+
+ // Setup signals
+ connect(child("kcfg_globalMail"), SIGNAL(toggled(bool)), this, SLOT(slotGeneralEmailChanged(bool)));
+ connect(child("kcfg_portForceIp"), SIGNAL(toggled(bool)), this, SLOT(slotTransfersForceIpChanged(bool)));
+ connect(child("kcfg_activeForcePort"), SIGNAL(toggled(bool)), this, SLOT(slotTransfersForcePortChanged(bool)));
+ connect(child("kcfg_diskCheckSpace"), SIGNAL(toggled(bool)), this, SLOT(slotTransfersDiskChanged(bool)));
+ connect(child("kcfg_failedAutoRetry"), SIGNAL(toggled(bool)), this, SLOT(slotTransfersFailedRetryChanged(bool)));
+ connect(child("kcfg_saveToFile"), SIGNAL(toggled(bool)), this, SLOT(slotLogOutputFileChanged(bool)));
+
+ // Refresh states
+ slotGeneralEmailChanged(static_cast<QCheckBox*>(child("kcfg_globalMail"))->isChecked());
+ slotTransfersForceIpChanged(static_cast<QCheckBox*>(child("kcfg_portForceIp"))->isChecked());
+ slotTransfersDiskChanged(static_cast<QCheckBox*>(child("kcfg_diskCheckSpace"))->isChecked());
+ slotTransfersFailedRetryChanged(static_cast<QCheckBox*>(child("kcfg_failedAutoRetry"))->isChecked());
+ slotLogOutputFileChanged(static_cast<QCheckBox*>(child("kcfg_saveToFile"))->isChecked());
+ slotTransfersForcePortChanged(static_cast<QCheckBox*>(child("kcfg_activeForcePort"))->isChecked());
+
+ // Let the config be up-to-date
+ connect(this, SIGNAL(settingsChanged()), KFTPCore::Config::self(), SLOT(emitChange()));
+ connect(this, SIGNAL(okClicked()), this, SLOT(slotSettingsChanged()));
+}
+
+void ConfigDialog::prepareDialog()
+{
+ // Update the actions
+ KFTPCore::Config::self()->dActions()->updateWidget();
+ KFTPCore::Config::self()->uActions()->updateWidget();
+ KFTPCore::Config::self()->fActions()->updateWidget();
+
+ // Populate charsets
+ QStringList charsets = KGlobal::charsets()->descriptiveEncodingNames();
+ static_cast<KComboBox*>(child("cfg_defEncoding"))->insertStringList(charsets);
+
+ QString defEncoding = KFTPCore::Config::defEncoding();
+ defEncoding = QString("%1 ( %2 )").arg(KGlobal::charsets()->languageForEncoding(defEncoding)).arg(defEncoding);
+ static_cast<KComboBox*>(child("cfg_defEncoding"))->setCurrentText(defEncoding);
+
+ m_configFilter->loadSettings();
+}
+
+void ConfigDialog::slotSettingsChanged()
+{
+ // Update the actions
+ KFTPCore::Config::self()->dActions()->updateConfig();
+ KFTPCore::Config::self()->uActions()->updateConfig();
+ KFTPCore::Config::self()->fActions()->updateConfig();
+
+ m_configFilter->saveSettings();
+
+ // Save encoding
+ KFTPCore::Config::setDefEncoding(KGlobal::charsets()->encodingForName(static_cast<KComboBox*>(child("cfg_defEncoding"))->currentText()));
+
+ // Show/hide the systray icon
+ if (KFTPCore::Config::showSystrayIcon())
+ SystemTray::self()->show();
+ else
+ SystemTray::self()->hide();
+}
+
+void ConfigDialog::slotGeneralEmailChanged(bool on)
+{
+ static_cast<QWidget*>(child("kcfg_anonMail"))->setEnabled(!on);
+}
+
+void ConfigDialog::slotTransfersForceIpChanged(bool on)
+{
+ static_cast<QWidget*>(child("kcfg_portIp"))->setEnabled(on);
+}
+
+void ConfigDialog::slotTransfersForcePortChanged(bool on)
+{
+ static_cast<QWidget*>(child("kcfg_activeMinPort"))->setEnabled(on);
+ static_cast<QWidget*>(child("kcfg_activeMaxPort"))->setEnabled(on);
+}
+
+void ConfigDialog::slotTransfersDiskChanged(bool on)
+{
+ static_cast<QWidget*>(child("kcfg_diskCheckInterval"))->setEnabled(on);
+ static_cast<QWidget*>(child("kcfg_diskMinFreeSpace"))->setEnabled(on);
+}
+
+void ConfigDialog::slotTransfersFailedRetryChanged(bool on)
+{
+ static_cast<QWidget*>(child("kcfg_failedAutoRetryCount"))->setEnabled(on);
+}
+
+void ConfigDialog::slotLogOutputFileChanged(bool on)
+{
+ static_cast<QWidget*>(child("kcfg_outputFilename"))->setEnabled(on);
+}
+
+}
+
+#include "configdialog.moc"
diff --git a/kftpgrabber/src/widgets/configdialog.h b/kftpgrabber/src/widgets/configdialog.h
new file mode 100644
index 0000000..6234c14
--- /dev/null
+++ b/kftpgrabber/src/widgets/configdialog.h
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+#ifndef KFTPCONFIGDIALOG_H
+#define KFTPCONFIGDIALOG_H
+
+#include <kconfigdialog.h>
+
+namespace KFTPWidgets {
+
+class ConfigFilter;
+
+/**
+ * @author Jernej Kos
+ */
+class ConfigDialog : public KConfigDialog
+{
+Q_OBJECT
+public:
+ ConfigDialog(QWidget *parent, const char *name = 0);
+
+ void prepareDialog();
+private:
+ ConfigFilter *m_configFilter;
+private slots:
+ void slotGeneralEmailChanged(bool on);
+
+ void slotTransfersForceIpChanged(bool on);
+ void slotTransfersDiskChanged(bool on);
+ void slotTransfersForcePortChanged(bool on);
+ void slotTransfersFailedRetryChanged(bool on);
+
+ void slotLogOutputFileChanged(bool on);
+
+ void slotSettingsChanged();
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/configfilter.cpp b/kftpgrabber/src/widgets/configfilter.cpp
new file mode 100644
index 0000000..c2dc3b9
--- /dev/null
+++ b/kftpgrabber/src/widgets/configfilter.cpp
@@ -0,0 +1,137 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "configfilter.h"
+#include "filtereditor.h"
+
+#include "misc/config.h"
+#include "misc.h"
+
+#include <klistview.h>
+#include <klocale.h>
+#include <kpushbutton.h>
+#include <kmessagebox.h>
+#include <klineeditdlg.h>
+
+#include <klineedit.h>
+#include <kcolorbutton.h>
+#include <kdialogbase.h>
+
+#include <qcheckbox.h>
+#include <qlayout.h>
+#include <qtabwidget.h>
+
+using namespace KFTPGrabberBase;
+
+namespace KFTPWidgets {
+
+ConfigFilter::ConfigFilter(QWidget *parent, const char *name)
+ : QWidget(parent, name)
+{
+ // Create the main widget
+ QVBoxLayout *t = new QVBoxLayout(this, 0, 0);
+
+ m_editorLayout = new ConfigFilterLayout(this);
+ t->addWidget(m_editorLayout);
+
+ m_filterEditor = new FilterEditor(this);
+ m_editorLayout->tabWidget->insertTab(m_filterEditor, i18n("Filters"), 0);
+ m_editorLayout->tabWidget->setCurrentPage(0);
+ m_editorLayout->tabWidget->setMargin(KDialog::spacingHint());
+
+ loadSettings();
+
+ // Connect the slots
+ connect(m_editorLayout->addExtButton, SIGNAL(clicked()), this, SLOT(slotAddAscii()));
+ connect(m_editorLayout->removeExtButton, SIGNAL(clicked()), this, SLOT(slotRemoveAscii()));
+}
+
+void ConfigFilter::loadSettings()
+{
+ m_filterEditor->reset();
+ asciiLoadExtensions();
+}
+
+void ConfigFilter::saveSettings()
+{
+ // Save the settings
+ KFTPCore::Config::setAsciiList(asciiToStringList());
+}
+
+void ConfigFilter::slotAddAscii()
+{
+ if (!m_editorLayout->newExtension->text().stripWhiteSpace().isEmpty()) {
+ new QListViewItem(m_editorLayout->extensionList, m_editorLayout->newExtension->text().stripWhiteSpace());
+ m_editorLayout->newExtension->clear();
+ }
+}
+
+void ConfigFilter::slotRemoveAscii()
+{
+ if (!m_editorLayout->extensionList->selectedItem())
+ return;
+
+ delete m_editorLayout->extensionList->selectedItem();
+}
+
+void ConfigFilter::asciiLoadExtensions()
+{
+ // Load the ascii extensions
+ m_editorLayout->extensionList->clear();
+ QStringList p_extensions = KFTPCore::Config::asciiList();
+
+ QStringList::iterator end( p_extensions.end() );
+ for (QStringList::iterator i( p_extensions.begin() ); i != end; ++i) {
+ new QListViewItem(m_editorLayout->extensionList, (*i));
+ }
+
+}
+
+QStringList ConfigFilter::asciiToStringList()
+{
+ QStringList p_extensions;
+ QListViewItem *i = m_editorLayout->extensionList->firstChild();
+ while (i) {
+ p_extensions.append(i->text(0));
+
+ i = i->itemBelow();
+ }
+
+ return p_extensions;
+}
+
+}
+#include "configfilter.moc"
diff --git a/kftpgrabber/src/widgets/configfilter.h b/kftpgrabber/src/widgets/configfilter.h
new file mode 100644
index 0000000..3d9ee22
--- /dev/null
+++ b/kftpgrabber/src/widgets/configfilter.h
@@ -0,0 +1,79 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPWIDGETSCONFIGFILTER_H
+#define KFTPWIDGETSCONFIGFILTER_H
+
+#include <qwidget.h>
+#include <kdialogbase.h>
+#include <knuminput.h>
+#include <qradiobutton.h>
+#include <qvaluelist.h>
+
+// Layouts
+#include "ui/config_filters.h"
+
+namespace KFTPWidgets {
+
+class FilterEditor;
+
+/**
+ * Filter related configuration dialog.
+ *
+ * @author Jernej Kos
+ */
+class ConfigFilter : public QWidget
+{
+Q_OBJECT
+public:
+ ConfigFilter(QWidget *parent = 0, const char *name = 0);
+
+ void saveSettings();
+ void loadSettings();
+private:
+ void asciiLoadExtensions();
+ QStringList asciiToStringList();
+
+ FilterEditor *m_filterEditor;
+ ConfigFilterLayout *m_editorLayout;
+private slots:
+ void slotAddAscii();
+ void slotRemoveAscii();
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/failedtransfers.cpp b/kftpgrabber/src/widgets/failedtransfers.cpp
new file mode 100644
index 0000000..30fc0a6
--- /dev/null
+++ b/kftpgrabber/src/widgets/failedtransfers.cpp
@@ -0,0 +1,213 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "failedtransfers.h"
+#include "kftpqueue.h"
+#include "listview.h"
+#include "misc.h"
+#include "kftpapi.h"
+
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kio/job.h>
+#include <kmessagebox.h>
+
+#include <qlayout.h>
+#include <qheader.h>
+
+using namespace KFTPGrabberBase;
+
+namespace KFTPWidgets {
+
+FailedTransferItem::FailedTransferItem(KFTPQueue::FailedTransfer *transfer, QListView *parent)
+ : KFTPWidgets::ListViewItem(parent),
+ m_failedTransfer(transfer)
+{
+ QString desc = "<nobr><b>";
+ desc += i18n("Transfer");
+ desc += ":</b> ";
+ desc += transfer->getTransfer()->getSourceUrl().prettyURL();
+ desc += " <b>&gt;&gt;&gt;</b> ";
+ desc += transfer->getTransfer()->getDestUrl().prettyURL();
+ desc += "<br><b>";
+ desc += i18n("Error");
+ desc += ":</b> <i>";
+ desc += transfer->getError();
+ desc += "</i></nobr>";
+
+ // Setup columns
+ setRichText(0, desc);
+ setText(1, KIO::convertSize(transfer->getTransfer()->getActualSize()));
+ setText(2, QString::number(transfer->getTransfer()->getId()));
+
+ setPixmap(0, loadSmallPixmap("info"));
+}
+
+KActionCollection *FailedTransfers::actionCollection()
+{
+ return KFTPAPI::getInstance()->mainWindow()->actionCollection();
+}
+
+FailedTransfers::FailedTransfers(QWidget *parent, const char *name)
+ : QWidget(parent, name)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+
+ // Create the list view
+ m_list = new KFTPWidgets::ListView(this);
+
+ // Create the columns
+ m_list->addColumn(i18n("Description"), 500);
+ m_list->addColumn(i18n("Size"), 75);
+ m_list->header()->setStretchEnabled(true, 0);
+
+ // Text when there are no failed transfers
+ m_list->setEmptyListText(i18n("There are no failed transfers."));
+ m_list->setAllColumnsShowFocus(true);
+
+ layout->addWidget(m_list);
+
+ connect(KFTPQueue::Manager::self(), SIGNAL(failedTransferNew(KFTPQueue::FailedTransfer*)), this, SLOT(slotFailedTransferNew(KFTPQueue::FailedTransfer*)));
+ connect(KFTPQueue::Manager::self(), SIGNAL(failedTransferRemoved(long)), this, SLOT(slotFailedTransferRemoved(long)));
+
+ connect(m_list, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)), this, SLOT(contextMenuRequested(KListView*, QListViewItem*, const QPoint&)));
+
+ // Initialize the actions
+ initActions();
+}
+
+FailedTransfers::~FailedTransfers()
+{
+}
+
+void FailedTransfers::initActions()
+{
+ m_restartAction = new KAction(i18n("&Restart Transfer"), "launch", KShortcut(), this, SLOT(slotRestart()), actionCollection(), "launch");
+ m_addToQueueAction = new KAction(i18n("&Add To Queue"), "queue", KShortcut(), this, SLOT(slotAddToQueue()), actionCollection(), "addtoqueue");
+ m_addAllToQueueAction = new KAction(i18n("Add All To Queue"), KShortcut(), this, SLOT(slotAddAllToQueue()), actionCollection(), "addalltoqueue");
+ m_removeAction = new KAction(i18n("R&emove"), "editdelete", KShortcut(), this, SLOT(slotRemove()), actionCollection(), "remove");
+ m_removeAllAction = new KAction(i18n("Remove All"), KShortcut(), this, SLOT(slotRemoveAll()), actionCollection(), "removeall");
+}
+
+void FailedTransfers::updateActions()
+{
+ m_restartAction->setEnabled(m_list->selectedItem());
+ m_addToQueueAction->setEnabled(m_list->selectedItem());
+ m_removeAction->setEnabled(m_list->selectedItem());
+
+ m_addAllToQueueAction->setEnabled(m_list->childCount());
+ m_removeAllAction->setEnabled(m_list->childCount());
+}
+
+void FailedTransfers::slotFailedTransferNew(KFTPQueue::FailedTransfer *transfer)
+{
+ // Create a new failed transfer list item
+ new FailedTransferItem(transfer, m_list);
+}
+
+void FailedTransfers::slotFailedTransferRemoved(long id)
+{
+ // Delete the failed transfer item
+ QListViewItem *item = m_list->findItem(QString::number(id), 2);
+
+ if (item)
+ delete item;
+}
+
+void FailedTransfers::slotRestart()
+{
+ // First restore the transfer
+ KFTPQueue::TransferFile *transfer = static_cast<FailedTransferItem*>(m_list->selectedItem())->getFailedTransfer()->restore();
+
+ // Then execute it
+ transfer->delayedExecute();
+}
+
+void FailedTransfers::slotAddToQueue()
+{
+ // Restore the transfer
+ static_cast<FailedTransferItem*>(m_list->selectedItem())->getFailedTransfer()->restore();
+}
+
+void FailedTransfers::slotAddAllToQueue()
+{
+ KFTPQueue::FailedTransfer *transfer;
+ QPtrList<KFTPQueue::FailedTransfer> *list = KFTPQueue::Manager::self()->getFailedTransferList();
+ QPtrListIterator<KFTPQueue::FailedTransfer> i(*list);
+
+ while ((transfer = i.current()) != 0) {
+ ++i;
+
+ // Restore the transfer
+ transfer->restore();
+ }
+}
+
+void FailedTransfers::slotRemove()
+{
+ if (KMessageBox::questionYesNo(this, i18n("Are you sure you want to remove this failed transfer?")) == KMessageBox::Yes) {
+ // Remove the failed transfer
+ KFTPQueue::Manager::self()->removeFailedTransfer(static_cast<FailedTransferItem*>(m_list->selectedItem())->getFailedTransfer());
+ }
+}
+
+void FailedTransfers::slotRemoveAll()
+{
+ if (KMessageBox::questionYesNo(this, i18n("Are you sure you want to remove ALL failed transfers?")) == KMessageBox::Yes) {
+ KFTPQueue::Manager::self()->clearFailedTransferList();
+ }
+}
+
+void FailedTransfers::contextMenuRequested(KListView*, QListViewItem*, const QPoint &p)
+{
+ KPopupMenu *contextMenu = new KPopupMenu(m_list);
+
+ m_restartAction->plug(contextMenu);
+ m_addToQueueAction->plug(contextMenu);
+ m_addAllToQueueAction->plug(contextMenu);
+ contextMenu->insertSeparator();
+ m_removeAction->plug(contextMenu);
+ m_removeAllAction->plug(contextMenu);
+
+ // Update the actions
+ updateActions();
+
+ contextMenu->exec(p);
+}
+
+}
+
+#include "failedtransfers.moc"
+
diff --git a/kftpgrabber/src/widgets/failedtransfers.h b/kftpgrabber/src/widgets/failedtransfers.h
new file mode 100644
index 0000000..2b17a5a
--- /dev/null
+++ b/kftpgrabber/src/widgets/failedtransfers.h
@@ -0,0 +1,111 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPWIDGETSFAILEDTRANSFERS_H
+#define KFTPWIDGETSFAILEDTRANSFERS_H
+
+#include <klistview.h>
+#include <kaction.h>
+
+#include <qwidget.h>
+#include <qguardedptr.h>
+
+#include "listviewitem.h"
+
+namespace KFTPQueue {
+ class FailedTransfer;
+}
+
+namespace KFTPWidgets {
+
+class ListView;
+
+/**
+ * This class represents a QListViewItem item that contains information
+ * about a specific failed transfer.
+ *
+ * @author Jernej Kos
+ */
+class FailedTransferItem : public KFTPWidgets::ListViewItem
+{
+public:
+ FailedTransferItem(KFTPQueue::FailedTransfer *transfer, QListView *parent);
+
+ KFTPQueue::FailedTransfer *getFailedTransfer() { return m_failedTransfer; }
+private:
+ QGuardedPtr<KFTPQueue::FailedTransfer> m_failedTransfer;
+};
+
+/**
+ * This class provides a list of failed transfers. The transfers
+ * can be restarted.
+ *
+ * @author Jernej Kos
+ */
+class FailedTransfers : public QWidget
+{
+Q_OBJECT
+public:
+ FailedTransfers(QWidget *parent = 0, const char *name = 0);
+ ~FailedTransfers();
+
+ void updateActions();
+ void initActions();
+private:
+ KActionCollection *actionCollection();
+
+ KFTPWidgets::ListView *m_list;
+
+ KAction *m_restartAction;
+ KAction *m_addToQueueAction;
+ KAction *m_addAllToQueueAction;
+ KAction *m_removeAction;
+ KAction *m_removeAllAction;
+private slots:
+ void slotRestart();
+ void slotAddToQueue();
+ void slotAddAllToQueue();
+ void slotRemove();
+ void slotRemoveAll();
+
+ void contextMenuRequested(KListView*, QListViewItem*, const QPoint&);
+
+ void slotFailedTransferNew(KFTPQueue::FailedTransfer*);
+ void slotFailedTransferRemoved(long);
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/filtereditor.cpp b/kftpgrabber/src/widgets/filtereditor.cpp
new file mode 100644
index 0000000..9be3b6e
--- /dev/null
+++ b/kftpgrabber/src/widgets/filtereditor.cpp
@@ -0,0 +1,625 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "filtereditor.h"
+#include "listview.h"
+#include "misc/filterwidgethandler.h"
+
+#include <qlayout.h>
+#include <qhbox.h>
+#include <qtooltip.h>
+#include <qheader.h>
+#include <qbuttongroup.h>
+
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kdialog.h>
+#include <kinputdialog.h>
+
+using namespace KFTPCore::Filter;
+
+namespace KFTPWidgets {
+
+FilterEditor::FilterEditor(QWidget *parent)
+ : QWidget(parent),
+ m_rule(0)
+{
+ QHBoxLayout *mainLayout = new QHBoxLayout(this, 0, KDialog::spacingHint());
+
+ m_listView = new FilterListView(this);
+ mainLayout->addWidget(m_listView, 1);
+
+ QVBoxLayout *rightLayout = new QVBoxLayout(mainLayout);
+ mainLayout->setStretchFactor(rightLayout, KDialog::spacingHint());
+
+ m_enabledCheck = new QCheckBox(i18n("Filter &enabled"), this);
+ rightLayout->addWidget(m_enabledCheck);
+
+ m_conditionsList = new FilterConditionsList(this);
+ rightLayout->addWidget(m_conditionsList, 0, Qt::AlignTop);
+
+ m_actionsList = new FilterActionsList(this);
+ rightLayout->addWidget(m_actionsList, 0, Qt::AlignTop);
+
+ rightLayout->addStretch(1);
+
+ // Connect some signals
+ connect(m_enabledCheck, SIGNAL(clicked()), this, SLOT(slotEnabledChanged()));
+
+ connect(m_listView, SIGNAL(ruleChanged(KFTPCore::Filter::Rule*)), this, SLOT(slotRuleChanged(KFTPCore::Filter::Rule*)));
+ connect(m_listView, SIGNAL(ruleRemoved()), this, SLOT(slotRuleRemoved()));
+
+ connect(m_listView, SIGNAL(ruleChanged(KFTPCore::Filter::Rule*)), m_conditionsList, SLOT(loadRule(KFTPCore::Filter::Rule*)));
+ connect(m_listView, SIGNAL(ruleRemoved()), m_conditionsList, SLOT(reset()));
+
+ connect(m_listView, SIGNAL(ruleChanged(KFTPCore::Filter::Rule*)), m_actionsList, SLOT(loadRule(KFTPCore::Filter::Rule*)));
+ connect(m_listView, SIGNAL(ruleRemoved()), m_actionsList, SLOT(reset()));
+}
+
+void FilterEditor::slotRuleChanged(KFTPCore::Filter::Rule *rule)
+{
+ m_enabledCheck->setEnabled(true);
+ m_enabledCheck->setChecked(rule->isEnabled());
+
+ m_rule = rule;
+}
+
+void FilterEditor::slotRuleRemoved()
+{
+ m_enabledCheck->setChecked(false);
+ m_enabledCheck->setEnabled(false);
+}
+
+void FilterEditor::slotEnabledChanged()
+{
+ if (m_rule)
+ m_rule->setEnabled(m_enabledCheck->isChecked());
+}
+
+void FilterEditor::reset()
+{
+ m_enabledCheck->setChecked(false);
+ m_enabledCheck->setEnabled(false);
+
+ m_conditionsList->reset();
+ m_actionsList->reset();
+ m_listView->reset();
+}
+
+FilterListItem::FilterListItem(ListView *parent, KFTPCore::Filter::Rule *rule)
+ : QListViewItem(parent),
+ m_rule(rule)
+{
+ setText(0, rule->name());
+}
+
+FilterListView::FilterListView(QWidget *parent)
+ : QGroupBox(1, Horizontal, i18n("Filters"), parent)
+{
+ m_listView = new ListView(this);
+ m_listView->setSelectionMode(QListView::Single);
+ m_listView->setSorting(-1);
+ m_listView->header()->hide();
+ m_listView->setMinimumWidth(150);
+ m_listView->setEmptyListText(i18n("No filters."));
+ m_listView->addColumn("");
+ m_listView->setFullWidth(true);
+
+ QHBox *hb = new QHBox(this);
+ hb->setSpacing(4);
+
+ // Up/down buttons
+ m_buttonUp = new KPushButton(QString::null, hb);
+ m_buttonUp->setAutoRepeat(true);
+ m_buttonUp->setIconSet(BarIconSet("up", KIcon::SizeSmall));
+ m_buttonUp->setMinimumSize(m_buttonUp->sizeHint() * 1.2);
+
+ m_buttonDown = new KPushButton(QString::null, hb);
+ m_buttonDown->setAutoRepeat(true);
+ m_buttonDown->setIconSet(BarIconSet("down", KIcon::SizeSmall));
+ m_buttonDown->setMinimumSize(m_buttonDown->sizeHint() * 1.2);
+
+ QToolTip::add(m_buttonUp, i18n("Up"));
+ QToolTip::add(m_buttonDown, i18n("Down"));
+
+ // New, copy, delete buttons
+ hb = new QHBox(this);
+ hb->setSpacing(4);
+
+ m_buttonNew = new QPushButton(QString::null, hb);
+ m_buttonNew->setPixmap(BarIcon("filenew", KIcon::SizeSmall));
+ m_buttonNew->setMinimumSize(m_buttonNew->sizeHint() * 1.2);
+
+ m_buttonCopy = new QPushButton(QString::null, hb);
+ m_buttonCopy->setPixmap(BarIcon("editcopy", KIcon::SizeSmall));
+ m_buttonCopy->setMinimumSize(m_buttonCopy->sizeHint() * 1.2);
+
+ m_buttonDelete = new QPushButton(QString::null, hb);
+ m_buttonDelete->setPixmap(BarIcon("editdelete", KIcon::SizeSmall));
+ m_buttonDelete->setMinimumSize(m_buttonDelete->sizeHint() * 1.2);
+
+ m_buttonRename = new QPushButton(i18n("Rename..."), hb);
+
+ QToolTip::add(m_buttonNew, i18n("New"));
+ QToolTip::add(m_buttonCopy, i18n("Copy"));
+ QToolTip::add(m_buttonDelete, i18n("Delete"));
+
+ // Connect the signals
+ connect(m_buttonNew, SIGNAL(clicked()), this, SLOT(slotNewRule()));
+ connect(m_buttonDelete, SIGNAL(clicked()), this, SLOT(slotDeleteRule()));
+ connect(m_buttonRename, SIGNAL(clicked()), this, SLOT(slotRenameRule()));
+ connect(m_buttonCopy, SIGNAL(clicked()), this, SLOT(slotCopyRule()));
+
+ connect(m_buttonUp, SIGNAL(clicked()), this, SLOT(slotUp()));
+ connect(m_buttonDown, SIGNAL(clicked()), this, SLOT(slotDown()));
+
+ connect(m_listView, SIGNAL(selectionChanged(QListViewItem*)), this, SLOT(slotSelectionChanged(QListViewItem*)));
+
+ m_buttonUp->setEnabled(false);
+ m_buttonDown->setEnabled(false);
+ m_buttonRename->setEnabled(false);
+
+ // Reset the view, loading all the existing rules
+ reset();
+}
+
+void FilterListView::reset()
+{
+ m_listView->clear();
+
+ // Load all existing rules
+ Filters *filters = Filters::self();
+ Filters::ConstIterator le = filters->end();
+
+ for (Filters::ConstIterator i = filters->begin(); i != le; ++i) {
+ FilterListItem *item = new FilterListItem(m_listView, (*i));
+ item->moveItem(m_listView->lastItem());
+ }
+
+ // Select the first rule
+ m_listView->setSelected(m_listView->firstChild(), true);
+}
+
+void FilterListView::slotSelectionChanged(QListViewItem *item)
+{
+ FilterListItem *selected = static_cast<FilterListItem*>(item);
+
+ m_buttonUp->setEnabled(item->itemAbove());
+ m_buttonDown->setEnabled(item->nextSibling());
+ m_buttonRename->setEnabled(true);
+
+ // Signal the rule change
+ emit ruleChanged(selected->rule());
+}
+
+void FilterListView::slotNewRule()
+{
+ Rule *rule = new Rule(i18n("Unnamed Rule"));
+ FilterListItem *selected = static_cast<FilterListItem*>(m_listView->selectedItem());
+ FilterListItem *item = new FilterListItem(m_listView, rule);
+
+ if (selected) {
+ Filters::self()->insert(Filters::self()->findRef(selected->rule()) + 1, rule);
+ item->moveItem(selected);
+ } else {
+ Filters::self()->append(rule);
+ }
+
+ m_listView->setSelected(item, true);
+}
+
+void FilterListView::slotDeleteRule()
+{
+ FilterListItem *selected = static_cast<FilterListItem*>(m_listView->selectedItem());
+
+ if (selected) {
+ Rule *rule = selected->rule();
+ delete selected;
+
+ emit ruleRemoved();
+
+ Filters::self()->removeRef(rule);
+ m_listView->setSelected(m_listView->lastItem(), true);
+ }
+
+ if (!m_listView->selectedItem())
+ m_buttonRename->setEnabled(false);
+}
+
+void FilterListView::slotRenameRule()
+{
+ FilterListItem *selected = static_cast<FilterListItem*>(m_listView->selectedItem());
+
+ if (selected) {
+ QString name = KInputDialog::getText(i18n("Rename Rule"), i18n("Rename rule '%1' to:").arg(selected->rule()->name()), selected->rule()->name());
+
+ if (name.stripWhiteSpace().isEmpty())
+ name = i18n("Unnamed Rule");
+
+ selected->rule()->setName(name);
+ selected->setText(0, name);
+ }
+}
+
+void FilterListView::slotCopyRule()
+{
+ FilterListItem *selected = static_cast<FilterListItem*>(m_listView->selectedItem());
+
+ if (selected) {
+ Rule *rule = new Rule(selected->rule());
+ FilterListItem *item = new FilterListItem(m_listView, rule);
+
+ Filters::self()->insert(Filters::self()->findRef(selected->rule()) + 1, rule);
+ item->moveItem(selected);
+ m_listView->setSelected(item, true);
+ }
+}
+
+void FilterListView::slotUp()
+{
+ FilterListItem *selected = static_cast<FilterListItem*>(m_listView->selectedItem());
+ QListViewItem *tmp = selected->itemAbove();
+ if (!tmp)
+ return;
+
+ FilterListItem *previous = static_cast<FilterListItem*>(tmp->itemAbove());
+
+ if (selected) {
+ Rule *rule = Filters::self()->take(Filters::self()->findRef(selected->rule()));
+
+ if (previous) {
+ Filters::self()->insert(Filters::self()->findRef(previous->rule()) + 1, rule);
+ selected->moveItem(previous);
+ } else {
+ Filters::self()->insert(0, rule);
+ m_listView->takeItem(selected);
+ m_listView->insertItem(selected);
+ m_listView->setSelected(selected, true);
+ }
+
+ m_buttonUp->setEnabled(selected->itemAbove());
+ m_buttonDown->setEnabled(selected->nextSibling());
+ }
+}
+
+void FilterListView::slotDown()
+{
+ FilterListItem *selected = static_cast<FilterListItem*>(m_listView->selectedItem());
+ FilterListItem *next = static_cast<FilterListItem*>(selected->nextSibling());
+
+ if (selected && next) {
+ Rule *rule = Filters::self()->take(Filters::self()->findRef(selected->rule()));
+ Filters::self()->insert(Filters::self()->findRef(next->rule()) + 1, rule);
+ selected->moveItem(next);
+
+ m_buttonUp->setEnabled(selected->itemAbove());
+ m_buttonDown->setEnabled(selected->nextSibling());
+ }
+}
+
+FilterConditionsList::FilterConditionsList(QWidget *parent)
+ : QGroupBox(1, Horizontal, i18n("Conditions"), parent)
+{
+ setEnabled(false);
+
+ m_buttonAll = new QRadioButton(i18n("Match a&ll of the following"), this);
+ m_buttonAny = new QRadioButton(i18n("Match an&y of the following"), this);
+
+ m_buttonAll->setChecked(true);
+ m_buttonAny->setChecked(false);
+
+ QButtonGroup *bg = new QButtonGroup(this);
+ bg->hide();
+ bg->insert(m_buttonAll, (int) ConditionChain::All);
+ bg->insert(m_buttonAny, (int) ConditionChain::Any);
+
+ // Connect some signals
+ connect(bg, SIGNAL(clicked(int)), this, SLOT(slotMatchTypeChanged(int)));
+
+ m_lister = new FilterConditionWidgetLister(this);
+}
+
+void FilterConditionsList::reset()
+{
+ m_lister->clear();
+ setEnabled(false);
+}
+
+void FilterConditionsList::loadRule(Rule *rule)
+{
+ m_rule = rule;
+
+ switch (rule->conditions()->type()) {
+ case ConditionChain::All: m_buttonAll->setChecked(true); break;
+ case ConditionChain::Any: m_buttonAny->setChecked(true); break;
+ }
+
+ m_lister->loadConditions(rule);
+ setEnabled(true);
+}
+
+void FilterConditionsList::slotMatchTypeChanged(int type)
+{
+ if (m_rule)
+ const_cast<ConditionChain*>(m_rule->conditions())->setType((ConditionChain::Type) type);
+}
+
+FilterConditionWidgetLister::FilterConditionWidgetLister(QWidget *parent)
+ : WidgetLister(parent, 0, 7),
+ m_rule(0)
+{
+ setMinimumWidth(400);
+}
+
+void FilterConditionWidgetLister::loadConditions(KFTPCore::Filter::Rule *rule)
+{
+ const ConditionChain *conditions = rule->conditions();
+
+ // Clear the current list
+ setNumberShown(QMAX(conditions->count(), 0));
+
+ ConditionChain::ConstIterator le = conditions->end();
+ QPtrList<QWidget>::Iterator wi = m_widgetList.begin();
+ for (ConditionChain::ConstIterator i = conditions->begin(); i != le; ++i, ++wi)
+ static_cast<FilterConditionWidget*>((*wi))->setCondition((*i));
+
+ m_rule = rule;
+}
+
+void FilterConditionWidgetLister::slotMore()
+{
+ WidgetLister::slotMore();
+
+ // Actually add the condition and update the latest widget
+ Condition *condition = new Condition(Filename, Condition::Contains, QVariant(""));
+
+ const_cast<ConditionChain*>(m_rule->conditions())->append(condition);
+ static_cast<FilterConditionWidget*>(m_widgetList.last())->setCondition(condition);
+}
+
+void FilterConditionWidgetLister::slotFewer()
+{
+ // Actually remove the condition
+ Condition *condition = static_cast<FilterConditionWidget*>(m_widgetList.last())->condition();
+ const_cast<ConditionChain*>(m_rule->conditions())->remove(condition);
+
+ WidgetLister::slotFewer();
+}
+
+void FilterConditionWidgetLister::slotClear()
+{
+ if (m_rule)
+ const_cast<ConditionChain*>(m_rule->conditions())->clear();
+
+ WidgetLister::slotClear();
+}
+
+QWidget *FilterConditionWidgetLister::createWidget(QWidget *parent)
+{
+ return new FilterConditionWidget(parent);
+}
+
+FilterConditionWidget::FilterConditionWidget(QWidget *parent)
+ : QWidget(parent),
+ m_condition(0)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this, 0, KDialog::spacingHint());
+
+ m_fieldCombo = new QComboBox(this);
+ m_fieldCombo->insertStringList(Filters::self()->getFieldNames());
+ layout->addWidget(m_fieldCombo);
+
+ m_typeStack = new QWidgetStack(this);
+ m_typeStack->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ layout->addWidget(m_typeStack);
+
+ m_valueStack = new QWidgetStack(this);
+ m_valueStack->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ layout->addWidget(m_valueStack);
+ layout->setStretchFactor(m_valueStack, 10);
+
+ // Initialize widgets
+ WidgetHandlerManager::self()->createConditionWidgets(m_typeStack, m_valueStack, this);
+
+ // Connect signals
+ connect(m_fieldCombo, SIGNAL(activated(int)), this, SLOT(slotFieldChanged(int)));
+
+ setFocusProxy(m_fieldCombo);
+}
+
+void FilterConditionWidget::setCondition(const Condition *condition)
+{
+ m_condition = const_cast<Condition*>(condition);
+
+ m_fieldCombo->setCurrentItem((int) condition->field());
+ WidgetHandlerManager::self()->setCondition(m_typeStack, m_valueStack, condition);
+}
+
+void FilterConditionWidget::slotFieldChanged(int field)
+{
+ WidgetHandlerManager::self()->update((Field) field, m_typeStack, m_valueStack);
+
+ if (m_condition) {
+ // Update the current condition
+ m_condition->setField((Field) field);
+ slotTypeChanged();
+ }
+}
+
+void FilterConditionWidget::slotTypeChanged()
+{
+ if (m_condition) {
+ // Update the current condition
+ m_condition->setType(WidgetHandlerManager::self()->getConditionType(m_condition->field(), m_typeStack));
+ slotValueChanged();
+ }
+}
+
+void FilterConditionWidget::slotValueChanged()
+{
+ if (m_condition) {
+ // Update the current condition
+ m_condition->setValue(WidgetHandlerManager::self()->getConditionValue(m_condition->field(), m_valueStack));
+ }
+}
+
+FilterActionsList::FilterActionsList(QWidget *parent)
+ : QGroupBox(1, Horizontal, i18n("Actions"), parent)
+{
+ setEnabled(false);
+
+ m_lister = new FilterActionWidgetLister(this);
+}
+
+void FilterActionsList::reset()
+{
+ m_lister->clear();
+ setEnabled(false);
+}
+
+void FilterActionsList::loadRule(Rule *rule)
+{
+ m_rule = rule;
+
+ m_lister->loadActions(rule);
+ setEnabled(true);
+}
+
+FilterActionWidgetLister::FilterActionWidgetLister(QWidget *parent)
+ : WidgetLister(parent, 0, 7),
+ m_rule(0)
+{
+ setMinimumWidth(400);
+}
+
+void FilterActionWidgetLister::loadActions(KFTPCore::Filter::Rule *rule)
+{
+ const ActionChain *actions = rule->actions();
+
+ // Clear the current list
+ setNumberShown(QMAX(actions->count(), 0));
+
+ ActionChain::ConstIterator le = actions->end();
+ QPtrList<QWidget>::Iterator wi = m_widgetList.begin();
+ for (ActionChain::ConstIterator i = actions->begin(); i != le; ++i, ++wi)
+ static_cast<FilterActionWidget*>((*wi))->setAction((*i));
+
+ m_rule = rule;
+}
+
+void FilterActionWidgetLister::slotMore()
+{
+ WidgetLister::slotMore();
+
+ // Actually add the action and update the latest widget
+ Action *action = new Action(Action::None, QVariant());
+
+ const_cast<ActionChain*>(m_rule->actions())->append(action);
+ static_cast<FilterActionWidget*>(m_widgetList.last())->setAction(action);
+}
+
+void FilterActionWidgetLister::slotFewer()
+{
+ // Actually remove the action
+ Action *action = static_cast<FilterActionWidget*>(m_widgetList.last())->action();
+ const_cast<ActionChain*>(m_rule->actions())->remove(action);
+
+ WidgetLister::slotFewer();
+}
+
+void FilterActionWidgetLister::slotClear()
+{
+ if (m_rule)
+ const_cast<ActionChain*>(m_rule->actions())->clear();
+
+ WidgetLister::slotClear();
+}
+
+QWidget *FilterActionWidgetLister::createWidget(QWidget *parent)
+{
+ return new FilterActionWidget(parent);
+}
+
+FilterActionWidget::FilterActionWidget(QWidget *parent)
+ : QWidget(parent),
+ m_action(0)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this, 0, KDialog::spacingHint());
+
+ m_actionCombo = new QComboBox(this);
+ m_actionCombo->insertStringList(Filters::self()->getActionNames());
+ layout->addWidget(m_actionCombo);
+
+ m_valueStack = new QWidgetStack(this);
+ m_valueStack->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ layout->addWidget(m_valueStack);
+ layout->setStretchFactor(m_valueStack, 10);
+
+ // Initialize widgets
+ WidgetHandlerManager::self()->createActionWidgets(m_valueStack, this);
+
+ // Connect signals
+ connect(m_actionCombo, SIGNAL(activated(int)), this, SLOT(slotActionChanged(int)));
+ connect(m_actionCombo, SIGNAL(activated(int)), m_valueStack, SLOT(raiseWidget(int)));
+
+ setFocusProxy(m_actionCombo);
+}
+
+void FilterActionWidget::setAction(const Action *action)
+{
+ m_action = const_cast<Action*>(action);
+
+ m_actionCombo->setCurrentItem((int) action->type());
+ WidgetHandlerManager::self()->setAction(m_valueStack, action);
+}
+
+void FilterActionWidget::slotActionChanged(int field)
+{
+ if (m_action) {
+ m_action->setType((Action::Type) field);
+ slotValueChanged();
+ }
+}
+
+void FilterActionWidget::slotValueChanged()
+{
+ if (m_action)
+ m_action->setValue(WidgetHandlerManager::self()->getActionValue(m_valueStack));
+}
+
+}
+
+#include "filtereditor.moc"
+
diff --git a/kftpgrabber/src/widgets/filtereditor.h b/kftpgrabber/src/widgets/filtereditor.h
new file mode 100644
index 0000000..95fd664
--- /dev/null
+++ b/kftpgrabber/src/widgets/filtereditor.h
@@ -0,0 +1,375 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+#ifndef KFTPWIDGETSFILTEREDITOR_H
+#define KFTPWIDGETSFILTEREDITOR_H
+
+#include "widgetlister.h"
+#include "misc/filter.h"
+
+#include <qwidget.h>
+#include <qpushbutton.h>
+#include <qgroupbox.h>
+#include <qlistview.h>
+#include <qradiobutton.h>
+#include <qcombobox.h>
+#include <qwidgetstack.h>
+#include <qcheckbox.h>
+
+#include <kpushbutton.h>
+
+namespace KFTPWidgets {
+
+class ListView;
+
+/**
+ * A visual representation of a condition.
+ *
+ * @author Jernej Kos
+ */
+class FilterConditionWidget : public QWidget {
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent Parent widget
+ */
+ FilterConditionWidget(QWidget *parent);
+
+ /**
+ * Associate a condition with this widget.
+ *
+ * @param condition The internal condition representation
+ */
+ void setCondition(const KFTPCore::Filter::Condition *condition);
+
+ /**
+ * Return the condition associated with this widget.
+ *
+ * @return A valid condition or 0 if no condition has been associated
+ */
+ KFTPCore::Filter::Condition *condition() const { return m_condition; }
+private slots:
+ void slotFieldChanged(int field);
+ void slotTypeChanged();
+ void slotValueChanged();
+private:
+ QComboBox *m_fieldCombo;
+ QWidgetStack *m_typeStack;
+ QWidgetStack *m_valueStack;
+
+ KFTPCore::Filter::Condition *m_condition;
+};
+
+/**
+ * A container for condition representation widgets.
+ *
+ * @author Jernej Kos
+ */
+class FilterConditionWidgetLister : public WidgetLister {
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent Parent widget
+ */
+ FilterConditionWidgetLister(QWidget *parent);
+
+ /**
+ * Load the conditions from the specified rule.
+ *
+ * @param rule The rule instance
+ */
+ void loadConditions(KFTPCore::Filter::Rule *rule);
+protected:
+ QWidget *createWidget(QWidget *parent);
+protected slots:
+ void slotMore();
+ void slotFewer();
+ void slotClear();
+private:
+ KFTPCore::Filter::Rule *m_rule;
+};
+
+/**
+ * A list of conditions together with all/any configuration.
+ *
+ * @author Jernej Kos
+ */
+class FilterConditionsList : public QGroupBox {
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent Parent widget
+ */
+ FilterConditionsList(QWidget *parent);
+public slots:
+ /**
+ * Reset the condition list and disable it.
+ */
+ void reset();
+
+ /**
+ * Load the conditions from the specified rule.
+ *
+ * @param rule The rule instance
+ */
+ void loadRule(KFTPCore::Filter::Rule *rule);
+private slots:
+ void slotMatchTypeChanged(int type);
+private:
+ QRadioButton *m_buttonAll;
+ QRadioButton *m_buttonAny;
+
+ FilterConditionWidgetLister *m_lister;
+ KFTPCore::Filter::Rule *m_rule;
+};
+
+/**
+ * A visual representation of an action.
+ *
+ * @author Jernej Kos
+ */
+class FilterActionWidget : public QWidget {
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent Parent widget
+ */
+ FilterActionWidget(QWidget *parent);
+
+ /**
+ * Associate an action with this widget.
+ *
+ * @param action The internal action representation
+ */
+ void setAction(const KFTPCore::Filter::Action *action);
+
+ /**
+ * Return the action associated with this widget.
+ *
+ * @return A valid action or 0 if no action has been associated
+ */
+ KFTPCore::Filter::Action *action() const { return m_action; }
+private slots:
+ void slotActionChanged(int field);
+ void slotValueChanged();
+private:
+ QComboBox *m_actionCombo;
+ QWidgetStack *m_valueStack;
+
+ KFTPCore::Filter::Action *m_action;
+};
+
+/**
+ * A container for action representation widgets.
+ *
+ * @author Jernej Kos
+ */
+class FilterActionWidgetLister : public WidgetLister {
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent Parent widget
+ */
+ FilterActionWidgetLister(QWidget *parent);
+
+ /**
+ * Load the actions from the specified rule.
+ *
+ * @param rule The rule instance
+ */
+ void loadActions(KFTPCore::Filter::Rule *rule);
+protected:
+ QWidget *createWidget(QWidget *parent);
+protected slots:
+ void slotMore();
+ void slotFewer();
+ void slotClear();
+private:
+ KFTPCore::Filter::Rule *m_rule;
+};
+
+/**
+ * A list of actions.
+ *
+ * @author Jernej Kos
+ */
+class FilterActionsList : public QGroupBox {
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent Parent widget
+ */
+ FilterActionsList(QWidget *parent);
+public slots:
+ /**
+ * Reset the action list and disable it.
+ */
+ void reset();
+
+ /**
+ * Load the actions from the specified rule.
+ *
+ * @param rule The rule instance
+ */
+ void loadRule(KFTPCore::Filter::Rule *rule);
+private:
+ FilterActionWidgetLister *m_lister;
+ KFTPCore::Filter::Rule *m_rule;
+};
+
+/**
+ * A widget that displays the list of currently loaded filter rules.
+ *
+ * @author Jernej Kos
+ */
+class FilterListView : public QGroupBox {
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent Parent widget
+ */
+ FilterListView(QWidget *parent);
+
+ /**
+ * Reset the filter editor and reload all the rules.
+ */
+ void reset();
+private slots:
+ void slotSelectionChanged(QListViewItem *item);
+
+ void slotNewRule();
+ void slotDeleteRule();
+ void slotRenameRule();
+ void slotCopyRule();
+
+ void slotUp();
+ void slotDown();
+private:
+ ListView *m_listView;
+
+ KPushButton *m_buttonUp;
+ KPushButton *m_buttonDown;
+
+ QPushButton *m_buttonNew;
+ QPushButton *m_buttonCopy;
+ QPushButton *m_buttonDelete;
+ QPushButton *m_buttonRename;
+signals:
+ /**
+ * This signal gets emitted when a new rule should be displayed by
+ * other widgets.
+ *
+ * @param rule The rule to display
+ */
+ void ruleChanged(KFTPCore::Filter::Rule *rule);
+
+ /**
+ * This signal gets emitted when a rule is removed.
+ */
+ void ruleRemoved();
+};
+
+/**
+ * An item visually representing a filter rule.
+ *
+ * @author Jernej Kos
+ */
+class FilterListItem : public QListViewItem {
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent The parent list view
+ * @param rule Rule this item represents
+ */
+ FilterListItem(ListView *parent, KFTPCore::Filter::Rule *rule);
+
+ /**
+ * Get the rule this item represents.
+ */
+ KFTPCore::Filter::Rule *rule() { return m_rule; }
+private:
+ KFTPCore::Filter::Rule *m_rule;
+};
+
+/**
+ * This widget is a global filter editor and enables the user to add,
+ * remove or modify existing filters.
+ *
+ * @author Jernej Kos
+ */
+class FilterEditor : public QWidget {
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ */
+ FilterEditor(QWidget *parent);
+
+ /**
+ * Reset the filter editor and reload all the rules.
+ */
+ void reset();
+private slots:
+ void slotRuleChanged(KFTPCore::Filter::Rule *rule);
+ void slotRuleRemoved();
+
+ void slotEnabledChanged();
+private:
+ KFTPCore::Filter::Rule *m_rule;
+
+ QCheckBox *m_enabledCheck;
+ FilterListView *m_listView;
+ FilterConditionsList *m_conditionsList;
+ FilterActionsList *m_actionsList;
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/kftpfilteraddpatternlayout.cpp b/kftpgrabber/src/widgets/kftpfilteraddpatternlayout.cpp
new file mode 100644
index 0000000..50c403b
--- /dev/null
+++ b/kftpgrabber/src/widgets/kftpfilteraddpatternlayout.cpp
@@ -0,0 +1,92 @@
+#include <klocale.h>
+/****************************************************************************
+** Form implementation generated from reading ui file '/home/kostko/development/kftpgrabber/src/widgets/kftpfilteraddpatternlayout.ui'
+**
+** Created: Mon Oct 20 18:26:31 2003
+** by: The User Interface Compiler ($Id: kftpfilteraddpatternlayout.cpp,v 1.1.1.1 2004/02/13 13:33:43 kostko Exp $)
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+
+#include "kftpfilteraddpatternlayout.h"
+
+#include <qvariant.h>
+#include <qpushbutton.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <klineedit.h>
+#include <kcolorbutton.h>
+#include <qlayout.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+
+/*
+ * Constructs a KFTPFilterAddPatternLayout as a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ */
+KFTPFilterAddPatternLayout::KFTPFilterAddPatternLayout( QWidget* parent, const char* name, WFlags fl )
+ : QWidget( parent, name, fl )
+{
+ if ( !name )
+ setName( "KFTPFilterAddPatternLayout" );
+ KFTPFilterAddPatternLayoutLayout = new QGridLayout( this, 1, 1, 11, 6, "KFTPFilterAddPatternLayoutLayout");
+
+ groupBox1 = new QGroupBox( this, "groupBox1" );
+ groupBox1->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)5, (QSizePolicy::SizeType)2, 0, 0, groupBox1->sizePolicy().hasHeightForWidth() ) );
+ groupBox1->setColumnLayout(0, Qt::Vertical );
+ groupBox1->layout()->setSpacing( 6 );
+ groupBox1->layout()->setMargin( 11 );
+ groupBox1Layout = new QGridLayout( groupBox1->layout() );
+ groupBox1Layout->setAlignment( Qt::AlignTop );
+
+ layout9 = new QHBoxLayout( 0, 0, 6, "layout9");
+
+ layout8 = new QVBoxLayout( 0, 0, 6, "layout8");
+
+ textLabel1 = new QLabel( groupBox1, "textLabel1" );
+ layout8->addWidget( textLabel1 );
+
+ textLabel2 = new QLabel( groupBox1, "textLabel2" );
+ layout8->addWidget( textLabel2 );
+ layout9->addLayout( layout8 );
+
+ layout7 = new QVBoxLayout( 0, 0, 6, "layout7");
+
+ kLineEdit1 = new KLineEdit( groupBox1, "kLineEdit1" );
+ layout7->addWidget( kLineEdit1 );
+
+ kColorButton1 = new KColorButton( groupBox1, "kColorButton1" );
+ kColorButton1->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, kColorButton1->sizePolicy().hasHeightForWidth() ) );
+ layout7->addWidget( kColorButton1 );
+ layout9->addLayout( layout7 );
+
+ groupBox1Layout->addLayout( layout9, 0, 0 );
+
+ KFTPFilterAddPatternLayoutLayout->addWidget( groupBox1, 0, 0 );
+ languageChange();
+ resize( QSize(380, 110).expandedTo(minimumSizeHint()) );
+ clearWState( WState_Polished );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+KFTPFilterAddPatternLayout::~KFTPFilterAddPatternLayout()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void KFTPFilterAddPatternLayout::languageChange()
+{
+ setCaption( tr2i18n( "Form1" ) );
+ groupBox1->setTitle( tr2i18n( "New Pattern" ) );
+ textLabel1->setText( tr2i18n( "Filename pattern:" ) );
+ textLabel2->setText( tr2i18n( "Color:" ) );
+ kColorButton1->setText( QString::null );
+}
+
+#include "kftpfilteraddpatternlayout.moc"
diff --git a/kftpgrabber/src/widgets/kftpfiltereditorlayout.cpp b/kftpgrabber/src/widgets/kftpfiltereditorlayout.cpp
new file mode 100644
index 0000000..b52913c
--- /dev/null
+++ b/kftpgrabber/src/widgets/kftpfiltereditorlayout.cpp
@@ -0,0 +1,115 @@
+#include <klocale.h>
+/****************************************************************************
+** Form implementation generated from reading ui file '/home/kostko/development/kftpgrabber/src/widgets/kftpfiltereditorlayout.ui'
+**
+** Created: Mon Oct 20 16:14:00 2003
+** by: The User Interface Compiler ($Id: kftpfiltereditorlayout.cpp,v 1.1.1.1 2004/02/13 13:33:43 kostko Exp $)
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+
+#include "kftpfiltereditorlayout.h"
+
+#include <qvariant.h>
+#include <qpushbutton.h>
+#include <qtabwidget.h>
+#include <kpushbutton.h>
+#include <qheader.h>
+#include <klistview.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+
+/*
+ * Constructs a KFTPFilterEditorLayout as a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ */
+KFTPFilterEditorLayout::KFTPFilterEditorLayout( QWidget* parent, const char* name, WFlags fl )
+ : QWidget( parent, name, fl )
+{
+ if ( !name )
+ setName( "KFTPFilterEditorLayout" );
+ KFTPFilterEditorLayoutLayout = new QGridLayout( this, 1, 1, 11, 6, "KFTPFilterEditorLayoutLayout");
+
+ tabWidget2 = new QTabWidget( this, "tabWidget2" );
+
+ tab = new QWidget( tabWidget2, "tab" );
+ tabLayout = new QGridLayout( tab, 1, 1, 11, 6, "tabLayout");
+
+ layout1 = new QVBoxLayout( 0, 0, 6, "layout1");
+
+ addPatternButton = new KPushButton( tab, "addPatternButton" );
+ layout1->addWidget( addPatternButton );
+
+ editPatternButton = new KPushButton( tab, "editPatternButton" );
+ layout1->addWidget( editPatternButton );
+
+ removePatternButton = new KPushButton( tab, "removePatternButton" );
+ layout1->addWidget( removePatternButton );
+
+ tabLayout->addLayout( layout1, 0, 1 );
+ QSpacerItem* spacer = new QSpacerItem( 31, 111, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ tabLayout->addItem( spacer, 1, 1 );
+
+ layout2 = new QVBoxLayout( 0, 0, 6, "layout2");
+
+ patternList = new KListView( tab, "patternList" );
+ patternList->addColumn( tr2i18n( "Pattern" ) );
+ patternList->addColumn( tr2i18n( "Color" ) );
+ layout2->addWidget( patternList );
+
+ enabledCheck = new QCheckBox( tab, "enabledCheck" );
+ layout2->addWidget( enabledCheck );
+
+ tabLayout->addMultiCellLayout( layout2, 0, 1, 0, 0 );
+ tabWidget2->insertTab( tab, QString("") );
+
+ tab_2 = new QWidget( tabWidget2, "tab_2" );
+
+ textLabel1 = new QLabel( tab_2, "textLabel1" );
+ textLabel1->setGeometry( QRect( 10, 10, 130, 20 ) );
+ tabWidget2->insertTab( tab_2, QString("") );
+
+ tab_3 = new QWidget( tabWidget2, "tab_3" );
+
+ textLabel1_2 = new QLabel( tab_3, "textLabel1_2" );
+ textLabel1_2->setGeometry( QRect( 10, 10, 130, 20 ) );
+ tabWidget2->insertTab( tab_3, QString("") );
+
+ KFTPFilterEditorLayoutLayout->addWidget( tabWidget2, 0, 0 );
+ languageChange();
+ resize( QSize(456, 299).expandedTo(minimumSizeHint()) );
+ clearWState( WState_Polished );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+KFTPFilterEditorLayout::~KFTPFilterEditorLayout()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void KFTPFilterEditorLayout::languageChange()
+{
+ setCaption( tr2i18n( "Form1" ) );
+ addPatternButton->setText( tr2i18n( "Add pattern" ) );
+ editPatternButton->setText( tr2i18n( "Edit" ) );
+ removePatternButton->setText( tr2i18n( "Remove" ) );
+ patternList->header()->setLabel( 0, tr2i18n( "Pattern" ) );
+ patternList->header()->setLabel( 1, tr2i18n( "Color" ) );
+ enabledCheck->setText( tr2i18n( "Enabled" ) );
+ tabWidget2->changeTab( tab, tr2i18n( "Highlighting" ) );
+ textLabel1->setText( tr2i18n( "<b>Not yet implemented.</b>" ) );
+ tabWidget2->changeTab( tab_2, tr2i18n( "Skip List" ) );
+ textLabel1_2->setText( tr2i18n( "<b>Not yet implemented.</b>" ) );
+ tabWidget2->changeTab( tab_3, tr2i18n( "ASCII xtensions" ) );
+}
+
+#include "kftpfiltereditorlayout.moc"
diff --git a/kftpgrabber/src/widgets/kftpselectserverdialog.cpp b/kftpgrabber/src/widgets/kftpselectserverdialog.cpp
new file mode 100644
index 0000000..f3b6b3a
--- /dev/null
+++ b/kftpgrabber/src/widgets/kftpselectserverdialog.cpp
@@ -0,0 +1,79 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2004 by the KFTPGrabber developers
+ * Copyright (C) 2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "kftpbookmarks.h"
+#include "kftpselectserverdialog.h"
+#include "kftpbookmarks.h"
+#include "bookmarks/listview.h"
+#include "misc.h"
+
+#include <klistview.h>
+#include <kiconloader.h>
+#include <klocale.h>
+
+using namespace KFTPGrabberBase;
+
+KFTPSelectServerDialog::KFTPSelectServerDialog(QWidget *parent, const char *name)
+ : KDialogBase(parent, name, true, "Select a server", KDialogBase::Ok | KDialogBase::Cancel,
+ KDialogBase::Ok), m_selectedSite(0)
+{
+ m_tree = new KFTPWidgets::Bookmarks::ListView(KFTPBookmarks::Manager::self(), this);
+ m_tree->setMinimumWidth(270);
+ m_tree->fillBookmarkData();
+
+ connect(m_tree, SIGNAL(clicked(QListViewItem*)), this, SLOT(slotTreeClicked()));
+
+ // Set some stuff
+ setMainWidget(m_tree);
+ enableButtonOK(false);
+}
+
+void KFTPSelectServerDialog::slotTreeClicked()
+{
+ enableButtonOK(false);
+
+ if (m_tree->selectedItem()) {
+ if (static_cast<KFTPWidgets::Bookmarks::ListViewItem*>(m_tree->selectedItem())->m_type == 1) {
+ // Set the active server
+ m_selectedSite = static_cast<KFTPWidgets::Bookmarks::ListViewItem*>(m_tree->selectedItem())->m_site;
+
+ enableButtonOK(true);
+ return;
+ }
+ }
+}
+
+
+#include "kftpselectserverdialog.moc"
diff --git a/kftpgrabber/src/widgets/kftpselectserverdialog.h b/kftpgrabber/src/widgets/kftpselectserverdialog.h
new file mode 100644
index 0000000..8c4afd3
--- /dev/null
+++ b/kftpgrabber/src/widgets/kftpselectserverdialog.h
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2004 by the KFTPGrabber developers
+ * Copyright (C) 2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPSELECTSERVERDIALOG_H
+#define KFTPSELECTSERVERDIALOG_H
+
+#include <kdialogbase.h>
+#include <qdom.h>
+#include <qlistview.h>
+
+namespace KFTPBookmarks {
+ class Site;
+}
+
+namespace KFTPWidgets {
+namespace Bookmarks {
+ class ListView;
+}
+}
+
+/**
+@author Jernej Kos
+*/
+class KFTPSelectServerDialog : public KDialogBase
+{
+Q_OBJECT
+public:
+ KFTPSelectServerDialog(QWidget *parent = 0, const char *name = 0);
+
+ KFTPBookmarks::Site *getSelectedSite() { return m_selectedSite; }
+private:
+ KFTPWidgets::Bookmarks::ListView *m_tree;
+ KFTPBookmarks::Site *m_selectedSite;
+private slots:
+ void slotTreeClicked();
+};
+
+#endif
diff --git a/kftpgrabber/src/widgets/kftpserverlineedit.cpp b/kftpgrabber/src/widgets/kftpserverlineedit.cpp
new file mode 100644
index 0000000..87e94e3
--- /dev/null
+++ b/kftpgrabber/src/widgets/kftpserverlineedit.cpp
@@ -0,0 +1,105 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "kftpbookmarks.h"
+#include "kftpserverlineedit.h"
+#include "kftpselectserverdialog.h"
+
+#include <kdialog.h>
+#include <kpushbutton.h>
+#include <klocale.h>
+
+#include <qlayout.h>
+
+KFTPServerLineEdit::KFTPServerLineEdit(QWidget *parent, const char *name, WFlags f)
+ : QWidget(parent, name, f), m_currentSite(0)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this, 0, KDialog::spacingHint());
+
+ m_lineEdit = new KLineEdit(this);
+ m_lineEdit->setReadOnly(true);
+
+ KPushButton *selectButton = new KPushButton(i18n("Select..."), this);
+ selectButton->setFlat(true);
+ connect(selectButton, SIGNAL(clicked()), this, SLOT(slotSelectButtonClicked()));
+
+ layout->addWidget(m_lineEdit);
+ layout->addWidget(selectButton);
+}
+
+KFTPServerLineEdit::~KFTPServerLineEdit()
+{
+}
+
+void KFTPServerLineEdit::setCurrentSite(KFTPBookmarks::Site *site)
+{
+ if (site) {
+ m_currentSite = site;
+ m_lineEdit->setText(m_currentSite->getAttribute("name"));
+
+ emit siteChanged(m_currentSite);
+ } else {
+ m_currentSite = 0L;
+
+ clear();
+ }
+}
+
+void KFTPServerLineEdit::clear()
+{
+ m_lineEdit->clear();
+}
+
+void KFTPServerLineEdit::slotSelectButtonClicked()
+{
+ KFTPSelectServerDialog *dialog = new KFTPSelectServerDialog(this);
+
+ if (dialog->exec() == QDialog::Accepted) {
+ m_currentSite = dialog->getSelectedSite();
+
+ if (m_currentSite)
+ m_lineEdit->setText(m_currentSite->getAttribute("name"));
+ else
+ m_lineEdit->setText(i18n("No name"));
+
+ emit siteChanged(m_currentSite);
+ }
+
+ delete dialog;
+}
+
+
+
+#include "kftpserverlineedit.moc"
diff --git a/kftpgrabber/src/widgets/kftpserverlineedit.h b/kftpgrabber/src/widgets/kftpserverlineedit.h
new file mode 100644
index 0000000..dd471ae
--- /dev/null
+++ b/kftpgrabber/src/widgets/kftpserverlineedit.h
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPSERVERLINEEDIT_H
+#define KFTPSERVERLINEEDIT_H
+
+#include <qwidget.h>
+#include <qdom.h>
+
+#include <klineedit.h>
+
+namespace KFTPBookmarks {
+ class Site;
+}
+
+/**
+@author Jernej Kos
+*/
+class KFTPServerLineEdit : public QWidget
+{
+Q_OBJECT
+public:
+ KFTPServerLineEdit(QWidget *parent = 0, const char *name = 0, WFlags f = 0);
+ ~KFTPServerLineEdit();
+
+ KFTPBookmarks::Site *getCurrentSite() { return m_currentSite; }
+ void setCurrentSite(KFTPBookmarks::Site *site);
+
+ void clear();
+private:
+ KFTPBookmarks::Site *m_currentSite;
+ KLineEdit *m_lineEdit;
+private slots:
+ void slotSelectButtonClicked();
+signals:
+ void siteChanged(KFTPBookmarks::Site *site);
+};
+
+#endif
diff --git a/kftpgrabber/src/widgets/kftptabwidget.cpp b/kftpgrabber/src/widgets/kftptabwidget.cpp
new file mode 100644
index 0000000..317f887
--- /dev/null
+++ b/kftpgrabber/src/widgets/kftptabwidget.cpp
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "kftptabwidget.h"
+#include "kftptabwidget.moc"
+
+KFTPTabWidget::KFTPTabWidget( QWidget* parent, const char* name )
+ : KTabWidget ( parent, name )
+{
+}
+
+
+KFTPTabWidget::~KFTPTabWidget()
+{
+}
+
+void KFTPTabWidget::mousePressEvent( QMouseEvent* )
+{
+ emit mouseEvent( this->name() );
+}
diff --git a/kftpgrabber/src/widgets/kftptabwidget.h b/kftpgrabber/src/widgets/kftptabwidget.h
new file mode 100644
index 0000000..d17efe3
--- /dev/null
+++ b/kftpgrabber/src/widgets/kftptabwidget.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+#ifndef KFTPTABWIDGET_H
+#define KFTPTABWIDGET_H
+
+#include <ktabwidget.h>
+
+/**
+@author Blacknator
+*/
+class KFTPTabWidget : public KTabWidget
+{
+ private:
+ Q_OBJECT
+
+ public:
+ KFTPTabWidget( QWidget* parent = 0, const char* name = 0 );
+ ~KFTPTabWidget();
+
+ virtual void mousePressEvent( QMouseEvent* mouseEvent );
+
+ signals:
+ void mouseEvent( QString widgetName );
+
+};
+
+#endif
diff --git a/kftpgrabber/src/widgets/kftpzeroconflistview.cpp b/kftpgrabber/src/widgets/kftpzeroconflistview.cpp
new file mode 100644
index 0000000..eb60204
--- /dev/null
+++ b/kftpgrabber/src/widgets/kftpzeroconflistview.cpp
@@ -0,0 +1,98 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "kftpzeroconflistview.h"
+#include "kftpapi.h"
+#include "kftpsession.h"
+
+#include <kdeversion.h>
+
+#if KDE_IS_VERSION(3,4,0)
+#include "kftpzeroconf.h"
+#endif
+
+#include <klocale.h>
+#include <kiconloader.h>
+
+KFTPZeroConfListView::KFTPZeroConfListView(QWidget *parent, const char *name)
+ : KFTPWidgets::ListView(parent, name)
+{
+ // Set some stuff
+ setMinimumWidth(150);
+ setFullWidth(true);
+ addColumn(i18n("Sites Near You"));
+ setRootIsDecorated(true);
+ setEmptyListText(i18n("No sites published."));
+ setItemsRenameable(false);
+
+#if KDE_IS_VERSION(3,4,0)
+ connect(KFTPAPI::getInstance()->zeroConfInterface(), SIGNAL(servicesUpdated()), this, SLOT(slotSitesChanged()));
+ connect(this, SIGNAL(executed(QListViewItem*)), this, SLOT(slotSiteExecuted(QListViewItem*)));
+
+ slotSitesChanged();
+#endif
+}
+
+void KFTPZeroConfListView::slotSitesChanged()
+{
+#if KDE_IS_VERSION(3,4,0)
+ // Update the site list
+ QValueList<DNSSD::RemoteService::Ptr> list = KFTPAPI::getInstance()->zeroConfInterface()->getServiceList();
+
+ clear();
+ if (!list.isEmpty()) {
+ QValueList<DNSSD::RemoteService::Ptr>::iterator end(list.end());
+
+ for (QValueList<DNSSD::RemoteService::Ptr>::iterator i(list.begin()); i != end; ++i) {
+ QString name = (*i)->serviceName();
+ QString ip = (*i)->hostName();
+ QString port = QString::number((*i)->port());
+
+ KListViewItem *site = new KListViewItem(this, name, ip, port);
+ site->setPixmap(0, SmallIcon("lan"));
+ }
+ }
+#endif
+}
+
+void KFTPZeroConfListView::slotSiteExecuted(QListViewItem *item)
+{
+#if KDE_IS_VERSION(3,4,0)
+ // Connect to the site
+ KFTPAPI::getInstance()->mainWindow()->slotQuickConnect(item->text(0), item->text(1), item->text(2).toInt());
+#endif
+}
+
+#include "kftpzeroconflistview.moc"
diff --git a/kftpgrabber/src/widgets/kftpzeroconflistview.h b/kftpgrabber/src/widgets/kftpzeroconflistview.h
new file mode 100644
index 0000000..9aea9aa
--- /dev/null
+++ b/kftpgrabber/src/widgets/kftpzeroconflistview.h
@@ -0,0 +1,56 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPZEROCONFLISTVIEW_H
+#define KFTPZEROCONFLISTVIEW_H
+
+#include "listview.h"
+
+/**
+ * This class provides a list view that displays all current FTP servers published via Zeroconf protocol.
+ *
+ * @author Jernej Kos
+ */
+class KFTPZeroConfListView : public KFTPWidgets::ListView
+{
+Q_OBJECT
+public:
+ KFTPZeroConfListView(QWidget *parent = 0, const char *name = 0);
+private slots:
+ void slotSitesChanged();
+ void slotSiteExecuted(QListViewItem*);
+};
+
+#endif
diff --git a/kftpgrabber/src/widgets/listview.cpp b/kftpgrabber/src/widgets/listview.cpp
new file mode 100644
index 0000000..635130b
--- /dev/null
+++ b/kftpgrabber/src/widgets/listview.cpp
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "listview.h"
+
+#include <qpainter.h>
+#include <qstringlist.h>
+
+namespace KFTPWidgets {
+
+ListView::ListView(QWidget *parent, const char *name)
+ : KListView(parent, name)
+{
+}
+
+
+ListView::~ListView()
+{
+}
+
+void ListView::resizeEvent(QResizeEvent *e)
+{
+ KListView::resizeEvent(e);
+ triggerUpdate();
+}
+
+void ListView::setEmptyListText(const QString &text)
+{
+ m_emptyListText = text;
+ triggerUpdate();
+}
+
+void ListView::drawContentsOffset(QPainter * p, int ox, int oy, int cx, int cy, int cw, int ch)
+{
+ KListView::drawContentsOffset(p, ox, oy, cx, cy, cw, ch);
+
+ if (childCount() == 0 && !m_emptyListText.isEmpty()) {
+ p->setPen(Qt::darkGray);
+
+ QStringList lines = QStringList::split("\n", m_emptyListText);
+ int ypos = 10 + p->fontMetrics().height();
+
+ QStringList::Iterator end(lines.end());
+ for (QStringList::Iterator str( lines.begin() ); str != end; ++str) {
+ p->drawText((viewport()->width()/2)-(p->fontMetrics().width(*str)/2), ypos, *str);
+ ypos += p->fontMetrics().lineSpacing();
+ }
+ }
+}
+
+}
+
+#include "listview.moc"
diff --git a/kftpgrabber/src/widgets/listview.h b/kftpgrabber/src/widgets/listview.h
new file mode 100644
index 0000000..8718f97
--- /dev/null
+++ b/kftpgrabber/src/widgets/listview.h
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPLISTVIEW_H
+#define KFTPLISTVIEW_H
+
+#include <klistview.h>
+
+namespace KFTPWidgets {
+
+/**
+ * @author Jernej Kos
+ */
+class ListView : public KListView
+{
+Q_OBJECT
+public:
+ ListView(QWidget *parent = 0, const char *name = 0);
+ ~ListView();
+
+ void setEmptyListText(const QString &text);
+ virtual void resizeEvent(QResizeEvent *e);
+protected:
+ virtual void drawContentsOffset(QPainter * p, int ox, int oy, int cx, int cy, int cw, int ch );
+private:
+ QString m_emptyListText;
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/listviewitem.cpp b/kftpgrabber/src/widgets/listviewitem.cpp
new file mode 100644
index 0000000..6b91feb
--- /dev/null
+++ b/kftpgrabber/src/widgets/listviewitem.cpp
@@ -0,0 +1,96 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "listviewitem.h"
+
+#include <qheader.h>
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qsimplerichtext.h>
+
+namespace KFTPWidgets {
+
+ListViewItem::ListViewItem(QListView *parent)
+ : KListViewItem(parent)
+{
+}
+
+void ListViewItem::setRichText(int col, const QString &text)
+{
+ setText(col, QString::null);
+ m_richText[col] = text;
+}
+
+void ListViewItem::setup()
+{
+ QListViewItem::setup();
+
+ int maxHeight = height();
+
+ for (int i = 0; i < listView()->header()->count() - 1; i++) {
+ if (text(i).isNull()) {
+ QSimpleRichText rt(m_richText[i], QFont());
+ maxHeight = rt.height() > maxHeight ? rt.height() : maxHeight;
+ }
+ }
+
+ setHeight(maxHeight);
+}
+
+void ListViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment)
+{
+ if (text(column).isNull()) {
+ KListViewItem::paintCell(p, cg, column, width, alignment);
+ int pad = 0;
+
+ if (pixmap(column)) {
+ pad = pixmap(column)->width() + 5;
+ }
+
+ QSimpleRichText rt(m_richText[column], p->font());
+ rt.draw(p, pad, 0, QRect(pad, 0, width, height()), cg);
+ } else if (m_colors.contains(column)) {
+ QColorGroup _cg(cg);
+ QColor c = _cg.text();
+
+ _cg.setColor(QColorGroup::Text, m_colors[column]);
+ KListViewItem::paintCell(p, _cg, column, width, alignment);
+ _cg.setColor(QColorGroup::Text, c);
+ } else {
+ KListViewItem::paintCell(p, cg, column, width, alignment);
+ }
+}
+
+}
diff --git a/kftpgrabber/src/widgets/listviewitem.h b/kftpgrabber/src/widgets/listviewitem.h
new file mode 100644
index 0000000..b9edc23
--- /dev/null
+++ b/kftpgrabber/src/widgets/listviewitem.h
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPWIDGETSLISTVIEWITEM_H
+#define KFTPWIDGETSLISTVIEWITEM_H
+
+#include <klistview.h>
+
+#include <qmap.h>
+#include <qcolor.h>
+
+namespace KFTPWidgets {
+
+/**
+ * This class is a simple QListViewItem replacement that supports displaying
+ * richtext.
+ *
+ * @author Jernej Kos
+ */
+class ListViewItem : public KListViewItem
+{
+public:
+ ListViewItem(QListView *parent);
+
+ void setRichText(int col, const QString &text);
+ QString richText(int col) { return m_richText[col]; }
+
+ void setTextColor(int col, QColor color) { m_colors[col] = color; }
+
+ void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment);
+ void setup();
+private:
+ QMap<int, QString> m_richText;
+ QMap<int, QColor> m_colors;
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/logview.cpp b/kftpgrabber/src/widgets/logview.cpp
new file mode 100644
index 0000000..bac9df8
--- /dev/null
+++ b/kftpgrabber/src/widgets/logview.cpp
@@ -0,0 +1,143 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "logview.h"
+#include "misc/config.h"
+#include "kftpapi.h"
+
+#include <klocale.h>
+#include <kstdaction.h>
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+
+#include <qfile.h>
+#include <qtextstream.h>
+
+namespace KFTPWidgets {
+
+LogView::LogView(QWidget *parent, const char *name)
+ : KTextEdit(parent, name)
+{
+ setTextFormat(Qt::LogText);
+ setMaxLogLines(200);
+ setFont(KFTPCore::Config::logFont());
+
+ // Override disabled background of KTextEdit
+ unsetPalette();
+
+ // Init actions
+ m_saveToFileAction = KStdAction::saveAs(this, SLOT(slotSaveToFile()), KFTPAPI::getInstance()->mainWindow()->actionCollection(), "log_safeAs");
+ m_clearLogAction = KStdAction::clear(this, SLOT(slotClearLog()), KFTPAPI::getInstance()->mainWindow()->actionCollection(), "log_clear");
+
+ append(i18n("<b>KFTPGrabber</b> logger initialized.<br>"));
+}
+
+
+LogView::~LogView()
+{
+}
+
+QPopupMenu *LogView::createPopupMenu(const QPoint &pos)
+{
+ QPopupMenu *menu = KTextEdit::createPopupMenu(pos);
+
+ m_saveToFileAction->plug(menu);
+ menu->insertSeparator();
+ m_clearLogAction->plug(menu);
+
+ return menu;
+}
+
+void LogView::slotSaveToFile()
+{
+ QString savePath = KFileDialog::getSaveFileName();
+
+ if (!savePath.isEmpty()) {
+ QFile file(savePath);
+ if (file.open(IO_WriteOnly)) {
+ QTextStream stream(&file);
+ stream << text();
+ file.close();
+ } else {
+ KMessageBox::error(0L, i18n("Unable to open file for writing."));
+ }
+ }
+}
+
+void LogView::slotClearLog()
+{
+ clear();
+}
+
+void LogView::append(const QString &text)
+{
+ QDateTime dt = QDateTime::currentDateTime();
+ QTextEdit::append("[" + dt.toString("hh:mm:ss") + "] " + text);
+ scrollToBottom();
+}
+
+void LogView::ftpLog(int type, const QString &text)
+{
+ // Set the font if changed
+ if (KFTPCore::Config::logFont() != font())
+ setFont(KFTPCore::Config::logFont());
+
+ QString line;
+ line = text.stripWhiteSpace();
+ line.replace("<", "&lt;");
+ line.replace(">", "&gt;");
+ switch (type) {
+ case 0: {
+ QString code = line.section(" ", 0, 0);
+ QString text = line.mid(line.find(' ')+1);
+ append("<font color=" + KFTPCore::Config::logResponsesColor().name() + "><b>" + code + "</b> " + text + "</font><br>");
+ break;
+ }
+ case 1: {
+ if (line.left(4) == "PASS")
+ line = "PASS (hidden)";
+
+ append("<font color=" + KFTPCore::Config::logCommandsColor().name() + "><b>" + line + "</b></font><br>");
+ break;
+ }
+ case 2: append("<font color=" + KFTPCore::Config::logMultilineColor().name() + ">" + line + "</font><br>"); break;
+ case 3: append("<font color=" + KFTPCore::Config::logStatusColor().name() + "><b>*** " + line + "</b></font><br>"); break;
+ case 4: append("<font color=" + KFTPCore::Config::logErrorColor().name() + "><b>*** " + line + "</b></font><br>"); break;
+ }
+}
+
+}
+
+#include "logview.moc"
diff --git a/kftpgrabber/src/widgets/logview.h b/kftpgrabber/src/widgets/logview.h
new file mode 100644
index 0000000..ac2f9e3
--- /dev/null
+++ b/kftpgrabber/src/widgets/logview.h
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPLOGVIEW_H
+#define KFTPLOGVIEW_H
+
+#include <ktextedit.h>
+#include <kaction.h>
+
+#include <qpopupmenu.h>
+
+namespace KFTPWidgets {
+
+/**
+ * This class provides a simple log widget.
+ *
+ * @author Jernej Kos
+ */
+class LogView : public KTextEdit
+{
+Q_OBJECT
+public:
+ LogView(QWidget *parent = 0, const char *name = 0);
+ ~LogView();
+
+ void append(const QString &text);
+protected:
+ KAction *m_saveToFileAction;
+ KAction *m_clearLogAction;
+
+ QPopupMenu *createPopupMenu(const QPoint &pos);
+public slots:
+ void ftpLog(int type, const QString &text);
+private slots:
+ void slotSaveToFile();
+ void slotClearLog();
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/multitabbar.cpp b/kftpgrabber/src/widgets/multitabbar.cpp
new file mode 100644
index 0000000..2b7c583
--- /dev/null
+++ b/kftpgrabber/src/widgets/multitabbar.cpp
@@ -0,0 +1,1160 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ * Copyright (C) 2001-2003 by Joseph Wenninger <jowenn@kde.org>
+ * Copyright (C) 2005 by Mark Kretschmann <markey@web.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 "multitabbar.h"
+#include "multitabbar.moc"
+#include "multitabbar_p.h"
+#include "multitabbar_p.moc"
+
+#include <math.h>
+
+#include <qapplication.h>
+#include <qbutton.h>
+#include <qpopupmenu.h>
+#include <qlayout.h>
+#include <qpainter.h>
+#include <qtooltip.h>
+#include <qfontmetrics.h>
+#include <qstyle.h>
+#include <qtimer.h>
+
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <kstringhandler.h>
+
+#define NEARBYINT(i) ((int(float(i) + 0.5)))
+
+namespace KFTPWidgets {
+
+class MultiTabBarTabPrivate
+{
+public:
+ QPixmap pix;
+};
+
+
+MultiTabBarInternal::MultiTabBarInternal( QWidget *parent, MultiTabBar::MultiTabBarMode bm ) : QScrollView( parent )
+{
+ m_expandedTabSize = -1;
+ m_showActiveTabTexts = false;
+ m_tabs.setAutoDelete( true );
+ m_barMode = bm;
+ setHScrollBarMode( AlwaysOff );
+ setVScrollBarMode( AlwaysOff );
+ if ( bm == MultiTabBar::Vertical ) {
+ box = new QWidget( viewport() );
+ mainLayout = new QVBoxLayout( box );
+ mainLayout->setAutoAdd( true );
+ box->setFixedWidth( 24 );
+ setFixedWidth( 24 );
+ } else {
+ box = new QWidget( viewport() );
+ mainLayout = new QHBoxLayout( box );
+ mainLayout->setAutoAdd( true );
+ box->setFixedHeight( 24 );
+ setFixedHeight( 24 );
+ }
+ addChild( box );
+ setFrameStyle( NoFrame );
+ viewport() ->setBackgroundMode( Qt::PaletteBackground );
+ /* box->setPaletteBackgroundColor(Qt::red);
+ setPaletteBackgroundColor(Qt::green);*/
+}
+
+void MultiTabBarInternal::setStyle( enum MultiTabBar::MultiTabBarStyle style )
+{
+ m_style = style;
+ for ( uint i = 0;i < m_tabs.count();i++ )
+ m_tabs.at( i ) ->setStyle( m_style );
+
+ if ( ( m_style == MultiTabBar::KDEV3 ) ||
+ ( m_style == MultiTabBar::KDEV3ICON ) ||
+ ( m_style == MultiTabBar::AMAROK ) ) {
+ delete mainLayout;
+ mainLayout = 0;
+ resizeEvent( 0 );
+ } else if ( mainLayout == 0 ) {
+ if ( m_barMode == MultiTabBar::Vertical ) {
+ box = new QWidget( viewport() );
+ mainLayout = new QVBoxLayout( box );
+ box->setFixedWidth( 24 );
+ setFixedWidth( 24 );
+ } else {
+ box = new QWidget( viewport() );
+ mainLayout = new QHBoxLayout( box );
+ box->setFixedHeight( 24 );
+ setFixedHeight( 24 );
+ }
+ addChild( box );
+ for ( uint i = 0;i < m_tabs.count();i++ )
+ mainLayout->add( m_tabs.at( i ) );
+ mainLayout->setAutoAdd( true );
+
+ }
+ viewport() ->repaint();
+}
+
+void MultiTabBarInternal::drawContents ( QPainter * paint, int clipx, int clipy, int clipw, int cliph )
+{
+ QScrollView::drawContents ( paint , clipx, clipy, clipw, cliph );
+
+ if ( m_position == MultiTabBar::Right ) {
+
+ paint->setPen( colorGroup().shadow() );
+ paint->drawLine( 0, 0, 0, viewport() ->height() );
+ paint->setPen( colorGroup().background().dark( 120 ) );
+ paint->drawLine( 1, 0, 1, viewport() ->height() );
+
+
+ } else
+ if ( m_position == MultiTabBar::Left ) {
+ paint->setPen( colorGroup().light() );
+ paint->drawLine( 23, 0, 23, viewport() ->height() );
+ paint->drawLine( 22, 0, 22, viewport() ->height() );
+
+ paint->setPen( colorGroup().shadow() );
+ paint->drawLine( 0, 0, 0, viewport() ->height() );
+ } else
+ if ( m_position == MultiTabBar::Bottom ) {
+ paint->setPen( colorGroup().shadow() );
+ paint->drawLine( 0, 0, viewport() ->width(), 0 );
+ paint->setPen( colorGroup().background().dark( 120 ) );
+ paint->drawLine( 0, 1, viewport() ->width(), 1 );
+ } else {
+ paint->setPen( colorGroup().light() );
+ paint->drawLine( 0, 23, viewport() ->width(), 23 );
+ paint->drawLine( 0, 22, viewport() ->width(), 22 );
+
+ /* paint->setPen(colorGroup().shadow());
+ paint->drawLine(0,0,0,viewport()->height());*/
+
+ }
+
+
+}
+
+void MultiTabBarInternal::contentsMousePressEvent( QMouseEvent *ev )
+{
+ ev->ignore();
+}
+
+void MultiTabBarInternal::mousePressEvent( QMouseEvent *ev )
+{
+ ev->ignore();
+}
+
+
+#define CALCDIFF(m_tabs,diff,i) if (m_lines>(int)lines) {\
+ /*kdDebug()<<"i="<<i<<" tabCount="<<tabCount<<" space="<<space<<endl;*/ \
+ uint ulen=0;\
+ diff=0; \
+ for (uint i2=i;i2<tabCount;i2++) {\
+ uint l1=m_tabs.at(i2)->neededSize();\
+ if ((ulen+l1)>space){\
+ if (ulen==0) diff=0;\
+ else diff=((float)(space-ulen))/(i2-i);\
+ break;\
+ }\
+ ulen+=l1;\
+ }\
+ } else {diff=0; }
+
+
+void MultiTabBarInternal::resizeEvent( QResizeEvent *ev )
+{
+ /* kdDebug()<<"MultiTabBarInternal::resizeEvent"<<endl;
+ kdDebug()<<"MultiTabBarInternal::resizeEvent - box geometry"<<box->geometry()<<endl;
+ kdDebug()<<"MultiTabBarInternal::resizeEvent - geometry"<<geometry()<<endl;*/
+ if ( ev ) QScrollView::resizeEvent( ev );
+
+ if ( ( m_style == MultiTabBar::KDEV3 ) ||
+ ( m_style == MultiTabBar::KDEV3ICON ) ||
+ ( m_style == MultiTabBar::AMAROK ) ) {
+ box->setGeometry( 0, 0, width(), height() );
+ int lines = 1;
+ uint space;
+ float tmp = 0;
+ if ( ( m_position == MultiTabBar::Bottom ) || ( m_position == MultiTabBar::Top ) )
+ space = width();
+ else
+ space = height();
+
+ int cnt = 0;
+ //CALCULATE LINES
+ const uint tabCount = m_tabs.count();
+ for ( uint i = 0;i < tabCount;i++ ) {
+ cnt++;
+ tmp += m_tabs.at( i ) ->neededSize();
+ if ( tmp > space ) {
+ if ( cnt > 1 ) i--;
+ else if ( i == ( tabCount - 1 ) ) break;
+ cnt = 0;
+ tmp = 0;
+ lines++;
+ }
+ }
+ //SET SIZE & PLACE
+ float diff = 0;
+ cnt = 0;
+
+ if ( ( m_position == MultiTabBar::Bottom ) || ( m_position == MultiTabBar::Top ) ) {
+
+ setFixedHeight( lines * 24 );
+ box->setFixedHeight( lines * 24 );
+ m_lines = height() / 24 - 1;
+ lines = 0;
+ CALCDIFF( m_tabs, diff, 0 )
+ tmp = -diff;
+
+ //kdDebug()<<"m_lines recalculated="<<m_lines<<endl;
+ for ( uint i = 0;i < tabCount;i++ ) {
+ MultiTabBarTab *tab = m_tabs.at( i );
+ cnt++;
+ tmp += tab->neededSize() + diff;
+ if ( tmp > space ) {
+ //kdDebug()<<"about to start new line"<<endl;
+ if ( cnt > 1 ) {
+ CALCDIFF( m_tabs, diff, i )
+ i--;
+ } else {
+ //kdDebug()<<"placing line on old line"<<endl;
+ kdDebug() << "diff=" << diff << endl;
+ tab->removeEventFilter( this );
+ tab->move( NEARBYINT( tmp - tab->neededSize() ), lines * 24 );
+ // tab->setFixedWidth(tab->neededSize()+diff);
+ tab->setFixedWidth( NEARBYINT( tmp + diff ) - tab->x() );;
+ tab->installEventFilter( this );
+ CALCDIFF( m_tabs, diff, ( i + 1 ) )
+
+ }
+ tmp = -diff;
+ cnt = 0;
+ lines++;
+ //kdDebug()<<"starting new line:"<<lines<<endl;
+
+ } else {
+ //kdDebug()<<"Placing line on line:"<<lines<<" pos: (x/y)=("<<tmp-m_tabs.at(i)->neededSize()<<"/"<<lines*24<<")"<<endl;
+ //kdDebug()<<"diff="<<diff<<endl;
+ tab->removeEventFilter( this );
+ tab->move( NEARBYINT( tmp - tab->neededSize() ), lines * 24 );
+ tab->setFixedWidth( NEARBYINT( tmp + diff ) - tab->x() );;
+
+ //tab->setFixedWidth(tab->neededSize()+diff);
+ tab->installEventFilter( this );
+
+ }
+ }
+ } else {
+ setFixedWidth( lines * 24 );
+ box->setFixedWidth( lines * 24 );
+ m_lines = lines = width() / 24;
+ lines = 0;
+ CALCDIFF( m_tabs, diff, 0 )
+ tmp = -diff;
+
+ for ( uint i = 0;i < tabCount;i++ ) {
+ MultiTabBarTab *tab = m_tabs.at( i );
+ cnt++;
+ tmp += tab->neededSize() + diff;
+ if ( tmp > space ) {
+ if ( cnt > 1 ) {
+ CALCDIFF( m_tabs, diff, i );
+ tmp = -diff;
+ i--;
+ } else {
+ tab->removeEventFilter( this );
+ tab->move( lines * 24, NEARBYINT( tmp - tab->neededSize() ) );
+ tab->setFixedHeight( NEARBYINT( tmp + diff ) - tab->y() );;
+ tab->installEventFilter( this );
+ }
+ cnt = 0;
+ tmp = -diff;
+ lines++;
+ } else {
+ tab->removeEventFilter( this );
+ tab->move( lines * 24, NEARBYINT( tmp - tab->neededSize() ) );
+ tab->setFixedHeight( NEARBYINT( tmp + diff ) - tab->y() );;
+ tab->installEventFilter( this );
+ }
+ }
+ }
+
+
+ //kdDebug()<<"needed lines:"<<m_lines<<endl;
+ } else {
+ int size = 0; /*move the calculation into another function and call it only on add tab and tab click events*/
+ for ( int i = 0;i < ( int ) m_tabs.count();i++ )
+ size += ( m_barMode == MultiTabBar::Vertical ? m_tabs.at( i ) ->height() : m_tabs.at( i ) ->width() );
+ if ( ( m_position == MultiTabBar::Bottom ) || ( m_position == MultiTabBar::Top ) )
+ box->setGeometry( 0, 0, size, height() );
+ else box->setGeometry( 0, 0, width(), size );
+
+ }
+}
+
+
+void MultiTabBarInternal::showActiveTabTexts( bool show )
+{
+ m_showActiveTabTexts = show;
+}
+
+
+MultiTabBarTab* MultiTabBarInternal::tab( int id ) const
+{
+ for ( QPtrListIterator<MultiTabBarTab> it( m_tabs );it.current();++it ) {
+ if ( it.current() ->id() == id ) return it.current();
+ }
+ return 0;
+}
+
+bool MultiTabBarInternal::eventFilter( QObject *, QEvent *e )
+{
+ if ( e->type() == QEvent::Resize )
+ resizeEvent( 0 );
+
+ //PATCH by markey: Allow switching of tabs with mouse wheel
+ if ( e->type() == QEvent::Wheel ) {
+ QWheelEvent* event = static_cast<QWheelEvent*>( e );
+ const int delta = event->delta() / 120;
+
+ // Determine which tab is currently active
+ uint i;
+ for( i = 0; i < m_tabs.count(); i++ )
+ if ( m_tabs.at( i )->isOn() ) break;
+
+ // Calculate index of the new tab to activate
+ int newTab = i - delta;
+ if ( newTab < 0 ) newTab = 0;
+ if ( newTab > (int)m_tabs.count() - 1 ) newTab = m_tabs.count() - 1;
+
+ if ( i < m_tabs.count() && newTab != (int)i )
+ m_tabs.at( newTab )->animateClick();
+
+ // Must return true here for the wheel to work properly
+ return true;
+ }
+
+ return false;
+}
+
+int MultiTabBarInternal::appendTab(const QPixmap &pic , int id, const QString &text)
+{
+ MultiTabBarTab *tab;
+
+ m_tabs.append(tab = new MultiTabBarTab(this, pic, text, id, box, m_position, m_style));
+ tab->installEventFilter(this);
+ tab->showActiveTabText(m_showActiveTabTexts);
+
+ if (m_style == MultiTabBar::KONQSBC) {
+ if (m_expandedTabSize < tab->neededSize()) {
+ m_expandedTabSize = tab->neededSize();
+
+ for (uint i = 0; i < m_tabs.count(); i++)
+ m_tabs.at(i)->setSize(m_expandedTabSize);
+ } else {
+ tab->setSize(m_expandedTabSize);
+ }
+ } else {
+ tab->updateState();
+ }
+
+ tab->show();
+ resizeEvent(0);
+
+ return 0;
+}
+
+void MultiTabBarInternal::removeTab( int id )
+{
+ for ( uint pos = 0;pos < m_tabs.count();pos++ ) {
+ if ( m_tabs.at( pos ) ->id() == id ) {
+ m_tabs.remove( pos );
+ resizeEvent( 0 );
+ break;
+ }
+ }
+}
+
+void MultiTabBarInternal::setPosition( enum MultiTabBar::MultiTabBarPosition pos )
+{
+ m_position = pos;
+ for ( uint i = 0;i < m_tabs.count();i++ )
+ m_tabs.at( i ) ->setTabsPosition( m_position );
+ viewport() ->repaint();
+}
+
+
+MultiTabBarButton::MultiTabBarButton(MultiTabBarInternal *tb, const QPixmap& pic, const QString& text, QPopupMenu *popup,
+ int id, QWidget *parent, MultiTabBar::MultiTabBarPosition pos, MultiTabBar::MultiTabBarStyle style )
+ : QPushButton(QIconSet(), text, parent),
+ m_tb(tb),
+ m_style(style),
+ m_animCount(0),
+ m_animTimer(new QTimer(this))
+{
+ setIconSet(pic);
+ setText(text);
+
+ m_position = pos;
+
+ if (popup)
+ setPopup( popup );
+
+ setFlat(true);
+ setFixedHeight(24);
+ setFixedWidth(24);
+ m_id = id;
+
+ connect(this, SIGNAL(clicked()), this, SLOT(slotClicked()));
+ connect(m_animTimer, SIGNAL(timeout()), this, SLOT(slotAnimTimer()));
+}
+
+MultiTabBarButton::MultiTabBarButton(MultiTabBarInternal *tb, const QString& text, QPopupMenu *popup,
+ int id, QWidget *parent, MultiTabBar::MultiTabBarPosition pos, MultiTabBar::MultiTabBarStyle style )
+ : QPushButton(QIconSet(), text, parent),
+ m_tb(tb),
+ m_style(style),
+ m_animCount(0),
+ m_animTimer(new QTimer(this))
+{
+ setText(text);
+ m_position = pos;
+
+ if (popup)
+ setPopup(popup);
+
+ setFlat(true);
+ setFixedHeight(24);
+ setFixedWidth(24);
+ m_id = id;
+
+ connect(this, SIGNAL(clicked()), this, SLOT(slotClicked()));
+ connect(m_animTimer, SIGNAL(timeout()), this, SLOT(slotAnimTimer()));
+}
+
+MultiTabBarButton::~MultiTabBarButton()
+{}
+
+int MultiTabBarButton::id() const
+{
+ return m_id;
+}
+
+void MultiTabBarButton::setText(const QString& text)
+{
+ QPushButton::setText(text);
+ m_text = text;
+}
+
+void MultiTabBarButton::slotClicked()
+{
+ emit clicked(m_id);
+}
+
+void MultiTabBarButton::setPosition(MultiTabBar::MultiTabBarPosition pos)
+{
+ m_position = pos;
+ repaint();
+}
+
+void MultiTabBarButton::setStyle(MultiTabBar::MultiTabBarStyle style)
+{
+ m_style = style;
+ repaint();
+}
+
+void MultiTabBarButton::hideEvent(QHideEvent* he)
+{
+ QPushButton::hideEvent(he);
+
+ MultiTabBar *tb = dynamic_cast<MultiTabBar*>(parentWidget());
+ if (tb)
+ tb->updateSeparator();
+}
+
+void MultiTabBarButton::showEvent(QShowEvent* he)
+{
+ QPushButton::showEvent(he);
+
+ MultiTabBar *tb = dynamic_cast<MultiTabBar*>(parentWidget());
+ if (tb)
+ tb->updateSeparator();
+}
+
+void MultiTabBarButton::enterEvent(QEvent*)
+{
+ m_animEnter = true;
+ m_animCount = 0;
+
+ m_animTimer->start(ANIM_INTERVAL);
+}
+
+void MultiTabBarButton::leaveEvent(QEvent*)
+{
+ if (m_animCount == 0)
+ m_animCount = 1;
+
+ m_animEnter = false;
+ m_animTimer->start(ANIM_INTERVAL);
+}
+
+void MultiTabBarButton::slotAnimTimer()
+{
+ if (m_animEnter) {
+ m_animCount += 1;
+ repaint(false);
+
+ if (m_animCount >= ANIM_MAX)
+ m_animTimer->stop();
+ } else {
+ m_animCount -= 1;
+ repaint(false);
+
+ if (m_animCount <= 0)
+ m_animTimer->stop();
+ }
+}
+
+QSize MultiTabBarButton::sizeHint() const
+{
+ constPolish();
+
+ int w = 0, h = 0;
+
+ // calculate contents size...
+#ifndef QT_NO_ICONSET
+ if ( iconSet() && !iconSet() ->isNull() ) {
+ int iw = iconSet() ->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 4;
+ int ih = iconSet() ->pixmap( QIconSet::Small, QIconSet::Normal ).height();
+ w += iw;
+ h = QMAX( h, ih );
+ }
+#endif
+ if ( isMenuButton() )
+ w += style().pixelMetric( QStyle::PM_MenuButtonIndicator, this );
+
+ if ( pixmap() ) {
+ QPixmap * pm = ( QPixmap * ) pixmap();
+ w += pm->width();
+ h += pm->height();
+ } else {
+ QString s( text() );
+ bool empty = s.isEmpty();
+ if ( empty )
+ s = QString::fromLatin1( "XXXX" );
+ QFontMetrics fm = fontMetrics();
+ QSize sz = fm.size( ShowPrefix, s );
+ if ( !empty || !w )
+ w += sz.width();
+ if ( !empty || !h )
+ h = QMAX( h, sz.height() );
+ }
+
+ //PATCH by markey
+ if ((m_style == MultiTabBar::AMAROK)) {
+ if (m_position == MultiTabBar::Bottom)
+ w = (parentWidget()->width() - 3) / m_tb->tabs()->count();
+ else
+ h = (parentWidget()->height() - 3) / m_tb->tabs()->count();
+ }
+
+ return ( style().sizeFromContents( QStyle::CT_ToolButton, this, QSize( w, h ) ).
+ expandedTo( QApplication::globalStrut() ) );
+}
+
+
+MultiTabBarTab::MultiTabBarTab( MultiTabBarInternal *tb, const QPixmap& pic, const QString& text,
+ int id, QWidget *parent, MultiTabBar::MultiTabBarPosition pos,
+ MultiTabBar::MultiTabBarStyle style )
+ : MultiTabBarButton(tb, text, 0, id, parent, pos, style),
+ m_showActiveTabText(false)
+{
+ d = new MultiTabBarTabPrivate();
+ setIcon( pic );
+ m_expandedSize = 24;
+ setToggleButton( true );
+
+ // Prevent flicker on redraw
+ setWFlags( getWFlags() | Qt::WNoAutoErase );
+}
+
+MultiTabBarTab::~MultiTabBarTab()
+{
+ delete d;
+}
+
+
+void MultiTabBarTab::setTabsPosition( MultiTabBar::MultiTabBarPosition pos )
+{
+ if ( ( pos != m_position ) && ( ( pos == MultiTabBar::Left ) || ( pos == MultiTabBar::Right ) ) ) {
+ if ( !d->pix.isNull() ) {
+ QWMatrix temp; // (1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F);
+ temp.rotate( 180 );
+ d->pix = d->pix.xForm( temp );
+ setIconSet( d->pix );
+ }
+ }
+
+ setPosition( pos );
+ // repaint();
+}
+
+void MultiTabBarTab::setIcon( const QString& icon )
+{
+ QPixmap pic = SmallIcon( icon );
+ setIcon( pic );
+}
+
+void MultiTabBarTab::setIcon( const QPixmap& icon )
+{
+
+ if ( m_style != MultiTabBar::KDEV3 ) {
+ if ( ( m_position == MultiTabBar::Left ) || ( m_position == MultiTabBar::Right ) ) {
+ QWMatrix rotateMatrix;
+ if ( m_position == MultiTabBar::Left )
+ rotateMatrix.rotate( 90 );
+ else
+ rotateMatrix.rotate( -90 );
+ QPixmap pic = icon.xForm( rotateMatrix ); //TODO FIX THIS, THIS SHOWS WINDOW
+ d->pix = pic;
+ setIconSet( pic );
+ } else setIconSet( icon );
+ }
+}
+
+void MultiTabBarTab::slotClicked()
+{
+ if (m_animTimer->isActive()) {
+ m_animCount = ANIM_MAX;
+ m_animTimer->stop();
+ repaint();
+ }
+
+ updateState();
+ MultiTabBarButton::slotClicked();
+}
+
+void MultiTabBarTab::setState(bool b)
+{
+ setOn(b);
+ updateState();
+}
+
+void MultiTabBarTab::updateState()
+{
+
+ if ( m_style != MultiTabBar::KONQSBC ) {
+ if ( ( m_style == MultiTabBar::KDEV3 ) || ( m_style == MultiTabBar::KDEV3ICON ) || ( m_style == MultiTabBar::AMAROK ) || ( isOn() ) ) {
+ QPushButton::setText( m_text );
+ } else {
+ kdDebug() << "MultiTabBarTab::updateState(): setting text to an empty QString***************" << endl;
+ QPushButton::setText( QString::null );
+ }
+
+ if ( ( m_position == MultiTabBar::Right || m_position == MultiTabBar::Left ) ) {
+ setFixedWidth( 24 );
+ if ( ( m_style == MultiTabBar::KDEV3 ) || ( m_style == MultiTabBar::KDEV3ICON ) || ( m_style == MultiTabBar::AMAROK ) || ( isOn() ) ) {
+ setFixedHeight( MultiTabBarButton::sizeHint().width() );
+ } else setFixedHeight( 36 );
+ } else {
+ setFixedHeight( 24 );
+ if ( ( m_style == MultiTabBar::KDEV3 ) || ( m_style == MultiTabBar::KDEV3ICON ) || ( m_style == MultiTabBar::AMAROK ) || ( isOn() ) ) {
+ setFixedWidth( MultiTabBarButton::sizeHint().width() );
+ } else setFixedWidth( 36 );
+ }
+ } else {
+ if ( ( !isOn() ) || ( !m_showActiveTabText ) ) {
+ setFixedWidth( 24 );
+ setFixedHeight( 24 );
+ return ;
+ }
+ if ( ( m_position == MultiTabBar::Right || m_position == MultiTabBar::Left ) )
+ setFixedHeight( m_expandedSize );
+ else
+ setFixedWidth( m_expandedSize );
+ }
+ QApplication::sendPostedEvents( 0, QEvent::Paint | QEvent::Move | QEvent::Resize | QEvent::LayoutHint );
+ QApplication::flush();
+}
+
+int MultiTabBarTab::neededSize()
+{
+ if (m_style == MultiTabBar::AMAROK) {
+ if (m_position == MultiTabBar::Left)
+ return (parentWidget()->height() - 3) / m_tb->tabs()->count();
+ else
+ return (parentWidget()->width() - 3) / m_tb->tabs()->count();
+ } else {
+ return (((m_style != MultiTabBar::KDEV3 ) ? 24 : 0) + QFontMetrics(QFont()).width(m_text) + 6);
+ }
+}
+
+void MultiTabBarTab::setSize( int size )
+{
+ m_expandedSize = size;
+ updateState();
+}
+
+void MultiTabBarTab::showActiveTabText(bool show)
+{
+ m_showActiveTabText = show;
+}
+
+void MultiTabBarTab::drawButtonLabel(QPainter *p)
+{
+ drawButton(p);
+}
+void MultiTabBarTab::drawButton(QPainter *paint)
+{
+ if (m_style == MultiTabBar::AMAROK) {
+ drawButtonAmarok(paint);
+ } else if (m_style != MultiTabBar::KONQSBC) {
+ drawButtonStyled(paint);
+ } else {
+ drawButtonClassic(paint);
+ }
+}
+
+void MultiTabBarTab::drawButtonStyled( QPainter *paint )
+{
+
+ QSize sh;
+ const int width = 36; // rotated
+ const int height = 24;
+ if ( ( m_style == MultiTabBar::KDEV3 ) || ( m_style == MultiTabBar::KDEV3ICON ) || ( m_style == MultiTabBar::AMAROK ) || ( isOn() ) ) {
+ if ( ( m_position == MultiTabBar::Left ) || ( m_position == MultiTabBar::Right ) )
+ sh = QSize( this->height(), this->width() ); //MultiTabBarButton::sizeHint();
+ else sh = QSize( this->width(), this->height() );
+ } else
+ sh = QSize( width, height );
+
+ QPixmap pixmap( sh.width(), height ); ///,sh.height());
+ pixmap.fill( eraseColor() );
+ QPainter painter( &pixmap );
+
+
+ QStyle::SFlags st = QStyle::Style_Default;
+
+ st |= QStyle::Style_Enabled;
+
+ if ( isOn() ) st |= QStyle::Style_On;
+
+ style().drawControl( QStyle::CE_PushButton, &painter, this, QRect( 0, 0, pixmap.width(), pixmap.height() ), colorGroup(), st );
+ style().drawControl( QStyle::CE_PushButtonLabel, &painter, this, QRect( 0, 0, pixmap.width(), pixmap.height() ), colorGroup(), st );
+
+ switch ( m_position ) {
+ case MultiTabBar::Left:
+ paint->rotate( -90 );
+ paint->drawPixmap( 1 - pixmap.width(), 0, pixmap );
+ break;
+ case MultiTabBar::Right:
+ paint->rotate( 90 );
+ paint->drawPixmap( 0, 1 - pixmap.height(), pixmap );
+ break;
+
+ default:
+ paint->drawPixmap( 0, 0, pixmap );
+ break;
+ }
+ // style().drawControl(QStyle::CE_PushButtonLabel,painter,this, QRect(0,0,pixmap.width(),pixmap.height()),
+ // colorGroup(),QStyle::Style_Enabled);
+
+
+}
+
+void MultiTabBarTab::drawButtonClassic( QPainter *paint )
+{
+ QPixmap pixmap;
+ if ( iconSet() )
+ pixmap = iconSet() ->pixmap( QIconSet::Small, QIconSet::Normal );
+ paint->fillRect( 0, 0, 24, 24, colorGroup().background() );
+
+ if ( !isOn() ) {
+
+ if ( m_position == MultiTabBar::Right ) {
+ paint->fillRect( 0, 0, 21, 21, QBrush( colorGroup().background() ) );
+
+ paint->setPen( colorGroup().background().dark( 150 ) );
+ paint->drawLine( 0, 22, 23, 22 );
+
+ paint->drawPixmap( 12 - pixmap.width() / 2, 12 - pixmap.height() / 2, pixmap );
+
+ paint->setPen( colorGroup().shadow() );
+ paint->drawLine( 0, 0, 0, 23 );
+ paint->setPen( colorGroup().background().dark( 120 ) );
+ paint->drawLine( 1, 0, 1, 23 );
+
+ } else
+ if ( ( m_position == MultiTabBar::Bottom ) || ( m_position == MultiTabBar::Top ) ) {
+ paint->fillRect( 0, 1, 23, 22, QBrush( colorGroup().background() ) );
+
+ paint->drawPixmap( 12 - pixmap.width() / 2, 12 - pixmap.height() / 2, pixmap );
+
+ paint->setPen( colorGroup().background().dark( 120 ) );
+ paint->drawLine( 23, 0, 23, 23 );
+
+
+ paint->setPen( colorGroup().light() );
+ paint->drawLine( 0, 22, 23, 22 );
+ paint->drawLine( 0, 23, 23, 23 );
+ paint->setPen( colorGroup().shadow() );
+ paint->drawLine( 0, 0, 23, 0 );
+ paint->setPen( colorGroup().background().dark( 120 ) );
+ paint->drawLine( 0, 1, 23, 1 );
+
+ } else {
+ paint->setPen( colorGroup().background().dark( 120 ) );
+ paint->drawLine( 0, 23, 23, 23 );
+ paint->fillRect( 0, 0, 23, 21, QBrush( colorGroup().background() ) );
+ paint->drawPixmap( 12 - pixmap.width() / 2, 12 - pixmap.height() / 2, pixmap );
+
+ paint->setPen( colorGroup().light() );
+ paint->drawLine( 23, 0, 23, 23 );
+ paint->drawLine( 22, 0, 22, 23 );
+
+ paint->setPen( colorGroup().shadow() );
+ paint->drawLine( 0, 0, 0, 23 );
+
+ }
+
+
+ } else {
+ if ( m_position == MultiTabBar::Right ) {
+ paint->setPen( colorGroup().shadow() );
+ paint->drawLine( 0, height() - 1, 23, height() - 1 );
+ paint->drawLine( 0, height() - 2, 23, height() - 2 );
+ paint->drawLine( 23, 0, 23, height() - 1 );
+ paint->drawLine( 22, 0, 22, height() - 1 );
+ paint->fillRect( 0, 0, 21, height() - 3, QBrush( colorGroup().light() ) );
+ paint->drawPixmap( 10 - pixmap.width() / 2, 10 - pixmap.height() / 2, pixmap );
+
+ if ( m_showActiveTabText ) {
+ if ( height() < 25 + 4 ) return ;
+
+ QPixmap tpixmap( height() - 25 - 3, width() - 2 );
+ QPainter painter( &tpixmap );
+
+ painter.fillRect( 0, 0, tpixmap.width(), tpixmap.height(), QBrush( colorGroup().light() ) );
+
+ painter.setPen( colorGroup().text() );
+ painter.drawText( 0, + width() / 2 + QFontMetrics( QFont() ).height() / 2, m_text );
+
+ paint->rotate( 90 );
+ kdDebug() << "tpixmap.width:" << tpixmap.width() << endl;
+ paint->drawPixmap( 25, -tpixmap.height() + 1, tpixmap );
+ }
+
+ } else
+ if ( m_position == MultiTabBar::Top ) {
+ paint->fillRect( 0, 0, width() - 1, 23, QBrush( colorGroup().light() ) );
+ paint->drawPixmap( 10 - pixmap.width() / 2, 10 - pixmap.height() / 2, pixmap );
+ if ( m_showActiveTabText ) {
+ paint->setPen( colorGroup().text() );
+ paint->drawText( 25, height() / 2 + QFontMetrics( QFont() ).height() / 2, m_text );
+ }
+ } else
+ if ( m_position == MultiTabBar::Bottom ) {
+ paint->setPen( colorGroup().shadow() );
+ paint->drawLine( 0, 23, width() - 1, 23 );
+ paint->drawLine( 0, 22, width() - 1, 22 );
+ paint->fillRect( 0, 0, width() - 1, 21, QBrush( colorGroup().light() ) );
+ paint->drawPixmap( 10 - pixmap.width() / 2, 10 - pixmap.height() / 2, pixmap );
+ if ( m_showActiveTabText ) {
+ paint->setPen( colorGroup().text() );
+ paint->drawText( 25, height() / 2 + QFontMetrics( QFont() ).height() / 2, m_text );
+ }
+
+ } else {
+
+
+ paint->setPen( colorGroup().shadow() );
+ paint->drawLine( 0, height() - 1, 23, height() - 1 );
+ paint->drawLine( 0, height() - 2, 23, height() - 2 );
+ paint->fillRect( 0, 0, 23, height() - 3, QBrush( colorGroup().light() ) );
+ paint->drawPixmap( 10 - pixmap.width() / 2, 10 - pixmap.height() / 2, pixmap );
+ if ( m_showActiveTabText ) {
+
+ if ( height() < 25 + 4 ) return ;
+
+ QPixmap tpixmap( height() - 25 - 3, width() - 2 );
+ QPainter painter( &tpixmap );
+
+ painter.fillRect( 0, 0, tpixmap.width(), tpixmap.height(), QBrush( colorGroup().light() ) );
+
+ painter.setPen( colorGroup().text() );
+ painter.drawText( tpixmap.width() - QFontMetrics( QFont() ).width( m_text ), + width() / 2 + QFontMetrics( QFont() ).height() / 2, m_text );
+
+ paint->rotate( -90 );
+ kdDebug() << "tpixmap.width:" << tpixmap.width() << endl;
+
+ paint->drawPixmap( -24 - tpixmap.width(), 2, tpixmap );
+
+ }
+
+ }
+
+ }
+}
+
+void MultiTabBarTab::drawButtonAmarok(QPainter *paint)
+{
+ QColor fillColor, textColor;
+
+ if (isOn()) {
+ fillColor = blendColors(colorGroup().highlight(), colorGroup().background(), static_cast<int>(m_animCount * 3.5));
+ textColor = blendColors(colorGroup().highlightedText(), colorGroup().text(), static_cast<int>(m_animCount * 4.5));
+ } else {
+ fillColor = blendColors(colorGroup().background(), colorGroup().highlight(), static_cast<int>(m_animCount * 3.5));
+ textColor = blendColors(colorGroup().text(), colorGroup().highlightedText(), static_cast<int>(m_animCount * 4.5));
+ }
+
+ const QPixmap icon = iconSet()->pixmap(QIconSet::Small, QIconSet::Normal);
+
+ // Our pixmap
+ QPixmap pixmap;
+
+ if (m_position == MultiTabBar::Left)
+ pixmap.resize(height(), width());
+ else
+ pixmap.resize(width(), height());
+
+ pixmap.fill(fillColor);
+ QPainter painter(&pixmap);
+
+ // Draw the frame
+ painter.setPen(colorGroup().mid());
+ if (m_id != m_tb->tabs()->count() - 1)
+ painter.drawLine(0, 0, 0, pixmap.height() - 1);
+ painter.drawLine(0, pixmap.height() - 1, pixmap.width() - 1, pixmap.height() - 1);
+
+ // Draw the text
+ QFont font;
+ font.setBold(isOn());
+ painter.setFont(font);
+ QString text = KStringHandler::rPixelSqueeze(m_text, QFontMetrics(font), pixmap.width() - icon.width() - 3);
+ text.replace( "...", ".." );
+ const int textX = pixmap.width() / 2 - QFontMetrics( font ).width( text ) / 2;
+ painter.setPen(textColor);
+ const QRect rect(textX + icon.width() / 2 + 2, 0, pixmap.width(), pixmap.height());
+ painter.drawText(rect, Qt::AlignLeft | Qt::AlignVCenter, text);
+
+ // Draw the icon
+ painter.drawPixmap(textX - icon.width() / 2 - 2, pixmap.height() / 2 - icon.height() / 2, icon);
+
+ // Paint to widget
+ if (m_position == MultiTabBar::Left) {
+ paint->rotate(-90);
+ paint->drawPixmap(1 - pixmap.width(), 0, pixmap);
+ } else {
+ paint->drawPixmap(0, 0, pixmap);
+ }
+}
+
+QColor MultiTabBarTab::blendColors( const QColor& color1, const QColor& color2, int percent )
+{
+ const float factor1 = ( 100 - ( float ) percent ) / 100;
+ const float factor2 = ( float ) percent / 100;
+
+ const int r = static_cast<int>( color1.red() * factor1 + color2.red() * factor2 );
+ const int g = static_cast<int>( color1.green() * factor1 + color2.green() * factor2 );
+ const int b = static_cast<int>( color1.blue() * factor1 + color2.blue() * factor2 );
+
+ QColor result;
+ result.setRgb( r, g, b );
+
+ return result;
+}
+
+
+
+
+MultiTabBar::MultiTabBar( MultiTabBarMode bm, QWidget *parent, const char *name ) : QWidget( parent, name )
+{
+ m_buttons.setAutoDelete( false );
+ if ( bm == Vertical ) {
+ m_l = new QVBoxLayout( this );
+ setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Expanding, true );
+ // setFixedWidth(24);
+ } else {
+ m_l = new QHBoxLayout( this );
+ setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed, true );
+ // setFixedHeight(24);
+ }
+ m_l->setMargin( 0 );
+ m_l->setAutoAdd( false );
+
+ m_internal = new MultiTabBarInternal( this, bm );
+ setPosition( ( bm == MultiTabBar::Vertical ) ? MultiTabBar::Right : MultiTabBar::Bottom );
+ setStyle( VSNET );
+ // setStyle(KDEV3);
+ //setStyle(KONQSBC);
+ m_l->insertWidget( 0, m_internal );
+ m_l->insertWidget( 0, m_btnTabSep = new QFrame( this ) );
+ m_btnTabSep->setFixedHeight( 4 );
+ m_btnTabSep->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ m_btnTabSep->setLineWidth( 2 );
+ m_btnTabSep->hide();
+
+ updateGeometry();
+}
+
+MultiTabBar::~MultiTabBar()
+{}
+
+/*int MultiTabBar::insertButton(QPixmap pic,int id ,const QString&)
+{
+(new KToolbarButton(pic,id,m_internal))->show();
+return 0;
+}*/
+
+int MultiTabBar::appendButton( const QPixmap &pic , int id, QPopupMenu *popup, const QString& )
+{
+ MultiTabBarButton * btn;
+ m_buttons.append(btn = new MultiTabBarButton(m_internal, pic, QString::null, popup, id, this, m_position, m_internal->m_style));
+
+ m_l->insertWidget( 0, btn );
+ btn->show();
+ m_btnTabSep->show();
+
+ return 0;
+}
+
+void MultiTabBar::updateSeparator()
+{
+ bool hideSep = true;
+ for ( QPtrListIterator<MultiTabBarButton> it( m_buttons );it.current();++it ) {
+ if ( it.current() ->isVisibleTo( this ) ) {
+ hideSep = false;
+ break;
+ }
+ }
+ if ( hideSep ) m_btnTabSep->hide();
+ else m_btnTabSep->show();
+
+}
+
+int MultiTabBar::appendTab( const QPixmap &pic , int id , const QString& text )
+{
+ m_internal->appendTab( pic, id, text );
+ return 0;
+}
+
+MultiTabBarButton* MultiTabBar::button( int id ) const
+{
+ for ( QPtrListIterator<MultiTabBarButton> it( m_buttons );it.current();++it ) {
+ if ( it.current() ->id() == id ) return it.current();
+ }
+ return 0;
+}
+
+MultiTabBarTab* MultiTabBar::tab( int id ) const
+{
+ return m_internal->tab( id );
+}
+
+
+
+void MultiTabBar::removeButton( int id )
+{
+ for ( uint pos = 0;pos < m_buttons.count();pos++ ) {
+ if ( m_buttons.at( pos ) ->id() == id ) {
+ m_buttons.take( pos ) ->deleteLater();
+ break;
+ }
+ }
+ if ( m_buttons.count() == 0 ) m_btnTabSep->hide();
+}
+
+void MultiTabBar::removeTab( int id )
+{
+ m_internal->removeTab( id );
+}
+
+void MultiTabBar::setTab( int id, bool state )
+{
+ MultiTabBarTab * ttab = tab( id );
+ if ( ttab ) {
+ ttab->setState( state );
+ }
+}
+
+bool MultiTabBar::isTabRaised( int id ) const
+{
+ MultiTabBarTab * ttab = tab( id );
+ if ( ttab ) {
+ return ttab->isOn();
+ }
+
+ return false;
+}
+
+
+void MultiTabBar::showActiveTabTexts( bool show )
+{
+ m_internal->showActiveTabTexts( show );
+}
+
+void MultiTabBar::setStyle( MultiTabBarStyle style )
+{
+ m_internal->setStyle( style );
+}
+
+void MultiTabBar::setPosition( MultiTabBarPosition pos )
+{
+ m_position = pos;
+ m_internal->setPosition( pos );
+ for ( uint i = 0;i < m_buttons.count();i++ )
+ m_buttons.at( i ) ->setPosition( pos );
+}
+void MultiTabBar::fontChange( const QFont& /* oldFont */ )
+{
+ for ( uint i = 0;i < tabs() ->count();i++ )
+ tabs() ->at( i ) ->resize();
+ repaint();
+}
+
+QPtrList<MultiTabBarTab> *MultiTabBar::tabs()
+{
+ return m_internal->tabs();
+}
+
+QPtrList<MultiTabBarButton>* MultiTabBar::buttons()
+{
+ return & m_buttons;
+}
+
+}
diff --git a/kftpgrabber/src/widgets/multitabbar.h b/kftpgrabber/src/widgets/multitabbar.h
new file mode 100644
index 0000000..ece61bf
--- /dev/null
+++ b/kftpgrabber/src/widgets/multitabbar.h
@@ -0,0 +1,281 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ * Copyright (C) 2001-2003 by Joseph Wenninger <jowenn@kde.org>
+ * Copyright (C) 2005 by Mark Kretschmann <markey@web.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.
+ */
+
+#ifndef KFTPWIDGETSMULTITABBAR_H
+#define KFTPWIDGETSMULTITABBAR_H
+
+#include <qscrollview.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qlayout.h>
+#include <qstring.h>
+#include <qptrlist.h>
+#include <qpushbutton.h>
+
+class QPixmap;
+class QPainter;
+class QFrame;
+
+namespace KFTPWidgets {
+
+class MultiTabBarPrivate;
+class MultiTabBarTabPrivate;
+class MultiTabBarButtonPrivate;
+class MultiTabBarInternal;
+
+/**
+ * A Widget for horizontal and vertical tabs.
+ * It is possible to add normal buttons to the top/left
+ * The handling if only one tab at a time or multiple tabs
+ * should be raisable is left to the "user".
+ *
+ * @author Joseph Wenninger
+ */
+class MultiTabBar: public QWidget
+{
+Q_OBJECT
+friend class MultiTabBarButton;
+public:
+ enum MultiTabBarMode { Horizontal, Vertical };
+ enum MultiTabBarPosition { Left, Right, Top, Bottom };
+
+ /**
+ * VSNET == Visual Studio .Net like (only show the text of active tabs
+ * KDEV3 == Kdevelop 3 like (always show the text)
+ * KONQSBC == konqy's classic sidebar style (unthemed), this one is disabled
+ * at the moment, but will be renabled soon too
+ * AMAROK == A nice clean style by the amaroK team
+ */
+ enum MultiTabBarStyle { VSNET = 0, KDEV3 = 1, KONQSBC = 2, KDEV3ICON = 3, AMAROK = 4, STYLELAST = 0xffff };
+
+ MultiTabBar(MultiTabBarMode bm, QWidget *parent = 0, const char *name = 0);
+ virtual ~MultiTabBar();
+
+ /**
+ * append a new button to the button area. The button can later on be accessed with button(ID)
+ * eg for connecting signals to it
+ *
+ * @param pic a pixmap for the button
+ * @param id an arbitraty ID value. It will be emitted in the clicked signal for identifying the button
+ * if more than one button is connected to a signals.
+ * @param popup A popup menu which should be displayed if the button is clicked
+ * @param not_used_yet will be used for a popup text in the future
+ */
+ int appendButton(const QPixmap &pic, int id = -1, QPopupMenu* popup = 0, const QString& not_used_yet = QString::null);
+
+ /**
+ * remove a button with the given ID
+ */
+ void removeButton(int id);
+
+ /**
+ * append a new tab to the tab area. It can be accessed lateron with tabb(id);
+ * @param pic a bitmap for the tab
+ * @param id an arbitrary ID which can be used later on to identify the tab
+ * @param text if a mode with text is used it will be the tab text, otherwise a mouse over hint
+ */
+ int appendTab( const QPixmap &pic, int id = -1, const QString& text = QString::null );
+
+ /**
+ * remove a tab with a given ID
+ */
+ void removeTab( int id );
+ /**
+ * set a tab to "raised"
+ * @param id The ID of the tab to manipulate
+ * @param state true == activated/raised, false == not active
+ */
+ void setTab( int id , bool state );
+ /**
+ * return the state of a tab, identified by it's ID
+ */
+ bool isTabRaised( int id ) const;
+ /**
+ * get a pointer to a button within the button area identified by its ID
+ */
+ class MultiTabBarButton *button( int id ) const;
+
+ /**
+ * get a pointer to a tab within the tab area, identiifed by its ID
+ */
+ class MultiTabBarTab *tab( int id ) const;
+ /**
+ * set the real position of the widget.
+ * @param pos if the mode is horizontal, only use top, bottom, if it is vertical use left or right
+ */
+ void setPosition( MultiTabBarPosition pos );
+ /**
+ * set the display style of the tabs
+ */
+ void setStyle( MultiTabBarStyle style );
+ /**
+ * be carefull, don't delete tabs yourself and don't delete the list itself
+ */
+ QPtrList<MultiTabBarTab>* tabs();
+ /**
+ * be carefull, don't delete buttons yourself and don't delete the list itself
+ */
+ QPtrList<MultiTabBarButton>* buttons();
+
+ /**
+ * might vanish, not sure yet
+ */
+ void showActiveTabTexts( bool show = true );
+protected:
+ virtual void fontChange( const QFont& );
+ void updateSeparator();
+private:
+ class MultiTabBarInternal *m_internal;
+ QBoxLayout *m_l;
+ QFrame *m_btnTabSep;
+ QPtrList<MultiTabBarButton> m_buttons;
+ MultiTabBarPosition m_position;
+ MultiTabBarPrivate *d;
+};
+
+/**
+ * This class should never be created except with the appendButton call of MultiTabBar
+ */
+class MultiTabBarButton: public QPushButton
+{
+Q_OBJECT
+public:
+ MultiTabBarButton(MultiTabBarInternal *tb, const QPixmap& pic, const QString&, QPopupMenu *popup,
+ int id, QWidget *parent, MultiTabBar::MultiTabBarPosition pos, MultiTabBar::MultiTabBarStyle style);
+ MultiTabBarButton(MultiTabBarInternal *tb, const QString&, QPopupMenu *popup,
+ int id, QWidget *parent, MultiTabBar::MultiTabBarPosition pos, MultiTabBar::MultiTabBarStyle style);
+ virtual ~MultiTabBarButton();
+
+ int id() const;
+public slots:
+ /**
+ * this is used internaly, but can be used by the user, if (s)he wants to
+ * It the according call of MultiTabBar is invoked though this modifications will be overwritten
+ */
+ void setPosition( MultiTabBar::MultiTabBarPosition );
+ /**
+ * this is used internaly, but can be used by the user, if (s)he wants to
+ * It the according call of MultiTabBar is invoked though this modifications will be overwritten
+ */
+ void setStyle( MultiTabBar::MultiTabBarStyle );
+
+ /**
+ * modify the text of the button
+ */
+ void setText( const QString & );
+
+ QSize sizeHint() const;
+protected:
+ static const int ANIM_INTERVAL = 18;
+ static const int ANIM_MAX = 20;
+
+ MultiTabBarInternal *m_tb;
+
+ MultiTabBar::MultiTabBarPosition m_position;
+ MultiTabBar::MultiTabBarStyle m_style;
+
+ QString m_text;
+ int m_id;
+ bool m_animEnter;
+ int m_animCount;
+ class QTimer *m_animTimer;
+
+ virtual void hideEvent(class QHideEvent*);
+ virtual void showEvent(class QShowEvent*);
+ virtual void enterEvent(class QEvent*);
+ virtual void leaveEvent(class QEvent*);
+private:
+ MultiTabBarButtonPrivate *d;
+signals:
+ /**
+ * this is emitted if the button is clicked
+ * @param id the ID identifying the button
+ */
+ void clicked(int id);
+protected slots:
+ virtual void slotClicked();
+ virtual void slotAnimTimer();
+};
+
+/**
+ * This class should never be created except with the appendTab call of MultiTabBar
+ */
+class MultiTabBarTab: public MultiTabBarButton
+{
+Q_OBJECT
+friend class MultiTabBarInternal;
+public:
+ MultiTabBarTab(MultiTabBarInternal *tb, const QPixmap &pic, const QString&, int id, QWidget *parent,
+ MultiTabBar::MultiTabBarPosition pos, MultiTabBar::MultiTabBarStyle style);
+ virtual ~MultiTabBarTab();
+ /**
+ * set the active state of the tab
+ * @param state true==active false==not active
+ */
+ void setState( bool state );
+ /**
+ * choose if the text should always be displayed
+ * this is only used in classic mode if at all
+ */
+ void showActiveTabText( bool show );
+ void resize() { setSize( neededSize() ); }
+private:
+ bool m_showActiveTabText;
+ int m_expandedSize;
+
+ MultiTabBarTabPrivate *d;
+protected:
+ void setSize( int );
+ int neededSize();
+ void updateState();
+ virtual void drawButton( QPainter * );
+ virtual void drawButtonLabel( QPainter * );
+ void drawButtonStyled( QPainter * );
+ void drawButtonClassic( QPainter * );
+ void drawButtonAmarok( QPainter * );
+ QColor blendColors( const QColor& color1, const QColor& color2, int percent );
+protected slots:
+ virtual void slotClicked();
+ void setTabsPosition( MultiTabBar::MultiTabBarPosition );
+public slots:
+ virtual void setIcon( const QString& );
+ virtual void setIcon( const QPixmap& );
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/multitabbar_p.h b/kftpgrabber/src/widgets/multitabbar_p.h
new file mode 100644
index 0000000..c630f61
--- /dev/null
+++ b/kftpgrabber/src/widgets/multitabbar_p.h
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ * Copyright (C) 2001-2003 by Joseph Wenninger <jowenn@kde.org>
+ *
+ * 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.
+ */
+
+#ifndef KFTPWIDGETSMULTITABBAR_P_H
+#define KFTPWIDGETSMULTITABBAR_P_H
+
+#include <qscrollview.h>
+
+#include "multitabbar.h"
+
+namespace KFTPWidgets {
+
+class MultiTabBarInternal : public QScrollView
+{
+Q_OBJECT
+friend class MultiTabBar;
+public:
+ MultiTabBarInternal(QWidget *parent,MultiTabBar::MultiTabBarMode bm);
+ int appendTab(const QPixmap &,int=-1,const QString& =QString::null);
+ MultiTabBarTab *tab(int) const;
+ void removeTab(int);
+ void setPosition(enum MultiTabBar::MultiTabBarPosition pos);
+ void setStyle(enum MultiTabBar::MultiTabBarStyle style);
+ void showActiveTabTexts(bool show);
+ QPtrList<MultiTabBarTab>* tabs() { return &m_tabs; }
+private:
+ QWidget *box;
+ QBoxLayout *mainLayout;
+ QPtrList<MultiTabBarTab> m_tabs;
+ enum MultiTabBar::MultiTabBarPosition m_position;
+ bool m_showActiveTabTexts;
+ enum MultiTabBar::MultiTabBarStyle m_style;
+ int m_expandedTabSize;
+ int m_lines;
+ MultiTabBar::MultiTabBarMode m_barMode;
+protected:
+ virtual bool eventFilter(QObject *,QEvent*);
+ virtual void drawContents ( QPainter *, int, int, int, int);
+
+ /**
+ * [contentsM|m]ousePressEvent are reimplemented from QScrollView
+ * in order to ignore all mouseEvents on the viewport, so that the
+ * parent can handle them.
+ */
+ virtual void contentsMousePressEvent(QMouseEvent *);
+ virtual void mousePressEvent(QMouseEvent *);
+ virtual void resizeEvent(QResizeEvent *);
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/overlaywidget.cpp b/kftpgrabber/src/widgets/overlaywidget.cpp
new file mode 100644
index 0000000..58ae387
--- /dev/null
+++ b/kftpgrabber/src/widgets/overlaywidget.cpp
@@ -0,0 +1,83 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ * Copyright (C) 2005 Max Howell <max.howell@methyblue.com>
+ *
+ * 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 "overlaywidget.h"
+
+#include <qpoint.h>
+
+namespace KFTPWidgets {
+
+OverlayWidget::OverlayWidget(QWidget *parent, QWidget *anchor)
+ : QFrame(parent->parentWidget()),
+ m_parent(parent),
+ m_anchor(anchor)
+{
+ parent->installEventFilter(this);
+ hide();
+}
+
+void OverlayWidget::reposition()
+{
+ setMaximumSize(parentWidget()->size());
+ adjustSize();
+
+ // P is in the alignWidget's coordinates
+ QPoint p;
+
+ p.setX(m_anchor->width() - width());
+ p.setY(-height());
+
+ // Position in the toplevelWidget's coordinates
+ QPoint pTopLevel = m_anchor->mapTo(topLevelWidget(), p);
+
+ // Position in the widget's parentWidget coordinates
+ QPoint pParent = parentWidget()->mapFrom(topLevelWidget(), pTopLevel);
+
+ if (pParent.x() < 0)
+ pParent.rx() = 0;
+
+ move(pParent);
+}
+
+bool OverlayWidget::event(QEvent *event)
+{
+ if (event->type() == QEvent::ChildInserted)
+ adjustSize();
+
+ return QFrame::event(event);
+}
+
+}
diff --git a/kftpgrabber/src/widgets/overlaywidget.h b/kftpgrabber/src/widgets/overlaywidget.h
new file mode 100644
index 0000000..1140909
--- /dev/null
+++ b/kftpgrabber/src/widgets/overlaywidget.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ * Copyright (C) 2005 Max Howell <max.howell@methyblue.com>
+ *
+ * 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.
+ */
+#ifndef KFTPWIDGETSOVERLAYWIDGET_H
+#define KFTPWIDGETSOVERLAYWIDGET_H
+
+#include <qhbox.h>
+
+namespace KFTPWidgets {
+
+/**
+ * @author Max Howell
+ */
+class OverlayWidget : public QFrame {
+public:
+ OverlayWidget(QWidget *parent, QWidget *anchor);
+ virtual void reposition();
+protected:
+ virtual bool event(QEvent *event);
+private:
+ QWidget *m_parent;
+ QWidget *m_anchor;
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/popupmessage.cpp b/kftpgrabber/src/widgets/popupmessage.cpp
new file mode 100644
index 0000000..62ee3c8
--- /dev/null
+++ b/kftpgrabber/src/widgets/popupmessage.cpp
@@ -0,0 +1,314 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ * Copyright (C) 2005 Max Howell <max.howell@methyblue.com>
+ * Copyright (C) 2005 Seb Ruiz <me@sebruiz.net>
+ *
+ * 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 "popupmessage.h"
+
+#include <kactivelabel.h>
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+
+#include <qfont.h>
+#include <qframe.h>
+#include <qlabel.h>
+#include <qmessagebox.h>
+#include <qpainter.h>
+#include <qtimer.h>
+#include <qtooltip.h>
+
+namespace KFTPWidgets {
+
+PopupMessage::PopupMessage(QWidget *parent, QWidget *anchor, int timeout)
+ : OverlayWidget(parent, anchor),
+ m_anchor(anchor),
+ m_parent(parent),
+ m_maskEffect(Slide),
+ m_dissolveSize(0),
+ m_dissolveDelta(-1),
+ m_offset(0),
+ m_counter(0),
+ m_stage(1),
+ m_timeout(timeout),
+ m_showCounter(true)
+{
+ setFrameStyle(QFrame::Panel | QFrame::Raised);
+ setFrameShape(QFrame::StyledPanel);
+ setWFlags(Qt::WX11BypassWM);
+
+ QPalette p = QToolTip::palette();
+ setPalette(p);
+
+ QHBoxLayout *hbox;
+ QLabel *label;
+ KActiveLabel *alabel;
+
+ m_layout = new QVBoxLayout(this, 9, 6);
+ hbox = new QHBoxLayout(m_layout, 12);
+
+ hbox->addWidget(m_countdownFrame = new QFrame(this, "counterVisual"));
+ m_countdownFrame->setFixedWidth(fontMetrics().width("X"));
+ m_countdownFrame->setFrameStyle(QFrame::Plain | QFrame::Box);
+ m_countdownFrame->setPaletteForegroundColor(paletteBackgroundColor().dark());
+
+ label = new QLabel(this, "image");
+ hbox->add(label);
+
+ alabel = new KActiveLabel(this, "label");
+ alabel->setTextFormat(Qt::RichText);
+ alabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
+ alabel->setPalette(p);
+
+ hbox->add(alabel);
+
+ hbox = new QHBoxLayout(m_layout);
+
+ hbox->addItem(new QSpacerItem(4, 4, QSizePolicy::Expanding, QSizePolicy::Preferred));
+ hbox->add(new KPushButton(KStdGuiItem::close(), this, "closeButton"));
+
+ connect(child("closeButton"), SIGNAL(clicked()), SLOT(close()));
+}
+
+void PopupMessage::addWidget(QWidget *widget)
+{
+ m_layout->add(widget);
+ adjustSize();
+}
+
+void PopupMessage::setShowCloseButton(bool show)
+{
+ static_cast<KPushButton*>(child("closeButton"))->setShown(show);
+ adjustSize();
+}
+
+void PopupMessage::setShowCounter(bool show)
+{
+ m_showCounter = show;
+ static_cast<QFrame*>(child("counterVisual"))->setShown(show);
+ adjustSize();
+}
+
+void PopupMessage::setText(const QString &text)
+{
+ static_cast<KActiveLabel*>(child("label"))->setText(text);
+ adjustSize();
+}
+
+void PopupMessage::setImage(const QString &location)
+{
+ static_cast<QLabel*>(child("image"))->setPixmap(QPixmap(location));
+ adjustSize();
+}
+
+void PopupMessage::setImage(const QPixmap &pix)
+{
+ static_cast<QLabel*>(child("image"))->setPixmap(pix);
+ adjustSize();
+}
+
+void PopupMessage::close()
+{
+ m_stage = 3;
+ killTimer(m_timerId);
+ m_timerId = startTimer(6);
+}
+
+void PopupMessage::display()
+{
+ m_dissolveSize = 24;
+ m_dissolveDelta = -1;
+
+ if (m_maskEffect == Dissolve) {
+ m_mask.resize(width(), height());
+ dissolveMask();
+ m_timerId = startTimer(1000 / 30);
+ } else {
+ m_timerId = startTimer( 6 );
+ }
+
+ show();
+}
+
+void PopupMessage::timerEvent(QTimerEvent*)
+{
+ switch(m_maskEffect) {
+ case Plain: plainMask(); break;
+ case Slide: slideMask(); break;
+ case Dissolve: dissolveMask(); break;
+ }
+}
+
+void PopupMessage::countDown()
+{
+ if (!m_timeout) {
+ killTimer(m_timerId);
+ return;
+ }
+
+ QFrame *&h = m_countdownFrame;
+
+ if (m_counter < h->height() - 3)
+ QPainter(h).fillRect(2, 2, h->width() - 4, m_counter, palette().active().highlight());
+
+ if (!hasMouse())
+ m_counter++;
+
+ if (m_counter > h->height()) {
+ m_stage = 3;
+ killTimer(m_timerId);
+ m_timerId = startTimer(6);
+ } else {
+ killTimer(m_timerId);
+ m_timerId = startTimer(m_timeout / h->height());
+ }
+}
+
+void PopupMessage::dissolveMask()
+{
+ if (m_stage == 1) {
+ repaint(false);
+ QPainter maskPainter(&m_mask);
+
+ m_mask.fill(Qt::black);
+
+ maskPainter.setBrush(Qt::white);
+ maskPainter.setPen(Qt::white);
+ maskPainter.drawRect(m_mask.rect());
+
+ m_dissolveSize += m_dissolveDelta;
+
+ if (m_dissolveSize > 0) {
+ maskPainter.setRasterOp(Qt::EraseROP);
+
+ int x, y, s;
+ const int size = 16;
+
+ for (y = 0; y < height() + size; y += size) {
+ x = width();
+ s = m_dissolveSize * x / 128;
+
+ for (; x > size; x -= size, s -= 2) {
+ if (s < 0)
+ break;
+
+ maskPainter.drawEllipse(x - s / 2, y - s / 2, s, s);
+ }
+ }
+ } else if (m_dissolveSize < 0) {
+ m_dissolveDelta = 1;
+ killTimer(m_timerId);
+
+ if (m_timeout) {
+ m_timerId = startTimer(40);
+ m_stage = 2;
+ }
+ }
+
+ setMask(m_mask);
+ } else if (m_stage == 2) {
+ countDown();
+ } else {
+ deleteLater();
+ }
+}
+
+void PopupMessage::plainMask()
+{
+ switch (m_stage) {
+ case 1: {
+ // Raise
+ killTimer(m_timerId);
+
+ if (m_timeout) {
+ m_timerId = startTimer(40);
+ m_stage = 2;
+ }
+
+ break;
+ }
+
+ case 2: {
+ // Counter
+ countDown();
+ break;
+ }
+
+ case 3: {
+ // Lower/Remove
+ deleteLater();
+ break;
+ }
+ }
+}
+
+void PopupMessage::slideMask()
+{
+ switch (m_stage) {
+ case 1: {
+ // Raise
+ move(0, m_parent->y() - m_offset);
+ m_offset++;
+
+ if (m_offset > height()) {
+ killTimer(m_timerId);
+
+ if (m_timeout) {
+ m_timerId = startTimer(40);
+ m_stage = 2;
+ }
+ }
+ break;
+ }
+
+ case 2: {
+ // Fill in pause timer bar
+ countDown();
+ break;
+ }
+
+ case 3: {
+ // Lower
+ m_offset--;
+ move(0, m_parent->y() - m_offset);
+
+ if (m_offset < 0)
+ deleteLater();
+ }
+ }
+}
+
+}
+
+#include "popupmessage.moc"
diff --git a/kftpgrabber/src/widgets/popupmessage.h b/kftpgrabber/src/widgets/popupmessage.h
new file mode 100644
index 0000000..0550d41
--- /dev/null
+++ b/kftpgrabber/src/widgets/popupmessage.h
@@ -0,0 +1,113 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ * Copyright (C) 2005 Max Howell <max.howell@methyblue.com>
+ * Copyright (C) 2005 Seb Ruiz <me@sebruiz.net>
+ *
+ * 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.
+ */
+#ifndef KFTPWIDGETSPOPUPMESSAGE_H
+#define KFTPWIDGETSPOPUPMESSAGE_H
+
+#include "overlaywidget.h"
+
+#include <qbitmap.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+
+namespace KFTPWidgets {
+
+/**
+ * Widget that animates itself into a position relative to an anchor widget.
+ */
+class PopupMessage : public OverlayWidget {
+Q_OBJECT
+public:
+ /**
+ * Possible animation effects.
+ */
+ enum MaskEffect {
+ Plain,
+ Slide,
+ Dissolve
+ };
+
+ /**
+ * Class constructor.
+ *
+ * @param parent Parent widget
+ * @param anchor Which widget to tie the popup widget to
+ * @param timeout How long to wait before auto closing
+ */
+ PopupMessage(QWidget *parent, QWidget *anchor, int timeout = 5000);
+
+ void addWidget(QWidget *widget);
+ void setShowCloseButton(bool show);
+ void setShowCounter(bool show);
+ void setImage(const QString &location);
+ void setImage(const QPixmap &pixmap);
+ void setMaskEffect(MaskEffect type) { m_maskEffect = type; }
+ void setText(const QString &text);
+ void setTimeout(int timeout) { m_timeout = timeout; }
+public slots:
+ void close();
+ void display();
+protected:
+ void timerEvent(QTimerEvent *event);
+ void countDown();
+
+ void dissolveMask();
+ void plainMask();
+ void slideMask();
+private:
+ QVBoxLayout *m_layout;
+ QFrame *m_countdownFrame;
+ QWidget *m_anchor;
+ QWidget *m_parent;
+ QBitmap m_mask;
+ MaskEffect m_maskEffect;
+
+ int m_dissolveSize;
+ int m_dissolveDelta;
+
+ int m_offset;
+ int m_counter;
+ int m_stage;
+ int m_timeout;
+ int m_timerId;
+
+ bool m_showCounter;
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/queueview/Makefile.am b/kftpgrabber/src/widgets/queueview/Makefile.am
new file mode 100644
index 0000000..5ba11d9
--- /dev/null
+++ b/kftpgrabber/src/widgets/queueview/Makefile.am
@@ -0,0 +1,13 @@
+INCLUDES = -I$(srcdir)/../.. \
+ -I$(srcdir)/../../engine \
+ -I$(srcdir)/../../misc \
+ -I$(srcdir)/../../ui -I../../ui\
+ -I$(srcdir)/.. \
+ -I$(srcdir)/../browser \
+ $(all_includes)
+
+METASOURCES = AUTO
+noinst_LIBRARIES = libqueueviewwidget.a
+libqueueviewwidget_a_SOURCES = queueeditor.cpp queueview.cpp threadview.cpp
+
+noinst_HEADERS = queueeditor.h queueview.h threadview.h
diff --git a/kftpgrabber/src/widgets/queueview/queueeditor.cpp b/kftpgrabber/src/widgets/queueview/queueeditor.cpp
new file mode 100644
index 0000000..c565165
--- /dev/null
+++ b/kftpgrabber/src/widgets/queueview/queueeditor.cpp
@@ -0,0 +1,323 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "queueeditor.h"
+#include "kftpserverlineedit.h"
+#include "kftpbookmarks.h"
+#include "kftpqueueeditorlayout.h"
+
+#include <klineedit.h>
+#include <kpassdlg.h>
+#include <kcombobox.h>
+#include <klocale.h>
+
+#include <qspinbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qtabwidget.h>
+
+#define REMOTE_PROTOCOL m_transfer->getSourceUrl().isLocalFile() ? m_transfer->getDestUrl().protocol() : m_transfer->getSourceUrl().protocol()
+
+namespace KFTPWidgets {
+
+QueueEditor::QueueEditor(QWidget *parent, const char *name)
+: KDialogBase(parent, name, true, "Edit queue", KDialogBase::Ok | KDialogBase::Cancel,
+ KDialogBase::Ok, true)
+{
+ m_layout = new KFTPQueueEditorLayout(this);
+ setMainWidget(m_layout);
+
+ connect(m_layout->srcPath, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged()));
+ connect(m_layout->dstPath, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged()));
+
+ connect(m_layout->srcHost, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged()));
+ connect(m_layout->srcUser, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged()));
+ connect(m_layout->srcPass, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged()));
+
+ connect(m_layout->dstHost, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged()));
+ connect(m_layout->dstUser, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged()));
+ connect(m_layout->dstPass, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged()));
+
+ connect(m_layout->srcName, SIGNAL(siteChanged(KFTPBookmarks::Site*)), this, SLOT(slotSourceSiteChanged(KFTPBookmarks::Site*)));
+ connect(m_layout->dstName, SIGNAL(siteChanged(KFTPBookmarks::Site*)), this, SLOT(slotDestSiteChanged(KFTPBookmarks::Site*)));
+
+ connect(m_layout->transferType, SIGNAL(activated(int)), this, SLOT(slotTransferModeChanged(int)));
+
+ setMaximumHeight(250);
+ setInitialSize(QSize(500, 250));
+
+ enableButtonOK(false);
+}
+
+void QueueEditor::resetTabs()
+{
+ m_layout->serverTab->setTabEnabled(m_layout->tab, false);
+ m_layout->serverTab->setTabEnabled(m_layout->tab_2, false);
+}
+
+void QueueEditor::resetServerData()
+{
+ // Source
+ m_layout->srcName->clear();
+ m_layout->srcHost->setText("");
+ m_layout->srcPort->setValue(21);
+ m_layout->srcUser->setText("");
+ m_layout->srcPass->erase();
+
+ // Destination
+ m_layout->dstName->clear();
+ m_layout->dstHost->setText("");
+ m_layout->dstPort->setValue(21);
+ m_layout->dstUser->setText("");
+ m_layout->dstPass->erase();
+}
+
+void QueueEditor::slotTransferModeChanged(int index)
+{
+ if (m_lastTransferType == index)
+ return;
+ else
+ m_lastTransferType = (KFTPQueue::TransferType) index;
+
+ resetTabs();
+ resetServerData();
+
+ switch (index) {
+ case 0: {
+ // Download - source: remote dest: local
+ m_layout->serverTab->setTabEnabled(m_layout->tab, true);
+ m_layout->serverTab->showPage(m_layout->tab);
+ break;
+ }
+ case 1: {
+ // Upload - source: local dest: remote
+ m_layout->serverTab->setTabEnabled(m_layout->tab_2, true);
+ m_layout->serverTab->showPage(m_layout->tab_2);
+ break;
+ }
+ case 2: {
+ // FXP - source: remote dest: remote
+ m_layout->serverTab->setTabEnabled(m_layout->tab, true);
+ m_layout->serverTab->setTabEnabled(m_layout->tab_2, true);
+ m_layout->serverTab->showPage(m_layout->tab);
+ break;
+ }
+ }
+
+ slotTextChanged();
+}
+
+bool QueueEditor::sourceIsValid()
+{
+ if (m_lastTransferType == 1) return true;
+
+ if (m_layout->srcHost->text().stripWhiteSpace().isEmpty() || m_layout->srcUser->text().stripWhiteSpace().isEmpty())
+ return false;
+ else
+ return true;
+}
+
+bool QueueEditor::destIsValid()
+{
+ if (m_lastTransferType == 0) return true;
+
+ if (m_layout->dstHost->text().stripWhiteSpace().isEmpty() || m_layout->dstUser->text().stripWhiteSpace().isEmpty())
+ return false;
+ else
+ return true;
+}
+
+void QueueEditor::slotTextChanged()
+{
+ if (m_layout->srcPath->text().stripWhiteSpace().isEmpty() || m_layout->dstPath->text().stripWhiteSpace().isEmpty() ||
+ m_layout->srcPath->text().left(1) != "/" || m_layout->dstPath->text().left(1) != "/" ||
+ !sourceIsValid() || !destIsValid() )
+ enableButtonOK(false);
+ else
+ enableButtonOK(true);
+}
+
+void QueueEditor::setData(KFTPQueue::Transfer *transfer)
+{
+ KURL sUrl, dUrl;
+
+ m_layout->srcPath->setText(transfer->getSourceUrl().path());
+ m_layout->dstPath->setText(transfer->getDestUrl().path());
+
+ // Source
+ sUrl = transfer->getSourceUrl();
+
+ if (!sUrl.isLocalFile()) {
+ m_layout->srcName->setCurrentSite(KFTPBookmarks::Manager::self()->findSite(sUrl));
+ m_layout->srcHost->setText(sUrl.host());
+ m_layout->srcPort->setValue(sUrl.port());
+ m_layout->srcUser->setText(sUrl.user());
+
+ m_layout->srcPass->erase();
+ m_layout->srcPass->insert(sUrl.pass());
+ } else {
+ m_layout->serverTab->setTabEnabled(m_layout->tab, false);
+ }
+
+ // Destination
+ dUrl = transfer->getDestUrl();
+
+ if (!dUrl.isLocalFile()) {
+ m_layout->dstName->setCurrentSite(KFTPBookmarks::Manager::self()->findSite(dUrl));
+ m_layout->dstHost->setText(dUrl.host());
+ m_layout->dstPort->setValue(dUrl.port());
+ m_layout->dstUser->setText(dUrl.user());
+
+ m_layout->dstPass->erase();
+ m_layout->dstPass->insert(dUrl.pass());
+ } else {
+ m_layout->serverTab->setTabEnabled(m_layout->tab_2, false);
+ }
+
+ // Transfer type
+ m_lastTransferType = transfer->getTransferType();
+ m_layout->transferType->setCurrentItem(m_lastTransferType);
+
+ m_transfer = transfer;
+}
+
+void QueueEditor::saveData()
+{
+ KURL sUrl, dUrl;
+
+ if (m_lastTransferType != 1) {
+ sUrl.setProtocol(REMOTE_PROTOCOL);
+ sUrl.setHost(m_layout->srcHost->text());
+ sUrl.setPort(m_layout->srcPort->value());
+ sUrl.setUser(m_layout->srcUser->text());
+ sUrl.setPass(m_layout->srcPass->password());
+
+ if (m_transfer->getSourceUrl().pass().isEmpty() && sUrl.pass().isEmpty())
+ sUrl.setPass(QString::null);
+ } else {
+ sUrl.setProtocol("file");
+ }
+
+ sUrl.setPath(m_layout->srcPath->text());
+
+ if (m_lastTransferType != 0) {
+ dUrl.setProtocol(REMOTE_PROTOCOL);
+ dUrl.setHost(m_layout->dstHost->text());
+ dUrl.setPort(m_layout->dstPort->value());
+ dUrl.setUser(m_layout->dstUser->text());
+ dUrl.setPass(m_layout->dstPass->password());
+
+ if (m_transfer->getDestUrl().pass().isEmpty() && dUrl.pass().isEmpty())
+ dUrl.setPass(QString::null);
+ } else {
+ dUrl.setProtocol("file");
+ }
+
+ dUrl.setPath(m_layout->dstPath->text());
+
+ m_transfer->setSourceUrl(sUrl);
+ m_transfer->setDestUrl(dUrl);
+ m_transfer->setTransferType(m_lastTransferType);
+
+ // If the transfer is a directory, we have to update all child transfers
+ // as well.
+ if (m_transfer->isDir())
+ recursiveSaveData(static_cast<KFTPQueue::TransferDir*>(m_transfer), sUrl, dUrl);
+}
+
+void QueueEditor::recursiveSaveData(KFTPQueue::TransferDir *parent, const KURL &srcUrl, const KURL &dstUrl)
+{
+ KFTPQueue::QueueObject *o;
+ QPtrList<KFTPQueue::QueueObject> children = parent->getChildrenList();
+
+ KURL sUrl, dUrl;
+
+ for (o = children.first(); o; o = children.next()) {
+ KFTPQueue::Transfer *i = static_cast<KFTPQueue::Transfer*>(o);
+
+ // Modify the urls
+ sUrl = srcUrl;
+ dUrl = dstUrl;
+
+ sUrl.addPath(i->getSourceUrl().fileName());
+ dUrl.addPath(i->getDestUrl().fileName());
+
+ // Set the urls
+ i->setSourceUrl(sUrl);
+ i->setDestUrl(dUrl);
+ i->setTransferType(m_lastTransferType);
+ i->emitUpdate();
+
+ if (i->isDir())
+ recursiveSaveData(static_cast<KFTPQueue::TransferDir*>(i), sUrl, dUrl);
+ }
+}
+
+void QueueEditor::slotSourceSiteChanged(KFTPBookmarks::Site *site)
+{
+ if (site) {
+ m_layout->srcHost->setText(site->getProperty("host"));
+ m_layout->srcPort->setValue(site->getIntProperty("port"));
+ m_layout->srcUser->setText(site->getProperty("username"));
+ m_layout->srcPass->erase();
+ m_layout->srcPass->insert(site->getProperty("password"));
+ } else {
+ m_layout->srcHost->clear();
+ m_layout->srcPort->setValue(21);
+ m_layout->srcUser->clear();
+ m_layout->srcPass->erase();
+ }
+}
+
+void QueueEditor::slotDestSiteChanged(KFTPBookmarks::Site *site)
+{
+ if (site) {
+ m_layout->dstHost->setText(site->getProperty("host"));
+ m_layout->dstPort->setValue(site->getIntProperty("port"));
+ m_layout->dstUser->setText(site->getProperty("username"));
+ m_layout->dstPass->erase();
+ m_layout->dstPass->insert(site->getProperty("password"));
+ } else {
+ m_layout->dstHost->clear();
+ m_layout->dstPort->setValue(21);
+ m_layout->dstUser->clear();
+ m_layout->dstPass->erase();
+ }
+}
+
+}
+
+#include "queueeditor.moc"
+
diff --git a/kftpgrabber/src/widgets/queueview/queueeditor.h b/kftpgrabber/src/widgets/queueview/queueeditor.h
new file mode 100644
index 0000000..09027d6
--- /dev/null
+++ b/kftpgrabber/src/widgets/queueview/queueeditor.h
@@ -0,0 +1,82 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPQUEUEEDITOR_H
+#define KFTPQUEUEEDITOR_H
+
+#include "kftpqueue.h"
+#include "kftpbookmarks.h"
+
+#include <kdialogbase.h>
+#include <qdom.h>
+
+class KFTPQueueEditorLayout;
+
+namespace KFTPWidgets {
+
+/**
+@author Jernej Kos
+*/
+class QueueEditor : public KDialogBase
+{
+Q_OBJECT
+public:
+ QueueEditor(QWidget *parent = 0, const char *name = 0);
+
+ void setData(KFTPQueue::Transfer *transfer);
+ void saveData();
+private:
+ KFTPQueueEditorLayout *m_layout;
+ KFTPQueue::Transfer *m_transfer;
+ KFTPQueue::TransferType m_lastTransferType;
+
+ void resetTabs();
+ void resetServerData();
+
+ bool sourceIsValid();
+ bool destIsValid();
+
+ void recursiveSaveData(KFTPQueue::TransferDir *parent, const KURL &srcUrl, const KURL &dstUrl);
+private slots:
+ void slotTextChanged();
+ void slotTransferModeChanged(int index);
+
+ void slotSourceSiteChanged(KFTPBookmarks::Site *site);
+ void slotDestSiteChanged(KFTPBookmarks::Site *site);
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/queueview/queueview.cpp b/kftpgrabber/src/widgets/queueview/queueview.cpp
new file mode 100644
index 0000000..4fc8e5f
--- /dev/null
+++ b/kftpgrabber/src/widgets/queueview/queueview.cpp
@@ -0,0 +1,888 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ * Copyright (C) 2005 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 "misc.h"
+
+#include "listview.h"
+#include "queueview.h"
+#include "kftpqueue.h"
+#include "kftpapi.h"
+#include "queueeditor.h"
+#include "widgets/searchdialog.h"
+#include "misc/config.h"
+
+#include <kapplication.h>
+#include <kfiledialog.h>
+#include <kiconloader.h>
+#include <kio/job.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kmimetype.h>
+#include <kpopupmenu.h>
+#include <klistviewsearchline.h>
+#include <kdebug.h>
+
+#include <qspinbox.h>
+#include <qtooltip.h>
+
+using namespace KFTPGrabberBase;
+using namespace KFTPCore;
+
+namespace KFTPWidgets {
+
+QueueViewItem::QueueViewItem(QueueView *view, KFTPQueue::QueueObject *object, QListView *parent)
+ : QListViewItem(parent),
+ m_lastChild(0),
+ m_queueObject(object),
+ m_queueView(view),
+ m_queueId(object->getId())
+{
+ init();
+}
+
+QueueViewItem::QueueViewItem(QueueView *view, KFTPQueue::QueueObject *object, QListViewItem *parent)
+ : QListViewItem(parent, static_cast<QueueViewItem*>(parent)->lastChild()),
+ m_lastChild(0),
+ m_queueObject(object),
+ m_queueView(view),
+ m_queueId(object->getId())
+{
+ init();
+}
+
+QueueViewItem::~QueueViewItem()
+{
+ m_queueView->m_queuedItems.remove(m_queueId);
+}
+
+void QueueViewItem::insertItem(QListViewItem *newChild)
+{
+ QListViewItem::insertItem(newChild);
+ m_lastChild = newChild;
+}
+
+void QueueViewItem::takeItem(QListViewItem *item)
+{
+ if (item == m_lastChild) {
+ QListViewItem *above = item->itemAbove();
+
+ if (above->parent() == m_lastChild->parent())
+ m_lastChild = above;
+ else
+ m_lastChild = 0;
+ }
+
+ QListViewItem::takeItem(item);
+}
+
+void QueueViewItem::moveUp()
+{
+ QListViewItem *above = itemAbove();
+
+ if (above && above->parent() == QListViewItem::parent()) {
+ QListViewItem *previous = above->itemAbove();
+
+ if (previous && previous->parent() == QListViewItem::parent()) {
+ QueueViewItem *parent = static_cast<QueueViewItem*>(QListViewItem::parent());
+ moveItem(previous);
+
+ if (parent && this == parent->lastChild())
+ parent->m_lastChild = above;
+ } else {
+ moveToTop();
+ }
+ }
+}
+
+void QueueViewItem::moveDown()
+{
+ QueueViewItem *parent = static_cast<QueueViewItem*>(QListViewItem::parent());
+ QueueViewItem *next = static_cast<QueueViewItem*>(nextSibling());
+
+ if (next) {
+ moveItem(next);
+
+ if (parent && parent->lastChild() == next)
+ parent->m_lastChild = this;
+ }
+}
+
+void QueueViewItem::moveToTop()
+{
+ QueueViewItem *parent = static_cast<QueueViewItem*>(QListViewItem::parent());
+
+ // Just reinsert the item
+ if (parent) {
+ if (this == parent->lastChild())
+ parent->m_lastChild = itemAbove();
+
+ parent->QListViewItem::takeItem(this);
+ parent->QListViewItem::insertItem(this);
+ } else {
+ ListView *view = m_queueView->m_queue;
+ view->QListView::takeItem(this);
+ view->QListView::insertItem(this);
+ }
+}
+
+void QueueViewItem::moveToBottom()
+{
+ QueueViewItem *parent = static_cast<QueueViewItem*>(QListViewItem::parent());
+
+ // Just reinsert the item
+ if (parent) {
+ QListViewItem *last = parent->lastChild();
+
+ parent->takeItem(this);
+ parent->insertItem(this);
+ moveItem(last);
+ } else {
+ ListView *view = m_queueView->m_queue;
+ view->takeItem(this);
+ view->insertItem(this);
+ }
+}
+
+void QueueViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment)
+{
+ QColorGroup _cg(cg);
+ QColor c = _cg.text();
+
+ QColor n_color;
+
+ if (m_queueObject && m_queueObject->isTransfer()) {
+ switch (m_queueObject->getStatus()) {
+ case KFTPQueue::Transfer::Running: n_color.setRgb(255, 0, 0); break;
+ case KFTPQueue::Transfer::Connecting: n_color.setRgb(0, 0, 255); break;
+ case KFTPQueue::Transfer::Waiting: n_color.setRgb(0, 0, 255); break;
+ case KFTPQueue::Transfer::Locked: n_color.setRgb(0, 150, 0); break;
+ default: break;
+ }
+ }
+
+ if (n_color.isValid())
+ _cg.setColor(QColorGroup::Text, n_color);
+
+ QListViewItem::paintCell(p, _cg, column, width, alignment);
+ _cg.setColor(QColorGroup::Text, c);
+}
+
+void QueueViewItem::init()
+{
+ if (m_queueObject->isTransfer()) {
+ KFTPQueue::Transfer *transfer = static_cast<KFTPQueue::Transfer*>(getObject());
+
+ setText(0, transfer->getSourceUrl().fileName());
+ setText(1, KIO::convertSize(transfer->getActualSize()));
+ setText(2, transfer->getSourceUrl().pathOrURL());
+ setText(3, transfer->getDestUrl().pathOrURL());
+
+ // Icon
+ QString iconText;
+ if (transfer->isDir()) {
+ iconText = "folder";
+ } else {
+ KMimeType::Ptr theType = KMimeType::findByURL("/" + transfer->getSourceUrl().path(), 0, false, true);
+ iconText = theType->icon(QString::null, false);
+ }
+
+ setPixmap(0, loadSmallPixmap(iconText));
+ } else if (m_queueObject->getType() == KFTPQueue::QueueObject::Site) {
+ KFTPQueue::Site *site = static_cast<KFTPQueue::Site*>(getObject());
+
+ setText(0, QString("%1:%2").arg(site->getUrl().host()).arg(site->getUrl().port()));
+ setText(1, KIO::convertSize(site->getActualSize()));
+
+ // Set the pixmap
+ setPixmap(0, loadSmallPixmap("server"));
+ }
+}
+
+void QueueViewItem::refresh()
+{
+ if (!m_queueObject)
+ return;
+
+ if (m_queueObject->isTransfer()) {
+ KFTPQueue::Transfer *transfer = static_cast<KFTPQueue::Transfer*>(getObject());
+
+ // Speed
+ bool noSpeed = transfer->getStatus() == KFTPQueue::Transfer::Waiting || transfer->getStatus() == KFTPQueue::Transfer::Connecting;
+ QString speed;
+ if ((!transfer->isDir() || !isOpen()) && transfer->isRunning() && !noSpeed) {
+ speed.sprintf( "%lld B/s", (transfer->getSpeed()) );
+
+ if (transfer->getSpeed() > 1024)
+ speed.sprintf( "%lld KB/s", (transfer->getSpeed() / 1024) );
+
+ if (transfer->getSpeed() > 1024*1024)
+ speed.sprintf("%lld MB/s", (transfer->getSpeed() / 1024) / 1024);
+
+ if (transfer->getSpeed() == 0 && transfer->getTransferType() != KFTPQueue::FXP)
+ speed = i18n("stalled");
+
+ if (transfer->getSpeed() == 0 && transfer->getTransferType() == KFTPQueue::FXP)
+ speed = i18n("running");
+ }
+
+ // ETA
+ QString eta;
+
+ if (transfer->isRunning() && transfer->getSpeed() > 0) {
+ eta = KIO::convertSeconds(KIO::calculateRemainingSeconds(transfer->getSize(),
+ transfer->getCompleted(),
+ transfer->getSpeed()));
+ } else {
+ eta = QString::null;
+ }
+
+ // Set the columns
+ setText(0, transfer->getSourceUrl().fileName());
+ setText(1, KIO::convertSize(transfer->getActualSize()));
+ setText(2, transfer->getSourceUrl().pathOrURL());
+ setText(3, transfer->getDestUrl().pathOrURL());
+ setText(5, speed);
+ setText(6, eta);
+
+ // Don't show the file:// for local src/dest
+ if (transfer->getSourceUrl().isLocalFile()) {
+ setText(2, transfer->getSourceUrl().path());
+ } else if (transfer->getDestUrl().isLocalFile()) {
+ setText(3, transfer->getDestUrl().path());
+ }
+
+ // Progress
+ int progress;
+ int r_progress;
+
+ if (transfer->getSize() == 0)
+ progress = 0;
+ else
+ progress = transfer->getCompleted()*100/transfer->getSize();
+
+ if (transfer->getResumed() == 0)
+ r_progress = 0;
+ else
+ r_progress = transfer->getResumed()*100/transfer->getSize();
+
+ if (transfer->getStatus() == KFTPQueue::Transfer::Waiting) {
+ // Transfer is waiting for a free connection
+ setText(4, i18n("Waiting for connection..."));
+ setPixmap(4, NULL);
+ } else if (transfer->getStatus() == KFTPQueue::Transfer::Connecting) {
+ // Transfer is not yet connected,
+ setText(4, i18n("Connecting..."));
+ setPixmap(4, NULL);
+ } else if (progress > 0) {
+ setPixmap(4, createProgressPixmap(progress, r_progress));
+
+ QString progressText;
+ progressText.sprintf("%d %%", progress);
+ setText(4, progressText);
+ } else {
+ setPixmap(4, NULL);
+ setText(4, QString::null);
+ }
+
+ // Icon
+ QString iconText;
+ if (transfer->isDir()) {
+ iconText = "folder";
+ } else {
+ KMimeType::Ptr theType = KMimeType::findByURL("/" + transfer->getSourceUrl().path(), 0, false, true);
+ iconText = theType->icon(QString::null, false);
+ }
+
+ setPixmap(0, loadSmallPixmap(iconText));
+ } else if (m_queueObject->getType() == KFTPQueue::QueueObject::Site) {
+ KFTPQueue::Site *site = static_cast<KFTPQueue::Site*>(getObject());
+
+ // Speed
+ QString speed;
+ speed.sprintf( "%lld B/s", (site->getSpeed()) );
+
+ if (site->getSpeed() > 1024)
+ speed.sprintf( "%lld KB/s", (site->getSpeed() / 1024) );
+
+ if (site->getSpeed() > 1024*1024)
+ speed.sprintf("%lld MB/s", (site->getSpeed() / 1024) / 1024);
+
+ if (site->getSpeed() == 0)
+ speed = QString::null;
+
+ // ETA
+ QString eta;
+
+ if (site->isRunning() && site->getSpeed() > 0) {
+ eta = KIO::convertSeconds(KIO::calculateRemainingSeconds(site->getSize(),
+ site->getCompleted(),
+ site->getSpeed()));
+ } else {
+ eta = "";
+ }
+
+ // Progress
+ if (site->isRunning()) {
+ int progress = 0;
+
+ if (site->getSize() > 0)
+ progress = site->getCompleted()*100/site->getSize();
+
+ setPixmap(4, createProgressPixmap(progress, 0));
+
+ QString progressText;
+ progressText.sprintf("%d %%", progress);
+ setText(4, progressText);
+ } else {
+ setPixmap(4, NULL);
+ setText(4, QString::null);
+ }
+
+ // Set the columns
+ setText(0, QString("%1:%2").arg(site->getUrl().host()).arg(site->getUrl().port()));
+ setText(1, KIO::convertSize(site->getActualSize()));
+ setText(5, speed);
+ setText(6, eta);
+
+ // Set the pixmap
+ setPixmap(0, loadSmallPixmap("server"));
+ }
+}
+
+QueueListView::QueueListView(QWidget *parent)
+ : ListView(parent)
+{
+}
+
+void QueueListView::insertItem(QListViewItem *item)
+{
+ QListViewItem *last = lastChild();
+ QListView::insertItem(item);
+
+ if (last)
+ item->moveItem(last);
+}
+
+QueueView::QueueView(QWidget *parent, const char *name)
+ : QWidget(parent, name)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+
+ m_toolBar = new KToolBar(this, "queueToolBar");
+ m_toolBar->setIconSize(16);
+ layout->addWidget(m_toolBar);
+
+ m_searchToolBar = new KToolBar(this, "searchToolBar");
+ m_searchToolBar->setEnableContextMenu(false);
+ m_searchToolBar->setMovingEnabled(false);
+ m_searchToolBar->setFullSize(true);
+
+ // Create the erase button
+ m_searchToolBar->insertButton(QApplication::reverseLayout() ? "clear_left" :"locationbar_erase", 0, SIGNAL(clicked()), this, SLOT(slotSearchEraseClicked()), true);
+
+ // Create the labels
+ QLabel *searchLabel = new QLabel(i18n("Filter: "), m_searchToolBar);
+ m_searchToolBar->insertWidget(1, 35, searchLabel);
+
+ // Create the list view
+ m_queue = new QueueListView(this);
+
+ // Create the search field
+ m_searchField = new KListViewSearchLine(m_searchToolBar, m_queue);
+
+ // Do some more stuff
+ m_searchToolBar->setItemAutoSized(1, true);
+ m_searchToolBar->setStretchableWidget(m_searchField);
+ m_searchToolBar->updateRects(true);
+ m_searchToolBar->hide();
+
+ layout->addWidget(m_searchToolBar);
+
+ // Create the columns
+ m_queue->addColumn(i18n("Name"), 150);
+ m_queue->addColumn(i18n("Size"), 75);
+ m_queue->addColumn(i18n("Source"), 250);
+ m_queue->addColumn(i18n("Destination"), 250);
+ m_queue->addColumn(i18n("Progress"), 140);
+ m_queue->addColumn(i18n("Speed"), 70);
+ m_queue->addColumn(i18n("ETA"), 80);
+
+ // Text when there is nothing queued
+ m_queue->setEmptyListText(i18n("You do not have any files in the queue."));
+
+ // Multi-select
+ m_queue->setSelectionModeExt(KListView::FileManager);
+ m_queue->setAllColumnsShowFocus(true);
+ m_queue->setRootIsDecorated(true);
+ m_queue->QListView::setSorting(-1);
+ m_queue->QListView::setSortColumn(-1);
+
+ layout->addWidget(m_queue);
+
+ // The signals
+ connect(m_queue, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)), this,
+ SLOT(contextMenuRequested(KListView*, QListViewItem*, const QPoint&)));
+ connect(m_queue, SIGNAL(selectionChanged()), this, SLOT(updateActions()));
+
+ // Let us be up-to-date
+ connect(KFTPQueue::Manager::self(), SIGNAL(transferRemoved(long)), this, SLOT(slotObjectRemoved(long)));
+ connect(KFTPQueue::Manager::self(), SIGNAL(siteRemoved(long)), this, SLOT(slotObjectRemoved(long)));
+ connect(KFTPQueue::Manager::self(), SIGNAL(newTransfer(KFTPQueue::Transfer*)), this, SLOT(slotTransferAdded(KFTPQueue::Transfer*)));
+ connect(KFTPQueue::Manager::self(), SIGNAL(newSite(KFTPQueue::Site*)), this, SLOT(slotSiteAdded(KFTPQueue::Site*)));
+ connect(KFTPQueue::Manager::self(), SIGNAL(queueUpdate()), this, SLOT(updateActions()));
+
+ // Load the listview layout
+ loadLayout();
+
+ // Create the context menu actions
+ initActions();
+ initToolBar();
+ updateActions();
+
+ setMinimumHeight(150);
+}
+
+void QueueView::saveLayout()
+{
+ m_queue->saveLayout(kapp->config(), "queueViewLayout");
+}
+
+void QueueView::loadLayout()
+{
+ m_queue->restoreLayout(kapp->config(), "queueViewLayout");
+}
+
+void QueueView::initToolBar()
+{
+ // Plug all actions
+ m_loadAction->plug(m_toolBar);
+ m_saveAction->plug(m_toolBar);
+ m_toolBar->insertSeparator();
+ m_startAction->plug(m_toolBar);
+ m_pauseAction->plug(m_toolBar);
+ m_stopAction->plug(m_toolBar);
+ m_toolBar->insertSeparator();
+ m_addAction->plug(m_toolBar);
+ m_removeAction->plug(m_toolBar);
+ m_searchAction->plug(m_toolBar);
+ m_toolBar->insertSeparator();
+ m_filterAction->plug(m_toolBar);
+
+ // Create speed control widgets
+ m_toolBar->insertSeparator();
+
+ QSpinBox *downloadSpeed = new QSpinBox(0, 10240, 1, m_toolBar);
+ QToolTip::add(downloadSpeed, i18n("Limit download transfer speed"));
+ m_toolBar->insertWidget(1, 35, new QLabel(i18n("Down: "), m_toolBar));
+ m_toolBar->insertWidget(2, 35, downloadSpeed);
+ downloadSpeed->setValue(Config::downloadSpeedLimit());
+ connect(downloadSpeed, SIGNAL(valueChanged(int)), this, SLOT(slotDownloadLimitChanged(int)));
+
+ m_toolBar->insertSeparator();
+
+ QSpinBox *uploadSpeed = new QSpinBox(0, 10240, 1, m_toolBar);
+ QToolTip::add(uploadSpeed, i18n("Limit upload transfer speed"));
+ m_toolBar->insertWidget(3, 35, new QLabel(i18n("Up: "), m_toolBar));
+ m_toolBar->insertWidget(4, 35, uploadSpeed);
+ uploadSpeed->setValue(Config::uploadSpeedLimit());
+ connect(uploadSpeed, SIGNAL(valueChanged(int)), this, SLOT(slotUploadLimitChanged(int)));
+
+ // Create thread count control widget
+ m_toolBar->insertSeparator();
+
+ QSpinBox *threadCount = new QSpinBox(1, 10, 1, m_toolBar);
+ QToolTip::add(threadCount, i18n("Per-session transfer thread count"));
+ m_toolBar->insertWidget(5, 35, new QLabel(i18n("Threads: "), m_toolBar));
+ m_toolBar->insertWidget(6, 35, threadCount);
+ threadCount->setValue(Config::threadCount());
+ connect(threadCount, SIGNAL(valueChanged(int)), this, SLOT(slotThreadCountChanged(int)));
+}
+
+void QueueView::slotDownloadLimitChanged(int value)
+{
+ Config::setDownloadSpeedLimit(value);
+ Config::self()->emitChange();
+}
+
+void QueueView::slotUploadLimitChanged(int value)
+{
+ Config::setUploadSpeedLimit(value);
+ Config::self()->emitChange();
+}
+
+void QueueView::slotThreadCountChanged(int value)
+{
+ Config::setThreadCount(value);
+ Config::self()->emitChange();
+}
+
+void QueueView::initActions()
+{
+ m_actionCollection = new KActionCollection(this, this);
+
+ // Create all the actions
+ m_launchAction = new KAction(i18n("&Start Transfer"), "launch", KShortcut(), this, SLOT(slotLaunch()), m_actionCollection, "launch");
+ m_abortAction = new KAction(i18n("&Abort Transfer"), KShortcut(), this, SLOT(slotAbort()), m_actionCollection, "abort");
+ m_removeAction = new KAction(i18n("&Remove"), "editdelete", KShortcut(Qt::Key_Delete), this, SLOT(slotRemove()), m_actionCollection, "remove");
+ m_removeAllAction = new KAction(i18n("Remove &All"), KShortcut(), this, SLOT(slotRemoveAll()), m_actionCollection, "removeAll");
+ m_moveUpAction = new KAction(i18n("Move &Up"), "up", KShortcut(), this, SLOT(slotMoveUp()), m_actionCollection, "moveUp");
+ m_moveDownAction = new KAction(i18n("Move &Down"), "down", KShortcut("del"), this, SLOT(slotMoveDown()), m_actionCollection, "moveDown");
+ m_moveTopAction = new KAction(i18n("Move To &Top"), "top", KShortcut(), this, SLOT(slotMoveTop()), m_actionCollection, "moveTop");
+ m_moveBottomAction = new KAction(i18n("Move To &Bottom"), "bottom", KShortcut(), this, SLOT(slotMoveBottom()), m_actionCollection, "moveBottom");
+ m_editAction = new KAction(i18n("&Change Transfer Info"), KShortcut(), this, SLOT(slotEdit()), m_actionCollection, "changeTransfer");
+
+ // Create the toolbar actions
+ m_loadAction = new KAction(i18n("&Load Queue From File"), "fileopen", KShortcut(), this, SLOT(slotLoad()), m_actionCollection, "load");
+ m_saveAction = new KAction(i18n("&Save Queue to File"), "filesaveas", KShortcut(), this, SLOT(slotSave()), m_actionCollection, "save");
+ m_startAction = new KAction(i18n("S&tart"), "player_play", KShortcut(), this, SLOT(slotStart()), m_actionCollection, "start");
+ m_pauseAction = new KAction(i18n("&Pause"), "player_pause", KShortcut(), this, SLOT(slotPause()), m_actionCollection, "pause");
+ m_stopAction = new KAction(i18n("St&op"), "player_stop", KShortcut(), this, SLOT(slotStop()), m_actionCollection, "stop");
+ m_addAction = new KAction(i18n("&Add Transfer..."), "filenew", KShortcut(), this, SLOT(slotAdd()), m_actionCollection, "add");
+ m_searchAction = new KAction(i18n("&Search && Replace..."), "find", KShortcut(), this, SLOT(slotSearch()), m_actionCollection, "search");
+ m_filterAction = new KToggleAction(i18n("Show &Filter"), "filter", KShortcut(), this, SLOT(slotFilter()), m_actionCollection, "filter");
+
+ m_saveAction->setEnabled( false );
+ m_startAction->setEnabled(false);
+ m_pauseAction->setEnabled(false);
+ m_stopAction->setEnabled(false);
+ m_addAction->setEnabled(false);
+ m_removeAction->setEnabled(false);
+ m_searchAction->setEnabled(false);
+ m_filterAction->setEnabled(true);
+}
+
+void QueueView::updateActions()
+{
+ m_startAction->setEnabled(!KFTPQueue::Manager::self()->isProcessing() && KFTPQueue::Manager::self()->topLevelObject()->hasChildren() && !KFTPQueue::Manager::self()->getNumRunning());
+ m_stopAction->setEnabled(KFTPQueue::Manager::self()->isProcessing());
+ m_removeAllAction->setEnabled(!KFTPQueue::Manager::self()->isProcessing());
+
+ QPtrList<QListViewItem> selection = m_queue->selectedItems();
+ QueueViewItem *firstItem = static_cast<QueueViewItem*>(selection.first());
+
+ m_removeAction->setEnabled((bool) firstItem);
+
+ if (!firstItem || !firstItem->getObject())
+ return;
+
+ bool locked = firstItem->getObject()->isLocked();
+ bool parentRunning = false;
+
+ if (firstItem->getObject()->hasParentObject())
+ parentRunning = firstItem->getObject()->parentObject()->isRunning();
+
+ m_launchAction->setEnabled(!firstItem->getObject()->isRunning() && !KFTPQueue::Manager::self()->isProcessing() && !locked);
+ m_abortAction->setEnabled(firstItem->getObject()->isRunning() && !KFTPQueue::Manager::self()->isProcessing());
+ m_removeAction->setEnabled(!firstItem->getObject()->isRunning() && !KFTPQueue::Manager::self()->isProcessing() && !locked);
+ m_editAction->setEnabled(!firstItem->getObject()->isRunning() && firstItem->getObject()->parentObject()->getType() == KFTPQueue::QueueObject::Site && !locked);
+
+ // Only allow moving of multi selections if they have the same parent
+ bool allowMove = true;
+ for (QListViewItem *i = selection.first(); i; i = selection.next()) {
+ if (i->parent() != static_cast<QListViewItem*>(firstItem)->parent()) {
+ allowMove = false;
+ break;
+ }
+ }
+
+ m_moveUpAction->setEnabled(allowMove && KFTPQueue::Manager::self()->canBeMovedUp(firstItem->getObject()) && !locked);
+ m_moveDownAction->setEnabled(allowMove && KFTPQueue::Manager::self()->canBeMovedDown(static_cast<QueueViewItem*>(selection.last())->getObject()) && !locked);
+
+ m_moveTopAction->setEnabled(allowMove && KFTPQueue::Manager::self()->canBeMovedUp(firstItem->getObject()) && !locked);
+ m_moveBottomAction->setEnabled(allowMove && KFTPQueue::Manager::self()->canBeMovedDown(static_cast<QueueViewItem*>(selection.last())->getObject()) && !locked);
+}
+
+void QueueView::slotSiteAdded(KFTPQueue::Site *site)
+{
+ // The site should be inserted top-level
+ m_queuedItems.insert(site->getId(), new QueueViewItem(this, site, m_queue));
+ connect(site, SIGNAL(objectUpdated()), this, SLOT(slotObjectUpdated()));
+}
+
+void QueueView::slotTransferAdded(KFTPQueue::Transfer *transfer)
+{
+ // This transfer should be inserted under some other transfer
+ QueueViewItem *parent = m_queuedItems.find(transfer->parentObject()->getId());
+
+ if (parent) {
+ m_queuedItems.insert(transfer->getId(), new QueueViewItem(this, transfer, parent));
+ connect(transfer, SIGNAL(objectUpdated()), this, SLOT(slotObjectUpdated()));
+ }
+
+ // Update actions
+ m_saveAction->setEnabled(true);
+ m_removeAllAction->setEnabled(true);
+ m_searchAction->setEnabled(true);
+}
+
+void QueueView::slotObjectRemoved(long id)
+{
+ // Delete the transfer
+ QueueViewItem *item = m_queuedItems.find(id);
+
+ if (item)
+ delete item;
+
+ // Update actions
+ bool empty = (m_queue->childCount() == 0);
+
+ m_saveAction->setEnabled(!empty);
+ if (empty) m_removeAction->setEnabled(false);
+ m_removeAllAction->setEnabled(!empty);
+ m_searchAction->setEnabled(!empty);
+}
+
+void QueueView::slotObjectUpdated()
+{
+ KFTPQueue::QueueObject *object = (KFTPQueue::QueueObject*) QObject::sender();
+
+ if (object) {
+ QueueViewItem *item = m_queuedItems.find(object->getId());
+
+ if (item)
+ item->refresh();
+ }
+}
+
+void QueueView::contextMenuRequested(KListView*, QListViewItem* item, const QPoint& p)
+{
+ if (!item)
+ return;
+
+ QueueViewItem *firstItem = static_cast<QueueViewItem*>(m_queue->selectedItems().first());
+ KPopupMenu *contextMenu = new KPopupMenu(m_queue);
+
+ // Populate context menu
+ if (firstItem->getObject()->isTransfer()) {
+ contextMenu->insertTitle(item->text(0) + ((m_queue->selectedItems().count() > 1) ? "..." : "" ));
+ m_launchAction->plug(contextMenu);
+ m_abortAction->plug(contextMenu);
+ contextMenu->insertSeparator();
+ m_removeAction->plug(contextMenu);
+ m_removeAllAction->plug(contextMenu);
+ contextMenu->insertSeparator();
+ m_moveTopAction->plug(contextMenu);
+ m_moveUpAction->plug(contextMenu);
+ m_moveDownAction->plug(contextMenu);
+ m_moveBottomAction->plug(contextMenu);
+ contextMenu->insertSeparator();
+ m_editAction->plug(contextMenu);
+ } else if (firstItem->getObject()->getType() == KFTPQueue::QueueObject::Site) {
+ contextMenu->insertTitle(i18n("Site"));
+ m_launchAction->plug(contextMenu);
+ m_abortAction->plug(contextMenu);
+ contextMenu->insertSeparator();
+ m_moveUpAction->plug(contextMenu);
+ m_moveDownAction->plug(contextMenu);
+ }
+
+ // Update the actions
+ updateActions();
+
+ // Show the context menu
+ contextMenu->exec(p);
+}
+
+void QueueView::slotLaunch()
+{
+ // Reset a possible preconfigured default action
+ KFTPQueue::Manager::self()->setDefaultFileExistsAction();
+
+ static_cast<QueueViewItem*>(m_queue->selectedItems().first())->getObject()->execute();
+}
+
+void QueueView::slotAbort()
+{
+ static_cast<QueueViewItem*>(m_queue->selectedItems().first())->getObject()->abort();
+}
+
+void QueueView::slotRemove()
+{
+ if (KMessageBox::questionYesNo(this, i18n("Are you sure you want to remove queued file(s)?")) == KMessageBox::Yes) {
+ KFTPQueue::Manager::self()->setEmitUpdate(false);
+
+ QPtrList<QListViewItem> selection = m_queue->selectedItems();
+ for (QListViewItem *item = selection.first(); item; item = selection.next()) {
+ if (item && static_cast<QueueViewItem*>(item)->getObject())
+ KFTPQueue::Manager::self()->removeTransfer(static_cast<KFTPQueue::Transfer*>(static_cast<QueueViewItem*>(item)->getObject()));
+ }
+
+ KFTPQueue::Manager::self()->setEmitUpdate(true);
+ KFTPQueue::Manager::self()->doEmitUpdate();
+ }
+}
+
+void QueueView::slotRemoveAll()
+{
+ if (KMessageBox::questionYesNo(this, i18n("Are you sure you want to remove ALL queued files?")) == KMessageBox::Yes) {
+ KFTPQueue::Manager::self()->clearQueue();
+ }
+}
+
+void QueueView::slotMoveUp()
+{
+ QPtrList<QListViewItem> selection = m_queue->selectedItems();
+
+ for (QListViewItem *item = selection.first(); item; item = selection.next()) {
+ QueueViewItem *queueItem = static_cast<QueueViewItem*>(item);
+
+ // Move the transfer
+ KFTPQueue::Manager::self()->moveTransferUp(queueItem->getObject());
+ queueItem->moveUp();
+ }
+}
+
+void QueueView::slotMoveDown()
+{
+ QPtrList<QListViewItem> selection = m_queue->selectedItems();
+
+ for (QListViewItem *item = selection.last(); item; item = selection.prev()) {
+ QueueViewItem *queueItem = static_cast<QueueViewItem*>(item);
+
+ // Move the transfer
+ KFTPQueue::Manager::self()->moveTransferDown(queueItem->getObject());
+ queueItem->moveDown();
+ }
+}
+
+void QueueView::slotMoveTop()
+{
+ QPtrList<QListViewItem> selection = m_queue->selectedItems();
+
+ for (QListViewItem *item = selection.last(); item; item = selection.prev()) {
+ QueueViewItem *queueItem = static_cast<QueueViewItem*>(item);
+
+ // Move the transfer
+ KFTPQueue::Manager::self()->moveTransferTop(queueItem->getObject());
+ queueItem->moveToTop();
+ }
+}
+
+void QueueView::slotMoveBottom()
+{
+ QPtrList<QListViewItem> selection = m_queue->selectedItems();
+
+ for (QListViewItem *item = selection.first(); item; item = selection.next()) {
+ QueueViewItem *queueItem = static_cast<QueueViewItem*>(item);
+
+ // Move the transfer
+ KFTPQueue::Manager::self()->moveTransferBottom(queueItem->getObject());
+ queueItem->moveToBottom();
+ }
+}
+
+void QueueView::slotEdit()
+{
+ QueueEditor *editor = new QueueEditor(this);
+
+ QueueViewItem* item = static_cast<QueueViewItem*>(m_queue->selectedItems().first());
+ editor->setData(static_cast<KFTPQueue::Transfer*>(item->getObject()));
+
+ // Show the queue editor
+ if (editor->exec() == QDialog::Accepted) {
+ editor->saveData();
+
+ KFTPQueue::Manager::self()->revalidateTransfer(static_cast<KFTPQueue::Transfer*>(item->getObject()));
+ KFTPQueue::Manager::self()->doEmitUpdate();
+ item->refresh();
+ }
+}
+
+void QueueView::slotSearch()
+{
+ SearchDialog *dialog = new SearchDialog();
+
+ dialog->exec();
+ delete dialog;
+}
+
+void QueueView::slotLoad()
+{
+ if (m_queue->childCount() && KMessageBox::warningContinueCancel(0L, i18n("Loading a new queue will overwrite the existing one; are you sure you want to continue?"), i18n("Load Queue")) == KMessageBox::Cancel)
+ return;
+
+ QString loadPath = KFileDialog::getOpenFileName();
+
+ if (!loadPath.isEmpty()) {
+ KFTPQueue::Manager::self()->getConverter()->importQueue(loadPath);
+ }
+}
+
+void QueueView::slotSave()
+{
+ QString savePath = KFileDialog::getSaveFileName();
+
+ if (!savePath.isEmpty()) {
+ KFTPQueue::Manager::self()->getConverter()->exportQueue(savePath);
+ }
+}
+
+void QueueView::slotStart()
+{
+ // Begin queue processing
+ KFTPQueue::Manager::self()->start();
+}
+
+void QueueView::slotPause()
+{
+}
+
+void QueueView::slotStop()
+{
+ // Abort queue processing
+ KFTPQueue::Manager::self()->abort();
+}
+
+void QueueView::slotAdd()
+{
+}
+
+void QueueView::slotSearchEraseClicked()
+{
+ m_searchField->clear();
+}
+
+void QueueView::slotFilter()
+{
+ if (m_filterAction->isChecked())
+ m_searchToolBar->show();
+ else
+ m_searchToolBar->hide();
+}
+
+}
+
+#include "queueview.moc"
diff --git a/kftpgrabber/src/widgets/queueview/queueview.h b/kftpgrabber/src/widgets/queueview/queueview.h
new file mode 100644
index 0000000..d93e14f
--- /dev/null
+++ b/kftpgrabber/src/widgets/queueview/queueview.h
@@ -0,0 +1,296 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ * Copyright (C) 2005 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.
+ */
+
+#ifndef KFTPQUEUEVIEW_H
+#define KFTPQUEUEVIEW_H
+
+#include <qguardedptr.h>
+#include <qintdict.h>
+#include <qlayout.h>
+#include <qlabel.h>
+
+#include <kaction.h>
+#include <klistview.h>
+
+#include "kftpqueue.h"
+
+class KToolBar;
+class KListViewSearchLine;
+
+namespace KFTPWidgets {
+
+class ListView;
+class QueueView;
+
+/**
+ * A visual representation of a queued object.
+ */
+class QueueViewItem : public QListViewItem
+{
+public:
+ /**
+ * Class constructor.
+ *
+ * @param view Queue view widget
+ * @param object Queue object
+ * @param parent Parent list view
+ */
+ QueueViewItem(QueueView *view, KFTPQueue::QueueObject *object, QListView *parent);
+
+ /**
+ * Class constructor.
+ *
+ * @param view Queue view widget
+ * @param object Queue object
+ * @param parent Parent item
+ */
+ QueueViewItem(QueueView *view, KFTPQueue::QueueObject *object, QListViewItem *parent);
+
+ /**
+ * Class destructor.
+ */
+ ~QueueViewItem();
+
+ /**
+ * Refresh the visual representation with data from the actual queue object.
+ */
+ void refresh();
+
+ /**
+ * Associate a queue object with this item.
+ *
+ * @param object A valid object pointer
+ */
+ void setObject(KFTPQueue::QueueObject *object) { m_queueObject = object; }
+
+ /**
+ * Returns the currently associated queue object.
+ */
+ KFTPQueue::QueueObject *getObject() const { return m_queueObject; }
+
+ /**
+ * Returns the last child item.
+ */
+ QListViewItem *lastChild() const { return m_lastChild; }
+
+ /**
+ * Moves this item one position up.
+ */
+ void moveUp();
+
+ /**
+ * Moves this item one position down.
+ */
+ void moveDown();
+
+ /**
+ * Moves this item to parent's top.
+ */
+ void moveToTop();
+
+ /**
+ * Moves this item to parent's bottom.
+ */
+ void moveToBottom();
+
+ /**
+ * @overload
+ * Reimplemented from QListViewItem.
+ */
+ void insertItem(QListViewItem *newChild);
+
+ /**
+ * @overload
+ * Reimplemented from QListViewItem.
+ */
+ void takeItem(QListViewItem *item);
+
+ /**
+ * @overload
+ * Reimplemented from QListViewItem for text colors.
+ */
+ void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment);
+
+ /**
+ * @overload
+ * Reimplemented from QListViewItem.
+ */
+ void sortChildItems(int, bool) {}
+protected:
+ /**
+ * Init the item.
+ */
+ void init();
+private:
+ QListViewItem *m_lastChild;
+
+ KFTPQueue::QueueObject *m_queueObject;
+ QueueView *m_queueView;
+ long m_queueId;
+};
+
+/**
+ * The list view widget.
+ *
+ * @author Jernej Kos
+ */
+class QueueListView : public ListView {
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent Parent widget
+ */
+ QueueListView(QWidget *parent);
+
+ /**
+ * @overload
+ * Reimplemented from QListView.
+ */
+ void insertItem(QListViewItem *item);
+
+ /**
+ * @overload
+ * Reimplemented from QListView.
+ */
+ void setSorting(int, bool = true) { QListView::setSorting(-1); }
+};
+
+/**
+ * A widget for displaying and manipulating the current queue.
+ *
+ * @author Jernej Kos
+ */
+class QueueView : public QWidget
+{
+friend class QueueViewItem;
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ */
+ QueueView(QWidget *parent, const char *name);
+
+ /**
+ * Load queue list layout from the configuration file.
+ */
+ void loadLayout();
+
+ /**
+ * Save queue list layout to the configuration file.
+ */
+ void saveLayout();
+public slots:
+ void updateActions();
+protected:
+ /**
+ * Initialize actions.
+ */
+ void initActions();
+
+ /**
+ * Initialize toolbar widgets.
+ */
+ void initToolBar();
+private:
+ KActionCollection *m_actionCollection;
+
+ // Actions
+ KAction *m_launchAction;
+ KAction *m_abortAction;
+ KAction *m_removeAction;
+ KAction *m_removeAllAction;
+ KAction *m_moveUpAction;
+ KAction *m_moveDownAction;
+ KAction *m_moveTopAction;
+ KAction *m_moveBottomAction;
+ KAction *m_editAction;
+
+ // Toolbar Actions
+ KAction *m_loadAction;
+ KAction *m_saveAction;
+ KAction *m_startAction;
+ KAction *m_pauseAction;
+ KAction *m_stopAction;
+ KAction *m_addAction;
+ KAction *m_searchAction;
+ KToggleAction *m_filterAction;
+
+ KListViewSearchLine *m_searchField;
+
+ KToolBar *m_toolBar;
+ KToolBar *m_searchToolBar;
+ QueueListView *m_queue;
+
+ QIntDict<QueueViewItem> m_queuedItems;
+private slots:
+ void slotObjectRemoved(long);
+ void slotObjectUpdated();
+ void slotTransferAdded(KFTPQueue::Transfer*);
+ void slotSiteAdded(KFTPQueue::Site*);
+
+ void contextMenuRequested(KListView*, QListViewItem*, const QPoint&);
+
+ void slotSearchEraseClicked();
+
+ // Slots for actions
+ void slotLaunch();
+ void slotAbort();
+ void slotRemove();
+ void slotRemoveAll();
+ void slotMoveUp();
+ void slotMoveDown();
+ void slotMoveTop();
+ void slotMoveBottom();
+ void slotEdit();
+
+ void slotLoad();
+ void slotSave();
+ void slotStart();
+ void slotPause();
+ void slotStop();
+ void slotAdd();
+ void slotSearch();
+ void slotFilter();
+
+ void slotDownloadLimitChanged(int value);
+ void slotUploadLimitChanged(int value);
+ void slotThreadCountChanged(int value);
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/queueview/threadview.cpp b/kftpgrabber/src/widgets/queueview/threadview.cpp
new file mode 100644
index 0000000..fd1c663
--- /dev/null
+++ b/kftpgrabber/src/widgets/queueview/threadview.cpp
@@ -0,0 +1,202 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "threadview.h"
+#include "kftpapi.h"
+
+#include "listview.h"
+
+#include <qlayout.h>
+#include <klocale.h>
+
+namespace KFTPWidgets {
+
+ThreadViewItem::ThreadViewItem(KFTPSession::Session *session, QListView *parent)
+ : QObject(parent),
+ QListViewItem(parent),
+ m_connection(0),
+ m_session(session)
+{
+ refresh();
+}
+
+ThreadViewItem::ThreadViewItem(KFTPSession::Connection *conn, QListViewItem *parent, int id)
+ : QObject(),
+ QListViewItem(parent),
+ m_id(id),
+ m_connection(conn),
+ m_session(0)
+{
+ connect(conn, SIGNAL(connectionRemoved()), this, SLOT(slotUpdateItemRequested()));
+ connect(conn, SIGNAL(connectionLost(KFTPSession::Connection*)), this, SLOT(slotUpdateItemRequested()));
+ connect(conn, SIGNAL(connectionEstablished()), this, SLOT(slotUpdateItemRequested()));
+
+ // Connect the transfer signals if the transfer is already present
+ KFTPQueue::Transfer *transfer = m_connection->getTransfer();
+ if (transfer) {
+ connect(transfer, SIGNAL(objectUpdated()), this, SLOT(slotUpdateItemRequested()));
+ } else {
+ connect(conn, SIGNAL(connectionAcquired()), this, SLOT(slotConnectionAcquired()));
+ }
+
+ refresh();
+}
+
+void ThreadViewItem::slotConnectionAcquired()
+{
+ if (!m_connection->getTransfer())
+ return;
+
+ connect(m_connection->getTransfer(), SIGNAL(objectUpdated()), this, SLOT(slotUpdateItemRequested()));
+ refresh();
+}
+
+void ThreadViewItem::refresh()
+{
+ if (m_session) {
+ // Set the columns
+ setText(0, i18n("Site session [%1]").arg(m_session->getClient()->socket()->getCurrentUrl().host()));
+ setPixmap(0, loadSmallPixmap("ftp"));
+ } else if (m_connection) {
+ setText(0, i18n("Thread %1").arg(m_id));
+ setPixmap(0, loadSmallPixmap("server"));
+ setText(1, m_connection->isConnected() ? i18n("idle") : i18n("disconnected"));
+ setText(2, "");
+
+ KFTPQueue::Transfer *transfer = m_connection->getTransfer();
+ if (transfer && transfer->isRunning()) {
+ QString speed;
+ filesize_t rawSpeed = transfer->getSpeed();
+
+ speed.sprintf( "%lld KB/s", (rawSpeed / 1024) );
+
+ if (rawSpeed > 1024*1024)
+ speed.sprintf("%lld MB/s", (rawSpeed / 1024) / 1024);
+ else if (rawSpeed == 0)
+ speed = "";
+
+ if (transfer->getStatus() == KFTPQueue::Transfer::Connecting) {
+ setText(1, i18n("connecting"));
+ } else {
+ setText(1, i18n("transferring"));
+ }
+
+ if (transfer->getTransferType() == KFTPQueue::FXP && rawSpeed == 0) {
+ KFTPSession::Connection *c = static_cast<KFTPQueue::TransferFile*>(transfer)->getOppositeConnection(m_connection);
+
+ setText(2, i18n("FXP - [%1]").arg(c->getUrl().host()));
+ } else {
+ setText(2, speed);
+ }
+ }
+ }
+}
+
+void ThreadViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment)
+{
+ QListViewItem::paintCell(p, cg, column, width, alignment);
+}
+
+void ThreadViewItem::slotUpdateItemRequested()
+{
+ refresh();
+}
+
+KActionCollection *ThreadView::actionCollection()
+{
+ return KFTPAPI::getInstance()->mainWindow()->actionCollection();
+}
+
+ThreadView::ThreadView(QWidget *parent, const char *name)
+ : QWidget(parent, name)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+
+ // Create the list view
+ m_threads = new KFTPWidgets::ListView(this);
+
+ // Create the columns
+ m_threads->addColumn(i18n("Name"), 400);
+ m_threads->addColumn(i18n("Status"), 120);
+ m_threads->addColumn(i18n("Speed"), 70);
+
+ // Text when there are no threads
+ m_threads->setEmptyListText(i18n("There are no threads currently running."));
+
+ // Multi-select
+ m_threads->setSelectionModeExt(KListView::FileManager);
+ m_threads->setAllColumnsShowFocus(true);
+ m_threads->setRootIsDecorated(true);
+
+ layout->addWidget(m_threads);
+
+ connect(KFTPSession::Manager::self(), SIGNAL(update()), this, SLOT(slotUpdateSessions()));
+}
+
+ThreadView::~ThreadView()
+{
+}
+
+void ThreadView::slotUpdateSessions()
+{
+ KFTPSession::SessionList *list = KFTPSession::Manager::self()->getSessionList();
+ KFTPSession::Session *i;
+
+ m_threads->clear();
+
+ for (i = list->first(); i; i = list->next()) {
+ if (i->isRemote()) {
+ ThreadViewItem *site = new ThreadViewItem(i, m_threads);
+
+ QPtrList<KFTPSession::Connection> *c_list = i->getConnectionList();
+
+ if (c_list->count() > 0) {
+ KFTPSession::Connection *conn;
+ int id = 0;
+
+ for (conn = c_list->first(); conn; conn = c_list->next()) {
+ new ThreadViewItem(conn, site, ++id);
+ }
+
+ site->setOpen(true);
+ }
+ }
+ }
+}
+
+}
+
+#include "threadview.moc"
+
diff --git a/kftpgrabber/src/widgets/queueview/threadview.h b/kftpgrabber/src/widgets/queueview/threadview.h
new file mode 100644
index 0000000..5c37e6c
--- /dev/null
+++ b/kftpgrabber/src/widgets/queueview/threadview.h
@@ -0,0 +1,93 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+#ifndef KFTPTHREADVIEW_H
+#define KFTPTHREADVIEW_H
+
+#include <qguardedptr.h>
+
+#include <kaction.h>
+#include <klistview.h>
+
+#include "kftpsession.h"
+
+class KToolBar;
+
+namespace KFTPWidgets {
+
+class ListView;
+
+class ThreadViewItem : public QObject, public QListViewItem
+{
+Q_OBJECT
+public:
+ ThreadViewItem(KFTPSession::Session *session, QListView *parent);
+ ThreadViewItem(KFTPSession::Connection *conn, QListViewItem *parent, int id);
+
+ void refresh();
+ virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment);
+private:
+ int m_id;
+
+ QGuardedPtr<KFTPSession::Connection> m_connection;
+ QGuardedPtr<KFTPSession::Session> m_session;
+private slots:
+ void slotConnectionAcquired();
+ void slotUpdateItemRequested();
+};
+
+/**
+ * This widget shows all the currently used threads in KFTPGrabber transfers.
+ *
+ * @author Jernej Kos
+ */
+class ThreadView : public QWidget
+{
+Q_OBJECT
+public:
+ ThreadView(QWidget *parent = 0, const char *name = 0);
+ ~ThreadView();
+
+ KActionCollection *actionCollection();
+
+private slots:
+ void slotUpdateSessions();
+private:
+ KFTPWidgets::ListView *m_threads;
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/quickconnect.cpp b/kftpgrabber/src/widgets/quickconnect.cpp
new file mode 100644
index 0000000..0eabdc8
--- /dev/null
+++ b/kftpgrabber/src/widgets/quickconnect.cpp
@@ -0,0 +1,476 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-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 "widgets/quickconnect.h"
+#include "bookmarks/editortls.h"
+#include "misc/config.h"
+#include "kftpbookmarks.h"
+#include "misc.h"
+
+#include "engine/thread.h"
+#include "engine/ftpsocket.h"
+
+#include <kglobal.h>
+#include <kcharsets.h>
+#include <kcombobox.h>
+#include <klocale.h>
+#include <klineedit.h>
+#include <kpassdlg.h>
+#include <kmessagebox.h>
+#include <kpushbutton.h>
+
+/* KSSL includes */
+#include <ksslpkcs12.h>
+
+#include <qcheckbox.h>
+#include <qspinbox.h>
+
+using namespace KFTPGrabberBase;
+
+namespace KFTPWidgets {
+
+QuickConnectDialog::QuickConnectDialog(QWidget *parent, const char *name)
+ : KDialogBase(parent, name, true, i18n("Quick Connect"), Ok|Cancel, Ok),
+ m_noUrlChange(false),
+ m_protocolAdvancedDialog(0L),
+ m_portChanged(false)
+{
+ // Create the main widget
+ m_layout = new KFTPQuickConnectLayout(this);
+
+ // Set the dialog options
+ setMainWidget(m_layout);
+ resize(QSize(200,300));
+
+ m_layout->clearRecent->setIconSet(loadSmallIcon("clear_left"));
+ m_layout->protoAdvanced->setIconSet(loadSmallIcon("configure"));
+
+ // Connect the slots
+ connect(m_layout->urlBox, SIGNAL(textChanged(const QString&)), this, SLOT(slotUrlChanged(const QString &)));
+ connect(m_layout->hostBox, SIGNAL(textChanged(const QString&)), this, SLOT(slotHostChanged(const QString&)));
+ connect(m_layout->protocolBox, SIGNAL(activated(int)), this, SLOT(slotProtocolChanged(int)));
+ connect(m_layout->protoAdvanced, SIGNAL(clicked()), this, SLOT(slotProtoAdvancedClicked()));
+ connect(m_layout->usernameBox, SIGNAL(textChanged(const QString&)), this, SLOT(slotUserChanged()));
+ connect(m_layout->passwordBox, SIGNAL(textChanged(const QString&)), this, SLOT(slotPassChanged()));
+ connect(m_layout->portBox, SIGNAL(valueChanged(int)), this, SLOT(slotPortChanged(int)));
+ connect(m_layout->anonLogin, SIGNAL(clicked()), this, SLOT(slotAnonClicked()));
+ connect(m_layout->recentConnections, SIGNAL(activated(int)), this, SLOT(slotRecentConnectionActivated(int)));
+ connect(m_layout->clearRecent, SIGNAL(clicked()), this, SLOT(slotClearRecentClicked()));
+
+ // Init url
+ m_url.setProtocol("ftp");
+ m_url.setPort(21);
+ m_url.setPath("/");
+ m_layout->urlBox->setURL(m_url);
+
+ // Use anonymous account by default
+ m_layout->anonLogin->setChecked(true);
+ slotAnonClicked();
+
+ // Init the protocol advanced button
+ m_layout->protoAdvanced->setEnabled(false);
+
+ // Populate charsets
+ QStringList charsets = KGlobal::charsets()->descriptiveEncodingNames();
+ m_layout->serverEncoding->insertStringList(charsets);
+
+ QString defEncoding = KFTPCore::Config::defEncoding();
+ defEncoding = QString("%1 ( %2 )").arg(KGlobal::charsets()->languageForEncoding(defEncoding)).arg(defEncoding);
+ m_layout->serverEncoding->setCurrentText(defEncoding);
+
+ // Populate recent sites
+ int index = 0;
+ QStringList recentSites = KFTPCore::Config::recentSites();
+ for (QStringList::Iterator i = recentSites.begin(); i != recentSites.end(); ++i) {
+ KURL siteUrl = KURL(*i);
+
+ m_recentSites[index] = siteUrl;
+ m_layout->recentConnections->insertItem(siteUrl.prettyURL(), index++);
+ }
+
+ slotRecentConnectionActivated(0);
+}
+
+QuickConnectDialog::~QuickConnectDialog()
+{
+ if (m_protocolAdvancedDialog)
+ delete m_protocolAdvancedDialog;
+}
+
+void QuickConnectDialog::slotRecentConnectionActivated(int index)
+{
+ KURL url = m_recentSites[index];
+ m_layout->urlBox->setText(url.url());
+
+ if (m_url.user() == "anonymous") {
+ m_layout->anonLogin->setChecked(true);
+ slotAnonClicked();
+ }
+}
+
+void QuickConnectDialog::slotClearRecentClicked()
+{
+ if (KMessageBox::questionYesNo(0, i18n("Clear list of recently accessed sites ?")) == KMessageBox::No)
+ return;
+
+ m_layout->recentConnections->clear();
+ m_recentSites.clear();
+ KFTPCore::Config::setRecentSites(QStringList());
+}
+
+void QuickConnectDialog::slotUrlChanged(const QString &text)
+{
+ if (m_noUrlChange)
+ return;
+
+ m_layout->anonLogin->setChecked(false);
+ m_layout->usernameBox->setEnabled(true);
+ m_layout->passwordBox->setEnabled(true);
+
+ KURL tmpUrl = text;
+ if (!tmpUrl.isValid())
+ return;
+ else
+ m_url = tmpUrl;
+
+ m_noUrlChange = true;
+
+ if (m_url.protocol() == "ftp")
+ m_layout->protocolBox->setCurrentItem(SP_FTP);
+ else if (m_url.protocol() == "sftp")
+ m_layout->protocolBox->setCurrentItem(SP_SFTP);
+ else {
+ // Force FTP protocol
+ m_url.setProtocol("ftp");
+ m_layout->protocolBox->setCurrentItem(SP_FTP);
+ }
+
+ m_layout->hostBox->setText(m_url.host());
+ m_layout->usernameBox->setText(m_url.user());
+
+ if (m_url.hasPass()) {
+ m_layout->passwordBox->erase();
+ m_layout->passwordBox->insert(m_url.pass());
+ }
+
+ if (m_url.port() == 0) {
+ switch (m_layout->protocolBox->currentItem()) {
+ case SP_SFTP: {
+ m_layout->portBox->setValue(22);
+ m_url.setPort(22);
+ break;
+ }
+ default: {
+ m_layout->portBox->setValue(21);
+ m_url.setPort(21);
+ break;
+ }
+ }
+ } else {
+ m_layout->portBox->setValue(m_url.port());
+ }
+
+ m_layout->urlBox->setText(m_url.prettyURL());
+ m_noUrlChange = false;
+}
+
+void QuickConnectDialog::slotHostChanged(const QString &text)
+{
+ if (m_noUrlChange) return;
+
+ m_noUrlChange = true;
+ m_url.setHost(text);
+ m_layout->urlBox->setURL(m_url);
+ m_noUrlChange = false;
+}
+
+void QuickConnectDialog::slotPortChanged(int port)
+{
+ if (m_noUrlChange) return;
+
+ m_noUrlChange = true;
+ m_url.setPort(port);
+ m_layout->urlBox->setURL(m_url);
+ m_portChanged = true;
+ m_noUrlChange = false;
+}
+
+void QuickConnectDialog::slotUserChanged()
+{
+ if (m_noUrlChange) return;
+
+ m_noUrlChange = true;
+ m_url.setUser(m_layout->usernameBox->text());
+ m_layout->urlBox->setURL(m_url);
+ m_noUrlChange = false;
+}
+
+void QuickConnectDialog::slotPassChanged()
+{
+ if (m_noUrlChange) return;
+
+ m_noUrlChange = true;
+ m_url.setPass(m_layout->passwordBox->password());
+ m_layout->urlBox->setURL(m_url);
+ m_noUrlChange = false;
+}
+
+void QuickConnectDialog::slotAnonClicked()
+{
+ static QString tmpUser, tmpPass;
+
+ if (m_layout->anonLogin->isChecked()) {
+ m_layout->usernameBox->setEnabled(false);
+ m_layout->passwordBox->setEnabled(false);
+ tmpUser = m_layout->usernameBox->text();
+ tmpPass = m_layout->passwordBox->text();
+ m_layout->usernameBox->setText("anonymous");
+ m_layout->passwordBox->erase();
+
+ // Use the appropriate e-mail address for anonymous accounts
+ if (!KFTPCore::Config::anonMail().isEmpty())
+ m_layout->passwordBox->insert(KFTPCore::Config::anonMail());
+ else
+ m_layout->passwordBox->insert("userlogin@anonymo.us");
+ } else {
+ m_layout->usernameBox->setText(tmpUser);
+ m_layout->passwordBox->erase();
+ m_layout->passwordBox->insert(tmpPass);
+ m_layout->usernameBox->setEnabled(true);
+ m_layout->passwordBox->setEnabled(true);
+ }
+
+ slotUserChanged();
+ slotPassChanged();
+}
+
+void QuickConnectDialog::slotOk()
+{
+ // Construct a nice error message
+ QString errorMessage;
+
+ if (m_url.host().isEmpty())
+ errorMessage = i18n("a hostname");
+
+ if (m_url.port() < 1)
+ errorMessage += (errorMessage.isEmpty() ? QString::null : QString::fromLatin1(", ")) + i18n("a valid port");
+
+ if (m_url.user().isEmpty())
+ errorMessage += (errorMessage.isEmpty() ? QString::null : QString::fromLatin1(", ")) + i18n("your username");
+
+ if (m_url.pass().isEmpty())
+ errorMessage += (errorMessage.isEmpty() ? QString::null : QString::fromLatin1(", ")) + i18n("your password");
+
+ if (errorMessage.findRev(",") != -1)
+ errorMessage = errorMessage.replace(errorMessage.findRev(","), 1 , i18n(" and"));
+
+ if (!errorMessage.isEmpty()) {
+ KMessageBox::sorry(0, i18n("Please enter ") + errorMessage + ".");
+ return;
+ }
+
+ if (m_layout->addBookmark->isChecked()) {
+ // Add the current connection to bookmarks. Use hostname as the bookmark name.
+ KFTPBookmarks::Site *root = KFTPBookmarks::Manager::self()->findCategory("root");
+ KFTPBookmarks::Site *site = root->addSite();
+ site->setAttribute("name", m_url.host());
+
+ site->setProperty("host", m_url.host());
+ site->setProperty("port", m_url.port());
+ site->setProperty("username", m_url.user());
+ site->setProperty("password", encodePassword(m_url.pass()));
+ site->setProperty("defremotepath", "/");
+ site->setProperty("protocol", m_layout->protocolBox->currentItem() == SP_SFTP ? "sftp" : "ftp");
+ site->setProperty("use_tls", m_layout->protocolBox->currentItem() == SP_SSL_EXPLICIT);
+ site->setProperty("use_implicit", m_layout->protocolBox->currentItem() == SP_SSL_IMPLICIT);
+ site->setProperty("encoding", KGlobal::charsets()->encodingForName(m_layout->serverEncoding->currentText()));
+
+ // Save TLS options
+ if (m_protocolAdvancedDialog) {
+ site->setProperty("tls_data_mode", m_protocolAdvancedDialog->getTLSMode());
+ site->setProperty("use_cert", m_protocolAdvancedDialog->isCertChecked());
+
+ if (m_protocolAdvancedDialog->isCertChecked())
+ site->setProperty("tls_cert_path", m_protocolAdvancedDialog->getCertPath());
+ }
+
+ KFTPBookmarks::Manager::self()->emitUpdate();
+ }
+
+ // Save to recent sites
+ QStringList recentSites = KFTPCore::Config::recentSites();
+ if (m_url.user() == "anonymous")
+ m_url.setPass("");
+
+ if (recentSites.findIndex(m_url.url()) == -1) {
+ recentSites.prepend(m_url.url());
+
+ if (recentSites.count() > 10)
+ recentSites.pop_back();
+
+ KFTPCore::Config::setRecentSites(recentSites);
+ }
+
+ // Close the dialog
+ accept();
+}
+
+void QuickConnectDialog::setupClient(KFTPEngine::Thread *client)
+{
+ // First activate the correct socket and reset the old flags
+ client->selectSocketForProtocol(KURL(QString("%1://test/").arg(m_layout->protocolBox->currentItem() == SP_SFTP ? "sftp" : "ftp")));
+ client->socket()->initConfig();
+
+ client->socket()->setConfig("retry", 0);
+
+ client->socket()->setConfig("ssl.use_tls", m_layout->protocolBox->currentItem() == SP_SSL_EXPLICIT);
+ client->socket()->setConfig("ssl.use_implicit", m_layout->protocolBox->currentItem() == SP_SSL_IMPLICIT);
+ client->socket()->setConfig("encoding", KGlobal::charsets()->encodingForName(m_layout->serverEncoding->currentText()));
+
+ // Set TLS options
+ if (m_protocolAdvancedDialog) {
+ client->socket()->setConfig("ssl.prot_mode", m_protocolAdvancedDialog->getTLSMode());
+
+ // Should we use a X509 certificate ?
+ if (m_protocolAdvancedDialog->isCertChecked() && m_layout->protocolBox->currentItem() == SP_FTP) {
+ // Ask the user for the decryption password
+ QCString certPass;
+ KPasswordDialog::getPassword(certPass, i18n("Please provide your X509 certificate decryption password."));
+
+ static_cast<KFTPEngine::FtpSocket*>(client->socket())->setSslClientCertificate(KSSLPKCS12::loadCertFile(m_protocolAdvancedDialog->getCertPath(), certPass));
+ }
+ }
+}
+
+void QuickConnectDialog::slotProtocolChanged(int item)
+{
+ if (m_noUrlChange) return;
+
+ // Enable/Disable the SSL/TLS settings if needed
+ m_layout->protoAdvanced->setEnabled( item == SP_SSL_EXPLICIT || item == SP_SSL_IMPLICIT );
+
+ // Set the default port
+ if (!m_portChanged) {
+ switch (item) {
+ case SP_SSL_IMPLICIT:
+ if (m_layout->portBox->value() == 21 || m_layout->portBox->value() == 22)
+ m_layout->portBox->setValue(993);
+ break;
+ case SP_SFTP:
+ if (m_layout->portBox->value() == 21 || m_layout->portBox->value() == 993)
+ m_layout->portBox->setValue(22);
+ break;
+ default:
+ if (m_layout->portBox->value() == 22 || m_layout->portBox->value() == 993)
+ m_layout->portBox->setValue(21);
+ break;
+ }
+
+ m_portChanged = false;
+ }
+
+ m_noUrlChange = true;
+ m_url.setProtocol( item == SP_SFTP ? "sftp" : "ftp");
+ m_url.setPort( m_layout->portBox->value() );
+ m_layout->urlBox->setURL(m_url);
+ m_noUrlChange = false;
+}
+
+void QuickConnectDialog::slotProtoAdvancedClicked()
+{
+ if (!m_protocolAdvancedDialog)
+ m_protocolAdvancedDialog = new KFTPWidgets::Bookmarks::BookmarkEditorTLS(this);
+
+ QChar tlsMode = m_protocolAdvancedDialog->getTLSMode();
+ bool certChecked = m_protocolAdvancedDialog->isCertChecked();
+ QString certPath = m_protocolAdvancedDialog->getCertPath();
+ m_protocolAdvancedDialog->slotChangeActiveX509Group();
+
+ if (!m_protocolAdvancedDialog->exec()) {
+ m_protocolAdvancedDialog->setTLSMode(tlsMode);
+ m_protocolAdvancedDialog->setCertChecked(certChecked);
+ m_protocolAdvancedDialog->setCertPath(certPath);
+ m_protocolAdvancedDialog->slotChangeActiveX509Group();
+ }
+}
+
+QChar QuickConnectDialog::getTLSMode()
+{
+ if (!m_protocolAdvancedDialog)
+ return false;
+
+ return m_protocolAdvancedDialog->getTLSMode();
+}
+
+bool QuickConnectDialog::isCertChecked()
+{
+ if (!m_protocolAdvancedDialog)
+ return false;
+
+ return m_protocolAdvancedDialog->isCertChecked();
+}
+
+QString QuickConnectDialog::getCertPath()
+{
+ if (!m_protocolAdvancedDialog)
+ return QString::null;
+
+ return m_protocolAdvancedDialog->getCertPath();
+}
+
+int QuickConnectDialog::getFTPMode()
+{
+ return m_layout->protocolBox->currentItem();
+}
+
+void QuickConnectDialog::setHost(const QString &host)
+{
+ m_layout->hostBox->setText(host);
+}
+
+void QuickConnectDialog::setPort(int port)
+{
+ m_layout->portBox->setValue(port);
+}
+
+void QuickConnectDialog::setFocusToUser()
+{
+ m_layout->usernameBox->setFocus();
+}
+
+}
+
+#include "quickconnect.moc"
diff --git a/kftpgrabber/src/widgets/quickconnect.h b/kftpgrabber/src/widgets/quickconnect.h
new file mode 100644
index 0000000..ad88212
--- /dev/null
+++ b/kftpgrabber/src/widgets/quickconnect.h
@@ -0,0 +1,162 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-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.
+ */
+
+#ifndef KFTPWIDGETSQUICKCONNECT_H
+#define KFTPWIDGETSQUICKCONNECT_H
+
+#include "kftpquickconnectlayout.h"
+
+#include <qmap.h>
+
+#include <kdialogbase.h>
+#include <kurl.h>
+
+namespace KFTPEngine {
+ class Thread;
+}
+
+namespace KFTPWidgets {
+
+namespace Bookmarks {
+ class BookmarkEditorTLS;
+}
+
+/**
+ * @author Jernej Kos
+ */
+class QuickConnectDialog : public KDialogBase
+{
+Q_OBJECT
+public:
+ QuickConnectDialog(QWidget *parent = 0, const char *name = 0);
+ ~QuickConnectDialog();
+
+ /**
+ * Get URL the user is trying to connect to.
+ *
+ * @return a KURL representing the destination server
+ */
+ KURL getUrl() { return m_url; }
+
+ /**
+ * Get the currently selected file transfer protocol.
+ *
+ * @return index of currently selected protocol
+ */
+ int getFTPMode();
+
+ /**
+ * Get the currently set TLS operation mode.
+ *
+ * @return currently set TLS operation mode
+ */
+ QChar getTLSMode();
+
+ /**
+ * Is the "use custom X509 certificate" checked or not.
+ *
+ * @return true if the "use custom X509 certificate" is checked
+ */
+ bool isCertChecked();
+
+ /**
+ * Get the currently set X509 certificate path.
+ *
+ * @return path to the user's X509 certificate for this connection
+ */
+ QString getCertPath();
+
+ /**
+ * Set the destination server's hostname.
+ *
+ * @param host destination server's hostname
+ */
+ void setHost(const QString &host);
+
+ /**
+ * Set the destination server's port.
+ *
+ * @param port destination server's port
+ */
+ void setPort(int port);
+
+ /**
+ * Focus the dialog's username input field.
+ */
+ void setFocusToUser();
+
+ /**
+ * Configures the client acoording to the settings chosen in the quick connect
+ * dialog.
+ *
+ * @param client a disconnected client socket
+ */
+ void setupClient(KFTPEngine::Thread *client);
+private:
+ enum ServerProtocol {
+ SP_FTP = 0,
+ SP_SSL_EXPLICIT,
+ SP_SSL_IMPLICIT,
+ SP_SFTP
+ };
+
+ KFTPQuickConnectLayout *m_layout;
+
+ bool m_noUrlChange;
+ KURL m_url;
+ Bookmarks::BookmarkEditorTLS *m_protocolAdvancedDialog;
+
+ bool m_portChanged;
+
+ QMap<int, KURL> m_recentSites;
+private slots:
+ virtual void slotOk();
+
+ void slotUrlChanged(const QString &);
+ void slotHostChanged(const QString&);
+ void slotPortChanged(int);
+ void slotUserChanged();
+ void slotPassChanged();
+ void slotAnonClicked();
+ void slotProtocolChanged(int);
+ void slotProtoAdvancedClicked();
+ void slotRecentConnectionActivated(int index);
+ void slotClearRecentClicked();
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/searchdialog.cpp b/kftpgrabber/src/widgets/searchdialog.cpp
new file mode 100644
index 0000000..ade32c3
--- /dev/null
+++ b/kftpgrabber/src/widgets/searchdialog.cpp
@@ -0,0 +1,165 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2004 by the KFTPGrabber developers
+ * Copyright (C) 2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "widgets/searchdialog.h"
+#include "kftpsearchlayout.h"
+#include "kftpserverlineedit.h"
+#include "kftpbookmarks.h"
+#include "kftpqueue.h"
+
+#include <qcheckbox.h>
+#include <qgroupbox.h>
+#include <qspinbox.h>
+#include <qregexp.h>
+
+#include <klocale.h>
+#include <klineedit.h>
+#include <kpassdlg.h>
+
+namespace KFTPWidgets {
+
+SearchDialog::SearchDialog(QWidget *parent, const char *name)
+ : KDialogBase(parent, name, true, i18n("Search & Replace"), Ok|Cancel, Ok)
+{
+ // Create the main widget
+ m_layout = new KFTPSearchLayout(this);
+
+ // Set the dialog options
+ setMainWidget(m_layout);
+ setInitialSize(QSize(500,400));
+
+ connect(m_layout->searchServer, SIGNAL(clicked()), this, SLOT(slotSearchServerClicked()));
+ connect(m_layout->searchServerName, SIGNAL(siteChanged(KFTPBookmarks::Site*)), this, SLOT(slotSiteChanged(KFTPBookmarks::Site*)));
+}
+
+QString SearchDialog::replaceCap(QStringList cap, const QString &text)
+{
+ QString tmp = text;
+
+ QStringList::Iterator end( cap.end() );
+ for(QStringList::Iterator i( cap.begin() ); i != end; ++i) {
+ tmp.replace("$" + QString::number(cap.findIndex(*i)), *i);
+ }
+
+ return tmp;
+}
+
+void SearchDialog::replace(KFTPQueue::Transfer *i)
+{
+ QRegExp s, d;
+
+ s.setPattern(m_layout->searchSrcPath->text());
+ d.setPattern(m_layout->searchDstPath->text());
+
+ KURL tmp = i->getSourceUrl().isLocalFile() ? i->getDestUrl() : i->getSourceUrl();
+ tmp.setPath("/");
+
+ KURL match;
+ match.setProtocol("ftp");
+ match.setHost(m_layout->searchServerHost->text());
+ match.setPort(m_layout->searchServerPort->value());
+ match.setUser(m_layout->searchServerUser->text());
+ match.setPass(m_layout->searchServerPass->password());
+ match.setPath("/");
+
+ if (s.search(i->getSourceUrl().path()) != -1 && d.search(i->getDestUrl().path()) != -1 &&
+ (!m_layout->searchServer->isChecked() || tmp.url() == match.url())) {
+ // Do the replacing
+ KURL newSource = i->getSourceUrl();
+ KURL newDest = i->getDestUrl();
+
+ newSource.setPath(replaceCap(s.capturedTexts(), m_layout->replaceSrcPath->text()));
+ newDest.setPath(replaceCap(d.capturedTexts(), m_layout->replaceDstPath->text()));
+
+ i->setSourceUrl(newSource);
+ i->setDestUrl(newDest);
+
+ i->emitUpdate();
+ }
+}
+
+void SearchDialog::searchAndReplace(KFTPQueue::QueueObject *parent)
+{
+ if (parent->isLocked())
+ return;
+
+ QPtrList<KFTPQueue::QueueObject> list = parent->getChildrenList();
+
+ KFTPQueue::QueueObject *i;
+ for (i = list.first(); i; i = list.next()) {
+ if (i->hasChildren() && !i->isLocked()) {
+ searchAndReplace(i);
+ }
+
+ if (i->isTransfer() && !i->isLocked())
+ replace(static_cast<KFTPQueue::Transfer*>(i));
+ }
+}
+
+void SearchDialog::searchAndReplace()
+{
+ searchAndReplace(KFTPQueue::Manager::self()->topLevelObject());
+}
+
+void SearchDialog::slotOk()
+{
+ searchAndReplace();
+ accept();
+}
+
+void SearchDialog::slotSearchServerClicked()
+{
+ m_layout->groupBox1->setEnabled(m_layout->searchServer->isChecked());
+}
+
+void SearchDialog::slotSiteChanged(KFTPBookmarks::Site *site)
+{
+ if (site) {
+ m_layout->searchServerHost->setText(site->getProperty("host"));
+ m_layout->searchServerPort->setValue(site->getIntProperty("port"));
+ m_layout->searchServerUser->setText(site->getProperty("username"));
+ m_layout->searchServerPass->erase();
+ m_layout->searchServerPass->insert(site->getProperty("password"));
+ } else {
+ m_layout->searchServerHost->clear();
+ m_layout->searchServerPort->setValue(21);
+ m_layout->searchServerUser->clear();
+ m_layout->searchServerPass->erase();
+ }
+}
+
+}
+
+#include "searchdialog.moc"
diff --git a/kftpgrabber/src/widgets/searchdialog.h b/kftpgrabber/src/widgets/searchdialog.h
new file mode 100644
index 0000000..7ae598b
--- /dev/null
+++ b/kftpgrabber/src/widgets/searchdialog.h
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2004 by the KFTPGrabber developers
+ * Copyright (C) 2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPWIDGETSSEARCHDIALOG_H
+#define KFTPWIDGETSSEARCHDIALOG_H
+
+#include <qdom.h>
+#include <kdialogbase.h>
+
+namespace KFTPQueue {
+ class Transfer;
+ class QueueObject;
+}
+
+namespace KFTPBookmarks {
+ class Site;
+}
+
+class KFTPSearchLayout;
+
+namespace KFTPWidgets {
+
+/**
+ * This dialog provides search & replace functionality for queued transfers.
+ *
+ * @author Jernej Kos
+ */
+class SearchDialog : public KDialogBase
+{
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ */
+ SearchDialog(QWidget *parent = 0, const char *name = 0);
+private:
+ KFTPSearchLayout *m_layout;
+
+ void replace(KFTPQueue::Transfer *i);
+
+ QString replaceCap(QStringList cap, const QString &text);
+ void searchAndReplace(KFTPQueue::QueueObject *parent);
+ void searchAndReplace();
+private slots:
+ virtual void slotOk();
+
+ void slotSearchServerClicked();
+ void slotSiteChanged(KFTPBookmarks::Site *site);
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/sidebar.cpp b/kftpgrabber/src/widgets/sidebar.cpp
new file mode 100644
index 0000000..bd7545b
--- /dev/null
+++ b/kftpgrabber/src/widgets/sidebar.cpp
@@ -0,0 +1,393 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ * Copyright (C) 2004-2005 Max Howell <max.howell@methylblue.com>
+ *
+ * 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 "misc.h"
+#include "sidebar.h"
+#include "multitabbar.h"
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kiconloader.h>
+#include <klocale.h>
+
+#include <qcursor.h>
+#include <qpainter.h>
+#include <qsignalmapper.h>
+#include <qstyle.h>
+
+namespace KFTPWidgets {
+
+class Splitter : public QWidget {
+public:
+ Splitter(Sidebar *w)
+ : QWidget(w, "divider"),
+ m_position(w->m_position)
+ {
+ if (m_position == Sidebar::Left)
+ setCursor(QCursor(SplitHCursor));
+ else
+ setCursor(QCursor(SplitVCursor));
+
+ styleChange(style());
+ }
+
+ virtual void paintEvent(QPaintEvent*)
+ {
+ QPainter p(this);
+ parentWidget()->style().drawPrimitive(QStyle::PE_Splitter, &p, rect(), colorGroup(), m_position == Sidebar::Left ? QStyle::Style_Horizontal : 0);
+ }
+
+ virtual void styleChange(QStyle&)
+ {
+ if (m_position == Sidebar::Left)
+ setFixedWidth(style().pixelMetric(QStyle::PM_SplitterWidth, this));
+ else
+ setFixedHeight(style().pixelMetric(QStyle::PM_SplitterWidth, this));
+ }
+
+ virtual void mouseMoveEvent(QMouseEvent *e)
+ {
+ static_cast<Sidebar*>(parent())->mouseMovedOverSplitter(e);
+ }
+private:
+ Sidebar::Position m_position;
+};
+
+Sidebar::Sidebar(QWidget *parent, Position position)
+ : QWidget(parent, "Sidebar"),
+ m_position(position),
+ m_divider(new KFTPWidgets::Splitter(this)),
+ m_content(new QVBox(this)),
+ m_tabBar(new MultiTabBar(position == Left ? MultiTabBar::Vertical : MultiTabBar::Horizontal, this)),
+ m_sidebarBox(new QWidget(this)),
+ m_currentIndex(-1),
+ m_lastIndex(-1),
+ m_mapper(new QSignalMapper(this))
+{
+ m_tabBar->setStyle(MultiTabBar::AMAROK);
+ m_tabBar->setPosition(m_position == Left ? MultiTabBar::Left : MultiTabBar::Bottom);
+ m_tabBar->showActiveTabTexts(true);
+
+ if (m_position == Left) {
+ m_pos = m_tabBar->sizeHint().width() + 5;
+
+ m_tabBar->setFixedWidth(m_pos);
+ m_tabBar->move(0, 3);
+
+ QVBoxLayout *layout = new QVBoxLayout(m_sidebarBox);
+ layout->addSpacing(3);
+ layout->setAutoAdd(true);
+
+ m_sidebarBox->move(m_pos, 0);
+ m_sidebarBox->hide();
+ m_divider->hide();
+ m_content->setSpacing(1);
+ } else {
+ m_pos = m_tabBar->sizeHint().height() + 5;
+ m_tabBar->setFixedHeight(m_pos);
+
+ QVBoxLayout *layout = new QVBoxLayout(m_sidebarBox);
+ layout->setAutoAdd(true);
+
+ m_sidebarBox->hide();
+ m_divider->hide();
+ m_content->setSpacing(1);
+ }
+
+ connect(m_mapper, SIGNAL(mapped(int)), SLOT(showHideSidebar(int)));
+}
+
+void Sidebar::setVisible(bool visible)
+{
+ if (m_position == Left) {
+ m_pos = m_tabBar->sizeHint().width() + 5;
+ m_tabBar->setFixedWidth(visible ? m_pos : 0);
+ } else {
+ m_pos = m_tabBar->sizeHint().height() + 5;
+ m_tabBar->setFixedHeight(visible ? m_pos : 0);
+ }
+
+ if (m_currentIndex != -1)
+ showHideSidebar(m_currentIndex);
+
+ if (visible)
+ m_tabBar->show();
+ else
+ m_tabBar->hide();
+
+ adjustWidgetSizes();
+}
+
+Sidebar::~Sidebar()
+{
+ KConfig *config;
+ // Save the currently selected sidebar
+ if (m_position == Left) {
+ config = KFTPGrabberBase::config(QString("Sidebar_%1").arg("Left"));
+ } else {
+ config = KFTPGrabberBase::config(QString("Sidebar_%1").arg("Bottom"));
+ }
+ if (m_currentIndex != -1) {
+ config->writeEntry("CurrentSidebar", currentSidebar()->name());
+ } else {
+ config->writeEntry("CurrentSidebar", QString::null);
+ }
+ if (m_position == Left) {
+ config->writeEntry("Size", m_sidebarBox->width());
+ } else {
+ config->writeEntry("Size", m_sidebarBox->height());
+ }
+}
+
+void Sidebar::polish()
+{
+ QWidget::polish();
+
+ KConfig *config = KFTPGrabberBase::config(QString("Sidebar_%1").arg(m_position == Left ? "Left" : "Bottom"));
+ const int index = indexForName(config->readEntry("CurrentSidebar"));
+
+ if (m_position == Left) {
+ uint M = 0;
+ for (SidebarList::ConstIterator it = m_sidebars.begin(), end = m_sidebars.end(); it != end; ++it) {
+ const uint m = (*it)->minimumWidth();
+ if (m > M) M = m;
+ }
+
+ const int width = config->readNumEntry("Size", sidebar(index)->sizeHint().width());
+
+ if (M > 250) {
+ M = 250;
+ }
+
+ m_sidebarBox->setMinimumWidth(M);
+ m_sidebarBox->resize(width, height());
+ } else {
+ uint M = 0;
+ for (SidebarList::ConstIterator it = m_sidebars.begin(), end = m_sidebars.end(); it != end; ++it) {
+ const uint m = (*it)->minimumHeight();
+ if (m > M) M = m;
+ }
+
+ const int height = config->readNumEntry("Size", sidebar(index)->height());
+
+ if (M > 250) {
+ M = 250;
+ }
+
+ m_sidebarBox->setMinimumHeight(M);
+ m_sidebarBox->resize(width(), height);
+ }
+
+ // If any sidebar should be open, open it
+ if (index != -1)
+ showHideSidebar(index);
+}
+
+void Sidebar::adjustWidgetSizes()
+{
+ if (m_position == Left) {
+ const uint w = width();
+ const uint h = height();
+ const uint mxW = maxSidebarWidth();
+ const uint p = (m_pos < mxW) ? m_pos : mxW;
+ const uint ppw = p + m_divider->width();
+ const uint tbw = m_tabBar->width();
+
+ m_divider->move(p, 0);
+
+ const uint offset = !m_divider->isHidden() ? ppw : tbw;
+
+ m_sidebarBox->resize(p - tbw, h);
+ m_content->setGeometry(offset, 0, w - offset, h);
+ } else {
+ const uint w = width();
+ const uint h = height();
+ const uint mxH = maxSidebarHeight();
+ const uint p = (m_pos < mxH) ? m_pos : mxH;
+ const uint pph = p + m_divider->height();
+ const uint tbh = m_tabBar->height();
+
+ m_divider->move(0, h - pph);
+
+ const uint offset = !m_divider->isHidden() ? pph : tbh;
+
+ m_sidebarBox->setGeometry(0, h - p, w, p - tbh);
+ m_content->setGeometry(0, 0, w, h - offset);
+ m_tabBar->move(0, h - tbh);
+ }
+}
+
+void Sidebar::mouseMovedOverSplitter(QMouseEvent *e)
+{
+ const uint oldPos = m_pos;
+ uint newPos;
+ uint minPos;
+ uint maxPos;
+
+ if (m_position == Left) {
+ newPos = mapFromGlobal(e->globalPos()).x();
+ minPos = m_tabBar->width() + m_sidebarBox->minimumWidth();
+ maxPos = maxSidebarWidth();
+ } else {
+ newPos = height() - mapFromGlobal(e->globalPos()).y();
+ minPos = m_tabBar->height() + m_sidebarBox->minimumHeight();
+ maxPos = maxSidebarHeight();
+ }
+
+ if (newPos < minPos)
+ m_pos = minPos;
+ else if (newPos > maxPos)
+ m_pos = maxPos;
+ else
+ m_pos = newPos;
+
+ if (m_pos != oldPos)
+ adjustWidgetSizes();
+}
+
+bool Sidebar::event(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::LayoutHint: {
+ if (m_position == Left) {
+ setMinimumWidth(m_tabBar->minimumWidth() + m_divider->minimumWidth() + m_sidebarBox->width() + m_content->minimumWidth());
+ } else {
+ setMinimumHeight(m_tabBar->minimumHeight() + m_divider->minimumHeight() + m_sidebarBox->height() + m_content->minimumHeight());
+ }
+ break;
+ }
+ case QEvent::Resize: {
+ if (m_position == Left) {
+ m_divider->resize(0, height());
+ m_tabBar->resize(0, height());
+ } else {
+ m_divider->resize(width(), 0);
+ m_tabBar->resize(width(), 0);
+ }
+
+ adjustWidgetSizes();
+ return true;
+ }
+ default: break;
+ }
+
+ return QWidget::event(e);
+}
+
+void Sidebar::addSidebar(QWidget *widget, const QString &title, const QString &icon)
+{
+ const int id = m_tabBar->tabs()->count(); // the next available id
+ const QString name(widget->name());
+ QWidget *tab;
+
+ widget->reparent(m_sidebarBox, QPoint());
+ widget->hide();
+
+ m_tabBar->appendTab(SmallIcon(icon), id, title);
+ tab = m_tabBar->tab(id);
+ tab->setFocusPolicy(QWidget::NoFocus);
+
+ // We use a SignalMapper to show/hide the corresponding browser when tabs are clicked
+ connect(tab, SIGNAL(clicked()), m_mapper, SLOT(map()));
+ m_mapper->setMapping(tab, id);
+
+ m_sidebars.push_back(widget);
+}
+
+void Sidebar::showHideSidebar(int index)
+{
+ const int prevIndex = m_currentIndex;
+
+ if (m_currentIndex != -1) {
+ // First we need to hide the currentBrowser
+ m_currentIndex = -1;
+
+ m_sidebars[prevIndex]->hide();
+ m_tabBar->setTab(prevIndex, false);
+ }
+
+ if (index == prevIndex) {
+ // Close the sidebar
+ m_sidebarBox->hide();
+ m_divider->hide();
+
+ adjustWidgetSizes();
+ } else if ((uint) index < m_sidebars.count()) {
+ // Open up target
+ QWidget* const target = m_sidebars[index];
+ m_currentIndex = index;
+
+ m_divider->show();
+ target->show();
+ target->setFocus();
+ m_sidebarBox->show();
+ m_tabBar->setTab(index, true);
+
+ if (prevIndex == -1) {
+ if (m_position == Left) {
+ m_pos = m_sidebarBox->width() + m_tabBar->width();
+ } else {
+ m_pos = currentSidebar()->height() + m_tabBar->height();
+ }
+
+ adjustWidgetSizes();
+ }
+ }
+}
+
+QWidget *Sidebar::sidebar(const QString &name) const
+{
+ for (SidebarList::ConstIterator it = m_sidebars.begin(), end = m_sidebars.end(); it != end; ++it) {
+ if (name == (*it)->name())
+ return *it;
+ }
+
+ return 0;
+}
+
+int Sidebar::indexForName(const QString &name) const
+{
+ for (uint x = 0; x < m_sidebars.count(); ++x) {
+ if (name == m_sidebars[x]->name())
+ return x;
+ }
+
+ return -1;
+}
+
+}
+
+#include "sidebar.moc"
diff --git a/kftpgrabber/src/widgets/sidebar.h b/kftpgrabber/src/widgets/sidebar.h
new file mode 100644
index 0000000..4d4f710
--- /dev/null
+++ b/kftpgrabber/src/widgets/sidebar.h
@@ -0,0 +1,157 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ * Copyright (C) 2004-2005 Max Howell <max.howell@methylblue.com>
+ *
+ * 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.
+ */
+
+#ifndef KFTPWIDGETSSIDEBAR_H
+#define KFTPWIDGETSSIDEBAR_H
+
+#include <qwidget.h>
+#include <qvaluevector.h>
+
+class KURL;
+class QSignalMapper;
+class QVBox;
+
+namespace KFTPWidgets {
+
+typedef QValueVector<QWidget*> SidebarList;
+
+class MultiTabBar;
+class MultiTabBarTab;
+
+/**
+ * This class provides a sidebar. It uses a customised version of KMultiTabBar for
+ * displaying the actual tabs. It uses a QSignalMapper to map signals from the
+ * tabs to the actual sidebars.
+ *
+ * This class was copied from amaroK (BrowserBar) and modified to support bottom
+ * sidebars as well.
+ *
+ * @author amaroK developers
+ * @author Jernej Kos
+ */
+class Sidebar : public QWidget
+{
+Q_OBJECT
+friend class Splitter;
+public:
+ enum Position {
+ Left,
+ Bottom
+ };
+
+ Sidebar(QWidget *parent, Position position);
+ ~Sidebar();
+
+ /**
+ * Toggle visibility of this sidebar.
+ *
+ * @param visible True if the sidbar should be visible, false otherwise
+ */
+ void setVisible(bool visible);
+
+ /**
+ * Returns the content box of the sidebar. This should be where the widget, that
+ * should be resized when the sidebar resizes, should be placed.
+ *
+ * @return A QVBox container widget
+ */
+ QVBox *content() { return m_content; }
+
+ /**
+ * Returns the sidebar by it's name.
+ *
+ * @param name The sidebar's name
+ * @return A QWidget representing the sidebar or NULL if it is not found
+ */
+ QWidget *sidebar(const QString &name) const;
+
+ /**
+ * Returns the sidebar by it's index.
+ *
+ * @param index The sidebar's index
+ * @return A QWidget representing the sidebar or NULL if the index is invalid
+ */
+ QWidget *sidebar(int index) const { if (index < 0) index = 0; return m_sidebars[index]; }
+
+ /**
+ * Returns the currently open sidebar.
+ *
+ * @return A QWidget representing the current sidebar
+ */
+ QWidget *currentSidebar() const { return sidebar(m_currentIndex); }
+
+ /**
+ * Adds a new sidebar widget.
+ *
+ * @param widget The widget to add
+ * @param title The title that will be displayed on the tab
+ * @param icon Name of the icon that will be displayed besides the title
+ */
+ void addSidebar(QWidget *widget, const QString &title, const QString &icon);
+protected:
+ virtual void polish();
+ virtual bool event(QEvent *e);
+public slots:
+ void showSidebar(const QString &name) { showSidebar(indexForName(name)); }
+ void showSidebar(int index) { if (index != m_currentIndex) showHideSidebar(index); }
+ void showHideSidebar(int);
+ void closeCurrentSidebar() { showHideSidebar(m_currentIndex); }
+private:
+ int indexForName(const QString&) const;
+ void mouseMovedOverSplitter(QMouseEvent *e);
+
+ void adjustWidgetSizes();
+ uint maxSidebarWidth() const { return width() / 2; }
+ uint maxSidebarHeight() const { return height() / 2; }
+
+ Position m_position;
+ uint m_pos;
+
+ QWidget *m_divider;
+ QVBox *m_content;
+ MultiTabBar *m_tabBar;
+ QWidget *m_sidebarBox;
+
+ SidebarList m_sidebars;
+ int m_currentIndex;
+ int m_lastIndex;
+
+ QSignalMapper *m_mapper;
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/systemtray.cpp b/kftpgrabber/src/widgets/systemtray.cpp
new file mode 100644
index 0000000..98179b7
--- /dev/null
+++ b/kftpgrabber/src/widgets/systemtray.cpp
@@ -0,0 +1,123 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 <kpopupmenu.h>
+#include <klocale.h>
+#include <kwin.h>
+
+#include "widgets/systemtray.h"
+#include "widgets/balloon.h"
+#include "mainwindow.h"
+#include "mainactions.h"
+#include "kftpbookmarks.h"
+#include "kftpqueue.h"
+#include "misc.h"
+#include "misc/config.h"
+
+using namespace KFTPGrabberBase;
+
+namespace KFTPWidgets {
+
+SystemTray *SystemTray::m_self = 0L;
+
+SystemTray::SystemTray(MainWindow *parent)
+ : KSystemTray(parent),
+ m_balloon(0),
+ m_actions(parent->getActions())
+{
+ m_self = this;
+
+ // Set icon and show it
+ setPixmap(loadToolbarPixmap("kftpgrabber"));
+
+ if (KFTPCore::Config::showSystrayIcon())
+ show();
+
+ // Add some actions
+ m_bookmarkMenu = new KActionMenu(i18n("Bookmarks"));
+ slotUpdateBookmarks();
+
+ // Let our bookmarks be up to date
+ connect(KFTPBookmarks::Manager::self(), SIGNAL(update()), this, SLOT(slotUpdateBookmarks()));
+
+ m_actions->m_fileConnectAction->plug(contextMenu(), 1);
+ m_bookmarkMenu->plug(contextMenu(), 1);
+
+ // Ensure that we actually quit
+ connect(this, SIGNAL(quitSelected()), this, SLOT(slotQuitSelected()));
+}
+
+SystemTray::~SystemTray()
+{
+ delete m_bookmarkMenu;
+}
+
+void SystemTray::slotQuitSelected()
+{
+ m_actions->m_closeApp = true;
+}
+
+void SystemTray::slotUpdateBookmarks()
+{
+ // Re-create the bookmarks menu
+ m_bookmarkMenu->popupMenu()->clear();
+ KFTPBookmarks::Manager::self()->guiPopulateBookmarksMenu(m_bookmarkMenu, QDomNode(), false);
+}
+
+void SystemTray::showBalloon(const QString &text)
+{
+ // Create a little modified Kopete balloon
+ if (m_balloon) {
+ m_balloon->hide();
+ delete m_balloon;
+ }
+
+ m_balloon = new Balloon("<qt><nobr><b>KFTPGrabber</b><br>" + text + "</nobr></qt>", "info");
+ m_balloon->setAnchor(mapToGlobal(pos()));
+ m_balloon->show();
+ KWin::setOnAllDesktops(m_balloon->winId() , true);
+
+ // Hide the balloon after 5 sec
+ QTimer::singleShot(5000, this, SLOT(slotHideBalloon()));
+}
+
+void SystemTray::slotHideBalloon()
+{
+ m_balloon->hide();
+}
+
+}
+
+#include "systemtray.moc"
diff --git a/kftpgrabber/src/widgets/systemtray.h b/kftpgrabber/src/widgets/systemtray.h
new file mode 100644
index 0000000..ce77811
--- /dev/null
+++ b/kftpgrabber/src/widgets/systemtray.h
@@ -0,0 +1,93 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPWIDGETSSYSTEMTRAY_H
+#define KFTPWIDGETSSYSTEMTRAY_H
+
+#include <ksystemtray.h>
+#include <kaction.h>
+
+#include <qmenudata.h>
+
+class MainWindow;
+class MainActions;
+
+namespace KFTPWidgets {
+
+class Balloon;
+
+/**
+ * A system tray icon that is used for some actions.
+ *
+ * @author Jernej Kos
+ */
+class SystemTray : public KSystemTray
+{
+Q_OBJECT
+public:
+ /**
+ * Get the global system tray instance.
+ */
+ static SystemTray *self() { return SystemTray::m_self; }
+
+ /**
+ * Class constructor.
+ */
+ SystemTray(MainWindow *parent);
+
+ /**
+ * Class destructor.
+ */
+ ~SystemTray();
+
+ /**
+ * Show a balloon notification widget.
+ */
+ void showBalloon(const QString &text);
+protected:
+ static SystemTray *m_self;
+private:
+ KActionMenu *m_bookmarkMenu;
+ Balloon *m_balloon;
+ MainActions *m_actions;
+private slots:
+ void slotHideBalloon();
+ void slotUpdateBookmarks();
+ void slotQuitSelected();
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/trafficgraph.cpp b/kftpgrabber/src/widgets/trafficgraph.cpp
new file mode 100644
index 0000000..ddd339f
--- /dev/null
+++ b/kftpgrabber/src/widgets/trafficgraph.cpp
@@ -0,0 +1,628 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2004 by the KFTPGrabber developers
+ * Copyright (C) 2003-2004 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 <math.h>
+#include <string.h>
+
+#include <qpainter.h>
+#include <qpixmap.h>
+
+#include <klocale.h>
+
+#include "trafficgraph.h"
+
+namespace KFTPWidgets {
+
+static inline int min(int a, int b)
+{
+ return (a < b ? a : b);
+}
+
+TrafficGraph::TrafficGraph(QWidget *parent, const char *name)
+ : QWidget(parent, name)
+{
+ // Auto deletion does not work for pointer to arrays.
+ m_beamData.setAutoDelete(false);
+
+ setBackgroundMode(NoBackground);
+
+ m_samples = 0;
+ m_minValue = m_maxValue = 0.0;
+ m_useAutoRange = true;
+
+ m_graphStyle = GRAPH_POLYGON;
+
+ // Anything smaller than this does not make sense.
+ setMinimumSize(16, 100);
+ setSizePolicy(QSizePolicy(QSizePolicy::Expanding,
+ QSizePolicy::Expanding, false));
+
+ m_showVerticalLines = true;
+ m_verticalLinesColor = QColor(0x04FB1D);
+ m_verticalLinesDistance = 30;
+ m_verticalLinesScroll = true;
+ m_verticalLinesOffset = 0;
+ m_horizontalScale = 1;
+
+ m_showHorizontalLines = true;
+ m_horizontalLinesColor = QColor(0x04FB1D);
+ m_horizontalLinesCount = 5;
+
+ m_showLabels = true;
+ m_showTopBar = false;
+ m_fontSize = 8;
+
+ m_backgroundColor = QColor(0x313031);
+}
+
+
+TrafficGraph::~TrafficGraph()
+{
+ for (double* p = m_beamData.first(); p; p = m_beamData.next())
+ delete [] p;
+}
+
+bool TrafficGraph::addBeam(const QColor &color)
+{
+ double* d = new double[m_samples];
+ memset(d, 0, sizeof(double) * m_samples);
+ m_beamData.append(d);
+ m_beamColor.append(color);
+
+ return true;
+}
+
+void TrafficGraph::addSample(const QValueList<double>& sampleBuf)
+{
+ if (m_beamData.count() != sampleBuf.count())
+ return;
+
+ double* d;
+ if (m_useAutoRange) {
+ double sum = 0;
+ for (d = m_beamData.first(); d; d = m_beamData.next()) {
+ sum += d[0];
+ if (sum < m_minValue)
+ m_minValue = sum;
+ if (sum > m_maxValue)
+ m_maxValue = sum;
+ }
+ }
+
+ /* If the vertical lines are scrolling, increment the offset
+ * so they move with the data. The vOffset / hScale confusion
+ * is because v refers to Vertical Lines, and h to the horizontal
+ * distance between the vertical lines. */
+ if (m_verticalLinesScroll) {
+ m_verticalLinesOffset = (m_verticalLinesOffset + m_horizontalScale)
+ % m_verticalLinesDistance;
+ }
+
+ // Shift data buffers one sample down and insert new samples.
+ QValueList<double>::ConstIterator s;
+ for (d = m_beamData.first(), s = sampleBuf.begin(); d; d = m_beamData.next(), ++s) {
+ memmove(d, d + 1, (m_samples - 1) * sizeof(double));
+ d[m_samples - 1] = *s;
+ }
+
+ update();
+}
+
+void TrafficGraph::changeRange(int beam, double min, double max)
+{
+ // Only the first beam affects range calculation.
+ if (beam > 1)
+ return;
+
+ m_minValue = min;
+ m_maxValue = max;
+}
+
+QValueList<QColor> &TrafficGraph::beamColors()
+{
+ return m_beamColor;
+}
+
+void TrafficGraph::removeBeam(uint pos)
+{
+ m_beamColor.remove(m_beamColor.at(pos));
+ m_beamData.remove(pos);
+}
+
+void TrafficGraph::setUseAutoRange(bool value)
+{
+ m_useAutoRange = value;
+}
+
+bool TrafficGraph::useAutoRange() const
+{
+ return m_useAutoRange;
+}
+
+void TrafficGraph::setMinValue(double min)
+{
+ m_minValue = min;
+}
+
+double TrafficGraph::minValue() const
+{
+ return (m_useAutoRange ? 0 : m_minValue);
+}
+
+void TrafficGraph::setMaxValue(double max)
+{
+ m_maxValue = max;
+}
+
+double TrafficGraph::maxValue() const
+{
+ return (m_useAutoRange ? 0 : m_maxValue);
+}
+
+void TrafficGraph::setGraphStyle(uint style)
+{
+ m_graphStyle = style;
+}
+
+uint TrafficGraph::graphStyle() const
+{
+ return m_graphStyle;
+}
+
+void TrafficGraph::setHorizontalScale(uint scale)
+{
+ if (scale == m_horizontalScale)
+ return;
+
+ m_horizontalScale = scale;
+ if (isVisible())
+ updateDataBuffers();
+}
+
+uint TrafficGraph::horizontalScale() const
+{
+ return m_horizontalScale;
+}
+
+void TrafficGraph::setShowVerticalLines(bool value)
+{
+ m_showVerticalLines = value;
+}
+
+bool TrafficGraph::showVerticalLines() const
+{
+ return m_showVerticalLines;
+}
+
+void TrafficGraph::setVerticalLinesColor(const QColor &color)
+{
+ m_verticalLinesColor = color;
+}
+
+QColor TrafficGraph::verticalLinesColor() const
+{
+ return m_verticalLinesColor;
+}
+
+void TrafficGraph::setVerticalLinesDistance(int distance)
+{
+ m_verticalLinesDistance = distance;
+}
+
+int TrafficGraph::verticalLinesDistance() const
+{
+ return m_verticalLinesDistance;
+}
+
+void TrafficGraph::setVerticalLinesScroll(bool value)
+{
+ m_verticalLinesScroll = value;
+}
+
+bool TrafficGraph::verticalLinesScroll() const
+{
+ return m_verticalLinesScroll;
+}
+
+void TrafficGraph::setShowHorizontalLines(bool value)
+{
+ m_showHorizontalLines = value;
+}
+
+bool TrafficGraph::showHorizontalLines() const
+{
+ return m_showHorizontalLines;
+}
+
+void TrafficGraph::setHorizontalLinesColor(const QColor &color)
+{
+ m_horizontalLinesColor = color;
+}
+
+QColor TrafficGraph::horizontalLinesColor() const
+{
+ return m_horizontalLinesColor;
+}
+
+void TrafficGraph::setHorizontalLinesCount(int count)
+{
+ m_horizontalLinesCount = count;
+}
+
+int TrafficGraph::horizontalLinesCount() const
+{
+ return m_horizontalLinesCount;
+}
+
+void TrafficGraph::setShowLabels(bool value)
+{
+ m_showLabels = value;
+}
+
+bool TrafficGraph::showLabels() const
+{
+ return m_showLabels;
+}
+
+void TrafficGraph::setShowTopBar(bool value)
+{
+ m_showTopBar = value;
+}
+
+bool TrafficGraph::showTopBar() const
+{
+ return m_showTopBar;
+}
+
+void TrafficGraph::setFontSize(int size)
+{
+ m_fontSize = size;
+}
+
+int TrafficGraph::fontSize() const
+{
+ return m_fontSize;
+}
+
+void TrafficGraph::setBackgroundColor(const QColor &color)
+{
+ m_backgroundColor = color;
+}
+
+QColor TrafficGraph::backgroundColor() const
+{
+ return m_backgroundColor;
+}
+
+void TrafficGraph::resizeEvent(QResizeEvent*)
+{
+ updateDataBuffers();
+}
+
+void TrafficGraph::updateDataBuffers()
+{
+ /* Since the data buffers for the beams are equal in size to the
+ * width of the widget minus 2 we have to enlarge or shrink the
+ * buffers accordingly when a resize occures. To have a nicer
+ * display we try to keep as much data as possible. Data that is
+ * lost due to shrinking the buffers cannot be recovered on
+ * enlarging though. */
+
+ /* Determine new number of samples first.
+ * +0.5 to ensure rounding up
+ * +2 for extra data points so there is
+ * 1) no wasted space and
+ * 2) no loss of precision when drawing the first data point. */
+ uint newSampleNum = static_cast<uint>(((width() - 2 ) / m_horizontalScale) + 2.5);
+
+ // overlap between the old and the new buffers.
+ int overlap = min(m_samples, newSampleNum);
+
+ for (uint i = 0; i < m_beamData.count(); ++i) {
+ double* nd = new double[newSampleNum];
+
+ // initialize new part of the new buffer
+ if (newSampleNum > (uint) overlap)
+ memset(nd, 0, sizeof(double) * (newSampleNum - overlap));
+
+ // copy overlap from old buffer to new buffer
+ memcpy(nd + (newSampleNum - overlap), m_beamData.at(i) + (m_samples - overlap), overlap * sizeof(double));
+
+ m_beamData.remove(i);
+ m_beamData.insert(i, nd);
+ }
+
+ m_samples = newSampleNum;
+}
+
+void TrafficGraph::paintEvent(QPaintEvent*)
+{
+ uint w = width();
+ uint h = height();
+
+ /* Do not do repaints when the widget is not yet setup properly. */
+ if (w <= 2)
+ return;
+
+ QPixmap pm(w, h);
+ QPainter p;
+ p.begin(&pm, this);
+
+ pm.fill(m_backgroundColor);
+ /* Draw white line along the bottom and the right side of the
+ * widget to create a 3D like look. */
+ p.setPen(QColor(colorGroup().light()));
+ p.drawLine(0, h - 1, w - 1, h - 1);
+ p.drawLine(w - 1, 0, w - 1, h - 1);
+
+ p.setClipRect(1, 1, w - 2, h - 2);
+ double range = m_maxValue - m_minValue;
+
+ /* If the range is too small we will force it to 1.0 since it
+ * looks a lot nicer. */
+ if (range < 0.000001)
+ range = 1.0;
+
+ double minValue = m_minValue;
+ if (m_useAutoRange) {
+ if (m_minValue != 0.0) {
+ double dim = pow(10, floor(log10(fabs(m_minValue )))) / 2;
+ if (m_minValue < 0.0)
+ minValue = dim * floor(m_minValue / dim);
+ else
+ minValue = dim * ceil(m_minValue / dim);
+ range = m_maxValue - minValue;
+ if (range < 0.000001)
+ range = 1.0;
+ }
+
+ // Massage the range so that the grid shows some nice values.
+ double step = range / m_horizontalLinesCount;
+ double dim = pow(10, floor(log10(step))) / 2;
+ range = dim * ceil(step / dim) * m_horizontalLinesCount;
+ }
+
+ double maxValue = minValue + range;
+
+ int top = 0;
+ if (m_showTopBar && h > (m_fontSize + 2 + m_horizontalLinesCount * 10)) {
+ /* Draw horizontal bar with current sensor values at top of display. */
+ p.setPen(m_horizontalLinesColor);
+ int x0 = w / 2;
+ p.setFont(QFont(p.font().family(), m_fontSize));
+ top = p.fontMetrics().height();
+ h -= top;
+ int h0 = top - 2;
+ p.drawText(0, 0, x0, top - 2, Qt::AlignCenter, i18n("Bandwidth usage"));
+
+ p.drawLine(x0 - 1, 1, x0 - 1, h0);
+ p.drawLine(0, top - 1, w - 2, top - 1);
+
+ double bias = -minValue;
+ double scaleFac = ( w - x0 - 2 ) / range;
+ QValueList<QColor>::Iterator col;
+ col = m_beamColor.begin();
+
+ for (double *d = m_beamData.first(); d; d = m_beamData.next(), ++col) {
+ int start = x0 + (int) (bias * scaleFac);
+ int end = x0 + (int) ((bias += d[ w - 3 ]) * scaleFac);
+
+ /* If the rect is wider than 2 pixels we draw only the last
+ * pixels with the bright color. The rest is painted with
+ * a 50% darker color. */
+ if (end - start > 1) {
+ p.setPen((*col).dark(150));
+ p.setBrush((*col).dark(150));
+ p.drawRect(start, 1, end - start, h0);
+ p.setPen(*col);
+ p.drawLine(end, 1, end, h0);
+ } else if (start - end > 1) {
+ p.setPen((*col).dark(150));
+ p.setBrush((*col).dark(150));
+ p.drawRect(end, 1, start - end, h0);
+ p.setPen(*col);
+ p.drawLine(end, 1, end, h0);
+ } else {
+ p.setPen(*col);
+ p.drawLine(start, 1, start, h0);
+ }
+ }
+ }
+
+ /* Draw scope-like grid vertical lines */
+ if (m_showVerticalLines && w > 60) {
+ p.setPen(m_verticalLinesColor);
+ for (uint x = m_verticalLinesOffset; x < (w - 2); x += m_verticalLinesDistance)
+ p.drawLine(w - x, top, w - x, h + top - 2);
+ }
+
+ /* In autoRange mode we determine the range and plot the values in
+ * one go. This is more efficiently than running through the
+ * buffers twice but we do react on recently discarded samples as
+ * well as new samples one plot too late. So the range is not
+ * correct if the recently discarded samples are larger or smaller
+ * than the current extreme values. But we can probably live with
+ * this. */
+ if (m_useAutoRange)
+ m_minValue = m_maxValue = 0.0;
+
+ /* Plot stacked values */
+ double scaleFac = (h - 2) / range;
+ if (m_graphStyle == GRAPH_ORIGINAL) {
+ int xPos = 0;
+
+ for (int i = 0; i < m_samples; i++, xPos += m_horizontalScale) {
+ double bias = -minValue;
+ QValueList<QColor>::Iterator col;
+ col = m_beamColor.begin();
+ double sum = 0.0;
+
+ for (double *d = m_beamData.first(); d; d = m_beamData.next(), ++col) {
+ if (m_useAutoRange) {
+ sum += d[i];
+ if (sum < m_minValue)
+ m_minValue = sum;
+ if (sum > m_maxValue)
+ m_maxValue = sum;
+ }
+
+ int start = top + h - 2 - (int) (bias * scaleFac);
+ int end = top + h - 2 - (int) ((bias + d[ i ] ) * scaleFac);
+ bias += d[i];
+
+ /* If the line is longer than 2 pixels we draw only the last
+ * 2 pixels with the bright color. The rest is painted with
+ * a 50% darker color. */
+ if (end - start > 2) {
+ p.fillRect(xPos, start, m_horizontalScale, end - start - 1, (*col).dark(150));
+ p.fillRect(xPos, end - 1, m_horizontalScale, 2, *col);
+ } else if (start - end > 2) {
+ p.fillRect(xPos, start, m_horizontalScale, end - start + 1, (*col).dark(150));
+ p.fillRect(xPos, end + 1, m_horizontalScale, 2, *col);
+ } else
+ p.fillRect(xPos, start, m_horizontalScale, end - start, *col);
+
+ }
+ }
+ } else if (m_graphStyle == GRAPH_POLYGON) {
+ int *prevVals = new int[m_beamData.count()];
+ int hack[4];
+ int x1 = w - ((m_samples + 1) * m_horizontalScale);
+
+ for (int i = 0; i < m_samples; i++) {
+ QValueList<QColor>::Iterator col;
+ col = m_beamColor.begin();
+ double sum = 0.0;
+ int y = top + h - 2;
+ int oldY = top + h;
+ int oldPrevY = oldY;
+ int height = 0;
+ int j = 0;
+ int jMax = m_beamData.count() - 1;
+ x1 += m_horizontalScale;
+ int x2 = x1 + m_horizontalScale;
+
+ for (double *d = m_beamData.first(); d; d = m_beamData.next(), ++col, j++) {
+ if (m_useAutoRange) {
+ sum += d[i];
+
+ if ( sum < m_minValue )
+ m_minValue = sum;
+ if ( sum > m_maxValue )
+ m_maxValue = sum;
+ }
+
+ height = (int) ((d[i] - minValue) * scaleFac);
+ y -= height;
+
+ /* If the line is longer than 2 pixels we draw only the last
+ * 2 pixels with the bright color. The rest is painted with
+ * a 50% darker color. */
+ QPen lastPen = QPen(p.pen());
+ p.setPen((*col).dark(150));
+ p.setBrush((*col).dark(150));
+ QPointArray pa(4);
+ int prevY = (i == 0) ? y : prevVals[j];
+ pa.putPoints(0, 1, x1, prevY);
+ pa.putPoints(1, 1, x2, y);
+ pa.putPoints(2, 1, x2, oldY);
+ pa.putPoints(3, 1, x1, oldPrevY);
+ p.drawPolygon(pa);
+ p.setPen(lastPen);
+ if (jMax == 0) {
+ // draw as normal, no deferred drawing req'd.
+ p.setPen(*col);
+ p.drawLine(x1, prevY, x2, y);
+ } else if (j == jMax) {
+ // draw previous values and current values
+ p.drawLine(hack[0], hack[1], hack[2], hack[3]);
+ p.setPen(*col);
+ p.drawLine(x1, prevY, x2, y);
+ } else if (j == 0) {
+ // save values only
+ hack[0] = x1;
+ hack[1] = prevY;
+ hack[2] = x2;
+ hack[3] = y;
+ p.setPen(*col);
+ } else {
+ p.drawLine(hack[0], hack[1], hack[2], hack[3]);
+ hack[0] = x1;
+ hack[1] = prevY;
+ hack[2] = x2;
+ hack[3] = y;
+ p.setPen(*col);
+ }
+
+ prevVals[j] = y;
+ oldY = y;
+ oldPrevY = prevY;
+ }
+ }
+
+ delete[] prevVals;
+ }
+
+ /* Draw horizontal lines and values. Lines are drawn when the
+ * height is greater than 10 times hCount + 1, values are shown
+ * when width is greater than 60 */
+ if (m_showHorizontalLines && h > (10 * (m_horizontalLinesCount + 1))) {
+ p.setPen(m_horizontalLinesColor);
+ p.setFont(QFont(p.font().family(), m_fontSize));
+ QString val;
+
+ for (uint y = 1; y < m_horizontalLinesCount; y++) {
+ p.drawLine(0, top + y * (h / m_horizontalLinesCount), w - 2, top + y * (h / m_horizontalLinesCount));
+
+ if (m_showLabels && h > (m_fontSize + 1) * (m_horizontalLinesCount + 1) && w > 60 ) {
+ val = QString("%1").arg(maxValue - y * (range / m_horizontalLinesCount));
+ p.drawText(6, top + y * (h / m_horizontalLinesCount) - 1, val);
+ }
+ }
+
+ if (m_showLabels && h > (m_fontSize + 1) * (m_horizontalLinesCount + 1) && w > 60) {
+ val = QString("%1").arg(minValue);
+ p.drawText(6, top + h - 2, val);
+ }
+ }
+
+ p.end();
+ bitBlt(this, 0, 0, &pm);
+}
+
+}
+
+#include "trafficgraph.moc"
diff --git a/kftpgrabber/src/widgets/trafficgraph.h b/kftpgrabber/src/widgets/trafficgraph.h
new file mode 100644
index 0000000..3822165
--- /dev/null
+++ b/kftpgrabber/src/widgets/trafficgraph.h
@@ -0,0 +1,155 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+#ifndef KFTPTRAFFICGRAPH_H
+#define KFTPTRAFFICGRAPH_H
+
+#include <qpoint.h>
+#include <qdialog.h>
+#include <qptrlist.h>
+#include <qstring.h>
+#include <qvaluelist.h>
+
+#define GRAPH_POLYGON 0
+#define GRAPH_ORIGINAL 1
+
+class QColor;
+
+namespace KFTPWidgets {
+
+/**
+@author Jernej Kos
+*/
+class TrafficGraph : public QWidget
+{
+Q_OBJECT
+public:
+ TrafficGraph(QWidget *parent = 0, const char *name = 0);
+ ~TrafficGraph();
+
+ bool addBeam(const QColor &color);
+ void addSample(const QValueList<double> &samples);
+
+ void removeBeam(uint pos);
+
+ void changeRange(int beam, double min, double max);
+
+ QValueList<QColor> &beamColors();
+
+ void setUseAutoRange(bool value);
+ bool useAutoRange() const;
+
+ void setMinValue(double min);
+ double minValue() const;
+
+ void setMaxValue(double max);
+ double maxValue() const;
+
+ void setGraphStyle(uint style);
+ uint graphStyle() const;
+
+ void setHorizontalScale(uint scale);
+ uint horizontalScale() const;
+
+ void setShowVerticalLines(bool value);
+ bool showVerticalLines() const;
+
+ void setVerticalLinesColor(const QColor &color);
+ QColor verticalLinesColor() const;
+
+ void setVerticalLinesDistance(int distance);
+ int verticalLinesDistance() const;
+
+ void setVerticalLinesScroll(bool value);
+ bool verticalLinesScroll() const;
+
+ void setShowHorizontalLines(bool value);
+ bool showHorizontalLines() const;
+
+ void setHorizontalLinesColor(const QColor &color);
+ QColor horizontalLinesColor() const;
+
+ void setHorizontalLinesCount(int count);
+ int horizontalLinesCount() const;
+
+ void setShowLabels(bool value);
+ bool showLabels() const;
+
+ void setShowTopBar(bool value);
+ bool showTopBar() const;
+
+ void setFontSize(int size);
+ int fontSize() const;
+
+ void setBackgroundColor(const QColor &color);
+ QColor backgroundColor() const;
+protected:
+ void updateDataBuffers();
+
+ virtual void resizeEvent(QResizeEvent*);
+ virtual void paintEvent(QPaintEvent*);
+private:
+ double m_minValue;
+ double m_maxValue;
+ bool m_useAutoRange;
+
+ uint m_graphStyle;
+
+ bool m_showVerticalLines;
+ QColor m_verticalLinesColor;
+ uint m_verticalLinesDistance;
+ bool m_verticalLinesScroll;
+ uint m_verticalLinesOffset;
+ uint m_horizontalScale;
+
+ bool m_showHorizontalLines;
+ QColor m_horizontalLinesColor;
+ uint m_horizontalLinesCount;
+
+ bool m_showLabels;
+ bool m_showTopBar;
+ uint m_fontSize;
+
+ QColor m_backgroundColor;
+
+ QPtrList<double> m_beamData;
+ QValueList<QColor> m_beamColor;
+
+ int m_samples;
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/verifier.cpp b/kftpgrabber/src/widgets/verifier.cpp
new file mode 100644
index 0000000..1f6c9d9
--- /dev/null
+++ b/kftpgrabber/src/widgets/verifier.cpp
@@ -0,0 +1,148 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "verifier.h"
+#include "misc.h"
+#include "listviewitem.h"
+
+#include <klocale.h>
+#include <klistview.h>
+#include <kmessagebox.h>
+#include <kprogress.h>
+#include <kurl.h>
+
+#include <qheader.h>
+#include <qlabel.h>
+
+// UI layouts
+#include "ui/checksum_verifier.h"
+
+using namespace KFTPGrabberBase;
+
+namespace KFTPWidgets {
+
+Verifier::Verifier(QWidget *parent, const char *name)
+ : KDialogBase(parent, name, true, i18n("Checksum verifier"), Cancel, Cancel, true),
+ m_verifier(0)
+{
+ m_layout = new VerifierLayout(this);
+ setMainWidget(m_layout);
+
+ // Create columns
+ m_layout->fileList->addColumn(i18n("Filename"));
+ m_layout->fileList->addColumn(i18n("Checksum"), 100);
+
+ m_layout->fileList->setAllColumnsShowFocus(true);
+ m_layout->fileList->header()->setStretchEnabled(true, 0);
+}
+
+Verifier::~Verifier()
+{
+ if (m_verifier)
+ delete m_verifier;
+}
+
+void Verifier::setFile(const QString &filename)
+{
+ // Create the verifier
+ m_verifier = new KFTPCore::ChecksumVerifier(filename);
+ m_layout->currentFile->setText(KURL(filename).fileName());
+
+ connect(m_verifier, SIGNAL(fileList(QValueList<QPair<QString, QString> >)), this, SLOT(slotHaveFileList(QValueList<QPair<QString, QString> >)));
+ connect(m_verifier, SIGNAL(fileDone(const QString&, KFTPCore::ChecksumVerifier::Result)), this, SLOT(slotFileDone(const QString&, KFTPCore::ChecksumVerifier::Result)));
+ connect(m_verifier, SIGNAL(progress(int)), this, SLOT(slotProgress(int)));
+ connect(m_verifier, SIGNAL(error()), this, SLOT(slotError()));
+
+ // Start the verification
+ m_verifier->verify();
+}
+
+void Verifier::slotHaveFileList(QValueList<QPair<QString, QString> > list)
+{
+ for (QValueList<QPair<QString, QString> >::iterator i = list.begin(); i != list.end(); ++i) {
+ KFTPWidgets::ListViewItem *item = new KFTPWidgets::ListViewItem(m_layout->fileList);
+ item->setText(0, (*i).first);
+ item->setText(1, (*i).second);
+ }
+}
+
+void Verifier::slotFileDone(const QString &filename, KFTPCore::ChecksumVerifier::Result result)
+{
+ KFTPWidgets::ListViewItem *item = static_cast<KFTPWidgets::ListViewItem*>(m_layout->fileList->findItem(filename, 0));
+
+ if (item) {
+ switch (result) {
+ case KFTPCore::ChecksumVerifier::Ok: {
+ item->setPixmap(0, loadSmallPixmap("ok"));
+ item->setTextColor(0, QColor(0, 200, 0));
+ item->setTextColor(1, QColor(0, 200, 0));
+ break;
+ }
+ case KFTPCore::ChecksumVerifier::NotFound: {
+ item->setPixmap(0, loadSmallPixmap("error"));
+ item->setTextColor(0, QColor(128, 128, 128));
+ item->setTextColor(1, QColor(128, 128, 128));
+ break;
+ }
+ case KFTPCore::ChecksumVerifier::Error: {
+ item->setPixmap(0, loadSmallPixmap("error"));
+ item->setTextColor(0, QColor(255, 0, 0));
+ item->setTextColor(1, QColor(255, 0, 0));
+ break;
+ }
+ }
+
+ m_layout->fileList->ensureItemVisible(item);
+ }
+}
+
+void Verifier::slotProgress(int percent)
+{
+ m_layout->checkProgress->setProgress(percent);
+
+ if (percent == 100) {
+ KMessageBox::information(0, i18n("Verification complete!"));
+ }
+}
+
+void Verifier::slotError()
+{
+ KMessageBox::error(0, i18n("Unable to open checksum file or file has an incorrect format!"));
+ close();
+}
+
+}
+#include "verifier.moc"
diff --git a/kftpgrabber/src/widgets/verifier.h b/kftpgrabber/src/widgets/verifier.h
new file mode 100644
index 0000000..6f1ee1e
--- /dev/null
+++ b/kftpgrabber/src/widgets/verifier.h
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2005 by the KFTPGrabber developers
+ * Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+
+#ifndef KFTPWIDGETSVERIFIER_H
+#define KFTPWIDGETSVERIFIER_H
+
+#include "checksumverifier.h"
+
+#include <kdialogbase.h>
+
+#include <qvaluelist.h>
+#include <qpair.h>
+
+class VerifierLayout;
+
+namespace KFTPWidgets {
+
+/**
+ * @author Jernej Kos
+ */
+class Verifier : public KDialogBase
+{
+Q_OBJECT
+public:
+ Verifier(QWidget *parent = 0, const char *name = 0);
+ ~Verifier();
+
+ void setFile(const QString &filename);
+private:
+ VerifierLayout *m_layout;
+ KFTPCore::ChecksumVerifier *m_verifier;
+private slots:
+ void slotHaveFileList(QValueList<QPair<QString, QString> > list);
+ void slotFileDone(const QString &filename, KFTPCore::ChecksumVerifier::Result result);
+ void slotProgress(int percent);
+ void slotError();
+};
+
+}
+
+#endif
diff --git a/kftpgrabber/src/widgets/widgetlister.cpp b/kftpgrabber/src/widgets/widgetlister.cpp
new file mode 100644
index 0000000..55022d2
--- /dev/null
+++ b/kftpgrabber/src/widgets/widgetlister.cpp
@@ -0,0 +1,172 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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 "widgetlister.h"
+
+#include <klocale.h>
+#include <kguiitem.h>
+#include <kpushbutton.h>
+#include <kdialog.h>
+
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qhbox.h>
+
+namespace KFTPWidgets {
+
+WidgetLister::WidgetLister(QWidget *parent, int minWidgets, int maxWidgets)
+ : QWidget(parent)
+{
+ m_widgetList.setAutoDelete(true);
+
+ m_minWidgets = QMAX(minWidgets, 0);
+ m_maxWidgets = QMAX(maxWidgets, m_minWidgets + 1);
+
+ // The button box
+ m_layout = new QVBoxLayout(this, 0, 4);
+ m_buttonBox = new QHBox(this);
+ m_buttonBox->setSpacing(KDialog::spacingHint());
+ m_layout->addWidget(m_buttonBox);
+
+ m_buttonMore = new KPushButton(KGuiItem(i18n("more widgets", "More"), "button_more"), m_buttonBox);
+ m_buttonBox->setStretchFactor(m_buttonMore, 0);
+
+ m_buttonFewer = new KPushButton(KGuiItem(i18n("fewer widgets", "Fewer"), "button_fewer"), m_buttonBox);
+ m_buttonBox->setStretchFactor(m_buttonFewer, 0);
+
+ QWidget *spacer = new QWidget(m_buttonBox);
+ m_buttonBox->setStretchFactor(spacer, 1);
+
+ m_buttonClear = new KPushButton(KGuiItem(i18n("clear widgets", "Clear"), "locationbar_erase"), m_buttonBox);
+ m_buttonBox->setStretchFactor(m_buttonClear, 0);
+
+ // Connect signals
+ connect(m_buttonMore, SIGNAL(clicked()), this, SLOT(slotMore()));
+ connect(m_buttonFewer, SIGNAL(clicked()), this, SLOT(slotFewer()));
+ connect(m_buttonClear, SIGNAL(clicked()), this, SLOT(slotClear()));
+
+ enableControls();
+}
+
+WidgetLister::~WidgetLister()
+{
+}
+
+void WidgetLister::slotMore()
+{
+ addWidget();
+ enableControls();
+}
+
+void WidgetLister::slotFewer()
+{
+ removeWidget();
+ enableControls();
+}
+
+void WidgetLister::clear()
+{
+ setNumberShown(m_minWidgets);
+
+ // Clear remaining widgets
+ QPtrListIterator<QWidget> i(m_widgetList);
+ for (i.toFirst(); i.current(); ++i)
+ clearWidget((*i));
+
+ enableControls();
+ emit clearWidgets();
+}
+
+void WidgetLister::slotClear()
+{
+ clear();
+}
+
+void WidgetLister::addWidget(QWidget *widget)
+{
+ if (!widget)
+ widget = createWidget(this);
+
+ m_layout->insertWidget(m_layout->findWidget(m_buttonBox), widget);
+ m_widgetList.append(widget);
+ widget->show();
+
+ enableControls();
+ emit widgetAdded(widget);
+}
+
+void WidgetLister::removeWidget()
+{
+ m_widgetList.removeLast();
+
+ enableControls();
+ emit widgetRemoved();
+}
+
+void WidgetLister::clearWidget(QWidget *widget)
+{
+ Q_UNUSED(widget)
+}
+
+QWidget *WidgetLister::createWidget(QWidget* parent)
+{
+ return new QWidget(parent);
+}
+
+void WidgetLister::setNumberShown(int number)
+{
+ int superfluousWidgets = QMAX((int) m_widgetList.count() - number, 0);
+ int missingWidgets = QMAX(number - (int) m_widgetList.count(), 0);
+
+ // Remove superfluous widgets
+ for (; superfluousWidgets; superfluousWidgets--)
+ removeWidget();
+
+ // Add missing widgets
+ for (; missingWidgets; missingWidgets--)
+ addWidget();
+}
+
+void WidgetLister::enableControls()
+{
+ int count = m_widgetList.count();
+ bool isMaxWidgets = (count >= m_maxWidgets);
+ bool isMinWidgets = (count <= m_minWidgets);
+
+ m_buttonMore->setEnabled(!isMaxWidgets);
+ m_buttonFewer->setEnabled(!isMinWidgets);
+}
+
+}
diff --git a/kftpgrabber/src/widgets/widgetlister.h b/kftpgrabber/src/widgets/widgetlister.h
new file mode 100644
index 0000000..8aac58f
--- /dev/null
+++ b/kftpgrabber/src/widgets/widgetlister.h
@@ -0,0 +1,177 @@
+/*
+ * This file is part of the KFTPGrabber project
+ *
+ * Copyright (C) 2003-2006 by the KFTPGrabber developers
+ * Copyright (C) 2003-2006 Jernej Kos <kostko@jweb-network.net>
+ *
+ * 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.
+ */
+#ifndef KFTPWIDGETSWIDGETLISTER_H
+#define KFTPWIDGETSWIDGETLISTER_H
+
+#include <qwidget.h>
+#include <qptrlist.h>
+
+class QPushButton;
+class QVBoxLayout;
+class QHBox;
+
+namespace KFTPWidgets {
+
+/**
+ * This class has been adopted from KDEPIM with slight functional and style
+ * changes.
+ *
+ * @author Jernej Kos
+ * @author Marc Mutz <marc@mutz.com>
+ */
+class WidgetLister : public QWidget
+{
+Q_OBJECT
+public:
+ /**
+ * Class constructor.
+ *
+ * @param parent Parent widget
+ * @param minWidgets Minimum number of widgets in the list
+ * @param maxWidgets Maximum number of widgets in the list
+ */
+ WidgetLister(QWidget* parent, int minWidgets, int maxWidgets);
+
+ /**
+ * Class destructor.
+ */
+ virtual ~WidgetLister();
+
+ /**
+ * Clears all widgets.
+ */
+ void clear();
+
+ /**
+ * Sets the number of currently shown widgets on screen.
+ *
+ * @param number The number of widgets that should be visible
+ */
+ virtual void setNumberShown(int number);
+protected slots:
+ /**
+ * Called whenever the user clicks on the 'more' button. Reimplementations
+ * should call this method, because this implementation does all the dirty
+ * work with adding the widgets to the layout (through @ref addWidget)
+ * and enabling/disabling the control buttons.
+ */
+ virtual void slotMore();
+
+ /**
+ * Called whenever the user clicks on the 'fewer' button. Reimplementations
+ * should call this method, because this implementation does all the dirty
+ * work with removing the widgets from the layout (through @ref removeWidget)
+ * and enabling/disabling the control buttons.
+ */
+ virtual void slotFewer();
+
+ /**
+ * Called whenever the user clicks on the 'clear' button. Reimplementations
+ * should call this method, because this implementation does all the dirty
+ * work with removing all but @ref m_minWidgets widgets from the layout and
+ * enabling/disabling the control buttons.
+ */
+ virtual void slotClear();
+protected:
+ /**
+ * Adds a single widget. Doesn't care if there are already @ref m_maxWidgets
+ * on screen and whether it should enable/disable any controls. It simply does
+ * what it is asked to do. You want to reimplement this method if you want to
+ * initialize the the widget when showing it on screen. Make sure you call this
+ * implementaion, though, since you cannot put the widget on screen from derived
+ * classes (@p m_layout is private). Make sure the parent of the QWidget to add is
+ * this WidgetLister.
+ *
+ * @param widget The widget that should be added
+ */
+ virtual void addWidget(QWidget *widget = 0);
+
+ /**
+ * Removes a single (always the last) widget. Doesn't care if there are still only
+ * @ref m_minWidgets left on screen and whether it should enable/disable any controls.
+ * It simply does what it is asked to do. You want to reimplement this method if you
+ * want to save the the widget's state before removing it from screen. Make sure you
+ * call this implementaion, though, since you should not remove the widget from
+ * screen from derived classes.
+ */
+ virtual void removeWidget();
+
+ /**
+ * Called to clear a given widget. The default implementation does nothing.
+ *
+ * @param widget The widget that should be cleared
+ */
+ virtual void clearWidget(QWidget *widget);
+
+ /**
+ * This method should return a new widget to add to the widget list.
+ *
+ * @param parent The parent widget
+ * @return A valid QWidget
+ */
+ virtual QWidget *createWidget(QWidget *parent);
+protected:
+ QPtrList<QWidget> m_widgetList;
+ int m_minWidgets;
+ int m_maxWidgets;
+signals:
+ /**
+ * This signal is emitted whenever a widget gets added.
+ */
+ void widgetAdded(QWidget *widget);
+
+ /**
+ * This signal is emitted whenever a widget gets removed.
+ */
+ void widgetRemoved();
+
+ /**
+ * This signal is emitted whenever the clear button is clicked.
+ */
+ void clearWidgets();
+private:
+ void enableControls();
+
+ QPushButton *m_buttonMore;
+ QPushButton *m_buttonFewer;
+ QPushButton *m_buttonClear;
+ QVBoxLayout *m_layout;
+ QHBox *m_buttonBox;
+};
+
+}
+
+#endif