diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 114a878c64ce6f8223cfd22d76a20eb16d177e5e (patch) | |
tree | acaf47eb0fa12142d3896416a69e74cbf5a72242 /lib/widgets | |
download | tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.tar.gz tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdevelop@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'lib/widgets')
98 files changed, 12274 insertions, 0 deletions
diff --git a/lib/widgets/Mainpage.dox b/lib/widgets/Mainpage.dox new file mode 100644 index 00000000..82ae4551 --- /dev/null +++ b/lib/widgets/Mainpage.dox @@ -0,0 +1,10 @@ +/** +@mainpage The KDevelop Widgets Library + +This library contains a collection of widgets. + +<b>Link with</b>: -lkdevwidgets + +<b>Include path</b>: -I\$(kde_includes)/kdevelop/widgets +*/ + diff --git a/lib/widgets/Makefile.am b/lib/widgets/Makefile.am new file mode 100644 index 00000000..442f0c1c --- /dev/null +++ b/lib/widgets/Makefile.am @@ -0,0 +1,30 @@ +INCLUDES = -I$(top_srcdir)/lib/compat -I$(top_srcdir)/lib/interfaces $(all_includes) + +METASOURCES = AUTO + +lib_LTLIBRARIES = libkdevwidgets.la + +kdevwidgetsincludedir = $(includedir)/kdevelop/widgets + +libkdevwidgets_la_SOURCES = flagboxes.cpp qcomboview.cpp klistviewaction.cpp \ + kcomboview.cpp resizablecombo.cpp kdevhtmlpart.cpp processlinemaker.cpp \ + processwidget.cpp ksavealldialog.cpp fancylistviewitem.cpp + + +kdevwidgetsinclude_HEADERS = klistviewaction.h qcomboview.h flagboxes.h \ + ksavealldialog.h resizablecombo.h kcomboview.h kdevhtmlpart.h processlinemaker.h \ + processwidget.h fancylistviewitem.h + + +SUBDIRS = propeditor + +libkdevwidgets_la_LIBADD = $(top_builddir)/lib/interfaces/libkdevinterfaces.la +libkdevwidgets_la_LDFLAGS = -no-undefined $(all_libraries) +rcdir = $(kde_datadir)/kdevelop + +rc_DATA = kdevhtml_partui.rc + +DOXYGEN_REFERENCES = dcop interfaces kdecore kdefx kdeui khtml kmdi kio kjs kparts kutils kdevutil kdevinterfaces +DOXYGEN_PROJECTNAME = KDevelop Widgets Library +DOXYGEN_DOCDIRPREFIX = kdev +include ../../Doxyfile.am diff --git a/lib/widgets/fancylistviewitem.cpp b/lib/widgets/fancylistviewitem.cpp new file mode 100644 index 00000000..d2bdcd1e --- /dev/null +++ b/lib/widgets/fancylistviewitem.cpp @@ -0,0 +1,203 @@ +/* This file is part of the KDE project + Copyright (C) 2006 David Nolden <david.nolden.kdevelop@art-master.de> + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <qpixmap.h> +#include <qapplication.h> +#include <qnamespace.h> +#include <kdeversion.h> + +#include "fancylistviewitem.h" + + +void FancyListViewItem::init(const QString& label1, const QString& /*label2*/) { + if( !label1.isEmpty() ) { + setText(0, label1); + } +} + + +void FancyListViewItem::setItem(int column, TextPaintItem item) { + if( column >= int(m_items.size()) ) { + m_items.append( item ); + }else{ + m_items[column] = item; + } +} + + +void FancyListViewItem::setText ( int column, const QString & text ) { + if( column >= int(m_items.size()) ) { + m_items.append( TextPaintItem(text) ); + }else{ + m_items[column] = TextPaintItem(text); + } +} + + +QString FancyListViewItem::text(int column) const { + if( m_items.isEmpty() ) return ""; + return (QString)m_items[column]; +} + + +QColor FancyListViewItem::backgroundColor(int col) { + + return KListViewItem::backgroundColor(col); +} + + +///this is a modified version of the original QListViewItem::paintCell from the qt source +///multiline is not supported! + +void FancyListViewItem::paintCell( QPainter *painter, const QColorGroup &cg, + int column, int width, int align) +{ + if(column < 0 || column >= int(m_items.size()) || m_items[column].items().isEmpty()) { + QListViewItem::paintCell(painter, cg, column, width, align); + return; + } + + painter->save(); + QColorGroup grp(cg); + + int styleNum = m_items[column].items()[0].style; + TextPaintStyleStore::Item& style = m_styles.getStyle( styleNum ); + ///currently only the first background-color is used + if( style.bgValid() ) { + grp.setColor( QColorGroup::Base, style.background ); + }else{ + if(backgroundColor(column).isValid()) + grp.setColor( QColorGroup::Base, backgroundColor(column) ); ///use the nice kde background-color + } + + QListView *lv = listView(); + if ( !lv ) + return; + QPainter* p = painter; + QFontMetrics fm( p->fontMetrics() ); + + QString t = text( column ); + + int marg = lv->itemMargin(); + int r = marg; + const QPixmap * icon = pixmap( column ); + + const BackgroundMode bgmode = lv->viewport()->backgroundMode(); + const QColorGroup::ColorRole crole = QPalette::backgroundRoleFromMode( bgmode ); + p->fillRect( 0, 0, width, height(), grp.brush( crole ) ); + + if ( isSelected() && (column == 0 || lv->allColumnsShowFocus()) ) { + p->fillRect( r - marg, 0, width - r + marg, height(), cg.brush( QColorGroup::Highlight ) ); + + if ( isEnabled() || !lv ) + p->setPen( cg.highlightedText() ); + else if ( !isEnabled() && lv) + p->setPen( lv->palette().disabled().highlightedText() ); + } + { + if ( isEnabled() || !lv ) + p->setPen( cg.text() ); + else if ( !isEnabled() && lv) + p->setPen( lv->palette().disabled().text() ); + + + int iconWidth = 0; + + if ( icon ) { + iconWidth = icon->width() + lv->itemMargin(); + int xo = r; + int yo = ( height() - icon->height() ) / 2; + + if ( align & AlignBottom ) + yo = height() - icon->height(); + else if ( align & AlignTop ) + yo = 0; + +// respect horizontal alignment when there is no text for an item. + if ( t.isEmpty() ) { + if ( align & AlignRight ) + xo = width - 2 * marg - iconWidth; + else if ( align & AlignHCenter ) + xo = ( width - iconWidth ) / 2; + } + p->drawPixmap( xo, yo, *icon ); + } + + + if ( !t.isEmpty() ) { + if ( !(align & AlignTop || align & AlignBottom) ) + align |= AlignVCenter; + + r += iconWidth; + + TextPaintItem::Chain::iterator it = m_items[column].items().begin(); + while(it != m_items[column].items().end()) + { + int styleNum = (*it).style; + TextPaintStyleStore::Item& style = m_styles.getStyle( styleNum ); + + painter->setFont(style.font); + p->drawText( r, 0, width-marg-r, height(), align, (*it).text ); + r += textWidth( style.font, (*it).text ); + ++it; + } + } + } + + painter->restore(); +} + + +int FancyListViewItem::textWidth(const QFont& font, const QString& text) +{ + QFontMetrics fm( font ); + if ( multiLinesEnabled() ) + return fm.size( AlignVCenter, text ).width(); + else + return fm.width( text ); + +} + + +int FancyListViewItem::width(const QFontMetrics &fm, const QListView *lv, int column) +{ + int width = 0; + if (column >= 0 && column < (int)m_items.size() && !multiLinesEnabled()) { + TextPaintItem::Chain::iterator it = m_items[column].items().begin(); + while(it != m_items[column].items().end()) { + int styleNum = (*it).style; + TextPaintStyleStore::Item& style = m_styles.getStyle( styleNum ); + + width += textWidth( style.font, (*it).text); + ++it; + } + width += lv->itemMargin() * 2;// - lv->d->minLeftBearing - lv->d->minRightBearing; + + const QPixmap * pm = pixmap( column ); + if ( pm ) + width += pm->width() + lv->itemMargin(); + + width = QMAX( width, QApplication::globalStrut().width() ); + } + else + width = QListViewItem::width(fm, lv, column); + return width; +} + + diff --git a/lib/widgets/fancylistviewitem.h b/lib/widgets/fancylistviewitem.h new file mode 100644 index 00000000..95375af4 --- /dev/null +++ b/lib/widgets/fancylistviewitem.h @@ -0,0 +1,162 @@ +/* This file is part of the KDE project + Copyright (C) 2006 David Nolden <david.nolden.kdevelop@art-master.de> + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef FANCYLISTVIEWITEM +#define FANCYLISTVIEWITEM + +#include <qvaluevector.h> +#include <qpainter.h> +#include <qfont.h> +#include <qlistview.h> +#include <klistview.h> + +class TextPaintStyleStore { + public: + class Item { + public: + QFont font; + QColor color; + QColor background; + + Item(const QFont& f = QFont(), const QColor& c = QColor(), const QColor b = QColor() ) : font(f), color(c), background(b) { + } + + bool bgValid() { + return background.isValid(); + } + + bool colValid() { + return color.isValid(); + } + }; + + typedef QMap<int, Item> Store ; + + TextPaintStyleStore( QFont defaultFont=QFont() ) { + m_styles.insert( 0, Item( defaultFont ) ); + } + + Item& getStyle( int num ) { + Store::Iterator it = m_styles.find( num ); + if( it != m_styles.end() ) return *it; + return m_styles[0]; + } + + void addStyle( int num, Item& style ) { + m_styles[num] = style; + } + + void addStyle( int num, const QFont& font ) { + m_styles[num] = Item( font ); + } + + bool hasStyle( int num ) { + Store::Iterator it = m_styles.find( num ); + return ( it != m_styles.end() ); + } + + private: + Store m_styles; +}; + +class TextPaintItem { + public: + struct Item { + QString text; + int style; + + Item( const QString& t = "", int st = 0 ) : text(t), style(st) { + } + + }; + typedef QValueList<Item> Chain; + + Chain& items() { + return m_chain; + } + + TextPaintItem(const QString& text="") { + addItem( text ); + } + + Item& addItem(const QString& item, int style = 0) { + m_chain.append( Item(item, style) ); + return m_chain.back(); + } + + void clear() { + m_chain.clear(); + } + + operator QString () const { + QString ret; + Chain::const_iterator it = m_chain.begin(); + while(it != m_chain.end()) { + ret += (*it).text; + ++it; + } + return ret; + } + + private: + Chain m_chain; +}; + +///does not support multiple column, a "column" represents a part of the real first column +///KListViewItem is only needed for the background-color + +class FancyListViewItem : public KListViewItem +{ + public: + FancyListViewItem(TextPaintStyleStore& styles, QListView *parent, const QString &label1, const QString &label2="") : KListViewItem(parent, label1, label2), m_styles(styles) { + init(label1, label2); + } + + FancyListViewItem(TextPaintStyleStore& styles, QListViewItem *parent, const QString &label1, const QString &label2="") : KListViewItem(parent, label1, label2), m_styles(styles) { + init(label1, label2); + } + + virtual void paintCell(QPainter *painter, const QColorGroup &cg, int column, int width, int align); + virtual int width(const QFontMetrics &fm, const QListView *lv, int column); + virtual void setText ( int column, const QString & text ); + virtual QString text(int column) const; + + inline void clear() { + m_items.clear(); + } + + inline TextPaintItem& item(int column = 0) { + if(m_items.isEmpty()) { + m_items.append( TextPaintItem() ); + } + + return m_items[column]; + } + + void setItem(int column, TextPaintItem item); + private: + virtual QColor backgroundColor(int col); + void init(const QString& label1, const QString& label2); + int textWidth(const QFont& font, const QString& text); + QValueVector<TextPaintItem> m_items; + protected: + TextPaintStyleStore& m_styles; +}; + +#endif diff --git a/lib/widgets/flagboxes.cpp b/lib/widgets/flagboxes.cpp new file mode 100644 index 00000000..dbbae793 --- /dev/null +++ b/lib/widgets/flagboxes.cpp @@ -0,0 +1,643 @@ +/* This file is part of the KDE project + Copyright (C) 2000-2001 Bernd Gehrmann <bernd@kdevelop.org> + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include <klocale.h> +#include <kdebug.h> +#include <kurlrequester.h> +#include <klineedit.h> +#include <kdialogbase.h> +#include <kdeversion.h> + +#include <qapplication.h> +#include <qtooltip.h> +#include <qheader.h> +#include <qstringlist.h> +#include <qlayout.h> +#include <qlabel.h> +#include <qregexp.h> +#include <qspinbox.h> + +#include "flagboxes.h" + +// partial copy of Qt-3.1 for back-compatibility to KDE-3.0 +QString QRegExp_escape( const QString& str ) +{ + static const char meta[] = "$()*+.?[\\]^{|}"; + QString quoted = str; + int i = 0; + + while ( i < (int) quoted.length() ) { + if ( strchr(meta, quoted[i].latin1()) != 0 ) + quoted.insert( i++, "\\" ); + i++; + } + return quoted; +} + + +class FlagListToolTip : public QToolTip +{ +public: + FlagListToolTip(QWidget *parent); +protected: + void maybeTip(const QPoint &p); +}; + + +FlagListToolTip::FlagListToolTip(QWidget *parent) + : QToolTip(parent) +{} + + +void FlagListToolTip::maybeTip(const QPoint &pos) +{ + FlagListBox *listbox = static_cast<FlagListBox*>(parentWidget()); + QListViewItem *item = listbox->itemAt(pos); + FlagListItem *flitem = static_cast<FlagListItem*>(item); + + if (item) + tip(listbox->itemRect(item), flitem->desc); +} + + +FlagListItem::FlagListItem(FlagListBox *parent, const QString &flagstr, + const QString &description) + : QCheckListItem(parent, flagstr, QCheckListItem::CheckBox), + flag(flagstr), desc(description) +{} + + +FlagListItem::FlagListItem(FlagListBox *parent, const QString &flagstr, + const QString &description, const QString &offstr) + : QCheckListItem(parent, flagstr, QCheckListItem::CheckBox), + flag(flagstr), off(offstr), desc(description) +{} + + +FlagListBox::FlagListBox(QWidget *parent, const char *name) + : QListView(parent, name) +{ + setResizeMode(LastColumn); + header()->hide(); + addColumn(i18n("Flags")); + (void) new FlagListToolTip(this); +} + + +void FlagListBox::readFlags(QStringList *list) +{ + QListViewItem *item = firstChild(); + for (; item; item = item->nextSibling()) { + FlagListItem *flitem = static_cast<FlagListItem*>(item); + QStringList::Iterator sli = list->find(flitem->flag); + if (sli != list->end()) { + flitem->setOn(true); + list->remove(sli); + } + sli = list->find(flitem->off); + if (sli != list->end()) { + flitem->setOn(false); + list->remove(sli); + } + } +} + + +void FlagListBox::writeFlags(QStringList *list) +{ + QListViewItem *item = firstChild(); + for (; item; item = item->nextSibling()) { + FlagListItem *flitem = static_cast<FlagListItem*>(item); + if (flitem->isOn()) + (*list) << flitem->flag; + } +} + + +FlagCheckBox::FlagCheckBox(QWidget *parent, FlagCheckBoxController *controller, + const QString &flagstr, const QString &description) + : QCheckBox(description, parent), flag(flagstr), includeOff(false), useDef(false), defSet(false) +{ + QToolTip::add(this, flagstr); + controller->addCheckBox(this); +} + + +FlagCheckBox::FlagCheckBox(QWidget *parent, FlagCheckBoxController *controller, + const QString &flagstr, const QString &description, + const QString &offstr) + : QCheckBox(description, parent), flag(flagstr), off(offstr), includeOff(false), useDef(false), defSet(false) +{ + QToolTip::add(this, flagstr); + controller->addCheckBox(this); +} + +FlagCheckBox::FlagCheckBox(QWidget *parent, FlagCheckBoxController *controller, + const QString &flagstr, const QString &description, + const QString &offstr, const QString &defstr) + : QCheckBox(description, parent), flag(flagstr), off(offstr), def(defstr), includeOff(false), useDef(true), defSet(false) +{ + QToolTip::add(this, flagstr); + controller->addCheckBox(this); +} + +FlagCheckBoxController::FlagCheckBoxController(QStringList multiKeys) + :m_multiKeys(multiKeys) +{ +} + + +void FlagCheckBoxController::addCheckBox(FlagCheckBox *item) +{ + cblist.append(item); +} + + +void FlagCheckBoxController::readFlags(QStringList *list) +{ + //handle keys like -vxyz -> transform they into -vx -vy -vz + //very "effective" algo :( +/* QStringList addons; + for (QStringList::Iterator mk = m_multiKeys.begin(); mk != m_multiKeys.end(); ++ mk) + { + kdDebug() << "multikey " << *mk << endl; + for (QStringList::Iterator sli = list->begin(); sli != list->end(); ++sli) + { + QString key = *sli; + kdDebug() << "current key: " << key << endl; + if ( (key.length() > 3) && (key.startsWith(*mk)) ) + { + list->remove(sli); + key = key.remove(*mk); + kdDebug() << "refined key " << key << endl; + for (int i = 0; i < key.length(); ++i) + { + kdDebug() << "adding key " << *mk + key[i] << endl; + addons << *mk + key[i]; + } + } + } + } + kdDebug() << "good" << endl; + *list += addons; + + for (QStringList::Iterator sli = list->begin(); sli != list->end(); ++sli) + { + kdDebug() << "KEYS: " << *sli << endl; + } +*/ + QPtrListIterator<FlagCheckBox> it(cblist); + for (; it.current(); ++it) { + FlagCheckBox *fitem = it.current(); + QStringList::Iterator sli = list->find(fitem->flag); + if (sli != list->end()) { + fitem->setChecked(true); + fitem->useDef = false; + list->remove(sli); + } + sli = list->find(fitem->off); + if (sli != list->end()) { + fitem->setChecked(false); + fitem->includeOff = true; + fitem->useDef = false; + list->remove(sli); + } + if (!fitem->def.isEmpty()) + if (fitem->useDef && (fitem->def == fitem->flag)) + { + fitem->setChecked(true); + fitem->defSet = true; + } + else + fitem->useDef = false; + } +} + + +void FlagCheckBoxController::writeFlags(QStringList *list) +{ + QPtrListIterator<FlagCheckBox> it(cblist); + for (; it.current(); ++it) { + FlagCheckBox *fitem = it.current(); + if (fitem->isChecked() && (!fitem->useDef)) + { + (*list) << fitem->flag; + } + else if ((!fitem->off.isEmpty()) && fitem->includeOff) + (*list) << fitem->off; + else if ((fitem->def == fitem->flag) && (!fitem->isChecked())) + (*list) << fitem->off; + else if ((fitem->def == fitem->off) && (fitem->isChecked())) + (*list) << fitem->flag; + } +} + + FlagPathEditController::FlagPathEditController( ) +{ +} + + FlagPathEditController::~ FlagPathEditController( ) +{ +} + +void FlagPathEditController::readFlags( QStringList * list ) +{ +// kdDebug() << "read path flags" << endl; + QPtrListIterator<FlagPathEdit> it(plist); + for (; it.current(); ++it) { + FlagPathEdit *peitem = it.current(); + + QStringList::Iterator sli = list->begin(); + while ( sli != list->end() ) + { + // kdDebug() << "option: " << (*sli) << " flag is: " << peitem->flag << endl; + if ((*sli).startsWith(peitem->flag)) + { +// kdDebug() << "Processing.." << endl; + peitem->setText((*sli).replace(QRegExp(QRegExp_escape(peitem->flag)),"")); + sli = list->remove(sli); + continue; + } + ++sli; + } +/* QStringList::Iterator sli = list->find(peitem->flag); + if (sli != list->end()) { + peitem->setText((*sli).remove(peitem->flag)); + list->remove(sli); + }*/ + } +} + +void FlagPathEditController::writeFlags( QStringList * list ) +{ + QPtrListIterator<FlagPathEdit> it(plist); + for (; it.current(); ++it) { + FlagPathEdit *pitem = it.current(); + if (!pitem->isEmpty()) + (*list) << pitem->flag + pitem->text(); + } +} + +void FlagPathEditController::addPathEdit( FlagPathEdit * item ) +{ + plist.append(item); +} + +FlagPathEdit::FlagPathEdit( QWidget * parent, QString pathDelimiter, + FlagPathEditController * controller, const QString & flagstr, const QString & description, + KFile::Mode mode ) + : QWidget(parent), delimiter(pathDelimiter), flag(flagstr), m_description(description) +{ + QBoxLayout *topLayout = new QVBoxLayout(this, 0, 1); + topLayout->addWidget(new QLabel(description, this)); + QBoxLayout *layout = new QHBoxLayout(topLayout, KDialog::spacingHint()); + + if (delimiter.isEmpty()) + { + url = new KURLRequester(this); + url->setMode(mode); + layout->addWidget(url); + } + else + { + edit = new KLineEdit(this); + layout->addWidget(edit); + details = new QPushButton("...", this); + details->setMaximumWidth(30); + connect(details, SIGNAL(clicked()), this, SLOT(showPathDetails())); + layout->addWidget(details); + } + + QApplication::sendPostedEvents(this, QEvent::ChildInserted); + + QToolTip::add(this, flagstr); + controller->addPathEdit(this); +} + +void FlagPathEdit::showPathDetails( ) +{ + KDialogBase *dia = new KDialogBase(0, "flag_path_edit_dia", true, m_description, + KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true); + + QBoxLayout *diaLayout = new QVBoxLayout(dia, KDialog::marginHint(), KDialog::spacingHint()); + diaLayout->setAutoAdd(true); + + KURLRequester *req = new KURLRequester( dia ); + req->setMode(KFile::Directory); + KEditListBox::CustomEditor pCustomEditor; + pCustomEditor = req->customEditor(); + KEditListBox *elb = new KEditListBox( "", pCustomEditor, dia ); + dia->setMainWidget(elb); + + elb->insertStringList(QStringList::split(delimiter, text())); + + if (dia->exec() == QDialog::Accepted) + { + setText(elb->items().join(delimiter)); + } + + delete dia; +} + +void FlagPathEdit::setText( const QString text ) +{ + if (delimiter.isEmpty()) + url->setURL(text); + else + edit->setText(text); +} + +QString FlagPathEdit::text( ) +{ + if (delimiter.isEmpty()) + return url->url(); + else + return edit->text(); +} + +bool FlagPathEdit::isEmpty( ) +{ + if (delimiter.isEmpty()) + return url->url().isEmpty(); + else + return edit->text().isEmpty(); +} + +FlagRadioButton::FlagRadioButton( QWidget * parent, FlagRadioButtonController * controller, const QString & flagstr, const QString & description ) + : QRadioButton(description, parent), flag(flagstr) +{ + QToolTip::add(this, flagstr); + controller->addRadioButton(this); +} + +FlagRadioButtonController::FlagRadioButtonController(QStringList multiKeys) + :m_multiKeys(multiKeys) +{ +} + +void FlagRadioButtonController::addRadioButton(FlagRadioButton *item) +{ + cblist.append(item); +} + + +void FlagRadioButtonController::readFlags(QStringList *list) +{ + //handle keys like -vxyz -> transform they into -vx -vy -vz + //very "effective" algo :( +/* QStringList addons; + for (QStringList::Iterator mk = m_multiKeys.begin(); mk != m_multiKeys.end(); ++ mk) + { + kdDebug() << "multikey " << *mk << endl; + for (QStringList::Iterator sli = list->begin(); sli != list->end(); ++sli) + { + QString key = *sli; + kdDebug() << "current key: " << key << endl; + if ( (key.length() > 3) && (key.startsWith(*mk)) ) + { + list->remove(sli); + key = key.remove(*mk); + kdDebug() << "refined key " << key << endl; + for (int i = 0; i < key.length(); ++i) + { + kdDebug() << "adding key " << *mk + key[i] << endl; + addons << *mk + key[i]; + } + } + } + } + kdDebug() << "good" << endl; + *list += addons; + + for (QStringList::Iterator sli = list->begin(); sli != list->end(); ++sli) + { + kdDebug() << "KEYS: " << *sli << endl; + } +*/ + QPtrListIterator<FlagRadioButton> it(cblist); + for (; it.current(); ++it) { + FlagRadioButton *fitem = it.current(); + QStringList::Iterator sli = list->find(fitem->flag); + if (sli != list->end()) { + fitem->setChecked(true); + list->remove(sli); + } + } +} + + +void FlagRadioButtonController::writeFlags(QStringList *list) +{ + QPtrListIterator<FlagRadioButton> it(cblist); + for (; it.current(); ++it) { + FlagRadioButton *fitem = it.current(); + if (fitem->isChecked()) + (*list) << fitem->flag; + } +} + + FlagEditController::FlagEditController( ) +{ +} + + FlagEditController::~ FlagEditController( ) +{ +} + +void FlagEditController::readFlags( QStringList * list ) +{ + QPtrListIterator<FlagListEdit> it(plist); + for (; it.current(); ++it) { + FlagListEdit *peitem = it.current(); + + QStringList::Iterator sli = list->begin(); + while (sli != list->end()) + { + if ((*sli).startsWith(peitem->flag)) + { + peitem->appendText((*sli).replace(QRegExp(QRegExp_escape(peitem->flag)),"")); + sli = list->remove(sli); + continue; + } + ++sli; + } + } + + + QPtrListIterator<FlagSpinEdit> it2(slist); + for (; it2.current(); ++it2) { + FlagSpinEdit *sitem = it2.current(); + + QStringList::Iterator sli = list->begin(); + while ( sli != list->end() ) + { + if ((*sli).startsWith(sitem->flag)) + { + sitem->setText((*sli).replace(QRegExp(QRegExp_escape(sitem->flag)),"")); + sli = list->remove(sli); + continue; + } + ++sli; + } + } +} + +void FlagEditController::writeFlags( QStringList * list ) +{ + QPtrListIterator<FlagListEdit> it(plist); + for (; it.current(); ++it) { + FlagListEdit *pitem = it.current(); + if (!pitem->isEmpty()) + (*list) += pitem->flags(); + } + + QPtrListIterator<FlagSpinEdit> it2(slist); + for (; it2.current(); ++it2) { + FlagSpinEdit *sitem = it2.current(); + if (!sitem->isDefault()) + (*list) << sitem->flags(); + } +} + +void FlagEditController::addListEdit( FlagListEdit * item ) +{ + plist.append(item); +} + +void FlagEditController::addSpinBox(FlagSpinEdit *item) +{ + slist.append(item); +} + + +FlagListEdit::FlagListEdit( QWidget * parent, QString listDelimiter, FlagEditController * controller, + const QString & flagstr, const QString & description) + : QWidget(parent), delimiter(listDelimiter), flag(flagstr), m_description(description) +{ + QBoxLayout *topLayout = new QVBoxLayout(this, 0, 1); + topLayout->addWidget(new QLabel(description, this)); + QBoxLayout *layout = new QHBoxLayout(topLayout, KDialog::spacingHint()); + + edit = new KLineEdit(this); + layout->addWidget(edit); + if (! listDelimiter.isEmpty()) + { + details = new QPushButton("...", this); + details->setMaximumWidth(30); + connect(details, SIGNAL(clicked()), this, SLOT(showListDetails())); + layout->addWidget(details); + } + + QApplication::sendPostedEvents(this, QEvent::ChildInserted); + + QToolTip::add(this, flagstr); + controller->addListEdit(this); +} + +void FlagListEdit::setText( const QString text ) +{ + edit->setText(text); +} + +bool FlagListEdit::isEmpty( ) +{ + return edit->text().isEmpty(); +} + +QString FlagListEdit::text( ) +{ + return edit->text(); +} + +void FlagListEdit::showListDetails( ) +{ + KDialogBase *dia = new KDialogBase(0, "flag_list_edit_dia", true, m_description, + KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true); + + QBoxLayout *diaLayout = new QVBoxLayout(dia, KDialog::marginHint(), KDialog::spacingHint()); + diaLayout->setAutoAdd(true); + + KEditListBox *elb = new KEditListBox( "", dia ); + dia->setMainWidget(elb); + + elb->insertStringList(QStringList::split(delimiter, text())); + + if (dia->exec() == QDialog::Accepted) + { + setText(elb->items().join(delimiter)); + } + + delete dia; +} + +void FlagListEdit::appendText( const QString text ) +{ + edit->setText(edit->text() + (edit->text().isEmpty()?QString(""):delimiter) + text); +} + +QStringList FlagListEdit::flags( ) +{ + QStringList fl = QStringList::split(delimiter, text()); + for (QStringList::iterator it = fl.begin(); it != fl.end(); ++it) + { + (*it).prepend(flag); + } + return fl; +} + +FlagSpinEdit::FlagSpinEdit( QWidget * parent, int minVal, int maxVal, int incr, int defaultVal, FlagEditController * controller, const QString & flagstr, const QString & description ) + :QWidget(parent), m_defaultVal(defaultVal), flag(flagstr) +{ + QBoxLayout *topLayout = new QVBoxLayout(this, 0, 1); + topLayout->addWidget(new QLabel(description, this)); + + spb = new QSpinBox(minVal, maxVal, incr, this); + spb->setValue(defaultVal); + topLayout->addWidget(spb); + + QApplication::sendPostedEvents(this, QEvent::ChildInserted); + + QToolTip::add(this, flagstr); + controller->addSpinBox(this); +} + +void FlagSpinEdit::setText( const QString text ) +{ + spb->setValue(text.toInt()); +} + +QString FlagSpinEdit::text( ) +{ + return QString("%1").arg(spb->value()); +} + +QString FlagSpinEdit::flags( ) +{ + return flag + text(); +} + +bool FlagSpinEdit::isDefault( ) +{ + if (spb->value() == m_defaultVal) + return true; + return false; +} + + +#include "flagboxes.moc" diff --git a/lib/widgets/flagboxes.h b/lib/widgets/flagboxes.h new file mode 100644 index 00000000..a64a47eb --- /dev/null +++ b/lib/widgets/flagboxes.h @@ -0,0 +1,283 @@ +/* This file is part of the KDE project + Copyright (C) 2000-2001 Bernd Gehrmann <bernd@kdevelop.org> + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _FLAGBOXES_H_ +#define _FLAGBOXES_H_ + +#include <kfile.h> + +/** +@file flagboxes.h +Support classes for compiler plugins. +*/ + +#include <qlistview.h> +#include <qcheckbox.h> +#include <qradiobutton.h> +#include <qptrlist.h> +#include <qstringlist.h> + +class QSpinBox; +class FlagListBox; +class FlagListToolTip; +class FlagCheckBoxController; +class FlagRadioButtonController; +class FlagPathEditController; +class FlagEditController; +class KLineEdit; +class QPushButton; +class KURLRequester; + +/**List item holding a compiler flag.*/ +class FlagListItem : public QCheckListItem +{ +public: + FlagListItem(FlagListBox *parent, const QString &flagstr, + const QString &description); + FlagListItem(FlagListBox *parent, const QString &flagstr, + const QString &description, const QString &offstr); + ~FlagListItem() + {} +private: + QString flag; + QString off; + QString desc; + friend class FlagListToolTip; + friend class FlagListBox; +}; + + +/**List box item holding a compiler flag.*/ +class FlagListBox : public QListView +{ + Q_OBJECT +public: + FlagListBox( QWidget *parent=0, const char *name=0 ); + ~FlagListBox() + {} + + void readFlags(QStringList *list); + void writeFlags(QStringList *list); +}; + + +/**Check box item holding a compiler flag.*/ +class FlagCheckBox : public QCheckBox +{ + Q_OBJECT +public: + FlagCheckBox(QWidget *parent, FlagCheckBoxController *controller, + const QString &flagstr, const QString &description); + FlagCheckBox(QWidget *parent, FlagCheckBoxController *controller, + const QString &flagstr, const QString &description, + const QString &offstr); + FlagCheckBox(QWidget *parent, FlagCheckBoxController *controller, + const QString &flagstr, const QString &description, + const QString &offstr, const QString &defstr); + ~FlagCheckBox() + {} + +private: + QString flag; + QString off; + QString def; + bool includeOff; + bool useDef; + bool defSet; + friend class FlagCheckBoxController; +}; + +/**Radiobutton item holding an option of a compiler flag.*/ +class FlagRadioButton : public QRadioButton +{ + Q_OBJECT +public: + FlagRadioButton(QWidget *parent, FlagRadioButtonController *controller, + const QString &flagstr, const QString &description); + ~FlagRadioButton() + {} + +private: + QString flag; + friend class FlagRadioButtonController; +}; + +/**Path editor if path is a compiler flag.*/ +class FlagPathEdit: public QWidget +{ + Q_OBJECT +public: + /**If the pathDelimiter is not empty then path edit can contain a list of paths*/ + FlagPathEdit(QWidget *parent, QString pathDelimiter, FlagPathEditController *controller, + const QString &flagstr, const QString &description, KFile::Mode mode = KFile::Directory); + + ~FlagPathEdit() {} + + void setText(const QString text); + bool isEmpty(); + QString text(); + +private slots: + void showPathDetails(); + +private: + KLineEdit *edit; + QPushButton *details; + KURLRequester *url; + + QString delimiter; + QString flag; + QString m_description; + friend class FlagPathEditController; +}; + +/**List editor if list is a compiler flag.*/ +class FlagListEdit: public QWidget +{ + Q_OBJECT +public: + /**If the listDelimiter is not empty then list edit can contain a list of entries*/ + FlagListEdit(QWidget *parent, QString listDelimiter, FlagEditController *controller, + const QString &flagstr, const QString &description); + + ~FlagListEdit() {} + + void setText(const QString text); + void appendText(const QString text); + bool isEmpty(); + QString text(); + QStringList flags(); + +private slots: + void showListDetails(); + +private: + KLineEdit *edit; + QPushButton *details; + + QString delimiter; + QString flag; + QString m_description; + friend class FlagEditController; +}; + +/**Spin editor of a compiler flag.*/ +class FlagSpinEdit: public QWidget +{ +public: + FlagSpinEdit(QWidget *parent, int minVal, int maxVal, int incr, int defaultVal, FlagEditController *controller, + const QString &flagstr, const QString &description); + ~FlagSpinEdit() {} + + void setText(const QString text); + QString text(); + bool isDefault(); + + QString flags(); + +private: + int m_defaultVal; + QString flag; + + QSpinBox *spb; + + friend class FlagEditController; +}; + +/**Controller for path editors.*/ +class FlagPathEditController +{ +public: + FlagPathEditController(); + ~FlagPathEditController(); + + void readFlags(QStringList *list); + void writeFlags(QStringList *list); + +private: + void addPathEdit(FlagPathEdit *item); + QPtrList<FlagPathEdit> plist; + friend class FlagPathEdit; +}; + +/**Controller for flag editors.*/ +class FlagEditController +{ +public: + FlagEditController(); + ~FlagEditController(); + + void readFlags(QStringList *list); + void writeFlags(QStringList *list); + +private: + void addListEdit(FlagListEdit *item); + void addSpinBox(FlagSpinEdit *item); + QPtrList<FlagListEdit> plist; + QPtrList<FlagSpinEdit> slist; + friend class FlagListEdit; + friend class FlagSpinEdit; +}; + +/**Controller for check box editors.*/ +class FlagCheckBoxController +{ +public: + /**"multi key" is a list of options like -vxyz (-vx -vy -vz) + multiKeys must contain a list of option names like {-v} + in the above example. + */ + FlagCheckBoxController(QStringList multiKeys = QStringList()); + ~FlagCheckBoxController() + {} + + void readFlags(QStringList *list); + void writeFlags(QStringList *list); + + void addCheckBox(FlagCheckBox *item); +private: + QPtrList<FlagCheckBox> cblist; + + QStringList m_multiKeys; +}; + +/**Controller for radiobutton editors.*/ +class FlagRadioButtonController +{ +public: + /**multiKeys is a list of options like -vxyz (-vx -vy -vz) + multiKeys must contain a list of option names like {-v} + in the above example. + */ + FlagRadioButtonController(QStringList multiKeys = QStringList()); + ~FlagRadioButtonController() + {} + + void readFlags(QStringList *list); + void writeFlags(QStringList *list); + + void addRadioButton(FlagRadioButton *item); +private: + QPtrList<FlagRadioButton> cblist; + + QStringList m_multiKeys; +}; + +#endif diff --git a/lib/widgets/kcomboview.cpp b/lib/widgets/kcomboview.cpp new file mode 100644 index 00000000..ecaf4593 --- /dev/null +++ b/lib/widgets/kcomboview.cpp @@ -0,0 +1,101 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include <klineedit.h> +#include <klistview.h> +#include <kcompletionbox.h> +#include <qheader.h> +#include <qmap.h> + +#include "kcomboview.h" + + +KComboView::KComboView( bool rw, int defaultWidth, QWidget* parent, const char* name , CustomCompleter* comp) + :QComboView(rw, parent, name), m_comp( comp ), m_defaultWidth(defaultWidth) +{ + if (rw) + { + KLineEdit *ed = new KLineEdit(this, "combo edit"); + ed->setCompletionMode(KGlobalSettings::CompletionPopup); + ed->setCompletionObject(m_comp); + ed->completionBox()->setHScrollBarMode(QListBox::Auto); + setLineEdit(ed); + } + setMinimumWidth(defaultWidth); +} + +KComboView::~KComboView() { + delete m_comp; +} + +void KComboView::addItem(QListViewItem *it) +{ + m_comp->addItem(it->text(0)); +} + +void KComboView::removeItem(QListViewItem *it) +{ + if (it == currentItem()) + { + setCurrentItem(0); + setCurrentText(m_defaultText); + } + m_comp->removeItem(it->text(0)); + delete it; +} + +void KComboView::renameItem(QListViewItem *it, const QString &newName) +{ + m_comp->removeItem(it->text(0)); + it->setText(0, newName); + m_comp->addItem(newName); +} + +void KComboView::clear( ) +{ + m_comp->clear(); + QComboView::clear(); + + setCurrentText(m_defaultText); +} + +int KComboView::defaultWidth( ) +{ + return m_defaultWidth; +} + +void KComboView::setDefaultText( const QString & text ) +{ + m_defaultText = text; +} + +void KComboView::setUpListView() +{ + KListView *listView = new KListView( this, "in-combo" ); + listView->setRootIsDecorated( false ); + listView->setAllColumnsShowFocus(true); + listView->addColumn(""); + listView->setResizeMode(QListView::LastColumn); + + listView->header()->hide(); + + setListView(listView); +} + + +#include "kcomboview.moc" diff --git a/lib/widgets/kcomboview.h b/lib/widgets/kcomboview.h new file mode 100644 index 00000000..9696d328 --- /dev/null +++ b/lib/widgets/kcomboview.h @@ -0,0 +1,80 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef KCOMBOVIEW_H +#define KCOMBOVIEW_H + +#include <kcompletion.h> + +#include "qcomboview.h" + +/** +@file kcomboview.h +KComboView class. +*/ + +/** +KComboView - a combo with a QListView as a popup widget. +KComboView provides text completion. +@sa QComboView for a description. +*/ + + +///This can be used to insert own KCompletion-implementations +class CustomCompleter : public KCompletion { + public: + virtual void addItem (const QString &item) { + KCompletion::addItem( item ); + } + + virtual void removeItem (const QString &item) { + KCompletion::removeItem( item ); + } + + virtual void clear() { + KCompletion::clear(); + } +}; + + +class KComboView: public QComboView +{ + Q_OBJECT +public: + ///The combo-view takes the ownership of the completer and deletes it on destruction + KComboView( bool rw, int defaultWidth = 100, QWidget* parent=0, const char* name=0, CustomCompleter* completer = new CustomCompleter() ); + virtual ~KComboView(); + + virtual void addItem(QListViewItem *it); + virtual void removeItem(QListViewItem *it); + virtual void renameItem(QListViewItem *it, const QString &newName); + + virtual void setDefaultText(const QString &text); + + virtual void clear(); + + int defaultWidth(); +private: + virtual void setUpListView(); + + CustomCompleter* m_comp; + int m_defaultWidth; + QString m_defaultText; +}; + +#endif diff --git a/lib/widgets/kdevhtml_partui.rc b/lib/widgets/kdevhtml_partui.rc new file mode 100644 index 00000000..5a55b7bf --- /dev/null +++ b/lib/widgets/kdevhtml_partui.rc @@ -0,0 +1,18 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui version="3" name="KDevHTMLPart" > + +<MenuBar> + <Menu name="file" noMerge="0"><text>&File</text> + <Action name="print_doc" group="print_merge"/> + </Menu> + <Menu name="edit" noMerge="0"> + <Action name="copy_doc_selection" group="edit_paste_merge"/> + </Menu> +</MenuBar> + +<ToolBar name="browserToolBar"> + <Action name="browser_back" group="browser_operations"/> + <Action name="browser_forward" group="browser_operations"/> +</ToolBar> + +</kpartgui> diff --git a/lib/widgets/kdevhtmlpart.cpp b/lib/widgets/kdevhtmlpart.cpp new file mode 100644 index 00000000..688e373a --- /dev/null +++ b/lib/widgets/kdevhtmlpart.cpp @@ -0,0 +1,512 @@ +#include <qfile.h> +#include <qclipboard.h> +#include <qapplication.h> + +#include <kxmlguiclient.h> +#include <kaction.h> +#include <kstdaction.h> +#include <kstandarddirs.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <kiconloader.h> +#include <kmainwindow.h> +#include <khtmlview.h> +#include <khtml_settings.h> +#include <kconfig.h> + +#include <kdevmainwindow.h> + + +#include "kdevhtmlpart.h" + +KDevHTMLPart::KDevHTMLPart() + : KHTMLPart(0L, 0L, 0L, "KDevHTMLPart", DefaultGUI ) +{ + setXMLFile(locate("data", "kdevelop/kdevhtml_partui.rc"), true); + + connect(browserExtension(), SIGNAL(openURLRequestDelayed(const KURL &,const KParts::URLArgs &)), + this, SLOT(openURLRequest(const KURL &)) ); + + connect(this, SIGNAL(started(KIO::Job *)), this, SLOT(slotStarted(KIO::Job* ))); + connect(this, SIGNAL(completed()), this, SLOT(slotCompleted())); + connect(this, SIGNAL(canceled(const QString &)), this, SLOT(slotCancelled(const QString &))); + + KActionCollection * actions = actionCollection();// new KActionCollection( this ); + reloadAction = new KAction( i18n( "Reload" ), "reload", 0, + this, SLOT( slotReload() ), actions, "doc_reload" ); + reloadAction->setWhatsThis(i18n("<b>Reload</b><p>Reloads the current document.")); + stopAction = new KAction( i18n( "Stop" ), "stop", 0, + this, SLOT( slotStop() ), actions, "doc_stop" ); + stopAction->setWhatsThis(i18n("<b>Stop</b><p>Stops the loading of current document.")); + duplicateAction = new KAction( i18n( "Duplicate Tab" ), "window_new", 0, + this, SLOT( slotDuplicate() ), actions, "doc_dup" ); + duplicateAction->setWhatsThis(i18n("<b>Duplicate window</b><p>Opens current document in a new window.")); + printAction = KStdAction::print(this, SLOT(slotPrint()), actions, "print_doc"); + copyAction = KStdAction::copy(this, SLOT(slotCopy()), actions, "copy_doc_selection"); + + connect( this, SIGNAL(popupMenu(const QString &, const QPoint &)), this, SLOT(popup(const QString &, const QPoint &))); + connect(this, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged())); + +//BEGIN documentation history stuff + + m_backAction = new KToolBarPopupAction(i18n("Back"), "back", 0, + this, SLOT(slotBack()), + actions, "browser_back"); + m_backAction->setEnabled( false ); + m_backAction->setToolTip(i18n("Back")); + m_backAction->setWhatsThis(i18n("<b>Back</b><p>Moves backwards one step in the <b>documentation</b> browsing history.")); + + connect(m_backAction->popupMenu(), SIGNAL(aboutToShow()), + this, SLOT(slotBackAboutToShow())); + connect(m_backAction->popupMenu(), SIGNAL(activated(int)), + this, SLOT(slotPopupActivated(int))); + + m_forwardAction = new KToolBarPopupAction(i18n("Forward"), "forward", 0, + this, SLOT(slotForward()), + actions, "browser_forward"); + m_forwardAction->setEnabled( false ); + m_forwardAction->setToolTip(i18n("Forward")); + m_forwardAction->setWhatsThis(i18n("<b>Forward</b><p>Moves forward one step in the <b>documentation</b> browsing history.")); + + connect(m_forwardAction->popupMenu(), SIGNAL(aboutToShow()), + this, SLOT(slotForwardAboutToShow())); + connect(m_forwardAction->popupMenu(), SIGNAL(activated(int)), + this, SLOT(slotPopupActivated(int))); + + m_restoring = false; + m_Current = m_history.end(); +//END documentation history stuff + + //settings: + KConfig *appConfig = KGlobal::config(); + appConfig->setGroup("KHTMLPart"); + setStandardFont(appConfig->readEntry("StandardFont", + settings()->stdFontName())); + setFixedFont(appConfig->readEntry("FixedFont", + settings()->fixedFontName())); + setZoomFactor(appConfig->readEntry("Zoom", "100").toInt()); +} + +void KDevHTMLPart::popup( const QString & url, const QPoint & p ) +{ +// KPopupMenu popup( i18n( "Documentation Viewer" ), this->widget() ); + KPopupMenu popup(this->widget()); + + bool needSep = false; + int idNewWindow = -2; + if (!url.isEmpty() && (m_options & CanOpenInNewWindow)) + { + idNewWindow = popup.insertItem(SmallIcon("window_new"),i18n("Open in New Tab")); + popup.setWhatsThis(idNewWindow, i18n("<b>Open in new window</b><p>Opens current link in a new window.")); + needSep = true; + } + if (m_options & CanDuplicate) + { + duplicateAction->plug(&popup); + needSep = true; + } + if (needSep) + popup.insertSeparator(); + + m_backAction->plug( &popup ); + m_forwardAction->plug( &popup ); + reloadAction->plug(&popup); +// stopAction->plug(&popup); + popup.insertSeparator(); + + copyAction->plug( &popup ); + popup.insertSeparator(); + + printAction->plug(&popup); + popup.insertSeparator(); + + KAction * incFontAction = this->action("incFontSizes"); + KAction * decFontAction = this->action("decFontSizes"); + if ( incFontAction && decFontAction ) + { + incFontAction->plug( &popup ); + decFontAction->plug( &popup ); + popup.insertSeparator(); + } + + KAction *ac = action("setEncoding"); + if (ac) + ac->plug(&popup); + + int r = popup.exec(p); + + if (r == idNewWindow) + { + KURL kurl; + if (!KURL(url).path().startsWith("/")) + { + kdDebug() << "processing relative url: " << url << endl; + if (url.startsWith("#")) + { + kurl = KURL(KDevHTMLPart::url()); + kurl.setRef(url.mid(1)); + } + else + kurl = KURL(KDevHTMLPart::url().upURL().url(true)+url); + } + else + kurl = KURL(url); + + if (kurl.isValid()) + slotOpenInNewWindow(kurl); + } +} + +void KDevHTMLPart::setContext(const QString &context) +{ + m_context = context; +} + + +QString KDevHTMLPart::context() const +{ + return m_context; +} + + +// Note: this function is a copy of code in kdecore/kconfigbase.cpp ;) +static bool isUtf8(const char *buf) { + int i, n; + register unsigned char c; + bool gotone = false; + +#define F 0 /* character never appears in text */ +#define T 1 /* character appears in plain ASCII text */ +#define I 2 /* character appears in ISO-8859 text */ +#define X 3 /* character appears in non-ISO extended ASCII (Mac, IBM PC) */ + + static const unsigned char text_chars[256] = { + /* BEL BS HT LF FF CR */ + F, F, F, F, F, F, F, T, T, T, T, F, T, T, F, F, /* 0x0X */ + /* ESC */ + F, F, F, F, F, F, F, F, F, F, F, T, F, F, F, F, /* 0x1X */ + T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x2X */ + T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x3X */ + T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x4X */ + T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x5X */ + T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x6X */ + T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, /* 0x7X */ + /* NEL */ + X, X, X, X, X, T, X, X, X, X, X, X, X, X, X, X, /* 0x8X */ + X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, /* 0x9X */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xaX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xbX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xcX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xdX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xeX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I /* 0xfX */ + }; + + /* *ulen = 0; */ + for (i = 0; (c = buf[i]); i++) { + if ((c & 0x80) == 0) { /* 0xxxxxxx is plain ASCII */ + /* + * Even if the whole file is valid UTF-8 sequences, + * still reject it if it uses weird control characters. + */ + + if (text_chars[c] != T) + return false; + + } else if ((c & 0x40) == 0) { /* 10xxxxxx never 1st byte */ + return false; + } else { /* 11xxxxxx begins UTF-8 */ + int following; + + if ((c & 0x20) == 0) { /* 110xxxxx */ + following = 1; + } else if ((c & 0x10) == 0) { /* 1110xxxx */ + following = 2; + } else if ((c & 0x08) == 0) { /* 11110xxx */ + following = 3; + } else if ((c & 0x04) == 0) { /* 111110xx */ + following = 4; + } else if ((c & 0x02) == 0) { /* 1111110x */ + following = 5; + } else + return false; + + for (n = 0; n < following; n++) { + i++; + if (!(c = buf[i])) + goto done; + + if ((c & 0x80) == 0 || (c & 0x40)) + return false; + } + gotone = true; + } + } +done: + return gotone; /* don't claim it's UTF-8 if it's all 7-bit */ +} +#undef F +#undef T +#undef I +#undef X + +QString KDevHTMLPart::resolveEnvVarsInURL(const QString& url) +{ + // check for environment variables and make necessary translations + QString path = url; + int nDollarPos = path.find( '$' ); + + // Note: the while loop below is a copy of code in kdecore/kconfigbase.cpp ;) + while( nDollarPos != -1 && nDollarPos+1 < static_cast<int>(path.length())) { + // there is at least one $ + if( (path)[nDollarPos+1] == '(' ) { + uint nEndPos = nDollarPos+1; + // the next character is no $ + while ( (nEndPos <= path.length()) && (path[nEndPos]!=')') ) + nEndPos++; + nEndPos++; + QString cmd = path.mid( nDollarPos+2, nEndPos-nDollarPos-3 ); + + QString result; + FILE *fs = popen(QFile::encodeName(cmd).data(), "r"); + if (fs) + { + QTextStream ts(fs, IO_ReadOnly); + result = ts.read().stripWhiteSpace(); + pclose(fs); + } + path.replace( nDollarPos, nEndPos-nDollarPos, result ); + } else if( (path)[nDollarPos+1] != '$' ) { + uint nEndPos = nDollarPos+1; + // the next character is no $ + QString aVarName; + if (path[nEndPos]=='{') + { + while ( (nEndPos <= path.length()) && (path[nEndPos]!='}') ) + nEndPos++; + nEndPos++; + aVarName = path.mid( nDollarPos+2, nEndPos-nDollarPos-3 ); + } + else + { + while ( nEndPos <= path.length() && (path[nEndPos].isNumber() + || path[nEndPos].isLetter() || path[nEndPos]=='_' ) ) + nEndPos++; + aVarName = path.mid( nDollarPos+1, nEndPos-nDollarPos-1 ); + } + const char* pEnv = 0; + if (!aVarName.isEmpty()) + pEnv = getenv( aVarName.ascii() ); + if( pEnv ) { + // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!! + // A environment variables may contain values in 8bit + // locale cpecified encoding or in UTF8 encoding. + if (isUtf8( pEnv )) + path.replace( nDollarPos, nEndPos-nDollarPos, QString::fromUtf8(pEnv) ); + else + path.replace( nDollarPos, nEndPos-nDollarPos, QString::fromLocal8Bit(pEnv) ); + } else + path.remove( nDollarPos, nEndPos-nDollarPos ); + } else { + // remove one of the dollar signs + path.remove( nDollarPos, 1 ); + nDollarPos++; + } + nDollarPos = path.find( '$', nDollarPos ); + } + + return path; +} + +bool KDevHTMLPart::openURL(const KURL &url) +{ + QString path = resolveEnvVarsInURL(url.url()); + KURL newUrl(path); + + bool retval = KHTMLPart::openURL(newUrl); + if ( retval ) + { + emit fileNameChanged(this); + if ( !m_restoring ) + { + addHistoryEntry(); + } + } + + m_backAction->setEnabled( m_Current != m_history.begin() ); + m_forwardAction->setEnabled( m_Current != m_history.fromLast() ); + + return retval; +} + +void KDevHTMLPart::openURLRequest(const KURL &url) +{ + openURL( url ); +} + +void KDevHTMLPart::slotReload( ) +{ + openURL( url() ); +} + +void KDevHTMLPart::slotStop( ) +{ + closeURL(); +} + +void KDevHTMLPart::slotStarted( KIO::Job * ) +{ + stopAction->setEnabled(true); +} + +void KDevHTMLPart::slotCompleted( ) +{ + stopAction->setEnabled(false); +} + +void KDevHTMLPart::slotCancelled( const QString & /*errMsg*/ ) +{ + stopAction->setEnabled(false); +} + +/*void KDevHTMLPart::slotDuplicate( ) +{ + PartController::getInstance()->showDocument(url(), true); +}*/ + +void KDevHTMLPart::slotPrint( ) +{ + view()->print(); +} + +void KDevHTMLPart::slotBack() +{ + if ( m_Current != m_history.begin() ) + { + --m_Current; + m_restoring = true; + openURL( (*m_Current).url ); + m_restoring = false; + } +} + +void KDevHTMLPart::slotForward() +{ + if ( m_Current != m_history.fromLast() ) + { + ++m_Current; + m_restoring = true; + openURL( (*m_Current).url ); + m_restoring = false; + } +} + +void KDevHTMLPart::slotBackAboutToShow() +{ + KPopupMenu *popup = m_backAction->popupMenu(); + popup->clear(); + + if ( m_Current == m_history.begin() ) return; + + QValueList<DocumentationHistoryEntry>::Iterator it = m_Current; + --it; + + int i = 0; + while( i < 10 ) + { + if ( it == m_history.begin() ) + { + popup->insertItem( (*it).url.url(), (*it).id ); + return; + } + + popup->insertItem( (*it).url.url(), (*it).id ); + ++i; + --it; + } +} + +void KDevHTMLPart::slotForwardAboutToShow() +{ + KPopupMenu *popup = m_forwardAction->popupMenu(); + popup->clear(); + + if ( m_Current == m_history.fromLast() ) return; + + QValueList<DocumentationHistoryEntry>::Iterator it = m_Current; + ++it; + + int i = 0; + while( i < 10 ) + { + if ( it == m_history.fromLast() ) + { + popup->insertItem( (*it).url.url(), (*it).id ); + return; + } + + popup->insertItem( (*it).url.url(), (*it).id ); + ++i; + ++it; + } +} + +void KDevHTMLPart::slotPopupActivated( int id ) +{ + kdDebug(9000) << "id: " << id << endl; + + QValueList<DocumentationHistoryEntry>::Iterator it = m_history.begin(); + while( it != m_history.end() ) + { + kdDebug(9000) << "(*it).id: " << (*it).id << endl; + if ( (*it).id == id ) + { + m_Current = it; + m_restoring = true; + openURL( (*m_Current).url ); + m_restoring = false; + return; + } + ++it; + } +} + +void KDevHTMLPart::addHistoryEntry() +{ + QValueList<DocumentationHistoryEntry>::Iterator it = m_Current; + + // if We're not already the last entry, we truncate the list here before adding an entry + if ( it != m_history.end() && it != m_history.fromLast() ) + { + m_history.erase( ++it, m_history.end() ); + } + + DocumentationHistoryEntry newEntry( url() ); + + // Only save the new entry if it is different from the last + if ( newEntry.url != (*m_Current).url ) + { + m_history.append( newEntry ); + m_Current = m_history.fromLast(); + } +} + +void KDevHTMLPart::slotCopy( ) +{ + QString text = selectedText(); + text.replace( QChar( 0xa0 ), ' ' ); + QClipboard *cb = QApplication::clipboard(); + disconnect( cb, SIGNAL( selectionChanged() ), this, SLOT( slotClearSelection() ) ); + cb->setText(text); + connect( cb, SIGNAL( selectionChanged() ), this, SLOT( slotClearSelection() ) ); +} + +void KDevHTMLPart::slotSelectionChanged( ) +{ + if (selectedText().isEmpty()) + copyAction->setEnabled(false); + else + copyAction->setEnabled(true); +} + +#include "kdevhtmlpart.moc" diff --git a/lib/widgets/kdevhtmlpart.h b/lib/widgets/kdevhtmlpart.h new file mode 100644 index 00000000..944f1e9b --- /dev/null +++ b/lib/widgets/kdevhtmlpart.h @@ -0,0 +1,111 @@ +#ifndef __KDEVHTMLPART_H__ +#define __KDEVHTMLPART_H__ + +#include <stdlib.h> + +#include <qdatetime.h> + +#include <khtml_part.h> + +/** +@file kdevhtmlpart.h +Customized KHTML part for KDevelop. +*/ + +class KAction; +class KToolBarPopupAction; +class KParts::ReadOnlyPart; + +struct DocumentationHistoryEntry { + KURL url; + int id; + + DocumentationHistoryEntry() {} + DocumentationHistoryEntry( const KURL& u ): url( u ) + { + id = abs( QTime::currentTime().msecsTo( QTime() ) ); // nasty, but should provide a reasonably unique number + } +}; + +/** +Customized KHTML part for KDevelop. +Used as HTML documentation and file viewer. + +Represents customized BrowserViewGUI mode of KHTMLPart. Provides also actions for: +- reload; +- stop; +- duplicate; +- print; +- copy text; +- back; +- forward. +. +It has it's own popup menu and font/zoom settings. +*/ +class KDevHTMLPart : public KHTMLPart +{ + Q_OBJECT + +public: + + enum Options { CanDuplicate=1, CanOpenInNewWindow=2 }; + + KDevHTMLPart(); + + void setContext(const QString &context); + QString context() const; + virtual bool openURL(const KURL &url); + static QString resolveEnvVarsInURL(const QString& url); + + void setOptions(int options) { m_options = options; } + +signals: + void fileNameChanged(KParts::ReadOnlyPart *part); + +protected slots: + + void slotStarted(KIO::Job *); + void slotCompleted(); + void slotCancelled(const QString &errMsg); + + void openURLRequest(const KURL &url); + void popup( const QString & url, const QPoint & p ); + + void slotReload(); + void slotStop(); + virtual void slotDuplicate() = 0; + virtual void slotOpenInNewWindow(const KURL &url) = 0; + void slotPrint(); + void slotCopy(); + void slotSelectionChanged(); + + void slotBack(); + void slotForward(); + void slotBackAboutToShow(); + void slotForwardAboutToShow(); + + void slotPopupActivated( int id ); + void addHistoryEntry(); + + +private: + + QValueList< DocumentationHistoryEntry > m_history; + QValueList< DocumentationHistoryEntry >::Iterator m_Current; + + KToolBarPopupAction* m_backAction; + KToolBarPopupAction* m_forwardAction; + + bool m_restoring; + + QString m_context; + KAction *stopAction; + KAction *reloadAction; + KAction *duplicateAction; + KAction *printAction; + KAction *copyAction; + + int m_options; +}; + +#endif diff --git a/lib/widgets/kdevtabwidget.cpp b/lib/widgets/kdevtabwidget.cpp new file mode 100644 index 00000000..49925115 --- /dev/null +++ b/lib/widgets/kdevtabwidget.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2001-2003 * + * The KDevelop Team * + * * + * 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 <qpopupmenu.h> + +#include <kglobal.h> +#include <klocale.h> +#include <kicontheme.h> +#include <kiconloader.h> + +#include "kdevtabwidget.h" + +KDevTabWidget::KDevTabWidget(QWidget *parent, const char *name) : QTabWidget(parent,name) +{ + m_pTabBar = new KTabBar(this, "tabbar"); + setTabBar(m_pTabBar); + connect(m_pTabBar, SIGNAL(closeWindow(const QWidget*)), this, SIGNAL(closeWindow(const QWidget*))); + connect(m_pTabBar, SIGNAL(closeOthers(QWidget*)), this, SIGNAL(closeOthers(QWidget*))); +} + +KTabBar::KTabBar(QWidget *parent, const char *name) : QTabBar(parent,name) +{ + m_pPopupMenu = new QPopupMenu(this); + + QPixmap closePixmap = KGlobal::instance()->iconLoader()->loadIcon( "tab_remove", KIcon::Small, 0, KIcon::DefaultState, 0, true ); + if (closePixmap.isNull()) + closePixmap = SmallIcon("fileclose"); + + m_pPopupMenu->insertItem(closePixmap, i18n("&Close"), this, SLOT(closeWindowSlot())); + m_pPopupMenu->insertItem(i18n("Close &Others"), this, SLOT(closeOthersSlot())); +} + +void KTabBar::closeWindowSlot() +{ + emit closeWindow(m_pPage); +} + +void KTabBar::closeOthersSlot() +{ + emit closeOthers(m_pPage); +} + +void KTabBar::mousePressEvent(QMouseEvent *e) +{ + if(e->button() == Qt::RightButton) { + + QTab *tab = selectTab(e->pos() ); + if( tab == 0L ) return; + + m_pPage = ((KDevTabWidget*)parent())->page(indexOf(tab->identifier() ) ); + if(m_pPage == 0L) return; + + m_pPopupMenu->exec(mapToGlobal(e->pos())); + } + QTabBar::mousePressEvent(e); +} + +#include "kdevtabwidget.moc" diff --git a/lib/widgets/klistviewaction.cpp b/lib/widgets/klistviewaction.cpp new file mode 100644 index 00000000..f9e4e1b9 --- /dev/null +++ b/lib/widgets/klistviewaction.cpp @@ -0,0 +1,86 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include "klistviewaction.h" +#include "kcomboview.h" +#include "resizablecombo.h" + +#include <qtooltip.h> +#include <qwhatsthis.h> + +#include <kconfig.h> +#include <kglobal.h> + +KListViewAction::~KListViewAction() +{ + KConfig *config = KGlobal::config(); + if (config && m_view->name()) + { + config->setGroup("KListViewAction"); + config->writeEntry(m_view->name(), m_view->width()); + } + delete m_view; +} + +KListViewAction::KListViewAction(KComboView *view, const QString & text, const KShortcut & cut, + const QObject * receiver, const char * slot, KActionCollection * parent, const char * name ): + KWidgetAction(view, text, cut, receiver, slot, parent, name), m_view(view) +{ + m_view->setDuplicatesEnabled(false); + m_view->setInsertionPolicy(KComboView::NoInsertion); + + loadComboWidth(); +} + +KListViewAction::KListViewAction( KComboView * view, const QString & text, const KShortcut & cut, + const QObject * receiver, const char * slot, KActionCollection * parent, const char * name, const bool /*dummy*/ ): + KWidgetAction(new ResizableCombo(view), text, cut, receiver, slot, parent, name), m_view(view) +{ + m_view->setDuplicatesEnabled(false); + m_view->setInsertionPolicy(KComboView::NoInsertion); + + loadComboWidth(); +} + +KComboView * KListViewAction::view( ) const +{ + return m_view; +} + +void KListViewAction::setToolTip( const QString & str ) +{ + QToolTip::remove(m_view); + QToolTip::add(m_view, str); +} + +void KListViewAction::setWhatsThis( const QString & str ) +{ + QWhatsThis::remove(m_view); + QWhatsThis::add(m_view, str); +} + +void KListViewAction::loadComboWidth( ) +{ + KConfig *config = KGlobal::config(); + if (config && m_view->name()) + { + config->setGroup("KListViewAction"); + m_view->setMinimumWidth(config->readNumEntry(m_view->name(), m_view->defaultWidth())); + } +} + diff --git a/lib/widgets/klistviewaction.h b/lib/widgets/klistviewaction.h new file mode 100644 index 00000000..1dbacf09 --- /dev/null +++ b/lib/widgets/klistviewaction.h @@ -0,0 +1,56 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef KLISTVIEWACTION_H +#define KLISTVIEWACTION_H + +#include <kxmlguiclient.h> +#include <kdeversion.h> +#include <kaction.h> + +class KComboView; + +/** +@file klistviewaction.h +Widget action with KComboView. +*/ + + +/** +Widget action with KComboView. +Can be used on toolbars. It appears as @ref ResizableCombo. +*/ +class KListViewAction: public KWidgetAction +{ +public: + KListViewAction(KComboView *view, const QString &text, const KShortcut &cut, const QObject *receiver, const char *slot, KActionCollection *parent, const char *name); + KListViewAction(KComboView *view, const QString &text, const KShortcut &cut, const QObject *receiver, const char *slot, KActionCollection *parent, const char *name, const bool); + + ~KListViewAction(); + + KComboView *view() const; + void setToolTip(const QString & str); + void setWhatsThis(const QString &str); + +private: + void loadComboWidth(); + + KComboView *m_view; +}; + +#endif diff --git a/lib/widgets/ksavealldialog.cpp b/lib/widgets/ksavealldialog.cpp new file mode 100644 index 00000000..dec2a80c --- /dev/null +++ b/lib/widgets/ksavealldialog.cpp @@ -0,0 +1,189 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Harald Fernengel <harry@kdevelop.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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <qvbox.h> +#include <qlabel.h> +#include <qheader.h> + +#include <klocale.h> +#include <kpushbutton.h> +#include <klistbox.h> +#include <klistview.h> +#include <kstdguiitem.h> + +#include "ksavealldialog.h" + +namespace +{ + +class CheckURL : public QCheckListItem +{ +public: + CheckURL( QListView * lv, KURL const & url ) + : QCheckListItem( lv, url.path(), QCheckListItem::CheckBox), + _url( url ) + {} + + KURL const & url() const { return _url; } + +private: + KURL _url; +}; + +} + + +KSaveSelectDialog::KSaveSelectDialog( KURL::List const & filelist, KURL::List const & ignorelist, QWidget * parent ) : + KDialogBase( parent, "SaveAllDialog", true, i18n("Save Modified Files?"), + Ok | User1 | Close ) +{ + QVBox *top = makeVBoxMainWidget(); + + (void)new QLabel( i18n("The following files have been modified. Save them?"), top ); + + _listview = new KListView( top ); + _listview->addColumn( "" ); + _listview->header()->hide(); + _listview->setResizeMode( QListView::LastColumn ); + + setButtonOK( KGuiItem(i18n("Save &Selected"), QString::null, i18n("Saves all selected files")) ); + setButtonText( User1, i18n("Save &None") ); + setButtonText( Close, KStdGuiItem::cancel().text() ); + setButtonTip( User1, i18n("Lose all modifications") ); + setButtonTip( Close, i18n("Cancels the action") ); + + KURL::List::ConstIterator it = filelist.begin(); + while ( it != filelist.end() ) + { + if ( !ignorelist.contains( *it ) ) + { + QCheckListItem * x = new CheckURL( _listview, *it ); + x->setOn( true ); + } + ++it; + } + + connect( this, SIGNAL(closeClicked()), this, SLOT(cancel()) ); + connect( this, SIGNAL(okClicked()), this, SLOT(save()) ); + connect( this, SIGNAL(user1Clicked()), this, SLOT(saveNone()) ); +} + +KSaveSelectDialog::~KSaveSelectDialog() {} + +void KSaveSelectDialog::saveNone( ) +{ + // deselect all + CheckURL * item = static_cast<CheckURL*>( _listview->firstChild() ); + while ( item ) + { + item->setOn( false ); + item = static_cast<CheckURL*>( item->nextSibling() ); + } + + QDialog::accept(); +} + +void KSaveSelectDialog::save( ) +{ + QDialog::accept(); +} + +void KSaveSelectDialog::cancel( ) +{ + QDialog::reject(); +} + +KURL::List KSaveSelectDialog::filesToSave( ) +{ + KURL::List filelist; + CheckURL const * item = static_cast<CheckURL*>( _listview->firstChild() ); + while ( item ) + { + if ( item->isOn() ) + { + filelist << item->url(); + } + item = static_cast<CheckURL*>( item->nextSibling() ); + } + return filelist; +} + +KURL::List KSaveSelectDialog::filesNotToSave( ) +{ + KURL::List filelist; + CheckURL const * item = static_cast<CheckURL*>( _listview->firstChild() ); + while ( item ) + { + if ( ! item->isOn() ) + { + filelist << item->url(); + } + item = static_cast<CheckURL*>( item->nextSibling() ); + } + return filelist; +} + + +KSaveAllDialog::KSaveAllDialog( const QStringList& filenames, QWidget* parent ) : + KDialogBase( parent, "SaveAllDialog", true, i18n("Save Modified Files?"), + Ok | User1 | Close ) +{ + m_result = Cancel; + + QVBox *top = makeVBoxMainWidget(); + + (void)new QLabel( i18n("The following files have been modified. Save them?"), top ); + KListBox* lb = new KListBox( top ); + lb->setMinimumHeight( lb->fontMetrics().height() * 5 ); + lb->insertStringList( filenames ); + + setButtonOK( KGuiItem(i18n("Save &All"), QString::null, i18n("Saves all modified files")) ); + setButtonText( User1, i18n("Save &None") ); + setButtonText( Close, KStdGuiItem::cancel().text() ); + setButtonTip( User1, i18n("Lose all modifications") ); + setButtonTip( Close, i18n("Cancels the action") ); + + connect( this, SIGNAL(closeClicked()), this, SLOT(cancel()) ); + connect( this, SIGNAL(okClicked()), this, SLOT(saveAll()) ); + connect( this, SIGNAL(user1Clicked()), this, SLOT(revert()) ); +} + +KSaveAllDialog::~KSaveAllDialog() +{ +} + +void KSaveAllDialog::revert() +{ + m_result = Revert; + QDialog::accept(); +} + +void KSaveAllDialog::saveAll() +{ + m_result = SaveAll; + QDialog::accept(); +} + +void KSaveAllDialog::cancel() +{ + m_result = Cancel; + QDialog::reject(); +} + +#include "ksavealldialog.moc" diff --git a/lib/widgets/ksavealldialog.h b/lib/widgets/ksavealldialog.h new file mode 100644 index 00000000..9d204bb7 --- /dev/null +++ b/lib/widgets/ksavealldialog.h @@ -0,0 +1,83 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Harald Fernengel <harry@kdevelop.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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef SAVEALLDIALOG_H +#define SAVEALLDIALOG_H + +#include <qstringlist.h> +#include <kdialogbase.h> +#include <kurl.h> + +class KListView; +/** +@file ksavealldialog.h +Dialogs to save multiple files. +*/ + +/** +Dialog to save selected files. +*/ +class KSaveSelectDialog : public KDialogBase +{ + Q_OBJECT + +public: + KSaveSelectDialog( KURL::List const & filelist, KURL::List const & ignorelist, QWidget * parent ); + virtual ~KSaveSelectDialog(); + + KURL::List filesToSave(); + KURL::List filesNotToSave(); + +private slots: + void saveNone(); + void save(); + void cancel(); + +private: + KListView * _listview; + +}; + + +/** +Dialog to save all files. +*/ +class KSaveAllDialog : public KDialogBase +{ + Q_OBJECT + +public: + enum SaveAllResult{ SaveAll, Cancel, Revert }; + + KSaveAllDialog( const QStringList& filenames, QWidget* parent ); + virtual ~KSaveAllDialog(); + + SaveAllResult result() const { return m_result; } + +private slots: + void revert(); + void saveAll(); + void cancel(); + +private: + SaveAllResult m_result; + +}; + +#endif diff --git a/lib/widgets/processlinemaker.cpp b/lib/widgets/processlinemaker.cpp new file mode 100644 index 00000000..9cb19971 --- /dev/null +++ b/lib/widgets/processlinemaker.cpp @@ -0,0 +1,93 @@ +/* This file is part of the KDE project + Copyright (C) 2002 John Firebaugh <jfirebaugh@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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "processlinemaker.h" +#include "processlinemaker.moc" + +#include <kprocess.h> + +ProcessLineMaker::ProcessLineMaker() +{ +} + +ProcessLineMaker::ProcessLineMaker( const KProcess* proc ) +{ + connect(proc, SIGNAL(receivedStdout(KProcess*,char*,int)), + this, SLOT(slotReceivedStdout(KProcess*,char*,int)) ); + + connect(proc, SIGNAL(receivedStderr(KProcess*,char*,int)), + this, SLOT(slotReceivedStderr(KProcess*,char*,int)) ); +} + +void ProcessLineMaker::slotReceivedStdout( const char *buffer ) +{ + stdoutbuf += buffer; + int pos; + while ( (pos = stdoutbuf.find('\n')) != -1) { + QCString line = stdoutbuf.left( pos ); + emit receivedStdoutLine(line); + stdoutbuf.remove(0, pos+1); + } + if( !stdoutbuf.isEmpty() ) { + emit receivedPartialStdoutLine( stdoutbuf ); + stdoutbuf.truncate(0); + } +} + +void ProcessLineMaker::slotReceivedStdout( KProcess*, char *buffer, int ) +{ + slotReceivedStdout(buffer); // It is zero-terminated +} + + +void ProcessLineMaker::slotReceivedStderr( const char *buffer ) +{ + stderrbuf += buffer; + int pos; + while ( (pos = stderrbuf.find('\n')) != -1) { + QCString line = stderrbuf.left( pos ); + emit receivedStderrLine(line); + stderrbuf.remove(0, pos+1); + } + if( !stderrbuf.isEmpty() ) { + emit receivedPartialStderrLine( stderrbuf ); + stderrbuf.truncate(0); + } +} + +void ProcessLineMaker::slotReceivedStderr( KProcess*, char *buffer, int ) +{ + slotReceivedStderr(buffer); // It is zero-terminated +} + +void ProcessLineMaker::clearBuffers( ) +{ + stderrbuf.truncate(0); + stdoutbuf.truncate(0); +} + +void ProcessLineMaker::flush() +{ + if( !stderrbuf.isEmpty() ) + emit receivedStderrLine(stderrbuf); + if( !stdoutbuf.isEmpty() ) + emit receivedStdoutLine(stdoutbuf); + clearBuffers(); +} + diff --git a/lib/widgets/processlinemaker.h b/lib/widgets/processlinemaker.h new file mode 100644 index 00000000..a529467f --- /dev/null +++ b/lib/widgets/processlinemaker.h @@ -0,0 +1,67 @@ +/* This file is part of the KDE project + Copyright (C) 2002 John Firebaugh <jfirebaugh@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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _PROCESSLINEMAKER_H_ +#define _PROCESSLINEMAKER_H_ + +#include <qobject.h> + +/** +@file processlinemaker.h +Utility objects for process output views. +*/ + +class KProcess; + +/** +Convenience class to catch output of KProcess. +*/ +class ProcessLineMaker : public QObject +{ +Q_OBJECT + +public: + ProcessLineMaker(); + ProcessLineMaker( const KProcess* ); + + void clearBuffers(); + void flush(); + +public slots: + void slotReceivedStdout(const char*); + void slotReceivedStderr(const char*); + +protected slots: + void slotReceivedStdout(KProcess *, char *buffer, int buflen); + void slotReceivedStderr(KProcess *, char *buffer, int buflen); + +signals: + void receivedStdoutLine( const QCString& line ); + void receivedStderrLine( const QCString& line ); + void receivedPartialStdoutLine( const QCString& line ); + void receivedPartialStderrLine( const QCString& line ); + +private: + QCString stdoutbuf; + QCString stderrbuf; +}; + +#endif + +//kate: replace-tabs off; indent-spaces off; diff --git a/lib/widgets/processwidget.cpp b/lib/widgets/processwidget.cpp new file mode 100644 index 00000000..54dd1751 --- /dev/null +++ b/lib/widgets/processwidget.cpp @@ -0,0 +1,283 @@ +/* This file is part of the KDE project + Copyright (C) 1999-2001 Bernd Gehrmann <bernd@kdevelop.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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "processwidget.h" +#include "processlinemaker.h" + +#include <kdeversion.h> +#include <qdir.h> +#include <kdebug.h> +#include <klocale.h> +#include <kprocess.h> +#include <qpainter.h> +#include <qapplication.h> + + +ProcessListBoxItem::ProcessListBoxItem(const QString &s, Type type) + : QListBoxText(s), t(type) +{ + QString clean = s; + clean.replace( QChar('\t'), QString(" ") ); + clean.replace( QChar('\n'), QString() ); + clean.replace( QChar('\r'), QString() ); + setText( clean ); + + setCustomHighlighting(true); +} + + +bool ProcessListBoxItem::isCustomItem() +{ + return false; +} + +static inline unsigned char normalize(int a) +{ + return (a < 0 ? 0 : a > 255 ? 255 : a); +} + +static inline double blend1(double a, double b, double k) +{ + return a + (b - a) * k; +} + +QColor ProcessListBoxItem::blend(const QColor &c1, const QColor &c2, double k) const +{ + if (k < 0.0) return c1; + if (k > 1.0) return c2; + + int r = normalize((int)blend1((double)c1.red(), (double)c2.red(), k)); + int g = normalize((int)blend1((double)c1.green(), (double)c2.green(), k)); + int b = normalize((int)blend1((double)c1.blue(), (double)c2.blue(), k)); + + return QColor(qRgb(r, g, b)); +} + +void ProcessListBoxItem::paint(QPainter *p) +{ + QColor dim, warn, err, back; + if (listBox()) { + const QColorGroup& group = listBox()->palette().active(); + if (isSelected()) { + back = group.button(); + warn = group.buttonText(); + } + else + { + back = group.base(); + warn = group.text(); + } + err = group.linkVisited(); + dim = blend(warn, back); + } + else + { + warn = Qt::black; + dim = Qt::darkBlue; + err = Qt::darkRed; + if (isSelected()) + back = Qt::lightGray; + else + back = Qt::white; + } + p->fillRect(p->window(), QBrush(back)); + p->setPen((t==Error)? err : + (t==Diagnostic)? warn : dim); + QListBoxText::paint(p); +} + + +ProcessWidget::ProcessWidget(QWidget *parent, const char *name) + : KListBox(parent, name) +{ + setFocusPolicy(QWidget::NoFocus); + + // Don't override the palette, as that can mess up styles. Instead, draw + // the background ourselves (see ProcessListBoxItem::paint). + + + childproc = new KProcess(); + childproc->setUseShell(true); + + procLineMaker = new ProcessLineMaker( childproc ); + + connect( procLineMaker, SIGNAL(receivedStdoutLine(const QCString&)), + this, SLOT(insertStdoutLine(const QCString&) )); + connect( procLineMaker, SIGNAL(receivedStderrLine(const QCString&)), + this, SLOT(insertStderrLine(const QCString&) )); + connect( procLineMaker, SIGNAL(receivedPartialStdoutLine(const QCString&)), + this, SLOT(addPartialStdoutLine(const QCString&) )); + connect( procLineMaker, SIGNAL(receivedPartialStderrLine(const QCString&)), + this, SLOT(addPartialStderrLine(const QCString&) )); + + connect(childproc, SIGNAL(processExited(KProcess*)), + this, SLOT(slotProcessExited(KProcess*) )) ; +} + + +ProcessWidget::~ProcessWidget() +{ + delete childproc; + delete procLineMaker; +} + + +void ProcessWidget::startJob(const QString &dir, const QString &command) +{ + procLineMaker->clearBuffers(); + procLineMaker->blockSignals( false ); + + clear(); + insertItem(new ProcessListBoxItem(command, ProcessListBoxItem::Diagnostic)); + childproc->clearArguments(); + if (!dir.isNull()) { + childproc->setWorkingDirectory( dir ); + } + + *childproc << command; + childproc->start(KProcess::OwnGroup, KProcess::AllOutput); +} + + +void ProcessWidget::killJob( int signo ) +{ + procLineMaker->blockSignals( true ); + + childproc->kill( signo ); +} + + +bool ProcessWidget::isRunning() +{ + return childproc->isRunning(); +} + + +void ProcessWidget::slotProcessExited(KProcess *) +{ + procLineMaker->flush(); + if( !stdoutbuf.isEmpty() ) + insertStdoutLine(""); + if( !stderrbuf.isEmpty() ) + insertStderrLine(""); + childFinished(childproc->normalExit(), childproc->exitStatus()); + maybeScrollToBottom(); + emit processExited(childproc); +} + + +void ProcessWidget::insertStdoutLine(const QCString &line) +{ + if( !stdoutbuf.isEmpty() ) + { + stdoutbuf += line; + insertItem( new ProcessListBoxItem( QString::fromLocal8Bit(stdoutbuf), + ProcessListBoxItem::Normal ), + lastRowStdout+1 ); + stdoutbuf.truncate( 0 ); + }else + { + insertItem( new ProcessListBoxItem( QString::fromLocal8Bit( line ), + ProcessListBoxItem::Normal) ); + } + lastRowStdout = count() - 1; + maybeScrollToBottom(); +} + + +void ProcessWidget::insertStderrLine(const QCString &line) +{ + if( !stderrbuf.isEmpty() ) + { + stderrbuf += line; + insertItem( new ProcessListBoxItem( QString::fromLocal8Bit( stderrbuf ), + ProcessListBoxItem::Error ), + lastRowStderr+1 ); + stderrbuf.truncate( 0 ); + } else + { + insertItem( new ProcessListBoxItem( QString::fromLocal8Bit( line ), + ProcessListBoxItem::Error) ); + } + lastRowStderr = count() - 1; + maybeScrollToBottom(); +} + + +void ProcessWidget::childFinished(bool normal, int status) +{ + QString s; + ProcessListBoxItem::Type t; + + if (normal) { + if (status) { + s = i18n("*** Exited with status: %1 ***").arg(status); + t = ProcessListBoxItem::Error; + } else { + s = i18n("*** Exited normally ***"); + t = ProcessListBoxItem::Diagnostic; + } + } else { + if ( childproc->signalled() && childproc->exitSignal() == SIGSEGV ) + { + s = i18n("*** Process aborted. Segmentation fault ***"); + } + else + { + s = i18n("*** Process aborted ***"); + } + t = ProcessListBoxItem::Error; + } + + insertItem(new ProcessListBoxItem(s, t)); +} + + +QSize ProcessWidget::minimumSizeHint() const +{ + // I'm not sure about this, but when I don't use override minimumSizeHint(), + // the initial size in clearly too small + + return QSize( QListBox::sizeHint().width(), + (fontMetrics().lineSpacing()+2)*4 ); +} + +/** Should be called right after an insertItem(), + will automatic scroll the listbox if it is already at the bottom + to prevent automatic scrolling when the user has scrolled up +*/ +void ProcessWidget::maybeScrollToBottom() +{ + if ( verticalScrollBar()->value() == verticalScrollBar()->maxValue() ) + { + setBottomItem( count() -1 ); + } +} + +void ProcessWidget::addPartialStderrLine(const QCString& linepart) +{ + stderrbuf += linepart; +} + +void ProcessWidget::addPartialStdoutLine(const QCString& linepart) +{ + stdoutbuf += linepart; +} + +#include "processwidget.moc" diff --git a/lib/widgets/processwidget.h b/lib/widgets/processwidget.h new file mode 100644 index 00000000..ac9693e2 --- /dev/null +++ b/lib/widgets/processwidget.h @@ -0,0 +1,127 @@ +/* This file is part of the KDE project + Copyright (C) 1999-2001 Bernd Gehrmann <bernd@kdevelop.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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _PROCESSWIDGET_H_ +#define _PROCESSWIDGET_H_ + +#include <klistbox.h> +#include <kprocess.h> + +/** +@file processwidget.h +Widgets for various output views. +*/ + +class ProcessLineMaker; + +/** +Listbox item for process widgets. +*/ +class ProcessListBoxItem : public QListBoxText +{ +public: + enum Type { Diagnostic, Normal, Error }; + + ProcessListBoxItem(const QString &s, Type type); + + virtual bool isCustomItem(); + +protected: + QColor blend(const QColor &c1, const QColor &c2, double k = 0.25) const; + +private: + virtual void paint(QPainter *p); + Type t; +}; + + +/** + * This class is designed to share code between the + * grep and application output widgets. + */ +class ProcessWidget : public KListBox +{ + Q_OBJECT + +public: + ProcessWidget(QWidget *parent, const char *name=0); + ~ProcessWidget(); + + /** + * Returns whether a process is running in this view. + */ + bool isRunning(); + +public slots: + /** + * Starts the child process. + */ + void startJob(const QString &dir, const QString &command); + /** + * Kills the child processss. + */ + void killJob( int signo = SIGTERM ); + /** + * Inserts one line from stdin into the listbox. This can + * be overridden by subclasses to implement + * syntax highlighting. + */ + virtual void insertStdoutLine(const QCString &line); + /** + * Inserts one line from stderr into the listbox. This can + * be overridden by subclasses to implement + * syntax highlighting. By default, a ProcessListBoxItem + * is used. + */ + virtual void insertStderrLine(const QCString &line); + + virtual void addPartialStdoutLine(const QCString&); + virtual void addPartialStderrLine(const QCString&); + +protected: + /** + * This is called when the child process exits. + * The flag 'normal' is true if the process exited + * normally (i.e. not by a signal or similar), otherwise + * the exit status can be taken from 'status'. + */ + virtual void childFinished(bool normal, int status); + +signals: + void processExited(KProcess *); + void rowSelected(int row); + +protected: + virtual QSize minimumSizeHint() const; + void maybeScrollToBottom(); + +protected slots: + void slotProcessExited(KProcess*); + +private: + KProcess *childproc; + ProcessLineMaker* procLineMaker; + QCString stderrbuf; + QCString stdoutbuf; + int lastRowStdout; + int lastRowStderr; +}; + + +#endif diff --git a/lib/widgets/propeditor/Mainpage.dox b/lib/widgets/propeditor/Mainpage.dox new file mode 100644 index 00000000..6bc81be0 --- /dev/null +++ b/lib/widgets/propeditor/Mainpage.dox @@ -0,0 +1,116 @@ +/** +@mainpage The KDevelop Property Editing Library + +<b>Link with</b>: -lkdevelop + +<b>Include path</b>: -I\$(kde_includes)/kdevelop/propeditor + + +\section whatis What is Property Editor? + +%Property editor is a collection of facilities to store and edit the +properties of an object. For example, look at %Qt Designer. Each widget +has a list of properties that can be edited in a nice table form. +Same ideology is used to edit properties in Kugar Report Designer +(from KOffice distribution). In KDevelop project manager can also display +the properties of currently selected build item in property editor. + +\section over Library Overview + +This PropertyEditor library is a redesign of Kugar property editing library +with the goal to be more generic and extensible. + +Library provides a @ref PropertyLib::Property class which stores property name, value and some +more important information like description or the list of possible values. +Using @ref PropertyLib::Property class adds more overhead over Q_PROPERTY but provides more +flexibility. You can subclass @ref PropertyLib::Property and create your custom properties. +Custom properties can have either predefined type (see @ref PropertyLib::Property::PropertyType) or +custom type. Custom type should be used if a custom property editor widget is +necessary. + +Properties are organized into lists. @ref PropertyLib::PropertyList is designed +to store such lists in most efficient manner. It also allows to group +properties (for example think about "geometrical" properties like "x", "y", etc.). + +Property lists can be displayed in @ref PropertyLib::PropertyEditor widget which will +display them in a table form. @ref PropertyLib::PropertyEditor takes a pointer to a @ref PropertyLib::PropertyList object so @ref PropertyLib::PropertyBuffer can be used too. + +@ref PropertyLib::PropertyBuffer is designed to provide a method to access an intersection +of property lists. For example, let's consider object A with property list a_list +abd object B with list b_list. Now let's imagine we want to display common properties +from a_list and b_list in one @ref PropertyLib::PropertyEditor widget. Obviously, we need to +"intersect" a_list with b_list and display the result of intersection. +This is why @ref PropertyLib::PropertyBuffer is used for editing. If we change +the value of a property in the editor, @ref PropertyLib::PropertyBuffer will update +both properties from underlying a_list and b_list. + +@ref PropertyLib::PropertyEditor at the same time shows only one editor for selected +property in the list. Each @ref PropertyLib::Property::PropertyType has corresponding @ref PropertyLib::PropertyWidget +which displays property editor or draws a property in the list if it is not edited. +More exactly, if @ref PropertyLib::PropertyEditor needs to display editor widget, it displays +@ref PropertyLib::PropertyWidget, else it calls @ref PropertyLib::PropertyWidget::drawViewer function. +Custom property widgets should be subclasses of @ref PropertyLib::PropertyWidget. + +To create property widgets at runtime, a factory is used. Factory class is +called @ref PropertyLib::PropertyMachineFactory. Static function @ref PropertyLib::PropertyMachineFactory::getInstance +can be used to obtain the reference to the factory instance. Factory creates and returns +so-called @ref PropertyLib::Machine for each registered property type (either predefined or user defined). + +@ref PropertyLib::Machine contains @ref PropertyLib::PropertyWidget and a list of "detailed" machines. +Usually only property widget is necessary for a property but there are +complex properties like "Font" for example. We would like to see separate editors +for font family, size, etc. and a button to choose all of these in the dialog. +For that "Font" property, a PropertyWidget with a "choose font" button +and also number of detailed widgets like "font family" combo, etc. can be created. + +\section Examples +A simple example on how to create a property editor and use it with one property list: +\code + using namespace PropertyLib; + + PropertyEditor *m_editor = new PropertyEditor(this); + + PropertyList *list = new PropertyList; + list->addProperty("My Group", new Property(Property::Integer, "First Property", + "This is my first property", -5)); + list->addProperty("My Group", new Property(Property::String, "Second Property", + "This is my second property", "Hello")); + list->addProperty(new Property(Property::Color, "Third Property", + "This is my third property", QColor("green"))); + + m_editor->populateProperties(*list); +\endcode +\image html propeditor1.png "Simple property editor" + +More advanced example with property buffers and list intersection: +\code + using namespace PropertyLib; + + PropertyEditor *m_editor = new PropertyEditor(this); + + PropertyList *list = new PropertyList; + list->addProperty("My Group", new Property(Property::Integer, "First Property", + "This is my first property", -5)); + list->addProperty("My Group", new Property(Property::String, "Second Property", + "This is my second property", "Hello")); + list->addProperty(new Property(Property::Color, "Third Property", + "This is my third property", QColor("green"))); + + PropertyList *list2 = new PropertyList; + list2->addProperty("My Group", new Property(Property::Integer, "First Property", + "This is my first property", -7)); + list2->addProperty("My Group", new Property(Property::String, "Second Property", + "This is my second property", "Hello")); + list2->addProperty(new Property(Property::String, "Third Property", + "This is my third property", "green")); + + PropertyBuffer buf(list); + buf.intersect(list2); + + m_editor->populateProperties(&buf); +\endcode +\image html propeditor2.png "Result of property list intersection" +In this example only properties named "First Property" and "Second Property" will be shown in editor. +"Third Property" has different types in list and list2 and will not be included in intersection. + +*/ diff --git a/lib/widgets/propeditor/Makefile.am b/lib/widgets/propeditor/Makefile.am new file mode 100644 index 00000000..bd055733 --- /dev/null +++ b/lib/widgets/propeditor/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES = -I$(top_srcdir)/lib/compat $(all_includes) +METASOURCES = AUTO + +lib_LTLIBRARIES = libkdevpropertyeditor.la +libkdevpropertyeditor_la_LIBADD = $(LIB_KIO) +libkdevpropertyeditor_la_LDFLAGS = -no-undefined $(all_libraries) +libkdevpropertyeditor_la_SOURCES = childproperty.cpp pcombobox.cpp pdummywidget.cpp ppointedit.cpp propertymachinefactory.cpp pstringlistedit.cpp\ +multiproperty.cpp pcursoredit.cpp pfontbutton.cpp prectedit.cpp propertywidget.cpp psymbolcombo.cpp\ +pcheckbox.cpp pdateedit.cpp pfontcombo.cpp property.cpp psizeedit.cpp purledit.cpp\ +pcolorbutton.cpp pdatetimeedit.cpp plineedit.cpp propertyeditor.cpp psizepolicyedit.cpp pyesnobutton.cpp\ +pcolorcombo.cpp pdoublenuminput.cpp ppixmapedit.cpp propertylist.cpp pspinbox.cpp propertywidgetproxy.cpp plinestyleedit.cpp qeditlistbox.cpp + +kdevpropeditorincludedir = $(includedir)/kdevelop/propeditor +kdevpropeditorinclude_HEADERS = childproperty.h pcombobox.h pdummywidget.h ppointedit.h propertymachinefactory.h pcursoredit.h pfontbutton.h prectedit.h propertywidget.h pdateedit.h pfontcombo.h property.h psizeedit.h pdatetimeedit.h plineedit.h propertyeditor.h psizepolicyedit.h pdoublenuminput.h ppixmapedit.h propertylist.h pspinbox.h propertywidgetproxy.h multiproperty.h pyesnobutton.h purledit.h psymbolcombo.h pstringlistedit.h pcolorcombo.h pcolorbutton.h pcheckbox.h plinestyleedit.h + +DOXYGEN_REFERENCES = dcop interfaces kdecore kdefx kdeui khtml kmdi kio kjs kparts kutils +DOXYGEN_PROJECTNAME = KDevelop Property Editing Library +include ../../../Doxyfile.am diff --git a/lib/widgets/propeditor/childproperty.cpp b/lib/widgets/propeditor/childproperty.cpp new file mode 100644 index 00000000..72cfb053 --- /dev/null +++ b/lib/widgets/propeditor/childproperty.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "childproperty.h" + +#include <qsize.h> +#include <qpoint.h> +#include <qrect.h> +#include <qsizepolicy.h> + +#include "multiproperty.h" + +namespace PropertyLib{ + +ChildProperty::ChildProperty(MultiProperty *parent, int type, ChildPropertyType childType, const QString &name, + const QString &description, const QVariant &value, bool save, bool readOnly) + :Property(type, name, description, value, save, readOnly), m_parent(parent), m_childType(childType) +{ +} + +ChildProperty::ChildProperty(MultiProperty *parent, const QString & name, ChildPropertyType childType, + const QMap<QString, QVariant> &v_valueList, const QString &description, + const QVariant &value, bool save, bool readOnly) + :Property(name, v_valueList, description, value, save, readOnly), m_parent(parent), m_childType(childType) +{ +} + +void ChildProperty::setValue(const QVariant &value, bool // rememberOldValue + ) +{ + qWarning("ChildProperty::setValue"); + if (!m_parent->valid()) + return; + switch (m_parent->type()) + { + case Size: + { + qWarning("ChildProperty::setValue for QSize"); + QSize v = m_parent->value().toSize(); + if (m_childType == Size_Height) + v.setHeight(value.toInt()); + else if (m_childType == Size_Width) + v.setWidth(value.toInt()); + m_parent->setValue(v); + break; + } + case Point: + { + qWarning("ChildProperty::setValue for QPoint"); + QPoint v = m_parent->value().toPoint(); + if (m_childType == Point_X) + v.setX(value.toInt()); + else if (m_childType == Point_Y) + v.setY(value.toInt()); + m_parent->setValue(v); + break; + } + case Rect: + { + qWarning("ChildProperty::setValue for QRect"); + QRect v = m_parent->value().toRect(); + if (m_childType == Rect_X) + v.setX(value.toInt()); + else if (m_childType == Rect_Y) + v.setY(value.toInt()); + else if (m_childType == Rect_Width) + v.setWidth(value.toInt()); + else if (m_childType == Rect_Height) + v.setHeight(value.toInt()); + m_parent->setValue(v); + break; + } + case SizePolicy: + { + qWarning("ChildProperty::setValue for QSizePolicy"); + QSizePolicy v = m_parent->value().toSizePolicy(); + if (m_childType == SizePolicy_HorData) + v.setHorData(QSizePolicy::SizeType(value.toInt())); + else if (m_childType == SizePolicy_VerData) + v.setVerData(QSizePolicy::SizeType(value.toInt())); + else if (m_childType == SizePolicy_HorStretch) + v.setHorStretch(value.toInt()); + else if (m_childType == SizePolicy_VerStretch) + v.setVerStretch(value.toInt()); + m_parent->setValue(v); + break; + } + } +} + +QVariant ChildProperty::value( ) const +{ + if (!m_parent->valid()) + return QVariant(); + switch (m_parent->type()) + { + case Size: + if (m_childType == Size_Height) + return m_parent->value().toSize().height(); + else if (m_childType == Size_Width) + return m_parent->value().toSize().width(); + case Point: + if (m_childType == Point_X) + return m_parent->value().toPoint().x(); + else if (m_childType == Point_Y) + return m_parent->value().toPoint().y(); + case Rect: + if (m_childType == Rect_X) + return m_parent->value().toRect().x(); + else if (m_childType == Rect_Y) + return m_parent->value().toRect().y(); + else if (m_childType == Rect_Width) + return m_parent->value().toRect().width(); + else if (m_childType == Rect_Height) + return m_parent->value().toRect().height(); + case SizePolicy: + if (m_childType == SizePolicy_HorData) + return m_parent->value().toSizePolicy().horData(); + else if (m_childType == SizePolicy_VerData) + return m_parent->value().toSizePolicy().verData(); + else if (m_childType == SizePolicy_HorStretch) + return m_parent->value().toSizePolicy().horStretch(); + else if (m_childType == SizePolicy_VerStretch) + return m_parent->value().toSizePolicy().verStretch(); + } + return QVariant(); +} + +} diff --git a/lib/widgets/propeditor/childproperty.h b/lib/widgets/propeditor/childproperty.h new file mode 100644 index 00000000..13399a08 --- /dev/null +++ b/lib/widgets/propeditor/childproperty.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef CHILDPROPERTY_H +#define CHILDPROPERTY_H + +#include "property.h" + +namespace PropertyLib{ + +class MultiProperty; + +/** +@short Child property + +Child property is a detailed property for complex parent properties. +For example, to edit a property of Point type one can request two +child properties for "x" and "y" components of a point. + +Child properties instances usually belong to MultiProperty class +which is used to fetch and display them in the property editor. +Child properties are created by a PropertyMachineFactory. +Factory in such case does not only creates a machine for a property, +but also fills corrresponding multiproperty with a list of child +properties. +*/ +class ChildProperty: public Property{ +public: + enum ChildPropertyType { + Size_Height, + Size_Width, + Point_X, + Point_Y, + Rect_X, + Rect_Y, + Rect_Width, + Rect_Height, + SizePolicy_HorData, + SizePolicy_VerData, + SizePolicy_HorStretch, + SizePolicy_VerStretch + }; + + /**Constructs empty property.*/ + ChildProperty() {} + /**Constructs property.*/ + ChildProperty(MultiProperty *parent, int type, ChildPropertyType childType, const QString &name, + const QString &description, const QVariant &value = QVariant(), + bool save = true, bool readOnly = false); + /**Constructs property with @ref ValueFromList type.*/ + ChildProperty(MultiProperty *parent, const QString &name, ChildPropertyType childType, + const QMap<QString, QVariant> &v_valueList, const QString &description, + const QVariant &value = QVariant(), bool save = true, bool readOnly = false); + + /**@return the value of the property.*/ + virtual QVariant value() const; + /**Sets the value of the property.*/ + virtual void setValue(const QVariant &value, bool rememberOldValue = true); + +private: + MultiProperty *m_parent; + ChildPropertyType m_childType; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/compat_tools.h b/lib/widgets/propeditor/compat_tools.h new file mode 100644 index 00000000..1a1a8735 --- /dev/null +++ b/lib/widgets/propeditor/compat_tools.h @@ -0,0 +1,6 @@ +#ifndef COMPAT_TOOLS_H +#define COMPAT_TOOLS_H + +#define i18n QObject::tr + +#endif diff --git a/lib/widgets/propeditor/multiproperty.cpp b/lib/widgets/propeditor/multiproperty.cpp new file mode 100644 index 00000000..7e32345a --- /dev/null +++ b/lib/widgets/propeditor/multiproperty.cpp @@ -0,0 +1,273 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo <cloudtemple@mskat.net> * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "multiproperty.h" + +#include "propertylist.h" + +namespace PropertyLib{ + +MultiProperty::MultiProperty(Property *prop) + :m_propertyList(0) +{ + list.append(prop); +} + +MultiProperty::MultiProperty(PropertyList *propertyList) + :m_propertyList(propertyList) +{ +} + +MultiProperty::MultiProperty(PropertyList *propertyList, Property *prop) + :m_propertyList(propertyList) +{ + list.append(prop); +} + +MultiProperty::~MultiProperty() +{ +} + +QString MultiProperty::name() const +{ + if (list.count() >= 1) + return list.getFirst()->name(); + return QString::null; +} + +int MultiProperty::type() const +{ + if (list.count() >= 1) + return list.getFirst()->type(); + return QVariant::Invalid; +} + +QVariant MultiProperty::value() const +{ + QVariant value; + if (list.count() >= 1) + value = list.getFirst()->value(); + + QPtrListIterator<Property> it(list); + Property *property; + while ((property = it.current()) != 0) + { + if (property->value() != value) + return QVariant::Invalid; + ++it; + } + + return value; +} + +QString MultiProperty::description() const +{ + QString description; + if (list.count() >= 1) + description = list.getFirst()->description(); + + QPtrListIterator<Property> it(list); + Property *property; + while ((property = it.current()) != 0) + { + if (property->description() != description) + return QString::null; + ++it; + } + + return description; +} + +bool MultiProperty::readOnly() const +{ + bool v = true; + if (list.count() >= 1) + v = list.getFirst()->readOnly(); + + QPtrListIterator<Property> it(list); + Property *property; + while ((property = it.current()) != 0) + { + if (property->readOnly() != v) + return false; + ++it; + } + + return v; +} + +bool MultiProperty::visible() const +{ + bool v = true; + if (list.count() >= 1) + v = list.getFirst()->readOnly(); + + QPtrListIterator<Property> it(list); + Property *property; + while ((property = it.current()) != 0) + { + if (property->visible() != v) + return false; + ++it; + } + + return v; +} + +QMap<QString, QVariant> MultiProperty::valueList() const +{ + if (list.count() >= 1) + return list.getFirst()->valueList; + return QMap<QString, QVariant>(); +} + +void MultiProperty::setDescription(const QString &description) +{ + Property *property; + for (property = list.first(); property; property = list.next()) + property->setDescription(description); +} + +/*void MultiProperty::setName(const QString &name) +{ +} + +void MultiProperty::setType(int type) +{ +} +*/ +void MultiProperty::setValue(const QVariant &value) +{ + Property *property; + for (property = list.first(); property; property = list.next()) + { + property->setValue(value); + if (m_propertyList) + { +// qWarning("emit change"); + emit m_propertyList->propertyValueChanged(property); + } + } +} + +void MultiProperty::setValue(const QVariant &value, bool emitChange) +{ + Property *property; + for (property = list.first(); property; property = list.next()) + { + property->setValue(value); + if (emitChange && m_propertyList) + emit m_propertyList->propertyValueChanged(property); + } +} + +void MultiProperty::setValueList(const QMap<QString, QVariant> &valueList) +{ + Property *property; + for (property = list.first(); property; property = list.next()) + property->setValueList(valueList); +} + +void MultiProperty::addProperty(Property *prop) +{ + list.append(prop); +} + +void MultiProperty::removeProperty(Property *prop) +{ +/* qWarning("op >> removing %s", prop->name().ascii()); + qWarning("op >> list is %d", list.count());*/ + /*bool b = */list.remove(prop); +/* qWarning("op >> list is %d", list.count()); + qWarning("op >> removal is %s", b?"true":"false"); */ +} + +bool MultiProperty::operator ==(const MultiProperty &prop) const +{ + if ( (type() == prop.type()) && (name() == prop.name()) ) + return true; + return false; +} + +bool MultiProperty::operator ==(const Property &prop) const +{ +/* qWarning("MultiProperty::operator == for %s = %s", name().ascii(), prop.name().ascii()); + qWarning("MultiProperty::operator == for %d = %d", type(), prop.type());*/ + if ( (type() == prop.type()) && (name() == prop.name()) ) + return true; + return false; +} + +void MultiProperty::addProperty( MultiProperty *prop) +{ + Property *property; + for (property = prop->list.first(); property; property = prop->list.next()) + addProperty(property); +} + +void MultiProperty::removeProperty( MultiProperty *prop) +{ + Property *property; + for (property = prop->list.first(); property; property = prop->list.next()) + removeProperty(property); +} + +QVariant MultiProperty::findValueDescription() const +{ + QVariant val = value(); + if (type() != Property::ValueFromList) + return val; + QMap<QString, QVariant> vl = valueList(); + for (QMap<QString, QVariant>::const_iterator it = vl.begin(); it != vl.end(); ++ it) + { + if (it.data() == val) + return it.key(); + } + return ""; +} + +QVariant MultiProperty::findValueDescription(QVariant val) const +{ + if (type() != Property::ValueFromList) + return val; + QMap<QString, QVariant> vl = valueList(); + for (QMap<QString, QVariant>::const_iterator it = vl.begin(); it != vl.end(); ++ it) + { + if (it.data() == val) + return it.key(); + } + return ""; +} + +bool MultiProperty::valid() const +{ + return list.count() != 0; +} + +void MultiProperty::undo() +{ + Property *property; + for (property = list.first(); property; property = list.next()) + { + property->setValue(property->oldValue(), false); + if (m_propertyList) + emit m_propertyList->propertyValueChanged(property); + } +} + +} diff --git a/lib/widgets/propeditor/multiproperty.h b/lib/widgets/propeditor/multiproperty.h new file mode 100644 index 00000000..e6402027 --- /dev/null +++ b/lib/widgets/propeditor/multiproperty.h @@ -0,0 +1,126 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo <cloudtemple@mskat.net> * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef MULTIPROPERTY_H +#define MULTIPROPERTY_H + +#include <qptrlist.h> +#include <qmap.h> +#include <qvariant.h> + +#include "property.h" +#include "childproperty.h" + +namespace PropertyLib{ + +class PropertyList; + +/** @file multiproperty.h +@short Contains @ref PropertyLib::MultiProperty class. +*/ + +/** +@short Holds a list of properties with the same name and type. + +It is used by @ref PropertyLib::PropertyList to store properties. Generally, @ref PropertyLib::PropertyList +stores a list of multiproperties instead of properties. This allows working +with many properties of the same name and type at the same type. + +MultiProperty is also responsible for storing detailed %property editors (instances +of @ref ChildProperty class. It's too much overhead to store child properties +with their parent properties. MultiProperty provides a way to store child properties +only once for all properties with the same name and same type. +*/ +class MultiProperty +{ +public: + /**Constructs multiproperty with one property which is not connected to a property list.*/ + MultiProperty(Property *prop); + /**Constructs empty multiproperty.*/ + MultiProperty(PropertyList *propertyList); + /**Constructs multiproperty with one Property in the list.*/ + MultiProperty(PropertyList *propertyList, Property *prop); + ~MultiProperty(); + + /**Compares two multiproperties.*/ + bool operator ==(const MultiProperty &prop) const; + /**Compares %multiproperty with %property.*/ + bool operator ==(const Property &prop) const; + + /**Adds %property to the list.*/ + void addProperty(Property *prop); + /**Removes %property from the list.*/ + void removeProperty(Property *prop); + /**Adds all properties from the %multiproperty prop.*/ + void addProperty(MultiProperty *prop); + /**Removes all properties that exists in the %multiproperty prop.*/ + void removeProperty(MultiProperty *prop); + + /**Returns the name of a %property.*/ + QString name() const; + /**Returns the type of a %property.*/ + int type() const; + /**Returns the value of a %property.*/ + QVariant value() const; + /**Returns the description of a %property.*/ + QString description() const; + /**Returns the readonly attribute of a %property.*/ + bool readOnly() const; + /**Returns the visibility attribute of a %property.*/ + bool visible() const; + /**The string-to-value correspondence list of the %property.*/ + QMap<QString, QVariant> valueList() const; + + /**Sets the value of a %property.*/ + void setValue(const QVariant& value); + /**Sets the value of a %property. + @param value new value of thus %multiproperty + @param emitChange if set to true then %property list which owns this %multiproperty + emits propertyValueChanged signal.*/ + void setValue(const QVariant& value, bool emitChange); + /**Sets the description of a %property.*/ + void setDescription(const QString &description); + /**Sets the list of possible values of a %property.*/ + void setValueList(const QMap< QString, QVariant >& valueList); + + /**Finds string description for a value.*/ + QVariant findValueDescription() const; + /**Finds string description for a value.*/ + QVariant findValueDescription(QVariant val) const; + + /**Returns true if the %multiproperty has no properties in the list (i.e. it's invalid).*/ + bool valid() const; + + /**Reverts the property value to previous setting.*/ + void undo(); + + /**The list of child properties.*/ + QValueList<ChildProperty> details; + +private: + QPtrList<Property> list; + + PropertyList *m_propertyList; + +friend class PropertyList; +friend class PropertyBuffer; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pcheckbox.cpp b/lib/widgets/propeditor/pcheckbox.cpp new file mode 100644 index 00000000..7b0b187e --- /dev/null +++ b/lib/widgets/propeditor/pcheckbox.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pcheckbox.h" + +#include <qlayout.h> +#include <qcheckbox.h> +#include <qpainter.h> + +#ifndef PURE_QT +#include <klocale.h> +#else +#include "compat_tools.h" +#endif + +namespace PropertyLib{ + +PCheckBox::PCheckBox(MultiProperty *property, QWidget *parent, const char *name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QCheckBox(this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + connect(m_edit, SIGNAL(toggled(bool)), this, SLOT(updateProperty(bool))); +} + +QVariant PCheckBox::value() const +{ + return QVariant(m_edit->isChecked()); +} + +void PCheckBox::setValue(const QVariant &value, bool emitChange) +{ + disconnect(m_edit, SIGNAL(toggled(bool)), this, SLOT(updateProperty(bool))); + m_edit->setChecked(value.toBool()); + connect(m_edit, SIGNAL(toggled(bool)), this, SLOT(updateProperty(bool))); + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PCheckBox::updateProperty(bool val) +{ + emit propertyChanged(m_property, QVariant(val)); +} + +void PCheckBox::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + p->setBrush(cg.background()); + p->setPen(Qt::NoPen); + p->drawRect(r); + p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, value.toBool() ? i18n("true") : i18n("false")); +} + +} + +#ifndef PURE_QT +#include "pcheckbox.moc" +#endif diff --git a/lib/widgets/propeditor/pcheckbox.h b/lib/widgets/propeditor/pcheckbox.h new file mode 100644 index 00000000..374617f7 --- /dev/null +++ b/lib/widgets/propeditor/pcheckbox.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PCHECKBOX_H +#define PCHECKBOX_H + +#include "propertywidget.h" + +class QCheckBox; + +namespace PropertyLib{ + +/** +@short %Property editor with checkbox. +*/ +class PCheckBox: public PropertyWidget{ + Q_OBJECT +public: + PCheckBox(MultiProperty *property, QWidget *parent = 0, const char *name = 0); + + /**@return the value currently entered in the editor widget.*/ + virtual QVariant value() const; + /**Sets the value shown in the editor widget. Set emitChange to false + if you don't want to emit propertyChanged signal.*/ + virtual void setValue(const QVariant &value, bool emitChange=true); + /**Function to draw a property viewer when the editor isn't shown.*/ + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + +private slots: + void updateProperty(bool val); + +private: + QCheckBox *m_edit; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pcolorbutton.cpp b/lib/widgets/propeditor/pcolorbutton.cpp new file mode 100644 index 00000000..7404e1de --- /dev/null +++ b/lib/widgets/propeditor/pcolorbutton.cpp @@ -0,0 +1,120 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pcolorbutton.h" + +#include <qlayout.h> +#include <qpainter.h> + +#ifndef PURE_QT +#include <kcolorbutton.h> +#else +#include <qpushbutton.h> +#include <qpixmap.h> +#include <qiconset.h> +#endif +#include <qcolordialog.h> + +namespace PropertyLib { + +PColorButton::PColorButton(MultiProperty* property, QWidget* parent, const char* name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); +#ifndef PURE_QT + m_edit = new KColorButton(this); + connect(m_edit, SIGNAL(changed(const QColor&)), this, SLOT(updateProperty(const QColor&))); +#else + m_edit = new QPushButton(this); + connect(m_edit, SIGNAL(clicked()), this, SLOT(changeColor())); +#endif + + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); +} + +QVariant PColorButton::value() const +{ +#ifndef PURE_QT + return QVariant(m_edit->color()); +#else + return QVariant(m_color); +#endif +} + +void PColorButton::drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value) +{ +/* p->setBrush(value.toColor()); + p->setPen(Qt::NoPen); + p->drawRect(r);*/ + p->setPen(Qt::NoPen); + p->setBrush(cg.background()); + p->drawRect(r); + + p->setBrush(value.toColor()); + p->setPen(Qt::SolidLine); + QRect r2(r); + r2.setTopLeft(r.topLeft() + QPoint(5,5)); + r2.setBottomRight(r.bottomRight() - QPoint(5,5)); + p->drawRect(r2); +} + +void PColorButton::setValue(const QVariant& value, bool emitChange) +{ +#ifndef PURE_QT + disconnect(m_edit, SIGNAL(changed(const QColor&)), this, SLOT(updateProperty(const QColor&))); + m_edit->setColor(value.toColor()); + connect(m_edit, SIGNAL(changed(const QColor&)), this, SLOT(updateProperty(const QColor&))); +#else + m_color = value.toColor(); + m_edit->setText(m_color.name()); + QPixmap px; + px.resize(14,14); + px.fill(m_color); + m_edit->setIconSet(px); +#endif + if (emitChange) + emit propertyChanged(m_property, value); + +} + +void PColorButton::updateProperty(const QColor &// color + ) +{ + emit propertyChanged(m_property, value()); +} + +void PColorButton::changeColor() +{ +#ifdef PURE_QT + m_color = QColorDialog::getColor(m_color,this); + updateProperty(m_color); + m_edit->setText(m_color.name()); + QPixmap px; + px.resize(14,14); + px.fill(m_color); + m_edit->setIconSet(px); + +#endif +} + +} +#ifndef PURE_QT +#include "pcolorbutton.moc" +#endif diff --git a/lib/widgets/propeditor/pcolorbutton.h b/lib/widgets/propeditor/pcolorbutton.h new file mode 100644 index 00000000..67e02ef9 --- /dev/null +++ b/lib/widgets/propeditor/pcolorbutton.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PCOLORBUTTON_H +#define PCOLORBUTTON_H + +#include "propertywidget.h" + +#ifndef PURE_QT +class KColorButton; +#else +class QPushButton; +#include <qcolor.h> +#endif +namespace PropertyLib{ + +/** +@short %Property editor with color chooser button. +*/ +class PColorButton: public PropertyWidget +{ + Q_OBJECT +public: + PColorButton(MultiProperty *property, QWidget *parent = 0, const char *name = 0); + + virtual QVariant value() const; + virtual void drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value); + virtual void setValue(const QVariant& value, bool emitChange); + +protected slots: + void updateProperty(const QColor& color); + + void changeColor(); + +private: +#ifndef PURE_QT + KColorButton *m_edit; +#else + QPushButton *m_edit; + QColor m_color; +#endif +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pcolorcombo.cpp b/lib/widgets/propeditor/pcolorcombo.cpp new file mode 100644 index 00000000..4d09a10f --- /dev/null +++ b/lib/widgets/propeditor/pcolorcombo.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pcolorcombo.h" + +#include <qlayout.h> +#include <qpainter.h> + +#include <kcolorcombo.h> + +namespace PropertyLib{ + +PColorCombo::PColorCombo(MultiProperty *property, QWidget *parent, const char *name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new KColorCombo(this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + connect(m_edit, SIGNAL(activated(int)), this, SLOT(updateProperty(int))); +} + +QVariant PColorCombo::value() const +{ + return QVariant(m_edit->color()); +} + +void PColorCombo::setValue(const QVariant &value, bool emitChange) +{ + disconnect(m_edit, SIGNAL(activated(int)), this, SLOT(updateProperty(int))); + m_edit->setColor(value.toColor()); + connect(m_edit, SIGNAL(activated(int)), this, SLOT(updateProperty(int))); + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PColorCombo::updateProperty(int /*val*/) +{ + emit propertyChanged(m_property, value()); +} + +void PColorCombo::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + p->setPen(Qt::NoPen); + p->setBrush(cg.background()); + p->drawRect(r); + + p->setBrush(value.toColor()); + p->setPen(Qt::SolidLine); + QRect r2(r); + r2.setTopLeft(r.topLeft() + QPoint(5,5)); + r2.setBottomRight(r.bottomRight() - QPoint(5,5)); + p->drawRect(r2); +} + +} + +#ifndef PURE_QT +#include "pcolorcombo.moc" +#endif + diff --git a/lib/widgets/propeditor/pcolorcombo.h b/lib/widgets/propeditor/pcolorcombo.h new file mode 100644 index 00000000..512fa9ad --- /dev/null +++ b/lib/widgets/propeditor/pcolorcombo.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PCOLORCOMBO_H +#define PCOLORCOMBO_H + +#include "propertywidget.h" + +class KColorCombo; + +namespace PropertyLib{ + +/** +@short %Property editor with color combobox. +*/ +class PColorCombo: public PropertyWidget{ + Q_OBJECT +public: + PColorCombo(MultiProperty *property, QWidget *parent = 0, const char *name = 0); + + /**@return the value currently entered in the editor widget.*/ + virtual QVariant value() const; + /**Sets the value shown in the editor widget. Set emitChange to false + if you don't want to emit propertyChanged signal.*/ + virtual void setValue(const QVariant &value, bool emitChange=true); + /**Function to draw a property viewer when the editor isn't shown.*/ + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + +private slots: + void updateProperty(int val); + +private: + KColorCombo *m_edit; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pcombobox.cpp b/lib/widgets/propeditor/pcombobox.cpp new file mode 100644 index 00000000..9c1619cf --- /dev/null +++ b/lib/widgets/propeditor/pcombobox.cpp @@ -0,0 +1,110 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pcombobox.h" + +#include <qcombobox.h> +#include <qlayout.h> + +namespace PropertyLib{ + +PComboBox::PComboBox(MultiProperty *property, const QMap<QString, QVariant> &list, QWidget *parent, const char *name) + :PropertyWidget(property, parent, name), m_valueList(list) +{ + init(false); +} + +PComboBox::PComboBox(MultiProperty *property, const QMap<QString, QVariant> &list, bool rw, QWidget *parent, const char *name) + :PropertyWidget(property, parent, name), m_valueList(list) +{ + init(rw); +} + +void PComboBox::init(bool rw) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QComboBox(rw, this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + fillBox(); + + connect(m_edit, SIGNAL(activated(int)), this, SLOT(updateProperty(int))); +} + +void PComboBox::fillBox() +{ + for (QMap<QString, QVariant>::const_iterator it = m_valueList.begin(); it != m_valueList.end(); it++) + { + m_edit->insertItem(it.key()); + } +} + +QVariant PComboBox::value() const +{ + QMap<QString, QVariant>::const_iterator it = m_valueList.find(m_edit->currentText()); + if (it == m_valueList.end()) + return QVariant(""); + return QVariant(it.data()); +} + +void PComboBox::setValue(const QVariant &value, bool emitChange) +{ +#if QT_VERSION >= 0x030100 + if (!value.isNull()) +#else + if (value.canCast(QVariant::String)) +#endif + { + disconnect(m_edit, SIGNAL(activated(int)), this, SLOT(updateProperty(int))); + m_edit->setCurrentText(findDescription(value)); + connect(m_edit, SIGNAL(activated(int)), this, SLOT(updateProperty(int))); + if (emitChange) + emit propertyChanged(m_property, value); + } +} + +void PComboBox::updateProperty(int /*val*/) +{ + emit propertyChanged(m_property, value()); +} + +QString PComboBox::findDescription(const QVariant &value) +{ + for (QMap<QString, QVariant>::const_iterator it = m_valueList.begin(); it != m_valueList.end(); ++ it) + { + if (it.data() == value) + return it.key(); + } + return ""; +} + +void PComboBox::setValueList(const QMap<QString, QVariant> &valueList) +{ + m_valueList = valueList; + m_edit->clear(); + fillBox(); +} + +} + +#ifndef PURE_QT +#include "pcombobox.moc" +#endif + diff --git a/lib/widgets/propeditor/pcombobox.h b/lib/widgets/propeditor/pcombobox.h new file mode 100644 index 00000000..c2f8dc2f --- /dev/null +++ b/lib/widgets/propeditor/pcombobox.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PCOMBOBOX_H +#define PCOMBOBOX_H + +#include <qmap.h> + +#include <qcombobox.h> + +#include "propertywidget.h" + +class QComboBox; + +namespace PropertyLib{ + +/** +@short %Property editor with combobox. +*/ +class PComboBox: public PropertyWidget{ + Q_OBJECT +public: + /**This constructor is used for read-only selection combo. It provides a value from valueList*/ + PComboBox(MultiProperty *property, const QMap<QString, QVariant> &list, QWidget *parent = 0, const char *name = 0); + /**This constructor is used for read-write selection combo. It provides a value from valueList*/ + PComboBox(MultiProperty *property, const QMap<QString, QVariant> &list, bool rw, QWidget *parent = 0, const char *name = 0); + + /**@return the value currently entered in the editor widget.*/ + virtual QVariant value() const; + /**Sets the value shown in the editor widget. Set emitChange to false + if you don't want to emit propertyChanged signal.*/ + virtual void setValue(const QVariant &value, bool emitChange=true); + /**Sets the list of possible values shown in the editor widget. This method + does not emit propertyChanged signal. Reimplemented because combobox is used + to display possible values from valueList.*/ + virtual void setValueList(const QMap<QString, QVariant> &valueList); + +protected: + QString findDescription(const QVariant &value); + +protected slots: + void updateProperty(int val); + +private: + virtual void fillBox(); + void init(bool rw = false); + + /** map<description, value>*/ + QMap<QString, QVariant> m_valueList; + + QComboBox *m_edit; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pcursoredit.cpp b/lib/widgets/propeditor/pcursoredit.cpp new file mode 100644 index 00000000..5667421d --- /dev/null +++ b/lib/widgets/propeditor/pcursoredit.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pcursoredit.h" + +#include <qpainter.h> + +namespace PropertyLib{ + +PCursorEdit::PCursorEdit(MultiProperty* property, const QMap<QString, QVariant> &spValues, + QWidget* parent, const char* name) + :PComboBox(property, spValues, parent, name) +{ +} + +void PCursorEdit::drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value) +{ + PropertyWidget::drawViewer(p, cg, r, findDescription(value)); +} + +} + +#ifndef PURE_QT +#include "pcursoredit.moc" +#endif diff --git a/lib/widgets/propeditor/pcursoredit.h b/lib/widgets/propeditor/pcursoredit.h new file mode 100644 index 00000000..0a9ccb9a --- /dev/null +++ b/lib/widgets/propeditor/pcursoredit.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PCURSOREDIT_H +#define PCURSOREDIT_H + +#include "pcombobox.h" + +namespace PropertyLib{ + +/** +@short %Property editor for QCursor values. +*/ +class PCursorEdit: public PComboBox +{ + Q_OBJECT +public: + PCursorEdit(MultiProperty* property, const QMap<QString, QVariant> &spValues, + QWidget* parent = 0, const char* name = 0); + + virtual void drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value); +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pdateedit.cpp b/lib/widgets/propeditor/pdateedit.cpp new file mode 100644 index 00000000..48a020e8 --- /dev/null +++ b/lib/widgets/propeditor/pdateedit.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pdateedit.h" + +#include <qdatetimeedit.h> +#include <qpainter.h> +#include <qlayout.h> + +namespace PropertyLib{ + +PDateEdit::PDateEdit(MultiProperty* property, QWidget* parent, const char* name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QDateEdit(this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + connect(m_edit, SIGNAL(valueChanged(const QDate&)), this, SLOT(updateProperty(const QDate&))); +} + +QVariant PDateEdit::value() const +{ + return QVariant(m_edit->date()); +} + +void PDateEdit::drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value) +{ + p->setPen(Qt::NoPen); + p->setBrush(cg.background()); + p->drawRect(r); + p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, value.toDate().toString(Qt::LocalDate)); +} + +void PDateEdit::setValue(const QVariant& value, bool emitChange) +{ + disconnect(m_edit, SIGNAL(valueChanged(const QDate&)), this, SLOT(updateProperty(const QDate&))); + m_edit->setDate(value.toDate()); + connect(m_edit, SIGNAL(valueChanged(const QDate&)), this, SLOT(updateProperty(const QDate&))); + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PDateEdit::updateProperty(const QDate &val) +{ + emit propertyChanged(m_property, QVariant(val)); +} + +} + +#ifndef PURE_QT +#include "pdateedit.moc" +#endif diff --git a/lib/widgets/propeditor/pdateedit.h b/lib/widgets/propeditor/pdateedit.h new file mode 100644 index 00000000..166e1e3f --- /dev/null +++ b/lib/widgets/propeditor/pdateedit.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PDATEEDIT_H +#define PDATEEDIT_H + +#include "propertywidget.h" + +class QDateEdit; + +namespace PropertyLib{ + +/** +@short %Property editor for QDate values. +*/ +class PDateEdit : public PropertyWidget +{ +Q_OBJECT +public: + PDateEdit(MultiProperty* property, QWidget* parent=0, const char* name=0); + + virtual QVariant value() const; + virtual void drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value); + virtual void setValue(const QVariant& value, bool emitChange); + +private slots: + void updateProperty(const QDate &val); + +private: + QDateEdit *m_edit; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pdatetimeedit.cpp b/lib/widgets/propeditor/pdatetimeedit.cpp new file mode 100644 index 00000000..ec9025ec --- /dev/null +++ b/lib/widgets/propeditor/pdatetimeedit.cpp @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pdatetimeedit.h" + +#include <qdatetimeedit.h> +#include <qpainter.h> +#include <qlayout.h> + +namespace PropertyLib{ + +PDateTimeEdit::PDateTimeEdit(MultiProperty* property, QWidget* parent, const char* name): PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QDateTimeEdit(this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + connect(m_edit, SIGNAL(valueChanged(const QDateTime&)), this, SLOT(updateProperty(const QDateTime&))); +} + +QVariant PDateTimeEdit::value() const +{ + return QVariant(m_edit->dateTime()); +} + +void PDateTimeEdit::drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value) +{ + p->setPen(Qt::NoPen); + p->setBrush(cg.background()); + p->drawRect(r); + p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, value.toDateTime().toString(Qt::LocalDate)); +} + +void PDateTimeEdit::setValue(const QVariant& value, bool emitChange) +{ + disconnect(m_edit, SIGNAL(valueChanged(const QDateTime&)), this, SLOT(updateProperty(const QDateTime&))); + m_edit->setDateTime(value.toDateTime()); + connect(m_edit, SIGNAL(valueChanged(const QDateTime&)), this, SLOT(updateProperty(const QDateTime&))); + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PDateTimeEdit::updateProperty(const QDateTime &val) +{ + emit propertyChanged(m_property, QVariant(val)); +} + +} + +#ifndef PURE_QT +#include "pdatetimeedit.moc" +#endif diff --git a/lib/widgets/propeditor/pdatetimeedit.h b/lib/widgets/propeditor/pdatetimeedit.h new file mode 100644 index 00000000..6421ef03 --- /dev/null +++ b/lib/widgets/propeditor/pdatetimeedit.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PDATETIMEEDIT_H +#define PDATETIMEEDIT_H + +#include "propertywidget.h" + +class QDateTimeEdit; + +namespace PropertyLib{ + +/** +@short %Property editor for QDateTime values. +*/ +class PDateTimeEdit : public PropertyWidget +{ +Q_OBJECT +public: + PDateTimeEdit(MultiProperty* property, QWidget* parent=0, const char* name=0); + + virtual QVariant value() const; + virtual void drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value); + virtual void setValue(const QVariant& value, bool emitChange); + +private slots: + void updateProperty(const QDateTime &val); + +private: + QDateTimeEdit *m_edit; + +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pdoublenuminput.cpp b/lib/widgets/propeditor/pdoublenuminput.cpp new file mode 100644 index 00000000..5be997e4 --- /dev/null +++ b/lib/widgets/propeditor/pdoublenuminput.cpp @@ -0,0 +1,94 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pdoublenuminput.h" + +#ifndef PURE_QT +#include <knuminput.h> +#else +#include "qfloatinput.h" +#endif + +#include <limits.h> +#include <math.h> +#include <qlayout.h> + +namespace PropertyLib{ + +PDoubleNumInput::PDoubleNumInput(MultiProperty *property, QWidget *parent, const char *name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); +#ifndef PURE_QT + m_edit = new KDoubleNumInput(-999999.0, 999999.0, 0.0, 0.01, 2, this); + m_edit->setLabel(QString::null); + connect(m_edit, SIGNAL(valueChanged(double)), this, SLOT(updateProperty(double))); +#else + m_edit = new QFloatInput(-999999, 999999, 0.01, 2, this ); + connect(m_edit, SIGNAL(valueChanged(int)), this, SLOT(updateProperty(int))); +#endif + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); +/* m_edit->setMinValue(-999999999); + m_edit->setMaxValue(+999999999); + m_edit->setPrecision(2);*/ + l->addWidget(m_edit); + +} + +QVariant PDoubleNumInput::value() const +{ + return QVariant(m_edit->value()); +} + +void PDoubleNumInput::setValue(const QVariant &value, bool emitChange) +{ +#ifndef PURE_QT + disconnect(m_edit, SIGNAL(valueChanged(double)), this, SLOT(updateProperty(double))); + m_edit->setValue(value.toDouble()); + connect(m_edit, SIGNAL(valueChanged(double)), this, SLOT(updateProperty(double))); +#else + disconnect(m_edit, SIGNAL(valueChanged(int)), this, SLOT(updateProperty(int))); + m_edit->setValue(int(value.toDouble()*pow(m_edit->digits(),10))); + connect(m_edit, SIGNAL(valueChanged(int)), this, SLOT(updateProperty(int))); +#endif + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PDoubleNumInput::updateProperty(double val) +{ + emit propertyChanged(m_property, QVariant(val)); +} +void PDoubleNumInput::updateProperty(int val) +{ +#ifdef PURE_QT + QString format = QString("%.%1f").arg( m_edit->digits() ); + QString strVal = QString().sprintf(format.latin1(), + (val/(float)pow(m_edit->digits(),10)) ); + emit propertyChanged(m_property, QVariant(strVal)); +#else + Q_UNUSED(val); +#endif +} + +} + +#ifndef PURE_QT +#include "pdoublenuminput.moc" +#endif diff --git a/lib/widgets/propeditor/pdoublenuminput.h b/lib/widgets/propeditor/pdoublenuminput.h new file mode 100644 index 00000000..f38622ed --- /dev/null +++ b/lib/widgets/propeditor/pdoublenuminput.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PDOUBLENUMINPUT_H +#define PDOUBLENUMINPUT_H + +#include "propertywidget.h" + +#ifndef PURE_QT +class KDoubleNumInput; +#else +class QFloatInput; +#endif + +namespace PropertyLib{ + +/** +@short %Property editor with double num input box. +*/ +class PDoubleNumInput: public PropertyWidget +{ +Q_OBJECT +public: + PDoubleNumInput(MultiProperty *property, QWidget *parent = 0, const char *name = 0); + + /**@return the value currently entered in the editor widget.*/ + virtual QVariant value() const; + /**Sets the value shown in the editor widget. Set emitChange to false + if you don't want to emit propertyChanged signal.*/ + virtual void setValue(const QVariant &value, bool emitChange=true); + +private slots: + //because of a bug in moc which doesn't detect conditional slots + //we need them both + void updateProperty(double val); + void updateProperty(int val); + +private: +#ifndef PURE_QT + KDoubleNumInput *m_edit; +#else + QFloatInput *m_edit; +#endif +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pdummywidget.cpp b/lib/widgets/propeditor/pdummywidget.cpp new file mode 100644 index 00000000..ddf09d12 --- /dev/null +++ b/lib/widgets/propeditor/pdummywidget.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pdummywidget.h" + +#include <qpainter.h> + +namespace PropertyLib{ + +PDummyWidget::PDummyWidget(MultiProperty *property, QWidget *parent, const char *name) + :PropertyWidget(property, parent, name) +{ +} + +QVariant PDummyWidget::value() const +{ + return m_value; +} + +void PDummyWidget::setValue(const QVariant &value, bool emitChange) +{ + m_value = value; + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PDummyWidget::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &/*value*/) +{ + p->setBrush(cg.background()); + p->setPen(Qt::NoPen); + p->drawRect(r); +} + +} + +#ifndef PURE_QT +#include "pdummywidget.moc" +#endif diff --git a/lib/widgets/propeditor/pdummywidget.h b/lib/widgets/propeditor/pdummywidget.h new file mode 100644 index 00000000..24a30837 --- /dev/null +++ b/lib/widgets/propeditor/pdummywidget.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PDUMMYWIDGET_H +#define PDUMMYWIDGET_H + +#include "propertywidget.h" +#include "multiproperty.h" + +class QWidget; +class QVariant; +class QPainter; +class QColorGroup; +class QRect; + +namespace PropertyLib{ + +/** +@short %Property editor with empty widget. + +This is usefull for properties which can't be edited in a generic way +like QValueList's or QMap's stored in a variant. +*/ +class PDummyWidget: public PropertyWidget +{ + Q_OBJECT +public: + PDummyWidget(MultiProperty *property, QWidget *parent = 0, const char *name = 0); + + /**@return the value currently entered in the editor widget.*/ + virtual QVariant value() const; + /**Sets the value shown in the editor widget. Set emitChange to false + if you don't want to emit propertyChanged signal.*/ + virtual void setValue(const QVariant& value, bool emitChange); + /**Function to draw a property viewer when the editor isn't shown.*/ + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + +private: + QVariant m_value; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pfontbutton.cpp b/lib/widgets/propeditor/pfontbutton.cpp new file mode 100644 index 00000000..3b999dd3 --- /dev/null +++ b/lib/widgets/propeditor/pfontbutton.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pfontbutton.h" + +#include <qlayout.h> +#include <qpainter.h> +#include <qpushbutton.h> + +#include <kfontrequester.h> + +#ifndef PURE_QT +#include <klocale.h> +#else +#include "compat_tools.h" +#endif + +namespace PropertyLib{ + +PFontButton::PFontButton(MultiProperty* property, QWidget* parent, const char* name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new KFontRequester(this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); +#ifndef PURE_QT + m_edit->button()->setText(i18n("...")); +#endif + l->addWidget(m_edit); + + connect(m_edit, SIGNAL(fontSelected(const QFont& )), this, SLOT(updateProperty(const QFont& ))); +} + +QVariant PFontButton::value() const +{ + return QVariant(m_edit->font()); +} + +void PFontButton::drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value) +{ + p->setPen(Qt::NoPen); + p->setBrush(cg.background()); + p->drawRect(r); + QFontInfo fi(value.toFont()); + p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, + fi.family() + (fi.bold() ? i18n(" Bold") : QString("")) + + (fi.italic() ? i18n(" Italic") : QString("")) + + " " + QString("%1").arg(fi.pointSize()) ); +} + +void PFontButton::setValue(const QVariant& value, bool emitChange) +{ + disconnect(m_edit, SIGNAL(fontSelected(const QFont&)), this, SLOT(updateProperty(const QFont&))); + m_edit->setFont(value.toFont()); + connect(m_edit, SIGNAL(fontSelected(const QFont& )), this, SLOT(updateProperty(const QFont& ))); + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PFontButton::updateProperty(const QFont &// font + ) +{ + emit propertyChanged(m_property, value()); +} + +} + +#ifndef PURE_QT +#include "pfontbutton.moc" +#endif diff --git a/lib/widgets/propeditor/pfontbutton.h b/lib/widgets/propeditor/pfontbutton.h new file mode 100644 index 00000000..20dcd566 --- /dev/null +++ b/lib/widgets/propeditor/pfontbutton.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PFONTBUTTON_H +#define PFONTBUTTON_H + +#include "propertywidget.h" + +class KFontRequester; + +namespace PropertyLib{ + +/** +@short %Property editor with font chooser button. +*/ +class PFontButton : public PropertyWidget +{ +Q_OBJECT +public: + PFontButton(MultiProperty* property, QWidget* parent = 0, const char* name = 0); + + virtual QVariant value() const; + virtual void drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value); + virtual void setValue(const QVariant& value, bool emitChange); + +protected slots: + void updateProperty(const QFont& font); + +private: + KFontRequester *m_edit; + +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pfontcombo.cpp b/lib/widgets/propeditor/pfontcombo.cpp new file mode 100644 index 00000000..7c648a30 --- /dev/null +++ b/lib/widgets/propeditor/pfontcombo.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pfontcombo.h" + +#ifndef PURE_QT +#include <kfontcombo.h> +#else +#include <qcombobox.h> +#endif + +#include <qlayout.h> + +#ifdef PURE_QT +#include <qfontdatabase.h> +#endif + +namespace PropertyLib{ + +PFontCombo::PFontCombo(MultiProperty *property, QWidget *parent, const char *name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new KFontCombo(this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + /*adymo: KFontCombo seems to have a bug: when it is not editable, the signals + activated(int) and textChanged(const QString &) are not emitted*/ +#ifdef PURE_QT + QFontDatabase fonts; + m_edit->insertStringList(fonts.families()); + connect(m_edit, SIGNAL(activated(const QString &)), this, SLOT(updateProperty(const QString&))); +#else + connect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(updateProperty(const QString&))); +#endif +} + +QVariant PFontCombo::value() const +{ +#ifndef PURE_QT + return QVariant(m_edit->currentFont()); +#else + return QVariant(m_edit->currentText()); +#endif +} + +void PFontCombo::setValue(const QVariant &value, bool emitChange) +{ + disconnect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(updateProperty(const QString&))); +#ifndef PURE_QT + m_edit->setCurrentFont(value.toString()); +#else + m_edit->setCurrentText(value.toString()); +#endif + connect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(updateProperty(const QString&))); + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PFontCombo::updateProperty(const QString &val) +{ + emit propertyChanged(m_property, QVariant(val)); +} + +} + +#ifndef PURE_QT +#include "pfontcombo.moc" +#endif diff --git a/lib/widgets/propeditor/pfontcombo.h b/lib/widgets/propeditor/pfontcombo.h new file mode 100644 index 00000000..be2671db --- /dev/null +++ b/lib/widgets/propeditor/pfontcombo.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PFONTCOMBO_H +#define PFONTCOMBO_H + +#include "propertywidget.h" + +#ifdef PURE_QT +#define KFontCombo QComboBox +#endif + +class KFontCombo; + +namespace PropertyLib{ + +/** +@short %Property editor with font combo box. +*/ +class PFontCombo: public PropertyWidget{ + Q_OBJECT +public: + PFontCombo(MultiProperty *property, QWidget *parent = 0, const char *name = 0); + + /**@return the value currently entered in the editor widget.*/ + virtual QVariant value() const; + /**Sets the value shown in the editor widget. Set emitChange to false + if you don't want to emit propertyChanged signal.*/ + virtual void setValue(const QVariant &value, bool emitChange=true); + +private slots: + void updateProperty(const QString &val); + +private: + KFontCombo *m_edit; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/plineedit.cpp b/lib/widgets/propeditor/plineedit.cpp new file mode 100644 index 00000000..ac5d7c2a --- /dev/null +++ b/lib/widgets/propeditor/plineedit.cpp @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "plineedit.h" + +#include <klineedit.h> +#include <qlayout.h> + +namespace PropertyLib{ + +PLineEdit::PLineEdit(MultiProperty *property, QWidget *parent, const char *name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new KLineEdit(this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + connect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(updateProperty(const QString&))); +} + +QVariant PLineEdit::value() const +{ + return QVariant(m_edit->text()); +} + +void PLineEdit::setValue(const QVariant &value, bool emitChange) +{ + disconnect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(updateProperty(const QString&))); + m_edit->setText(value.toString()); + connect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(updateProperty(const QString&))); + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PLineEdit::updateProperty(const QString& val) +{ + emit propertyChanged(m_property, QVariant(val)); +} + +} + +#ifndef PURE_QT +#include "plineedit.moc" +#endif diff --git a/lib/widgets/propeditor/plineedit.h b/lib/widgets/propeditor/plineedit.h new file mode 100644 index 00000000..ea6f0bd9 --- /dev/null +++ b/lib/widgets/propeditor/plineedit.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PLINEEDIT_H +#define PLINEEDIT_H + +#include "propertywidget.h" + +class KLineEdit; + +namespace PropertyLib{ + +/** +@short %Property editor with line edit. +*/ +class PLineEdit: public PropertyWidget{ + Q_OBJECT +public: + PLineEdit(MultiProperty *property, QWidget *parent = 0, const char *name = 0); + + /**@return the value currently entered in the editor widget.*/ + virtual QVariant value() const; + /**Sets the value shown in the editor widget. Set emitChange to false + if you don't want to emit propertyChanged signal.*/ + virtual void setValue(const QVariant &value, bool emitChange=true); + +private slots: + void updateProperty(const QString &val); + +private: + KLineEdit *m_edit; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/plinestyleedit.cpp b/lib/widgets/propeditor/plinestyleedit.cpp new file mode 100644 index 00000000..d596ad93 --- /dev/null +++ b/lib/widgets/propeditor/plinestyleedit.cpp @@ -0,0 +1,205 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "plinestyleedit.h" + +#include <qpainter.h> +#include <qpixmap.h> +#include <qcombobox.h> +#include <qlayout.h> + +namespace PropertyLib { + + const char *nopen[]={ + "48 16 1 1", + ". c None", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................"}; + const char *solid[]={ + "48 16 2 1", + ". c None", + "# c #000000", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + ".###########################################....", + ".###########################################....", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................"}; + const char *dash[]={ + "48 16 2 1", + ". c None", + "# c #000000", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + ".#########..#########..#########..##########....", + ".#########..#########..#########..##########....", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................"}; + const char *dashdot[]={ + "48 16 2 1", + ". c None", + "# c #000000", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + ".#########..##..#########..##..#########..##....", + ".#########..##..#########..##..#########..##....", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................"}; + const char *dashdotdot[]={ + "48 16 2 1", + ". c None", + "# c #000000", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + ".#########..##..##..#########..##..##..#####....", + ".#########..##..##..#########..##..##..#####....", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................"}; + + +PLineStyleEdit::PLineStyleEdit(MultiProperty* property, QWidget* parent, const char* name): PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QComboBox(this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + m_edit->insertItem(QPixmap(nopen)); + m_edit->insertItem(QPixmap(solid)); + m_edit->insertItem(QPixmap(dash)); + m_edit->insertItem(QPixmap(dashdot)); + m_edit->insertItem(QPixmap(dashdotdot)); + + connect(m_edit, SIGNAL(activated(int)), this, SLOT(updateProperty(int))); +} + +QVariant PLineStyleEdit::value() const +{ + return m_edit->currentItem(); +} + +void PLineStyleEdit::drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value) +{ + p->setPen(Qt::NoPen); + p->setBrush(cg.background()); + p->drawRect(r); + + if (!value.canCast(QVariant::Int)) + if ((value.toInt() > 5) || (value.toInt() < 0)) + return; + + switch (value.toInt()) { + case 0: + p->drawPixmap(r, QPixmap(nopen)); + break; + case 1: + p->drawPixmap(r, QPixmap(solid)); + break; + case 2: + p->drawPixmap(r, QPixmap(dash)); + break; + case 3: + p->drawPixmap(r, QPixmap(dashdot)); + break; + case 4: + p->drawPixmap(r, QPixmap(dashdot)); + break; + case 5: + p->drawPixmap(r, QPixmap(dashdotdot)); + break; + } +} + +void PLineStyleEdit::setValue(const QVariant& value, bool emitChange) +{ + if (!value.canCast(QVariant::Int)) + return; + if ((value.toInt() > 5) || (value.toInt() < 0)) + return; + disconnect(m_edit, SIGNAL(activated(int)), this, SLOT(updateProperty(int))); + m_edit->setCurrentItem(value.toInt()); + connect(m_edit, SIGNAL(activated(int)), this, SLOT(updateProperty(int))); + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PLineStyleEdit::updateProperty(int val) +{ + emit propertyChanged(m_property, QVariant(val)); +} + +} + +#ifndef PURE_QT +#include "plinestyleedit.moc" +#endif diff --git a/lib/widgets/propeditor/plinestyleedit.h b/lib/widgets/propeditor/plinestyleedit.h new file mode 100644 index 00000000..1992efba --- /dev/null +++ b/lib/widgets/propeditor/plinestyleedit.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PROPERTYLIBPLINESTYLEEDIT_H +#define PROPERTYLIBPLINESTYLEEDIT_H + +#include "propertywidget.h" + +class QComboBox; + +namespace PropertyLib { + +/** +@short Line style editor +*/ +class PLineStyleEdit : public PropertyWidget { + Q_OBJECT +public: + PLineStyleEdit(MultiProperty* property, QWidget* parent = 0, const char* name = 0); + + virtual QVariant value() const; + virtual void drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value); + virtual void setValue(const QVariant& value, bool emitChange); + +private slots: + void updateProperty(int val); + +private: + QComboBox *m_edit; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/ppixmapedit.cpp b/lib/widgets/propeditor/ppixmapedit.cpp new file mode 100644 index 00000000..b20cc7b3 --- /dev/null +++ b/lib/widgets/propeditor/ppixmapedit.cpp @@ -0,0 +1,149 @@ +/*************************************************************************** + * Copyright (C) 2003 Cedric Pasteur * + * <cedric.pasteur@free.fr> * + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "ppixmapedit.h" + +#include <qlayout.h> +#include <qpainter.h> +#include <qlabel.h> +#include <qcursor.h> + +#ifndef PURE_QT +#include <klocale.h> +#else +#include "compat_tools.h" +#endif + +#ifndef PURE_QT +#include <kfiledialog.h> +#else +#include <qfiledialog.h> +#endif +#include <qpushbutton.h> + +namespace PropertyLib{ + +PPixmapEdit::PPixmapEdit(MultiProperty* property, QWidget* parent, const char* name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QLabel(this); + m_edit->setAlignment(Qt::AlignTop); + m_edit->resize(width(), height()-1); + m_edit->setBackgroundMode(Qt::PaletteBase); + m_edit->installEventFilter(this); + + m_button = new QPushButton(i18n("..."), this); + m_button->resize(height(), height()-8); + m_button->move(width() - m_button->width() -1, 0); + m_button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + l->addWidget(m_edit); + l->addWidget(m_button); + m_popup = new QLabel(0, 0, Qt::WStyle_NoBorder|Qt::WX11BypassWM|WStyle_StaysOnTop); + m_popup->hide(); + + + connect(m_button, SIGNAL(clicked()), this, SLOT(updateProperty())); +} + +QVariant PPixmapEdit::value() const +{ + return QVariant(*(m_edit->pixmap())); +} + +void PPixmapEdit::drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value) +{ + p->setPen(Qt::NoPen); + p->setBrush(cg.background()); + p->drawRect(r); + p->drawPixmap(r.topLeft().x(), r.topLeft().y(), value.toPixmap()); +} + +void PPixmapEdit::setValue(const QVariant& value, bool emitChange) +{ + m_edit->setPixmap(value.toPixmap()); + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PPixmapEdit::updateProperty() +{ +#ifndef PURE_QT + KURL url = KFileDialog::getImageOpenURL(QString::null, this); + if (!url.isEmpty()) + { + m_edit->setPixmap(QPixmap(url.path())); + emit propertyChanged(m_property, value()); + } +#else + QString url = QFileDialog::getOpenFileName(); + if (!url.isEmpty()) + { + m_edit->setPixmap(QPixmap(url)); + emit propertyChanged(m_property, value()); + } +#endif +} + +void PPixmapEdit::resizeEvent(QResizeEvent *ev) +{ + m_edit->resize(ev->size().width(), ev->size().height()-1); + m_button->move(ev->size().width() - m_button->width(), 0); + m_edit->setMaximumHeight(m_button->height()); +} + +bool PPixmapEdit::eventFilter(QObject *o, QEvent *ev) +{ + if(o == m_edit) + { + if(ev->type() == QEvent::MouseButtonPress) + { + if(m_edit->pixmap()->size().height() < height()-2 + && m_edit->pixmap()->size().width() < width()-20) + return false; + m_popup->setPixmap(*(m_edit->pixmap())); + m_popup->resize(m_edit->pixmap()->size()); + m_popup->move(QCursor::pos()); + m_popup->show(); + } + if(ev->type() == QEvent::MouseButtonRelease) + { + if(m_popup->isVisible()) + m_popup->hide(); + } + if(ev->type() == QEvent::KeyPress) + { + QKeyEvent* e = static_cast<QKeyEvent*>(ev); + if((e->key() == Key_Enter) || (e->key()== Key_Space) || (e->key() == Key_Return)) + { + m_button->animateClick(); + return true; + } + } + } + return PropertyWidget::eventFilter(o, ev); +} + +} + +#ifndef PURE_QT +#include "ppixmapedit.moc" +#endif diff --git a/lib/widgets/propeditor/ppixmapedit.h b/lib/widgets/propeditor/ppixmapedit.h new file mode 100644 index 00000000..e61dc73c --- /dev/null +++ b/lib/widgets/propeditor/ppixmapedit.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PPIXMAPEDIT_H +#define PPIXMAPEDIT_H + +#include "propertywidget.h" + +class QLabel; +class QPushButton; + +namespace PropertyLib{ + +/** +@short %Property editor which shows a pixmap and allows to load it from file. +*/ +class PPixmapEdit : public PropertyWidget +{ + Q_OBJECT +public: + PPixmapEdit(MultiProperty* property, QWidget* parent = 0, const char* name = 0); + + virtual QVariant value() const; + virtual void drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value); + virtual void setValue(const QVariant& value, bool emitChange); + + virtual void resizeEvent(QResizeEvent *ev); + virtual bool eventFilter(QObject *o, QEvent *ev); + +protected slots: + void updateProperty(); + +private: + QLabel *m_edit; + QLabel *m_popup; + QPushButton *m_button; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/ppointedit.cpp b/lib/widgets/propeditor/ppointedit.cpp new file mode 100644 index 00000000..f9f37bf0 --- /dev/null +++ b/lib/widgets/propeditor/ppointedit.cpp @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "ppointedit.h" + +#include <klineedit.h> +#include <qlayout.h> +#include <qpainter.h> + +namespace PropertyLib{ + +PPointEdit::PPointEdit(MultiProperty* property, QWidget* parent, const char* name): PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new KLineEdit(this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + m_edit->setReadOnly(true); +} + +QVariant PPointEdit::value() const +{ + return m_value; +} + +void PPointEdit::drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value) +{ + p->setPen(Qt::NoPen); + p->setBrush(cg.background()); + p->drawRect(r); + p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, QString("[ %1, %2 ]").arg(value.toPoint().x()).arg(value.toPoint().y())); +} + +void PPointEdit::setValue(const QVariant& value, bool emitChange) +{ + m_value = value; + m_edit->setText(QString("[ %1, %2 ]").arg(value.toPoint().x()).arg(value.toPoint().y())); + + if (emitChange) + emit propertyChanged(m_property, value); +} + +} + +#ifndef PURE_QT +#include "ppointedit.moc" +#endif diff --git a/lib/widgets/propeditor/ppointedit.h b/lib/widgets/propeditor/ppointedit.h new file mode 100644 index 00000000..9b571ced --- /dev/null +++ b/lib/widgets/propeditor/ppointedit.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PPOINTEDIT_H +#define PPOINTEDIT_H + +#include "propertywidget.h" + +class KLineEdit; + +namespace PropertyLib{ + +/** +@short %Property editor for QPoint values. +*/ +class PPointEdit : public PropertyWidget +{ +Q_OBJECT +public: + PPointEdit(MultiProperty* property, QWidget* parent=0, const char* name=0); + + virtual QVariant value() const; + virtual void drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value); + virtual void setValue(const QVariant& value, bool emitChange); + +private: + KLineEdit *m_edit; + QVariant m_value; + +}; + +} + +#endif diff --git a/lib/widgets/propeditor/prectedit.cpp b/lib/widgets/propeditor/prectedit.cpp new file mode 100644 index 00000000..c049b5d6 --- /dev/null +++ b/lib/widgets/propeditor/prectedit.cpp @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "prectedit.h" + +#include <klineedit.h> +#include <qlayout.h> +#include <qpainter.h> + +namespace PropertyLib{ + +PRectEdit::PRectEdit(MultiProperty* property, QWidget* parent, const char* name): PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new KLineEdit(this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + m_edit->setReadOnly(true); +} + +QVariant PRectEdit::value() const +{ + return m_value; +} + +void PRectEdit::drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value) +{ + p->setPen(Qt::NoPen); + p->setBrush(cg.background()); + p->drawRect(r); + p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, QString("[ %1, %2, %3, %4 ]").arg(value.toRect().x()).arg(value.toRect().y()).arg(value.toRect().width()).arg(value.toRect().height())); +} + +void PRectEdit::setValue(const QVariant& value, bool emitChange) +{ + m_value = value; + m_edit->setText(QString("[ %1, %2, %3, %4 ]").arg(value.toRect().x()).arg(value.toRect().y()).arg(value.toRect().width()).arg(value.toRect().height())); + + if (emitChange) + emit propertyChanged(m_property, value); +} + +} + +#ifndef PURE_QT +#include "prectedit.moc" +#endif diff --git a/lib/widgets/propeditor/prectedit.h b/lib/widgets/propeditor/prectedit.h new file mode 100644 index 00000000..44bcfed4 --- /dev/null +++ b/lib/widgets/propeditor/prectedit.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PRECTEDIT_H +#define PRECTEDIT_H + +#include "propertywidget.h" + +class KLineEdit; + +namespace PropertyLib{ + +/** +@short %Property editor for QRect values. +*/ +class PRectEdit : public PropertyWidget +{ + Q_OBJECT +public: + PRectEdit(MultiProperty* property, QWidget* parent=0, const char* name=0); + + virtual QVariant value() const; + virtual void drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value); + virtual void setValue(const QVariant& value, bool emitChange); + +private: + KLineEdit *m_edit; + QVariant m_value; + +}; + +} + +#endif diff --git a/lib/widgets/propeditor/property.cpp b/lib/widgets/propeditor/property.cpp new file mode 100644 index 00000000..d53af8cf --- /dev/null +++ b/lib/widgets/propeditor/property.cpp @@ -0,0 +1,129 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo <cloudtemple@mskat.net> * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "property.h" + +#include <qstring.h> + +namespace PropertyLib{ + +Property::Property(int type, const QString &name, const QString &description, + const QVariant &value, bool save, bool readOnly): + m_type(type), m_name(name), m_description(description), m_value(value), m_save(save), + m_readOnly(readOnly), m_visible(true) +{ +} + +Property::Property(const QString &name, const QMap<QString, QVariant> &v_valueList, + const QString &description, const QVariant &value, bool save, bool readOnly): + valueList(v_valueList), m_type(ValueFromList), m_name(name), + m_description(description), m_value(value), m_save(save), m_readOnly(readOnly), + m_visible(true) +{ +} + +Property::~Property() +{ +} + +bool Property::allowSaving() const +{ + return m_save; +} + +bool Property::operator<(const Property &prop) const +{ + if ((type() < prop.type()) && (name() < prop.name())) + return true; + else + return false; +} + +QString Property::name() const +{ + return m_name; +} + +void Property::setName(const QString &name) +{ + m_name = name; +} + +int Property::type() const +{ + return m_type; +} + +void Property::setType(int type) +{ + m_type = type; +} + +QVariant Property::value() const +{ + return m_value; +} + +void Property::setValue(const QVariant &value, bool rememberOldValue) +{ + if (rememberOldValue) + m_oldValue = m_value; + else + m_oldValue = value; + m_value = value; +} + +QString Property::description() const +{ + return m_description; +} + +void Property::setDescription(const QString &description) +{ + m_description = description; +} + +void Property::setValueList(const QMap<QString, QVariant> &v_valueList) +{ + valueList = v_valueList; +} + +bool Property::readOnly() const +{ + return m_readOnly; +} + +bool Property::visible() const +{ + return m_visible; +} + +void Property::setVisible( const bool visible ) +{ + m_visible = visible; +} + +QVariant Property::oldValue() const +{ + if (m_oldValue.isNull()) + return m_value; + else + return m_oldValue; +} + +} diff --git a/lib/widgets/propeditor/property.h b/lib/widgets/propeditor/property.h new file mode 100644 index 00000000..13a1ad8b --- /dev/null +++ b/lib/widgets/propeditor/property.h @@ -0,0 +1,181 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo <cloudtemple@mskat.net> * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PROPERTY_H +#define PROPERTY_H + +#include <qvariant.h> + +#include <qmap.h> + +class QWidget; +class QString; + +/**Namespace which contain property editing classes.*/ +namespace PropertyLib{ + +/** @file property.h +@short Contains @ref PropertyLib::Property class and @ref PropertyLib::Property::PropertyType enum. +*/ + +/** +@short Property. + +It includes support for QStringList properties, an i18n'ed label and stores an old value to allow undo. + +Contains name, type and value. + +Type can be one of predefined types (including standard @ref QVariant types) by @ref PropertyLib::Property::PropertyType +enum or custom user type. User defined types should have values more than 3000. + +Value is a @ref QVariant. + +Property can optionally have a list of possible values. +In that case use @ref ValueFromList type and valueList member. +Use @ref description for i18n'ed label. + +Examples: +creating property: +\code +Property *property = new Property(String, name, description, value) +\endcode +using convenience constructor to create property of ValueFromList type: +\code +Property *property = new Property(name, possibleValuesList, description, value); +\endcode +*/ +class Property { +public: + /** PropertyType. + Integers that represent the type of the property. */ + enum PropertyType { + //standard supported QVariant types + Invalid = QVariant::Invalid /**<invalid property type*/, + Map = QVariant::Map /**<QMap<QString, QVariant>*/, + List = QVariant::List /**<QValueList<QVariant>*/, + String = QVariant::String /**<string*/, + StringList = QVariant::StringList /**<string list*/, + Font = QVariant::Font /**<font*/, + Pixmap = QVariant::Pixmap /**<pixmap*/, + //@todo implement QVariant::Brush + Rect = QVariant::Rect /**<rectangle (x,y, width, height)*/, + Size = QVariant::Size /**<size (width, height)*/, + Color = QVariant::Color /**<color*/, + //@todo implement QVariant::Palette + //@todo implement QVariant::ColorGroup + //@todo implement QVariant::IconSet + Point = QVariant::Point /**<point (x,y)*/, + //@todo implement QVariant::Image + Integer = QVariant::Int /**<integer*/, + //@todo implement QVariant::UInt + Boolean = QVariant::Bool /**<boolean*/, + Double = QVariant::Double /**<double*/, + //@todo implement QVariant::CString + //@todo implement QVariant::PointArray + //@todo implement QVariant::Region + //@todo implement QVariant::Bitmap + Cursor = QVariant::Cursor /**<cursor*/, + SizePolicy = QVariant::SizePolicy /**<size policy (horizontal, vertical)*/, + Date = QVariant::Date /**<date*/, + //@todo implement QVariant::Time + DateTime = QVariant::DateTime /**<date and time*/, + //@todo implement QVariant::ByteArray + //@todo implement QVariant::BitArray + //@todo implement QVariant::KeySequence + //@todo implement QVariant::Pen + //@todo implement QVariant::Long + //@todo implement QVariant::LongLong + //@todo implement QVariant::ULongLong + + + //predefined custom types + ValueFromList = 2000 /**<string value from a list*/, + Symbol = 2001 /**<unicode symbol code*/, + FontName = 2002 /**<font name, e.g. "times new roman"*/, + FileURL = 2003 /**<url of a file*/, + DirectoryURL = 2004 /**<url of a directory*/, + LineStyle = 2005 /**<line style*/, + + UserDefined = 3000 /**<plugin defined properties should start here*/ + }; + + /**Constructs empty property.*/ + Property() {} + /**Constructs property.*/ + Property(int type, const QString &name, const QString &description, + const QVariant &value = QVariant(), bool save = true, bool readOnly = false); + /**Constructs property with @ref ValueFromList type.*/ + Property(const QString &name, const QMap<QString, QVariant> &v_valueList, + const QString &description, const QVariant &value = QVariant(), bool save = true, bool readOnly = false); + virtual ~Property(); + + virtual bool operator<(const Property &prop) const; + + /**@return the name of the property.*/ + virtual QString name() const; + /**Sets the name of the property.*/ + virtual void setName(const QString &name); + /**@return the type of the property.*/ + virtual int type() const; + /**Sets the type of the property.*/ + virtual void setType(int type); + /**@return the value of the property.*/ + virtual QVariant value() const; + /**Sets the value of the property.*/ + virtual void setValue(const QVariant &value, bool rememberOldValue = true); + /**@return the description of the property.*/ + virtual QString description() const; + /**Sets the description of the property.*/ + virtual void setDescription(const QString &description); + /**Sets the string-to-value correspondence list of the property. + This is used to create comboboxes-like property editors.*/ + virtual void setValueList(const QMap<QString, QVariant> &list); + /**The string-to-value correspondence list of the property.*/ + QMap<QString, QVariant> valueList; + + /**Tells if the property can be saved to a stream, xml, etc. + There is a possibility to use "GUI" properties that aren't + stored but used only in a GUI.*/ + virtual bool allowSaving() const; + /**Tells if the property is read only.*/ + virtual bool readOnly() const; + /**Tells if the property is visible.*/ + virtual bool visible() const; + /**Set the visibility.*/ + virtual void setVisible(const bool visible); + + /**Gets the previous property value.*/ + virtual QVariant oldValue() const; + +private: +// Property(Property &property) {}; +// void operator=(Property &property) {}; + + int m_type; + QString m_name; + QString m_description; + QVariant m_value; + QVariant m_oldValue; + bool m_save; + bool m_readOnly; + bool m_visible; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/propertyeditor.cpp b/lib/widgets/propeditor/propertyeditor.cpp new file mode 100644 index 00000000..58c2b936 --- /dev/null +++ b/lib/widgets/propeditor/propertyeditor.cpp @@ -0,0 +1,480 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "propertyeditor.h" + +#ifndef PURE_QT +#include <klocale.h> +#include <kdebug.h> +#include <kiconloader.h> +#else +#include "compat_tools.h" +#endif + +#include <qtable.h> +#include <qlayout.h> +#include <qpainter.h> +#include <qptrlist.h> +#include <qvaluelist.h> +#include <qpushbutton.h> + +#include "property.h" +#include "multiproperty.h" +#include "propertymachinefactory.h" + +namespace PropertyLib{ + +class PropertyItem: public KListViewItem{ +public: + PropertyItem(PropertyEditor *parent, MultiProperty *property) + :KListViewItem(parent, property->description()), m_editor(parent), m_property(property), + m_changed(false) + { + } + + PropertyItem(PropertyEditor *editor, KListViewItem *parent, MultiProperty *property) + :KListViewItem(parent, property->description()), m_editor(editor), + m_property(property), m_changed(false) + { + } + +/* int type() const + { + return m_property->type(); + } + + QString name() const + { + return m_property->name(); + } + */ + MultiProperty *property() const + { + return m_property; + } + + virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align) + { + if ((column == 0) && m_changed) + { + QFont font; + font.setBold(true); + p->setFont(font); + p->setBrush(cg.highlight()); + p->setPen(cg.highlightedText()); + } + if (column == 1) + { + QRect r(0, 0, m_editor->header()->sectionSize(1), height()); + //FIXME: this is ugly, but how else can we deal with ValueFromList properties? + QVariant valueToDraw; + if (m_property->type() == Property::ValueFromList) + valueToDraw = m_property->findValueDescription(); + else + valueToDraw = m_property->value(); + QColorGroup icg(cg); +#ifndef PURE_QT + icg.setColor(QColorGroup::Background, backgroundColor()); +#else + icg.setColor(QColorGroup::Background, white); +#endif + m_editor->machine(m_property)->propertyEditor->drawViewer(p, icg, r, valueToDraw); + return; + } + KListViewItem::paintCell(p, cg, column, width, align); + } + + virtual void setup() + { + KListViewItem::setup(); + setHeight(static_cast<int>(height()*1.5)); + } + + void setChanged(bool changed) + { + m_changed = changed; + } + +private: + PropertyEditor *m_editor; + MultiProperty *m_property; + bool m_changed; +}; + + +class PropertyGroupItem: public KListViewItem{ +public: + PropertyGroupItem(KListView *parent, const QString &name) + :KListViewItem(parent, name) + { + init(); + } + PropertyGroupItem(KListViewItem *parent, const QString &name) + :KListViewItem(parent, name) + { + init(); + } + + virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align) + { + if (column == 0) + { + QFont font; + font.setBold(true); + p->setFont(font); + p->setBrush(cg.highlight()); + p->setPen(cg.highlightedText()); + } + KListViewItem::paintCell(p, cg, column, width, align); + } + virtual void setup() + { + KListViewItem::setup(); + setHeight(static_cast<int>(height()*1.4)); + } + +private: + void init() + { + setOpen(true); + } +}; + +class SeparatorItem: public KListViewItem{ +public: + SeparatorItem(KListView *parent) + :KListViewItem(parent) + { + setSelectable(false); + } +}; +PropertyEditor::PropertyEditor(QWidget *parent, const char *name) + :KListView(parent, name) +{ + setSorting(-1); + + addColumn(i18n("Name")); + addColumn(i18n("Value")); + setAllColumnsShowFocus(true); + setColumnWidthMode(0, QListView::Maximum); + setResizeMode(QListView::LastColumn); + + header()->setClickEnabled(false); + + connect(header(), SIGNAL(sizeChange(int, int, int)), + this, SLOT(updateEditorSize())); + connect(this, SIGNAL(currentChanged(QListViewItem*)), + this, SLOT(slotClicked(QListViewItem*))); + + m_currentEditItem = 0; + m_doubleClickForEdit = true; + m_lastClickedItem = 0; + m_currentEditWidget = 0; + m_list = 0; + + m_currentEditArea = new QWidget(viewport()); + m_currentEditArea->hide(); + m_undoButton = new QPushButton(m_currentEditArea); +#ifndef PURE_QT + m_undoButton->setPixmap(SmallIcon("undo")); +#else + m_undoButton->setPixmap( QPixmap("undo.xpm") ); +#endif + m_undoButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::MinimumExpanding); + m_undoButton->resize(m_undoButton->height(), m_undoButton->height()); + m_undoButton->hide(); + connect(m_undoButton, SIGNAL(clicked()), this, SLOT(undo())); + m_currentEditLayout = new QGridLayout(m_currentEditArea, 1, 2, 0, 0); +// m_currentEditLayout->addWidget(m_undoButton, 0, 1); +} + +PropertyEditor::~PropertyEditor() +{ + clearMachineCache(); +} + +void PropertyEditor::populateProperties(PropertyList *list) +{ + if (list == 0) + return; + m_list = list; + connect(m_list, SIGNAL(propertyValueChanged(Property*)), this, SLOT(propertyValueChanged(Property*))); + const QValueList<QPair<QString, QValueList<QString> > >& groups = m_list->propertiesOfGroup(); + for (QValueList<QPair<QString, QValueList<QString> > >::const_iterator it = groups.begin(); + it != groups.end(); ++it) + { +// qWarning("PropertyEditor::populateProperties: adding group %s", (*it).first.ascii()); + PropertyGroupItem *group = 0; + if ( (!(*it).first.isEmpty()) && ((*it).second.count() > 0) ) + group = new PropertyGroupItem(this, (*it).first); + const QValueList<QString> &properties = (*it).second; + for (QValueList<QString>::const_iterator it2 = properties.begin(); it2 != properties.end(); ++it2) + { +// qWarning("PropertyEditor::populateProperties: adding property %s", (*it2).ascii()); + if (group) + addProperty(group, *it2); + else + addProperty(*it2); + } + } + if (firstChild()) + { + setCurrentItem(firstChild()); + setSelected(firstChild(), true); + slotClicked(firstChild()); + } +} + +void PropertyEditor::addProperty(PropertyGroupItem *group, const QString &name) +{ + if ((*m_list)[name] == 0) + return; +// qWarning("%s = name : object null ", name.ascii()); + PropertyItem *pitem = new PropertyItem(this, group, (*m_list)[name]); + addChildProperties(pitem); +} + +void PropertyEditor::addProperty(const QString &name) +{ + if ((*m_list)[name] == 0) + return; +// qWarning("%s = name : object null ", name.ascii()); + PropertyItem *pitem = new PropertyItem(this, (*m_list)[name]); + addChildProperties(pitem); +} + +void PropertyEditor::addChildProperties(PropertyItem *parent) +{ + MultiProperty *prop = parent->property(); + //force machine creation to get detailed properties appended to current multiproperty + if ( !m_registeredForType.contains(prop->name()) + && (PropertyMachineFactory::getInstance()->hasDetailedEditors(prop->type())) ) + { + //FIXME: find better solution + machine(prop); + } + +// qWarning("seeking children: count: %d", prop->details.count()); + + parent->setOpen(true); + for (QValueList<ChildProperty>::iterator it = prop->details.begin(); it != prop->details.end(); ++it) + { +// qWarning("found child %s", (*it).name().ascii()); + new PropertyItem(this, parent, new MultiProperty(&m_detailedList, &(*it))); + } +} + +void PropertyEditor::clearProperties() +{ + m_detailedList.clear(); + if (!m_list) + return; + + hideEditor(); + + disconnect(m_list, SIGNAL(propertyValueChanged(Property*)), this, SLOT(propertyValueChanged(Property*))); + clear(); + delete m_list; + m_list = 0; +} + +void PropertyEditor::propertyValueChanged(Property *property) +{ +// qWarning("PropertyEditor::propertyValueChanged"); + if (m_currentEditWidget->propertyName() == property->name()) + m_currentEditWidget->setValue(property->value(), false); + else + { +// repaint all items + QListViewItemIterator it(this); + while (it.current()) + { + repaintItem(it.current()); + ++it; + } + } +} + +void PropertyEditor::propertyChanged(MultiProperty *property, const QVariant &value) +{ + if (!property) + return; + + qWarning("editor: assign %s to %s", property->name().latin1(), value.toString().latin1()); + property->setValue(value, false); + + //highlight changed properties + if (m_currentEditItem && (m_currentEditItem->property() == property)) + { + m_currentEditItem->setChanged(true); + repaintItem(m_currentEditItem); + } + + emit changed(); + +/* if (m_list->contains(name)) + { + (*m_list)[name]->setValue(value, false); +// else if (m_detailedList->contains(*/ +} + +void PropertyEditor::hideEditor() +{ + m_lastClickedItem = 0; + m_currentEditItem = 0; + if (m_currentEditWidget) + { + m_currentEditLayout->remove(m_currentEditWidget); + m_currentEditWidget->hide(); + } + m_currentEditLayout->remove(m_undoButton); + m_undoButton->hide(); + m_currentEditArea->hide(); + m_currentEditWidget = 0; +} + +void PropertyEditor::showEditor(PropertyItem *item) +{ + m_currentEditItem = item; + placeEditor(item); + m_currentEditWidget->show(); + m_undoButton->show(); + m_currentEditArea->show(); +} + +void PropertyEditor::placeEditor(PropertyItem *item) +{ + QRect r = itemRect(item); + if (!r.size().isValid()) + { + ensureItemVisible(item); + r = itemRect(item); + } + + r.setX(header()->sectionPos(1)); + r.setWidth(header()->sectionSize(1)); + + // check if the column is fully visible + if (visibleWidth() < r.right()) + r.setRight(visibleWidth()); + + r = QRect(viewportToContents(r.topLeft()), r.size()); + + if (item->pixmap(1)) + { + r.setX(r.x() + item->pixmap(1)->width()); + } + + if (PropertyWidget* editor = prepareEditor(item)) + { + m_currentEditLayout->addWidget(editor, 0, 0); + m_currentEditLayout->addWidget(m_undoButton, 0, 1); + m_currentEditArea->resize(r.size()); +// m_currentEditLayout->invalidate(); + moveChild(m_currentEditArea, r.x(), r.y()); + m_currentEditWidget = editor; + } +} + +PropertyWidget* PropertyEditor::prepareEditor(PropertyItem *item) +{ + PropertyWidget *editorWidget = 0; +/* if (item->depth() >= 2) + { + editorWidget = machine(item->name())->propertyEditor; + editorWidget->setValue(m_accessor->value(item->name()), false); + } + else + {*/ + editorWidget = machine(item->property())->propertyEditor; + editorWidget->setProperty(item->property()); + if (item->property()->type() == Property::ValueFromList) + editorWidget->setValueList(item->property()->valueList()); + editorWidget->setValue(item->property()->value(), false); + //} + return editorWidget; +} + +void PropertyEditor::updateEditorSize() +{ + if (m_currentEditItem) + placeEditor(m_currentEditItem); +} + +void PropertyEditor::slotClicked(QListViewItem *item) +{ + if (item == 0) + { + hideEditor(); + return; + } + if (item != m_lastClickedItem) + { + hideEditor(); + PropertyItem *it = dynamic_cast<PropertyItem*>(item); + if (it) + { + showEditor(it); + } + } + + m_lastClickedItem = item; +} + +Machine *PropertyEditor::machine(MultiProperty *property) +{ +// int type = property->type(); + QString name = property->name(); + QMap<QString, QVariant> values = property->valueList(); + if (m_registeredForType[name] == 0) + { + m_registeredForType[name] = PropertyMachineFactory::getInstance()->machineForProperty(property); + connect(m_registeredForType[name]->propertyEditor, SIGNAL(propertyChanged(MultiProperty*, const QVariant&)), + this, SLOT(propertyChanged(MultiProperty*, const QVariant&))); + m_registeredForType[name]->propertyEditor->reparent(m_currentEditArea, 0, m_currentEditArea->childrenRect().topLeft()); + m_registeredForType[name]->propertyEditor->hide(); + } + return m_registeredForType[name]; +} + +void PropertyEditor::clearMachineCache() +{ + for (QMap<QString, Machine* >::iterator it = m_registeredForType.begin(); it != m_registeredForType.end(); ++it) + { + delete it.data(); + } + m_registeredForType.clear(); +} + +void PropertyEditor::undo() +{ + if ((m_currentEditItem == 0) || (m_currentEditWidget == 0) + || (!m_currentEditWidget->isVisible())) + return; + + m_currentEditWidget->undo(); + m_currentEditItem->setChanged(false); + repaintItem(m_currentEditItem); +} + +} + +#ifndef PURE_QT +#include "propertyeditor.moc" +#endif diff --git a/lib/widgets/propeditor/propertyeditor.h b/lib/widgets/propeditor/propertyeditor.h new file mode 100644 index 00000000..f641118c --- /dev/null +++ b/lib/widgets/propeditor/propertyeditor.h @@ -0,0 +1,129 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PROPERTYEDITOR_H +#define PROPERTYEDITOR_H + +#ifndef PURE_QT +#include <klistview.h> +#else +#include <qlistview.h> +#define KListView QListView +#define KListViewItem QListViewItem +#endif + +#include "propertylist.h" + +class QPushButton; +class QGridLayout; + +namespace PropertyLib{ + +class PropertyItem; +class PropertyGroupItem; +class PropertyWidget; +class Property; +class MultiProperty; +struct Machine; + +/** @file propertyeditor.h +@short Contains @ref PropertyLib::PropertyEditor class. +*/ + +/** +@short %Property editor. + +Displays a list of properties in a table form. Also performs grouping and +creation of property widgets from the machine factory. +@see PropertyWidget +@see Machine +@see PropertyMachineFactory +*/ +class PropertyEditor: public KListView{ + Q_OBJECT +public: + /**Constructs the property editor.*/ + PropertyEditor(QWidget *parent = 0, const char *name = 0); + ~PropertyEditor(); + + /**@return @ref Machine for given property. + Uses cache to store created machines. + Cache will be cleared only with @ref clearMachineCache.*/ + Machine *machine(MultiProperty *property); + +public slots: + /**Shows properties from a list.*/ + void populateProperties(PropertyList *list); + /**Clears property list, disconnects accessor from the editor and deletes it.*/ + void clearProperties(); + /**Deletes cached machines.*/ + void clearMachineCache(); + +signals: + /**Emitted when something is changed in property editor.*/ + void changed(); + +protected slots: + /**Updates property widget in the editor.*/ + void propertyValueChanged(Property* property); + /**Updates property in the list when new value is selected in the editor.*/ + void propertyChanged(MultiProperty *property, const QVariant &value); + + /**Shows property editor.*/ + void slotClicked(QListViewItem* item); + void updateEditorSize(); + + /**Undoes the last change in property editor.*/ + void undo(); + +protected: + void editItem(QListViewItem*, int); + void hideEditor(); + void showEditor(PropertyItem *item); + void placeEditor(PropertyItem *item); + PropertyWidget *prepareEditor(PropertyItem *item); + + void addGroup(const QString &name); + void addProperty(PropertyGroupItem *group, const QString &name); + void addProperty(const QString &name); + void addChildProperties(PropertyItem *parent); + +private: + PropertyList *m_list; + PropertyList m_detailedList; + + //machines cache for property types, machines will be deleted + QMap<QString, Machine* > m_registeredForType; + + PropertyItem *m_currentEditItem; + PropertyWidget *m_currentEditWidget; + QWidget *m_currentEditArea; + QGridLayout *m_currentEditLayout; + + bool m_doubleClickForEdit; + QListViewItem* m_lastClickedItem; + + QPushButton *m_undoButton; + +friend class PropertyItem; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/propertyeditor.pro b/lib/widgets/propeditor/propertyeditor.pro new file mode 100644 index 00000000..125ce510 --- /dev/null +++ b/lib/widgets/propeditor/propertyeditor.pro @@ -0,0 +1,40 @@ +TEMPLATE = lib +CONFIG += debug +DEFINES += PURE_QT + +SOURCES += childproperty.cpp pcombobox.cpp \ + pdummywidget.cpp ppointedit.cpp \ + propertymachinefactory.cpp pstringlistedit.cpp \ + multiproperty.cpp pcursoredit.cpp \ + prectedit.cpp propertywidget.cpp \ + psymbolcombo.cpp pcheckbox.cpp \ + pdateedit.cpp pfontcombo.cpp \ + property.cpp psizeedit.cpp \ + pdatetimeedit.cpp \ + plineedit.cpp propertyeditor.cpp \ + psizepolicyedit.cpp pyesnobutton.cpp \ + ppixmapedit.cpp \ + propertylist.cpp pspinbox.cpp \ + propertywidgetproxy.cpp plinestyleedit.cpp \ + qeditlistbox.cpp pdoublenuminput.cpp \ + qfloatinput.cpp pcolorbutton.cpp \ + purledit.cpp + +HEADERS += childproperty.h pcombobox.h \ + pdummywidget.h ppointedit.h \ + propertymachinefactory.h pcursoredit.h \ + prectedit.h propertywidget.h \ + pdateedit.h pfontcombo.h \ + property.h psizeedit.h \ + pdatetimeedit.h plineedit.h \ + propertyeditor.h psizepolicyedit.h \ + ppixmapedit.h propertylist.h \ + pspinbox.h propertywidgetproxy.h \ + multiproperty.h pyesnobutton.h \ + psymbolcombo.h pstringlistedit.h \ + pcheckbox.h plinestyleedit.h \ + qeditlistbox.h pdoublenuminput.h \ + qfloatinput.h pcolorbutton.h \ + purledit.h + +IMAGES += undo.xpm diff --git a/lib/widgets/propeditor/propertylist.cpp b/lib/widgets/propeditor/propertylist.cpp new file mode 100644 index 00000000..3ea79a87 --- /dev/null +++ b/lib/widgets/propeditor/propertylist.cpp @@ -0,0 +1,369 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "propertylist.h" + +#include "property.h" +#include "multiproperty.h" + +namespace PropertyLib{ + +PropertyList::PropertyList() + :QObject(0, 0), m_propertyOwner(true) +{ +} + +PropertyList::PropertyList(bool propertyOwner) + :QObject(0, 0), m_propertyOwner(propertyOwner) +{ +} + +PropertyList::~PropertyList() +{ + clear(); +} + +MultiProperty *PropertyList::operator[](const QString &name) +{ + if (m_list.contains(name)) + return m_list[name]; + else + return new MultiProperty(this); +} + +MultiProperty *PropertyList::property( const QString &name ) +{ + if (m_list.contains(name)) + return m_list[name]; + else + return new MultiProperty(this); +} + +void PropertyList::addProperty(Property *property) +{ + if (property == 0) + return; + MultiProperty *mp = 0; + if ( m_list.contains(property->name()) ) + { + mp = m_list[property->name()]; + mp->addProperty(property); + } + else + { + mp = new MultiProperty(this, property); + m_list[property->name()] = mp; + addToGroup("", mp); + } +} + +void PropertyList::addProperty(const QString &group, Property *property) +{ + if (property == 0) + return; + + MultiProperty *mp = 0; + if (m_list.contains(property->name())) + { + mp = m_list[property->name()]; + mp->addProperty(property); + } + else + { + mp = new MultiProperty(this, property); + m_list[property->name()] = mp; + addToGroup(group, mp); + } +} + +void PropertyList::removeProperty(Property *property) +{ + if (property == 0) + return; + + if (m_propertyOwner) + emit aboutToDeleteProperty(property); + + MultiProperty *mp = m_list[property->name()]; + QString group = m_groupOfProperty[mp]; + removeFromGroup(mp); + QString pname = property->name(); + mp->removeProperty(property); + if (m_propertyOwner) + delete property; + if (mp->list.count() == 0) + { +// qWarning("rp: removing mp for %s itself", pname.ascii()); + m_list.remove(pname); + delete mp; + } + else + addToGroup(group, mp); +} + +void PropertyList::removeProperty(const QString &name) +{ + if (m_list.contains(name)) + { + QString group = m_groupOfProperty[m_list[name]]; + removeFromGroup(m_list[name]); + Property *property; + for (property = m_list[name]->list.first(); property; property = m_list[name]->list.next()) + { + if (m_propertyOwner) + emit aboutToDeleteProperty(property); + + m_list[property->name()]->removeProperty(property); + if (m_propertyOwner) + delete property; + } + if (m_list[name]->list.count() == 0) + { +// qWarning("rp2: removing mp for %s itself", name.ascii()); + delete m_list[name]; + m_list.remove(name); + } + else + { + addToGroup(group, m_list[name]); + } + } +} + +const QValueList<QPair<QString, QValueList<QString> > >& PropertyList::propertiesOfGroup() const +{ + return m_propertiesOfGroup; +} + +const QMap<MultiProperty*, QString>& PropertyList::groupOfProperty() const +{ + return m_groupOfProperty; +} + +void PropertyList::addToGroup(const QString &group, MultiProperty *property) +{ + if (!property) + return; + + //do not add same property to the group twice + if (m_groupOfProperty.contains(property) && (m_groupOfProperty[property] == group)) + return; + + QPair<QString, QValueList<QString> > *groupPair = 0; + for(QValueList<QPair<QString, QValueList<QString> > >::iterator it = m_propertiesOfGroup.begin(); + it != m_propertiesOfGroup.end(); ++it) + { + if ((*it).first == group) + { + groupPair = &(*it); + break; + } + } + if (groupPair == 0) + { + groupPair = new QPair<QString, QValueList<QString> >(); + groupPair->first = group; + groupPair->second.append(property->name()); + m_propertiesOfGroup.append(*groupPair); + m_groupOfProperty[property] = group; + return; + } + //check if group already contains property with the same name + if (!groupPair->second.contains(property->name())) + groupPair->second.append(property->name()); + + m_groupOfProperty[property] = group; +} + +void PropertyList::removeFromGroup(MultiProperty *property) +{ + QString group = m_groupOfProperty[property]; +// qWarning("removeFromGroup group=%s", group.ascii()); + + for(QValueList<QPair<QString, QValueList<QString> > >::iterator it = m_propertiesOfGroup.begin(); + it != m_propertiesOfGroup.end(); ++it) + { +// qWarning("removeFromGroup checking %s", (*it).first.ascii()); + if ((*it).first == group) + { +// qWarning("removeFromGroup removing %s", property->name().ascii()); + (*it).second.remove(property->name()); + break; + } + } + + m_groupOfProperty.remove(property); +} + +void PropertyList::clear( ) +{ + for (QMap<QString, MultiProperty*>::iterator it = m_list.begin(); it != m_list.end(); ++it) + removeProperty(it.key()); +} + +bool PropertyList::contains( const QString & name ) +{ + if (m_list.contains(name)) + return true; + return false; +} + +QPtrList<Property> PropertyList::properties(const QString &name) +{ + if (m_list.contains(name)) + return m_list[name]->list; + return QPtrList<Property>(); +} + +PropertyList::Iterator PropertyList::begin() +{ + return Iterator(this); +} + +PropertyList::Iterator PropertyList::end() +{ + return Iterator(this, true); +} + +//PropertyList::Iterator class + +PropertyList::Iterator::Iterator(PropertyList *list) + :m_list(list) +{ + current = m_list->m_list.begin(); +} + +PropertyList::Iterator::Iterator(PropertyList *list, bool // end + ) + :m_list(list) +{ + current = m_list->m_list.end(); +} + +void PropertyList::Iterator::operator ++() +{ + next(); +} + +void PropertyList::Iterator::operator ++(int) +{ + next(); +} + +void PropertyList::Iterator::next() +{ + ++current; +} + +MultiProperty *PropertyList::Iterator::operator *() +{ + return data(); +} + +QString PropertyList::Iterator::key() +{ + return current.key(); +} + +MultiProperty *PropertyList::Iterator::data() +{ + return current.data(); +} + +bool PropertyList::Iterator::operator !=(Iterator it) +{ + return current != it.current; +} + + +// PropertyBuffer class + + + + + +PropertyBuffer::PropertyBuffer( ) + :PropertyList(false) +{ +} + +void PropertyBuffer::intersect(const PropertyList *list) +{ + qWarning("PropertyBuffer::intersect"); + for (QMap<QString, MultiProperty*>::iterator it = m_list.begin(); it != m_list.end(); ++it) + { +// qWarning("intersect:: for mp = %s", it.data()->name().ascii()); + if (list->m_list.contains(it.key())) + { +/* qWarning("intersect:: list contains %s", it.key().ascii()); + if ( (*(it.data()) == *(list->m_list[it.key()]))) + qWarning("intersect:: equal properties"); + else + qWarning("intersect:: not equal properties");*/ + if ( ((*it.data()) == *(list->m_list[it.key()])) + && (list->m_groupOfProperty[list->m_list[it.key()]] == m_groupOfProperty[it.data()]) ) + { +// qWarning("intersect:: equal properties, adding"); + it.data()->addProperty(list->m_list[it.key()]); + continue; + } + } +// qWarning("intersect:: removing %s from intersection", it.key().ascii()); + removeProperty(it.key()); + } + connect(list, SIGNAL(propertyValueChanged(Property*)), this, SLOT(intersectedValueChanged(Property*))); +} + +void PropertyBuffer::intersectedValueChanged(Property *property) +{ +// qWarning("PropertyBuffer::intersectedValueChanged"); + QString propertyName = property->name(); + if (!contains(propertyName)) + return; + + MultiProperty mp(property); + if (mp == *m_list[propertyName]) + { + Property *prop; + QPtrList<Property> props = properties(propertyName); + for (prop = props.first(); prop; prop = props.next()) + emit propertyValueChanged(prop); + } +} + +PropertyBuffer::PropertyBuffer(PropertyList *list) + :PropertyList(false) +{ + //deep copy of m_list + for (QMap<QString, MultiProperty*>::const_iterator it = list->m_list.begin(); + it != list->m_list.end(); ++it) + { + MultiProperty *mp = new MultiProperty(*it.data()); + mp->m_propertyList = this; + addToGroup(list->m_groupOfProperty[it.data()], mp); + m_list[it.key()] = mp; + } + connect(list, SIGNAL(propertyValueChanged(Property*)), this, SLOT(intersectedValueChanged(Property*))); +} + +} + +#ifndef PURE_QT +#include "propertylist.moc" +#endif diff --git a/lib/widgets/propeditor/propertylist.h b/lib/widgets/propeditor/propertylist.h new file mode 100644 index 00000000..c07cebbd --- /dev/null +++ b/lib/widgets/propeditor/propertylist.h @@ -0,0 +1,200 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PROPERTYLIST_H +#define PROPERTYLIST_H + +#include <qobject.h> +#include <qmap.h> +#include <qptrlist.h> +#include <qvaluelist.h> +#include <qpair.h> + +namespace PropertyLib{ + +class Property; +class MultiProperty; + +/** @file propertylist.h +@short Contains @ref PropertyLib::PropertyList class. +*/ + +/** +@short The list of properties. + +Every object in a program should operate with properties through +this list in order to: +- be informed about property changes +- allow property lists intersections +- display properties in the property editor widget (see @ref PropertyLib::PropertyEditor). +. + +PropertyList owns properties and deletes them itself. For a list that does not own +it's properties, look at @ref PropertyLib::PropertyBuffer class. + +PropertyList is also capable of grouping properties. +You can have unsorted list of groups of properties or a plain +alphabetically sorted list of properties or both at the same time. +*/ +class PropertyList: public QObject +{ + Q_OBJECT + +public: + class Iterator { + public: + void operator ++(); + void operator ++(int); + + MultiProperty *operator *(); + + bool operator != (Iterator it); + + QString key(); + MultiProperty *data(); + + private: + Iterator(PropertyList *list); + Iterator(PropertyList *list, bool end); + + void next(); + QMap<QString, MultiProperty*>::iterator current; + + PropertyList *m_list; + friend class PropertyList; + }; + + typedef Iterator iterator; + + PropertyList(); + virtual ~PropertyList(); + + /**Accesses a property by it's name. All property modifications are allowed + trough this method. For example, to set a value of a property, use: + /code + PropertyList list; + ... + list["My Property"]->setValue("My Value"); + /endcode + @return @ref MultiProperty with given name.*/ + virtual MultiProperty *operator[](const QString &name); + /**Accesses a property by it's name. All property modifications are allowed + trough this method. For example, to set a value of a property + */ + MultiProperty *property( const QString &name ); + + /**Adds the property to the list to the "common" group.*/ + virtual void addProperty(Property *property); + /**Adds the property to the list in group.*/ + virtual void addProperty(const QString &group, Property *property); + /**Removes property from the list. Emits aboutToDeleteProperty before removing.*/ + virtual void removeProperty(Property *property); + /**Removes property with the given name from the list. + Emits @ref aboutToDeleteProperty before removing.*/ + virtual void removeProperty(const QString &name); + + /**@return the list of grouped properties.*/ + virtual const QValueList<QPair<QString, QValueList<QString> > >& propertiesOfGroup() const; + /**@return the map: property - group name.*/ + virtual const QMap<MultiProperty*, QString>& groupOfProperty() const; + + /**Clears the list of properties.*/ + virtual void clear(); + /**Returns true if the list of properties contains property with given name.*/ + virtual bool contains(const QString &name); + + /**The list of properties with given name.*/ + QPtrList<Property> properties(const QString &name); + + Iterator begin(); + Iterator end(); + +signals: + /**Emitted when the value of the property is changed.*/ + void propertyValueChanged(Property* property); + /**Emitted when property is about to be deleted.*/ + void aboutToDeleteProperty(Property* property); + +protected: + /**Constructs a list which owns or does not own it's properties.*/ + PropertyList(bool propertyOwner); + + /**Adds property to a group.*/ + void addToGroup(const QString &group, MultiProperty *property); + /**Removes property from a group.*/ + void removeFromGroup(MultiProperty *property); + +private: + //sorted list of properties in form name: property + QMap<QString, MultiProperty*> m_list; + + //groups of properties: + // list of group name: (list of property names) + QValueList<QPair<QString, QValueList<QString> > > m_propertiesOfGroup; + // map of property: group + QMap<MultiProperty*, QString> m_groupOfProperty; + + //indicates that this list will delete properties after removeProperty() + //and also in destructor + bool m_propertyOwner; + +friend class MultiProperty; +friend class PropertyBuffer; +friend class Iterator; +}; + + +/** +@short The list of properties which does not own them. + +This class acts as @ref PropertyLib::PropertyList but it does not delete properties +in destructor (i.e. it does not own properties). +This class should be used to store results of property intersections. + +Example: +/code +PropertyList *list = new PropertyList(); +PropertyList *list2 = new PropertyList(); +PropertyList *list3 = new PropertyList(); +... +PropertyBuffer *buf = new PropertyBuffer(list); +buf->intersect(list2); +buf->intersect(list3); +... +/endcode +*/ +class PropertyBuffer: public PropertyList{ + Q_OBJECT +public: + /**Constructs a buffer from given property list.*/ + PropertyBuffer(PropertyList *list); + /**Constructs an empty property buffer.*/ + PropertyBuffer(); + + /**Intersects with other @ref PropertyLib::PropertyList.*/ + virtual void intersect(const PropertyList *list); + +protected slots: + void intersectedValueChanged(Property *property); + +}; + +} + +#endif diff --git a/lib/widgets/propeditor/propertymachinefactory.cpp b/lib/widgets/propeditor/propertymachinefactory.cpp new file mode 100644 index 00000000..222aa930 --- /dev/null +++ b/lib/widgets/propeditor/propertymachinefactory.cpp @@ -0,0 +1,207 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "propertymachinefactory.h" + +#ifndef PURE_QT +#include <klocale.h> +#else +#define i18n QObject::tr +#endif + +#include <qmap.h> + +#include "property.h" +#include "childproperty.h" +#include "multiproperty.h" +#include "plineedit.h" +#include "pspinbox.h" +#include "pdoublenuminput.h" +#include "pcheckbox.h" +#include "pstringlistedit.h" +#include "pdummywidget.h" +#include "pcombobox.h" +#include "psymbolcombo.h" +#include "pfontcombo.h" +#include "psizeedit.h" +#include "pdateedit.h" +#include "pdatetimeedit.h" +#include "ppointedit.h" +#include "prectedit.h" +#include "psizepolicyedit.h" +#include "pcolorbutton.h" +#include "pyesnobutton.h" +#include "ppixmapedit.h" +#include "pcursoredit.h" +#include "plinestyleedit.h" +#include "purledit.h" + + +#ifndef PURE_QT +#include "pfontbutton.h" +#include "pcolorcombo.h" +#endif + +namespace PropertyLib{ + +PropertyMachineFactory *PropertyMachineFactory::m_factory = 0; + +PropertyMachineFactory::PropertyMachineFactory() +{ +} + +PropertyMachineFactory::~PropertyMachineFactory() +{ +} + +Machine *PropertyMachineFactory::machineForProperty(MultiProperty *property) +{ + int type = property->type(); + QString propertyName = property->name(); + QMap<QString, QVariant> valueList = property->valueList(); + + if (m_registeredForType.contains(propertyName)) + return (*m_registeredForType[propertyName])(); + + switch (type) + { + case Property::String: + return new Machine(new PLineEdit(property)); + case Property::Integer: + return new Machine(new PSpinBox(property)); + case Property::Boolean: + return new Machine(new PYesNoButton(property)); + case Property::Date: + return new Machine(new PDateEdit(property)); + case Property::DateTime: + return new Machine(new PDateTimeEdit(property)); + case Property::StringList: + return new Machine(new PStringListEdit(property)); + case Property::Color: + return new Machine(new PColorButton(property)); +#ifndef PURE_QT + case Property::Font: + return new Machine(new PFontButton(property)); +#endif + case Property::FileURL: + return new Machine(new PUrlEdit(PUrlEdit::File, property)); + case Property::DirectoryURL: + return new Machine(new PUrlEdit(PUrlEdit::Directory, property)); + + case Property::Double: + return new Machine(new PDoubleNumInput(property)); + case Property::Pixmap: + return new Machine(new PPixmapEdit(property)); + + case Property::ValueFromList: + return new Machine(new PComboBox(property, valueList)); + case Property::Symbol: + return new Machine(new PSymbolCombo(property)); + case Property::FontName: + return new Machine(new PFontCombo(property)); + case Property::LineStyle: + return new Machine(new PLineStyleEdit(property)); + + case Property::Size: + { + Machine *mach = new Machine(new PSizeEdit(property)); + property->details.append(ChildProperty(property, Property::Integer, ChildProperty::Size_Width, i18n("Width"), i18n("Width"))); + property->details.append(ChildProperty(property, Property::Integer, ChildProperty::Size_Height, i18n("Height"), i18n("Height"))); + return mach; + } + case Property::Point: + { + Machine *mach = new Machine(new PPointEdit(property)); + property->details.append(ChildProperty(property, Property::Integer, ChildProperty::Point_X, i18n("x"), i18n("x"))); + property->details.append(ChildProperty(property, Property::Integer, ChildProperty::Point_Y, i18n("y"), i18n("y"))); + return mach; + } + case Property::Rect: + { + Machine *mach = new Machine(new PRectEdit(property)); + property->details.append(ChildProperty(property, Property::Integer, ChildProperty::Rect_X, i18n("x"), i18n("x"))); + property->details.append(ChildProperty(property, Property::Integer, ChildProperty::Rect_Y, i18n("y"), i18n("y"))); + property->details.append(ChildProperty(property, Property::Integer, ChildProperty::Rect_Width, i18n("Width"), i18n("Width"))); + property->details.append(ChildProperty(property, Property::Integer, ChildProperty::Rect_Height, i18n("Height"), i18n("Height"))); + return mach; + } + case Property::SizePolicy: + { + QMap<QString, QVariant> spValues; + spValues[i18n("Fixed")] = QSizePolicy::Fixed; + spValues[i18n("Minimum")] = QSizePolicy::Minimum; + spValues[i18n("Maximum")] = QSizePolicy::Maximum; + spValues[i18n("Preferred")] = QSizePolicy::Preferred; + spValues[i18n("Expanding")] = QSizePolicy::Expanding; + spValues[i18n("Minimum Expanding")] = QSizePolicy::MinimumExpanding; + spValues[i18n("Ignored")] = QSizePolicy::Ignored; + + Machine *mach = new Machine(new PSizePolicyEdit(property, spValues)); + property->details.append(ChildProperty(property, i18n("hSizeType"), ChildProperty::SizePolicy_HorData, spValues, i18n("Horizontal Size Type"))); + property->details.append(ChildProperty(property, i18n("vSizeType"), ChildProperty::SizePolicy_VerData, spValues, i18n("Vertical Size Type"))); + property->details.append(ChildProperty(property, Property::Integer, ChildProperty::SizePolicy_HorStretch, i18n("hStretch"), i18n("Horizontal Stretch"))); + property->details.append(ChildProperty(property, Property::Integer, ChildProperty::SizePolicy_VerStretch, i18n("vStretch"), i18n("Vertical Stretch"))); + return mach; + } + case Property::Cursor: + { + QMap<QString, QVariant> spValues; + spValues[i18n("Arrow")] = Qt::ArrowCursor; + spValues[i18n("Up Arrow")] = Qt::UpArrowCursor; + spValues[i18n("Cross")] = Qt::CrossCursor; + spValues[i18n("Waiting")] = Qt::WaitCursor; + spValues[i18n("iBeam")] = Qt::IbeamCursor; + spValues[i18n("Size Vertical")] = Qt::SizeVerCursor; + spValues[i18n("Size Horizontal")] = Qt::SizeHorCursor; + spValues[i18n("Size Slash")] = Qt::SizeBDiagCursor; + spValues[i18n("Size Backslash")] = Qt::SizeFDiagCursor; + spValues[i18n("Size All")] = Qt::SizeAllCursor; + spValues[i18n("Blank")] = Qt::BlankCursor; + spValues[i18n("Split Vertical")] = Qt::SplitVCursor; + spValues[i18n("Split Horizontal")] = Qt::SplitHCursor; + spValues[i18n("Pointing Hand")] = Qt::PointingHandCursor; + spValues[i18n("Forbidden")] = Qt::ForbiddenCursor; + spValues[i18n("What's this")] = Qt::WhatsThisCursor; + Machine *mach = new Machine(new PCursorEdit(property, spValues)); + return mach; + } + + case Property::List: + case Property::Map: + default: + return new Machine(new PDummyWidget(property)); + } +} + +PropertyMachineFactory *PropertyMachineFactory::getInstance() +{ + if (m_factory == 0) + m_factory = new PropertyMachineFactory(); + return m_factory; +} + +bool PropertyMachineFactory::hasDetailedEditors( int type ) +{ + if ( (type==Property::Size) || (type==Property::Point) || + (type==Property::Rect) || (type==Property::SizePolicy) ) + return true; + return 0; +} + +} diff --git a/lib/widgets/propeditor/propertymachinefactory.h b/lib/widgets/propeditor/propertymachinefactory.h new file mode 100644 index 00000000..fe776b63 --- /dev/null +++ b/lib/widgets/propeditor/propertymachinefactory.h @@ -0,0 +1,97 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PROPERTYMACHINEFACTORY_H +#define PROPERTYMACHINEFACTORY_H + +#include <qmap.h> + +#include "propertywidget.h" + +class QWidget; + +namespace PropertyLib{ + +class Property; +class MultiProperty; +class ChildProperty; + +/** @file propertymachinefactory.h +@short Contains @ref PropertyLib::PropertyMachineFactory class and @ref PropertyLib::Machine structure. +*/ + +/** +@short Machine for a property type. + +Contains a pointer to a property viewer, +property editor and a list of detailed property +editors and viewers. +*/ +struct Machine{ + Machine() + { + } + Machine(PropertyWidget *widget) + { + propertyEditor = widget; + } + ~Machine() + { + delete propertyEditor; + } + + /**Property viewer and editor widget.*/ + PropertyWidget *propertyEditor; +}; + +/**A pointer to factory function which creates and returns machine for a property.*/ +typedef Machine *(*createMachine)(); + +/** +@short Factory to create property editors and property viewers. +*/ +class PropertyMachineFactory{ +public: + /**Registers property editor factory function for a type. + This factory functions are considered before defaults + when @ref machineForProperty is called.*/ + void registerEditor(int type, createMachine creator); + + /**Creates and returns the editor for given property type. + Warning: editor and viewer widgets won't have parent widget. %Property editor + cares about reparenting and deletion of returned widgets in machines.*/ + Machine *machineForProperty(MultiProperty *property); + bool hasDetailedEditors(int type); + + /**@return a pointer to a property machine factory instance.*/ + static PropertyMachineFactory *getInstance(); + + static PropertyMachineFactory *m_factory; + +private: + PropertyMachineFactory(); + virtual ~PropertyMachineFactory(); + + //registered machines for property types + QMap<QString, createMachine > m_registeredForType; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/propertywidget.cpp b/lib/widgets/propeditor/propertywidget.cpp new file mode 100644 index 00000000..7895acb1 --- /dev/null +++ b/lib/widgets/propeditor/propertywidget.cpp @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "propertywidget.h" + +#include <qpainter.h> + +namespace PropertyLib{ + +PropertyWidget::PropertyWidget(MultiProperty *property, QWidget *parent, const char *name) + :QWidget(parent, name), m_property(property) +{ +} + +QString PropertyWidget::propertyName() const +{ + return m_property->name(); +} + +void PropertyWidget::setProperty(MultiProperty *property) +{ + m_property = property; +} + +void PropertyWidget::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + p->setPen(Qt::NoPen); + p->setBrush(cg.background()); + p->drawRect(r); + p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, value.toString()); +} + +void PropertyWidget::setValueList(const QMap<QString, QVariant> &// valueList + ) +{ + //this does nothing +} + +void PropertyWidget::undo() +{ + m_property->undo(); +} + +} + +#ifndef PURE_QT +#include "propertywidget.moc" +#endif diff --git a/lib/widgets/propeditor/propertywidget.h b/lib/widgets/propeditor/propertywidget.h new file mode 100644 index 00000000..3383a206 --- /dev/null +++ b/lib/widgets/propeditor/propertywidget.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PROPERTYWIDGET_H +#define PROPERTYWIDGET_H + +#include <qwidget.h> +#include <qvariant.h> + +/** @file propertywidget.h +@short Contains @ref PropertyLib::PropertyWidget class. +*/ + +#include "multiproperty.h" + +namespace PropertyLib{ + +/** +@short An abstract base class of property viewer and editor vidget. + +Subclass this class to create custom property viewer and editor widget. + +Descendants should implement value() and setValue() methods. + +Hint: in case you want to implement your property editor widget using +existing widgets like QLineEdit, QComboBox, etc. you can't use multiple +inheritance from two QObject descendants due to Qt library restriction. +Therefore use line edits and combo boxes as child widgets. + +A set of predefined widgets for predefined property types are available +in the library. +*/ +class PropertyWidget: public QWidget{ + Q_OBJECT +public: + /**Constructs widget for property with name "propertyName".*/ + PropertyWidget(MultiProperty *property, QWidget *parent = 0, const char *name = 0); + virtual ~PropertyWidget() {} + + /**@return the value currently entered in the editor widget.*/ + virtual QVariant value() const = 0; + /**Sets the value shown in the editor widget. Set emitChange to false + if you don't want to emit propertyChanged signal.*/ + virtual void setValue(const QVariant &value, bool emitChange=true) = 0; + /**@return the name of edited property.*/ + virtual QString propertyName() const; + /**Sets the name of edited property.*/ + virtual void setProperty(MultiProperty *property); + /**Sets the list of possible values shown in the editor widget. This method + does not emit propertyChanged signal.*/ + virtual void setValueList(const QMap<QString, QVariant> &valueList); + + /**Function to draw a property viewer when the editor isn't shown.*/ + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + /**Reverts the property value to previous setting.*/ + virtual void undo(); + +signals: + /**Emit this signal when property value is changed. Probably you want + to emit it only from @ref setValue() method. + @ref PropertyLib::PropertyEditor widget will connect this to the appropriate slot which + will make updates to the @ref PropertyLib::PropertyList that hold propeties.*/ + void propertyChanged(MultiProperty *property, const QVariant &value); + +protected: + MultiProperty *m_property; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/propertywidgetproxy.cpp b/lib/widgets/propeditor/propertywidgetproxy.cpp new file mode 100644 index 00000000..35fdc73b --- /dev/null +++ b/lib/widgets/propeditor/propertywidgetproxy.cpp @@ -0,0 +1,106 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "propertywidgetproxy.h" + +#include <qlayout.h> + +#include "propertywidget.h" +#include "propertymachinefactory.h" + +namespace PropertyLib{ + +PropertyWidgetProxy::PropertyWidgetProxy(QWidget *parent, const char *name) + :QWidget(parent, name), mp(0), m_propertyType(Property::Invalid), m_editor(0) +{ + p = new Property(); + m_layout = new QHBoxLayout(this, 0, 0); +} + +PropertyWidgetProxy::~PropertyWidgetProxy() +{ + delete mp; + delete p; +} + +void PropertyWidgetProxy::setPropertyType(int propertyType) +{ + m_propertyType = static_cast<PropertyType>(propertyType); + setWidget(); +} + +void PropertyWidgetProxy::setPropertyType2(PropertyType propertyType) +{ + m_propertyType = propertyType; + setWidget(); +} + +void PropertyWidgetProxy::setWidget() +{ + if (m_editor) + delete m_editor; + p->setType(m_propertyType); + mp = new MultiProperty(p); + m_editor = PropertyMachineFactory::getInstance()->machineForProperty(mp)->propertyEditor; + if (m_editor) + { + m_editor->reparent(this, QPoint(0,0), true); + m_layout->addWidget(m_editor); + } +} + +QVariant PropertyWidgetProxy::value() const +{ + if (m_editor) + return m_editor->value(); + else + return QVariant(); +} + +void PropertyWidgetProxy::setValue(const QVariant &value) +{ + if (m_editor) + m_editor->setValue(value, false); +} + +bool PropertyWidgetProxy::setProperty( const char * name, const QVariant & value ) +{ + if( strcmp( name, "value") == 0 ) + { + setPropertyType((int) value.type() ); + setValue( value ); + return true; + } + else + return QWidget::setProperty(name, value); +} + +QVariant PropertyWidgetProxy::property( const char * name ) const +{ + if( strcmp( name, "value") == 0 ) + return value( ); + else + return QWidget::property(name); +} + +} + +#ifndef PURE_QT +#include "propertywidgetproxy.moc" +#endif diff --git a/lib/widgets/propeditor/propertywidgetproxy.h b/lib/widgets/propeditor/propertywidgetproxy.h new file mode 100644 index 00000000..6a88b8b1 --- /dev/null +++ b/lib/widgets/propeditor/propertywidgetproxy.h @@ -0,0 +1,81 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PROPERTYWIDGETPROXY_H +#define PROPERTYWIDGETPROXY_H + +#include <qwidget.h> +#include <qvariant.h> + +#include "multiproperty.h" + +class QHBoxLayout; + +namespace PropertyLib{ + +class PropertyWidget; + +#define PropertyType Property::PropertyType + +/** +Property Widget Proxy. +It is sometimes useful to create single property editor widgets instead of having them +all in the property editor. Proxy creates an empty widget and shows the property editor +depending on the property type. +*/ +class PropertyWidgetProxy: public QWidget +{ +Q_OBJECT +Q_PROPERTY( int propertyType READ propertyType WRITE setPropertyType DESIGNABLE true ) +Q_PROPERTY( PropertyType propertyType2 READ propertyType2 WRITE setPropertyType2 DESIGNABLE false ) +public: + PropertyWidgetProxy(QWidget *parent = 0, const char *name = 0); + ~PropertyWidgetProxy(); + + /**Sets the type of a property editor to appear.*/ + void setPropertyType(int propertyType); + int propertyType() const { return m_propertyType; } + /**Sets the type of a property editor to appear.*/ + void setPropertyType2(PropertyType propertyType); + PropertyType propertyType2() const { return m_propertyType; } + + QVariant value() const; + void setValue(const QVariant &value); + + /**Sets the type of an editor basing on the @p value if the name is "value". + Otherwise works as QWidget::setProperty.*/ + bool setProperty( const char *name, const QVariant &value); + QVariant property( const char *name) const; + +protected: + virtual void setWidget(); + +private: + Property *p; + MultiProperty *mp; + + PropertyType m_propertyType; + PropertyWidget *m_editor; + + QHBoxLayout *m_layout; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/psizeedit.cpp b/lib/widgets/propeditor/psizeedit.cpp new file mode 100644 index 00000000..7e322ba5 --- /dev/null +++ b/lib/widgets/propeditor/psizeedit.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "psizeedit.h" + +#include <klineedit.h> +#include <qlayout.h> +#include <qpainter.h> + +namespace PropertyLib{ + +PSizeEdit::PSizeEdit(MultiProperty *property, QWidget *parent, const char *name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new KLineEdit(this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + m_edit->setReadOnly(true); +} + +QVariant PSizeEdit::value() const +{ + return m_value; +} + +void PSizeEdit::drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value) +{ + p->setPen(Qt::NoPen); + p->setBrush(cg.background()); + p->drawRect(r); + p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, QString("[ %1, %2 ]").arg(value.toSize().width()).arg(value.toSize().height())); +} + +void PSizeEdit::setValue(const QVariant& value, bool emitChange) +{ + m_value = value; + m_edit->setText(QString("[ %1, %2 ]").arg(value.toSize().width()).arg(value.toSize().height())); + + if (emitChange) + emit propertyChanged(m_property, value); +} + +} + +#ifndef PURE_QT +#include "psizeedit.moc" +#endif diff --git a/lib/widgets/propeditor/psizeedit.h b/lib/widgets/propeditor/psizeedit.h new file mode 100644 index 00000000..53ea5201 --- /dev/null +++ b/lib/widgets/propeditor/psizeedit.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PSIZEEDIT_H +#define PSIZEEDIT_H + +#include "propertywidget.h" +#include "multiproperty.h" + +class KLineEdit; +class QPainter; + +namespace PropertyLib{ + +/** +@short %Property editor for QSize values. +*/ +class PSizeEdit: public PropertyWidget +{ + Q_OBJECT +public: + PSizeEdit(MultiProperty *property, QWidget *parent = 0, const char *name = 0); + + virtual QVariant value() const; + virtual void drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value); + virtual void setValue(const QVariant& value, bool emitChange); + +private: + KLineEdit *m_edit; + QVariant m_value; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/psizepolicyedit.cpp b/lib/widgets/propeditor/psizepolicyedit.cpp new file mode 100644 index 00000000..d903c95a --- /dev/null +++ b/lib/widgets/propeditor/psizepolicyedit.cpp @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "psizepolicyedit.h" + +#include <klineedit.h> +#include <qlayout.h> +#include <qpainter.h> +#include <qsizepolicy.h> + +namespace PropertyLib{ + +PSizePolicyEdit::PSizePolicyEdit(MultiProperty* property, const QMap<QString, QVariant> &spValues, QWidget* parent, const char* name) + :PropertyWidget(property, parent, name), m_spValues(spValues) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new KLineEdit(this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + m_edit->setReadOnly(true); +} + +QVariant PSizePolicyEdit::value() const +{ + return m_value; +} + +void PSizePolicyEdit::drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value) +{ + p->setPen(Qt::NoPen); + p->setBrush(cg.background()); + p->drawRect(r); + p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, QString("%1/%2/%3/%4").arg(findValueDescription(value.toSizePolicy().horData())).arg(findValueDescription(value.toSizePolicy().verData())).arg(value.toSizePolicy().horStretch()).arg(value.toSizePolicy().verStretch())); +} + +void PSizePolicyEdit::setValue(const QVariant& value, bool emitChange) +{ + m_value = value; + m_edit->setText(QString("%1/%2/%3/%4").arg(findValueDescription(value.toSizePolicy().horData())).arg(findValueDescription(value.toSizePolicy().verData())).arg(value.toSizePolicy().horStretch()).arg(value.toSizePolicy().verStretch())); + + if (emitChange) + emit propertyChanged(m_property, value); +} + +QString PSizePolicyEdit::findValueDescription(QVariant val) const +{ +// qWarning("PSizePolicyEdit::findValueDescription : %d", val.toInt()); + for (QMap<QString, QVariant>::const_iterator it = m_spValues.begin(); it != m_spValues.end(); ++ it) + { + if (it.data() == val) + return it.key(); + } + return ""; +} + +} + +#ifndef PURE_QT +#include "psizepolicyedit.moc" +#endif diff --git a/lib/widgets/propeditor/psizepolicyedit.h b/lib/widgets/propeditor/psizepolicyedit.h new file mode 100644 index 00000000..42651eac --- /dev/null +++ b/lib/widgets/propeditor/psizepolicyedit.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PSIZEPOLICYEDIT_H +#define PSIZEPOLICYEDIT_H + +#include "propertywidget.h" + +#include <qmap.h> + +class KLineEdit; + +namespace PropertyLib{ + +/** +@short %Property editor for QSizePolicy values. +*/ +class PSizePolicyEdit : public PropertyWidget +{ +Q_OBJECT +public: + PSizePolicyEdit(MultiProperty* property, const QMap<QString, QVariant> &spValues, QWidget* parent=0, const char* name=0); + + virtual QVariant value() const; + virtual void drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value); + virtual void setValue(const QVariant& value, bool emitChange); + + QString findValueDescription(QVariant val) const; + +private: + KLineEdit *m_edit; + QVariant m_value; + QMap<QString, QVariant> m_spValues; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pspinbox.cpp b/lib/widgets/propeditor/pspinbox.cpp new file mode 100644 index 00000000..2e83f66c --- /dev/null +++ b/lib/widgets/propeditor/pspinbox.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pspinbox.h" + +#include <limits.h> + +#include <qspinbox.h> +#include <qlayout.h> + +namespace PropertyLib{ + +PSpinBox::PSpinBox(MultiProperty *property, QWidget *parent, const char *name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QSpinBox(INT_MIN, INT_MAX, 1, this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + connect(m_edit, SIGNAL(valueChanged(int)), this, SLOT(updateProperty(int))); +} + +PSpinBox::PSpinBox(MultiProperty *property, int minValue, int maxValue, int step, QWidget *parent, const char *name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QSpinBox(minValue, maxValue, step, this); + l->addWidget(m_edit); + + connect(m_edit, SIGNAL(valueChanged(int)), this, SLOT(updateProperty(int))); +} + +QVariant PSpinBox::value() const +{ + return QVariant(m_edit->cleanText().toInt()); +} + +void PSpinBox::setValue(const QVariant &value, bool emitChange) +{ + disconnect(m_edit, SIGNAL(valueChanged(int)), this, SLOT(updateProperty(int))); + m_edit->setValue(value.toInt()); + connect(m_edit, SIGNAL(valueChanged(int)), this, SLOT(updateProperty(int))); + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PSpinBox::updateProperty(int val) +{ + emit propertyChanged(m_property, QVariant(val)); +} + +} + +#ifndef PURE_QT +#include "pspinbox.moc" +#endif diff --git a/lib/widgets/propeditor/pspinbox.h b/lib/widgets/propeditor/pspinbox.h new file mode 100644 index 00000000..1ca839b8 --- /dev/null +++ b/lib/widgets/propeditor/pspinbox.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PSPINBOX_H +#define PSPINBOX_H + +#include "propertywidget.h" + +class QSpinBox; + +namespace PropertyLib{ + +/** +@short %Property editor with integer num input box. +*/ +class PSpinBox: public PropertyWidget{ + Q_OBJECT +public: + PSpinBox(MultiProperty *property, QWidget *parent = 0, const char *name = 0); + PSpinBox(MultiProperty *property, int minValue, int maxValue, int step = 1, QWidget *parent = 0, const char *name = 0); + + /**@return the value currently entered in the editor widget.*/ + virtual QVariant value() const; + /**Sets the value shown in the editor widget. Set emitChange to false + if you don't want to emit propertyChanged signal.*/ + virtual void setValue(const QVariant &value, bool emitChange=true); + +private slots: + void updateProperty(int val); + +private: + QSpinBox *m_edit; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pstringlistedit.cpp b/lib/widgets/propeditor/pstringlistedit.cpp new file mode 100644 index 00000000..227050f9 --- /dev/null +++ b/lib/widgets/propeditor/pstringlistedit.cpp @@ -0,0 +1,121 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pstringlistedit.h" + +#include <qlayout.h> +#include <qdialog.h> +#include <qpainter.h> +#include <klineedit.h> + +#ifndef PURE_QT +#include <keditlistbox.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> +#else +#include "qeditlistbox.h" +#include <qpushbutton.h> +#include "compat_tools.h" +#endif + +namespace PropertyLib{ + +PStringListEdit::PStringListEdit(MultiProperty *property, QWidget *parent, const char *name) + :PropertyWidget(property, parent, name) +{ + l = new QHBoxLayout(this); + + edit = new KLineEdit(this); + edit->setReadOnly(true); + edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(edit); + pbSelect = new QPushButton("...", this); + pbSelect->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::MinimumExpanding); + l->addWidget(pbSelect); + + connect(pbSelect, SIGNAL(clicked()), this, SLOT(showEditor())); +} + +QVariant PStringListEdit::value() const +{ + return QVariant(m_list); +} + +void PStringListEdit::setValue(const QVariant &value, bool emitChange) +{ + m_list = value.toStringList(); + edit->setText(value.toStringList().join(", ")); + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PStringListEdit::showEditor() +{ + QDialog* dia = new QDialog(this, "stringlist_dialog", true); + QVBoxLayout *dv = new QVBoxLayout(dia, 2); + +#ifdef PURE_QT + QEditListBox *select = new QEditListBox(dia, "select_char"); +#else + KEditListBox *select = new KEditListBox(dia, "select_char"); +#endif + dv->addWidget(select); + + QHBoxLayout *dh = new QHBoxLayout(dv, 6); +#ifndef PURE_QT + KPushButton *pbOk = new KPushButton(KStdGuiItem::ok(), dia); + KPushButton *pbCancel = new KPushButton(KStdGuiItem::cancel(), dia); +#else + QPushButton *pbOk = new QPushButton(i18n("Ok"), dia); + QPushButton *pbCancel = new QPushButton(i18n("Cancel"), dia); +#endif + QSpacerItem *si = new QSpacerItem(30, 0, QSizePolicy::Expanding, QSizePolicy::Expanding); + + connect(pbOk, SIGNAL(clicked()), dia, SLOT(accept())); + connect(pbCancel, SIGNAL(clicked()), dia, SLOT(reject())); + + dh->addItem(si); + dh->addWidget(pbOk); + dh->addWidget(pbCancel); + + select->insertStringList(m_list); + + if (dia->exec() == QDialog::Accepted) + { + m_list = select->items(); + edit->setText(select->items().join(", ")); + } + delete dia; + + emit propertyChanged(m_property, m_list); +} + +void PStringListEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + p->setPen(Qt::NoPen); + p->setBrush(cg.background()); + p->drawRect(r); + p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, value.toStringList().join(", ")); +} + +} + +#ifndef PURE_QT +#include "pstringlistedit.moc" +#endif diff --git a/lib/widgets/propeditor/pstringlistedit.h b/lib/widgets/propeditor/pstringlistedit.h new file mode 100644 index 00000000..25d6db19 --- /dev/null +++ b/lib/widgets/propeditor/pstringlistedit.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 2003-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PSTRINGLISTEDIT_H +#define PSTRINGLISTEDIT_H + +#include "propertywidget.h" + + +class KLineEdit; +class QPushButton; +class QHBoxLayout; + +namespace PropertyLib{ + +/** +@short %Property editor with string list editor. +*/ +class PStringListEdit: public PropertyWidget +{ + Q_OBJECT +public: + PStringListEdit(MultiProperty *property, QWidget *parent = 0, const char *name = 0); + + /**@return the value currently entered in the editor widget.*/ + virtual QVariant value() const; + /**Sets the value shown in the editor widget. Set emitChange to false + if you don't want to emit propertyChanged signal.*/ + virtual void setValue(const QVariant &value, bool emitChange=true); + /**Function to draw a property viewer when the editor isn't shown.*/ + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + +private slots: + void showEditor(); + +private: + QPushButton *pbSelect; + QHBoxLayout *l; + KLineEdit *edit; + + QStringList m_list; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/psymbolcombo.cpp b/lib/widgets/propeditor/psymbolcombo.cpp new file mode 100644 index 00000000..70dd7ba9 --- /dev/null +++ b/lib/widgets/propeditor/psymbolcombo.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include <qlayout.h> +#include <qpainter.h> +#include <qpushbutton.h> +#include <klineedit.h> + +#ifndef PURE_QT +#include <kcharselect.h> +#include <klocale.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> +#include <qdialog.h> +#endif + +#include "psymbolcombo.h" + +namespace PropertyLib{ + +PSymbolCombo::PSymbolCombo(MultiProperty *property, QWidget *parent, const char *name) + :PropertyWidget(property, parent, name) +{ + l = new QHBoxLayout(this); + m_edit = new KLineEdit(this); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + m_edit->setMaxLength(1); + l->addWidget(m_edit); + m_select = new QPushButton("...", this); + m_select->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::MinimumExpanding); + l->addWidget(m_select); + +#ifdef PURE_QT + m_select->hide(); +#endif + + connect(m_select, SIGNAL(clicked()), this, SLOT(selectChar())); + connect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(updateProperty(const QString&))); +} + +QVariant PSymbolCombo::value() const +{ + if (!(m_edit->text().isNull())) + return QVariant(QString("%1").arg(m_edit->text().at(0).unicode())); + else + return QVariant(0); +} + +void PSymbolCombo::setValue(const QVariant &value, bool emitChange) +{ +#if QT_VERSION >= 0x030100 + if (!(value.isNull())) +#else + if (value.canCast(QVariant::Int)) +#endif + { + disconnect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(updateProperty(const QString&))); + m_edit->setText(QChar(value.toInt())); + connect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(updateProperty(const QString&))); + if (emitChange) + emit propertyChanged(m_property, value); + } +} + +void PSymbolCombo::selectChar() +{ +#ifndef PURE_QT + QDialog* dia = new QDialog(this, "select_dialog", true); + QVBoxLayout *dv = new QVBoxLayout(dia, 2); + + KCharSelect *select = new KCharSelect(dia, "select_char"); + dv->addWidget(select); + + QHBoxLayout *dh = new QHBoxLayout(dv, 6); + KPushButton *pbOk = new KPushButton(KStdGuiItem::ok(), dia); + KPushButton *pbCancel = new KPushButton(KStdGuiItem::cancel(), dia); + QSpacerItem *si = new QSpacerItem(30, 0, QSizePolicy::Expanding, QSizePolicy::Expanding); + + connect(pbOk, SIGNAL(clicked()), dia, SLOT(accept())); + connect(pbCancel, SIGNAL(clicked()), dia, SLOT(reject())); + + dh->addItem(si); + dh->addWidget(pbOk); + dh->addWidget(pbCancel); + + if (!(m_edit->text().isNull())) + select->setChar(m_edit->text().at(0)); + + if (dia->exec() == QDialog::Accepted) + { + m_edit->setText(select->chr()); + } + delete dia; +#endif +} + +void PSymbolCombo::updateProperty(const QString& val) +{ + emit propertyChanged(m_property, QVariant(QString("%1").arg(val.at(0).unicode()))); +} + +void PSymbolCombo::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + p->setBrush(cg.background()); + p->setPen(Qt::NoPen); + p->drawRect(r); + p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, QChar(value.toInt())); +} + +} + +#ifndef PURE_QT +#include "psymbolcombo.moc" +#endif diff --git a/lib/widgets/propeditor/psymbolcombo.h b/lib/widgets/propeditor/psymbolcombo.h new file mode 100644 index 00000000..fd6e57ec --- /dev/null +++ b/lib/widgets/propeditor/psymbolcombo.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 2002-2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PSYMBOLCOMBO_H +#define PSYMBOLCOMBO_H + +#include "propertywidget.h" + +class KLineEdit; +class QPushButton; +class QHBoxLayout; + +namespace PropertyLib{ + + +/** +@short %Property editor with char selector. +*/ +class PSymbolCombo: public PropertyWidget{ + Q_OBJECT +public: + PSymbolCombo(MultiProperty *property, QWidget *parent = 0, const char *name = 0); + + /**@return the value currently entered in the editor widget.*/ + virtual QVariant value() const; + /**Sets the value shown in the editor widget. Set emitChange to false + if you don't want to emit propertyChanged signal.*/ + virtual void setValue(const QVariant &value, bool emitChange=true); + /**Function to draw a property viewer when the editor isn't shown.*/ + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + +public slots: + void selectChar(); + +private slots: + void updateProperty(const QString &val); + +private: + KLineEdit *m_edit; + QPushButton *m_select; + QHBoxLayout *l; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/purledit.cpp b/lib/widgets/propeditor/purledit.cpp new file mode 100644 index 00000000..9d90273a --- /dev/null +++ b/lib/widgets/propeditor/purledit.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "purledit.h" + +#ifndef PURE_QT +#include <kurlrequester.h> +#else +#include <qpushbutton.h> +#include <qlineedit.h> +#endif +#include <qfiledialog.h> +#include <qlayout.h> + +namespace PropertyLib{ + +PUrlEdit::PUrlEdit(Mode mode, MultiProperty* property, QWidget* parent, const char* name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); +#ifndef PURE_QT + m_edit = new KURLRequester(this); + l->addWidget(m_edit); + m_edit->setMode((KFile::Mode)mode); + connect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(updateProperty(const QString&))); +#else + m_edit = new KLineEdit(this); + m_select = new QPushButton("...",this); + l->addWidget(m_edit); + l->addWidget(m_select); + m_mode = mode; + connect( m_select, SIGNAL(clicked()),this,SLOT(select())); +#endif + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); +} + +QVariant PUrlEdit::value() const +{ +#ifndef PURE_QT + return QVariant(m_edit->url()); +#else + return QVariant(m_url); +#endif +} + +void PUrlEdit::setValue(const QVariant& value, bool emitChange) +{ +#ifndef PURE_QT + disconnect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(updateProperty(const QString&))); + m_edit->setURL(value.toString()); + connect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(updateProperty(const QString&))); +#else + m_edit->setText(value.toString()); +#endif + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PUrlEdit::updateProperty(const QString &val) +{ + emit propertyChanged(m_property, QVariant(val)); +} + +void PUrlEdit::select() +{ +#ifdef PURE_QT + QString path = m_url; + if( m_mode == Directory ) + m_url = QFileDialog::getExistingDirectory( m_url,this); + else + m_url = QFileDialog::getOpenFileName(m_url, QString::null, this); + updateProperty(m_url); + m_edit->setText(m_url); +#endif +} + +} + +#ifndef PURE_QT +#include "purledit.moc" +#endif diff --git a/lib/widgets/propeditor/purledit.h b/lib/widgets/propeditor/purledit.h new file mode 100644 index 00000000..5da0108d --- /dev/null +++ b/lib/widgets/propeditor/purledit.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PURLEDIT_H +#define PURLEDIT_H + +#include "propertywidget.h" + +#ifndef PURE_QT +#include <kfile.h> +class KURLRequester; +#else +#include <klineedit.h> +class QPushButton; +#endif + + +namespace PropertyLib{ + +/** +@short %Property editor with an url editor to choose the location of file or directory. +*/ +class PUrlEdit : public PropertyWidget +{ +Q_OBJECT +public: +#ifndef PURE_QT + enum Mode {File = KFile::File,Directory = KFile::Directory}; +#else + enum Mode {File,Directory}; +#endif + + PUrlEdit(Mode mode, MultiProperty* property, QWidget* parent=0, const char* name=0); + + virtual QVariant value() const; + virtual void setValue(const QVariant& value, bool emitChange); + +private slots: + void updateProperty(const QString &val); + void select(); +private: +#ifndef PURE_QT + KURLRequester *m_edit; +#else + KLineEdit *m_edit; + QPushButton *m_select; + QString m_url; + Mode m_mode; +#endif +}; + +} + +#endif diff --git a/lib/widgets/propeditor/pyesnobutton.cpp b/lib/widgets/propeditor/pyesnobutton.cpp new file mode 100644 index 00000000..c27f4a60 --- /dev/null +++ b/lib/widgets/propeditor/pyesnobutton.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "pyesnobutton.h" + +#include <qlayout.h> +#include <qpainter.h> +#include <qpushbutton.h> + +#ifndef PURE_QT +#include <klocale.h> +#else +#include "compat_tools.h" +#endif + +namespace PropertyLib{ + +PYesNoButton::PYesNoButton(MultiProperty* property, QWidget* parent, const char* name) + :PropertyWidget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QPushButton(this); + m_edit->setToggleButton(true); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + l->addWidget(m_edit); + + connect(m_edit, SIGNAL(toggled(bool)), this, SLOT(updateProperty(bool))); +} + +QVariant PYesNoButton::value() const +{ + return QVariant(m_edit->isOn()); +} + +void PYesNoButton::drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value) +{ + PropertyWidget::drawViewer(p, cg, r, value.toBool() ? i18n("Yes") : i18n("No")); +} + +void PYesNoButton::setValue(const QVariant& value, bool emitChange) +{ + disconnect(m_edit, SIGNAL(toggled(bool)), this, SLOT(updateProperty(bool))); + m_edit->setDown(value.toBool()); + value.toBool() ? m_edit->setText(i18n("Yes")) : m_edit->setText(i18n("No")); + connect(m_edit, SIGNAL(toggled(bool)), this, SLOT(updateProperty(bool))); + if (emitChange) + emit propertyChanged(m_property, value); +} + +void PYesNoButton::updateProperty(bool toggled) +{ + toggled ? m_edit->setText(i18n("Yes")) : m_edit->setText(i18n("No")); + emit propertyChanged(m_property, value()); +} + +} + +#ifndef PURE_QT +#include "pyesnobutton.moc" +#endif diff --git a/lib/widgets/propeditor/pyesnobutton.h b/lib/widgets/propeditor/pyesnobutton.h new file mode 100644 index 00000000..f0596a8f --- /dev/null +++ b/lib/widgets/propeditor/pyesnobutton.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mskat.net * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PYESNOBUTTON_H +#define PYESNOBUTTON_H + +#include <propertywidget.h> + +class QPushButton; + +namespace PropertyLib{ + +/** +@short %Property editor with yes-no button to edit boolean values. +*/ +class PYesNoButton : public PropertyWidget +{ + Q_OBJECT +public: + PYesNoButton(MultiProperty* property, QWidget* parent = 0, const char* name = 0); + + virtual QVariant value() const; + virtual void drawViewer(QPainter* p, const QColorGroup& cg, const QRect& r, const QVariant& value); + virtual void setValue(const QVariant& value, bool emitChange); + +protected slots: + void updateProperty(bool toggled); + +private: + QPushButton *m_edit; +}; + +} + +#endif diff --git a/lib/widgets/propeditor/qeditlistbox.cpp b/lib/widgets/propeditor/qeditlistbox.cpp new file mode 100644 index 00000000..e9b17d54 --- /dev/null +++ b/lib/widgets/propeditor/qeditlistbox.cpp @@ -0,0 +1,401 @@ +/* This file is part of the KDE libraries + Copyright (C) 2000 David Faure <faure@kde.org>, Alexander Neundorf <neundorf@kde.org> + 2000, 2002 Carsten Pfeiffer <pfeiffer@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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include "qeditlistbox.h" + +#include "compat_tools.h" + +#include <klineedit.h> + +#include <qpushbutton.h> +#include <qlayout.h> +#include <qgroupbox.h> +#include <qlistbox.h> +#include <qwhatsthis.h> +#include <qlabel.h> +#include <qcombobox.h> +#include <qapplication.h> +#include <qstringlist.h> + +#include <assert.h> + +//same as kdialog.cpp ones +#define MarginSize 11 +#define SpazingSize 6 + +class QEditListBoxPrivate +{ +public: + bool m_checkAtEntering; + int buttons; +}; + +QEditListBox::QEditListBox(QWidget *parent, const char *name, + bool checkAtEntering, int buttons ) + :QGroupBox(parent, name ) +{ + init( checkAtEntering, buttons ); +} + +QEditListBox::QEditListBox(const QString& title, QWidget *parent, + const char *name, bool checkAtEntering, int buttons) + :QGroupBox(title, parent, name ) +{ + init( checkAtEntering, buttons ); +} + +QEditListBox::QEditListBox(const QString& title, const CustomEditor& custom, + QWidget *parent, const char *name, + bool checkAtEntering, int buttons) + :QGroupBox(title, parent, name ) +{ + m_lineEdit = custom.lineEdit(); + init( checkAtEntering, buttons, custom.representationWidget() ); +} + +QEditListBox::~QEditListBox() +{ + delete d; + d=0; +} + +void QEditListBox::init( bool checkAtEntering, int buttons, + QWidget *representationWidget ) +{ + d=new QEditListBoxPrivate; + d->m_checkAtEntering=checkAtEntering; + d->buttons = buttons; + + int lostButtons = 0; + if ( (buttons & Add) == 0 ) + lostButtons++; + if ( (buttons & Remove) == 0 ) + lostButtons++; + if ( (buttons & UpDown) == 0 ) + lostButtons += 2; + + + servNewButton = servRemoveButton = servUpButton = servDownButton = 0L; + setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding)); + + QWidget * gb = this; + QGridLayout * grid = new QGridLayout(gb, 7 - lostButtons, 2, + MarginSize, + SpazingSize); + grid->addRowSpacing(0, fontMetrics().lineSpacing()); + for ( int i = 1; i < 7 - lostButtons; i++ ) + grid->setRowStretch(i, 1); + + grid->setMargin(15); + + if ( representationWidget ) + representationWidget->reparent( gb, QPoint(0,0) ); + else + m_lineEdit=new KLineEdit(gb); + + m_listBox = new QListBox(gb); + + QWidget *editingWidget = representationWidget ? + representationWidget : m_lineEdit; + grid->addMultiCellWidget(editingWidget,1,1,0,1); + grid->addMultiCellWidget(m_listBox, 2, 6 - lostButtons, 0, 0); + int row = 2; + if ( buttons & Add ) { + servNewButton = new QPushButton(i18n("&Add"), gb); + servNewButton->setEnabled(false); + connect(servNewButton, SIGNAL(clicked()), SLOT(addItem())); + + grid->addWidget(servNewButton, row++, 1); + } + + if ( buttons & Remove ) { + servRemoveButton = new QPushButton(i18n("&Remove"), gb); + servRemoveButton->setEnabled(false); + connect(servRemoveButton, SIGNAL(clicked()), SLOT(removeItem())); + + grid->addWidget(servRemoveButton, row++, 1); + } + + if ( buttons & UpDown ) { + servUpButton = new QPushButton(i18n("Move &Up"), gb); + servUpButton->setEnabled(false); + connect(servUpButton, SIGNAL(clicked()), SLOT(moveItemUp())); + + servDownButton = new QPushButton(i18n("Move &Down"), gb); + servDownButton->setEnabled(false); + connect(servDownButton, SIGNAL(clicked()), SLOT(moveItemDown())); + + grid->addWidget(servUpButton, row++, 1); + grid->addWidget(servDownButton, row++, 1); + } + + connect(m_lineEdit,SIGNAL(textChanged(const QString&)),this,SLOT(typedSomething(const QString&))); + + connect(m_lineEdit,SIGNAL(returnPressed()),this,SLOT(addItem())); + connect(m_listBox, SIGNAL(highlighted(int)), SLOT(enableMoveButtons(int))); + + // maybe supplied lineedit has some text already + typedSomething( m_lineEdit->text() ); +} + +void QEditListBox::typedSomething(const QString& text) +{ + if(currentItem() >= 0) { + if(currentText() != m_lineEdit->text()) + { + // IMHO changeItem() shouldn't do anything with the value + // of currentItem() ... like changing it or emitting signals ... + // but TT disagree with me on this one (it's been that way since ages ... grrr) + bool block = m_listBox->signalsBlocked(); + m_listBox->blockSignals( true ); + m_listBox->changeItem(text, currentItem()); + m_listBox->blockSignals( block ); + emit changed(); + } + } + + if ( !servNewButton ) + return; + + if (!d->m_checkAtEntering) + servNewButton->setEnabled(!text.isEmpty()); + else + { + if (text.isEmpty()) + { + servNewButton->setEnabled(false); + } + else + { + StringComparisonMode mode = (StringComparisonMode) (ExactMatch | CaseSensitive ); + bool enable = (m_listBox->findItem( text, mode ) == 0L); + servNewButton->setEnabled( enable ); + } + } +} + +void QEditListBox::moveItemUp() +{ + if (!m_listBox->isEnabled()) + { + qDebug("beep"); + return; + } + + unsigned int selIndex = m_listBox->currentItem(); + if (selIndex == 0) + { + qDebug("beep"); + return; + } + + QListBoxItem *selItem = m_listBox->item(selIndex); + m_listBox->takeItem(selItem); + m_listBox->insertItem(selItem, selIndex-1); + m_listBox->setCurrentItem(selIndex - 1); + + emit changed(); +} + +void QEditListBox::moveItemDown() +{ + if (!m_listBox->isEnabled()) + { + qDebug("beep"); + return; + } + + unsigned int selIndex = m_listBox->currentItem(); + if (selIndex == m_listBox->count() - 1) + { + qDebug("beep"); + return; + } + + QListBoxItem *selItem = m_listBox->item(selIndex); + m_listBox->takeItem(selItem); + m_listBox->insertItem(selItem, selIndex+1); + m_listBox->setCurrentItem(selIndex + 1); + + emit changed(); +} + +void QEditListBox::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 ( !servNewButton || !servNewButton->isEnabled() ) + return; + + const QString& currentTextLE=m_lineEdit->text(); + bool alreadyInList(false); + //if we didn't check for dupes at the inserting we have to do it now + if (!d->m_checkAtEntering) + { + // first check current item instead of dumb iterating the entire list + if ( m_listBox->currentText() == currentTextLE ) + alreadyInList = true; + else + { + StringComparisonMode mode = (StringComparisonMode) (ExactMatch | CaseSensitive ); + alreadyInList =(m_listBox->findItem(currentTextLE, mode) != 0); + } + } + + if ( servNewButton ) + servNewButton->setEnabled(false); + + bool block = m_lineEdit->signalsBlocked(); + m_lineEdit->blockSignals(true); + m_lineEdit->clear(); + m_lineEdit->blockSignals(block); + + m_listBox->setSelected(currentItem(), false); + + if (!alreadyInList) + { + block = m_listBox->signalsBlocked(); + m_listBox->blockSignals( true ); + m_listBox->insertItem(currentTextLE); + m_listBox->blockSignals( block ); + emit changed(); + emit added( currentTextLE ); + } +} + +int QEditListBox::currentItem() const +{ + int nr = m_listBox->currentItem(); + if(nr >= 0 && !m_listBox->item(nr)->isSelected()) return -1; + return nr; +} + +void QEditListBox::removeItem() +{ + int selected = m_listBox->currentItem(); + + if ( selected >= 0 ) + { + QString removedText = m_listBox->currentText(); + + m_listBox->removeItem( selected ); + if ( count() > 0 ) + m_listBox->setSelected( QMIN( selected, count() - 1 ), true ); + + emit changed(); + emit removed( removedText ); + } + + if ( servRemoveButton && m_listBox->currentItem() == -1 ) + servRemoveButton->setEnabled(false); +} + +void QEditListBox::enableMoveButtons(int index) +{ + // Update the lineEdit when we select a different line. + if(currentText() != m_lineEdit->text()) + m_lineEdit->setText(currentText()); + + bool moveEnabled = servUpButton && servDownButton; + + if (moveEnabled ) + { + if (m_listBox->count() <= 1) + { + servUpButton->setEnabled(false); + servDownButton->setEnabled(false); + } + else if ((uint) index == (m_listBox->count() - 1)) + { + servUpButton->setEnabled(true); + servDownButton->setEnabled(false); + } + else if (index == 0) + { + servUpButton->setEnabled(false); + servDownButton->setEnabled(true); + } + else + { + servUpButton->setEnabled(true); + servDownButton->setEnabled(true); + } + } + + if ( servRemoveButton ) + servRemoveButton->setEnabled(true); +} + +void QEditListBox::clear() +{ + m_lineEdit->clear(); + m_listBox->clear(); + emit changed(); +} + +void QEditListBox::insertStringList(const QStringList& list, int index) +{ + m_listBox->insertStringList(list,index); +} + +void QEditListBox::insertStrList(const QStrList* list, int index) +{ + m_listBox->insertStrList(list,index); +} + +void QEditListBox::insertStrList(const QStrList& list, int index) +{ + m_listBox->insertStrList(list,index); +} + +void QEditListBox::insertStrList(const char ** list, int numStrings, int index) +{ + m_listBox->insertStrList(list,numStrings,index); +} + +QStringList QEditListBox::items() const +{ + QStringList list; + for ( uint i = 0; i < m_listBox->count(); i++ ) + list.append( m_listBox->text( i )); + + return list; +} + +void QEditListBox::setItems(const QStringList& items) +{ + m_listBox->clear(); + m_listBox->insertStringList(items, 0); +} + +void QEditListBox::virtual_hook( int, void* ) +{ /*BASE::virtual_hook( id, data );*/ } + + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + +QEditListBox::CustomEditor::CustomEditor( QComboBox *combo ) +{ + m_representationWidget = combo; + m_lineEdit = dynamic_cast<KLineEdit*>( combo->lineEdit() ); + assert( m_lineEdit ); +} diff --git a/lib/widgets/propeditor/qeditlistbox.h b/lib/widgets/propeditor/qeditlistbox.h new file mode 100644 index 00000000..0b95a919 --- /dev/null +++ b/lib/widgets/propeditor/qeditlistbox.h @@ -0,0 +1,255 @@ +/* This file is part of the KDE libraries + Copyright (C) 2000 David Faure <faure@kde.org>, Alexander Neundorf <neundorf@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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef QEDITLISTBOX_H +#define QEDITLISTBOX_H + +#include <qgroupbox.h> +#include <qlistbox.h> + +class KLineEdit; +class QComboBox; +class QPushButton; + +/** + * An editable listbox + * + * This class provides a editable listbox ;-), this means + * a listbox which is accompanied by a line edit to enter new + * items into the listbox and pushbuttons to add and remove + * items from the listbox and two buttons to move items up and down. + * + * \image html keditlistbox.png "KDE Edit List Box Widget" + * + */ + + +class QEditListBoxPrivate; + +class QEditListBox : public QGroupBox +{ + Q_OBJECT + + Q_PROPERTY( QStringList items READ items WRITE setItems ) + +public: + // @since 3.1 + class CustomEditor + { + public: + CustomEditor() + : m_representationWidget( 0L ), + m_lineEdit( 0L ) {} + CustomEditor( QWidget *repWidget, KLineEdit *edit ) + : m_representationWidget( repWidget ), + m_lineEdit( edit ) {} + CustomEditor( QComboBox *combo ); + + void setRepresentationWidget( QWidget *repWidget ) { + m_representationWidget = repWidget; + } + void setLineEdit( KLineEdit *edit ) { + m_lineEdit = edit; + } + + virtual QWidget *representationWidget() const { + return m_representationWidget; + } + virtual KLineEdit *lineEdit() const { + return m_lineEdit; + } + + protected: + QWidget *m_representationWidget; + KLineEdit *m_lineEdit; + }; + + public: + + /** + * Enumeration of the buttons, the listbox offers. Specify them in the + * constructor in the buttons parameter. + */ + enum Button { Add = 1, Remove = 2, UpDown = 4, All = Add|Remove|UpDown }; + + /** + * Create an editable listbox. + * + * If @p checkAtEntering is true, after every character you type + * in the line edit QEditListBox will enable or disable + * the Add-button, depending whether the current content of the + * line edit is already in the listbox. Maybe this can become a + * performance hit with large lists on slow machines. + * If @p checkAtEntering is false, + * it will be checked if you press the Add-button. It is not + * possible to enter items twice into the listbox. + */ + QEditListBox(QWidget *parent = 0, const char *name = 0, + bool checkAtEntering=false, int buttons = All ); + /** + * Create an editable listbox. + * + * The same as the other constructor, additionally it takes + * @p title, which will be the title of the frame around the listbox. + */ + QEditListBox(const QString& title, QWidget *parent = 0, + const char *name = 0, bool checkAtEntering=false, + int buttons = All ); + + /** + * Another constructor, which allows to use a custom editing widget + * instead of the standard QLineEdit widget. E.g. you can use a + * KURLRequester or a QComboBox as input widget. The custom + * editor must consist of a lineedit and optionally another widget that + * is used as representation. A QComboBox or a KURLRequester have a + * QLineEdit as child-widget for example, so the QComboBox is used as + * the representation widget. + * + * @see KURLRequester::customEditor() + * @since 3.1 + */ + QEditListBox( const QString& title, + const CustomEditor &customEditor, + QWidget *parent = 0, const char *name = 0, + bool checkAtEntering = false, int buttons = All ); + + virtual ~QEditListBox(); + + /** + * Return a pointer to the embedded QListBox. + */ + QListBox* listBox() const { return m_listBox; } + /** + * Return a pointer to the embedded KLineEdit. + */ + KLineEdit* lineEdit() const { return m_lineEdit; } + /** + * Return a pointer to the Add button + */ + QPushButton* addButton() const { return servNewButton; } + /** + * Return a pointer to the Remove button + */ + QPushButton* removeButton() const { return servRemoveButton; } + /** + * Return a pointer to the Up button + */ + QPushButton* upButton() const { return servUpButton; } + /** + * Return a pointer to the Down button + */ + QPushButton* downButton() const { return servDownButton; } + + /** + * See QListBox::count() + */ + int count() const { return int(m_listBox->count()); } + /** + * See QListBox::insertStringList() + */ + void insertStringList(const QStringList& list, int index=-1); + /** + * See QListBox::insertStringList() + */ + void insertStrList(const QStrList* list, int index=-1); + /** + * See QListBox::insertStrList() + */ + void insertStrList(const QStrList& list, int index=-1); + /** + * See QListBox::insertStrList() + */ + void insertStrList(const char ** list, int numStrings=-1, int index=-1); + /** + * See QListBox::insertItem() + */ + void insertItem(const QString& text, int index=-1) {m_listBox->insertItem(text,index);} + /** + * Clears both the listbox and the line edit. + */ + void clear(); + /** + * See QListBox::text() + */ + QString text(int index) const { return m_listBox->text(index); } + /** + * See QListBox::currentItem() + */ + int currentItem() const; + /** + * See QListBox::currentText() + */ + QString currentText() const { return m_listBox->currentText(); } + + /** + * @returns a stringlist of all items in the listbox + */ + QStringList items() const; + + /** + * Clears the listbox and sets the contents to @p items + * + * @since 3.4 + */ + void setItems(const QStringList& items); + + signals: + void changed(); + + /** + * This signal is emitted when the user adds a new string to the list, + * the parameter is the added string. + * @since 3.2 + */ + void added( const QString & text ); + + /** + * This signal is emitted when the user removes a string from the list, + * the parameter is the removed string. + * @since 3.2 + */ + void removed( const QString & text ); + + protected slots: + //the names should be self-explaining + void moveItemUp(); + void moveItemDown(); + void addItem(); + void removeItem(); + void enableMoveButtons(int index); + void typedSomething(const QString& text); + + private: + QListBox *m_listBox; + QPushButton *servUpButton, *servDownButton; + QPushButton *servNewButton, *servRemoveButton; + KLineEdit *m_lineEdit; + + //this is called in both ctors, to avoid code duplication + void init( bool checkAtEntering, int buttons, + QWidget *representationWidget = 0L ); + + protected: + virtual void virtual_hook( int id, void* data ); + private: + //our lovely private d-pointer + QEditListBoxPrivate *d; +}; + +#endif diff --git a/lib/widgets/propeditor/qfloatinput.cpp b/lib/widgets/propeditor/qfloatinput.cpp new file mode 100644 index 00000000..ea3b17f1 --- /dev/null +++ b/lib/widgets/propeditor/qfloatinput.cpp @@ -0,0 +1,51 @@ +/* + * qfloatinput.cpp + * + * Copyright (C) 2004 David Faure <faure@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + */ +#include "qfloatinput.h" + +#include <math.h> + +QFloatInput::QFloatInput( int min, int max, float step, int digits, + QWidget *parent, const char *name ) + : QSpinBox( (int) (min*pow(digits,10)), + (int) (max*pow(digits,10)), + (int) (step*pow(digits,10)), parent, name ), + m_digits( digits ) +{ + setValue( (int) (min*pow(digits,10)) ); + delete validator(); + QDoubleValidator* validator = + new QDoubleValidator( min, max, m_digits, this ); + setValidator( validator ); +} + +QString QFloatInput::mapValueToText( int value ) +{ + QString format = QString("%.%1f").arg( m_digits ); + return QString().sprintf(format.latin1(), + (value/(float)pow(m_digits,10)) ); +} + +int QFloatInput::mapTextToValue( bool* ok ) +{ + return int(cleanText().toFloat(ok)*pow(m_digits,10)); +} + + diff --git a/lib/widgets/propeditor/qfloatinput.h b/lib/widgets/propeditor/qfloatinput.h new file mode 100644 index 00000000..72977dd5 --- /dev/null +++ b/lib/widgets/propeditor/qfloatinput.h @@ -0,0 +1,48 @@ +/** + * qfloatinput.h + * + * Copyright (C) 2004 David Faure <faure@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + */ +#ifndef QFLOATINPUT_H +#define QFLOATINPUT_H + +#include <qapplication.h> +#include <qspinbox.h> +#include <qvalidator.h> + +class QFloatInput : public QSpinBox +{ +public: + QFloatInput( int min, int max, float step, int digits, + QWidget *parent, const char *name = 0 ); + + virtual QString mapValueToText( int value ); + + virtual int mapTextToValue( bool* ok ); + + int digits() const + { + return m_digits; + } + +private: + int m_digits; +}; + + +#endif diff --git a/lib/widgets/propeditor/test.cpp b/lib/widgets/propeditor/test.cpp new file mode 100644 index 00000000..db49addc --- /dev/null +++ b/lib/widgets/propeditor/test.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (C) 2004 by SourceXtreme, Inc * + * oss@sourcextreme.com * + * * + * This program 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 program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include <qapplication.h> + +#include "propertyeditor.h" +#include "propertylist.h" +#include "multiproperty.h" + +using namespace PropertyLib; + +int main( int argc, char **argv ) +{ + QApplication app( argc, argv ); + + PropertyEditor *editor = new PropertyEditor( 0 ); + + PropertyList *currentList = new PropertyList(); + + currentList->addProperty( + new Property(Property::String, "Sample string", + "Sample description", "value" ) ); + currentList->addProperty( + new Property(Property::Color, "Color", + "Sample color description", Qt::red ) ); + currentList->addProperty( + new Property( Property::Pixmap, "Pixmap", + "sample pixmap description" ) ); + currentList->addProperty( + new Property( Property::Rect, "Rectangle", + "sample rectangle", QRect( 10, 11, 30, 40 ) ) ); + currentList->addProperty( + new Property( Property::Point, "Point", + "sample point", QPoint( 20, 30 ) ) ); + currentList->addProperty( + new Property( Property::Boolean, "Boolean", + "sample bool", false ) ); + currentList->addProperty( + new Property( Property::Integer, "Integer", + "sample integer", 7 ) ); + + currentList->addProperty( + new Property( Property::Double, "Double", + "sample double", 7.0 ) ); + + QStringList things; + things += "Thing 1"; + things += "Thing 2"; + + currentList->addProperty( + new Property( Property::StringList, "StringList", + "sample stringlist", things ) ); + + + currentList->addProperty( + new Property( Property::DirectoryURL, "Directory", + "sample dir", "C:/" ) ); + + currentList->addProperty( + new Property( Property::FileURL, "File", + "sample file", "C:/" ) ); + + editor->populateProperties( currentList ); + + app.setMainWidget( editor ); + editor->show(); + + return app.exec(); +} + diff --git a/lib/widgets/propeditor/test.pro b/lib/widgets/propeditor/test.pro new file mode 100755 index 00000000..c5b53846 --- /dev/null +++ b/lib/widgets/propeditor/test.pro @@ -0,0 +1,40 @@ +TEMPLATE = app +CONFIG += release +DEFINES += PURE_QT + +SOURCES += childproperty.cpp pcombobox.cpp \ + pdummywidget.cpp ppointedit.cpp \ + propertymachinefactory.cpp pstringlistedit.cpp \ + multiproperty.cpp pcursoredit.cpp \ + prectedit.cpp propertywidget.cpp \ + psymbolcombo.cpp pcheckbox.cpp \ + pdateedit.cpp pfontcombo.cpp \ + property.cpp psizeedit.cpp \ + pdatetimeedit.cpp \ + plineedit.cpp propertyeditor.cpp \ + psizepolicyedit.cpp pyesnobutton.cpp \ + ppixmapedit.cpp \ + propertylist.cpp pspinbox.cpp \ + propertywidgetproxy.cpp plinestyleedit.cpp \ + qeditlistbox.cpp pcolorbutton.cpp \ + pdoublenuminput.cpp qfloatinput.cpp \ + purledit.cpp test.cpp + +HEADERS += childproperty.h pcombobox.h \ + pdummywidget.h ppointedit.h \ + propertymachinefactory.h pcursoredit.h \ + prectedit.h propertywidget.h \ + pdateedit.h pfontcombo.h \ + property.h psizeedit.h \ + pdatetimeedit.h plineedit.h \ + propertyeditor.h psizepolicyedit.h \ + ppixmapedit.h propertylist.h \ + pspinbox.h propertywidgetproxy.h \ + multiproperty.h pyesnobutton.h \ + psymbolcombo.h pstringlistedit.h \ + pcheckbox.h plinestyleedit.h \ + qeditlistbox.h pcolorbutton.h \ + pdoublenuminput.h qfloatinput.h \ + compat_tools.h purledit.h + +IMAGES += undo.xpm diff --git a/lib/widgets/propeditor/undo.xpm b/lib/widgets/propeditor/undo.xpm new file mode 100644 index 00000000..42cbaed0 --- /dev/null +++ b/lib/widgets/propeditor/undo.xpm @@ -0,0 +1,44 @@ +/* XPM */ +static char *undo[] = { +/* columns rows colors chars-per-pixel */ +"16 15 23 1", +" c #000100010001", +". c #0170016F0162", +"X c #02B802E802C8", +"o c #037D026B0273", +"O c #048802AC02C1", +"+ c #055D031C0338", +"@ c #08D206B006B1", +"# c #14B10C350C95", +"$ c #20CA134E13E8", +"% c #216B13B71451", +"& c #230A14A51546", +"* c #2EDD2EF02D48", +"= c #3F0D25332654", +"- c #4EA039B73A18", +"; c #542530E9329F", +": c #4FBD4FDA4D09", +"> c #4FDD506B4D88", +", c #558351244ECB", +"< c #7CAF498E4BCC", +"1 c #7CF25FC15FA7", +"2 c #CB51C348BD5B", +"3 c #CF18CD55C654", +"4 c None", +/* pixels */ +"4444444444444444", +"4444444444444444", +"4444444444444444", +"44444 444444444", +"44444 444444444", +"4444 ,-@@ 44444", +"444 *321;& 44444", +"4444 ,>X%<#44444", +"44444 4 &= 4444", +"44444 44 O 4444", +"444444444 4444", +"444444444 44444", +"4444444444444444", +"4444444444444444", +"4444444444444444" +}; diff --git a/lib/widgets/qcomboview.cpp b/lib/widgets/qcomboview.cpp new file mode 100644 index 00000000..2cab4fea --- /dev/null +++ b/lib/widgets/qcomboview.cpp @@ -0,0 +1,1505 @@ +/********************************************************************** +** +** +** Implementation of QComboView widget class +** +** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +**********************************************************************/ + +#include "qcomboview.h" +#include <kdeversion.h> +#ifndef QT_NO_COMBOBOX +#include "qpopupmenu.h" +#include "qlistview.h" +#include "qpainter.h" +#include "qdrawutil.h" +#include "qstrlist.h" +#include "qpixmap.h" +#include "qtimer.h" +#include "qapplication.h" +#include "qlineedit.h" +#include "qbitmap.h" +#include "private/qeffects_p.h" +#include "qstringlist.h" +#include "qcombobox.h" +#include "qstyle.h" +#include "qheader.h" +#include <limits.h> + +class QComboViewData +{ +public: + QComboViewData( QComboView *cb ): current(0), lView( 0 ), combo( cb ) + { + duplicatesEnabled = TRUE; + cb->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) ); + } + + inline QListView * listView() { return lView; } + void updateLinedGeometry(); + + void setListView( QListView *l ) { lView = l ; + l->setMouseTracking( TRUE );} + + QListViewItem *current; + int maxCount; + int sizeLimit; + QComboView::Policy p; + bool autoresize; + bool poppedUp; + bool mouseWasInsidePopup; + bool arrowPressed; + bool arrowDown; + bool discardNextMousePress; + bool shortClick; + bool useCompletion; + bool completeNow; + int completeAt; + bool duplicatesEnabled; + int fullHeight, currHeight; + + QLineEdit * ed; // /bin/ed rules! + QTimer *completionTimer; + + QSize sizeHint; + +private: + bool usinglView; + QListView *lView; + QComboView *combo; + +}; + +void QComboViewData::updateLinedGeometry() +{ + if ( !ed || !combo ) + return; + QRect r = QStyle::visualRect( combo->style().querySubControlMetrics(QStyle::CC_ComboBox, combo, + QStyle::SC_ComboBoxEditField), combo ); + +// qWarning("updateLinedGeometry(): currentItem is %d", combo->currentItem() == 0 ? 0 : 1); + const QPixmap *pix = combo->currentItem() ? combo->currentItem()->pixmap(0) : 0; + if ( pix && pix->width() < r.width() ) + r.setLeft( r.left() + pix->width() + 4 ); + if ( r != ed->geometry() ) + ed->setGeometry( r ); +} + +static inline bool checkInsertIndex( const char *method, const char * name, + int count, int *index) +{ + bool range_err = (*index > count); +#if defined(QT_CHECK_RANGE) + if ( range_err ) + qWarning( "QComboView::%s: (%s) Index %d out of range", + method, name ? name : "<no name>", *index ); +#else + Q_UNUSED( method ) + Q_UNUSED( name ) +#endif + if ( *index < 0 ) // append + *index = count; + return !range_err; +} + + +static inline bool checkIndex( const char *method, const char * name, + int count, int index ) +{ + bool range_err = (index >= count); +#if defined(QT_CHECK_RANGE) + if ( range_err ) + qWarning( "QComboView::%s: (%s) Index %i out of range", + method, name ? name : "<no name>", index ); +#else + Q_UNUSED( method ) + Q_UNUSED( name ) +#endif + return !range_err; +} + + +/*! + Constructs a combobox with a maximum size and either Motif 2.0 or + Windows look and feel. + + The input field can be edited if \a rw is TRUE, otherwise the user + may only choose one of the items in the combobox. + + The \a parent and \a name arguments are passed on to the QWidget + constructor. +*/ + + +QComboView::QComboView( bool rw, QWidget *parent, const char *name ) + : QWidget( parent, name, WResizeNoErase ) +{ + d = new QComboViewData( this ); + setUpListView(); + + d->current = 0; + d->maxCount = INT_MAX; + setSizeLimit(10); + d->p = AtBottom; + d->autoresize = FALSE; + d->poppedUp = FALSE; + d->arrowDown = FALSE; + d->discardNextMousePress = FALSE; + d->shortClick = FALSE; + d->useCompletion = FALSE; + d->completeAt = 0; + d->completeNow = FALSE; + d->completionTimer = new QTimer( this ); + + setFocusPolicy( StrongFocus ); + + d->ed = 0; + if ( rw ) + setUpLineEdit(); + setBackgroundMode( PaletteButton, PaletteBase ); +} + + + +/*! + Destroys the combobox. +*/ + +QComboView::~QComboView() +{ + delete d; +} + +void QComboView::setDuplicatesEnabled( bool enable ) +{ + d->duplicatesEnabled = enable; +} + +bool QComboView::duplicatesEnabled() const +{ + return d->duplicatesEnabled; +} + +int QComboView::childCount() const +{ + return d->listView()->childCount(); +} + + +/*! + Removes all comboview items. +*/ + +void QComboView::clear() +{ + d->listView()->resize( 0, 0 ); + d->listView()->clear(); + + d->current = 0; + if ( d->ed ) { + d->ed->setText( QString::fromLatin1("") ); + d->updateLinedGeometry(); + } + currentChanged(); +} + +QListViewItem *QComboView::currentItem() const +{ + return d->current; +} + +void QComboView::setCurrentItem( QListViewItem *item ) +{ + if ( item == d->current && !d->ed ) { + return; + } + + if (!item) + { + d->current = 0; + if ( d->ed ) { +// d->ed->setText( "" ); + d->updateLinedGeometry(); + } + return; + } + + d->current = item; + d->completeAt = 0; + if ( d->ed ) { + d->ed->setText( item->text(0) ); +// qWarning("setCurrentItem( %s )", item->text(0).latin1()); + d->updateLinedGeometry(); + } + if ( d->listView() ) { + d->listView()->setCurrentItem( item ); + } else { + internalHighlight( item ); + // internalActivate( item ); ### this leads to weird behavior, as in 3.0.1 + } + + currentChanged(); + + d->listView()->ensureItemVisible(item); +} + +bool QComboView::autoResize() const +{ + return d->autoresize; +} + +void QComboView::setAutoResize( bool enable ) +{ + if ( (bool)d->autoresize != enable ) { + d->autoresize = enable; + if ( enable ) + adjustSize(); + } +} + + +/*! + reimp + + This implementation caches the size hint to avoid resizing when + the contents change dynamically. To invalidate the cached value + call setFont(). +*/ +QSize QComboView::sizeHint() const +{ + if ( isVisible() && d->sizeHint.isValid() ) + return d->sizeHint; + + constPolish(); +// int i, w; + QFontMetrics fm = fontMetrics(); + + int maxW = childCount() ? 18 : 7 * fm.width(QChar('x')) + 18; + int maxH = QMAX( fm.lineSpacing(), 14 ) + 2; + +/* for( i = 0; i < count(); i++ ) { + w = d->listView()->item( i )->width( d->listView() ); + if ( w > maxW ) + maxW = w; + } +*/ + d->sizeHint = (style().sizeFromContents(QStyle::CT_ComboBox, this, + QSize(maxW, maxH)).expandedTo(QApplication::globalStrut())); + + return d->sizeHint; +} + + +/*! + \internal + Receives activated signals from an internal popup list and emits + the activated() signal. +*/ + +void QComboView::internalActivate( QListViewItem * item ) +{ + if (!item) + { + d->current = 0; + if ( d->ed ) { +// d->ed->setText( "" ); + d->updateLinedGeometry(); + } + return; + } + popDownListView(); + d->poppedUp = FALSE; + + d->current = item; + + QString t( item->text(0) ); + if ( d->ed ) { + d->ed->setText( t ); +// qWarning("internalActivate( %s )", item->text(0).latin1()); + d->updateLinedGeometry(); + } + emit activated( item ); + emit activated( t ); + +// item->setOpen(true); +} + +/*! + \internal + Receives highlighted signals from an internal popup list and emits + the highlighted() signal. +*/ + +void QComboView::internalHighlight( QListViewItem * item ) +{ + if (!item) + { + d->current = 0; + if ( d->ed ) { +// d->ed->setText( "" ); + d->updateLinedGeometry(); + } + return; + } + emit highlighted( item ); + QString t = item->text(0); + if ( !t.isNull() ) + emit highlighted( t ); +} + +/*! + \internal + Receives timeouts after a click. Used to decide if a Motif style + popup should stay up or not after a click. +*/ +void QComboView::internalClickTimeout() +{ + d->shortClick = FALSE; +} + +/*! + Sets the palette for both the combobox button and the combobox + popup list to \a palette. +*/ + +void QComboView::setPalette( const QPalette &palette ) +{ + QWidget::setPalette( palette ); + if( d ) { + if(d->listView()) + d->listView()->setPalette( palette ); + } +} + +/*! + Sets the font for both the combobox button and the combobox popup + list to \a font. +*/ + +void QComboView::setFont( const QFont &font ) +{ + d->sizeHint = QSize(); // invalidate size hint + QWidget::setFont( font ); + d->listView()->setFont( font ); + if (d->ed) + d->ed->setFont( font ); + if ( d->autoresize ) + adjustSize(); +} + + +/*!reimp +*/ + +void QComboView::resizeEvent( QResizeEvent * e ) +{ + if ( d->ed ) + d->updateLinedGeometry(); + d->listView()->resize( width(), d->listView()->height() ); + QWidget::resizeEvent( e ); +} + +/*!reimp +*/ + +void QComboView::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + const QColorGroup & g = colorGroup(); + p.setPen(g.text()); + + QStyle::SFlags flags = QStyle::Style_Default; + if (isEnabled()) + flags |= QStyle::Style_Enabled; + if (hasFocus()) + flags |= QStyle::Style_HasFocus; + + if ( width() < 5 || height() < 5 ) { + qDrawShadePanel( &p, rect(), g, FALSE, 2, + &g.brush( QColorGroup::Button ) ); + return; + } + +// bool reverse = QApplication::reverseLayout(); + style().drawComplexControl( QStyle::CC_ComboBox, &p, this, rect(), g, + flags, QStyle::SC_All, + (d->arrowDown ? + QStyle::SC_ComboBoxArrow : + QStyle::SC_None )); + + QRect re = style().querySubControlMetrics( QStyle::CC_ComboBox, this, + QStyle::SC_ComboBoxEditField ); + re = QStyle::visualRect(re, this); + p.setClipRect( re ); + + if ( !d->ed ) { + QListViewItem * item = d->current; + if ( item ) { + // we calculate the QListBoxTexts height (ignoring strut) + int itemh = d->listView()->fontMetrics().lineSpacing() + 2; + p.translate( re.x(), re.y() + (re.height() - itemh)/2 ); + item->paintCell( &p, d->listView()->colorGroup(), 0, width(), AlignLeft | AlignVCenter ); + } + } else if ( d->listView() && d->listView()->currentItem( ) && d->current ) { + QListViewItem * item = d->current ; + const QPixmap *pix = item->pixmap(0); + if ( pix ) { + p.fillRect( re.x(), re.y(), pix->width() + 4, re.height(), + colorGroup().brush( QColorGroup::Base ) ); + p.drawPixmap( re.x() + 2, re.y() + + ( re.height() - pix->height() ) / 2, *pix ); + } + } + p.setClipping( FALSE ); +} + + +/*!reimp +*/ + +void QComboView::mousePressEvent( QMouseEvent *e ) +{ + if ( e->button() != LeftButton ) + return; + if ( d->discardNextMousePress ) { + d->discardNextMousePress = FALSE; + return; + } + QRect arrowRect = style().querySubControlMetrics( QStyle::CC_ComboBox, this, + QStyle::SC_ComboBoxArrow); + arrowRect = QStyle::visualRect(arrowRect, this); + + // Correction for motif style, where arrow is smaller + // and thus has a rect that doesn't fit the button. + arrowRect.setHeight( QMAX( height() - (2 * arrowRect.y()), arrowRect.height() ) ); + + if ( childCount() && ( !editable() || arrowRect.contains( e->pos() ) ) ) { + d->arrowPressed = FALSE; + listView()->blockSignals( TRUE ); + qApp->sendEvent( listView(), e ); // trigger the listbox's autoscroll + listView()->blockSignals( FALSE ); + popup(); + if ( arrowRect.contains( e->pos() ) ) { + d->arrowPressed = TRUE; + d->arrowDown = TRUE; + repaint( FALSE ); + } + QTimer::singleShot( 200, this, SLOT(internalClickTimeout())); + d->shortClick = TRUE; + } +} + +/*!reimp +*/ + +void QComboView::mouseMoveEvent( QMouseEvent * ) +{ +} + +/*!reimp +*/ + +void QComboView::mouseReleaseEvent( QMouseEvent * ) +{ +} + +/*!reimp +*/ + +void QComboView::mouseDoubleClickEvent( QMouseEvent *e ) +{ + mousePressEvent( e ); +} + + +/*!reimp +*/ + +void QComboView::keyPressEvent( QKeyEvent *e ) +{ + QListViewItem *c = currentItem(); + if ( ( e->key() == Key_F4 && e->state() == 0 ) || + ( e->key() == Key_Down && (e->state() & AltButton) ) || + ( !d->ed && e->key() == Key_Space ) ) { + if ( childCount() ) { + popup(); + } + return; + } else if ( e->key() == Key_Up ) { +/* if ((!c) && (listView()->firstChild())) + setCurrentItem(listView()->firstChild());*/ + if (c && c->itemAbove() ) + setCurrentItem( c->itemAbove() ); + else + return; + } else if ( e->key() == Key_Down ) { + if ((!c) && (listView()->firstChild())) + { + setCurrentItem(listView()->firstChild()); + return; + } + if ( c && c->itemBelow() ) + setCurrentItem( c->itemBelow() ); + else + return; + } else if ( e->key() == Key_Home && ( !d->ed || !d->ed->hasFocus() ) ) { + if (listView()->firstChild()) + setCurrentItem( listView()->firstChild() ); + else + return; + } else if ( e->key() == Key_End && ( !d->ed || !d->ed->hasFocus() ) ) { + if (listView()->lastItem()) + setCurrentItem( listView()->lastItem() ); + else + return; + } else if ( !d->ed && e->ascii() >= 32 && !e->text().isEmpty() ) { + if ( !d->completionTimer->isActive() ) { + d->completeAt = 0; + c = completionIndex( e->text(), c->itemBelow() ); + if ( c ) { + setCurrentItem( c ); + d->completeAt = e->text().length(); + } + else + return; + } else { + d->completionTimer->stop(); + QString ct = currentText().left( d->completeAt ) + e->text(); + c = completionIndex( ct, c ); + if ( c == 0 && d->completeAt > 0 ) { + c = completionIndex( e->text(), listView()->firstChild() ); + ct = e->text(); + } + d->completeAt = 0; + if ( c ) { + setCurrentItem( c ); + d->completeAt = ct.length(); + } + else + return; + } + d->completionTimer->start( 400, TRUE ); + } else { + e->ignore(); + return; + } + + c = currentItem(); + if ( childCount() && c && !c->text(0).isNull() ) + emit activated( c->text(0) ); + emit activated( c ); +} + +QString QComboView::currentText() const +{ + if ( d->ed ) + return d->ed->text(); + else if ( d->current ) + return currentItem()->text(0); + else + return QString::null; +} + +/*!reimp +*/ + +void QComboView::focusInEvent( QFocusEvent * e ) +{ + QWidget::focusInEvent( e ); + d->completeNow = FALSE; + d->completeAt = 0; + + emit focusGranted(); +} + +/*!reimp +*/ + +void QComboView::focusOutEvent( QFocusEvent * e ) +{ + QWidget::focusOutEvent( e ); + d->completeNow = FALSE; + d->completeAt = 0; + + emit focusLost(); +} + +/*!reimp +*/ + +void QComboView::wheelEvent( QWheelEvent *e ) +{ + if ( d->poppedUp ) { + QApplication::sendEvent( d->listView(), e ); + } else { + if ( e->delta() > 0 ) { + QListViewItem *c = currentItem(); + if ( c && c->itemAbove() ) { + setCurrentItem( c->itemAbove() ); + emit activated( currentItem() ); + emit activated( currentText() ); + } + } else { + QListViewItem *c = currentItem(); + if ( c && c->itemBelow() ) { + setCurrentItem( c->itemBelow() ); + emit activated( currentItem() ); + emit activated( currentText() ); + } + } + e->accept(); + } +} + +int childCount(QListViewItem *it) +{ + int count = 1; + QListViewItem * myChild = it->firstChild(); + while( myChild ) { + count += childCount(myChild); + myChild = myChild->nextSibling(); + } + return count; +} + +int childCount(QListView *lv) +{ + int count = 0; + QListViewItem * myChild = lv->firstChild(); + while( myChild ) { + count += childCount(myChild); +// count += 1; + myChild = myChild->nextSibling(); + } + return count; +} + +/*! + \internal + Calculates the listbox height needed to contain all items, or as + many as the list box is supposed to contain. +*/ +static int listHeight( QListView *l, int /*sl*/ ) +{ +/* if ( l->childCount() > 0 ) + return QMIN( l->childCount(), (uint)sl) * l->firstChild()->height(); + else*/ + + int prefH = 0; + int ch = childCount(l); + ch = QMIN(ch, 10); + if (l->firstChild()) + { + prefH = ch * l->firstChild()->height(); + } + else + prefH = l->sizeHint().height(); + + if (l->header()->isVisible()) + prefH += l->header()->sizeHint().height(); + +// return prefH < l->sizeHint().height() ? prefH : l->sizeHint().height(); + + return prefH+2; +} + +/*! + Pops up the combobox popup list. + + If the list is empty, no items appear. +*/ + +void QComboView::popup() +{ + if ( !childCount() ) + return; + + // Send all listbox events to eventFilter(): + QListView* lb = d->listView(); + lb->triggerUpdate( ); + lb->installEventFilter( this ); + lb->viewport()->installEventFilter( this ); + d->mouseWasInsidePopup = FALSE; +// int w = lb->variableWidth() ? lb->sizeHint().width() : width(); + int w = width(); + int h = listHeight( lb, d->sizeLimit ); + QRect screen = QApplication::desktop()->availableGeometry( const_cast<QComboView*>(this) ); + + int sx = screen.x(); // screen pos + int sy = screen.y(); + int sw = screen.width(); // screen width + int sh = screen.height(); // screen height + QPoint pos = mapToGlobal( QPoint(0,height()) ); + // ## Similar code is in QPopupMenu + int x = pos.x(); + int y = pos.y(); + + // the complete widget must be visible + if ( x + w > sx + sw ) + x = sx+sw - w; + if ( x < sx ) + x = sx; + if (y + h > sy+sh && y - h - height() >= 0 ) + y = y - h - height(); + QRect rect = + style().querySubControlMetrics( QStyle::CC_ComboBox, this, + QStyle::SC_ComboBoxListBoxPopup, + QStyleOption( x, y, w, h ) ); + if ( rect.isNull() ) + rect.setRect( x, y, w, h ); + lb->setGeometry( rect ); + + lb->raise(); + bool block = lb->signalsBlocked(); + lb->blockSignals( TRUE ); + QListViewItem *currentLBItem = d->current ; + lb->setCurrentItem( currentLBItem ); + // set the current item to also be the selected item if it isn't already + if ( currentLBItem && currentLBItem->isSelectable() && !currentLBItem->isSelected() ) + lb->setSelected( currentLBItem, TRUE ); + lb->blockSignals( block ); + lb->setVScrollBarMode(QScrollView::Auto); + +//#ifndef QT_NO_EFFECTS +/* if ( QApplication::isEffectEnabled( UI_AnimateCombo ) ) { + if ( lb->y() < mapToGlobal(QPoint(0,0)).y() ) + qScrollEffect( lb, QEffects::UpScroll ); + else + qScrollEffect( lb ); + } else*/ +//#endif + lb->show(); + d->poppedUp = TRUE; +} + + +/*! + reimp +*/ +void QComboView::updateMask() +{ + QBitmap bm( size() ); + bm.fill( color0 ); + + { + QPainter p( &bm, this ); + style().drawComplexControlMask(QStyle::CC_ComboBox, &p, this, rect()); + } + + setMask( bm ); +} + +/*! + \internal + Pops down (removes) the combobox popup list box. +*/ +void QComboView::popDownListView() +{ + d->listView()->removeEventFilter( this ); + d->listView()->viewport()->removeEventFilter( this ); + d->listView()->hide(); + d->listView()->setCurrentItem( d->current ); + if ( d->arrowDown ) { + d->arrowDown = FALSE; + repaint( FALSE ); + } + d->poppedUp = FALSE; +} + + +/*! + \internal + Re-indexes the identifiers in the popup list. +*/ + +void QComboView::reIndex() +{ +} + +/*! + \internal + Repaints the combobox. +*/ + +void QComboView::currentChanged() +{ + if ( d->autoresize ) + adjustSize(); + update(); +} + +/*! reimp + + \internal + + The event filter steals events from the popup or listbox when they + are popped up. It makes the popup stay up after a short click in + motif style. In windows style it toggles the arrow button of the + combobox field, and activates an item and takes down the listbox + when the mouse button is released. +*/ + +bool QComboView::eventFilter( QObject *object, QEvent *event ) +{ + if ( !event ) + return TRUE; + else if ( object == d->ed ) { + if ( event->type() == QEvent::KeyPress ) { + bool isAccepted = ( (QKeyEvent*)event )->isAccepted(); + keyPressEvent( (QKeyEvent *)event ); + if ( ((QKeyEvent *)event)->isAccepted() ) { + d->completeNow = FALSE; + return TRUE; + } else if ( ((QKeyEvent *)event)->key() != Key_End ) { + d->completeNow = TRUE; + d->completeAt = d->ed->cursorPosition(); + } + if ( isAccepted ) + ( (QKeyEvent*)event )->accept(); + else + ( (QKeyEvent*)event )->ignore(); + } else if ( event->type() == QEvent::KeyRelease ) { + d->completeNow = FALSE; + keyReleaseEvent( (QKeyEvent *)event ); + return ((QKeyEvent *)event)->isAccepted(); + } else if ( event->type() == QEvent::FocusIn ) { + focusInEvent( (QFocusEvent *)event ); + } else if ( event->type() == QEvent::FocusOut ) { + focusOutEvent( (QFocusEvent *)event ); + } else if ( d->useCompletion && d->completeNow ) { + if ( !d->ed->text().isNull() && + d->ed->cursorPosition() > d->completeAt && + d->ed->cursorPosition() == (int)d->ed->text().length() ) { + d->completeNow = FALSE; + QString ct( d->ed->text() ); + QListViewItem *i = completionIndex( ct, currentItem() ); + if ( i ) { + QString it = i->text(0); + d->ed->validateAndSet( it, ct.length(), + ct.length(), it.length() ); + } + } + } + } else if ( ( object == d->listView() || + object == d->listView()->viewport() )) { + QMouseEvent *e = (QMouseEvent*)event; + switch( event->type() ) { + case QEvent::MouseMove: + if ( !d->mouseWasInsidePopup ) { +// qWarning("!d->mouseWasInsidePopup"); + QPoint pos = e->pos(); + if ( d->listView()->rect().contains( pos ) ) + d->mouseWasInsidePopup = TRUE; + // Check if arrow button should toggle + if ( d->arrowPressed ) { + QPoint comboPos; + comboPos = mapFromGlobal( d->listView()->mapToGlobal(pos) ); + QRect arrowRect = + style().querySubControlMetrics( QStyle::CC_ComboBox, this, + QStyle::SC_ComboBoxArrow); + arrowRect = QStyle::visualRect(arrowRect, this); + if ( arrowRect.contains( comboPos ) ) { + if ( !d->arrowDown ) { + d->arrowDown = TRUE; + repaint( FALSE ); + } + } else { + if ( d->arrowDown ) { + d->arrowDown = FALSE; + repaint( FALSE ); + } + } + } + } else if ((e->state() & ( RightButton | LeftButton | MidButton ) ) == 0 && + style().styleHint(QStyle::SH_ComboBox_ListMouseTracking, this)) { +// qWarning("event filter:: emu"); + QWidget *mouseW = QApplication::widgetAt( e->globalPos(), TRUE ); +// if ( mouseW == d->listView()->viewport() ) { //### + if ( mouseW == d->listView()->viewport() ) { + QListViewItem *sel = d->listView()->itemAt(e->pos()); + if (sel) + { + d->listView()->setCurrentItem(sel); + d->listView()->setSelected(sel, true); + } + return TRUE; + } + } + + break; + case QEvent::MouseButtonRelease: + if ( d->listView()->rect().contains( e->pos() ) ) { + QMouseEvent tmp( QEvent::MouseButtonDblClick, + e->pos(), e->button(), e->state() ) ; + // will hide popup + QApplication::sendEvent( object, &tmp ); + return TRUE; + } else { + if ( d->mouseWasInsidePopup ) { + popDownListView(); + } else { + d->arrowPressed = FALSE; + if ( d->arrowDown ) { + d->arrowDown = FALSE; + repaint( FALSE ); + } + } + } + break; + case QEvent::MouseButtonDblClick: + case QEvent::MouseButtonPress: + if ( !d->listView()->rect().contains( e->pos() ) ) { + QPoint globalPos = d->listView()->mapToGlobal(e->pos()); + if ( QApplication::widgetAt( globalPos, TRUE ) == this ) { + d->discardNextMousePress = TRUE; + // avoid popping up again + } + popDownListView(); + return TRUE; + } + break; + case QEvent::KeyPress: + switch( ((QKeyEvent *)event)->key() ) { + case Key_Up: + case Key_Down: + if ( !(((QKeyEvent *)event)->state() & AltButton) ) + break; + case Key_F4: + case Key_Escape: + if ( d->poppedUp ) { + popDownListView(); + return TRUE; + } + break; + case Key_Enter: + case Key_Return: + // work around QDialog's enter handling + return FALSE; + default: + break; + } + break; + case QEvent::Hide: + popDownListView(); + break; + default: + break; + } + } + return QWidget::eventFilter( object, event ); +} + + +/*! + Returns the index of the first item \e after \a startingAt of + which \a prefix is a case-insensitive prefix. Returns -1 if no + items start with \a prefix. +*/ + +QListViewItem *QComboView::completionIndex( const QString & prefix, + QListViewItem *startingAt ) const +{ + QListViewItem *start = startingAt; +/* if ( start < 0 || start >= count() ) + start = 0; + if ( start >= count() ) + return -1;*/ + if (!start) + start = listView()->firstChild(); + if (!start) + return 0; +/* if (!start->itemBelow()) + return 0;*/ + QString match = prefix.lower(); + if ( match.length() < 1 ) + return start; + + QString current; + QListViewItem *i = start; + do { + current = i->text(0).lower(); + if ( current.startsWith( match ) ) + return i; + i = i->itemBelow(); + if ( i ) + i = listView()->firstChild(); + } while ( i != start ); + return 0; +} + + +int QComboView::sizeLimit() const +{ + return d ? d->sizeLimit : INT_MAX; +} + +void QComboView::setSizeLimit( int lines ) +{ + d->sizeLimit = lines; +} + + +/*int QComboView::maxCount() const +{ + return d ? d->maxCount : INT_MAX; +} + +void QComboView::setMaxCount( int count ) +{ + int l = this->count(); + while( --l > count ) + removeItem( l ); + d->maxCount = count; +} +*/ +QComboView::Policy QComboView::insertionPolicy() const +{ + return d->p; +} + +void QComboView::setInsertionPolicy( Policy policy ) +{ + d->p = policy; +} + + + +/*! + Internal slot to keep the line editor up to date. +*/ + +void QComboView::returnPressed() +{ + QString s( d->ed->text() ); + + if ( s.isEmpty() ) + return; + + QListViewItem *c = 0; + bool doInsert = TRUE; + if ( !d->duplicatesEnabled ) { + c = listView()->findItem(s, 0); + if ( c ) + doInsert = FALSE; + } + + if ( doInsert ) { + if ( insertionPolicy() != NoInsertion ) { +/* int cnt = count(); + while ( cnt >= d->maxCount ) { + removeItem( --cnt ); + }*/ + } + + switch ( insertionPolicy() ) { + case AtCurrent: + if ( s != currentItem()->text(0) ) + currentItem()->setText(0, s); + emit activated( currentItem() ); + emit activated( s ); + return; + case NoInsertion: + emit activated( s ); + return; + case AtTop: + c = 0; + return; +// break; + case AtBottom: + c = new QListViewItem(listView(), listView()->lastItem(), s); + break; + case BeforeCurrent: + if (currentItem() && currentItem()->itemAbove()) + c = new QListViewItem(listView(), currentItem()->itemAbove(), s); + else + { + c = 0; + return; + } + break; + case AfterCurrent: + if (currentItem() && currentItem()->itemBelow()) + c = new QListViewItem(listView(), currentItem()->itemBelow(), s); + else + { + c = 0; + return; + } + break; + } + } + + if (c) + { + setCurrentItem( c ); + emit activated( c ); + emit activated( s ); + } +} + + +/*! reimp +*/ + +void QComboView::setEnabled( bool enable ) +{ + QWidget::setEnabled( enable ); +} + + + +/*! + Applies the validator \a v to the combobox so that only text which + is valid according to \a v is accepted. + + This function does nothing if the combobox is not editable. + + \sa validator() clearValidator() QValidator +*/ + +void QComboView::setValidator( const QValidator * v ) +{ + if ( d && d->ed ) + d->ed->setValidator( v ); +} + + +/*! + Returns the validator which constrains editing for this combobox + if there is one; otherwise returns 0. + + \sa setValidator() clearValidator() QValidator +*/ + +const QValidator * QComboView::validator() const +{ + return d && d->ed ? d->ed->validator() : 0; +} + + +/*! + This slot is equivalent to setValidator( 0 ). +*/ + +void QComboView::clearValidator() +{ + if ( d && d->ed ) + d->ed->setValidator( 0 ); +} + + +/*! + Sets the combobox to use \a newListBox instead of the current list + box or popup. As a side effect, it clears the combobox of its + current contents. + + \warning QComboView assumes that newListBox->text(n) returns + non-null for 0 \<= n \< newListbox->count(). This assumption is + necessary because of the line edit in QComboView. +*/ + +void QComboView::setListView( QListView * newListView ) +{ + clear(); + + delete d->listView(); + + newListView->reparent( this, WType_Popup, QPoint(0,0), FALSE ); + d->setListView( newListView ); + d->listView()->setFont( font() ); + d->listView()->setPalette( palette() ); +/* d->listView()->setVScrollBarMode(QScrollView::AlwaysOff); + d->listView()->setHScrollBarMode(QScrollView::AlwaysOff);*/ + d->listView()->setFrameStyle( QFrame::Box | QFrame::Plain ); + d->listView()->setLineWidth( 1 ); +/* d->listView()->setRootIsDecorated( true ); + d->listView()->setAllColumnsShowFocus(true);*/ + d->listView()->resize( 100, 10 ); + + if (d->listView()->firstChild()) + d->current = d->listView()->firstChild(); + +// d->listView()->header()->hide(); + + +/* d->listView()->setFont( font() ); + d->listView()->setPalette( palette() ); + d->listView()->setVScrollBarMode( QScrollView::AlwaysOff ); + d->listView()->setHScrollBarMode( QScrollView::AlwaysOff ); + d->listView()->setFrameStyle( QFrame::Box | QFrame::Plain ); + d->listView()->setLineWidth( 1 ); + d->listView()->setRootIsDecorated( true ); + d->listView()->setAllColumnsShowFocus(true); + d->listView()->addColumn(""); + d->listView()->resize( 100, 10 ); +*/ + + connect( d->listView(), SIGNAL(returnPressed(QListViewItem*)), + SLOT(internalActivate(QListViewItem*))); + connect( d->listView(), SIGNAL(doubleClicked(QListViewItem*)), + SLOT(internalActivate(QListViewItem*))); + connect( d->listView(), SIGNAL(doubleClicked(QListViewItem*)), + SLOT(checkState(QListViewItem*))); + connect( d->listView(), SIGNAL(currentChanged(QListViewItem*)), + SLOT(internalHighlight(QListViewItem*))); + connect( d->listView(), SIGNAL(selectionChanged(QListViewItem*)), + SLOT(internalHighlight(QListViewItem*))); +} + + +/*! + Returns the current list box, or 0 if there is no list box. + (QComboView can use QPopupMenu instead of QListBox.) Provided to + match setlistView(). + + \sa setlistView() +*/ + +QListView * QComboView::listView() const +{ + return d ? d->listView() : 0; +} + +/*! + Returns the line edit, or 0 if there is no line edit. + + Only editable listboxes have a line editor. +*/ +QLineEdit* QComboView::lineEdit() const +{ + return d->ed; +} + + + +/*! + Clears the line edit without changing the combobox's contents. + Does nothing if the combobox isn't editable. + + This is particularly useful when using a combobox as a line edit + with history. For example you can connect the combobox's + activated() signal to clearEdit() in order to present the user + with a new, empty line as soon as Enter is pressed. + + \sa setEditText() +*/ + +void QComboView::clearEdit() +{ + if ( d && d->ed ) + d->ed->clear(); +} + + +/*! + Sets the text in the line edit to \a newText without changing the + combobox's contents. Does nothing if the combobox isn't editable. + + This is useful e.g. for providing a good starting point for the + user's editing and entering the change in the combobox only when + the user presses Enter. + + \sa clearEdit() insertItem() +*/ + +void QComboView::setEditText( const QString &newText ) +{ + if ( d && d->ed ) { + d->updateLinedGeometry(); + d->ed->setText( newText ); + } +} + +void QComboView::setAutoCompletion( bool enable ) +{ + d->useCompletion = enable; + d->completeNow = FALSE; +} + + +bool QComboView::autoCompletion() const +{ + return d->useCompletion; +} + +/*!reimp + */ +void QComboView::styleChange( QStyle& s ) +{ + d->sizeHint = QSize(); // invalidate size hint... + if ( d->ed ) + d->updateLinedGeometry(); + QWidget::styleChange( s ); +} + +bool QComboView::editable() const +{ + return d->ed != 0; +} + +void QComboView::setEditable( bool y ) +{ + if ( y == editable() ) + return; + if ( y ) { + setUpListView(); + setUpLineEdit(); + d->ed->show(); + if ( currentItem() ) + setEditText( currentText() ); + } else { + delete d->ed; + d->ed = 0; + } + + setFocusPolicy( StrongFocus ); + updateGeometry(); + update(); +} + + +void QComboView::setUpListView() +{ + d->setListView( new QListView( this, "in-combo", WType_Popup ) ); + + d->listView()->setFont( font() ); + d->listView()->setPalette( palette() ); +/* d->listView()->setVScrollBarMode( QScrollView::AlwaysOff ); + d->listView()->setHScrollBarMode( QScrollView::AlwaysOff );*/ + d->listView()->setFrameStyle( QFrame::Box | QFrame::Plain ); + d->listView()->setLineWidth( 1 ); + d->listView()->setRootIsDecorated( false ); + d->listView()->setAllColumnsShowFocus(true); + d->listView()->addColumn(""); + d->listView()->resize( 100, 10 ); + d->listView()->setResizeMode(QListView::LastColumn); + + if (d->listView()->firstChild()) + d->current = d->listView()->firstChild(); + + d->listView()->header()->hide(); + + connect( d->listView(), SIGNAL(returnPressed(QListViewItem*)), + SLOT(internalActivate(QListViewItem*))); + connect( d->listView(), SIGNAL(doubleClicked(QListViewItem*)), + SLOT(internalActivate(QListViewItem*))); + connect( d->listView(), SIGNAL(doubleClicked(QListViewItem*)), + SLOT(checkState(QListViewItem*))); + connect( d->listView(), SIGNAL(currentChanged(QListViewItem*)), + SLOT(internalHighlight(QListViewItem*))); + connect( d->listView(), SIGNAL(selectionChanged(QListViewItem*)), + SLOT(internalHighlight(QListViewItem*))); +} + + +void QComboView::setUpLineEdit() +{ + if ( !d->ed ) + setLineEdit( new QLineEdit( this, "combo edit" ) ); +} + +/*! + Sets the line edit to use \a edit instead of the current line edit. +*/ + +void QComboView::setLineEdit( QLineEdit *edit ) +{ + if ( !edit ) { +#if defined(QT_CHECK_NULL) + Q_ASSERT( edit != 0 ); +#endif + return; + } + + edit->setText( currentText() ); + if ( d->ed ) { + int start = 0, end = 0; + d->ed->getSelection( &start, &end ); + edit->setSelection( start, end ); + edit->setCursorPosition( d->ed->cursorPosition() ); + edit->setEdited( d->ed->edited() ); + delete d->ed; + } + + d->ed = edit; + + if ( edit->parent() != this ) { + edit->reparent( this, QPoint(0,0), FALSE ); + edit->setFont( font() ); + } + + connect (edit, SIGNAL( textChanged( const QString& ) ), + this, SIGNAL( textChanged( const QString& ) ) ); + connect( edit, SIGNAL(returnPressed()), SLOT(returnPressed()) ); + + edit->setFrame( FALSE ); + d->updateLinedGeometry(); + edit->installEventFilter( this ); + setFocusProxy( edit ); + setFocusPolicy( StrongFocus ); + + setUpListView(); + + if ( isVisible() ) + edit->show(); + + updateGeometry(); + update(); +} + +void QComboView::setCurrentText( const QString& txt ) +{ + QListViewItem *i; + i = listView()->findItem(txt, 0); + if ( i ) + setCurrentItem( i ); + else if ( d->ed ) + d->ed->setText( txt ); + else if (currentItem()) + currentItem()->setText(0, txt); +} + +void QComboView::checkState( QListViewItem * item) +{ + item->setOpen(!item->isOpen()); +} + +void QComboView::setCurrentActiveItem( QListViewItem * item ) +{ + if ( item == d->current && !d->ed ) { + return; + } + + d->current = item; + d->completeAt = 0; + if ( d->ed ) { + d->ed->setText( item->text(0) ); + d->ed->setCursorPosition(0); +// qWarning("setCurrentActiveItem( %s )", item->text(0).latin1()); + d->updateLinedGeometry(); + } + if ( d->listView() ) { + d->listView()->setCurrentItem( item ); + emit activated( item ); + emit activated( item->text(0) ); + } else { + internalHighlight( item ); + internalActivate( item ); + } + + currentChanged(); + + d->listView()->ensureItemVisible(item); +} + +#include "qcomboview.moc" + +#endif // QT_NO_COMBOBOX + diff --git a/lib/widgets/qcomboview.h b/lib/widgets/qcomboview.h new file mode 100644 index 00000000..8f618f50 --- /dev/null +++ b/lib/widgets/qcomboview.h @@ -0,0 +1,172 @@ +/********************************************************************** +** +** +** Definition of QComboView class +** +** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +**********************************************************************/ + +#ifndef QCOMBOVIEW_H +#define QCOMBOVIEW_H + +#ifndef QT_H +#include "qwidget.h" +#endif // QT_H + +#ifndef QT_NO_COMBOBOX + +/** +@file qcomboview.h +QComboView class. +*/ + +class QStrList; +class QStringList; +class QLineEdit; +class QValidator; +class QListView; +class QListViewItem; +class QComboViewData; + +/** +QComboView - a combo with a QListView as a popup widget. +This means that you can have a treeview inside of a combo. Otherwise it works +in the same way as QComboBox and have similar API. +*/ +class Q_EXPORT QComboView : public QWidget +{ + Q_OBJECT + Q_ENUMS( Policy ) + Q_PROPERTY( bool editable READ editable WRITE setEditable ) +// Q_PROPERTY( int count READ count ) + Q_PROPERTY( QString currentText READ currentText WRITE setCurrentText DESIGNABLE false ) +// Q_PROPERTY( QListView *currentItem READ currentItem WRITE setCurrentItem ) + Q_PROPERTY( bool autoResize READ autoResize WRITE setAutoResize DESIGNABLE false ) + Q_PROPERTY( int sizeLimit READ sizeLimit WRITE setSizeLimit ) +// Q_PROPERTY( int maxCount READ maxCount WRITE setMaxCount ) + Q_PROPERTY( Policy insertionPolicy READ insertionPolicy WRITE setInsertionPolicy ) + Q_PROPERTY( bool autoCompletion READ autoCompletion WRITE setAutoCompletion ) + Q_PROPERTY( bool duplicatesEnabled READ duplicatesEnabled WRITE setDuplicatesEnabled ) + Q_OVERRIDE( bool autoMask DESIGNABLE true SCRIPTABLE true ) + +public: +// QComboView( QWidget* parent=0, const char* name=0 ); + QComboView( bool rw, QWidget* parent=0, const char* name=0 ); + ~QComboView(); + + int childCount() const; + + QListViewItem *currentItem() const; + virtual void setCurrentItem( QListViewItem * ); + virtual void setCurrentActiveItem( QListViewItem * ); + + bool autoResize() const; + virtual void setAutoResize( bool ); + QSize sizeHint() const; + + void setPalette( const QPalette & ); + void setFont( const QFont & ); + void setEnabled( bool ); + + virtual void setSizeLimit( int ); + int sizeLimit() const; + +/* virtual void setMaxCount( int ); + int maxCount() const;*/ + + enum Policy { NoInsertion, AtTop, AtCurrent, AtBottom, + AfterCurrent, BeforeCurrent }; + + virtual void setInsertionPolicy( Policy policy ); + Policy insertionPolicy() const; + + virtual void setValidator( const QValidator * ); + const QValidator * validator() const; + + virtual void setListView( QListView * ); + QListView * listView() const; + + virtual void setLineEdit( QLineEdit *edit ); + QLineEdit* lineEdit() const; + + virtual void setAutoCompletion( bool ); + bool autoCompletion() const; + + bool eventFilter( QObject *object, QEvent *event ); + + void setDuplicatesEnabled( bool enable ); + bool duplicatesEnabled() const; + + bool editable() const; + void setEditable( bool ); + + virtual void popup(); + + QString currentText() const; + void setCurrentText( const QString& ); + +public slots: + virtual void clear(); + void clearValidator(); + void clearEdit(); + virtual void setEditText( const QString &); + +signals: + void activated( QListViewItem * item ); + void highlighted( QListViewItem * item ); + void activated( const QString &); + void highlighted( const QString &); + void textChanged( const QString &); + void focusGranted(); + void focusLost(); + +private slots: + void internalActivate( QListViewItem * ); + void internalHighlight( QListViewItem * ); + void internalClickTimeout(); + void returnPressed(); + void checkState(QListViewItem*); + +protected: + void paintEvent( QPaintEvent * ); + void resizeEvent( QResizeEvent * ); + void mousePressEvent( QMouseEvent * ); + void mouseMoveEvent( QMouseEvent * ); + void mouseReleaseEvent( QMouseEvent * ); + void mouseDoubleClickEvent( QMouseEvent * ); + void keyPressEvent( QKeyEvent *e ); + void focusInEvent( QFocusEvent *e ); + void focusOutEvent( QFocusEvent *e ); + void wheelEvent( QWheelEvent *e ); + void styleChange( QStyle& ); + + void updateMask(); + +private: + virtual void setUpListView(); + void setUpLineEdit(); + void popDownListView(); + void reIndex(); + void currentChanged(); + QListViewItem *completionIndex( const QString &, QListViewItem * ) const; + + QComboViewData *d; + +private: // Disabled copy constructor and operator= +#if defined(Q_DISABLE_COPY) + QComboView( const QComboView & ); + QComboView &operator=( const QComboView & ); +#endif +}; + + +#endif // QT_NO_COMBOBOX + +#endif // QCOMBOVIEW_H diff --git a/lib/widgets/resizablecombo.cpp b/lib/widgets/resizablecombo.cpp new file mode 100644 index 00000000..436125a9 --- /dev/null +++ b/lib/widgets/resizablecombo.cpp @@ -0,0 +1,98 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include "resizablecombo.h" + +#include "kcomboview.h" + +#include <qevent.h> +#include <qlayout.h> +#include <qpixmap.h> +#include <qapplication.h> +#include <qwhatsthis.h> + +#include <klocale.h> + +static const char * resize_xpm[] = { +"9 18 2 1", +" c None", +". c #000000", +" . ", +" ", +" . ", +" ", +" . ", +" ", +" . . . ", +" .. .. ", +".........", +" .. .. ", +" . . . ", +" ", +" . ", +" ", +" . ", +" ", +" . ", +" "}; + +ResizableCombo::ResizableCombo(KComboView *view, QWidget *parent, const char *name): + QWidget(parent, name), m_sizer(0), m_combo(view) +{ + QHBoxLayout *l = new QHBoxLayout(this); + view->reparent(this, QPoint(0,0)); + l->addWidget(view); + + m_sizer = new MyPushButton(this); + m_sizer->setPixmap(QPixmap(resize_xpm)); + QWhatsThis::add(m_sizer, i18n("Drag this to resize the combobox.")); + l->addWidget(m_sizer); +} + +void MyPushButton::mousePressEvent( QMouseEvent * e ) +{ + m_resizing = true; + m_pressedPos = e->globalPos(); + m_width = m_combo->m_combo->width(); + QPushButton::mousePressEvent(e); +} + +void MyPushButton::mouseReleaseEvent( QMouseEvent * e ) +{ + m_resizing = false; + QPushButton::mouseReleaseEvent(e); +} + +void MyPushButton::mouseMoveEvent( QMouseEvent * e ) +{ + if (m_resizing) + m_combo->m_combo->setMinimumWidth(m_width + e->globalPos().x() - pressedPos().x()); + + QPushButton::mouseMoveEvent(e); +} + +MyPushButton::MyPushButton( ResizableCombo * parent, const char * name ) + :QPushButton(parent, name), m_resizing(false), m_combo(parent) +{ + setFocusPolicy(NoFocus); + setFlat(true); + m_width = m_combo->m_combo->width(); +} + + +#include "resizablecombo.moc" diff --git a/lib/widgets/resizablecombo.h b/lib/widgets/resizablecombo.h new file mode 100644 index 00000000..587712d0 --- /dev/null +++ b/lib/widgets/resizablecombo.h @@ -0,0 +1,72 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef RESIZABLECOMBO_H +#define RESIZABLECOMBO_H + +#include <qpushbutton.h> +#include <qpoint.h> + +class KComboView; +class QMouseEvent; +class MyPushButton; + +/** +@file resizablecombo.h +Resizable combo box. +*/ + +/** +Resizable combo box. +Used to place resizable KComboBox onto toolbars. +*/ +class ResizableCombo: public QWidget{ + Q_OBJECT +public: + ResizableCombo(KComboView *view, QWidget *parent = 0, const char *name = 0); + +private: + MyPushButton *m_sizer; + KComboView *m_combo; + +friend class MyPushButton; +}; + +class MyPushButton: public QPushButton +{ +public: + MyPushButton(ResizableCombo *parent = 0, const char *name = 0 ); + + QPoint pressedPos() + { + return m_pressedPos; + } + +protected: + virtual void mouseReleaseEvent ( QMouseEvent * e ); + virtual void mousePressEvent ( QMouseEvent * e ); + virtual void mouseMoveEvent ( QMouseEvent * e ); + +private: + bool m_resizing; + QPoint m_pressedPos; + int m_width; + ResizableCombo *m_combo; +}; + +#endif diff --git a/lib/widgets/sticky.xpm b/lib/widgets/sticky.xpm new file mode 100644 index 00000000..f6c5c5af --- /dev/null +++ b/lib/widgets/sticky.xpm @@ -0,0 +1,13 @@ +/* XPM */ +static const char * const sticky[] = { +/* width height num_colors chars_per_pixel */ +" 4 4 2 1", +/* colors */ +". c #ffffff", +"x c #000000", +/* pixels */ +".xx.", +"xxxx", +"xxxx", +".xx." +}; |