summaryrefslogtreecommitdiffstats
path: root/src/common/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/gui')
-rw-r--r--src/common/gui/Makefile.am7
-rw-r--r--src/common/gui/config_widget.h107
-rw-r--r--src/common/gui/container.cpp80
-rw-r--r--src/common/gui/container.h58
-rw-r--r--src/common/gui/dialog.cpp199
-rw-r--r--src/common/gui/dialog.h77
-rw-r--r--src/common/gui/editlistbox.cpp340
-rw-r--r--src/common/gui/editlistbox.h95
-rw-r--r--src/common/gui/hexword_gui.cpp136
-rw-r--r--src/common/gui/hexword_gui.h88
-rw-r--r--src/common/gui/key_gui.h125
-rw-r--r--src/common/gui/list_container.cpp95
-rw-r--r--src/common/gui/list_container.h55
-rw-r--r--src/common/gui/list_view.cpp221
-rw-r--r--src/common/gui/list_view.h93
-rw-r--r--src/common/gui/misc_gui.cpp234
-rw-r--r--src/common/gui/misc_gui.h164
-rw-r--r--src/common/gui/number_gui.cpp72
-rw-r--r--src/common/gui/number_gui.h40
-rw-r--r--src/common/gui/pfile_ext.cpp114
-rw-r--r--src/common/gui/pfile_ext.h29
-rw-r--r--src/common/gui/purl_ext.cpp111
-rw-r--r--src/common/gui/purl_gui.cpp151
-rw-r--r--src/common/gui/purl_gui.h120
24 files changed, 2811 insertions, 0 deletions
diff --git a/src/common/gui/Makefile.am b/src/common/gui/Makefile.am
new file mode 100644
index 0000000..c4bb948
--- /dev/null
+++ b/src/common/gui/Makefile.am
@@ -0,0 +1,7 @@
+INCLUDES = -I$(top_srcdir)/src $(all_includes)
+METASOURCES = AUTO
+libcommonui_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libcommonui.la
+libcommonui_la_SOURCES = container.cpp dialog.cpp editlistbox.cpp \
+ hexword_gui.cpp list_view.cpp misc_gui.cpp number_gui.cpp pfile_ext.cpp purl_ext.cpp \
+ purl_gui.cpp list_container.cpp
diff --git a/src/common/gui/config_widget.h b/src/common/gui/config_widget.h
new file mode 100644
index 0000000..abfafab
--- /dev/null
+++ b/src/common/gui/config_widget.h
@@ -0,0 +1,107 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2004 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef CONFIG_WIDGET_H
+#define CONFIG_WIDGET_H
+
+#include <qpixmap.h>
+#include <qcheckbox.h>
+#include <qvaluevector.h>
+#include <qvariant.h>
+
+#include "container.h"
+
+//-----------------------------------------------------------------------------
+class ConfigWidget : public Container
+{
+Q_OBJECT
+public:
+ ConfigWidget(QWidget *parent = 0) : Container(parent) {}
+ virtual QString title() const { return QString::null; }
+ virtual QString header() const { return QString::null; }
+ virtual QPixmap pixmap() const { return QPixmap(); }
+
+public slots:
+ virtual void loadConfig() = 0;
+ virtual void saveConfig() = 0;
+};
+
+//-----------------------------------------------------------------------------
+template <typename Type>
+class BaseConfigWidget
+{
+public:
+ BaseConfigWidget(ConfigWidget *widget) {
+ _widgets.resize(Type::Nb_Types);
+ for(Type type; type<Type::Nb_Types; ++type) _widgets[type.type()] = createWidget(type, widget);
+ }
+ void loadConfig() {
+ for(Type type; type<Type::Nb_Types; ++type) load(type, _widgets[type.type()]);
+ }
+ void saveConfig() {
+ for(Type type; type<Type::Nb_Types; ++type) save(type, _widgets[type.type()]);
+ }
+ void setDefault() {
+ for(Type type; type<Type::Nb_Types; ++type) setDefault(type, _widgets[type.type()]);
+ }
+
+private:
+ QValueVector<QWidget *> _widgets;
+
+ static QWidget *createWidget(Type type, ConfigWidget *widget) {
+ QWidget *w = 0;
+ uint row = widget->numRows();
+ switch (type.data().defValue.type()) {
+ case QVariant::Bool:
+ w = new QCheckBox(type.label(), widget);
+ widget->addWidget(w, row,row, 0,1);
+ break;
+ default: Q_ASSERT(false); break;
+ }
+ return w;
+ }
+ void load(Type type, QWidget *widget) const {
+ switch (type.data().defValue.type()) {
+ case QVariant::Bool:
+ static_cast<QCheckBox *>(widget)->setChecked(readConfigEntry(type).toBool());
+ break;
+ default: Q_ASSERT(false); break;
+ }
+ }
+ void save(Type type, QWidget *widget) {
+ switch (type.data().defValue.type()) {
+ case QVariant::Bool:
+ writeConfigEntry(type, QVariant(static_cast<QCheckBox *>(widget)->isChecked(), 0));
+ break;
+ default: Q_ASSERT(false); break;
+ }
+ }
+ void setDefault(Type type, QWidget *widget) const {
+ switch (type.data().defValue.type()) {
+ case QVariant::Bool:
+ static_cast<QCheckBox *>(widget)->setChecked(type.data().defValue.toBool());
+ break;
+ default: Q_ASSERT(false); break;
+ }
+ }
+};
+
+//-----------------------------------------------------------------------------
+#define BEGIN_DECLARE_CONFIG_WIDGET(ConfigType, ConfigWidgetType) \
+class ConfigWidgetType : public ::ConfigWidget, public BaseConfigWidget<ConfigType> \
+{ \
+public: \
+ ConfigWidgetType() : BaseConfigWidget<ConfigType>(this) {} \
+ virtual void loadConfig() { BaseConfigWidget<ConfigType>::loadConfig(); } \
+ virtual void saveConfig() { BaseConfigWidget<ConfigType>::saveConfig(); } \
+
+#define END_DECLARE_CONFIG_WIDGET \
+};
+
+#endif
diff --git a/src/common/gui/container.cpp b/src/common/gui/container.cpp
new file mode 100644
index 0000000..881e265
--- /dev/null
+++ b/src/common/gui/container.cpp
@@ -0,0 +1,80 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#include "container.h"
+
+#include "misc_gui.h"
+
+//----------------------------------------------------------------------------
+Container::Container(QWidget *parent, Type type)
+ : QFrame(parent), _type(type)
+{
+ initLayout();
+}
+
+Container::Container(QWidgetStack *stack, uint index, Type type)
+ : QFrame(stack), _type(type)
+{
+ initLayout();
+ stack->addWidget(this, index);
+}
+
+Container::Container(QTabWidget *tabw, const QString &title, Type type)
+ : QFrame(tabw), _type(type)
+{
+ initLayout();
+ tabw->addTab(this, title);
+}
+
+void Container::setFrame(Type type)
+{
+ _type = type;
+ switch (type) {
+ case Flat:
+ setMargin(parent() && parent()->inherits("QTabWidget") ? 10 : 0);
+ setFrameStyle(QFrame::NoFrame);
+ break;
+ case Sunken:
+ setMargin(10);
+ setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
+ break;
+ }
+}
+
+void Container::initLayout()
+{
+ _topLayout = new QGridLayout(this, 1, 1, 0, 10);
+ _gridLayout = new QGridLayout(1, 1, 10);
+ _topLayout->addLayout(_gridLayout, 0, 0);
+ _topLayout->setRowStretch(1, 1);
+ setFrame(_type);
+}
+
+void Container::addWidget(QWidget *w, uint startRow, uint endRow, uint startCol, uint endCol, int alignment)
+{
+ Q_ASSERT( startRow<=endRow );
+ Q_ASSERT( startCol<=endCol );
+ w->show();
+ _gridLayout->addMultiCellWidget(w, startRow, endRow, startCol, endCol, alignment);
+}
+
+void Container::addLayout(QLayout *l, uint startRow, uint endRow, uint startCol, uint endCol, int alignment)
+{
+ Q_ASSERT( startRow<=endRow );
+ Q_ASSERT( startCol<=endCol );
+ _gridLayout->addMultiCellLayout(l, startRow, endRow, startCol, endCol, alignment);
+}
+
+//----------------------------------------------------------------------------
+ButtonContainer::ButtonContainer(const QString &title, QWidget *parent)
+ : Container(parent, Sunken)
+{
+ _button = new PopupButton(title, this);
+ addWidget(_button, 0,0, 0,1);
+ setColStretch(2, 1);
+}
diff --git a/src/common/gui/container.h b/src/common/gui/container.h
new file mode 100644
index 0000000..d718c6f
--- /dev/null
+++ b/src/common/gui/container.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#ifndef CONTAINER_H
+#define CONTAINER_H
+
+#include <qframe.h>
+#include <qwidgetstack.h>
+#include <qtabwidget.h>
+#include <qlayout.h>
+
+class PopupButton;
+
+//----------------------------------------------------------------------------
+class Container : public QFrame
+{
+Q_OBJECT
+public:
+ enum Type { Flat, Sunken };
+ Container(QWidget *parent = 0, Type type = Flat);
+ Container(QWidgetStack *stack, uint index, Type type = Flat);
+ Container(QTabWidget *tabw, const QString &title, Type type = Flat);
+ void addWidget(QWidget *widget, uint startRow, uint endRow, uint startCol, uint endCol, int alignment = 0);
+ void addLayout(QLayout *layout, uint startRow, uint endRow, uint startCol, uint endCol, int alignment = 0);
+ uint numRows() const { return _gridLayout->numRows(); }
+ uint numCols() const { return _gridLayout->numCols(); }
+ void setFrame(Type type);
+ void setMargin(uint margin) { _topLayout->setMargin(margin); }
+ void setRowSpacing(uint row, uint spacing) { _gridLayout->setRowSpacing(row, spacing); }
+ void setColSpacing(uint col, uint spacing) { _gridLayout->setColSpacing(col, spacing); }
+ void setRowStretch(uint row, uint stretch) { _gridLayout->setRowStretch(row, stretch); }
+ void setColStretch(uint col, uint stretch) { _gridLayout->setColStretch(col, stretch); }
+
+private:
+ Type _type;
+ QGridLayout *_topLayout, *_gridLayout;
+
+ void initLayout();
+};
+
+//----------------------------------------------------------------------------
+class ButtonContainer : public Container
+{
+Q_OBJECT
+public:
+ ButtonContainer(const QString &title, QWidget *parent);
+ PopupButton &button() { return *_button; }
+
+private:
+ PopupButton *_button;
+};
+
+#endif
diff --git a/src/common/gui/dialog.cpp b/src/common/gui/dialog.cpp
new file mode 100644
index 0000000..650b086
--- /dev/null
+++ b/src/common/gui/dialog.cpp
@@ -0,0 +1,199 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#include "dialog.h"
+
+#include <qheader.h>
+#include <qtimer.h>
+#include <qlabel.h>
+#include <qwidgetstack.h>
+#include <ktextedit.h>
+
+#include "misc_gui.h"
+
+//-----------------------------------------------------------------------------
+Dialog::Dialog(QWidget *parent, const char *name, bool modal,
+ const QString &caption, int buttonMask, ButtonCode defaultButton,
+ bool separator, const QSize &defaultSize)
+ : KDialogBase(parent, name, modal, caption, buttonMask, defaultButton, separator),
+ _defaultSize(defaultSize)
+{
+ BusyCursor::start();
+ Q_ASSERT(name);
+ QWidget *main = new QWidget(this);
+ setMainWidget(main);
+
+ QTimer::singleShot(0, this, SLOT(updateSize()));
+}
+
+Dialog::Dialog(DialogType type, const QString &caption, int buttonMask, ButtonCode defaultButton,
+ QWidget *parent, const char *name, bool modal, bool separator, const QSize &defaultSize)
+ : KDialogBase(type, caption, buttonMask, defaultButton, parent, name, modal, separator),
+ _defaultSize(defaultSize)
+{
+ BusyCursor::start();
+ Q_ASSERT(name);
+ QTimer::singleShot(0, this, SLOT(updateSize()));
+}
+
+Dialog::~Dialog()
+{
+ GuiConfig gc;
+ gc.writeEntry(QString(name()) + "_size", size());
+}
+
+void Dialog::updateSize()
+{
+ GuiConfig gc;
+ resize(gc.readSizeEntry(QString(name()) + "_size", &_defaultSize));
+ BusyCursor::stop();
+}
+
+//-----------------------------------------------------------------------------
+TreeListDialog::Item::Item(const QString &label, QWidget *page, const QString &title, QListView *listview)
+ : KListViewItem(listview, label), _page(page), _title(title)
+{}
+TreeListDialog::Item::Item(const QString &label, QWidget *page, const QString &title, QListViewItem *item)
+ : KListViewItem(item, label), _page(page), _title(title)
+{}
+
+TreeListDialog::TreeListDialog(QWidget *parent, const char *name, bool modal,
+ const QString &caption, int buttonMask, ButtonCode defaultButton,
+ bool separator)
+ : Dialog(parent, name, modal, caption, buttonMask, defaultButton, separator)
+{
+ QVBoxLayout *top = new QVBoxLayout(mainWidget(), 0, 10);
+
+ // list view
+ QValueList<int> widths;
+ widths += 80;
+ widths += 500;
+ Splitter *splitter = new Splitter(widths, Horizontal, mainWidget(), name);
+ top->addWidget(splitter);
+ _listView = new KListView(splitter);
+ connect(_listView, SIGNAL(currentChanged(QListViewItem *)), SLOT(currentChanged(QListViewItem *)));
+ _listView->setAllColumnsShowFocus(true);
+ _listView->setRootIsDecorated(true);
+ _listView->setSorting(0);
+ _listView->addColumn(QString::null);
+ _listView->header()->hide();
+ _listView->setResizeMode(QListView::LastColumn);
+
+ // pages
+ _frame = new QFrame(splitter);
+ QVBoxLayout *vbox = new QVBoxLayout(_frame, 10, 10);
+ _titleBox = new QHBoxLayout(vbox);
+ _label = new QLabel(_frame);
+ _titleBox->addWidget(_label);
+ _stack = new QWidgetStack(_frame);
+ connect(_stack, SIGNAL(aboutToShow(QWidget *)), SIGNAL(aboutToShowPage(QWidget *)));
+ vbox->addWidget(_stack);
+ vbox->addStretch(1);
+}
+
+QWidget *TreeListDialog::addPage(const QStringList &labels)
+{
+ Q_ASSERT( !labels.isEmpty() );
+
+ QWidget *page = 0;
+ QListViewItem *item = 0;
+ QListViewItemIterator it(_listView);
+ for (; it.current(); ++it) {
+ if ( it.current()->text(0)==labels[0] ) {
+ item = it.current();
+ break;
+ }
+ }
+ if ( item==0 ) {
+ page = new QWidget(_stack);
+ connect(page, SIGNAL(destroyed(QObject *)), SLOT(pageDestroyed(QObject *)));
+ _stack->addWidget(page);
+ item = new Item(labels[0], page, labels[0], _listView);
+ item->setOpen(true);
+ bool last = ( labels.count()==1 );
+ item->setSelectable(last);
+ }
+ for (uint i=1; i<labels.count(); i++) {
+ QListViewItem *parent = item;
+ item = 0;
+ QListViewItemIterator iti(parent);
+ for (; it.current(); ++it) {
+ if ( it.current()->text(0)==labels[i] ) {
+ item = it.current();
+ break;
+ }
+ }
+ if ( item==0 ) {
+ page = new QWidget(_stack);
+ connect(page, SIGNAL(destroyed(QObject *)), SLOT(pageDestroyed(QObject *)));
+ _stack->addWidget(page);
+ item = new Item(labels[i], page, labels[i], parent);
+ item->setOpen(true);
+ bool last = ( labels.count()==i+1 );
+ item->setSelectable(last);
+ }
+ }
+
+ return page;
+}
+
+void TreeListDialog::currentChanged(QListViewItem *lvitem)
+{
+ if ( lvitem==0 ) return;
+ Item *item = static_cast<Item *>(lvitem);
+ _listView->ensureItemVisible(item);
+ _label->setText(item->_title);
+ _stack->raiseWidget(item->_page);
+}
+
+void TreeListDialog::showPage(QWidget *page)
+{
+ QListViewItemIterator it(_listView);
+ for (; it.current(); ++it) {
+ Item *item = static_cast<Item *>(it.current());
+ if ( item->_page==page ) {
+ _listView->setCurrentItem(item);
+ currentChanged(item);
+ break;
+ }
+ }
+}
+
+int TreeListDialog::pageIndex(QWidget *page) const
+{
+ return _stack->id(page);
+}
+
+int TreeListDialog::activePageIndex() const
+{
+ const Item *item = static_cast<const Item *>(_listView->currentItem());
+ if ( item==0 ) return -1;
+ return pageIndex(item->_page);
+}
+
+void TreeListDialog::pageDestroyed(QObject *object)
+{
+ QListViewItemIterator it(_listView);
+ for (; it.current(); ++it) {
+ Item *item = static_cast<Item *>(it.current());
+ if ( item->_page!=object ) continue;
+ delete item;
+ break;
+ }
+}
+
+//-----------------------------------------------------------------------------
+TextEditorDialog::TextEditorDialog(const QString &text, const QString &caption,
+ bool wrapAtWidgetWidth, QWidget *parent)
+ : Dialog(parent, "text_editor_dialog", true, caption, Close, Close, false, QSize(200, 100))
+{
+ KTextEdit *w = new KTextEdit(text, QString::null, this);
+ w->setReadOnly(true);
+ w->setWordWrap(wrapAtWidgetWidth ? QTextEdit::WidgetWidth : QTextEdit::NoWrap);
+ setMainWidget(w);
+}
diff --git a/src/common/gui/dialog.h b/src/common/gui/dialog.h
new file mode 100644
index 0000000..1227a7d
--- /dev/null
+++ b/src/common/gui/dialog.h
@@ -0,0 +1,77 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#ifndef DIALOG_H
+#define DIALOG_H
+
+#include <qlayout.h>
+#include <kdialogbase.h>
+#include <klistview.h>
+
+//-----------------------------------------------------------------------------
+class Dialog : public KDialogBase
+{
+Q_OBJECT
+public:
+ Dialog(QWidget *parent, const char *name, bool modal,
+ const QString &caption, int buttonMask, ButtonCode defaultButton, bool separator,
+ const QSize &defaultSize = QSize());
+ Dialog(DialogType type, const QString &caption,
+ int buttonMask, ButtonCode defaultButton, QWidget *parent, const char *name,
+ bool modal, bool separator, const QSize &defaultSize = QSize());
+ virtual ~Dialog();
+
+private slots:
+ void updateSize();
+
+private:
+ QSize _defaultSize;
+};
+
+//-----------------------------------------------------------------------------
+class TreeListDialog : public Dialog
+{
+Q_OBJECT
+public:
+ TreeListDialog(QWidget *parent, const char *name, bool modal,
+ const QString &caption, int buttonMask, ButtonCode defaultButton, bool separator);
+ QWidget *addPage(const QStringList &labels);
+ void showPage(QWidget *page);
+ int activePageIndex() const;
+ int pageIndex(QWidget *page) const;
+
+protected slots:
+ virtual void currentChanged(QListViewItem *item);
+ void pageDestroyed(QObject *page);
+
+protected:
+ QFrame *_frame;
+ KListView *_listView;
+ QHBoxLayout *_titleBox;
+ QLabel *_label;
+ QWidgetStack *_stack;
+
+ class Item : public KListViewItem {
+ public:
+ Item(const QString &label, QWidget *page, const QString &title, QListView *listview);
+ Item(const QString &label, QWidget *page, const QString &title, QListViewItem *item);
+ QWidget *_page;
+ QString _title;
+ };
+};
+
+//-----------------------------------------------------------------------------
+class TextEditorDialog : public Dialog
+{
+Q_OBJECT
+public:
+ TextEditorDialog(const QString &text, const QString &caption,
+ bool wrapAtWidgetWidth, QWidget *parent);
+};
+
+#endif
diff --git a/src/common/gui/editlistbox.cpp b/src/common/gui/editlistbox.cpp
new file mode 100644
index 0000000..1d2916d
--- /dev/null
+++ b/src/common/gui/editlistbox.cpp
@@ -0,0 +1,340 @@
+/* Copyright (C) 2000 David Faure <faure@kde.org>, Alexander Neundorf <neundorf@kde.org>
+ 2000, 2002 Carsten Pfeiffer <pfeiffer@kde.org>
+ Copyright (C) 2006-2007 Nicolas Hadacek <hadacek@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#include "editlistbox.h"
+
+#include <qstringlist.h>
+#include <qlabel.h>
+#include <qheader.h>
+
+#include <kdialog.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <knotifyclient.h>
+#include <kiconloader.h>
+#include <kstdguiitem.h>
+
+EditListBox::EditListBox(uint nbColumns, QWidget *parent, const char *name, Mode mode, Buttons buttons)
+ : QFrame(parent, name), _mode(mode), _buttons(buttons)
+{
+ m_lineEdit = new KLineEdit;
+ init(nbColumns, m_lineEdit);
+}
+
+EditListBox::EditListBox(uint nbColumns, QWidget *view, KLineEdit *lineEdit, QWidget *parent, const char *name,
+ Mode mode, Buttons buttons)
+ : QFrame(parent, name), _mode(mode), _buttons(buttons)
+{
+ m_lineEdit = lineEdit;
+ init(nbColumns, view);
+}
+
+void EditListBox::init(uint nbColumns, QWidget *view)
+{
+ _addButton = 0;
+ _removeButton = 0;
+ _moveUpButton = 0;
+ _moveDownButton = 0;
+ _removeAllButton = 0;
+ _resetButton = 0;
+ setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
+
+ QGridLayout *grid = new QGridLayout(this, 1, 1, 0, KDialog::spacingHint());
+ uint row = 0;
+ if (view) {
+ QHBoxLayout *hbox = new QHBoxLayout(KDialog::spacingHint());
+ grid->addMultiCellLayout(hbox, row,row, 0,1);
+ if (m_lineEdit) {
+ KIconLoader loader;
+ QIconSet iconset = loader.loadIcon("locationbar_erase", KIcon::Toolbar);
+ KPushButton *button = new KPushButton(iconset, QString::null, this);
+ connect(button, SIGNAL(clicked()), SLOT(clearEdit()));
+ hbox->addWidget(button);
+ }
+ view->reparent( this, QPoint(0,0) );
+ hbox->addWidget(view);
+ row++;
+ }
+ _listView= new KListView(this);
+ for (uint i=0; i<nbColumns; i++) _listView->addColumn(QString::null);
+ _listView->header()->hide();
+ _listView->setSorting(-1);
+ _listView->setResizeMode(KListView::LastColumn);
+ _listView->setColumnWidthMode(nbColumns-1, KListView::Maximum);
+ grid->addWidget(_listView, row, 0);
+ QVBoxLayout *vbox = new QVBoxLayout(10);
+ grid->addLayout(vbox, row, 1);
+ _buttonsLayout = new QVBoxLayout(10);
+ vbox->addLayout(_buttonsLayout);
+ vbox->addStretch(1);
+
+ setButtons(_buttons);
+
+ if (m_lineEdit) {
+ connect(m_lineEdit,SIGNAL(textChanged(const QString&)),this,SLOT(typedSomething(const QString&)));
+ m_lineEdit->setTrapReturnKey(true);
+ connect(m_lineEdit,SIGNAL(returnPressed()),this,SLOT(addItem()));
+ }
+ connect(_listView, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
+
+ // maybe supplied lineedit has some text already
+ typedSomething(m_lineEdit ? m_lineEdit->text() : QString::null);
+}
+
+void EditListBox::setButtons(Buttons buttons)
+{
+ _buttons = buttons;
+
+ delete _addButton;
+ _addButton = 0;
+ if ( buttons & Add ) {
+#if KDE_VERSION < KDE_MAKE_VERSION(3,4,0)
+ _addButton = new KPushButton(KGuiItem(i18n("Add"), "edit_add"), this);
+#else
+ _addButton = new KPushButton(KStdGuiItem::add(), this);
+#endif
+ _addButton->setEnabled(false);
+ _addButton->show();
+ connect(_addButton, SIGNAL(clicked()), SLOT(addItem()));
+ _buttonsLayout->addWidget(_addButton);
+ }
+
+ delete _removeButton;
+ _removeButton = 0;
+ if ( buttons & Remove ) {
+ _removeButton = new KPushButton(KGuiItem(i18n("Remove"), "clear"), this);
+ _removeButton->setEnabled(false);
+ _removeButton->show();
+ connect(_removeButton, SIGNAL(clicked()), SLOT(removeItem()));
+ _buttonsLayout->addWidget(_removeButton);
+ }
+
+ delete _removeAllButton;
+ _removeAllButton = 0;
+ if ( buttons & RemoveAll ) {
+ _removeAllButton = new KPushButton(KGuiItem(i18n("Remove All"), "delete"), this);
+ _removeAllButton->show();
+ connect(_removeAllButton, SIGNAL(clicked()), SLOT(clear()));
+ _buttonsLayout->addWidget(_removeAllButton);
+ }
+
+ delete _moveUpButton;
+ _moveUpButton = 0;
+ delete _moveDownButton;
+ _moveDownButton = 0;
+ if ( buttons & UpDown ) {
+ _moveUpButton = new KPushButton(KGuiItem(i18n("Move &Up"), "up"), this);
+ _moveUpButton->setEnabled(false);
+ _moveUpButton->show();
+ connect(_moveUpButton, SIGNAL(clicked()), SLOT(moveItemUp()));
+ _buttonsLayout->addWidget(_moveUpButton);
+ _moveDownButton = new KPushButton(KGuiItem(i18n("Move &Down"), "down"), this);
+ _moveDownButton->setEnabled(false);
+ _moveDownButton->show();
+ connect(_moveDownButton, SIGNAL(clicked()), SLOT(moveItemDown()));
+ _buttonsLayout->addWidget(_moveDownButton);
+ }
+
+ delete _resetButton;
+ _resetButton = 0;
+ if ( buttons & Reset ) {
+ _resetButton = new KPushButton(KStdGuiItem::reset(), this);
+ _resetButton->show();
+ connect(_resetButton, SIGNAL(clicked()), SIGNAL(reset()));
+ _buttonsLayout->addWidget(_resetButton);
+ }
+}
+
+void EditListBox::typedSomething(const QString& text)
+{
+ QListViewItem *item = _listView->selectedItem();
+ if (item) {
+ if( selectedText()!=text ) {
+ item->setText(textColumn(), text);
+ emit changed();
+ }
+ }
+ updateButtons();
+}
+
+void EditListBox::moveItemUp()
+{
+ QListViewItem *item = _listView->selectedItem();
+ if ( item==0 || item->itemAbove()==0 ) return;
+ item->itemAbove()->moveItem(item);
+ updateButtons();
+ emit changed();
+}
+
+void EditListBox::moveItemDown()
+{
+ QListViewItem *item = _listView->selectedItem();
+ if ( item==0 || item->itemBelow()==0 ) return;
+ item->moveItem(item->itemBelow());
+ updateButtons();
+ emit changed();
+}
+
+void EditListBox::addItem()
+{
+ // when m_checkAtEntering is true, the add-button is disabled, but this
+ // slot can still be called through Key_Return/Key_Enter. So we guard
+ // against this.
+ if ( !_addButton || !_addButton->isEnabled() || m_lineEdit==0 ) return;
+
+ addItem(m_lineEdit->text());
+}
+
+void EditListBox::addItem(const QString &text)
+{
+ bool alreadyInList(false);
+ //if we didn't check for dupes at the inserting we have to do it now
+ if ( _mode==DuplicatesDisallowed ) alreadyInList = _listView->findItem(text, textColumn());
+
+ if (m_lineEdit) {
+ bool block = m_lineEdit->signalsBlocked();
+ m_lineEdit->blockSignals(true);
+ m_lineEdit->clear();
+ m_lineEdit->blockSignals(block);
+ }
+ _listView->clearSelection();
+
+ if (!alreadyInList) {
+ QListViewItem *item = createItem();
+ item->setText(textColumn(), text);
+ if ( _listView->lastItem() ) item->moveItem(_listView->lastItem());
+ emit changed();
+ emit added(text);
+ }
+ updateButtons();
+}
+
+void EditListBox::clearEdit()
+{
+ _listView->clearSelection();
+ if (m_lineEdit) {
+ m_lineEdit->clear();
+ m_lineEdit->setFocus();
+ }
+ updateButtons();
+}
+
+void EditListBox::removeItem()
+{
+ QListViewItem *item = _listView->selectedItem();
+ if (item) {
+ QString text = item->text(textColumn());
+ delete item;
+ emit changed();
+ emit removed(text);
+ updateButtons();
+ }
+}
+
+void EditListBox::selectionChanged()
+{
+ if (m_lineEdit) m_lineEdit->setText(selectedText());
+ updateButtons();
+}
+
+void EditListBox::clear()
+{
+ _listView->clear();
+ if (m_lineEdit) {
+ m_lineEdit->clear();
+ m_lineEdit->setFocus();
+ }
+ updateButtons();
+ emit changed();
+}
+
+uint EditListBox::count() const
+{
+ uint nb = 0;
+ QListViewItemIterator it(_listView);
+ for (; it.current(); ++it) nb++;
+ return nb;
+}
+
+const QListViewItem *EditListBox::item(uint i) const
+{
+ uint k = 0;
+ QListViewItemIterator it(_listView);
+ for (; it.current(); ++it) {
+ if ( k==i ) return it.current();
+ k++;
+ }
+ return 0;
+}
+
+QStringList EditListBox::texts() const
+{
+ QStringList list;
+ QListViewItemIterator it(_listView);
+ for (; it.current(); ++it) list.append(it.current()->text(textColumn()));
+ return list;
+}
+
+void EditListBox::setTexts(const QStringList& items)
+{
+ _listView->clear();
+ for (int i=items.count()-1; i>=0; i--) {
+ QListViewItem *item = createItem();
+ item->setText(textColumn(), items[i]);
+ }
+ if (m_lineEdit) m_lineEdit->clear();
+ updateButtons();
+}
+
+void EditListBox::updateButtons()
+{
+ QListViewItem *item = _listView->selectedItem();
+ if (_addButton) {
+ if ( m_lineEdit==0 ) _addButton->setEnabled(true);
+ else {
+ QString text = m_lineEdit->text();
+ if ( _mode!=DuplicatesCheckedAtEntering ) _addButton->setEnabled(!text.isEmpty());
+ else if ( text.isEmpty() ) _addButton->setEnabled(false);
+ else _addButton->setEnabled(!_listView->findItem(text, textColumn()));
+ }
+ }
+ if (_removeButton) _removeButton->setEnabled(item);
+ if (_moveUpButton) _moveUpButton->setEnabled(item && item->itemAbove());
+ if (_moveDownButton) _moveDownButton->setEnabled(item && item->itemBelow());
+ if (_removeAllButton) _removeAllButton->setEnabled(_listView->firstChild());
+}
+
+void EditListBox::setEditText(const QString &text)
+{
+ _listView->clearSelection();
+ if (m_lineEdit) m_lineEdit->setText(text);
+ updateButtons();
+}
+
+QListViewItem *EditListBox::createItem()
+{
+ return new KListViewItem(_listView);
+}
+
+QString EditListBox::selectedText() const
+{
+ QListViewItem *item = _listView->selectedItem();
+ if ( item==0 ) return QString::null;
+ return item->text(textColumn());
+}
diff --git a/src/common/gui/editlistbox.h b/src/common/gui/editlistbox.h
new file mode 100644
index 0000000..c259278
--- /dev/null
+++ b/src/common/gui/editlistbox.h
@@ -0,0 +1,95 @@
+/* Copyright (C) 2000 David Faure <faure@kde.org>, Alexander Neundorf <neundorf@kde.org>
+ Copyright (C) 2006-2007 Nicolas Hadacek <hadacek@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#ifndef EDITLISTBOX_H
+#define EDITLISTBOX_H
+
+#include <qlayout.h>
+#include <klineedit.h>
+#include <kpushbutton.h>
+#include <klistview.h>
+
+#include "common/common/qflags.h"
+
+//----------------------------------------------------------------------------
+// modified KEditListBox (beyond recognition)
+// * support for duplicated items
+// * use KStdGuiItem for buttons
+// * support for New, Clear, Reset buttons
+// * use KListView
+class EditListBox : public QFrame
+{
+Q_OBJECT
+ public:
+ enum Mode { DuplicatesDisallowed, DuplicatesAllowed, DuplicatesCheckedAtEntering };
+ enum Button { Add = 1, Remove = 2, UpDown = 4, RemoveAll = 8, Reset = 16 };
+ Q_DECLARE_FLAGS(Buttons, Button)
+
+ EditListBox(uint nbColumns, QWidget *parent = 0, const char *name = 0, Mode mode = DuplicatesDisallowed,
+ Buttons buttons = Buttons(Add|Remove|RemoveAll|UpDown) );
+ EditListBox(uint nbColumns, QWidget *view, KLineEdit *lineEdit, QWidget *parent = 0, const char *name = 0,
+ Mode mode = DuplicatesDisallowed, Buttons buttons = Buttons(Add|Remove|RemoveAll|UpDown) );
+ void setTexts(const QStringList& items);
+ QStringList texts() const;
+ uint count() const;
+ QString text(uint i) const { return item(i)->text(textColumn()); }
+ const QListViewItem *item(uint i) const;
+ Buttons buttons() const { return _buttons; }
+ void setButtons(Buttons buttons);
+ void setEditText(const QString &text);
+ void addItem(const QString &text);
+
+ signals:
+ void reset();
+ void changed();
+ void added( const QString & text );
+ void removed( const QString & text );
+
+ public slots:
+ void clear();
+
+ protected slots:
+ virtual void moveItemUp();
+ virtual void moveItemDown();
+ virtual void clearEdit();
+ virtual void addItem();
+ virtual void removeItem();
+ void selectionChanged();
+ void typedSomething(const QString& text);
+
+ protected:
+ KListView *_listView;
+
+ virtual QListViewItem *createItem();
+ virtual uint textColumn() const { return 0; }
+ QString selectedText() const;
+
+ private:
+ Mode _mode;
+ Buttons _buttons;
+ QVBoxLayout *_buttonsLayout;
+ KLineEdit *m_lineEdit;
+ KPushButton *_addButton, *_removeButton, *_moveUpButton, *_moveDownButton,
+ *_removeAllButton, *_resetButton;
+
+ void init(uint nbColumns, QWidget *view);
+ void updateButtons();
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(EditListBox::Buttons)
+
+#endif
diff --git a/src/common/gui/hexword_gui.cpp b/src/common/gui/hexword_gui.cpp
new file mode 100644
index 0000000..d794a11
--- /dev/null
+++ b/src/common/gui/hexword_gui.cpp
@@ -0,0 +1,136 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * 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. *
+ ***************************************************************************/
+#include "hexword_gui.h"
+
+#include <qtimer.h>
+
+#include "common/gui/number_gui.h"
+#include "common/common/misc.h"
+
+//-----------------------------------------------------------------------------
+HexValueValidator::HexValueValidator(uint nbChars, QObject *parent)
+ : QValidator(parent, "hex_value_validator"), _nbChars(nbChars) {}
+
+QValidator::State HexValueValidator::validate(QString &input, int &) const
+{
+ if ( input.length()==0 ) return Acceptable;
+ if ( input.length()>_nbChars ) return Invalid;
+ for (uint i=0; i<input.length(); i++)
+ if ( !isxdigit(input[i].latin1()) && input[i]!='-' ) return Invalid;
+ return Acceptable;
+}
+
+//-----------------------------------------------------------------------------
+GenericHexWordEditor::GenericHexWordEditor(uint nbChars, bool hasBlankValue, QWidget *parent)
+ : KLineEdit(parent, "hex_word_editor"), _nbChars(nbChars), _hasBlankValue(hasBlankValue)
+{
+ setFocusPolicy(ClickFocus);
+ setValidator(new HexValueValidator(nbChars, this));
+ connect(this, SIGNAL(textChanged(const QString &)), SLOT(slotTextChanged()));
+ setFrame(false);
+}
+
+void GenericHexWordEditor::slotTextChanged()
+{
+ if ( text().length()!=_nbChars ) return;
+ if ( changeValue() ) emit moveNext();
+}
+
+bool GenericHexWordEditor::changeValue()
+{
+ if ( !isValid() ) return false;
+ QString s = text();
+ BitValue v = blankValue();
+ if ( s!=QString(repeat("-", _nbChars)) ) {
+ s = s.leftJustify(_nbChars, '0', true);
+ for (uint i=0; i<_nbChars; i++)
+ if ( !isxdigit(s[i].latin1()) ) s[i] = '0';
+ v = normalizeWord(fromHex(s, 0));
+ setText(toHex(v, _nbChars));
+ }
+ if ( v==word() ) return false;
+ setWord(v);
+ emit modified();
+ return true;
+}
+
+void GenericHexWordEditor::set()
+{
+ blockSignals(true);
+ setEnabled(isValid());
+ if ( !isValid() ) clear();
+ else {
+ BitValue value = word();
+ if ( _hasBlankValue && value==blankValue() ) setText(repeat("-", _nbChars));
+ else setText(toHex(normalizeWord(value), _nbChars));
+ }
+ blockSignals(false);
+}
+
+bool GenericHexWordEditor::event(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::FocusOut:
+ changeValue();
+ break;
+ case QEvent::FocusIn:
+ QTimer::singleShot(0, this, SLOT(selectAll())); // ugly but it works
+ break;
+ case QEvent::KeyPress:
+ switch ( static_cast<QKeyEvent *>(e)->key() ) {
+ case Key_Next:
+ emit moveNextPage();
+ return true;
+ case Key_Tab:
+ case Key_Enter:
+ case Key_Return:
+ emit moveNext();
+ return true;
+ case Key_Prior:
+ emit movePrevPage();
+ return true;
+ case Key_BackTab:
+ emit movePrev();
+ return true;
+ case Key_Down:
+ emit moveDown();
+ return true;
+ case Key_Up:
+ emit moveUp();
+ return true;
+ case Key_Home:
+ emit moveFirst();
+ return true;
+ case Key_End:
+ emit moveLast();
+ return true;
+ case Key_Right:
+ if ( cursorPosition()!=int(text().length()) ) break;
+ emit moveNext();
+ return true;
+ case Key_Left:
+ if ( cursorPosition()!=0 ) break;
+ emit movePrev();
+ return true;
+ }
+ default: break;
+ }
+ return QLineEdit::event(e);
+}
+
+QSize GenericHexWordEditor::sizeHint() const
+{
+ return QSize(maxCharWidth(NumberBase::Hex, font()) * (_nbChars+1), fontMetrics().height());
+}
+
+QSize GenericHexWordEditor::minimumSizeHint() const
+{
+ return QSize(maxCharWidth(NumberBase::Hex, font()) * (_nbChars+1), fontMetrics().height());
+}
diff --git a/src/common/gui/hexword_gui.h b/src/common/gui/hexword_gui.h
new file mode 100644
index 0000000..5da6840
--- /dev/null
+++ b/src/common/gui/hexword_gui.h
@@ -0,0 +1,88 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef HEXWORD_GUI_H
+#define HEXWORD_GUI_H
+
+#include <qvalidator.h>
+#include <klineedit.h>
+
+#include "common/common/bitvalue.h"
+
+//-----------------------------------------------------------------------------
+class HexValueValidator : public QValidator
+{
+Q_OBJECT
+public:
+ HexValueValidator(uint nbChars, QObject *parent);
+ virtual State validate(QString &input, int &pos) const;
+
+private:
+ uint _nbChars;
+};
+
+//-----------------------------------------------------------------------------
+class GenericHexWordEditor : public KLineEdit
+{
+Q_OBJECT
+public:
+ GenericHexWordEditor(uint nbChars, bool hasBlankValue, QWidget *parent);
+ virtual QSize sizeHint() const;
+ virtual QSize minimumSizeHint() const;
+
+signals:
+ void modified();
+ void moveNext();
+ void movePrev();
+ void moveUp();
+ void moveDown();
+ void moveFirst();
+ void moveLast();
+ void moveNextPage();
+ void movePrevPage();
+
+private slots:
+ bool changeValue();
+ void slotTextChanged();
+
+protected:
+ uint _nbChars;
+ bool _hasBlankValue;
+
+ virtual bool isValid() const = 0;
+ virtual BitValue mask() const = 0;
+ virtual BitValue normalizeWord(BitValue value) const = 0;
+ virtual bool event(QEvent *e);
+ virtual void set();
+ virtual BitValue word() const = 0;
+ virtual void setWord(BitValue value) = 0;
+ virtual BitValue blankValue() const = 0;
+};
+
+//-----------------------------------------------------------------------------
+class HexWordEditor : public GenericHexWordEditor
+{
+Q_OBJECT
+public:
+ HexWordEditor(uint nbChars, QWidget *parent) : GenericHexWordEditor(nbChars, false, parent) {}
+ void setValue(BitValue word) { _word = word; set(); }
+ BitValue value() const { return _word; }
+
+protected:
+ BitValue _word;
+
+ virtual bool isValid() const { return true; }
+ virtual BitValue mask() const { return maxValue(NumberBase::Hex, _nbChars); }
+ virtual BitValue normalizeWord(BitValue value) const { return value.maskWith(mask()); }
+ virtual BitValue word() const { return _word; }
+ virtual void setWord(BitValue value) { _word = value; }
+ virtual BitValue blankValue() const { return 0; }
+};
+
+#endif
diff --git a/src/common/gui/key_gui.h b/src/common/gui/key_gui.h
new file mode 100644
index 0000000..fb8a9f5
--- /dev/null
+++ b/src/common/gui/key_gui.h
@@ -0,0 +1,125 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#ifndef KEY_GUI_H
+#define KEY_GUI_H
+
+#include <qcombobox.h>
+#include <qwidgetstack.h>
+#include <qpopupmenu.h>
+
+#include "common/gui/misc_gui.h"
+#include "common/common/misc.h"
+
+//-----------------------------------------------------------------------------
+template <typename KeyType, typename Type, typename WidgetType>
+class KeyWidget
+{
+public:
+ typedef QMapConstIterator<KeyType, int> ConstIterator;
+
+public:
+ KeyWidget(QWidget *parent) { _widget = new WidgetType(parent); }
+ virtual ~KeyWidget() { delete _widget; }
+ virtual WidgetType *widget() { return _widget; }
+ virtual void clear() { _ids.clear(); }
+ ConstIterator begin() const { return _ids.begin(); }
+ ConstIterator end() const { return _ids.end(); }
+ uint count() const { return _ids.count(); }
+ void appendItem(const KeyType &key, Type type) {
+ CRASH_ASSERT( !_ids.contains(key) );
+ _ids[key] = append(type);
+ }
+ KeyType currentItem() const { return key(currentId()); }
+ void setCurrentItem(const KeyType &key) {
+ if ( _ids.contains(key) ) setCurrentId(_ids[key]);
+ }
+ bool contains(const KeyType &key) const { return _ids.contains(key); }
+ Type item(const KeyType &key) const {
+ CRASH_ASSERT( _ids.contains(key) );
+ return get(_ids[key]);
+ }
+ Type item(ConstIterator it) const {
+ CRASH_ASSERT( it!=end() );
+ return get(it.data());
+ }
+ KeyType key(int id) const {
+ for (ConstIterator it=begin(); it!=end(); it++)
+ if ( it.data()==id ) return it.key();
+ return KeyType();
+ }
+
+protected:
+ virtual int append(Type type) = 0;
+ virtual int currentId() const = 0;
+ virtual void setCurrentId(int id) = 0;
+ virtual Type get(int id) const = 0;
+
+ QWidget *_parent;
+ QMap<KeyType, int> _ids;
+ WidgetType *_widget;
+};
+
+//-----------------------------------------------------------------------------
+template <typename KeyType>
+class KeyComboBox : public KeyWidget<KeyType, QString, QComboBox>
+{
+public:
+ typedef KeyWidget<KeyType, QString, QComboBox> ParentType;
+ KeyComboBox(QWidget *parent = 0) : ParentType(parent) {}
+ virtual void clear() {
+ ParentType::clear();
+ ParentType::_widget->clear();
+ }
+ void fixMinimumWidth() {
+ ParentType::_widget->setMinimumWidth(ParentType::_widget->sizeHint().width());
+ }
+
+protected:
+ virtual int append(QString label) { ParentType::_widget->insertItem(label); return ParentType::_widget->count()-1; }
+ virtual int currentId() const { return ParentType::_widget->currentItem(); }
+ virtual void setCurrentId(int id) { ParentType::_widget->setCurrentItem(id); }
+ virtual QString get(int id) const { return ParentType::_widget->text(id); }
+};
+
+//-----------------------------------------------------------------------------
+template <typename KeyType>
+class KeyWidgetStack : public KeyWidget<KeyType, QWidget *, QWidgetStack>
+{
+public:
+ typedef KeyWidget<KeyType, QWidget *, QWidgetStack> ParentType;
+ KeyWidgetStack(QWidget *parent = 0) : ParentType(parent) {}
+
+protected:
+ virtual int append(QWidget *widget) { return ParentType::_widget->addWidget(widget); }
+ virtual int currentId() const { return ParentType::_widget->id(ParentType::_widget->visibleWidget()); }
+ virtual void setCurrentId(int id) { ParentType::_widget->raiseWidget(id); }
+ virtual QWidget *get(int id) const { return ParentType::_widget->widget(id); }
+};
+
+//-----------------------------------------------------------------------------
+template <typename KeyType>
+class KeyPopupButton : public KeyWidget<KeyType, QString, PopupButton>
+{
+public:
+ typedef KeyWidget<KeyType, QString, PopupButton> ParentType;
+ KeyPopupButton(QWidget *parent = 0) : ParentType(parent) {}
+
+protected:
+ virtual int append(QString label) { return ParentType::_widget->appendItem(label, QPixmap()); }
+ virtual QString get(int id) const { return ParentType::_widget->popup()->text(id); }
+
+private:
+ // disabled
+ QString currentItem() const;
+ void setCurrentItem(const QString &key);
+ virtual int currentId() const { return 0; }
+ virtual void setCurrentId(int) {}
+};
+
+#endif
diff --git a/src/common/gui/list_container.cpp b/src/common/gui/list_container.cpp
new file mode 100644
index 0000000..0103175
--- /dev/null
+++ b/src/common/gui/list_container.cpp
@@ -0,0 +1,95 @@
+/***************************************************************************
+ * Copyright (C) 2007 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#include "list_container.h"
+
+//----------------------------------------------------------------------------
+PopupContainer::PopupContainer(const QString &title, QWidget *parent, const char *name)
+ : KPopupMenu(parent, name)
+{
+ if ( !title.isEmpty() ) insertTitle(title);
+}
+
+ListContainer *PopupContainer::appendBranch(const QString &title)
+{
+ PopupContainer *branch = new PopupContainer(title, this);
+ insertItem(title, branch);
+ return branch;
+}
+
+ListContainer *PopupContainer::appendBranch(const QPixmap &pixmap, const QString &title)
+{
+ PopupContainer *branch = new PopupContainer(title, this);
+ insertItem(pixmap, title, branch);
+ return branch;
+}
+
+void PopupContainer::appendItem(const QPixmap &icon, const QString &label, uint id, ItemState state)
+{
+ insertItem(icon, label, id);
+ switch (state) {
+ case Normal: break;
+ case Checked: setItemChecked(id, true); break;
+ case UnChecked: setItemChecked(id, false); break;
+ case Disabled: setItemEnabled(id, false); break;
+ }
+}
+
+//----------------------------------------------------------------------------
+ListViewItemContainer::ListViewItemContainer(const QString &title, KListView *parent)
+ : KListViewItem(parent, title), _parent(0), _column(0)
+{
+ _ids = new QMap<const QListViewItem *, uint>;
+}
+
+ListViewItemContainer::ListViewItemContainer(const QString &title, ListViewItemContainer *parent)
+ : KListViewItem(parent, title), _parent(parent), _column(0)
+{
+ _ids = parent->_ids;
+}
+
+ListViewItemContainer::~ListViewItemContainer()
+{
+ if ( _parent==0 ) delete _ids;
+}
+
+ListContainer *ListViewItemContainer::appendBranch(const QString &title)
+{
+ ListViewItemContainer *branch = new ListViewItemContainer(title, this);
+ branch->setColumn(_column);
+ branch->setSelectable(false);
+ // append instead of prepend
+ QListViewItem *litem=firstChild();
+ while ( litem && litem->nextSibling() ) litem = litem->nextSibling();
+ if (litem) branch->moveItem(litem);
+ return branch;
+}
+
+void ListViewItemContainer::appendItem(const QPixmap &icon, const QString &title, uint id, ItemState state)
+{
+ QListViewItem *item = 0;
+ if ( state==Normal || state==Disabled ) {
+ item = new KListViewItem(this);
+ item->setText(_column, title);
+ } else {
+ item = new QCheckListItem(this, title, QCheckListItem::CheckBox);
+ static_cast<QCheckListItem *>(item)->setState(state==Checked ? QCheckListItem::On : QCheckListItem::Off);
+ }
+ item->setPixmap(_column, icon);
+ item->setSelectable(state==Normal);
+ // append instead of prepend
+ QListViewItem *litem=firstChild();
+ while ( litem && litem->nextSibling() ) litem = litem->nextSibling();
+ if (litem) item->moveItem(litem);
+ (*_ids)[item] = id;
+}
+
+int ListViewItemContainer::id(const QListViewItem *item) const
+{
+ return (_ids->contains(item) ? int((*_ids)[item]) : -1);
+}
diff --git a/src/common/gui/list_container.h b/src/common/gui/list_container.h
new file mode 100644
index 0000000..b70db57
--- /dev/null
+++ b/src/common/gui/list_container.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * Copyright (C) 2007 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#ifndef LIST_CONTAINER_H
+#define LIST_CONTAINER_H
+
+#include <kpopupmenu.h>
+#include <klistview.h>
+
+//----------------------------------------------------------------------------
+class ListContainer
+{
+public:
+ virtual ~ListContainer() {}
+ virtual ListContainer *appendBranch(const QString &title) = 0;
+ enum ItemState { Normal, Checked, UnChecked, Disabled };
+ void appendItem(const QString &label, uint id, ItemState state) { appendItem(QPixmap(), label, id, state); }
+ virtual void appendItem(const QPixmap &icon, const QString &label, uint id, ItemState state) = 0;
+};
+
+//----------------------------------------------------------------------------
+class PopupContainer : public KPopupMenu, public ListContainer
+{
+Q_OBJECT
+public:
+ PopupContainer(const QString &title, QWidget *parent = 0, const char *name = 0);
+ virtual ListContainer *appendBranch(const QString &title);
+ virtual ListContainer *appendBranch(const QPixmap &icon, const QString &title);
+ virtual void appendItem(const QPixmap &icon, const QString &label, uint id, ItemState state);
+};
+
+//----------------------------------------------------------------------------
+class ListViewItemContainer : public KListViewItem, public ListContainer
+{
+public:
+ ListViewItemContainer(const QString &title, KListView *parent);
+ ListViewItemContainer(const QString &title, ListViewItemContainer *parent);
+ virtual ~ListViewItemContainer();
+ void setColumn(uint column) { _column = column; }
+ virtual ListContainer *appendBranch(const QString &title);
+ virtual void appendItem(const QPixmap &icon, const QString &label, uint id, ItemState state);
+ int id(const QListViewItem* item) const; // -1 if not known
+
+private:
+ ListViewItemContainer *_parent;
+ uint _column;
+ QMap<const QListViewItem *, uint> *_ids;
+};
+
+#endif
diff --git a/src/common/gui/list_view.cpp b/src/common/gui/list_view.cpp
new file mode 100644
index 0000000..c9434f3
--- /dev/null
+++ b/src/common/gui/list_view.cpp
@@ -0,0 +1,221 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 1992-2003 Trolltech AS. *
+ * *
+ * 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. *
+ ***************************************************************************/
+#include "list_view.h"
+
+#include <qapplication.h>
+#include <qpainter.h>
+#include <qlineedit.h>
+#include <qheader.h>
+#include <qmetaobject.h>
+#include <qvariant.h>
+
+//----------------------------------------------------------------------------
+ListView::ListView(QWidget *parent, const char *name)
+ : KListView(parent, name)
+{
+ QToolTip::remove(this);
+ _tooltip = new ListViewToolTip(this);
+}
+
+ListView::~ListView()
+{
+ delete _tooltip;
+}
+
+QString ListView::tooltip(const QListViewItem &, int) const
+{
+ return QString::null;
+}
+
+void ListView::clear()
+{
+ _editItems.clear();
+ KListView::clear();
+}
+
+bool ListView::eventFilter(QObject *o, QEvent *e)
+{
+ QValueList<EditListViewItem *>::const_iterator it;
+ for (it=_editItems.begin(); it!=_editItems.end(); ++it) {
+ for (uint i=0; i<(*it)->_editWidgets.count(); i++) {
+ if ( (*it)->_editWidgets[i]==o ) {
+ //qDebug("event %i", e->type());
+ switch (e->type()) {
+ case QEvent::KeyPress: {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
+ switch (ke->key()) {
+ case Key_Enter:
+ case Key_Return:
+ (*it)->renameDone(true);
+ return true;
+ case Key_Escape:
+ (*it)->removeEditBox();
+ return true;
+ }
+ break;
+ }
+ case QEvent::FocusOut: {
+ //qDebug("focus out %i %i=%i", qApp->focusWidget(), focusWidget(), (*it)->_editWidgets[i]);
+ if ( qApp->focusWidget() && focusWidget()==(*it)->_editWidgets[i] ) break;
+ //qDebug("ext");
+ QCustomEvent *e = new QCustomEvent(9999);
+ QApplication::postEvent(o, e);
+ return true;
+ }
+ case 9999:
+ (*it)->renameDone(false);
+ return true;
+ default:
+ //qDebug(" ignored");
+ break;
+ }
+ }
+ }
+ }
+ return KListView::eventFilter(o, e);
+}
+
+void ListView::stopRenaming(bool force)
+{
+ QValueList<EditListViewItem *>::const_iterator it;
+ for (it=_editItems.begin(); it!=_editItems.end(); ++it)
+ if ( (*it)->isRenaming() ) (*it)->renameDone(force);
+}
+
+//----------------------------------------------------------------------------
+void ListViewToolTip::maybeTip(const QPoint &p)
+{
+ if ( _listView==0 ) return;
+ const QListViewItem* item = _listView->itemAt(p);
+ if ( item==0 ) return;
+ QRect rect = _listView->itemRect(item);
+ if ( !rect.isValid() ) return;
+ int col = _listView->header()->sectionAt(p.x());
+ QString text = _listView->tooltip(*item, col);
+ if ( !text.isEmpty() ) {
+ int hpos = _listView->header()->sectionPos(col);
+ rect.setLeft(hpos);
+ rect.setRight(hpos + _listView->header()->sectionSize(col));
+ tip(rect, text);
+ }
+}
+
+//----------------------------------------------------------------------------
+EditListViewItem::EditListViewItem(ListView *list)
+ : KListViewItem(list), _renaming(false)
+{
+ setRenameEnabled(0, true);
+ list->_editItems.append(this);
+}
+
+EditListViewItem::EditListViewItem(KListViewItem *item)
+ : KListViewItem(item), _renaming(false)
+{
+ setRenameEnabled(0, true);
+ static_cast<ListView *>(listView())->_editItems.append(this);
+}
+
+EditListViewItem::~EditListViewItem()
+{
+ if ( listView() ) static_cast<ListView *>(listView())->_editItems.remove(this);
+ for (uint i=0; i<_editWidgets.count(); i++) delete _editWidgets[i];
+}
+
+void EditListViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align)
+{
+ if ( column<int(_editWidgets.count()) && _editWidgets[column] )
+ p->fillRect(0, 0, width, height(), cg.color(QColorGroup::Background));
+ else KListViewItem::paintCell(p, cg, column, width, align);
+}
+
+void EditListViewItem::startRename()
+{
+ if ( !renameEnabled(0) ) return;
+ QListView *lv = listView();
+ if ( !lv ) return;
+ KListViewItem::startRename(0);
+ if (renameBox) {
+ renameBox->removeEventFilter(lv);
+ renameBox->hide();
+ lv->removeChild(renameBox);
+ }
+ _renaming = true;
+ _editWidgets.resize(lv->columns());
+ for (uint i=0; i<_editWidgets.count(); i++) {
+ QRect r = lv->itemRect(this);
+ r = QRect(lv->viewportToContents(r.topLeft()), r.size());
+ r.setLeft(lv->header()->sectionPos(i));
+ r.setWidth(lv->header()->sectionSize(i) - 1);
+ if ( i==0 ) r.setLeft(r.left() + lv->itemMargin() + (depth() + (lv->rootIsDecorated() ? 1 : 0)) * lv->treeStepSize() - 1);
+ if ( (lv->contentsX() + lv->visibleWidth())<(r.x() + r.width()) )
+ lv->scrollBy((r.x() + r.width() ) - ( lv->contentsX() + lv->visibleWidth() ), 0);
+ if ( r.width()>lv->visibleWidth() ) r.setWidth(lv->visibleWidth());
+
+ _editWidgets[i] = editWidgetFactory(i);
+ if ( _editWidgets[i]==0 ) continue;
+ _editWidgets[i]->installEventFilter(lv);
+ lv->addChild(_editWidgets[i], r.x(), r.y());
+ uint w = QMIN(r.width(), _editWidgets[i]->sizeHint().width());
+ _editWidgets[i]->resize(w, r.height());
+ lv->viewport()->setFocusProxy(_editWidgets[i]);
+ _editWidgets[i]->setFocus();
+ _editWidgets[i]->show();
+ }
+}
+
+void EditListViewItem::removeEditBox()
+{
+ QListView *lv = listView();
+ if ( !lv ) return;
+ _renaming = false;
+ bool resetFocus = false;
+ for (uint i=0; i<_editWidgets.count(); i++) {
+ if ( lv->viewport()->focusProxy()==_editWidgets[i] ) resetFocus = true;
+ delete _editWidgets[i];
+ }
+ _editWidgets.clear();
+ delete renameBox;
+ renameBox = 0;
+ if (resetFocus) {
+ lv->viewport()->setFocusProxy(lv);
+ lv->setFocus();
+ }
+}
+
+void EditListViewItem::editDone(int col, const QWidget *edit)
+{
+ if ( edit->metaObject()->findProperty("text", true)!=-1 )
+ emit listView()->itemRenamed(this, col, edit->property("text").toString());
+ else if ( edit->metaObject()->findProperty("currentText", true)!=-1 )
+ emit listView()->itemRenamed(this, col, edit->property("currentText").toString());
+}
+
+void EditListViewItem::renameDone(bool force)
+{
+ QListView *lv = listView();
+ if ( !lv || !_renaming ) return;
+ _renaming = false;
+ for (uint i=0; i<_editWidgets.count(); i++) {
+ if ( !force && !alwaysAcceptEdit(i) ) continue;
+ emit lv->itemRenamed(this, i);
+ if ( _editWidgets[i] ) editDone(i, _editWidgets[i]);
+ }
+ removeEditBox();
+}
+
+int EditListViewItem::width(const QFontMetrics &fm, const QListView *lv, int col) const
+{
+ int w = KListViewItem::width(fm, lv, col);
+ QWidget *edit = editWidgetFactory(col);
+ if ( edit==0 ) return w;
+ w = QMAX(w, edit->sizeHint().width());
+ delete edit;
+ return w;
+}
diff --git a/src/common/gui/list_view.h b/src/common/gui/list_view.h
new file mode 100644
index 0000000..09ca984
--- /dev/null
+++ b/src/common/gui/list_view.h
@@ -0,0 +1,93 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#ifndef LIST_VIEW_H
+#define LIST_VIEW_H
+
+#include <qtooltip.h>
+#include <qvaluevector.h>
+#define private public
+#define protected public
+#include <klistview.h>
+#undef private
+#undef protected
+
+//-----------------------------------------------------------------------------
+class EditListViewItem;
+class ListViewToolTip;
+
+class ListView : public KListView
+{
+Q_OBJECT
+public:
+ ListView(QWidget *parent = 0, const char *name = 0);
+ virtual ~ListView();
+ virtual void clear();
+ void stopRenaming(bool force);
+ virtual QString tooltip(const QListViewItem &item, int column) const;
+
+public slots:
+ void cancelRenaming() { stopRenaming(false); }
+ void finishRenaming() { stopRenaming(true); }
+
+protected:
+ virtual bool eventFilter(QObject *o, QEvent *e);
+
+private:
+ ListViewToolTip *_tooltip;
+ QValueList<EditListViewItem *> _editItems;
+
+ friend class EditListViewItem;
+};
+
+//-----------------------------------------------------------------------------
+class ListViewToolTip : public QToolTip
+{
+public:
+ ListViewToolTip(ListView *parent)
+ : QToolTip(parent->viewport()), _listView(parent) {}
+
+protected:
+ virtual void maybeTip(const QPoint &p);
+
+private:
+ ListView *_listView;
+};
+
+//-----------------------------------------------------------------------------
+class EditListViewItem : public KListViewItem
+{
+public:
+ EditListViewItem(ListView *list);
+ EditListViewItem(KListViewItem *item);
+ virtual ~EditListViewItem();
+ void startRename();
+ bool isRenaming() const { return _renaming; }
+
+protected:
+ virtual QWidget *editWidgetFactory(int col) const = 0;
+ virtual bool alwaysAcceptEdit(int col) const = 0;
+ virtual int width(const QFontMetrics &fm, const QListView *lv, int c) const;
+ virtual void editDone(int col, const QWidget *editWidget);
+ virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align);
+
+private:
+ bool _renaming;
+ QValueVector<QWidget *> _editWidgets;
+
+ virtual void activate() { startRename(); }
+ virtual void startRename(int) { startRename(); }
+ virtual void okRename(int) { renameDone(true); }
+ virtual void cancelRename(int) { renameDone(false); }
+ void renameDone(bool force);
+ void removeEditBox();
+
+ friend class ListView;
+};
+
+#endif
diff --git a/src/common/gui/misc_gui.cpp b/src/common/gui/misc_gui.cpp
new file mode 100644
index 0000000..00f4997
--- /dev/null
+++ b/src/common/gui/misc_gui.cpp
@@ -0,0 +1,234 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#include "misc_gui.h"
+
+#include <qapplication.h>
+#include <qpushbutton.h>
+#include <qtimer.h>
+#include <qwidgetstack.h>
+#include <qobjectlist.h>
+#include <qpainter.h>
+#include <qheader.h>
+#include <qmetaobject.h>
+#include <qvariant.h>
+#include <qpopupmenu.h>
+
+#include <kcursor.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kaction.h>
+#include <ktabbar.h>
+
+#include "dialog.h"
+#include "common/common/number.h"
+#include "common/common/misc.h"
+#include "common/gui/number_gui.h"
+
+//-----------------------------------------------------------------------------
+bool BusyCursor::_overridePaused = false;
+
+void BusyCursor::start()
+{
+ QApplication::setOverrideCursor(KCursor::waitCursor(), true);
+}
+
+void BusyCursor::stop()
+{
+ QApplication::restoreOverrideCursor();
+}
+
+void BusyCursor::pause()
+{
+ _overridePaused = QApplication::overrideCursor();
+ stop();
+}
+
+void BusyCursor::restore()
+{
+ if (_overridePaused) start();
+}
+
+//-----------------------------------------------------------------------------
+void MessageBox::information(const QString &text, Log::ShowMode show, const QString &dontShowAgainName)
+{
+ if ( show==Log::DontShow ) return;
+ BusyCursor::pause();
+ KMessageBox::information(qApp->mainWidget(), text, QString::null, dontShowAgainName, KMessageBox::Notify | KMessageBox::AllowLink);
+ BusyCursor::restore();
+}
+
+void MessageBox::detailedSorry(const QString &text, const QString &details, Log::ShowMode show)
+{
+ if ( show==Log::DontShow ) return;
+ BusyCursor::pause();
+ if ( details.isEmpty() ) KMessageBox::sorry(qApp->mainWidget(), text, QString::null, KMessageBox::Notify | KMessageBox::AllowLink);
+ else KMessageBox::detailedSorry(qApp->mainWidget(), text, details, QString::null, KMessageBox::Notify | KMessageBox::AllowLink);
+ BusyCursor::restore();
+}
+
+bool MessageBox::askContinue(const QString &text, const KGuiItem &buttonContinue, const QString &caption)
+{
+ ::BusyCursor::pause();
+ int res = KMessageBox::warningContinueCancel(qApp->mainWidget(), text, caption, buttonContinue);
+ ::BusyCursor::restore();
+ return ( res==KMessageBox::Continue );
+}
+
+bool MessageBox::questionYesNo(const QString &text, const KGuiItem &yesButton,const KGuiItem &noButton, const QString &caption)
+{
+ ::BusyCursor::pause();
+ int res = KMessageBox::questionYesNo(qApp->mainWidget(), text, caption, yesButton, noButton);
+ ::BusyCursor::restore();
+ return ( res==KMessageBox::Yes );
+}
+
+MessageBox::Result MessageBox::questionYesNoCancel(const QString &text, const KGuiItem &yesButton, const KGuiItem &noButton,
+ const QString &caption)
+{
+ ::BusyCursor::pause();
+ int res = KMessageBox::questionYesNoCancel(qApp->mainWidget(), text, caption, yesButton, noButton);
+ ::BusyCursor::restore();
+ if ( res==KMessageBox::Yes ) return Yes;
+ if ( res==KMessageBox::No ) return No;
+ return Cancel;
+}
+
+void MessageBox::text(const QString &text, Log::ShowMode show)
+{
+ if ( show==Log::DontShow ) return;
+ BusyCursor::pause();
+ TextEditorDialog dialog(text, QString::null, false, qApp->mainWidget());
+ dialog.exec();
+ BusyCursor::restore();
+}
+
+//----------------------------------------------------------------------------
+PopupButton::PopupButton(QWidget *parent, const char *name)
+ : KPushButton(parent, name)
+{
+ init();
+}
+
+PopupButton::PopupButton(const QString &text, QWidget *parent, const char *name)
+ : KPushButton(text, parent, name)
+{
+ init();
+}
+
+void PopupButton::init()
+{
+ _separator = false;
+ setFlat(true);
+ QPopupMenu *popup = new QPopupMenu(this);
+ connect(popup, SIGNAL(activated(int)), SIGNAL(activated(int)));
+ setPopup(popup);
+}
+
+void PopupButton::appendAction(KAction *action)
+{
+ if ( _separator && popup()->count()!=0 ) popup()->insertSeparator();
+ _separator = false;
+ action->plug(popup());
+}
+
+void PopupButton::appendAction(const QString &label, const QString &icon,
+ QObject *receiver, const char *slot)
+{
+ appendAction(new KAction(label, icon, 0, receiver, slot, (KActionCollection *)0));
+}
+
+int PopupButton::appendItem(const QString &label, const QString &icon, int id)
+{
+ KIconLoader loader;
+ QPixmap pixmap = loader.loadIcon(icon, KIcon::Small);
+ return appendItem(label, pixmap, id);
+}
+
+int PopupButton::appendItem(const QString &label, const QPixmap &icon, int id)
+{
+ if ( _separator && popup()->count()!=0 ) popup()->insertSeparator();
+ _separator = false;
+ return popup()->insertItem(icon, label, id);
+}
+
+//-----------------------------------------------------------------------------
+Splitter::Splitter(const QValueList<int> &defaultSizes, Orientation o, QWidget *parent, const char *name)
+ : QSplitter(o, parent, name), _defaultSizes(defaultSizes)
+{
+ Q_ASSERT(name);
+ setOpaqueResize(true);
+ QTimer::singleShot(0, this, SLOT(updateSizes()));
+}
+
+Splitter::~Splitter()
+{
+ GuiConfig gc;
+ gc.writeEntry(QString(name()) + "_sizes", sizes());
+}
+
+void Splitter::updateSizes()
+{
+ GuiConfig gc;
+ QValueList<int> sizes = gc.readIntListEntry(QString(name()) + "_sizes");
+ for (uint i=sizes.count(); i<_defaultSizes.count(); i++) sizes.append(_defaultSizes[i]);
+ setSizes(sizes);
+}
+
+//-----------------------------------------------------------------------------
+TabBar::TabBar(QWidget *parent, const char *name)
+ : KTabBar(parent, name), _ignoreWheelEvent(false)
+{}
+
+void TabBar::wheelEvent(QWheelEvent *e)
+{
+ if (_ignoreWheelEvent) QApplication::sendEvent(parent(), e); // #### not sure why ignoring is not enough...
+ else KTabBar::wheelEvent(e);
+}
+
+TabWidget::TabWidget(QWidget *parent, const char *name)
+ : KTabWidget(parent, name)
+{
+ setTabBar(new TabBar(this));
+}
+
+void TabWidget::setIgnoreWheelEvent(bool ignore)
+{
+ static_cast<TabBar *>(tabBar())->_ignoreWheelEvent = ignore;
+}
+
+void TabWidget::wheelEvent(QWheelEvent *e)
+{
+ if (static_cast<TabBar *>(tabBar())->_ignoreWheelEvent) e->ignore();
+ else KTabWidget::wheelEvent(e);
+}
+
+void TabWidget::setTabBar(TabBar *tabbar)
+{
+ KTabWidget::setTabBar(tabbar);
+ connect(tabBar(), SIGNAL(contextMenu( int, const QPoint & )), SLOT(contextMenu( int, const QPoint & )));
+ connect(tabBar(), SIGNAL(mouseDoubleClick( int )), SLOT(mouseDoubleClick( int )));
+ connect(tabBar(), SIGNAL(mouseMiddleClick( int )), SLOT(mouseMiddleClick( int )));
+ connect(tabBar(), SIGNAL(initiateDrag( int )), SLOT(initiateDrag( int )));
+ connect(tabBar(), SIGNAL(testCanDecode(const QDragMoveEvent *, bool & )), SIGNAL(testCanDecode(const QDragMoveEvent *, bool & )));
+ connect(tabBar(), SIGNAL(receivedDropEvent( int, QDropEvent * )), SLOT(receivedDropEvent( int, QDropEvent * )));
+ connect(tabBar(), SIGNAL(moveTab( int, int )), SLOT(moveTab( int, int )));
+ connect(tabBar(), SIGNAL(closeRequest( int )), SLOT(closeRequest( int )));
+ connect(tabBar(), SIGNAL(wheelDelta( int )), SLOT(wheelDelta( int )));
+}
+
+//-----------------------------------------------------------------------------
+ComboBox::ComboBox(QWidget *parent, const char *name)
+ : QComboBox(parent, name), _ignoreWheelEvent(false)
+{}
+
+void ComboBox::wheelEvent(QWheelEvent *e)
+{
+ if (_ignoreWheelEvent) QApplication::sendEvent(parent(), e); // #### not sure why ignoring is not enough...
+ else QComboBox::wheelEvent(e);
+}
diff --git a/src/common/gui/misc_gui.h b/src/common/gui/misc_gui.h
new file mode 100644
index 0000000..2d58569
--- /dev/null
+++ b/src/common/gui/misc_gui.h
@@ -0,0 +1,164 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#ifndef MISC_GUI_H
+#define MISC_GUI_H
+
+#include <qlayout.h>
+#include <qsplitter.h>
+#include <qvaluevector.h>
+#include <qvalidator.h>
+#include <qcombobox.h>
+#include <qwidgetstack.h>
+
+#include <klocale.h>
+#include <kpushbutton.h>
+#include <ktabwidget.h>
+#include <ktabbar.h>
+#include <kstdguiitem.h>
+#include <klineedit.h>
+class KAction;
+
+#include "common/global/generic_config.h"
+#include "common/global/log.h"
+#include "common/common/number.h"
+
+//-----------------------------------------------------------------------------
+class BusyCursor
+{
+public:
+ BusyCursor() { start(); }
+ ~BusyCursor() { stop(); }
+ static void start();
+ static void stop();
+ static void pause();
+ static void restore();
+
+private:
+ static bool _overridePaused;
+};
+
+//-----------------------------------------------------------------------------
+namespace MessageBox
+{
+extern void information(const QString &text, Log::ShowMode show, const QString &dontShowAgainName = QString::null);
+extern void detailedSorry(const QString &text, const QString &details, Log::ShowMode show);
+inline void sorry(const QString &text, Log::ShowMode show) { detailedSorry(text, QString::null, show); }
+extern bool askContinue(const QString &text, const KGuiItem &continueButton = KStdGuiItem::cont(),
+ const QString &caption = i18n("Warning"));
+extern bool questionYesNo(const QString &text, const KGuiItem &yesButton, const KGuiItem &noButton,
+ const QString &caption = i18n("Warning"));
+enum Result { Yes, No, Cancel };
+extern Result questionYesNoCancel(const QString &text, const KGuiItem &yesButton, const KGuiItem &noButton,
+ const QString &caption = i18n("Warning"));
+extern void text(const QString &text, Log::ShowMode show);
+}
+
+//----------------------------------------------------------------------------
+class PopupButton : public KPushButton
+{
+Q_OBJECT
+public:
+ PopupButton(QWidget *parent = 0, const char *name = 0);
+ PopupButton(const QString &text, QWidget *parent = 0, const char *name = 0);
+ void appendAction(KAction *action);
+ void appendAction(const QString &label, const QString &icon = QString::null,
+ QObject *receiver = 0, const char *slot = 0);
+ int appendItem(const QString &label, uint id) { return appendItem(label, QPixmap(), id); }
+ int appendItem(const QString &label, const QString &icon, int id = -1);
+ int appendItem(const QString &label, const QPixmap &icon, int id = -1);
+ void appendSeparator() { _separator = true; }
+
+signals:
+ void activated(int id);
+
+private:
+ bool _separator;
+
+ void init();
+};
+
+//-----------------------------------------------------------------------------
+class Splitter : public QSplitter
+{
+Q_OBJECT
+public:
+ Splitter(const QValueList<int> &defaultSizes, Orientation orientation,
+ QWidget *parent, const char *name);
+ virtual ~Splitter();
+
+private slots:
+ void updateSizes();
+
+private:
+ QValueList<int> _defaultSizes;
+};
+
+//-----------------------------------------------------------------------------
+class GuiConfig : public GenericConfig
+{
+public:
+ GuiConfig() : GenericConfig("gui") {}
+};
+
+//-----------------------------------------------------------------------------
+class SeparatorWidget : public QFrame
+{
+Q_OBJECT
+public:
+ SeparatorWidget(QWidget *parent) : QFrame(parent, "separator") {
+ setFrameStyle(QFrame::Panel | QFrame::Sunken);
+ setMargin(2);
+ setFixedHeight(2*2);
+ }
+};
+
+//-----------------------------------------------------------------------------
+class TabBar : public KTabBar
+{
+Q_OBJECT
+public:
+ TabBar(QWidget *parent = 0, const char *name = 0);
+
+protected:
+ virtual void wheelEvent(QWheelEvent *e);
+
+private:
+ bool _ignoreWheelEvent;
+
+ friend class TabWidget;
+};
+
+class TabWidget : public KTabWidget
+{
+Q_OBJECT
+public:
+ TabWidget(QWidget *parent = 0, const char *name = 0);
+ void setIgnoreWheelEvent(bool ignore);
+
+protected:
+ virtual void wheelEvent(QWheelEvent *e);
+ void setTabBar(TabBar *tabbar);
+};
+
+//-----------------------------------------------------------------------------
+class ComboBox : public QComboBox
+{
+Q_OBJECT
+public:
+ ComboBox(QWidget *parent = 0, const char *name = 0);
+ void setIgnoreWheelEvent(bool ignore) { _ignoreWheelEvent = ignore; }
+
+protected:
+ virtual void wheelEvent(QWheelEvent *e);
+
+private:
+ bool _ignoreWheelEvent;
+};
+
+#endif
diff --git a/src/common/gui/number_gui.cpp b/src/common/gui/number_gui.cpp
new file mode 100644
index 0000000..d855407
--- /dev/null
+++ b/src/common/gui/number_gui.cpp
@@ -0,0 +1,72 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#include "number_gui.h"
+
+#include <qfontmetrics.h>
+
+//-----------------------------------------------------------------------------
+uint maxCharWidth(const QString &s, const QFont &font)
+{
+ QFontMetrics fm(font);
+ uint w = 0;
+ for (uint i=0; i<uint(s.length()); i++)
+ w = QMAX(w, uint(fm.width(s[i])));
+ return w;
+}
+
+uint maxCharWidth(NumberBase base, const QFont &font)
+{
+ QString s;
+ for (uint i=0; i<base.data().base; i++) s += toChar(base, i);
+ return maxCharWidth(s, font);
+}
+
+uint maxLabelWidth(NumberBase base, uint nbChars, const QFont &font)
+{
+ uint w = maxStringWidth(base, nbChars, font);
+ QFontMetrics fm(font);
+ if ( base==NumberBase::String ) return w + 2 * fm.width("\"");
+ return w + fm.width(base.data().prefix);
+}
+
+//-----------------------------------------------------------------------------
+NumberLineEdit::NumberLineEdit(QWidget *parent, const char *name)
+ : KLineEdit(parent, name)
+{
+ connect(this, SIGNAL(textChanged(const QString &)), SLOT(textChangedSlot()));
+}
+
+NumberLineEdit::NumberLineEdit(const QString &text, QWidget *parent, const char *name)
+ : KLineEdit(text, parent, name)
+{
+ connect(this, SIGNAL(textChanged(const QString &)), SLOT(textChangedSlot()));
+}
+
+QValidator::State validateNumber(const QString &input)
+{
+ if ( input.isEmpty() ) return QValidator::Intermediate;
+ bool ok;
+ (void)fromAnyLabel(input, &ok);
+ if (ok) return QValidator::Acceptable;
+ FOR_EACH(NumberBase, base)
+ if ( input==base.data().prefix ) return QValidator::Intermediate;
+ if ( input[0]=='\"' ) return QValidator::Intermediate;
+ if ( input[0]=='\'' ) return QValidator::Intermediate;
+ return QValidator::Invalid;
+}
+
+void NumberLineEdit::textChangedSlot()
+{
+ QValidator::State state = validateNumber(text());
+ switch (state) {
+ case QValidator::Acceptable: unsetColor(); break;
+ case QValidator::Intermediate: setColor(QColor("#FF9900")); break;
+ case QValidator::Invalid: setColor(red); break;
+ }
+}
diff --git a/src/common/gui/number_gui.h b/src/common/gui/number_gui.h
new file mode 100644
index 0000000..f910820
--- /dev/null
+++ b/src/common/gui/number_gui.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#ifndef NUMBER_GUI_H
+#define NUMBER_GUI_H
+
+#include <qvalidator.h>
+#include <klineedit.h>
+
+#include "common/common/number.h"
+
+//-----------------------------------------------------------------------------
+extern uint maxCharWidth(const QString &s, const QFont &font);
+extern uint maxCharWidth(NumberBase base, const QFont &font);
+inline uint maxStringWidth(NumberBase base, uint nbChars, const QFont &font) { return nbChars * maxCharWidth(base, font); }
+extern uint maxLabelWidth(NumberBase base, uint nbChars, const QFont &font);
+
+extern QValidator::State validateNumber(const QString &s);
+
+//-----------------------------------------------------------------------------
+class NumberLineEdit : public KLineEdit
+{
+Q_OBJECT
+public:
+ NumberLineEdit(QWidget *parent = 0, const char *name = 0);
+ NumberLineEdit(const QString &text, QWidget *parent = 0, const char *name = 0);
+ uint value(bool *ok = 0) const { return fromAnyLabel(text(), ok); }
+ void setColor(const QColor &color) { setPaletteForegroundColor(color); }
+ void unsetColor() { unsetPalette(); }
+
+private slots:
+ void textChangedSlot();
+};
+
+#endif
diff --git a/src/common/gui/pfile_ext.cpp b/src/common/gui/pfile_ext.cpp
new file mode 100644
index 0000000..d42de16
--- /dev/null
+++ b/src/common/gui/pfile_ext.cpp
@@ -0,0 +1,114 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#include "pfile_ext.h"
+
+#include <qfile.h>
+#include <kio/netaccess.h>
+#include <ktempfile.h>
+#include "common/gui/misc_gui.h"
+
+//-----------------------------------------------------------------------------
+bool PURL::File::openForWrite()
+{
+ close();
+ if (_tmp) delete _tmp;
+ _tmp = new KTempFile(QString::null, _extension);
+ _tmp->setAutoDelete(true);
+ if ( _tmp->status()!=0 ) {
+ _error = i18n("Could not create temporary file.");
+ _log.sorry(_error, i18n("File: %1").arg(_tmp->name()));
+ return false;
+ }
+ return true;
+}
+
+bool PURL::File::close()
+{
+ if (_tmp) _tmp->close();
+ else _file->close();
+ bool ok = (_tmp ? _tmp->status() : _file->status())==IO_Ok;
+ if ( !_file->name().isEmpty() ) {
+ KIO::NetAccess::removeTempFile(_file->name());
+ _file->setName(QString::null);
+ }
+ delete _stream;
+ _stream = 0;
+ if ( ok && _tmp && !_url.isEmpty() && !KIO::NetAccess::upload(_tmp->name(), _url.kurl(), qApp->mainWidget()) ) {
+ _error = KIO::NetAccess::lastErrorString();
+ ok = false;
+ _log.sorry(i18n("Could not save file."), errorString());
+ }
+ delete _tmp;
+ _tmp = 0;
+ return ok;
+}
+
+bool PURL::File::openForRead()
+{
+ close();
+ QString tmp;
+ if ( !KIO::NetAccess::download(_url.kurl(), tmp, qApp->mainWidget()) ) {
+ _error = KIO::NetAccess::lastErrorString();
+ _log.sorry(i18n("Could not open file for reading."), errorString());
+ return false;
+ }
+ _file->setName(tmp);
+ if ( !_file->open(IO_ReadOnly) ) {
+ _error = i18n("Could not open temporary file.");
+ _log.sorry(_error, i18n("File: %1").arg(_file->name()));
+ return false;
+ }
+ return true;
+}
+
+bool PURL::File::remove()
+{
+ close();
+ if ( !_url.isEmpty() ) return _url.del(_log);
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+PURL::TempFile::TempFile(Log::Generic &log, const QString &extension)
+ : FileBase(log, extension)
+{}
+
+PURL::Url PURL::TempFile::url() const
+{
+ return (_tmp ? Url::fromPathOrUrl(_tmp->name()) : Url());
+}
+
+bool PURL::TempFile::close()
+{
+ delete _stream;
+ _stream = 0;
+ if (_tmp) {
+ _tmp->close();
+ if ( _tmp->status()!=IO_Ok ) {
+ _error = i18n("Could not write to temporary file.");
+ _log.sorry(_error, i18n("File: %1").arg(_tmp->name()));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool PURL::TempFile::openForWrite()
+{
+ close();
+ if (_tmp) delete _tmp;
+ _tmp = new KTempFile(QString::null, _extension);
+ _tmp->setAutoDelete(true);
+ if ( _tmp->status()!=0 ) {
+ _error = i18n("Could not create temporary file.");
+ _log.sorry(_error, i18n("File: %1").arg(_tmp->name()));
+ return false;
+ }
+ return true;
+}
diff --git a/src/common/gui/pfile_ext.h b/src/common/gui/pfile_ext.h
new file mode 100644
index 0000000..14c007a
--- /dev/null
+++ b/src/common/gui/pfile_ext.h
@@ -0,0 +1,29 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#ifndef PFILE_EXT_H
+#define PFILE_EXT_H
+
+#include "common/global/pfile.h"
+
+namespace PURL
+{
+
+class TempFile : public FileBase
+{
+public:
+ TempFile(Log::Generic &log, const QString &extension = QString::null);
+ ~TempFile() { close(); }
+ Url url() const;
+ bool close();
+ bool openForWrite();
+};
+
+} // namespace
+
+#endif
diff --git a/src/common/gui/purl_ext.cpp b/src/common/gui/purl_ext.cpp
new file mode 100644
index 0000000..5d69d05
--- /dev/null
+++ b/src/common/gui/purl_ext.cpp
@@ -0,0 +1,111 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#include "common/global/purl.h"
+
+#include <qfile.h>
+#include <qapplication.h>
+#include <kio/netaccess.h>
+#include <kfileitem.h>
+#include <ktempfile.h>
+#include <kconfigbackend.h>
+
+#include "common/global/pfile.h"
+
+bool PURL::Url::copyTo(const Url &destination, Log::Generic &log) const
+{
+//#if defined(NO_KDE)
+// Synchronous sync;
+// if ( sync.op().copy(_url.filepath(), destination.filepath()) && sync.execute() ) {
+// if ( show==Log::Show ) ConsoleView::sorry(i18n("Could not copy file"), sync.error());
+// return false;
+// }
+//#else
+ // do not overwrite
+ bool ok = KIO::NetAccess::file_copy(_url, destination._url, -1, false, false, qApp->mainWidget());
+ if ( !ok ) log.sorry(i18n("Could not copy file"), KIO::NetAccess::lastErrorString());
+ return ok;
+//#endif
+}
+
+bool PURL::Url::create(Log::Generic &log) const
+{
+//#if defined(NO_KDE)
+// QByteArray a;
+// Synchronous sync;
+// if ( sync.op().put(a, _url.filepath()) && sync.execute() ) {
+// if ( show==Log::Show ) ConsoleView::sorry(i18n("Could not create file"), sync.error());
+// return false;
+// }
+//#else
+ // assume file do no exist if ioslave cannot tell...
+ if ( KIO::NetAccess::exists(_url, false, qApp->mainWidget()) ) return true;
+ KTempFile tmp;
+ tmp.setAutoDelete(true);
+ // do not overwrite
+ bool ok = KIO::NetAccess::file_copy(tmp.name(), _url, -1, false, false, qApp->mainWidget());
+ if ( !ok ) log.sorry(i18n("Could not create file"), KIO::NetAccess::lastErrorString());
+//#endif
+ return ok;
+}
+
+bool PURL::Url::write(const QString &text, Log::Generic &log) const
+{
+ File file(*this, log);
+ if ( !file.openForWrite() ) return false;
+ file.stream() << text;
+ return file.close();
+}
+
+bool PURL::Url::del(Log::Generic &log) const
+{
+//#if defined(NO_KDE)
+// Synchronous sync;
+// if ( sync.op().remove(_url.filepath()) && sync.execute() ) {
+// if ( show==Log::Show ) ConsoleView::sorry(i18n("Could not delete file"), sync.error());
+// return false;
+// }
+//#else
+ bool ok = KIO::NetAccess::del(_url, qApp->mainWidget());
+ if ( !ok ) log.sorry(i18n("Could not delete file."), KIO::NetAccess::lastErrorString());
+ return ok;
+//#endif
+}
+
+bool PURL::Url::isDosFile() const
+{
+ Log::Base log;
+ File file(*this, log);
+ if( !file.openForRead() ) return false;
+ int oldc = 0;
+ for (;;) {
+ int c = file.qfile()->getch();
+ if ( c==-1 ) break;
+ if( c=='\n' && oldc=='\r' ) return true;
+ oldc = c;
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+bool PURL::Directory::create(Log::Generic &log) const
+{
+//#if defined(NO_KDE)
+// Synchronous sync;
+// if ( sync.op().mkdir(_url.filepath()) && sync.execute() ) {
+// if ( show==Log::Show ) ConsoleView::sorry(i18n("Could not create directory"), sync.error());
+// return false;
+// }
+//#else
+ // assume dir do no exist if ioslave cannot tell...
+ if ( KIO::NetAccess::exists(_url, false, qApp->mainWidget()) ) return true;
+ bool ok = KIO::NetAccess::mkdir(_url, qApp->mainWidget());
+ if ( !ok ) log.sorry(i18n("Could not create directory"), KIO::NetAccess::lastErrorString());
+//#endif
+ return ok;
+}
diff --git a/src/common/gui/purl_gui.cpp b/src/common/gui/purl_gui.cpp
new file mode 100644
index 0000000..d81fdb6
--- /dev/null
+++ b/src/common/gui/purl_gui.cpp
@@ -0,0 +1,151 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#include "purl_gui.h"
+
+#include <qlayout.h>
+#include <kiconloader.h>
+#include <kpushbutton.h>
+#include <krun.h>
+#include <kfiledialog.h>
+#include <kdirselectdialog.h>
+
+#include "misc_gui.h"
+
+//-----------------------------------------------------------------------------
+PURL::Url PURL::getOpenUrl(const QString &startDir, const QString &filter,
+ QWidget *widget, const QString &caption)
+{
+ return KFileDialog::getOpenURL(startDir, filter, widget, caption);
+}
+
+PURL::UrlList PURL::getOpenUrls(const QString &startDir, const QString &filter,
+ QWidget *widget, const QString &caption)
+{
+ return KFileDialog::getOpenURLs(startDir, filter, widget, caption);
+}
+
+PURL::Url PURL::getSaveUrl(const QString &startDir, const QString &filter,
+ QWidget *widget, const QString &caption,
+ SaveAction action)
+{
+ Url url = KFileDialog::getSaveURL(startDir, filter, widget, caption);
+ if ( url.isEmpty() ) return Url();
+ switch (action) {
+ case NoSaveAction: break;
+ case AskOverwrite:
+ if ( url.exists() ) {
+ if ( !MessageBox::askContinue(i18n("File \"%1\" already exists. Overwrite ?").arg(url.pretty())) ) return Url();
+ }
+ break;
+ case CancelIfExists:
+ if ( url.exists() ) return Url();
+ break;
+ }
+ return url;
+}
+
+PURL::Directory PURL::getExistingDirectory(const QString &startDir, QWidget *widget,
+ const QString &caption)
+{
+ KURL kurl = KDirSelectDialog::selectDirectory(startDir, false, widget, caption);
+ if ( kurl.isEmpty() ) return Directory();
+ return Directory(kurl.path(1));
+}
+
+QPixmap PURL::icon(FileType type)
+{
+ if (type.data().xpm_icon) return QPixmap(type.data().xpm_icon);
+ if ( hasMimetype(type) ) return KMimeType::mimeType(type.data().mimetype)->pixmap(KIcon::Small);
+ return QPixmap();
+}
+
+bool PURL::hasMimetype(FileType type)
+{
+ if ( type.data().mimetype==0 ) return false;
+ KMimeType::Ptr ptr = KMimeType::mimeType(type.data().mimetype);
+ return ( ptr!=KMimeType::defaultMimeTypePtr() );
+}
+
+//-----------------------------------------------------------------------------
+PURL::Label::Label(const QString &url, const QString &text,
+ QWidget *parent, const char *name)
+ : KURLLabel(url, text, parent, name)
+{
+ connect(this, SIGNAL(leftClickedURL()), SLOT(urlClickedSlot()));
+}
+
+void PURL::Label::urlClickedSlot()
+{
+ (void)new KRun(url());
+}
+
+//-----------------------------------------------------------------------------
+PURL::BaseWidget::BaseWidget(QWidget *parent, const char *name)
+ : QWidget(parent, name)
+{
+ init();
+}
+
+PURL::BaseWidget::BaseWidget(const QString &defaultDir, QWidget *parent, const char *name)
+ : QWidget(parent, name), _defaultDir(defaultDir)
+{
+ init();
+}
+
+void PURL::BaseWidget::init()
+{
+ QHBoxLayout *top = new QHBoxLayout(this, 0, 10);
+
+ _edit = new KLineEdit(this);
+ connect(_edit, SIGNAL(textChanged(const QString &)), SIGNAL(changed()));
+ top->addWidget(_edit);
+ KIconLoader loader;
+ QIconSet iconset = loader.loadIcon("fileopen", KIcon::Toolbar);
+ QPushButton *button = new KPushButton(iconset, QString::null, this);
+ connect(button, SIGNAL(clicked()), SLOT(buttonClicked()));
+ top->addWidget(button);
+}
+
+//----------------------------------------------------------------------------
+void PURL::DirectoryWidget::buttonClicked()
+{
+ Directory dir = getExistingDirectory(_defaultDir, this, i18n("Select Directory"));
+ if ( dir.isEmpty() ) return;
+ _edit->setText(dir.path());
+ emit changed();
+}
+
+//----------------------------------------------------------------------------
+PURL::DirectoriesWidget::DirectoriesWidget(const QString &title, QWidget *parent, const char *name)
+ : QVGroupBox(title, parent, name)
+{
+ init(QString::null);
+}
+
+PURL::DirectoriesWidget::DirectoriesWidget(const QString &title, const QString &defaultDir, QWidget *parent, const char *name)
+ : QVGroupBox(title, parent, name)
+{
+ init(defaultDir);
+}
+
+void PURL::DirectoriesWidget::init(const QString &defaultDir)
+{
+ DirectoryWidget *edit = new DirectoryWidget(defaultDir);
+ _editListBox = new EditListBox(1, edit, edit->lineEdit(), this, "directories_editlistbox");
+ connect(_editListBox, SIGNAL(changed()), SIGNAL(changed()));
+}
+
+//----------------------------------------------------------------------------
+void PURL::UrlWidget::buttonClicked()
+{
+ Url url = getOpenUrl(_defaultDir, _filter, this, i18n("Select File"));
+ if ( url.isEmpty() ) return;
+ _edit->setText(url.filepath());
+ emit changed();
+}
diff --git a/src/common/gui/purl_gui.h b/src/common/gui/purl_gui.h
new file mode 100644
index 0000000..a11bedf
--- /dev/null
+++ b/src/common/gui/purl_gui.h
@@ -0,0 +1,120 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 Nicolas Hadacek <hadacek@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. *
+ ***************************************************************************/
+#ifndef PURL_GUI_H
+#define PURL_GUI_H
+
+#include <qvgroupbox.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <kurllabel.h>
+
+#include "common/global/purl.h"
+#include "editlistbox.h"
+
+namespace PURL
+{
+//-----------------------------------------------------------------------------
+extern bool hasMimetype(FileType type);
+extern QPixmap icon(FileType type);
+extern Directory getExistingDirectory(const QString &startDir, QWidget *widget, const QString &caption);
+extern Url getOpenUrl(const QString &startDir, const QString &filter, QWidget *widget,
+ const QString &caption);
+extern UrlList getOpenUrls(const QString &startDir, const QString &filter, QWidget *widget,
+ const QString &caption);
+enum SaveAction { NoSaveAction, AskOverwrite, CancelIfExists };
+extern Url getSaveUrl(const QString &startDir, const QString &filter, QWidget *widget,
+ const QString &caption, SaveAction action);
+
+//-----------------------------------------------------------------------------
+class Label : public KURLLabel
+{
+Q_OBJECT
+public:
+ Label(const QString &url, const QString &text, QWidget *parent = 0, const char *name = 0);
+
+private slots:
+ void urlClickedSlot();
+};
+
+//-----------------------------------------------------------------------------
+class BaseWidget : public QWidget
+{
+Q_OBJECT
+public:
+ BaseWidget(QWidget *parent = 0, const char *name = 0);
+ BaseWidget(const QString &defaultDir, QWidget *parent = 0, const char *name = 0);
+ KLineEdit *lineEdit() { return _edit; }
+
+signals:
+ void changed();
+
+protected slots:
+ virtual void buttonClicked() = 0;
+
+protected:
+ QString _defaultDir;
+ KLineEdit *_edit;
+
+ void init();
+};
+
+//-----------------------------------------------------------------------------
+class DirectoryWidget : public BaseWidget
+{
+Q_OBJECT
+public:
+ DirectoryWidget(QWidget *parent = 0, const char *name = 0) : BaseWidget(parent, name) {}
+ DirectoryWidget(const QString &defaultDir, QWidget *parent = 0, const char *name = 0) : BaseWidget(defaultDir, parent, name) {}
+ void setDirectory(const Directory &dir) { _edit->setText(dir.path()); }
+ Directory directory() const { return _edit->text(); }
+
+protected slots:
+ virtual void buttonClicked();
+};
+
+//-----------------------------------------------------------------------------
+class DirectoriesWidget : public QVGroupBox
+{
+Q_OBJECT
+public:
+ DirectoriesWidget(const QString &title, QWidget *parent = 0, const char *name = 0);
+ DirectoriesWidget(const QString &title, const QString &defaultDir, QWidget *parent = 0, const char *name = 0);
+ void setDirectories(const QStringList &dirs) { _editListBox->setTexts(dirs); }
+ QStringList directories() const { return _editListBox->texts(); }
+
+signals:
+ void changed();
+
+private:
+ EditListBox *_editListBox;
+ void init(const QString &defaultDir);
+};
+
+//-----------------------------------------------------------------------------
+class UrlWidget : public BaseWidget
+{
+Q_OBJECT
+public:
+ UrlWidget(const QString &filter, QWidget *parent = 0, const char *name = 0)
+ : BaseWidget(parent, name), _filter(filter) {}
+ UrlWidget(const QString &defaultDir, const QString &filter, QWidget *parent = 0, const char *name = 0)
+ : BaseWidget(defaultDir, parent, name), _filter(filter) {}
+ Url url() const { return PURL::Url::fromPathOrUrl(_edit->text()); }
+ void setUrl(const Url &url) { _edit->setText(url.filepath()); }
+
+protected slots:
+ virtual void buttonClicked();
+
+private:
+ QString _filter;
+};
+
+} // namespace
+
+#endif