diff options
Diffstat (limited to 'src/common/gui')
-rw-r--r-- | src/common/gui/Makefile.am | 7 | ||||
-rw-r--r-- | src/common/gui/config_widget.h | 107 | ||||
-rw-r--r-- | src/common/gui/container.cpp | 80 | ||||
-rw-r--r-- | src/common/gui/container.h | 58 | ||||
-rw-r--r-- | src/common/gui/dialog.cpp | 199 | ||||
-rw-r--r-- | src/common/gui/dialog.h | 77 | ||||
-rw-r--r-- | src/common/gui/editlistbox.cpp | 340 | ||||
-rw-r--r-- | src/common/gui/editlistbox.h | 95 | ||||
-rw-r--r-- | src/common/gui/hexword_gui.cpp | 136 | ||||
-rw-r--r-- | src/common/gui/hexword_gui.h | 88 | ||||
-rw-r--r-- | src/common/gui/key_gui.h | 125 | ||||
-rw-r--r-- | src/common/gui/list_container.cpp | 95 | ||||
-rw-r--r-- | src/common/gui/list_container.h | 55 | ||||
-rw-r--r-- | src/common/gui/list_view.cpp | 221 | ||||
-rw-r--r-- | src/common/gui/list_view.h | 93 | ||||
-rw-r--r-- | src/common/gui/misc_gui.cpp | 234 | ||||
-rw-r--r-- | src/common/gui/misc_gui.h | 164 | ||||
-rw-r--r-- | src/common/gui/number_gui.cpp | 72 | ||||
-rw-r--r-- | src/common/gui/number_gui.h | 40 | ||||
-rw-r--r-- | src/common/gui/pfile_ext.cpp | 114 | ||||
-rw-r--r-- | src/common/gui/pfile_ext.h | 29 | ||||
-rw-r--r-- | src/common/gui/purl_ext.cpp | 111 | ||||
-rw-r--r-- | src/common/gui/purl_gui.cpp | 151 | ||||
-rw-r--r-- | src/common/gui/purl_gui.h | 120 |
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 |