From 8362bf63dea22bbf6736609b0f49c152f975eb63 Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 20 Jan 2010 01:29:50 +0000 Subject: Added old abandoned KDE3 version of koffice git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- lib/koproperty/Makefile.am | 22 + lib/koproperty/TODO | 8 + lib/koproperty/cr16-action-button_no.png | Bin 0 -> 1165 bytes lib/koproperty/customproperty.cpp | 376 +++++++++++ lib/koproperty/customproperty.h | 123 ++++ lib/koproperty/editor.cpp | 1027 +++++++++++++++++++++++++++++ lib/koproperty/editor.h | 188 ++++++ lib/koproperty/editoritem.cpp | 619 +++++++++++++++++ lib/koproperty/editoritem.h | 129 ++++ lib/koproperty/editors/Makefile.am | 13 + lib/koproperty/editors/booledit.cpp | 213 ++++++ lib/koproperty/editors/booledit.h | 77 +++ lib/koproperty/editors/coloredit.cpp | 96 +++ lib/koproperty/editors/coloredit.h | 56 ++ lib/koproperty/editors/combobox.cpp | 199 ++++++ lib/koproperty/editors/combobox.h | 59 ++ lib/koproperty/editors/cursoredit.cpp | 138 ++++ lib/koproperty/editors/cursoredit.h | 50 ++ lib/koproperty/editors/dateedit.cpp | 89 +++ lib/koproperty/editors/dateedit.h | 56 ++ lib/koproperty/editors/datetimeedit.cpp | 89 +++ lib/koproperty/editors/datetimeedit.h | 56 ++ lib/koproperty/editors/dummywidget.cpp | 63 ++ lib/koproperty/editors/dummywidget.h | 53 ++ lib/koproperty/editors/fontedit.cpp | 156 +++++ lib/koproperty/editors/fontedit.h | 57 ++ lib/koproperty/editors/linestyledit.cpp | 225 +++++++ lib/koproperty/editors/linestyleedit.h | 55 ++ lib/koproperty/editors/pixmapedit.cpp | 247 +++++++ lib/koproperty/editors/pixmapedit.h | 72 ++ lib/koproperty/editors/pointedit.cpp | 91 +++ lib/koproperty/editors/pointedit.h | 56 ++ lib/koproperty/editors/rectedit.cpp | 92 +++ lib/koproperty/editors/rectedit.h | 55 ++ lib/koproperty/editors/sizeedit.cpp | 91 +++ lib/koproperty/editors/sizeedit.h | 55 ++ lib/koproperty/editors/sizepolicyedit.cpp | 122 ++++ lib/koproperty/editors/sizepolicyedit.h | 59 ++ lib/koproperty/editors/spinbox.cpp | 329 +++++++++ lib/koproperty/editors/spinbox.h | 117 ++++ lib/koproperty/editors/stringedit.cpp | 74 +++ lib/koproperty/editors/stringedit.h | 53 ++ lib/koproperty/editors/stringlistedit.cpp | 111 ++++ lib/koproperty/editors/stringlistedit.h | 60 ++ lib/koproperty/editors/symbolcombo.cpp | 122 ++++ lib/koproperty/editors/symbolcombo.h | 58 ++ lib/koproperty/editors/timeedit.cpp | 87 +++ lib/koproperty/editors/timeedit.h | 55 ++ lib/koproperty/editors/urledit.cpp | 96 +++ lib/koproperty/editors/urledit.h | 55 ++ lib/koproperty/factory.cpp | 265 ++++++++ lib/koproperty/factory.h | 168 +++++ lib/koproperty/koproperty_global.h | 29 + lib/koproperty/property.cpp | 778 ++++++++++++++++++++++ lib/koproperty/property.h | 443 +++++++++++++ lib/koproperty/set.cpp | 535 +++++++++++++++ lib/koproperty/set.h | 254 +++++++ lib/koproperty/test/Makefile.am | 17 + lib/koproperty/test/main.cpp | 68 ++ lib/koproperty/test/test.cpp | 126 ++++ lib/koproperty/test/test.h | 47 ++ lib/koproperty/utils.h | 49 ++ lib/koproperty/widget.cpp | 232 +++++++ lib/koproperty/widget.h | 120 ++++ lib/koproperty/widgetproxy.cpp | 125 ++++ lib/koproperty/widgetproxy.h | 63 ++ 66 files changed, 9768 insertions(+) create mode 100644 lib/koproperty/Makefile.am create mode 100644 lib/koproperty/TODO create mode 100644 lib/koproperty/cr16-action-button_no.png create mode 100644 lib/koproperty/customproperty.cpp create mode 100644 lib/koproperty/customproperty.h create mode 100644 lib/koproperty/editor.cpp create mode 100644 lib/koproperty/editor.h create mode 100644 lib/koproperty/editoritem.cpp create mode 100644 lib/koproperty/editoritem.h create mode 100644 lib/koproperty/editors/Makefile.am create mode 100644 lib/koproperty/editors/booledit.cpp create mode 100644 lib/koproperty/editors/booledit.h create mode 100644 lib/koproperty/editors/coloredit.cpp create mode 100644 lib/koproperty/editors/coloredit.h create mode 100644 lib/koproperty/editors/combobox.cpp create mode 100644 lib/koproperty/editors/combobox.h create mode 100644 lib/koproperty/editors/cursoredit.cpp create mode 100644 lib/koproperty/editors/cursoredit.h create mode 100644 lib/koproperty/editors/dateedit.cpp create mode 100644 lib/koproperty/editors/dateedit.h create mode 100644 lib/koproperty/editors/datetimeedit.cpp create mode 100644 lib/koproperty/editors/datetimeedit.h create mode 100644 lib/koproperty/editors/dummywidget.cpp create mode 100644 lib/koproperty/editors/dummywidget.h create mode 100644 lib/koproperty/editors/fontedit.cpp create mode 100644 lib/koproperty/editors/fontedit.h create mode 100644 lib/koproperty/editors/linestyledit.cpp create mode 100644 lib/koproperty/editors/linestyleedit.h create mode 100644 lib/koproperty/editors/pixmapedit.cpp create mode 100644 lib/koproperty/editors/pixmapedit.h create mode 100644 lib/koproperty/editors/pointedit.cpp create mode 100644 lib/koproperty/editors/pointedit.h create mode 100644 lib/koproperty/editors/rectedit.cpp create mode 100644 lib/koproperty/editors/rectedit.h create mode 100644 lib/koproperty/editors/sizeedit.cpp create mode 100644 lib/koproperty/editors/sizeedit.h create mode 100644 lib/koproperty/editors/sizepolicyedit.cpp create mode 100644 lib/koproperty/editors/sizepolicyedit.h create mode 100644 lib/koproperty/editors/spinbox.cpp create mode 100644 lib/koproperty/editors/spinbox.h create mode 100644 lib/koproperty/editors/stringedit.cpp create mode 100644 lib/koproperty/editors/stringedit.h create mode 100644 lib/koproperty/editors/stringlistedit.cpp create mode 100644 lib/koproperty/editors/stringlistedit.h create mode 100644 lib/koproperty/editors/symbolcombo.cpp create mode 100644 lib/koproperty/editors/symbolcombo.h create mode 100644 lib/koproperty/editors/timeedit.cpp create mode 100644 lib/koproperty/editors/timeedit.h create mode 100644 lib/koproperty/editors/urledit.cpp create mode 100644 lib/koproperty/editors/urledit.h create mode 100644 lib/koproperty/factory.cpp create mode 100644 lib/koproperty/factory.h create mode 100644 lib/koproperty/koproperty_global.h create mode 100644 lib/koproperty/property.cpp create mode 100644 lib/koproperty/property.h create mode 100644 lib/koproperty/set.cpp create mode 100644 lib/koproperty/set.h create mode 100644 lib/koproperty/test/Makefile.am create mode 100644 lib/koproperty/test/main.cpp create mode 100644 lib/koproperty/test/test.cpp create mode 100644 lib/koproperty/test/test.h create mode 100644 lib/koproperty/utils.h create mode 100644 lib/koproperty/widget.cpp create mode 100644 lib/koproperty/widget.h create mode 100644 lib/koproperty/widgetproxy.cpp create mode 100644 lib/koproperty/widgetproxy.h (limited to 'lib/koproperty') diff --git a/lib/koproperty/Makefile.am b/lib/koproperty/Makefile.am new file mode 100644 index 00000000..654debd3 --- /dev/null +++ b/lib/koproperty/Makefile.am @@ -0,0 +1,22 @@ +INCLUDES = -I$(srcdir)/editors -I$(top_srcdir)/lib/kofficecore $(all_includes) + +lib_LTLIBRARIES = libkoproperty.la + +libkoproperty_la_LIBADD = $(LIB_KDEUI) ./editors/libkopropertyeditors.la +libkoproperty_la_LDFLAGS = -no-undefined $(all_libraries) -version-info 2:0:0 +libkoproperty_la_SOURCES = property.cpp customproperty.cpp set.cpp editor.cpp \ + editoritem.cpp factory.cpp widget.cpp + +METASOURCES = AUTO + +SUBDIRS = editors . test + + +icondir = $(kde_datadir)/koffice/icons +icon_ICON = button_no + +EXTRA_DIST = $(icon_ICON) + +messages: +# $(EXTRACTRC) */*.rc */*.ui > rc.cpp + $(XGETTEXT) *.cpp editors/*.cpp -o $(podir)/koproperty.pot diff --git a/lib/koproperty/TODO b/lib/koproperty/TODO new file mode 100644 index 00000000..60888749 --- /dev/null +++ b/lib/koproperty/TODO @@ -0,0 +1,8 @@ +KOProperty Library TODOs +------------------------ + +General +- more powerful editors + +PixmapEdit +- add copy/cut/paste/delete actions diff --git a/lib/koproperty/cr16-action-button_no.png b/lib/koproperty/cr16-action-button_no.png new file mode 100644 index 00000000..9f29ee21 Binary files /dev/null and b/lib/koproperty/cr16-action-button_no.png differ diff --git a/lib/koproperty/customproperty.cpp b/lib/koproperty/customproperty.cpp new file mode 100644 index 00000000..700baa79 --- /dev/null +++ b/lib/koproperty/customproperty.cpp @@ -0,0 +1,376 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "customproperty.h" +#include "property.h" + +#include +#include +#include +#include + +#include +#include + +using namespace KoProperty; + +CustomProperty::CustomProperty(Property *parent) + : m_property(parent) +{ +} + +CustomProperty::~CustomProperty() +{ +} + +void +CustomProperty::emitPropertyChanged() +{ + m_property->emitPropertyChanged(); +} + +/////////////// SizeCustomProperty ///////////////////// + +SizeCustomProperty::SizeCustomProperty(Property *property) +: CustomProperty(property) +{ + if(property && (property->type() == Size) ) { + QSize s = property->value().toSize(); + new Property("width", s.width(), i18n("Width"), i18n("Width"), Size_Width, property); + new Property("height", s.height(), i18n("Height"), i18n("Height"), Size_Height, property); + } +} + +SizeCustomProperty::~SizeCustomProperty() +{} + +bool +SizeCustomProperty::handleValue() const +{ + if(!m_property) + return false; + + switch(m_property->type()) { + case Size_Width: case Size_Height: + return true; + default: + return false; + } +} + +void +SizeCustomProperty::setValue(const QVariant &value, bool rememberOldValue) +{ + if(!m_property) + return; + + if(m_property->parent()) { + QSize s = m_property->parent()->value().toSize(); + + if(m_property->type() == Size_Height) + s.setHeight(value.toInt()); + else if(m_property->type() == Size_Width) + s.setWidth(value.toInt()); + + m_property->parent()->setValue(s, true, false); + } + else{ + QSize s = value.toSize(); + m_property->child("width")->setValue(s.width(), rememberOldValue, false); + m_property->child("height")->setValue(s.height(), rememberOldValue, false); + } +} + +QVariant +SizeCustomProperty::value() const +{ + if(!m_property || !m_property->parent()) + return QVariant(); + + if(m_property->type() == Size_Height) + return m_property->parent()->value().toSize().height(); + else if(m_property->type() == Size_Width) + return m_property->parent()->value().toSize().width(); + + return QVariant(); +} + +/////////////// PointCustomProperty ///////////////////// + +PointCustomProperty::PointCustomProperty(Property *property) +: CustomProperty(property) +{ + if(property && (property->type() == Point) ) { + QPoint p = property->value().toPoint(); + new Property("x", p.x(), i18n("X"), i18n("X"), Point_X, property); + new Property("y", p.y(), i18n("Y"), i18n("Y"), Point_Y, property); + } +} + +PointCustomProperty::~PointCustomProperty() +{} + +bool +PointCustomProperty::handleValue() const +{ + if(!m_property) + return false; + + switch(m_property->type()) { + case Point_X: case Point_Y: + return true; + default: + return false; + } +} + +void +PointCustomProperty::setValue(const QVariant &value, bool rememberOldValue) +{ + if(!m_property) + return; + + if(m_property->parent()) { + QPoint p = m_property->parent()->value().toPoint(); + + if(m_property->type() == Point_X) + p.setX(value.toInt()); + else if(m_property->type() == Point_Y) + p.setY(value.toInt()); + + m_property->parent()->setValue(p, true, false); + } + else { + QPoint p = value.toPoint(); + m_property->child("x")->setValue(p.x(), rememberOldValue, false); + m_property->child("y")->setValue(p.y(), rememberOldValue, false); + } +} + +QVariant +PointCustomProperty::value() const +{ + if(!m_property || !m_property->parent()) + return QVariant(); + + if(m_property->type() == Point_X) + return m_property->parent()->value().toPoint().x(); + else if(m_property->type() == Point_Y) + return m_property->parent()->value().toPoint().y(); + + return QVariant(); +} + +/////////////// RectCustomProperty ///////////////////// + +RectCustomProperty::RectCustomProperty(Property *property) +: CustomProperty(property) +{ + if(property && (property->type() == Rect) ) { + QRect r = property->value().toRect(); + new Property("x", r.x(), i18n("X"), i18n("X"), Rect_X, property); + new Property("y", r.y(), i18n("Y"), i18n("Y"), Rect_Y, property); + new Property("width", r.width(), i18n("Width"), i18n("Width"), Rect_Width, property); + new Property("height", r.height(), i18n("Height"), i18n("Height"), Rect_Height, property); + } +} + +RectCustomProperty::~RectCustomProperty() +{} + +bool +RectCustomProperty::handleValue() const +{ + if(!m_property) + return false; + + switch(m_property->type()) { + case Rect_X: case Rect_Y: case Rect_Width: case Rect_Height: + return true; + default: + return false; + } +} + +void +RectCustomProperty::setValue(const QVariant &value, bool rememberOldValue) +{ + if(!m_property) + return; + + if(m_property->parent()) { + QRect r = m_property->parent()->value().toRect(); + + if(m_property->type() == Rect_X) { + //changing x component of Rect shouldn't change width + const int delta = value.toInt() - r.x(); + r.setX(value.toInt()); + r.setWidth(r.width()+delta); + } + else if(m_property->type() == Rect_Y) { + //changing y component of Rect shouldn't change height + const int delta = value.toInt() - r.y(); + r.setY(value.toInt()); + r.setHeight(r.height()+delta); + } + else if(m_property->type() == Rect_Width) + r.setWidth(value.toInt()); + else if(m_property->type() == Rect_Height) + r.setHeight(value.toInt()); + + m_property->parent()->setValue(r, true, false); + } + else { + QRect r = value.toRect(); + m_property->child("x")->setValue(r.x(), rememberOldValue, false); + m_property->child("y")->setValue(r.y(), rememberOldValue, false); + m_property->child("width")->setValue(r.width(), rememberOldValue, false); + m_property->child("height")->setValue(r.height(), rememberOldValue, false); + } +} + +QVariant +RectCustomProperty::value() const +{ + if(!m_property || !m_property->parent()) + return QVariant(); + + if(m_property->type() == Rect_X) + return m_property->parent()->value().toRect().x(); + else if(m_property->type() == Rect_Y) + return m_property->parent()->value().toRect().y(); + else if(m_property->type() == Rect_Width) + return m_property->parent()->value().toRect().width(); + else if(m_property->type() == Rect_Height) + return m_property->parent()->value().toRect().height(); + + return QVariant(); +} + + +/////////////// SizePolicyCustomProperty ///////////////////// + +SizePolicyCustomProperty::SizePolicyCustomProperty(Property *property) +: CustomProperty(property) +{ + if(property && (property->type() == SizePolicy) ) { +// QMap spValues; + QValueList keys; + keys << QSizePolicy::Fixed + << QSizePolicy::Minimum + << QSizePolicy::Maximum + << QSizePolicy::Preferred + << QSizePolicy::Expanding + << QSizePolicy::MinimumExpanding + << QSizePolicy::Ignored; + QStringList strings; + strings << i18n("Size Policy", "Fixed") + << i18n("Size Policy", "Minimum") + << i18n("Size Policy", "Maximum") + << i18n("Size Policy", "Preferred") + << i18n("Size Policy", "Expanding") + << i18n("Size Policy", "Minimum Expanding") + << i18n("Size Policy", "Ignored"); + + new Property("hSizeType", new Property::ListData(keys, strings), + (int)property->value().toSizePolicy().horData(), + i18n("Horz. Size Type"),i18n("Horizontal Size Type"), + SizePolicy_HorData, property); + new Property("vSizeType", new Property::ListData(keys, strings), + (int)property->value().toSizePolicy().verData(), + i18n("Vert. Size Type"), i18n("Vertical Size Type"), + SizePolicy_VerData, property); + new Property("hStretch", + property->value().toSizePolicy().horStretch(), + i18n("Horz. Stretch"), i18n("Horizontal Stretch"), + SizePolicy_HorStretch, property); + new Property("vStretch", + property->value().toSizePolicy().verStretch(), + i18n("Vert. Stretch"), i18n("Vertical Stretch"), + SizePolicy_VerStretch, property); + } +} + +SizePolicyCustomProperty::~SizePolicyCustomProperty() +{ +} + +bool +SizePolicyCustomProperty::handleValue() const +{ + if(!m_property) + return false; + + switch(m_property->type()) { + case SizePolicy_HorData: + case SizePolicy_VerData: + case SizePolicy_HorStretch: + case SizePolicy_VerStretch: + return true; + default: + return false; + } +} + +void +SizePolicyCustomProperty::setValue(const QVariant &value, bool rememberOldValue) +{ + if(!m_property) + return; + + if(m_property->parent()) { + QSizePolicy v = m_property->parent()->value().toSizePolicy(); + + if(m_property->type() == SizePolicy_HorData) + v.setHorData(QSizePolicy::SizeType(value.toInt())); + else if(m_property->type() == SizePolicy_VerData) + v.setVerData(QSizePolicy::SizeType(value.toInt())); + else if(m_property->type() == SizePolicy_HorStretch) + v.setHorStretch(value.toInt()); + else if(m_property->type() == SizePolicy_VerStretch) + v.setVerStretch(value.toInt()); + + m_property->parent()->setValue(v, true, false); + } + else { + QSizePolicy v = value.toSizePolicy(); + m_property->child("hSizeType")->setValue(v.horData(), rememberOldValue, false); + m_property->child("vSizeType")->setValue(v.verData(), rememberOldValue, false); + m_property->child("hStretch")->setValue(v.horStretch(), rememberOldValue, false); + m_property->child("vStretch")->setValue(v.verStretch(), rememberOldValue, false); + } +} + +QVariant +SizePolicyCustomProperty::value() const +{ + if(!m_property || !m_property->parent()) + return QVariant(); + + if(m_property->type() == SizePolicy_HorData) + return m_property->parent()->value().toSizePolicy().horData(); + else if(m_property->type() == SizePolicy_VerData) + return m_property->parent()->value().toSizePolicy().verData(); + else if(m_property->type() == SizePolicy_HorStretch) + return m_property->parent()->value().toSizePolicy().horStretch(); + else if(m_property->type() == SizePolicy_VerStretch) + return m_property->parent()->value().toSizePolicy().verStretch(); + + return QVariant(); +} diff --git a/lib/koproperty/customproperty.h b/lib/koproperty/customproperty.h new file mode 100644 index 00000000..dff3e990 --- /dev/null +++ b/lib/koproperty/customproperty.h @@ -0,0 +1,123 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_CUSTOMPROPERTY_H +#define KPROPERTY_CUSTOMPROPERTY_H + +#include "koproperty_global.h" + +class QVariant; + +namespace KoProperty { + +class Property; + +//! \brief Base class for custom properties +/*! You will need to subclass CustomProperty to override the behaviour of a property type.\n + In the constructor, you should create the child properties (if needed). + Then, you need to implement the functions concerning values.\n + + Examples of custom properties implementation can be found in customproperty.cpp. + + \author Cedric Pasteur +*/ +class KOPROPERTY_EXPORT CustomProperty +{ + public: + CustomProperty(Property *parent); + virtual ~CustomProperty(); + + /*! This function is called by \ref Property::setValue() when + a custom property is set. + You don't have to modify the property value, it is done by Property class. + You just have to update child or parent properties value (m_property->parent()->setValue()). + Note that, when calling Property::setValue, you need to set + useCustomProperty (3rd parameter) to false, or there will be infinite recursion. */ + virtual void setValue(const QVariant &value, bool rememberOldValue) = 0; + + /*! This function is called by \ref Property::value() when + a custom property is set and \ref handleValue() is true. + You should return property's value, taken from parent's value.*/ + virtual QVariant value() const = 0; + + /*! Tells whether CustomProperty should be used to get the property's value. + CustomProperty::setValue() will always be called. But if hadleValue() == true, + then the value stored in the Property won't be changed. + You should return true for child properties, and false for others. */ + virtual bool handleValue() const { return false; } + + protected: + Property *m_property; + + /*! This method emits the \a Set::propertyChanged() signal for all + sets our parent-property is registered in. */ + void emitPropertyChanged(); +}; + +//! \brief Custom property implementation for QSize type +class KOPROPERTY_EXPORT SizeCustomProperty : public CustomProperty +{ + public: + SizeCustomProperty(Property *parent); + ~SizeCustomProperty(); + + void setValue(const QVariant &value, bool rememberOldValue); + QVariant value() const; + bool handleValue() const; +}; + +//! \brief Custom property implementation for QPoint type +class KOPROPERTY_EXPORT PointCustomProperty : public CustomProperty +{ + public: + PointCustomProperty(Property *parent); + ~PointCustomProperty(); + + void setValue(const QVariant &value, bool rememberOldValue); + QVariant value() const; + bool handleValue() const; +}; + +//! \brief Custom property implementation for QRect type +class KOPROPERTY_EXPORT RectCustomProperty : public CustomProperty +{ + public: + RectCustomProperty(Property *parent); + ~RectCustomProperty(); + + void setValue(const QVariant &value, bool rememberOldValue); + QVariant value() const; + bool handleValue() const; +}; + +//! \brief Custom property implementation for QSizePolicy type +class KOPROPERTY_EXPORT SizePolicyCustomProperty : public CustomProperty +{ + public: + SizePolicyCustomProperty(Property *parent); + ~SizePolicyCustomProperty(); + + void setValue(const QVariant &value, bool rememberOldValue); + QVariant value() const; + bool handleValue() const; +}; + +} + +#endif diff --git a/lib/koproperty/editor.cpp b/lib/koproperty/editor.cpp new file mode 100644 index 00000000..3ae52d40 --- /dev/null +++ b/lib/koproperty/editor.cpp @@ -0,0 +1,1027 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2004-2006 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "editor.h" +#include "editoritem.h" +#include "set.h" +#include "factory.h" +#include "property.h" +#include "widget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace KoProperty { + +//! @internal +static bool kofficeAppDirAdded = false; + +//! \return true if \a o has parent \a par. +//! @internal +inline bool hasParent(QObject* par, QObject* o) +{ + if (!o || !par) + return false; + while (o && o != par) + o = o->parent(); + return o == par; +} + +class EditorPrivate +{ + public: + EditorPrivate(Editor *editor) + : itemDict(101, false), justClickedItem(false) + { + currentItem = 0; + undoButton = 0; + topItem = 0; + itemToSelectLater = 0; + if (!kofficeAppDirAdded) { + kofficeAppDirAdded = true; + KGlobal::iconLoader()->addAppDir("koffice"); + } + previouslyCollapsedGroupItem = 0; + childFormPreviouslyCollapsedGroupItem = 0; + slotPropertyChanged_enabled = true; + QObject::connect(&changeSetLaterTimer, SIGNAL(timeout()), + editor, SLOT(changeSetLater())); + } + ~EditorPrivate() + { + } + + QGuardedPtr set; + //! widget cache for property types, widget will be deleted + QMap widgetCache; + QGuardedPtr currentWidget; + EditorItem *currentItem; + EditorItem *topItem; //! The top item is used to control the drawing of every branches. + QPushButton *undoButton; //! "Revert to defaults" button + EditorItem::Dict itemDict; + + int baseRowHeight; + bool sync : 1; + bool insideSlotValueChanged : 1; + + //! Helpers for changeSetLater() + QTimer changeSetLaterTimer; + bool setListLater_set : 1; + bool preservePrevSelection_preservePrevSelection : 1; + QCString preservePrevSelection_propertyToSelect; + //bool doNotSetFocusOnSelection : 1; + //! Used in setFocus() to prevent scrolling to previously selected item on mouse click + bool justClickedItem : 1; + //! Helper for slotWidgetValueChanged() + bool slotPropertyChanged_enabled : 1; + //! Helper for changeSet() + Set* setListLater_list; + //! used by selectItemLater() + EditorItem *itemToSelectLater; + + QListViewItem *previouslyCollapsedGroupItem; + QListViewItem *childFormPreviouslyCollapsedGroupItem; +}; +} + +using namespace KoProperty; + +Editor::Editor(QWidget *parent, bool autoSync, const char *name) + : KListView(parent, name) +{ + d = new EditorPrivate(this); + d->itemDict.setAutoDelete(false); + + d->set = 0; + d->topItem = 0; + d->currentItem = 0; + d->sync = autoSync; + d->insideSlotValueChanged = false; + d->setListLater_set = false; + d->preservePrevSelection_preservePrevSelection = false; + d->setListLater_list = 0; + + d->undoButton = new QPushButton(viewport()); + d->undoButton->setFocusPolicy(QWidget::NoFocus); + setFocusPolicy(QWidget::ClickFocus); + d->undoButton->setMinimumSize(QSize(5,5)); // allow to resize undoButton even below pixmap size + d->undoButton->setPixmap(SmallIcon("undo")); + QToolTip::add(d->undoButton, i18n("Undo changes")); + d->undoButton->hide(); + connect(d->undoButton, SIGNAL(clicked()), this, SLOT(undo())); + + installEventFilter(this); + viewport()->installEventFilter(this); + + addColumn(i18n("Name")); + addColumn(i18n("Value")); + setAllColumnsShowFocus(true); + setColumnWidthMode(0, QListView::Maximum); + setFullWidth(true); + setShowSortIndicator(false); +#if KDE_IS_VERSION(3,3,9) + setShadeSortColumn(false); +#endif + setTooltipColumn(0); + setSorting(0); + setItemMargin(KPROPEDITOR_ITEM_MARGIN); + header()->setMovingEnabled( false ); + setTreeStepSize(16 + 2/*left*/ + 1/*right*/); + + updateFont(); +// d->baseRowHeight = QFontMetrics(font()).height() + itemMargin()*2; + + connect(this, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(slotClicked(QListViewItem *))); + connect(this, SIGNAL(currentChanged(QListViewItem *)), this, SLOT(slotCurrentChanged(QListViewItem *))); + connect(this, SIGNAL(expanded(QListViewItem *)), this, SLOT(slotExpanded(QListViewItem *))); + connect(this, SIGNAL(collapsed(QListViewItem *)), this, SLOT(slotCollapsed(QListViewItem *))); + connect(header(), SIGNAL(sizeChange(int, int, int)), this, SLOT(slotColumnSizeChanged(int, int, int))); +// connect(header(), SIGNAL(clicked(int)), this, SLOT(updateEditorGeometry())); +// connect(header(), SIGNAL(clicked(int)), this, SLOT(updateEditorGeometryAndGroupLabels())); + connect(header(), SIGNAL(sectionHandleDoubleClicked (int)), this, SLOT(slotColumnSizeChanged(int))); + updateGroupLabelsPosition(); +} + +Editor::~Editor() +{ + clearWidgetCache(); + delete d; + d = 0; +} + +void +Editor::fill() +{ + setUpdatesEnabled(false); + d->itemToSelectLater = 0; + qApp->eventLoop()->processEvents(QEventLoop::AllEvents); + hideEditor(); + KListView::clear(); + d->itemDict.clear(); + clearWidgetCache(); + if(!d->set) { + d->topItem = 0; + setUpdatesEnabled(true); + triggerUpdate(); + return; + } + + d->topItem = new EditorDummyItem(this); + + const QValueList groupNames = d->set->groupNames(); +// kopropertydbg << "Editor::fill(): group names = " << groupNames.count() << endl; + if(groupNames.count() == 1) { // one group (default one), so don't show groups + //add flat set of properties + const QValueList& propertyNames = d->set->propertyNamesForGroup( groupNames.first() ); + QValueListConstIterator it = propertyNames.constBegin(); + for( ; it != propertyNames.constEnd(); ++it) + addItem(*it, d->topItem); + } + else { // create a groupItem for each group + EditorGroupItem *prevGroupItem = 0; + int sortOrder = 0; + for (QValueListConstIterator it = groupNames.constBegin(); it!=groupNames.constEnd(); + ++it, sortOrder++) + { + const QValueList& propertyNames = d->set->propertyNamesForGroup(*it); + EditorGroupItem *groupItem; + if (prevGroupItem) + groupItem = new EditorGroupItem(d->topItem, prevGroupItem, + d->set->groupDescription(*it), d->set->groupIcon(*it), sortOrder ); + else + groupItem = new EditorGroupItem(d->topItem, + d->set->groupDescription(*it), d->set->groupIcon(*it), sortOrder ); + + QValueList::ConstIterator it2 = propertyNames.constBegin(); + for( ; it2 != propertyNames.constEnd(); ++it2) + addItem(*it2, groupItem); + + prevGroupItem = groupItem; + } + } + +// repaint(); + + if (firstChild()) + { + setCurrentItem(firstChild()); + setSelected(firstChild(), true); + slotClicked(firstChild()); + updateGroupLabelsPosition(); + } + setUpdatesEnabled(true); + // aaah, call this instead of update() as explained here http://lists.trolltech.com/qt-interest/2000-06/thread00337-0.html + triggerUpdate(); +} + +void +Editor::addItem(const QCString &name, EditorItem *parent) +{ + if(!d->set || !d->set->contains(name)) + return; + + Property *property = &(d->set->property(name)); + if(!property || !property->isVisible()) { +// kopropertydbg << "Property is not visible: " << name << endl; + return; + } + QListViewItem *last = parent ? parent->firstChild() : d->topItem->firstChild(); + while(last && last->nextSibling()) + last = last->nextSibling(); + + EditorItem *item=0; + if(parent) + item = new EditorItem(this, parent, property, last); + else + item = new EditorItem(this, d->topItem, property, last); + d->itemDict.insert(name, item); + + // Create child items + item->setOpen(true); + if(!property->children()) + return; + + last = 0; + QValueList::ConstIterator endIt = property->children()->constEnd(); + for(QValueList::ConstIterator it = property->children()->constBegin(); it != endIt; ++it) { + //! \todo allow to have child prop with child items too + if( *it && (*it)->isVisible() ) + last = new EditorItem(this, item, *it, last); + } +} + +void +Editor::changeSet(Set *set, bool preservePrevSelection) +{ + changeSetInternal(set, preservePrevSelection, ""); +} + +void +Editor::changeSet(Set *set, const QCString& propertyToSelect) +{ + changeSetInternal(set, !propertyToSelect.isEmpty(), propertyToSelect); +} + +void +Editor::changeSetInternal(Set *set, bool preservePrevSelection, const QCString& propertyToSelect) +{ + if (d->insideSlotValueChanged) { + //changeSet() called from inside of slotValueChanged() + //this is dangerous, because there can be pending events, + //especially for the GUI stuff, so let's do delayed work + d->setListLater_list = set; + d->preservePrevSelection_preservePrevSelection = preservePrevSelection; + d->preservePrevSelection_propertyToSelect = propertyToSelect; + qApp->eventLoop()->processEvents(QEventLoop::AllEvents); + if (d->set) { + //store prev. selection for this prop set + if (d->currentItem) + d->set->setPrevSelection( d->currentItem->property()->name() ); + kdDebug() << d->set->prevSelection() << endl; + } + if (!d->setListLater_set) { + d->setListLater_set = true; + d->changeSetLaterTimer.start(10, true); + } + return; + } + + if (d->set) { + slotWidgetAcceptInput(d->currentWidget); + //store prev. selection for this prop set + if (d->currentItem) + d->set->setPrevSelection( d->currentItem->property()->name() ); + else + d->set->setPrevSelection( "" ); + d->set->disconnect(this); + } + + QCString selectedPropertyName1 = propertyToSelect, selectedPropertyName2 = propertyToSelect; + if (preservePrevSelection) { + //try to find prev. selection: + //1. in new list's prev. selection + if(set) + selectedPropertyName1 = set->prevSelection(); + //2. in prev. list's current selection + if(d->set) + selectedPropertyName2 = d->set->prevSelection(); + } + + d->set = set; + if (d->set) { + //receive property changes + connect(d->set, SIGNAL(propertyChangedInternal(KoProperty::Set&, KoProperty::Property&)), + this, SLOT(slotPropertyChanged(KoProperty::Set&, KoProperty::Property&))); + connect(d->set, SIGNAL(propertyReset(KoProperty::Set&, KoProperty::Property&)), + this, SLOT(slotPropertyReset(KoProperty::Set&, KoProperty::Property&))); + connect(d->set,SIGNAL(aboutToBeCleared()), this, SLOT(slotSetWillBeCleared())); + connect(d->set,SIGNAL(aboutToBeDeleted()), this, SLOT(slotSetWillBeDeleted())); + } + + fill(); + + emit propertySetChanged(d->set); + + if (d->set) { + //select prev. selected item + EditorItem * item = 0; + if (!selectedPropertyName2.isEmpty()) //try other one for old prop set + item = d->itemDict[selectedPropertyName2]; + if (!item && !selectedPropertyName1.isEmpty()) //try old one for current prop set + item = d->itemDict[selectedPropertyName1]; + + if (item) { + d->itemToSelectLater = item; + QTimer::singleShot(10, this, SLOT(selectItemLater())); + //d->doNotSetFocusOnSelection = !hasParent(this, focusWidget()); + //setSelected(item, true); + //d->doNotSetFocusOnSelection = false; +// ensureItemVisible(item); + } + } +} + +//! @internal +void Editor::selectItemLater() +{ + if (!d->itemToSelectLater) + return; + EditorItem *item = d->itemToSelectLater; + d->itemToSelectLater = 0; + setSelected(item, true); + ensureItemVisible(item); +} + +//! @internal +void +Editor::changeSetLater() +{ + qApp->eventLoop()->processEvents(QEventLoop::AllEvents); + if (kapp->hasPendingEvents()) { + d->changeSetLaterTimer.start(10, true); //try again... + return; + } + d->setListLater_set = false; + if (!d->setListLater_list) + return; + + bool b = d->insideSlotValueChanged; + d->insideSlotValueChanged = false; + changeSetInternal(d->setListLater_list, d->preservePrevSelection_preservePrevSelection, + d->preservePrevSelection_propertyToSelect); + d->insideSlotValueChanged = b; +} + +void +Editor::clear(bool editorOnly) +{ + d->itemToSelectLater = 0; + hideEditor(); + + if(!editorOnly) { + qApp->eventLoop()->processEvents(QEventLoop::AllEvents); + if(d->set) + d->set->disconnect(this); + clearWidgetCache(); + KListView::clear(); + d->itemDict.clear(); + d->topItem = 0; + } +} + +void +Editor::undo() +{ + if(!d->currentWidget || !d->currentItem || (d->set && d->set->isReadOnly()) || (d->currentWidget && d->currentWidget->isReadOnly())) + return; + + int propertySync = d->currentWidget->property()->autoSync(); + bool sync = (propertySync != 0 && propertySync != 1) ? + d->sync : (propertySync!=0); + + if(sync) + d->currentItem->property()->resetValue(); + if (d->currentWidget && d->currentItem) {//(check because current widget could be removed by resetValue()) + d->currentWidget->setValue( d->currentItem->property()->value()); + repaintItem(d->currentItem); + } +} + +void +Editor::slotPropertyChanged(Set& set, Property& property) +{ + if (!d->slotPropertyChanged_enabled) + return; + if(&set != d->set) + return; + + if (d->currentItem && d->currentItem->property() == &property) { + d->currentWidget->setValue(property.value(), false); + for(QListViewItem *item = d->currentItem->firstChild(); item; item = item->nextSibling()) + repaintItem(item); + } + else { + // prop not in the dict, might be a child property: + EditorItem *item = d->itemDict[property.name()]; + if(!item && property.parent()) + item = d->itemDict[property.parent()->name()]; + if (item) { + repaintItem(item); + for(QListViewItem *it = item->firstChild(); it; it = it->nextSibling()) + repaintItem(it); + } + } + +//! @todo should we move this somewhere? +#if 0 + if (property.parent() && property.parent()->type()==Rect) { + const int delta = property.value().toInt()-previousValue.toInt(); + if (property.type()==Rect_X) { //|| property.type()==Rect_Y) + property.parent()->child("width")->setValue(delta, false); + } + +/* if (widget->property() && (QWidget*)d->currentWidget==widget && d->currentItem->parent()) { + EditorItem *parentItem = static_cast(d->currentItem->parent()); + const int thisType = ; + && parentItem->property()->type()==Rect) { + //changing x or y components of Rect type shouldn't change width or height, respectively + if (thisType==Rect_X) { + EditorItem *rectWidthItem = static_cast(d->currentItem->nextSibling()->nextSibling()); + if (delta!=0) { + rectWidthItem->property()->setValue(rectWidthItem->property()->value().toInt()+delta, false); + } + } + }*/ + } +#endif + showUndoButton( property.isModified() ); +} + +void +Editor::slotPropertyReset(Set& set, Property& property) +{ + if(&set != d->set) + return; + + if (d->currentItem && d->currentItem->property() == &property) { + d->currentWidget->setValue(property.value(), false); + for(QListViewItem *item = d->currentItem->firstChild(); item; item = item->nextSibling()) + repaintItem(item); + } + else { + EditorItem *item = d->itemDict[property.name()]; + // prop not in the dict, might be a child prop. + if(!item && property.parent()) + item = d->itemDict[property.parent()->name()]; + if (item) { + repaintItem(item); + for(QListViewItem *it = item->firstChild(); it; it = it->nextSibling()) + repaintItem(it); + } + } + + showUndoButton( false ); +} + +void +Editor::slotWidgetValueChanged(Widget *widget) +{ + if(!widget || !d->set || (d->set && d->set->isReadOnly()) || (widget && widget->isReadOnly()) || !widget->property()) + return; + + d->insideSlotValueChanged = true; + + QVariant value = widget->value(); + int propertySync = widget->property()->autoSync(); + bool sync = (propertySync != 0 && propertySync != 1) ? + d->sync : (propertySync!=0); + + if(sync) { + d->slotPropertyChanged_enabled = false; + QGuardedPtr pWidget = widget; //safe, widget can be destroyed in the meantime + widget->property()->setValue(value); + if (pWidget) + showUndoButton( pWidget->property()->isModified() ); + d->slotPropertyChanged_enabled = true; + } + + d->insideSlotValueChanged = false; +} + +void +Editor::acceptInput() +{ + slotWidgetAcceptInput(d->currentWidget); +} + +void +Editor::slotWidgetAcceptInput(Widget *widget) +{ + if(!widget || !d->set || !widget->property() || (d->set && d->set->isReadOnly()) || (widget && widget->isReadOnly())) + return; + + widget->property()->setValue(widget->value()); +} + +void +Editor::slotWidgetRejectInput(Widget *widget) +{ + if(!widget || !d->set) + return; + + undo(); +} + +void +Editor::slotClicked(QListViewItem *it) +{ + d->previouslyCollapsedGroupItem = 0; + d->childFormPreviouslyCollapsedGroupItem = 0; + + acceptInput(); + + hideEditor(); + if(!it) + return; + + EditorItem *item = static_cast(it); + Property *p = item ? item->property() : 0; + if(!p) + return; + + d->currentItem = item; + d->currentWidget = createWidgetForProperty(p); + + //moved up updateEditorGeometry(); + showUndoButton( p->isModified() ); + if (d->currentWidget) { + if (d->currentWidget->visibleFlag()) { + d->currentWidget->show(); + if (hasParent( this, kapp->focusWidget() )) + d->currentWidget->setFocus(); + } + } + + d->justClickedItem = true; +} + +void +Editor::slotCurrentChanged(QListViewItem *item) +{ + if (item == firstChild()) { + QListViewItem *oldItem = item; + while (item && (!item->isSelectable() || !item->isVisible())) + item = item->itemBelow(); + if (item && item != oldItem) { + setSelected(item,true); + return; + } + } +} + +void +Editor::slotSetWillBeCleared() +{ + d->itemToSelectLater = 0; + if (d->currentWidget) { + acceptInput(); + d->currentWidget->setProperty(0); + } + clear(); +} + +void +Editor::slotSetWillBeDeleted() +{ + clear(); + d->set = 0; +} + +Widget* +Editor::createWidgetForProperty(Property *property, bool changeWidgetProperty) +{ +// int type = property->type(); + QGuardedPtr widget = d->widgetCache[property]; + + if(!widget) { + widget = FactoryManager::self()->createWidgetForProperty(property); + if (!widget) + return 0; + widget->setReadOnly( (d->set && d->set->isReadOnly()) || property->isReadOnly() ); + d->widgetCache[property] = widget; + widget->setProperty(0); // to force reloading property later + widget->hide(); + connect(widget, SIGNAL(valueChanged(Widget*)), + this, SLOT(slotWidgetValueChanged(Widget*)) ); + connect(widget, SIGNAL(acceptInput(Widget*)), + this, SLOT(slotWidgetAcceptInput(Widget*)) ); + connect(widget, SIGNAL(rejectInput(Widget*)), + this, SLOT(slotWidgetRejectInput(Widget*)) ); + } + + //update geometry earlier, because Widget::setValue() can depend on widget's geometry + updateEditorGeometry(d->currentItem, widget); + + if(widget && (!widget->property() || changeWidgetProperty)) + widget->setProperty(property); + +// if (!d->doNotSetFocusOnSelection) { +// widget->setFocus(); +// } + + return widget; +} + + +void +Editor::clearWidgetCache() +{ + for(QMap::iterator it = d->widgetCache.begin(); it != d->widgetCache.end(); ++it) + it.data()->deleteLater(); +// delete it.data(); + d->widgetCache.clear(); +} + +void +Editor::updateEditorGeometry(bool forceUndoButtonSettings, bool undoButtonVisible) +{ + updateEditorGeometry(d->currentItem, d->currentWidget, + forceUndoButtonSettings, undoButtonVisible); +} + +void +Editor::updateEditorGeometry(EditorItem *item, Widget* widget, + bool forceUndoButtonSettings, bool undoButtonVisible) +{ + if(!item || !widget) + return; + + int placeForUndoButton; + if (forceUndoButtonSettings ? undoButtonVisible : d->undoButton->isVisible()) + placeForUndoButton = d->undoButton->width(); + else + placeForUndoButton = widget->leavesTheSpaceForRevertButton() ? d->undoButton->width() : 0; + + QRect r; + int y = itemPos(item); + r.setX(header()->sectionPos(1)-(widget->hasBorders()?1:0)); //-1, to align to horizontal line + r.setY(y-(widget->hasBorders()?1:0)); + r.setWidth(header()->sectionSize(1)+(widget->hasBorders()?1:0) //+1 because we subtracted 1 from X + - placeForUndoButton); + r.setHeight(item->height()+(widget->hasBorders()?1:-1)); + + // check if the column is fully visible + if (visibleWidth() < r.right()) + r.setRight(visibleWidth()); + + moveChild(widget, r.x(), r.y()); + widget->resize(r.size()); + qApp->eventLoop()->processEvents(QEventLoop::AllEvents); +} + +void +Editor::updateGroupLabelsPosition() +{ + if(!d->topItem || d->itemDict.isEmpty()) + return; + + EditorGroupItem *group = dynamic_cast(d->topItem->firstChild()); + while(group) { + QRect r = itemRect((QListViewItem*) group); + if(group->label()) { + group->label()->setGeometry(r); + group->label()->repaint(); + } + group = dynamic_cast(group->nextSibling()); + } +} + +void +Editor::hideEditor() +{ + d->currentItem = 0; + QWidget *cw = d->currentWidget; + if(cw) { + d->currentWidget = 0; + cw->hide(); + } + d->undoButton->hide(); +} + +void +Editor::showUndoButton( bool show ) +{ + if (!d->currentItem || !d->currentWidget || (d->currentWidget && d->currentWidget->isReadOnly())) + return; + + int y = viewportToContents(QPoint(0, itemRect(d->currentItem).y())).y(); + QRect geometry(columnWidth(0), y, columnWidth(1) + 1, d->currentItem->height()); + d->undoButton->resize(d->baseRowHeight, d->currentItem->height()); + + updateEditorGeometry(true, show); + + if (!show) { +/* if (d->currentWidget) { + if (d->currentWidget->leavesTheSpaceForRevertButton()) { + geometry.setWidth(geometry.width()-d->undoButton->width()); + } + d->currentWidget->resize(geometry.width(), geometry.height()); + }*/ + d->undoButton->hide(); + return; + } + + QPoint p = contentsToViewport(QPoint(0, geometry.y())); + d->undoButton->move(geometry.x() + geometry.width() + -((d->currentWidget && d->currentWidget->hasBorders())?1:0)/*editor is moved by 1 to left*/ + - d->undoButton->width(), p.y()); +// if (d->currentWidget) { +// d->currentWidget->move(d->currentWidget->x(), p.y()); +// d->currentWidget->resize(geometry.width()-d->undoButton->width(), geometry.height()); +// } + d->undoButton->show(); +} + +void +Editor::slotExpanded(QListViewItem *item) +{ + if (!item) + return; + + //select child item again if a group item has been expanded + if (!selectedItem() && dynamic_cast(item) && d->previouslyCollapsedGroupItem == item + && d->childFormPreviouslyCollapsedGroupItem) { + setSelected(d->childFormPreviouslyCollapsedGroupItem, true); + setCurrentItem(selectedItem()); + slotClicked(selectedItem()); + } + updateEditorGeometry(); + updateGroupLabelsPosition(); + repaintContents(); + repaint(); +} + +void +Editor::slotCollapsed(QListViewItem *item) +{ + if (!item) + return; + //unselect child item and hide editor if a group item has been collapsed + if (dynamic_cast(item)) { + for (QListViewItem *i = selectedItem(); i; i = i->parent()) { + if (i->parent()==item) { + d->previouslyCollapsedGroupItem = item; + d->childFormPreviouslyCollapsedGroupItem = selectedItem(); + hideEditor(); + setSelected(selectedItem(), false); + setSelected(item->nextSibling(), true); + break; + } + } + } + updateEditorGeometry(); + updateGroupLabelsPosition(); + repaintContents(); + repaint(); +} + +void +Editor::slotColumnSizeChanged(int section, int oldSize, int newSize) +{ + Q_UNUSED(section); + Q_UNUSED(oldSize); + Q_UNUSED(newSize); + /*for (QListViewItemIterator it(this); it.current(); ++it) { + if (section == 0 && dynamic_cast(it.current())) { + it.current()->repaint(); + } + }*/ +/* + if(d->currentWidget) { + if(section == 0) + d->currentWidget->move(newS, d->currentWidget->y()); + else { + if(d->undoButton->isVisible()) + d->currentWidget->resize(newS - d->undoButton->width(), d->currentWidget->height()); + else + d->currentWidget->resize( + newS-(d->currentWidget->leavesTheSpaceForRevertButton() ? d->undoButton->width() : 0), + d->currentWidget->height()); + } + }*/ +// repaintContents(); +// repaint(); + updateEditorGeometry(); + update(); +} + +void +Editor::slotColumnSizeChanged(int section) +{ + setColumnWidth(1, viewport()->width() - columnWidth(0)); + slotColumnSizeChanged(section, 0, header()->sectionSize(section)); + +/* if(d->currentWidget) { + if(d->undoButton->isVisible()) + d->currentWidget->resize(columnWidth(1) - d->undoButton->width(), d->currentWidget->height()); + else + d->currentWidget->resize( + columnWidth(1)-(d->currentWidget->leavesTheSpaceForRevertButton() ? d->undoButton->width() : 0), + d->currentWidget->height()); + }*/ + if(d->undoButton->isVisible()) + showUndoButton(true); + else + updateEditorGeometry(); +} + +QSize +Editor::sizeHint() const +{ + return QSize( QFontMetrics(font()).width(columnText(0)+columnText(1)+" "), + KListView::sizeHint().height()); +} + +void +Editor::setFocus() +{ + EditorItem *item = static_cast(selectedItem()); + if (item) { + if (!d->justClickedItem) + ensureItemVisible(item); + d->justClickedItem = false; + } + else { + //select an item before focusing + item = static_cast(itemAt(QPoint(10,1))); + if (item) { + ensureItemVisible(item); + setSelected(item, true); + } + } + if (d->currentWidget) { +// kopropertydbg << "d->currentWidget->setFocus()" << endl; + d->currentWidget->setFocus(); + } + else { +// kopropertydbg << "KListView::setFocus()" << endl; + KListView::setFocus(); + } +} + +void +Editor::resizeEvent(QResizeEvent *ev) +{ + KListView::resizeEvent(ev); + if(d->undoButton->isVisible()) + showUndoButton(true); + update(); + updateGroupLabelsPosition(); +} + +bool +Editor::eventFilter( QObject * watched, QEvent * e ) +{ + if ((watched==this || watched==viewport()) && e->type()==QEvent::KeyPress) { + if (handleKeyPress(static_cast(e))) + return true; + } + return KListView::eventFilter(watched, e); +} + +bool +Editor::handleKeyPress(QKeyEvent* ev) +{ + const int k = ev->key(); + const Qt::ButtonState s = ev->state(); + + //selection moving + QListViewItem *item = 0; + + if ( ((s == NoButton) && (k == Key_Up)) || (k==Key_BackTab) ) { + //find prev visible + item = selectedItem() ? selectedItem()->itemAbove() : 0; + while (item && (!item->isSelectable() || !item->isVisible())) + item = item->itemAbove(); + if (!item) + return true; + } + else if( (s == NoButton) && ((k == Key_Down) || (k == Key_Tab)) ) { + //find next visible + item = selectedItem() ? selectedItem()->itemBelow() : 0; + while (item && (!item->isSelectable() || !item->isVisible())) + item = item->itemBelow(); + if (!item) + return true; + } + else if( (s==NoButton) && (k==Key_Home) ) { + if (d->currentWidget && d->currentWidget->hasFocus()) + return false; + //find 1st visible + item = firstChild(); + while (item && (!item->isSelectable() || !item->isVisible())) + item = item->itemBelow(); + } + else if( (s==NoButton) && (k==Key_End) ) { + if (d->currentWidget && d->currentWidget->hasFocus()) + return false; + //find last visible + item = selectedItem(); + QListViewItem *lastVisible = item; + while (item) { // && (!item->isSelectable() || !item->isVisible())) + item = item->itemBelow(); + if (item && item->isSelectable() && item->isVisible()) + lastVisible = item; + } + item = lastVisible; + } + + if(item) { + ev->accept(); + ensureItemVisible(item); + setSelected(item, true); + return true; + } + return false; +} + +void +Editor::updateFont() +{ + setFont(parentWidget()->font()); + d->baseRowHeight = QFontMetrics(parentWidget()->font()).height() + itemMargin() * 2; + if (!d->currentItem) + d->undoButton->resize(d->baseRowHeight, d->baseRowHeight); + else { + showUndoButton(d->undoButton->isVisible()); + updateEditorGeometry(); + } + updateGroupLabelsPosition(); +} + +bool +Editor::event( QEvent * e ) +{ + if (e->type()==QEvent::ParentFontChange) { + updateFont(); + } + return KListView::event(e); +} + +void +Editor::contentsMousePressEvent( QMouseEvent * e ) +{ + QListViewItem *item = itemAt(e->pos()); + if (dynamic_cast(item)) { + setOpen( item, !isOpen(item) ); + return; + } + KListView::contentsMousePressEvent(e); +} + +void +Editor::setSorting( int column, bool ascending ) +{ + if (d->set && d->set->groupNames().count()>1) //do not sort when groups are present (maybe reenable this later?) + return; + KListView::setSorting( column, ascending ); + updateEditorGeometry(); + updateGroupLabelsPosition(); + repaintContents(); + repaint(); +} + +#include "editor.moc" diff --git a/lib/koproperty/editor.h b/lib/koproperty/editor.h new file mode 100644 index 00000000..9cd794f7 --- /dev/null +++ b/lib/koproperty/editor.h @@ -0,0 +1,188 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2004-2006 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_PROPERTYEDITOR_H +#define KPROPERTY_PROPERTYEDITOR_H + +#include +#include "koproperty_global.h" + +#include + +class QSize; + +namespace KoProperty { + +class EditorPrivate; +class Property; +class Set; +class Widget; +class EditorItem; + + +/*! \brief A listview to edit properties + Editor widgets use property options using Property::option(const char *) + to override default behaviour of editor items. + Currently supported options are: +
  • min: integer setting for minimum value of IntEdit and DoubleEdit item. Default is 0. + Set "min" to -1, if you want this special value to be allowed.
  • +
  • minValueText: i18n'd QString used in IntEdit to set "specialValueText" + widget's property
  • +
  • max: integer setting for minimum value of IntEdit item. Default is 0xffff.
  • +
  • precision: The number of decimals after the decimal point. (for DoubleEdit)
  • +
  • step : the size of the step that is taken when the user hits the up + or down buttons (for DoubleEdit)
  • +
  • 3rdState: i18n'd QString used in BoolEdit. If not empty, the the editor's button + accept third "null" state with name equal to this string. When this value is selected, + Widget::value() returns null QVariant. This option is used for example in the "defaultValue" + property for a field of type boolean (in Kexi Table Designer). Third, "null" value + of the property means there is no "defaultValue" specified.
  • +
+ \author Cedric Pasteur + \author Alexander Dymo + \author Jaroslaw Staniek + */ +class KOPROPERTY_EXPORT Editor : public KListView +{ + Q_OBJECT + + public: + /*! Creates an empty Editor with \a parent as parent widget. + If \a autoSync == true, properties values are automatically synced as + soon as editor contents change (eg the user types text, etc.) + and the values are written in the property set. Otherwise, property set + is updated only when selected item changes or user presses Enter key. + Each property can overwrite this if its autoSync() == 0 or 1. + */ + Editor(QWidget *parent=0, bool autoSync=true, const char *name=0); + + virtual ~Editor(); + + virtual QSize sizeHint() const; + virtual void setFocus(); + virtual void setSorting( int column, bool ascending = true ); + + public slots: + /*! Populates the editor with an item for each property in the List. + Also creates child items for composed properties. + If \a preservePrevSelection is true, previously selected editor + item will be kept selected, if present. */ + void changeSet(Set *set, bool preservePrevSelection = false); + + /*! Populates the editor with an item for each property in the List. + Also creates child items for composed properties. + If \a propertyToSelect is not empty, editor item for this property name + will be selected, if present. */ + void changeSet(Set *set, const QCString& propertyToSelect); + + /*! Clears all items in the list. + if \a editorOnly is true, then only the current editor will be cleared, + not the whole list. + */ + void clear(bool editorOnly = false); + + /*! Accept the changes mae to the current editor (as if the user had pressed Enter key) */ + void acceptInput(); + + signals: + /*! Emitted when current property set has been changed. May be 0. */ + void propertySetChanged(KoProperty::Set *set); + + protected slots: + /*! Updates property widget in the editor.*/ + void slotPropertyChanged(KoProperty::Set& set, KoProperty::Property& property); + + void slotPropertyReset(KoProperty::Set& set, KoProperty::Property& property); + + /*! Updates property in the list when new value is selected in the editor.*/ + void slotWidgetValueChanged(Widget* widget); + + /*! Called when the user presses Enter to accet the input + (only applies when autoSync() == false).*/ + void slotWidgetAcceptInput(Widget *widget); + + /*! Called when the user presses Esc. Calls undo(). */ + void slotWidgetRejectInput(Widget *widget); + + /*! Called when current property set is about to be cleared. */ + void slotSetWillBeCleared(); + + /*! Called when current property set is about to be destroyed. */ + void slotSetWillBeDeleted(); + + /*! This slot is called when the user clicks the list view. + It takes care of deleting current editor and + creating a new editor for the newly selected item. */ + void slotClicked(QListViewItem *item); + + /*! Undoes the last change in property editor.*/ + void undo(); + + void updateEditorGeometry(bool forceUndoButtonSettings = false, bool undoButtonVisible = false); + void updateEditorGeometry(EditorItem *item, Widget* widget, bool forceUndoButtonSettings = false, bool undoButtonVisible = false); + void updateGroupLabelsPosition(); + + void hideEditor(); + + void slotCollapsed(QListViewItem *item); + void slotExpanded(QListViewItem *item); + void slotColumnSizeChanged(int section); + void slotColumnSizeChanged(int section, int oldSize, int newSize); + void slotCurrentChanged(QListViewItem *item); + void changeSetLater(); + void selectItemLater(); + protected: + /*! \return \ref Widget for given property. + Uses cache to store created widgets. + Cache will be cleared only with clearWidgetCache().*/ + Widget *createWidgetForProperty(Property *property, bool changeWidgetProperty=true); + + /*! Deletes cached machines.*/ + void clearWidgetCache(); + + void fill(); + void addItem(const QCString &name, EditorItem *parent); + + void showUndoButton( bool show ); + + virtual void resizeEvent(QResizeEvent *ev); + virtual bool eventFilter( QObject * watched, QEvent * e ); + bool handleKeyPress(QKeyEvent* ev); + + virtual bool event( QEvent * e ); + void updateFont(); + + virtual void contentsMousePressEvent( QMouseEvent * e ); + + /*! Used for changeSet(). */ + void changeSetInternal(Set *set, bool preservePrevSelection, + const QCString& propertyToSelect); + + private: + EditorPrivate *d; + + friend class EditorItem; + friend class Widget; +}; + +} + +#endif diff --git a/lib/koproperty/editoritem.cpp b/lib/koproperty/editoritem.cpp new file mode 100644 index 00000000..604c9fab --- /dev/null +++ b/lib/koproperty/editoritem.cpp @@ -0,0 +1,619 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2004-2006 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "editoritem.h" +#include "editor.h" +#include "property.h" +#include "widget.h" +#include "factory.h" +#include "utils.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define BRANCHBOX_SIZE 9 + +namespace KoProperty { +class EditorItemPrivate +{ + public: + EditorItemPrivate() + : property(0) {} + ~EditorItemPrivate() {} + + Property *property; + Editor *editor; +}; + +//! @internal +static void paintListViewExpander(QPainter* p, QWidget* w, int height, const QColorGroup& cg, bool isOpen) +{ + const int marg = (height -2 - BRANCHBOX_SIZE) / 2; + int xmarg = marg; +// if (dynamic_cast(item)) +// xmarg = xmarg * 10 / 14 -1; +#if 0 +//! @todo disabled: kstyles do not paint background yet... reenable in the future... + KStyle* kstyle = dynamic_cast(widget->style()); + if (kstyle) { + kstyle->drawKStylePrimitive( + KStyle::KPE_ListViewExpander, p, w, QRect( xmarg, marg, BRANCHBOX_SIZE, BRANCHBOX_SIZE ), + cg, isOpen ? 0 : QStyle::Style_On, + QStyleOption::Default); + } + else { +#endif + Q_UNUSED(w); + //draw by hand + p->setPen( KPROPEDITOR_ITEM_BORDER_COLOR ); + p->drawRect(xmarg, marg, BRANCHBOX_SIZE, BRANCHBOX_SIZE); + p->fillRect(xmarg+1, marg + 1, BRANCHBOX_SIZE-2, BRANCHBOX_SIZE-2, +// item->listView()->paletteBackgroundColor()); + cg.base()); +// p->setPen( item->listView()->paletteForegroundColor() ); + p->setPen( cg.foreground() ); + p->drawLine(xmarg+2, marg+BRANCHBOX_SIZE/2, xmarg+BRANCHBOX_SIZE-3, marg+BRANCHBOX_SIZE/2); + if(!isOpen) { + p->drawLine(xmarg+BRANCHBOX_SIZE/2, marg+2, + xmarg+BRANCHBOX_SIZE/2, marg+BRANCHBOX_SIZE-3); + } +// } +} + +//! @internal +//! Based on KPopupTitle, see kpopupmenu.cpp +class GroupWidgetBase : public QWidget +{ + public: + GroupWidgetBase(QWidget* parent) + : QWidget(parent) + , m_isOpen(true) + , m_mouseDown(false) + { + setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed, 0, 1)); + } + + void setText( const QString &text ) + { + m_titleStr = text; + } + + void setIcon( const QPixmap &pix ) + { + m_miniicon = pix; + } + + virtual bool isOpen() const + { + return m_isOpen; + } + + virtual void setOpen(bool set) + { + m_isOpen = set; + } + + virtual QSize sizeHint () const + { + QSize s( QWidget::sizeHint() ); + s.setHeight(fontMetrics().height()*2); + return s; + } + + protected: + virtual void paintEvent(QPaintEvent *) { + QRect r(rect()); + QPainter p(this); + QStyle::StyleFlags flags = m_mouseDown ? QStyle::Style_Down : QStyle::Style_Default; + kapp->style().drawPrimitive(QStyle::PE_HeaderSection, &p, r, palette().active(), flags); + + paintListViewExpander(&p, this, r.height()+2, palette().active(), isOpen()); + if (!m_miniicon.isNull()) { + p.drawPixmap(24, (r.height()-m_miniicon.height())/2, m_miniicon); + } + + if (!m_titleStr.isNull()) + { + int indent = 16 + (m_miniicon.isNull() ? 0 : (m_miniicon.width()+4)); + p.setPen(palette().active().text()); + QFont f = p.font(); + f.setBold(true); + p.setFont(f); + p.drawText(indent+8, 0, width()-(indent+8), + height(), AlignLeft | AlignVCenter | SingleLine, + m_titleStr); + } +// p.setPen(palette().active().mid()); +// p.drawLine(0, 0, r.right(), 0); + } + + virtual bool event( QEvent * e ) { + if (e->type()==QEvent::MouseButtonPress || e->type()==QEvent::MouseButtonRelease) { + QMouseEvent* me = static_cast(e); + if (me->button() == Qt::LeftButton) { + m_mouseDown = e->type()==QEvent::MouseButtonPress; + update(); + } + } + return QWidget::event(e); + } + + protected: + QString m_titleStr; + QPixmap m_miniicon; + bool m_isOpen : 1; + bool m_mouseDown : 1; +}; + +class GroupWidget : public GroupWidgetBase +{ + public: + GroupWidget(EditorGroupItem *parentItem) + : GroupWidgetBase(parentItem->listView()->viewport()) + , m_parentItem(parentItem) + { + } + + virtual bool isOpen() const + { + return m_parentItem->isOpen(); + } + + protected: + EditorGroupItem *m_parentItem; +}; + +class GroupContainer::Private +{ + public: + Private() {} + QVBoxLayout* lyr; + GroupWidgetBase *groupWidget; + QGuardedPtr contents; +}; + +}//namespace + +using namespace KoProperty; + +GroupContainer::GroupContainer(const QString& title, QWidget* parent) +: QWidget(parent) +, d(new Private()) +{ + setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed, 0, 1)); + d->lyr = new QVBoxLayout(this); + d->groupWidget = new GroupWidgetBase(this); + d->groupWidget->setText( title ); + d->lyr->addWidget(d->groupWidget); + d->lyr->addSpacing(4); +} + +GroupContainer::~GroupContainer() +{ + delete d; +} + +void GroupContainer::setContents( QWidget* contents ) +{ + if (d->contents) { + d->contents->hide(); + d->lyr->remove(d->contents); + delete d->contents; + } + d->contents = contents; + if (d->contents) { + d->lyr->addWidget(d->contents); + d->contents->show(); + } + update(); +} + +bool GroupContainer::event( QEvent * e ) { + if (e->type()==QEvent::MouseButtonPress) { + QMouseEvent* me = static_cast(e); + if (me->button() == Qt::LeftButton && d->contents && d->groupWidget->rect().contains(me->pos())) { + d->groupWidget->setOpen(!d->groupWidget->isOpen()); + if (d->groupWidget->isOpen()) + d->contents->show(); + else + d->contents->hide(); + d->lyr->invalidate(); + update(); + } + } + return QWidget::event(e); +} + +////////////////////////////////////////////////////// + +EditorItem::EditorItem(Editor *editor, EditorItem *parent, Property *property, QListViewItem *after) + : KListViewItem(parent, after, + property->captionForDisplaying().isEmpty() ? property->name() : property->captionForDisplaying()) +{ + d = new EditorItemPrivate(); + d->property = property; + d->editor = editor; + + setMultiLinesEnabled(true); + //setHeight(static_cast(listView())->baseRowHeight()*3); +/* + if (property && !property->caption().isEmpty()) { + QSimpleRichText srt(property->caption(), font()); + srt.setWidth(columnWidth(0)-KPROPEDITOR_ITEM_MARGIN*2-20+1); + int oldHeight = it.current()->height(); + int textHeight = srt.height()+KPROPEDITOR_ITEM_MARGIN; + int textLines = textHeight / d->baseRowHeight + (((textHeight % d->baseRowHeight) > 0) ? 1 : 0); + kdDebug() << " textLines: " << textLines << endl; + if (textLines != newNumLines) { + dynamic_cast(it.current())->setHeight(newNumLines * d->baseRowHeight); + } + kdDebug() << it.current()->text(0) << ": " << oldHeight << " -> " << newHeight << endl; + } +*/ +} + +EditorItem::EditorItem(KListView *parent) + : KListViewItem(parent) +{ + d = new EditorItemPrivate(); + d->property = 0; + d->editor = 0; + setMultiLinesEnabled(true); +} + +EditorItem::EditorItem(EditorItem *parent, const QString &text) + : KListViewItem(parent, text) +{ + d = new EditorItemPrivate(); + d->property = 0; + d->editor = 0; + setMultiLinesEnabled(true); +} + +EditorItem::EditorItem(EditorItem *parent, EditorItem *after, const QString &text) + : KListViewItem(parent, after, text) +{ + d = new EditorItemPrivate(); + d->property = 0; + d->editor = 0; + setMultiLinesEnabled(true); +} + +EditorItem::~EditorItem() +{ + delete d; +} + +Property* +EditorItem::property() +{ + return d->property; +} + +void +EditorItem::paintCell(QPainter *p, const QColorGroup & cg, int column, int width, int align) +{ + //int margin = static_cast(listView())->itemMargin(); + if(!d->property) + return; + + if(column == 0) + { + QFont font = listView()->font(); + if(d->property->isModified()) + font.setBold(true); + p->setFont(font); + p->setBrush(cg.highlight()); + p->setPen(cg.highlightedText()); + KListViewItem::paintCell(p, cg, column, width, align); + p->fillRect(parent() ? 0 : 50, 0, width, height()-1, + QBrush(isSelected() ? cg.highlight() : backgroundColor())); + p->setPen(isSelected() ? cg.highlightedText() : cg.text()); + int delta = -20+KPROPEDITOR_ITEM_MARGIN; + if ((firstChild() && dynamic_cast(parent()))) { + delta = -KPROPEDITOR_ITEM_MARGIN-1; + } + if (dynamic_cast(parent())) { + delta = KPROPEDITOR_ITEM_MARGIN*2; + } + else if (parent() && dynamic_cast(parent()->parent())) { + if (dynamic_cast(parent())) + delta += KPROPEDITOR_ITEM_MARGIN*2; + else + delta += KPROPEDITOR_ITEM_MARGIN*5; + } + p->drawText( + QRect(delta,2, width+listView()->columnWidth(1)-KPROPEDITOR_ITEM_MARGIN*2, height()), + Qt::AlignLeft | Qt::AlignTop /*| Qt::SingleLine*/, text(0)); + + p->setPen( KPROPEDITOR_ITEM_BORDER_COLOR ); + p->drawLine(width-1, 0, width-1, height()-1); + p->drawLine(0, -1, width-1, -1); + + p->setPen( KPROPEDITOR_ITEM_BORDER_COLOR ); //! \todo custom color? + if (dynamic_cast(parent())) + p->drawLine(0, 0, 0, height()-1 ); + } + else if(column == 1) + { + QColorGroup icg(cg); + icg.setColor(QColorGroup::Background, backgroundColor()); + p->setBackgroundColor(backgroundColor()); + Widget *widget = d->editor->createWidgetForProperty(d->property, false /*don't change Widget::property() */); + if(widget) { + QRect r(0, 0, d->editor->header()->sectionSize(1), height() - (widget->hasBorders() ? 0 : 1)); + p->setClipRect(r, QPainter::CoordPainter); + p->setClipping(true); + widget->drawViewer(p, icg, r, d->property->value()); + p->setClipping(false); + } + } + p->setPen( KPROPEDITOR_ITEM_BORDER_COLOR ); //! \todo custom color? + p->drawLine(0, height()-1, width, height()-1 ); +} + +void +EditorItem::paintBranches(QPainter *p, const QColorGroup &cg, int w, int y, int h) +{ + p->eraseRect(0,0,w,h); + KListViewItem *item = static_cast(firstChild()); + if(!item) + return; + + QColor backgroundColor; + p->save(); + p->translate(0,y); + QFont font = listView()->font(); + while(item) + { + if(item->isSelected()) + backgroundColor = cg.highlight(); + else { + if (dynamic_cast(item)) + backgroundColor = cg.base(); + else + backgroundColor = item->backgroundColor(); + } +// p->fillRect(-50,0,50, item->height(), QBrush(backgroundColor)); + p->save(); + p->setPen( KPROPEDITOR_ITEM_BORDER_COLOR ); + int delta = 0; + int fillWidth = w; + int x = 0; + if (dynamic_cast(item->parent())) { + delta = 0;//-19; + fillWidth += 19; + } + else { + if (dynamic_cast(item) || /*for flat mode*/ dynamic_cast(item->parent())) + x = 19; + else + x = -19; + fillWidth += 19; + } + if (dynamic_cast(item->parent())) { + x = 19; + } + else if (item->parent() && dynamic_cast(item->parent()->parent())) { + x = 0; + } + p->fillRect(x+1, 0, fillWidth-1, item->height()-1, QBrush(backgroundColor)); + p->drawLine(x, item->height()-1, w, item->height()-1 ); + if (!dynamic_cast(item)) + p->drawLine(x, 0, x, item->height()-1 ); + p->restore(); + +// for (int i=0; i<10000000; i++) +// ; +// if(item->isSelected()) { +// p->fillRect(parent() ? 0 : 50, 0, w, item->height()-1, QBrush(cg.highlight())); +// p->fillRect(-50,0,50, item->height(), QBrush(cg.highlight())); +// } + + //sorry, but we need to draw text here again + font.setBold( dynamic_cast(item) + || (static_cast(item)->property() && static_cast(item)->property()->isModified()) ); + p->setFont(font); + p->setPen(item->isSelected() ? cg.highlightedText() : cg.text()); + if (item->firstChild() && dynamic_cast(item->parent())) { + delta = 19-KPROPEDITOR_ITEM_MARGIN-1; + } + else if (dynamic_cast(item->parent())) { + delta = 19; + } + if (item->parent() && dynamic_cast(item->parent()->parent())) { + if (dynamic_cast(item->parent())) + delta += KPROPEDITOR_ITEM_MARGIN*2; + else + delta += KPROPEDITOR_ITEM_MARGIN*5; + } + + if (!dynamic_cast(item->parent())) + p->drawText(QRect(delta+1,0, w+listView()->columnWidth(1), item->height()), + Qt::AlignLeft | Qt::AlignVCenter /*| Qt::SingleLine*/, item->text(0)); + + if(item->firstChild()) { + paintListViewExpander(p, listView(), item->height(), + cg, item->isOpen()); + } + + // draw icon (if there is one) + EditorItem *editorItem = dynamic_cast(item); + if (editorItem && editorItem->property() && !editorItem->property()->icon().isEmpty()) { + //int margin = listView()->itemMargin(); + QPixmap pix = SmallIcon(editorItem->property()->icon()); + if (!pix.isNull()) + p->drawPixmap(-19+(19-pix.width())/2, (item->height() - pix.height()) / 2, pix); + } + + p->translate(0, item->totalHeight()); + item = (KListViewItem*)item->nextSibling(); + } + p->restore(); +} + +void +EditorItem::paintFocus(QPainter *, const QColorGroup &, const QRect & ) +{ +} + +int +EditorItem::compare( QListViewItem *i, int col, bool ascending ) const +{ + if (!ascending) + return -QListViewItem::key( col, ascending ).localeAwareCompare( i->key( col, ascending ) ); + + if (d->property) { +// kopropertydbg << d->property->name() << " " << d->property->sortingKey() << " | " +// << static_cast(i)->property()->name() << " " +// << static_cast(i)->property()->sortingKey() << endl; + return d->property->sortingKey() + - ((dynamic_cast(i) && dynamic_cast(i)->property()) + ? dynamic_cast(i)->property()->sortingKey() : 0); + } + + return 0; +// return d->order - static_cast(i)->d->order; +} + +void +EditorItem::setHeight( int height ) +{ + KListViewItem::setHeight(height); +} + +////////////////////////////////////////////////////// + +EditorGroupItem::EditorGroupItem(EditorItem *parent, EditorItem *after, const QString &text, const QString &icon, int sortOrder) + : EditorItem(parent, after, text) + , m_label(0) + , m_sortOrder(sortOrder) +{ + init(icon); +} + +EditorGroupItem::EditorGroupItem(EditorItem *parent, const QString &text, const QString &icon, int sortOrder) + : EditorItem(parent, text) + , m_label(0) + , m_sortOrder(sortOrder) +{ + init(icon); +} + +EditorGroupItem::~EditorGroupItem() +{ + delete m_label; +} + +QWidget* EditorGroupItem::label() const +{ + return m_label; +} + +void EditorGroupItem::init(const QString &icon) +{ + setOpen(true); + setSelectable(false); + m_label = new GroupWidget(this); + m_label->setText(text(0)); //todo: icon? + if (!icon.isEmpty()) + m_label->setIcon( SmallIcon(icon) ); + m_label->show(); +} + +void +EditorGroupItem::paintCell(QPainter *p, const QColorGroup & cg, int column, int width, int /*align*/) +{ + Q_UNUSED(p); + Q_UNUSED(cg); + Q_UNUSED(column); + Q_UNUSED(width); + //no need to draw anything since there's a label on top of it +// p->fillRect(0, 0, width, height(), cg.base()); + + //if(column == 1) + // return; + /*p->setPen( KPROPEDITOR_ITEM_BORDER_COLOR ); //! \todo custom color? + + p->setClipRect(listView()->itemRect(this)); + if(column == 1) + p->translate(-listView()->columnWidth(0) + 20, 0); + int totalWidth = listView()->columnWidth(0) + listView()->columnWidth(1) - 20; + p->eraseRect(QRect(0,0, totalWidth,height()-1)); + p->drawLine(0, height()-1, totalWidth-1, height()-1); + + QFont font = listView()->font(); + font.setBold(true); + p->setFont(font); + p->setBrush(cg.highlight()); + //p->setPen(cg.highlightedText()); + KListViewItem::paintCell(p, cg, column, width, align); + p->setPen(cg.text()); + p->drawText(QRect(0,0, totalWidth, height()), + Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, text(0));*/ +} + +void +EditorGroupItem::setup() +{ + KListViewItem::setup(); + setHeight( height()+4 ); +} + +int +EditorGroupItem::compare( QListViewItem *i, int col, bool ascending ) const +{ + Q_UNUSED(col); + Q_UNUSED(ascending); + if (dynamic_cast(i)) { + return m_sortOrder + - dynamic_cast(i)->m_sortOrder; + } + return 0; +} + +//////////////////////////////////////////////////////// + +EditorDummyItem::EditorDummyItem(KListView *listview) + : EditorItem(listview) +{ + setSelectable(false); + setOpen(true); +} + +EditorDummyItem::~EditorDummyItem() +{} + +void +EditorDummyItem::setup() +{ + setHeight(0); +} diff --git a/lib/koproperty/editoritem.h b/lib/koproperty/editoritem.h new file mode 100644 index 00000000..4cc1a28e --- /dev/null +++ b/lib/koproperty/editoritem.h @@ -0,0 +1,129 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2004-2006 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_PROPERTYEDITORITEM_H +#define KPROPERTY_PROPERTYEDITORITEM_H + +#include "koproperty_global.h" +#include + +#define KPROPEDITOR_ITEM_MARGIN 2 +#define KPROPEDITOR_ITEM_BORDER_COLOR QColor(200,200,200) //! \todo custom color? + +template class QAsciiDict; +class QLabel; + +namespace KoProperty { + +class EditorItemPrivate; +class Property; +class Editor; +class GroupWidget; + +/*! \brief Item for a single property displayed within Editor object. + \author Cedric Pasteur + \author Alexander Dymo + \author Jaroslaw Staniek + @internal + */ +class EditorItem : public KListViewItem +{ + public: + typedef QAsciiDict Dict; + + /*! Creates an EditorItem child of \a parent, associated to \a property. + It \a property has not desctiption set, its name (i.e. not i18n'ed) is reused. + */ + EditorItem(Editor *editor, EditorItem *parent, Property *property, + QListViewItem *after=0); + + //! Two helper contructors for subclass + EditorItem(KListView *parent); + EditorItem(EditorItem *parent, const QString &text); + EditorItem(EditorItem *parent, EditorItem *after, const QString &text); + + virtual ~EditorItem(); + + //! \return a pointer to the property associated to this item. + Property* property(); + + protected: + /*! Reimplemented from KListViewItem to draw custom contents. Properties names are wriiten in bold if + modified. Also takes care of drawing borders around the cells as well as pixmaps or colors if necessary. + */ + virtual void paintCell(QPainter *p, const QColorGroup & cg, int column, int width, int align); + + /*! Reimplemented from KListViewItem to draw custom contents. It takes care of drawing the [+] and [-] + signs only if the item has children. + */ + virtual void paintBranches(QPainter *p, const QColorGroup &cg, int w, int y, int h); + + virtual void paintFocus(QPainter * p, const QColorGroup & cg, const QRect & r); + + virtual int compare( QListViewItem *i, int col, bool ascending ) const; + + virtual void setHeight( int height ); + + protected: + EditorItemPrivate *d; +}; + +//! @internal +class EditorGroupItem : public EditorItem +{ + public: + EditorGroupItem(EditorItem *parent, EditorItem *after, const QString &text, + const QString &icon, int sortOrder); + EditorGroupItem(EditorItem *parent, const QString &text, + const QString &icon, int sortOrder); + virtual ~EditorGroupItem(); + +// void setLabel(QLabel *label) { m_label = label; } + QWidget* label() const; + + protected: + virtual void init(const QString &icon); + + /*! Reimplemented from KListViewItem to draw custom contents. */ + virtual void paintCell(QPainter *p, const QColorGroup & cg, int column, int width, int align); + virtual void setup(); + virtual int compare( QListViewItem *i, int col, bool ascending ) const; + + GroupWidget *m_label; + int m_sortOrder; +}; + +//! @internal +class EditorDummyItem : public EditorItem +{ + public: + EditorDummyItem(KListView *parent); + virtual ~EditorDummyItem(); + + protected: + virtual void setup(); + /*virtual void paintCell(QPainter *p, const QColorGroup & cg, int column, int width, int align); + virtual void paintFocus(QPainter * p, const QColorGroup & cg, const QRect & r);*/ +}; + +} + +#endif diff --git a/lib/koproperty/editors/Makefile.am b/lib/koproperty/editors/Makefile.am new file mode 100644 index 00000000..461fbc00 --- /dev/null +++ b/lib/koproperty/editors/Makefile.am @@ -0,0 +1,13 @@ +INCLUDES = -I$(top_srcdir)/lib/koproperty -I$(top_srcdir)/lib/kofficecore $(all_includes) + +noinst_LTLIBRARIES = libkopropertyeditors.la +libkopropertyeditors_la_LIBADD = $(LIB_KDEUI) $(LIB_KIO) +libkopropertyeditors_la_LDFLAGS = -Wno-unresolved $(all_libraries) +libkopropertyeditors_la_SOURCES = booledit.cpp coloredit.cpp combobox.cpp cursoredit.cpp dateedit.cpp \ + datetimeedit.cpp dummywidget.cpp fontedit.cpp linestyledit.cpp pixmapedit.cpp pointedit.cpp \ + rectedit.cpp sizeedit.cpp sizepolicyedit.cpp spinbox.cpp stringedit.cpp stringlistedit.cpp \ + symbolcombo.cpp timeedit.cpp urledit.cpp + +METASOURCES = AUTO + +SUBDIRS = . diff --git a/lib/koproperty/editors/booledit.cpp b/lib/koproperty/editors/booledit.cpp new file mode 100644 index 00000000..67fb82ec --- /dev/null +++ b/lib/koproperty/editors/booledit.cpp @@ -0,0 +1,213 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2006 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "booledit.h" +#include "../property.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace KoProperty; + +BoolEdit::BoolEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) + , m_yesIcon( SmallIcon("button_ok") ) + , m_noIcon( SmallIcon("button_no") ) +{ + m_toggle = new QToolButton(this); + m_toggle->setToggleButton( true ); + m_toggle->setFocusPolicy(QWidget::WheelFocus); + m_toggle->setUsesTextLabel(true); + m_toggle->setTextPosition(QToolButton::Right); + m_toggle->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + //we're not using layout to because of problems with button size + m_toggle->move(0, 0); + m_toggle->resize(width(), height()); + setFocusWidget(m_toggle); + connect(m_toggle, SIGNAL(stateChanged(int)), this, SLOT(slotValueChanged(int))); +} + +BoolEdit::~BoolEdit() +{ +} + +QVariant +BoolEdit::value() const +{ + return QVariant(m_toggle->isOn(), 4); +} + +void +BoolEdit::setValue(const QVariant &value, bool emitChange) +{ + m_toggle->blockSignals(true); + m_toggle->setOn(value.toBool()); + setState( value.toBool() ? QButton::On : QButton::Off ); + m_toggle->blockSignals(false); + if (emitChange) + emit valueChanged(this); +} + +void +BoolEdit::slotValueChanged(int state) +{ + setState(state); + emit valueChanged(this); +} + +static void drawViewerInternal(QPainter *p, const QRect &r, const QVariant &value, + const QPixmap& yesIcon, const QPixmap& noIcon, const QString& nullText) +{ + p->eraseRect(r); + QRect r2(r); + r2.moveLeft(KIcon::SizeSmall + 6); + + if(value.isNull() && !nullText.isEmpty()) { + p->drawText(r2, Qt::AlignVCenter | Qt::AlignLeft, nullText); + } + else if(value.toBool()) { + p->drawPixmap(3, (r.height()-1-KIcon::SizeSmall)/2, yesIcon); + p->drawText(r2, Qt::AlignVCenter | Qt::AlignLeft, i18n("Yes")); + } + else { + p->drawPixmap(3, (r.height()-1-KIcon::SizeSmall)/2, noIcon); + p->drawText(r2, Qt::AlignVCenter | Qt::AlignLeft, i18n("No")); + } +} + +void +BoolEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + Q_UNUSED(cg); + drawViewerInternal(p, r, value, m_yesIcon, m_noIcon, ""); +} + +void +BoolEdit::setState(int state) +{ + if(QButton::On == state) { + m_toggle->setIconSet(QIconSet(m_yesIcon)); + m_toggle->setTextLabel(i18n("Yes")); + } + else if (QButton::Off == state) { + m_toggle->setIconSet(QIconSet(m_noIcon)); + m_toggle->setTextLabel(i18n("No")); + } +} + +void +BoolEdit::resizeEvent(QResizeEvent *ev) +{ + m_toggle->resize(ev->size()); +} + +bool +BoolEdit::eventFilter(QObject* watched, QEvent* e) +{ + if(e->type() == QEvent::KeyPress) { + QKeyEvent* ev = static_cast(e); + const int k = ev->key(); + if(k == Qt::Key_Space || k == Qt::Key_Enter || k == Qt::Key_Return) { + if (m_toggle) + m_toggle->toggle(); + return true; + } + } + return Widget::eventFilter(watched, e); +} + +void +BoolEdit::setReadOnlyInternal(bool readOnly) +{ + setVisibleFlag(!readOnly); +} + +//-------------------------------------------------- + +ThreeStateBoolEdit::ThreeStateBoolEdit(Property *property, QWidget *parent, const char *name) + : ComboBox(property, parent, name) + , m_yesIcon( SmallIcon("button_ok") ) + , m_noIcon( SmallIcon("button_no") ) +{ + m_edit->insertItem( m_yesIcon, i18n("Yes") ); + m_edit->insertItem( m_noIcon, i18n("No") ); + QVariant thirdState = property ? property->option("3rdState") : QVariant(); + QPixmap nullIcon( m_yesIcon.size() ); //transparent pixmap of appropriate size + nullIcon.setMask(QBitmap(m_yesIcon.size(), true)); + m_edit->insertItem( nullIcon, thirdState.toString().isEmpty() ? i18n("None") : thirdState.toString() ); +} + +ThreeStateBoolEdit::~ThreeStateBoolEdit() +{ +} + +QVariant +ThreeStateBoolEdit::value() const +{ + // list items: true, false, NULL + const int idx = m_edit->currentItem(); + if (idx==0) + return QVariant(true, 1); + else + return idx==1 ? QVariant(false) : QVariant(); +} + +void +ThreeStateBoolEdit::setProperty(Property *prop) +{ + m_setValueEnabled = false; //setValue() couldn't be called before fillBox() + Widget::setProperty(prop); + m_setValueEnabled = true; + if(prop) + setValue(prop->value(), false); //now the value can be set +} + +void +ThreeStateBoolEdit::setValue(const QVariant &value, bool emitChange) +{ + if (!m_setValueEnabled) + return; + + if (value.isNull()) + m_edit->setCurrentItem(2); + else + m_edit->setCurrentItem(value.toBool() ? 0 : 1); + + if (emitChange) + emit valueChanged(this); +} + +void +ThreeStateBoolEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + Q_UNUSED(cg); + drawViewerInternal(p, r, value, m_yesIcon, m_noIcon, m_edit->text(2)); +} + +#include "booledit.moc" diff --git a/lib/koproperty/editors/booledit.h b/lib/koproperty/editors/booledit.h new file mode 100644 index 00000000..f9ab371f --- /dev/null +++ b/lib/koproperty/editors/booledit.h @@ -0,0 +1,77 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2006 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_BOOLEDIT_H +#define KPROPERTY_BOOLEDIT_H + +#include "../widget.h" +#include "combobox.h" +#include + +class QToolButton; + +namespace KoProperty { + +class KOPROPERTY_EXPORT BoolEdit : public Widget +{ + Q_OBJECT + + public: + BoolEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~BoolEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected slots: + void slotValueChanged(int state); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + void setState(int state); + virtual void resizeEvent(QResizeEvent *ev); + virtual bool eventFilter(QObject* watched, QEvent* e); + + private: + QToolButton *m_toggle; + QPixmap m_yesIcon, m_noIcon; //!< icons for m_toggle +}; + +class KOPROPERTY_EXPORT ThreeStateBoolEdit : public ComboBox +{ + Q_OBJECT + + public: + ThreeStateBoolEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~ThreeStateBoolEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void setProperty(Property *property); + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + QPixmap m_yesIcon, m_noIcon; //!< icons for m_toggle +}; + +} + +#endif diff --git a/lib/koproperty/editors/coloredit.cpp b/lib/koproperty/editors/coloredit.cpp new file mode 100644 index 00000000..81897e1d --- /dev/null +++ b/lib/koproperty/editors/coloredit.cpp @@ -0,0 +1,96 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "coloredit.h" + +#include +#include +#include +#include + +#include + +using namespace KoProperty; + +ColorButton::ColorButton(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new KColorCombo(this); + m_edit->setFocusPolicy(QWidget::NoFocus); + connect(m_edit, SIGNAL(activated(int)), this, SLOT(slotValueChanged(int))); + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMinimumHeight(5); + l->addWidget(m_edit); + setFocusWidget(m_edit); +} + +ColorButton::~ColorButton() +{} + +QVariant +ColorButton::value() const +{ + return m_edit->color(); +} + +void +ColorButton::setValue(const QVariant &value, bool emitChange) +{ + m_edit->blockSignals(true); + m_edit->setColor(value.toColor()); + m_edit->blockSignals(false); + if (emitChange) + emit valueChanged(this); +} + +void +ColorButton::drawViewer(QPainter *p, const QColorGroup &, const QRect &r, const QVariant &value) +{ + p->eraseRect(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 +ColorButton::slotValueChanged(int) +{ + emit valueChanged(this); +} + + +bool +ColorButton::eventFilter(QObject* watched, QEvent* e) +{ + return Widget::eventFilter(watched, e); +} + +void +ColorButton::setReadOnlyInternal(bool readOnly) +{ + setVisibleFlag(!readOnly); +} + +#include "coloredit.moc" diff --git a/lib/koproperty/editors/coloredit.h b/lib/koproperty/editors/coloredit.h new file mode 100644 index 00000000..339d6239 --- /dev/null +++ b/lib/koproperty/editors/coloredit.h @@ -0,0 +1,56 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_COLOREDIT_H +#define KPROPERTY_COLOREDIT_H + +#include "../widget.h" + +class KColorCombo; + +namespace KoProperty { + +class KOPROPERTY_EXPORT ColorButton : public Widget +{ + Q_OBJECT + + public: + ColorButton(Property *property, QWidget *parent=0, const char *name=0); + virtual ~ColorButton(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + virtual bool eventFilter(QObject* watched, QEvent* e); + + protected slots: + void slotValueChanged(int index); + + private: + KColorCombo *m_edit; +}; + +} + +#endif diff --git a/lib/koproperty/editors/combobox.cpp b/lib/koproperty/editors/combobox.cpp new file mode 100644 index 00000000..64563dcb --- /dev/null +++ b/lib/koproperty/editors/combobox.cpp @@ -0,0 +1,199 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ +#include "combobox.h" + +#include +#include +#include +#include + +#include +#include + +#include "property.h" + +using namespace KoProperty; + +ComboBox::ComboBox(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) + , m_setValueEnabled(true) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new KComboBox(this); + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMinimumHeight(5); + l->addWidget(m_edit); + + m_edit->setEditable(false); + m_edit->setInsertionPolicy(QComboBox::NoInsertion); + m_edit->setMinimumSize(10, 0); // to allow the combo to be resized to a small size + m_edit->setAutoCompletion(true); + m_edit->setContextMenuEnabled(false); + + if (this->property()->listData()) { + fillBox(); + } +//not needed for combo setLeavesTheSpaceForRevertButton(true); + + setFocusWidget(m_edit); + connect(m_edit, SIGNAL(activated(int)), this, SLOT(slotValueChanged(int))); +} + +ComboBox::~ComboBox() +{ +} + +QVariant +ComboBox::value() const +{ + if (!property()->listData()) { + kopropertywarn << "ComboBox::value(): propery listData not available!" << endl; + return QVariant(); + } + const int idx = m_edit->currentItem(); + if (idx<0 || idx>=(int)property()->listData()->keys.count()) + return QVariant(); + return QVariant( property()->listData()->keys[idx] ); +// if(property()->listData() && property()->listData()->contains(m_edit->currentText())) +// return (*(property()->valueList()))[m_edit->currentText()]; +// return QVariant(); +} + +void +ComboBox::setValue(const QVariant &value, bool emitChange) +{ + if (!property() || !property()->listData()) { + kopropertywarn << "ComboBox::value(): propery listData not available!" << endl; + return; + } + if (!m_setValueEnabled) + return; + int idx = property()->listData()->keys.findIndex( value ); + if (idx>=0 && idxcount()) { + m_edit->setCurrentItem(idx); + } + else { + if (idx<0) { + kopropertywarn << "ComboBox::setValue(): NO SUCH KEY '" << value.toString() + << "' (property '" << property()->name() << "')" << endl; + } else { + QStringList list; + for (int i=0; icount(); i++) + list += m_edit->text(i); + kopropertywarn << "ComboBox::setValue(): NO SUCH INDEX WITHIN COMBOBOX: " << idx + << " count=" << m_edit->count() << " value='" << value.toString() + << "' (property '" << property()->name() << "')\nActual combobox contents: " + << list << endl; + } + m_edit->setCurrentText(QString::null); + } + + if(value.isNull()) + return; + +// m_edit->blockSignals(true); +// m_edit->setCurrentText(keyForValue(value)); +// m_edit->blockSignals(false); + if (emitChange) + emit valueChanged(this); +} + +void +ComboBox::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + QString txt; + if (property()->listData()) { + const int idx = property()->listData()->keys.findIndex( value ); + if (idx>=0) + txt = property()->listData()->names[ idx ]; + } + + Widget::drawViewer(p, cg, r, txt); //keyForValue(value)); +// p->eraseRect(r); +// p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, keyForValue(value)); +} + +void +ComboBox::fillBox() +{ + m_edit->clear(); + //m_edit->clearContents(); + + if(!property()) + return; + if (!property()->listData()) { + kopropertywarn << "ComboBox::fillBox(): propery listData not available!" << endl; + return; + } + + m_edit->insertStringList(property()->listData()->names); + KCompletion *comp = m_edit->completionObject(); + comp->insertItems(property()->listData()->names); + comp->setCompletionMode(KGlobalSettings::CompletionShell); +} + +void +ComboBox::setProperty(Property *prop) +{ + const bool b = (property() == prop); + m_setValueEnabled = false; //setValue() couldn't be called before fillBox() + Widget::setProperty(prop); + m_setValueEnabled = true; + if(!b) + fillBox(); + if(prop) + setValue(prop->value(), false); //now the value can be set +} + +void +ComboBox::slotValueChanged(int) +{ + emit valueChanged(this); +} + +void +ComboBox::setReadOnlyInternal(bool readOnly) +{ + setVisibleFlag(!readOnly); +} + + +/*QString +ComboBox::keyForValue(const QVariant &value) +{ + const QMap *list = property()->valueList(); + Property::ListData *list = property()->listData(); + + if (!list) + return QString::null; + int idx = listData->keys.findIndex( value ); + + + QMap::ConstIterator endIt = list->constEnd(); + for(QMap::ConstIterator it = list->constBegin(); it != endIt; ++it) { + if(it.data() == value) + return it.key(); + } + return QString::null; +}*/ + + +#include "combobox.moc" + diff --git a/lib/koproperty/editors/combobox.h b/lib/koproperty/editors/combobox.h new file mode 100644 index 00000000..5d1f56f9 --- /dev/null +++ b/lib/koproperty/editors/combobox.h @@ -0,0 +1,59 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_COMBOBOX_H +#define KPROPERTY_COMBOBOX_H + +#include "../widget.h" + +class KComboBox; + +namespace KoProperty { + +class KOPROPERTY_EXPORT ComboBox : public Widget +{ + Q_OBJECT + + public: + ComboBox(Property *property, QWidget *parent=0, const char *name=0); + virtual ~ComboBox(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void setProperty(Property *property); + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected slots: + void slotValueChanged(int value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + QString keyForValue(const QVariant &value); + void fillBox(); + + KComboBox *m_edit; + bool m_setValueEnabled : 1; +}; + +} + +#endif + diff --git a/lib/koproperty/editors/cursoredit.cpp b/lib/koproperty/editors/cursoredit.cpp new file mode 100644 index 00000000..a0b3227c --- /dev/null +++ b/lib/koproperty/editors/cursoredit.cpp @@ -0,0 +1,138 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "cursoredit.h" + +#include +#include +#include + +#include +#include + +#include "property.h" + +using namespace KoProperty; + +//QMap *CursorEdit::m_spValues = 0; +Property::ListData *m_cursorListData = 0; + + +CursorEdit::CursorEdit(Property *property, QWidget *parent, const char *name) +: ComboBox(property, parent, name) +{ + /* + if(!m_spValues) { + m_spValues = new QMap(); + (*m_spValues)[i18n("Arrow")] = Qt::ArrowCursor; + (*m_spValues)[i18n("Up Arrow")] = Qt::UpArrowCursor; + (*m_spValues)[i18n("Cross")] = Qt::CrossCursor; + (*m_spValues)[i18n("Waiting")] = Qt::WaitCursor; + (*m_spValues)[i18n("iBeam")] = Qt::IbeamCursor; + (*m_spValues)[i18n("Size Vertical")] = Qt::SizeVerCursor; + (*m_spValues)[i18n("Size Horizontal")] = Qt::SizeHorCursor; + (*m_spValues)[i18n("Size Slash")] = Qt::SizeBDiagCursor; + (*m_spValues)[i18n("Size Backslash")] = Qt::SizeFDiagCursor; + (*m_spValues)[i18n("Size All")] = Qt::SizeAllCursor; + (*m_spValues)[i18n("Blank")] = Qt::BlankCursor; + (*m_spValues)[i18n("Split Vertical")] = Qt::SplitVCursor; + (*m_spValues)[i18n("Split Horizontal")] = Qt::SplitHCursor; + (*m_spValues)[i18n("Pointing Hand")] = Qt::PointingHandCursor; + (*m_spValues)[i18n("Forbidden")] = Qt::ForbiddenCursor; + (*m_spValues)[i18n("What's this")] = Qt::WhatsThisCursor; + }*/ + +//! @todo NOT THREAD-SAFE + if (!m_cursorListData) { + QValueList keys; + keys + << Qt::BlankCursor + << Qt::ArrowCursor + << Qt::UpArrowCursor + << Qt::CrossCursor + << Qt::WaitCursor + << Qt::IbeamCursor + << Qt::SizeVerCursor + << Qt::SizeHorCursor + << Qt::SizeBDiagCursor + << Qt::SizeFDiagCursor + << Qt::SizeAllCursor + << Qt::SplitVCursor + << Qt::SplitHCursor + << Qt::PointingHandCursor + << Qt::ForbiddenCursor + << Qt::WhatsThisCursor; + QStringList strings; + strings << i18n("Mouse Cursor Shape", "No Cursor") + << i18n("Mouse Cursor Shape", "Arrow") + << i18n("Mouse Cursor Shape", "Up Arrow") + << i18n("Mouse Cursor Shape", "Cross") + << i18n("Mouse Cursor Shape", "Waiting") + << i18n("Mouse Cursor Shape", "I") + << i18n("Mouse Cursor Shape", "Size Vertical") + << i18n("Mouse Cursor Shape", "Size Horizontal") + << i18n("Mouse Cursor Shape", "Size Slash") + << i18n("Mouse Cursor Shape", "Size Backslash") + << i18n("Mouse Cursor Shape", "Size All") + << i18n("Mouse Cursor Shape", "Split Vertical") + << i18n("Mouse Cursor Shape", "Split Horizontal") + << i18n("Mouse Cursor Shape", "Pointing Hand") + << i18n("Mouse Cursor Shape", "Forbidden") + << i18n("Mouse Cursor Shape", "What's This?"); + m_cursorListData = new Property::ListData(keys, strings); + } + + if(property) + property->setListData(new Property::ListData(*m_cursorListData)); +} + +CursorEdit::~CursorEdit() +{ + delete m_cursorListData; + m_cursorListData = 0; +} + +QVariant +CursorEdit::value() const +{ + return QCursor(ComboBox::value().toInt()); +} + +void +CursorEdit::setValue(const QVariant &value, bool emitChange) +{ + ComboBox::setValue(value.toCursor().shape(), emitChange); +} + +void +CursorEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + ComboBox::drawViewer(p, cg, r, value.toCursor().shape()); +} + +void +CursorEdit::setProperty(Property *prop) +{ + if(prop && prop != property()) + prop->setListData(new Property::ListData(*m_cursorListData)); + ComboBox::setProperty(prop); +} + +#include "cursoredit.moc" diff --git a/lib/koproperty/editors/cursoredit.h b/lib/koproperty/editors/cursoredit.h new file mode 100644 index 00000000..81587cc4 --- /dev/null +++ b/lib/koproperty/editors/cursoredit.h @@ -0,0 +1,50 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_CURSOREDIT_H +#define KPROPERTY_CURSOREDIT_H + +#include "combobox.h" + +template class QMap; + +namespace KoProperty { + +class KOPROPERTY_EXPORT CursorEdit : public ComboBox +{ + Q_OBJECT + + public: + CursorEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~CursorEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void setProperty(Property *property); + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + private: + static QMap *m_spValues; +}; + +} + +#endif diff --git a/lib/koproperty/editors/dateedit.cpp b/lib/koproperty/editors/dateedit.cpp new file mode 100644 index 00000000..797c0e5c --- /dev/null +++ b/lib/koproperty/editors/dateedit.cpp @@ -0,0 +1,89 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "dateedit.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace KoProperty; + +DateEdit::DateEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QDateEdit(this); + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMinimumHeight(5); + l->addWidget(m_edit); + + setLeavesTheSpaceForRevertButton(true); + + setFocusWidget(m_edit); + connect(m_edit, SIGNAL(valueChanged(const QDate&)), this, SLOT(slotValueChanged(const QDate&))); +} + +DateEdit::~DateEdit() +{} + +QVariant +DateEdit::value() const +{ + return m_edit->date(); +} + +void +DateEdit::setValue(const QVariant &value, bool emitChange) +{ + m_edit->blockSignals(true); + m_edit->setDate(value.toDate()); + m_edit->blockSignals(false); + if (emitChange) + emit valueChanged(this); +} + +void +DateEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + p->eraseRect(r); + Widget::drawViewer(p, cg, r, KGlobal::locale()->formatDate(value.toDate(), true /* use short format*/ )); +// p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, KGlobal::locale()->formatDate(value.toDate(), true /* use short format*/ )); +} + +void +DateEdit::slotValueChanged(const QDate&) +{ + emit valueChanged(this); +} + +void +DateEdit::setReadOnlyInternal(bool readOnly) +{ + setVisibleFlag(!readOnly); +} + +#include "dateedit.moc" diff --git a/lib/koproperty/editors/dateedit.h b/lib/koproperty/editors/dateedit.h new file mode 100644 index 00000000..509ae572 --- /dev/null +++ b/lib/koproperty/editors/dateedit.h @@ -0,0 +1,56 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_DATEEDIT_H +#define KPROPERTY_DATEEDIT_H + +#include "../widget.h" + +class QDateEdit; +class QDate; + +namespace KoProperty { + +class KOPROPERTY_EXPORT DateEdit : public Widget +{ + Q_OBJECT + + public: + DateEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~DateEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + + protected slots: + void slotValueChanged(const QDate &date); + + private: + QDateEdit *m_edit; +}; + +} + +#endif diff --git a/lib/koproperty/editors/datetimeedit.cpp b/lib/koproperty/editors/datetimeedit.cpp new file mode 100644 index 00000000..33bb8de3 --- /dev/null +++ b/lib/koproperty/editors/datetimeedit.cpp @@ -0,0 +1,89 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "datetimeedit.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace KoProperty; + +DateTimeEdit::DateTimeEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QDateTimeEdit(this); + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMinimumHeight(5); + l->addWidget(m_edit); + + setLeavesTheSpaceForRevertButton(true); + setFocusWidget(m_edit); + connect(m_edit, SIGNAL(valueChanged(const QDateTime&)), this, SLOT(slotValueChanged(const QDateTime&))); +} + +DateTimeEdit::~DateTimeEdit() +{} + +QVariant +DateTimeEdit::value() const +{ + return m_edit->dateTime(); +} + +void +DateTimeEdit::setValue(const QVariant &value, bool emitChange) +{ + m_edit->blockSignals(true); + m_edit->setDateTime(value.toDateTime()); + m_edit->blockSignals(false); + if (emitChange) + emit valueChanged(this); +} + +void +DateTimeEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + p->eraseRect(r); + Widget::drawViewer(p, cg, r, KGlobal::locale()->formatDateTime(value.toDateTime(), true /* use short format*/, false /*no sec */ )); +// p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, +// KGlobal::locale()->formatDateTime(value.toDateTime(), true /* use short format*/, false /*no sec */ )); +} + +void +DateTimeEdit::slotValueChanged(const QDateTime&) +{ + emit valueChanged(this); +} + +void +DateTimeEdit::setReadOnlyInternal(bool readOnly) +{ + setVisibleFlag(!readOnly); +} + +#include "datetimeedit.moc" diff --git a/lib/koproperty/editors/datetimeedit.h b/lib/koproperty/editors/datetimeedit.h new file mode 100644 index 00000000..f7b81795 --- /dev/null +++ b/lib/koproperty/editors/datetimeedit.h @@ -0,0 +1,56 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_DATETIMEEDIT_H +#define KPROPERTY_DATETIMEEDIT_H + +#include "../widget.h" + +class QDateTimeEdit; +class QDateTime; + +namespace KoProperty { + +class KOPROPERTY_EXPORT DateTimeEdit : public Widget +{ + Q_OBJECT + + public: + DateTimeEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~DateTimeEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + + protected slots: + void slotValueChanged(const QDateTime &dateTime); + + private: + QDateTimeEdit *m_edit; +}; + +} + +#endif diff --git a/lib/koproperty/editors/dummywidget.cpp b/lib/koproperty/editors/dummywidget.cpp new file mode 100644 index 00000000..9c72c8cd --- /dev/null +++ b/lib/koproperty/editors/dummywidget.cpp @@ -0,0 +1,63 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "dummywidget.h" + +#include + +using namespace KoProperty; + +DummyWidget::DummyWidget(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{} + +DummyWidget::~DummyWidget() +{} + +QVariant +DummyWidget::value() const +{ + return m_value; +} + +void +DummyWidget::setValue(const QVariant &value, bool emitChange) +{ + m_value = value; + if(emitChange) + emit valueChanged(this); +} + +void +DummyWidget::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &) +{ + p->setBrush(cg.background()); + p->setPen(Qt::NoPen); + p->drawRect(r); +} + +void +DummyWidget::setReadOnlyInternal(bool readOnly) +{ + Q_UNUSED(readOnly); +} + +#include "dummywidget.moc" + diff --git a/lib/koproperty/editors/dummywidget.h b/lib/koproperty/editors/dummywidget.h new file mode 100644 index 00000000..b85ccb95 --- /dev/null +++ b/lib/koproperty/editors/dummywidget.h @@ -0,0 +1,53 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_DUMMYWIDGET_H +#define KPROPERTY_DUMMYWIDGET_H + +#include "../widget.h" + +#include + +namespace KoProperty { + +class KOPROPERTY_EXPORT DummyWidget: public Widget +{ + Q_OBJECT + + public: + DummyWidget(Property *property, QWidget *parent=0, const char *name=0); + virtual ~DummyWidget(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + + private: + QVariant m_value; +}; + +} + +#endif + diff --git a/lib/koproperty/editors/fontedit.cpp b/lib/koproperty/editors/fontedit.cpp new file mode 100644 index 00000000..9d0101fa --- /dev/null +++ b/lib/koproperty/editors/fontedit.cpp @@ -0,0 +1,156 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2005 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "fontedit.h" +#include "editoritem.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +//! @internal +//! reimplemented to better button and label's positioning + +namespace KoProperty { + +class FontEditRequester : public KFontRequester +{ + public: + FontEditRequester(QWidget* parent) + : KFontRequester(parent) + { + label()->setPaletteBackgroundColor(palette().active().base()); + label()->setMinimumWidth(0); + label()->setFrameShape(QFrame::Box); + label()->setIndent(-1); +#if KDE_VERSION >= KDE_MAKE_VERSION(3,4,0) + label()->setFocusPolicy(ClickFocus); + KAcceleratorManager::setNoAccel(label()); +#endif + layout()->remove(label()); + layout()->remove(button());//->reparent(this, 0, QPoint(0,0)); + delete layout(); + button()->setText(i18n("...")); + QToolTip::add(button(), i18n("Change font")); + button()->setFocusPolicy(NoFocus); + button()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + QFontMetrics fm(button()->font()); + button()->setFixedWidth(fm.width(button()->text()+' ')); + } + virtual void resizeEvent(QResizeEvent *e) + { + KFontRequester::resizeEvent(e); + label()->move(0,0); + label()->resize(e->size()-QSize(button()->width(),-1)); + button()->move(label()->width(),0); + button()->setFixedSize(button()->width(), height()); + } +}; + +} + +using namespace KoProperty; + +FontEdit::FontEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + m_edit = new FontEditRequester(this); + m_edit->setMinimumHeight(5); + setEditor(m_edit); + setFocusWidget(m_edit->label()); + connect(m_edit, SIGNAL(fontSelected(const QFont& )), this, SLOT(slotValueChanged(const QFont&))); +} + +FontEdit::~FontEdit() +{} + +QVariant +FontEdit::value() const +{ + return m_edit->font(); +} + +static QString sampleText(const QVariant &value) +{ + QFontInfo fi(value.toFont()); + return fi.family() + (fi.bold() ? " " + i18n("Bold") : QString()) + + (fi.italic() ? " " + i18n("Italic") : QString::null) + + " " + QString::number(fi.pointSize()); +} + +void +FontEdit::setValue(const QVariant &value, bool emitChange) +{ + m_edit->blockSignals(true); + m_edit->setFont(value.toFont()); + m_edit->blockSignals(false); + m_edit->setSampleText(sampleText(value)); + if (emitChange) + emit valueChanged(this); +} + +void +FontEdit::drawViewer(QPainter *p, const QColorGroup &, const QRect &r, const QVariant &value) +{ + p->eraseRect(r); + p->setFont(value.toFont()); + QRect r2(r); + r2.setLeft(r2.left()+KPROPEDITOR_ITEM_MARGIN); + r2.setBottom(r2.bottom()+1); + p->drawText(r2, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, sampleText(value)); +} + +void +FontEdit::slotValueChanged(const QFont &) +{ + emit valueChanged(this); +} + +bool +FontEdit::eventFilter(QObject* watched, QEvent* e) +{ + if(e->type() == QEvent::KeyPress) { + QKeyEvent* ev = static_cast(e); + if(ev->key() == Key_Space) { + m_edit->button()->animateClick(); + return true; + } + } + return Widget::eventFilter(watched, e); +} + +void +FontEdit::setReadOnlyInternal(bool readOnly) +{ + setVisibleFlag(!readOnly); +} + +#include "fontedit.moc" diff --git a/lib/koproperty/editors/fontedit.h b/lib/koproperty/editors/fontedit.h new file mode 100644 index 00000000..0112171a --- /dev/null +++ b/lib/koproperty/editors/fontedit.h @@ -0,0 +1,57 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2005 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_FONTEDIT_H +#define KPROPERTY_FONTEDIT_H + +#include "widget.h" + +namespace KoProperty { + +class FontEditRequester; + +class KOPROPERTY_EXPORT FontEdit : public Widget +{ + Q_OBJECT + + public: + FontEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~FontEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + virtual bool eventFilter(QObject* watched, QEvent* e); + + protected slots: + void slotValueChanged(const QFont &font); + + private: + FontEditRequester *m_edit; +}; + +} + +#endif diff --git a/lib/koproperty/editors/linestyledit.cpp b/lib/koproperty/editors/linestyledit.cpp new file mode 100644 index 00000000..0d2353ff --- /dev/null +++ b/lib/koproperty/editors/linestyledit.cpp @@ -0,0 +1,225 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "linestyleedit.h" +#include "editoritem.h" + +#include +#include +#include +#include +#include + +using namespace KoProperty; + + //! @internal + static const char *nopen[]={ + "48 16 1 1", + ". c None", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................"}; + //! @internal + static const char *solid[]={ + "48 16 2 1", + ". c None", + "# c #000000", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + ".###########################################....", + ".###########################################....", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................"}; + //! @internal + static const char *dash[]={ + "48 16 2 1", + ". c None", + "# c #000000", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + ".#########..#########..#########..##########....", + ".#########..#########..#########..##########....", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................"}; + //! @internal + static const char *dashdot[]={ + "48 16 2 1", + ". c None", + "# c #000000", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + ".#########..##..#########..##..#########..##....", + ".#########..##..#########..##..#########..##....", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................"}; + //! @internal + static const char *dashdotdot[]={ + "48 16 2 1", + ". c None", + "# c #000000", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + ".#########..##..##..#########..##..##..#####....", + ".#########..##..##..#########..##..##..#####....", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................", + "................................................"}; + + +LineStyleEdit::LineStyleEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QComboBox(this); + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMinimumHeight(5); + 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)); + + setLeavesTheSpaceForRevertButton(true); + setFocusWidget(m_edit); + connect(m_edit, SIGNAL(activated(int)), this, SLOT(slotValueChanged(int))); +} + +LineStyleEdit::~LineStyleEdit() +{} + +QVariant +LineStyleEdit::value() const +{ + return m_edit->currentItem(); +} + +void +LineStyleEdit::setValue(const QVariant &value, bool emitChange) +{ + if (!value.canCast(QVariant::Int)) + return; + if ((value.toInt() > 5) || (value.toInt() < 0)) + return; + + m_edit->blockSignals(true); + m_edit->setCurrentItem(value.toInt()); + m_edit->blockSignals(false); + if (emitChange) + emit valueChanged(this); +} + +void +LineStyleEdit::drawViewer(QPainter *p, const QColorGroup &, const QRect &r, const QVariant &value) +{ + p->eraseRect(r); + + if (!value.canCast(QVariant::Int)) + return; + + QPixmap px; + switch (value.toInt()) { + case 0: + px = QPixmap(nopen); + break; + case 1: + px = QPixmap(solid); + break; + case 2: + px = QPixmap(dash); + break; + case 3: + px = QPixmap(dashdot); + break; + case 4: + px = QPixmap(dashdotdot); + break; + default: + return; + } + p->drawPixmap(r.left()+KPROPEDITOR_ITEM_MARGIN, r.top()+(r.height()-px.height())/2, px); +} + +void +LineStyleEdit::slotValueChanged(int) +{ + emit valueChanged(this); +} + +void +LineStyleEdit::setReadOnlyInternal(bool readOnly) +{ + setVisibleFlag(!readOnly); +} + +#include "linestyleedit.moc" diff --git a/lib/koproperty/editors/linestyleedit.h b/lib/koproperty/editors/linestyleedit.h new file mode 100644 index 00000000..6392e2f7 --- /dev/null +++ b/lib/koproperty/editors/linestyleedit.h @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_LINESTYLEEDIT_H +#define KPROPERTY_LINESTYLEEDIT_H + +#include "../widget.h" + +class QComboBox; + +namespace KoProperty { + +class KOPROPERTY_EXPORT LineStyleEdit : public Widget +{ + Q_OBJECT + + public: + LineStyleEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~LineStyleEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + + protected slots: + void slotValueChanged(int value); + + private: + QComboBox *m_edit; +}; + +} + +#endif diff --git a/lib/koproperty/editors/pixmapedit.cpp b/lib/koproperty/editors/pixmapedit.cpp new file mode 100644 index 00000000..d141eed3 --- /dev/null +++ b/lib/koproperty/editors/pixmapedit.cpp @@ -0,0 +1,247 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2005 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "pixmapedit.h" +#include "editoritem.h" +#include "property.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef Q_WS_WIN +#include +#include +#endif + +#ifndef PURE_QT +#include +#include +#include +#endif + +using namespace KoProperty; + +PixmapEdit::PixmapEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + setHasBorders(false); + + m_edit = new QLabel(this, "m_edit"); + QToolTip::add(m_edit, i18n("Click to show image preview")); + m_edit->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + m_edit->setMinimumHeight(5); + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_edit->setBackgroundMode(Qt::PaletteBase); + m_edit->setMouseTracking(true); + setBackgroundMode(Qt::PaletteBase); + + m_button = new QPushButton(i18n("..."), this, "m_button"); + QToolTip::add(m_button, i18n("Insert image from file")); + m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + QFontMetrics fm(m_button->font()); + m_button->setFixedWidth(fm.width(m_button->text()+' ')); + m_button->setFocusPolicy(NoFocus); + + m_popup = new QLabel(0, "m_popup", Qt::WStyle_Customize|Qt::WStyle_NoBorder|Qt::WX11BypassWM|WStyle_StaysOnTop); + m_popup->setPaletteBackgroundColor(m_popup->palette().active().base()); + m_popup->setFrameStyle(QFrame::Plain|QFrame::Box); + m_popup->setMargin(2); + m_popup->setLineWidth(1); + m_popup->hide(); + + setFocusWidget(m_edit); + connect(m_button, SIGNAL(clicked()), this, SLOT(selectPixmap())); +} + +PixmapEdit::~PixmapEdit() +{ + delete m_popup; +} + +QVariant +PixmapEdit::value() const +{ + return m_pixmap; +} + +void +PixmapEdit::setValue(const QVariant &value, bool emitChange) +{ + m_pixmap = value.toPixmap(); + if (m_pixmap.isNull() || (m_pixmap.height()<=height())) { + m_edit->setPixmap(m_pixmap); + m_previewPixmap = m_pixmap; + } + else { + QImage img(m_pixmap.convertToImage()); + if (!QRect(QPoint(0,0), m_edit->size()*3).contains(m_pixmap.rect())) { + img = img.smoothScale(m_edit->size()*3, QImage::ScaleMin); + m_previewPixmap.convertFromImage(img);//preview pixmap is a bit larger + } + else { + m_previewPixmap = m_pixmap; + } + img = img.smoothScale(m_edit->size(), QImage::ScaleMin); + QPixmap pm; + pm.convertFromImage(img); + m_edit->setPixmap(pm); + } + if (emitChange) + emit valueChanged(this); +} + +void +PixmapEdit::drawViewer(QPainter *p, const QColorGroup &, const QRect &r, const QVariant &value) +{ + QRect r2(r); + r2.setHeight(r2.height()+1); + p->setClipRect(r2, QPainter::CoordPainter); + p->setClipping(true); + p->eraseRect(r2); + if (value.toPixmap().isNull()) + return; + if (m_recentlyPainted!=value) { + m_recentlyPainted = value; + m_scaledPixmap = value.toPixmap(); + if (m_scaledPixmap.height() > r2.height() || m_scaledPixmap.width() > r2.width()) { //scale down + QImage img(m_scaledPixmap.convertToImage()); + img = img.smoothScale(r2.size()/*+QSize(0,2)*/, QImage::ScaleMin); + m_scaledPixmap.convertFromImage(img); + } + } + p->drawPixmap(r2.topLeft().x(), //+KPROPEDITOR_ITEM_MARGIN, + r2.topLeft().y()+(r2.height()-m_scaledPixmap.height())/2, m_scaledPixmap); +} + +QString +PixmapEdit::selectPixmapFileName() +{ +/*#ifdef PURE_QT + QString url = QFileDialog::getOpenFileName(); + if (!url.isEmpty()) { + m_edit->setPixmap(QPixmap(url)); + emit valueChanged(this); + } +#endif*/ + QString caption( i18n("Insert Image From File (for \"%1\" property)").arg(property()->caption()) ); +#ifdef Q_WS_WIN + QString recentDir; + QString fileName = QFileDialog::getOpenFileName( + KFileDialog::getStartURL(":lastVisitedImagePath", recentDir).path(), + convertKFileDialogFilterToQFileDialogFilter(KImageIO::pattern(KImageIO::Reading)), + this, 0, caption); +#else + KURL url( KFileDialog::getImageOpenURL( + ":lastVisitedImagePath", this, caption) ); + QString fileName = url.isLocalFile() ? url.path() : url.prettyURL(); + + //! @todo download the file if remote, then set fileName properly +#endif + return fileName; +} + +void +PixmapEdit::selectPixmap() +{ + QString fileName( selectPixmapFileName() ); + if (fileName.isEmpty()) + return; + + QPixmap pm; + if (!pm.load(fileName)) { + //! @todo err msg + return; + } + setValue(pm); + +#ifdef Q_WS_WIN + //save last visited path + KURL url(fileName); + if (url.isLocalFile()) + KRecentDirs::add(":lastVisitedImagePath", url.directory()); +#endif +} + +void +PixmapEdit::resizeEvent(QResizeEvent *e) +{ + Widget::resizeEvent(e); + m_edit->move(0,0); + m_edit->resize(e->size()-QSize(m_button->width(),-1)); + m_button->move(m_edit->width(),0); + m_button->setFixedSize(m_button->width(), height()); +} + +bool +PixmapEdit::eventFilter(QObject *o, QEvent *ev) +{ + if(o == m_edit) { + if(ev->type() == QEvent::MouseButtonPress && static_cast(ev)->button()==LeftButton) { + if(m_previewPixmap.height() <= m_edit->height() + && m_previewPixmap.width() <= m_edit->width()) + return false; + + m_popup->setPixmap(m_previewPixmap.isNull() ? m_pixmap : m_previewPixmap); + m_popup->resize(m_previewPixmap.size()+QSize(2*3,2*3)); + QPoint pos = QCursor::pos()+QPoint(3,15); + QRect screenRect = QApplication::desktop()->availableGeometry( this ); + if ((pos.x()+m_popup->width()) > screenRect.width()) + pos.setX(screenRect.width()-m_popup->width()); + if ((pos.y()+m_popup->height()) > screenRect.height()) + pos.setY(mapToGlobal(QPoint(0,0)).y()-m_popup->height()); + m_popup->move(pos); + m_popup->show(); + } + else if(ev->type() == QEvent::MouseButtonRelease || ev->type() == QEvent::Hide) { + if(m_popup->isVisible()) + m_popup->hide(); + } + else if(ev->type() == QEvent::KeyPress) { + QKeyEvent* e = static_cast(ev); + if((e->key() == Key_Enter) || (e->key()== Key_Space) || (e->key() == Key_Return)) { + m_button->animateClick(); + return true; + } + } + } + + return Widget::eventFilter(o, ev); +} + +void +PixmapEdit::setReadOnlyInternal(bool readOnly) +{ + m_button->setEnabled(!readOnly); +} + +#include "pixmapedit.moc" diff --git a/lib/koproperty/editors/pixmapedit.h b/lib/koproperty/editors/pixmapedit.h new file mode 100644 index 00000000..7b0268bf --- /dev/null +++ b/lib/koproperty/editors/pixmapedit.h @@ -0,0 +1,72 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2005 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_PIXMAPEDIT_H +#define KPROPERTY_PIXMAPEDIT_H + +#include "../widget.h" +#include +#include + +class QLabel; +class QPushButton; + +namespace KoProperty { + +class KOPROPERTY_EXPORT PixmapEdit : public Widget +{ + Q_OBJECT + + public: + PixmapEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~PixmapEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + void resizeEvent(QResizeEvent *ev); + bool eventFilter(QObject *o, QEvent *ev); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + + protected slots: + /*! Helper used by selectPixmap(). Can be also used by subclassess. + Selected path will be stored in "lastVisitedImagePath" config entry within "Recent Dirs" + config group of application's settings. This entry can be later reused when file dialogs + are opened for selecting image files. */ + QString selectPixmapFileName(); + + /*! Selects a new pixmap using "open" file dialog. Can be reimplemented. */ + virtual void selectPixmap(); + + protected: + QLabel *m_edit; + QLabel *m_popup; + QPushButton *m_button; + QVariant m_recentlyPainted; + QPixmap m_pixmap, m_scaledPixmap, m_previewPixmap; +}; + +} + +#endif diff --git a/lib/koproperty/editors/pointedit.cpp b/lib/koproperty/editors/pointedit.cpp new file mode 100644 index 00000000..60d74a89 --- /dev/null +++ b/lib/koproperty/editors/pointedit.cpp @@ -0,0 +1,91 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "pointedit.h" +#include "editoritem.h" + +#include +#include +#include +#include + +#include +#include + +//"[ %1, %2 ]" +#define POINTEDIT_MASK "%1,%2" + +using namespace KoProperty; + +PointEdit::PointEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + setHasBorders(false); + m_edit = new KActiveLabel(this); + m_edit->setFocusPolicy(NoFocus); +// m_edit->setIndent(KPROPEDITOR_ITEM_MARGIN); + m_edit->setPaletteBackgroundColor(palette().active().base()); + m_edit->setWordWrap( QTextEdit::NoWrap ); +// m_edit->setBackgroundMode(Qt::PaletteBase); +// m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMinimumHeight(5); + setEditor(m_edit); +// setFocusWidget(m_edit); +} + +PointEdit::~PointEdit() +{} + +QVariant +PointEdit::value() const +{ + return m_value; +} + +void +PointEdit::setValue(const QVariant &value, bool emitChange) +{ + m_value = value; + m_edit->selectAll(false); + m_edit->setText(QString(POINTEDIT_MASK).arg(value.toPoint().x()).arg(value.toPoint().y())); + QToolTip::add(this, QString("%1, %2").arg(value.toPoint().x()).arg(value.toPoint().y())); + + if (emitChange) + emit valueChanged(this); +} + +void +PointEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + QRect rect(r); + rect.setBottom(r.bottom()+1); + Widget::drawViewer(p, cg, rect, QString(POINTEDIT_MASK).arg(value.toPoint().x()).arg(value.toPoint().y())); +// p->eraseRect(r); +// p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, +// QString("[ %1, %2 ]").arg(value.toPoint().x()).arg(value.toPoint().y())); +} + +void +PointEdit::setReadOnlyInternal(bool readOnly) +{ + Q_UNUSED(readOnly); +} + +#include "pointedit.moc" diff --git a/lib/koproperty/editors/pointedit.h b/lib/koproperty/editors/pointedit.h new file mode 100644 index 00000000..bba2fda1 --- /dev/null +++ b/lib/koproperty/editors/pointedit.h @@ -0,0 +1,56 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_POINTEDIT_H +#define KPROPERTY_POINTEDIT_H + +#include "../widget.h" + +#include + +class KActiveLabel; + +namespace KoProperty { + +class KOPROPERTY_EXPORT PointEdit : public Widget +{ + Q_OBJECT + + public: + PointEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~PointEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + + private: + KActiveLabel *m_edit; + QVariant m_value; +}; + +} + +#endif + diff --git a/lib/koproperty/editors/rectedit.cpp b/lib/koproperty/editors/rectedit.cpp new file mode 100644 index 00000000..4f495b60 --- /dev/null +++ b/lib/koproperty/editors/rectedit.cpp @@ -0,0 +1,92 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ +#include "rectedit.h" +#include "editoritem.h" + +#include +#include +#include +#include + +#include +#include + +// "[ %1, %2, %3, %4 ]" +#define RECTEDIT_MASK "%1,%2 %3x%4" + +using namespace KoProperty; + +RectEdit::RectEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + setHasBorders(false); + m_edit = new KActiveLabel(this); + m_edit->setFocusPolicy(NoFocus); + m_edit->setPaletteBackgroundColor(palette().active().base()); + m_edit->setWordWrap( QTextEdit::NoWrap ); + m_edit->setMinimumHeight(5); + setEditor(m_edit); +// setFocusWidget(m_edit); +} + +RectEdit::~RectEdit() +{} + +QVariant +RectEdit::value() const +{ + return m_value; +} + +void +RectEdit::setValue(const QVariant &value, bool emitChange) +{ + m_value = value; + m_edit->selectAll(false); + m_edit->setText(QString(RECTEDIT_MASK).arg(value.toRect().x()). + arg(value.toRect().y()).arg(value.toRect().width()).arg(value.toRect().height())); + QToolTip::add(this, i18n("Position: %1, %2\nSize: %3 x %4").arg(value.toRect().x()). + arg(value.toRect().y()).arg(value.toRect().width()).arg(value.toRect().height())); + + if (emitChange) + emit valueChanged(this); +} + +void +RectEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + QRect rect(r); + rect.setBottom(r.bottom()+1); + Widget::drawViewer(p, cg, rect, + QString(RECTEDIT_MASK).arg(value.toRect().x()).arg(value.toRect().y()) + .arg(value.toRect().width()).arg(value.toRect().height())); +// p->eraseRect(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 +RectEdit::setReadOnlyInternal(bool readOnly) +{ + Q_UNUSED(readOnly); +} + +#include "rectedit.moc" diff --git a/lib/koproperty/editors/rectedit.h b/lib/koproperty/editors/rectedit.h new file mode 100644 index 00000000..fe1f7e74 --- /dev/null +++ b/lib/koproperty/editors/rectedit.h @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_RECTEDIT_H +#define KPROPERTY_RECTEDIT_H + +#include "../widget.h" + +#include + +class KActiveLabel; + +namespace KoProperty { + +class KOPROPERTY_EXPORT RectEdit : public Widget +{ + Q_OBJECT + + public: + RectEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~RectEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + + private: + KActiveLabel *m_edit; + QVariant m_value; +}; + +} + +#endif diff --git a/lib/koproperty/editors/sizeedit.cpp b/lib/koproperty/editors/sizeedit.cpp new file mode 100644 index 00000000..e8a0c339 --- /dev/null +++ b/lib/koproperty/editors/sizeedit.cpp @@ -0,0 +1,91 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "sizeedit.h" +#include "editoritem.h" + +#include +#include +#include +#include + +#include +#include + +//"[ %1, %2 ]" +#define SIZEEDIT_MASK "%1x%2" + +using namespace KoProperty; + +SizeEdit::SizeEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + setHasBorders(false); + m_edit = new KActiveLabel(this); + m_edit->setFocusPolicy(NoFocus); +// m_edit->setIndent(KPROPEDITOR_ITEM_MARGIN); + m_edit->setPaletteBackgroundColor(palette().active().base()); +// m_edit->setBackgroundMode(Qt::PaletteBase); +// m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMinimumHeight(5); + setEditor(m_edit); +// setFocusWidget(m_edit); +} + +SizeEdit::~SizeEdit() +{} + +QVariant +SizeEdit::value() const +{ + return m_value; +} + +void +SizeEdit::setValue(const QVariant &value, bool emitChange) +{ + m_value = value; + m_edit->selectAll(false); + m_edit->setText(QString(SIZEEDIT_MASK).arg(value.toSize().width()).arg(value.toSize().height())); + QToolTip::add(this, QString("%1 x %2").arg(value.toSize().width()).arg(value.toSize().height())); + + if (emitChange) + emit valueChanged(this); +} + +void +SizeEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + QRect rect(r); + rect.setBottom(r.bottom()+1); + Widget::drawViewer(p, cg, rect, + QString(SIZEEDIT_MASK).arg(value.toSize().width()).arg(value.toSize().height())); +// p->eraseRect(r); +// p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, +// QString("[ %1, %2 ]").arg(value.toSize().width()).arg(value.toSize().height())); +} + +void +SizeEdit::setReadOnlyInternal(bool readOnly) +{ + Q_UNUSED(readOnly); +} + +#include "sizeedit.moc" diff --git a/lib/koproperty/editors/sizeedit.h b/lib/koproperty/editors/sizeedit.h new file mode 100644 index 00000000..0fe96c64 --- /dev/null +++ b/lib/koproperty/editors/sizeedit.h @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_SIZEEDIT_H +#define KPROPERTY_SIZEEDIT_H + +#include "../widget.h" + +#include + +class KActiveLabel; + +namespace KoProperty { + +class KOPROPERTY_EXPORT SizeEdit : public Widget +{ + Q_OBJECT + + public: + SizeEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~SizeEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + + private: + KActiveLabel *m_edit; + QVariant m_value; +}; + +} + +#endif diff --git a/lib/koproperty/editors/sizepolicyedit.cpp b/lib/koproperty/editors/sizepolicyedit.cpp new file mode 100644 index 00000000..c04c9579 --- /dev/null +++ b/lib/koproperty/editors/sizepolicyedit.cpp @@ -0,0 +1,122 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "sizepolicyedit.h" +#include "editoritem.h" + +#include +#include +#include +#include +#include +#include + +#include + +using namespace KoProperty; + +QMap *SizePolicyEdit::m_spValues = 0; + +SizePolicyEdit::SizePolicyEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + setHasBorders(false); +// QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QLabel(this); + m_edit->setIndent(KPROPEDITOR_ITEM_MARGIN); + m_edit->setBackgroundMode(Qt::PaletteBase); +// m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMinimumHeight(5); + setEditor(m_edit); +// l->addWidget(m_edit); + setFocusWidget(m_edit); + + + if(!m_spValues) { + m_spValues = new QMap(); + (*m_spValues)[i18n("Size Policy", "Fixed")] = QSizePolicy::Fixed; + (*m_spValues)[i18n("Size Policy", "Minimum")] = QSizePolicy::Minimum; + (*m_spValues)[i18n("Size Policy", "Maximum")] = QSizePolicy::Maximum; + (*m_spValues)[i18n("Size Policy", "Preferred")] = QSizePolicy::Preferred; + (*m_spValues)[i18n("Size Policy", "Expanding")] = QSizePolicy::Expanding; + (*m_spValues)[i18n("Size Policy", "Minimum Expanding")] = QSizePolicy::MinimumExpanding; + (*m_spValues)[i18n("Size Policy", "Ignored")] = QSizePolicy::Ignored; + } +} + +SizePolicyEdit::~SizePolicyEdit() +{ + delete m_spValues; + m_spValues = 0; +} + +QVariant +SizePolicyEdit::value() const +{ + return m_value; +} + +void +SizePolicyEdit::setValue(const QVariant &value, bool emitChange) +{ + m_value = value; + m_edit->setText(QString("%1/%2/%3/%4").arg(findDescription(value.toSizePolicy().horData())). + arg(findDescription(value.toSizePolicy().verData())). + arg(value.toSizePolicy().horStretch()).arg(value.toSizePolicy().verStretch())); + QToolTip::add(this, m_edit->text()); + + if (emitChange) + emit valueChanged(this); +} + +void +SizePolicyEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ +// p->eraseRect(r); +// p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, + QRect rect(r); + rect.setBottom(r.bottom()+1); + Widget::drawViewer(p, cg, rect, + QString("%1/%2/%3/%4").arg(findDescription(value.toSizePolicy().horData())). + arg(findDescription(value.toSizePolicy().verData())). + arg(value.toSizePolicy().horStretch()).arg(value.toSizePolicy().verStretch())); +} + +QString +SizePolicyEdit::findDescription(const QVariant &value) const +{ + if(!m_spValues) + return QString::null; + + QMap::ConstIterator endIt = m_spValues->constEnd(); + for (QMap::ConstIterator it = m_spValues->constBegin(); it != endIt; ++ it) { + if (it.data() == value) + return it.key(); + } + return QString::null;; +} + +void +SizePolicyEdit::setReadOnlyInternal(bool readOnly) +{ + Q_UNUSED(readOnly); +} + +#include "sizepolicyedit.moc" diff --git a/lib/koproperty/editors/sizepolicyedit.h b/lib/koproperty/editors/sizepolicyedit.h new file mode 100644 index 00000000..0edd3b38 --- /dev/null +++ b/lib/koproperty/editors/sizepolicyedit.h @@ -0,0 +1,59 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_SIZEPOLICYEDIT_H +#define KPROPERTY_SIZEPOLICYEDIT_H + +#include "../widget.h" + +#include + +template class QMap; + +class QLabel; + +namespace KoProperty { + +class KOPROPERTY_EXPORT SizePolicyEdit : public Widget +{ + Q_OBJECT + + public: + SizePolicyEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~SizePolicyEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + QString findDescription(const QVariant &value) const; + + private: + QVariant m_value; + QLabel *m_edit; + static QMap *m_spValues; +}; + +} + +#endif diff --git a/lib/koproperty/editors/spinbox.cpp b/lib/koproperty/editors/spinbox.cpp new file mode 100644 index 00000000..2e4bcc7c --- /dev/null +++ b/lib/koproperty/editors/spinbox.cpp @@ -0,0 +1,329 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "spinbox.h" + +#include "property.h" + +#include +#include +#include +#include +#include + +#include +#include + +using namespace KoProperty; + +IntSpinBox::IntSpinBox(int lower, int upper, int step, int value, int base, IntEdit *parent, const char *name) +: KIntSpinBox(lower, upper, step, value, base, parent, name) +{ + editor()->setAlignment(Qt::AlignLeft); + installEventFilter(editor()); + installEventFilter(this); + QObjectList *spinwidgets = queryList( "QSpinWidget", 0, false, true ); + QSpinWidget* spin = static_cast(spinwidgets->first()); + if (spin) + spin->installEventFilter(this); + delete spinwidgets; +} + +void IntSpinBox::setValue(const QVariant &value) +{ + if (dynamic_cast(parentWidget()) && dynamic_cast(parentWidget())->isReadOnly()) + return; + if (value.isNull()) + editor()->clear(); + else + KIntSpinBox::setValue(value.toInt()); +} + +bool +IntSpinBox::eventFilter(QObject *o, QEvent *e) +{ + if(o == editor()) + { + if(e->type() == QEvent::KeyPress) + { + QKeyEvent* ev = static_cast(e); + if((ev->key()==Key_Up || ev->key()==Key_Down) && ev->state() !=ControlButton) + { + parentWidget()->eventFilter(o, e); + return true; + } + } + } + if ((o == editor() || o == this || o->parent() == this) + && e->type() == QEvent::Wheel && static_cast(parentWidget())->isReadOnly()) + { + return true; //avoid value changes for read-only widget + } + + return KIntSpinBox::eventFilter(o, e); +} + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +IntEdit::IntEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + QVariant minVal( property ? property->option("min") : 0 ); + QVariant maxVal( property ? property->option("max") : QVariant() ); + QVariant minValueText( property ? property->option("minValueText") : QVariant() ); + if (minVal.isNull()) + minVal = 0; + if (maxVal.isNull()) + maxVal = INT_MAX; + + m_edit = new IntSpinBox(minVal.toInt(), maxVal.toInt(), 1, 0, 10, this); + if (!minValueText.isNull()) + m_edit->setSpecialValueText(minValueText.toString()); + m_edit->setMinimumHeight(5); + setEditor(m_edit); + + setLeavesTheSpaceForRevertButton(true); + setFocusWidget(m_edit); + connect(m_edit, SIGNAL(valueChanged(int)), this, SLOT(slotValueChanged(int))); +} + +IntEdit::~IntEdit() +{} + +QVariant +IntEdit::value() const +{ + if (m_edit->cleanText().isEmpty()) + return QVariant(); + return m_edit->value(); +} + +void +IntEdit::setValue(const QVariant &value, bool emitChange) +{ + m_edit->blockSignals(true); + m_edit->setValue(value); + updateSpinWidgets(); + m_edit->blockSignals(false); + if (emitChange) + emit valueChanged(this); +} + +void +IntEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + QString valueText = value.toString(); + if (property() && property()->hasOptions()) { + //replace min value with minValueText if defined + QVariant minValue( property()->option("min") ); + QVariant minValueText( property()->option("minValueText") ); + if (!minValue.isNull() && !minValueText.isNull() && minValue.toInt() == value.toInt()) { + valueText = minValueText.toString(); + } + } + + Widget::drawViewer(p, cg, r, valueText); +// p->eraseRect(r); +// p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, valueText); +} + +void +IntEdit::slotValueChanged(int) +{ + emit valueChanged(this); +} + +void +IntEdit::updateSpinWidgets() +{ + QObjectList *spinwidgets = queryList( "QSpinWidget", 0, false, true ); + QSpinWidget* spin = static_cast(spinwidgets->first()); + if (spin) { + spin->setUpEnabled(!isReadOnly()); + spin->setDownEnabled(!isReadOnly()); + } + delete spinwidgets; +} + +void +IntEdit::setReadOnlyInternal(bool readOnly) +{ + //disable editor and spin widget + m_edit->editor()->setReadOnly(readOnly); + updateSpinWidgets(); + if (readOnly) + setLeavesTheSpaceForRevertButton(false); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +DoubleSpinBox::DoubleSpinBox (double lower, double upper, double step, double value, int precision, DoubleEdit *parent) +: KDoubleSpinBox(lower, upper, step, value, precision, parent) +{ + editor()->setAlignment(Qt::AlignLeft); + installEventFilter(editor()); + installEventFilter(this); + QObjectList *spinwidgets = queryList( "QSpinWidget", 0, false, true ); + QSpinWidget* spin = static_cast(spinwidgets->first()); + if (spin) + spin->installEventFilter(this); + delete spinwidgets; +} + +bool +DoubleSpinBox::eventFilter(QObject *o, QEvent *e) +{ + if(o == editor()) + { + if(e->type() == QEvent::KeyPress) + { + QKeyEvent* ev = static_cast(e); + if((ev->key()==Key_Up || ev->key()==Key_Down) && ev->state()!=ControlButton) + { + parentWidget()->eventFilter(o, e); + return true; + } + } + } + if ((o == editor() || o == this || o->parent() == this) + && e->type() == QEvent::Wheel && static_cast(parentWidget())->isReadOnly()) + { + return true; //avoid value changes for read-only widget + } + + return KDoubleSpinBox::eventFilter(o, e); +} + + +void DoubleSpinBox::setValue( const QVariant& value ) +{ + if (dynamic_cast(parentWidget()) && dynamic_cast(parentWidget())->isReadOnly()) + return; + if (value.isNull()) + editor()->clear(); + else + KDoubleSpinBox::setValue(value.toDouble()); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +DoubleEdit::DoubleEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + QVariant minVal( property ? property->option("min") : 0 ); + QVariant maxVal( property ? property->option("max") : QVariant() ); + QVariant step( property ? property->option("step") : QVariant()); + QVariant precision( property ? property->option("precision") : QVariant()); + QVariant minValueText( property ? property->option("minValueText") : QVariant() ); + if (minVal.isNull()) + minVal = 0; + if (maxVal.isNull()) + maxVal = (double)(INT_MAX/100); + if(step.isNull()) + step = 0.1; + if(precision.isNull()) + precision = 2; + + m_edit = new DoubleSpinBox(minVal.toDouble(), maxVal.toDouble(), step.toDouble(), + 0, precision.toInt(), this); + if (!minValueText.isNull()) + m_edit->setSpecialValueText(minValueText.toString()); + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMinimumHeight(5); + setEditor(m_edit); + + setLeavesTheSpaceForRevertButton(true); + setFocusWidget(m_edit); + connect(m_edit, SIGNAL(valueChanged(double)), this, SLOT(slotValueChanged(double))); +} + +DoubleEdit::~DoubleEdit() +{} + +QVariant +DoubleEdit::value() const +{ + if (m_edit->cleanText().isEmpty()) + return QVariant(); + return m_edit->value(); +} + +void +DoubleEdit::setValue(const QVariant &value, bool emitChange) +{ + m_edit->blockSignals(true); + m_edit->setValue(value); + updateSpinWidgets(); + m_edit->blockSignals(false); + if (emitChange) + emit valueChanged(this); +} + +void +DoubleEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + QString valueText; + if (property() && property()->hasOptions()) { + //replace min value with minValueText if defined + QVariant minValue( property()->option("min") ); + QVariant minValueText( property()->option("minValueText") ); + if (!minValue.isNull() && !minValueText.isNull() && minValue.toString().toDouble() == value.toString().toDouble()) { + valueText = minValueText.toString(); + } + } + if (valueText.isEmpty()) + valueText = QString(value.toString()).replace('.', KGlobal::locale()->decimalSymbol()); + + Widget::drawViewer(p, cg, r, valueText); +// p->eraseRect(r); +// p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, valueText); +} + +void +DoubleEdit::slotValueChanged(double) +{ + emit valueChanged(this); +} + +void +DoubleEdit::updateSpinWidgets() +{ + QObjectList *spinwidgets = queryList( "QSpinWidget", 0, false, true ); + QSpinWidget* spin = static_cast(spinwidgets->first()); + if (spin) { + spin->setUpEnabled(!isReadOnly()); + spin->setDownEnabled(!isReadOnly()); + } + delete spinwidgets; +} + +void +DoubleEdit::setReadOnlyInternal(bool readOnly) +{ + //disable editor and spin widget + m_edit->editor()->setReadOnly(readOnly); + updateSpinWidgets(); + if (readOnly) + setLeavesTheSpaceForRevertButton(false); +} + +#include "spinbox.moc" diff --git a/lib/koproperty/editors/spinbox.h b/lib/koproperty/editors/spinbox.h new file mode 100644 index 00000000..527aae4f --- /dev/null +++ b/lib/koproperty/editors/spinbox.h @@ -0,0 +1,117 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_SPINBOX_H +#define KPROPERTY_SPINBOX_H + +#include + +#include "../widget.h" + +namespace KoProperty { + +class IntEdit; +class DoubleEdit; + +// Int Editor + +class IntSpinBox : public KIntSpinBox +{ + Q_OBJECT + + public: + IntSpinBox(int lower, int upper, int step, int value, int base=10, + IntEdit *parent=0, const char *name=0); + virtual ~IntSpinBox() {;} + + virtual void setValue(const QVariant &value); + + virtual bool eventFilter(QObject *o, QEvent *e); + QLineEdit * editor () const { return KIntSpinBox::editor(); } +}; + +class KOPROPERTY_EXPORT IntEdit : public Widget +{ + Q_OBJECT + + public: + IntEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~IntEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + void updateSpinWidgets(); + + protected slots: + void slotValueChanged(int value); + + private: + IntSpinBox *m_edit; +}; + +// Double editor + +class DoubleSpinBox : public KDoubleSpinBox +{ + Q_OBJECT + + public: + //! \todo Support setting precision limits, step, etc. + DoubleSpinBox(double lower, double upper, double step, double value=0, + int precision=2, DoubleEdit *parent=0); + virtual ~DoubleSpinBox() {;} + + virtual bool eventFilter(QObject *o, QEvent *e); + QLineEdit * editor () const { return KDoubleSpinBox::editor(); } + + public slots: + virtual void setValue( const QVariant& value ); +}; + +class KOPROPERTY_EXPORT DoubleEdit : public Widget +{ + Q_OBJECT + + public: + DoubleEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~DoubleEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + void updateSpinWidgets(); + + protected slots: + void slotValueChanged(double value); + + private: + DoubleSpinBox *m_edit; +}; + +} + +#endif diff --git a/lib/koproperty/editors/stringedit.cpp b/lib/koproperty/editors/stringedit.cpp new file mode 100644 index 00000000..8c58b511 --- /dev/null +++ b/lib/koproperty/editors/stringedit.cpp @@ -0,0 +1,74 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "stringedit.h" + +#include +#include +#include + +using namespace KoProperty; + +StringEdit::StringEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QLineEdit(this); + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMargin(1); + m_edit->setMinimumHeight(5); + l->addWidget(m_edit); + setFocusWidget(m_edit); + + connect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(slotValueChanged(const QString&))); +} + +StringEdit::~StringEdit() +{} + +QVariant +StringEdit::value() const +{ + return m_edit->text(); +} + +void +StringEdit::setValue(const QVariant &value, bool emitChange) +{ + m_edit->blockSignals(true); + m_edit->setText(value.toString()); + m_edit->blockSignals(false); + if (emitChange) + emit valueChanged(this); +} + +void +StringEdit::slotValueChanged(const QString &) +{ + emit valueChanged(this); +} + +void +StringEdit::setReadOnlyInternal(bool readOnly) +{ + m_edit->setReadOnly(readOnly); +} + +#include "stringedit.moc" diff --git a/lib/koproperty/editors/stringedit.h b/lib/koproperty/editors/stringedit.h new file mode 100644 index 00000000..69dd45a2 --- /dev/null +++ b/lib/koproperty/editors/stringedit.h @@ -0,0 +1,53 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_STRINGEDIT_H +#define KPROPERTY_STRINGEDIT_H + +#include "../widget.h" + +class QLineEdit; + +namespace KoProperty { + +class KOPROPERTY_EXPORT StringEdit : public Widget +{ + Q_OBJECT + + public: + StringEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~StringEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + + protected slots: + void slotValueChanged(const QString&); + + protected: + QLineEdit *m_edit; +}; + +} + +#endif diff --git a/lib/koproperty/editors/stringlistedit.cpp b/lib/koproperty/editors/stringlistedit.cpp new file mode 100644 index 00000000..44238ff9 --- /dev/null +++ b/lib/koproperty/editors/stringlistedit.cpp @@ -0,0 +1,111 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "stringlistedit.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "property.h" + +using namespace KoProperty; + +StringListEdit::StringListEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + setHasBorders(false); + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + + m_edit = new QLineEdit(this); + m_edit->setLineWidth(0); + m_edit->setReadOnly(true); + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMinimumHeight(5); + l->addWidget(m_edit); + + m_selectButton = new QPushButton("...", this); + m_selectButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); + l->addWidget(m_selectButton); + setFocusWidget(m_selectButton); + + connect(m_selectButton, SIGNAL(clicked()), this, SLOT(showEditor())); +} + +StringListEdit::~StringListEdit() +{} + +QVariant +StringListEdit::value() const +{ + return m_list; +} + +void +StringListEdit::setValue(const QVariant &value, bool emitChange) +{ + m_list = value.toStringList(); + m_edit->setText(value.toStringList().join(", ")); + if(emitChange) + emit valueChanged(this); +} + +void +StringListEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ +// p->eraseRect(r); +// p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, value.toStringList().join(", ")); + Widget::drawViewer(p, cg, r, value.toStringList().join(", ")); +} + +void +StringListEdit::showEditor() +{ + KDialogBase dialog(this->topLevelWidget(), "stringlist_dialog", true, i18n("Edit List of Items"), + KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, false); + + KEditListBox *edit = new KEditListBox(i18n("Contents of %1").arg(property()->caption()), &dialog, "editlist"); + dialog.setMainWidget(edit); + edit->insertStringList(m_list); + + if(dialog.exec() == QDialog::Accepted) + { + m_list = edit->items(); + m_edit->setText(m_list.join(", ")); + emit valueChanged(this); + } +} + +void +StringListEdit::setReadOnlyInternal(bool readOnly) +{ + m_selectButton->setEnabled(!readOnly); +} + +#include "stringlistedit.moc" diff --git a/lib/koproperty/editors/stringlistedit.h b/lib/koproperty/editors/stringlistedit.h new file mode 100644 index 00000000..0370e98a --- /dev/null +++ b/lib/koproperty/editors/stringlistedit.h @@ -0,0 +1,60 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_STRINGLISTEDIT_H +#define KPROPERTY_STRINGLISTEDIT_H + +#include "../widget.h" + +#include + +class QLineEdit; +class QPushButton; + +namespace KoProperty { + +class KOPROPERTY_EXPORT StringListEdit : public Widget +{ + Q_OBJECT + + public: + StringListEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~StringListEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + + protected slots: + void showEditor(); + + private: + QLineEdit *m_edit; + QStringList m_list; + QPushButton *m_selectButton; +}; + +} + +#endif diff --git a/lib/koproperty/editors/symbolcombo.cpp b/lib/koproperty/editors/symbolcombo.cpp new file mode 100644 index 00000000..ee0056bd --- /dev/null +++ b/lib/koproperty/editors/symbolcombo.cpp @@ -0,0 +1,122 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "symbolcombo.h" + +using namespace KoProperty; + +SymbolCombo::SymbolCombo(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + setHasBorders(false); + QHBoxLayout *l = new QHBoxLayout(this); + + m_edit = new QLineEdit(this); + m_edit->setLineWidth(0); + m_edit->setReadOnly(true); + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMinimumHeight(5); + m_edit->setMaxLength(1); + l->addWidget(m_edit); + m_select = new QPushButton("...", this); + m_select->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::MinimumExpanding); + m_select->setMinimumHeight(5); + l->addWidget(m_select); + + connect(m_select, SIGNAL(clicked()), this, SLOT(selectChar())); + connect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(slotValueChanged(const QString&))); +} + +SymbolCombo::~SymbolCombo() +{} + +QVariant +SymbolCombo::value() const +{ + if (!(m_edit->text().isNull())) + return m_edit->text().at(0).unicode(); + else + return 0; +} + +void +SymbolCombo::setValue(const QVariant &value, bool emitChange) +{ +#if QT_VERSION >= 0x030100 + if (!(value.isNull())) +#else + if (value.canCast(QVariant::Int)) +#endif + { + m_edit->blockSignals(true); + m_edit->setText(QChar(value.toInt())); + m_edit->blockSignals(false); + if (emitChange) + emit valueChanged(this); + } +} + +void +SymbolCombo::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ +// p->eraseRect(r); +// p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, QChar(value.toInt())); + Widget::drawViewer(p, cg, r, QString( QChar(value.toInt()) )); +} + +void +SymbolCombo::selectChar() +{ + KDialogBase dialog(this->topLevelWidget(), "charselect_dialog", true, i18n("Select Char"), + KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, false); + + KCharSelect *select = new KCharSelect(&dialog, "select_char"); + dialog.setMainWidget(select); + + if (!(m_edit->text().isNull())) + select->setChar(m_edit->text().at(0)); + + if (dialog.exec() == QDialog::Accepted) + m_edit->setText(select->chr()); +} + +void +SymbolCombo::slotValueChanged(const QString&) +{ + emit valueChanged(this); +} + +void +SymbolCombo::setReadOnlyInternal(bool readOnly) +{ + m_select->setEnabled(!readOnly); +} + +#include "symbolcombo.moc" diff --git a/lib/koproperty/editors/symbolcombo.h b/lib/koproperty/editors/symbolcombo.h new file mode 100644 index 00000000..5812d4a8 --- /dev/null +++ b/lib/koproperty/editors/symbolcombo.h @@ -0,0 +1,58 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_SYMBOLCOMBO_H +#define KPROPERTY_SYMBOLCOMBO_H + +#include "../widget.h" + +class QLineEdit; +class QPushButton; + +namespace KoProperty { + +class KOPROPERTY_EXPORT SymbolCombo : public Widget +{ + Q_OBJECT + + public: + SymbolCombo(Property *property, QWidget *parent=0, const char *name=0); + virtual ~SymbolCombo(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + + protected slots: + void selectChar(); + void slotValueChanged(const QString &text); + + private: + QLineEdit *m_edit; + QPushButton *m_select; +}; + +} + +#endif diff --git a/lib/koproperty/editors/timeedit.cpp b/lib/koproperty/editors/timeedit.cpp new file mode 100644 index 00000000..3d38d39b --- /dev/null +++ b/lib/koproperty/editors/timeedit.cpp @@ -0,0 +1,87 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "timeedit.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace KoProperty; + +TimeEdit::TimeEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new QTimeEdit(this); + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMinimumHeight(5); + l->addWidget(m_edit); + + setLeavesTheSpaceForRevertButton(true); + connect(m_edit, SIGNAL(valueChanged(const QTime&)), this, SLOT(slotValueChanged(const QTime&))); +} + +TimeEdit::~TimeEdit() +{} + +QVariant +TimeEdit::value() const +{ + return m_edit->time(); +} + +void +TimeEdit::setValue(const QVariant &value, bool emitChange) +{ + m_edit->blockSignals(true); + m_edit->setTime(value.toTime()); + m_edit->blockSignals(false); + if (emitChange) + emit valueChanged(this); +} + +void +TimeEdit::drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value) +{ + Widget::drawViewer(p, cg, r, KGlobal::locale()->formatTime(value.toTime(), true /* include sec*/)); +// p->drawText(r, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, KGlobal::locale()->formatTime(value.toTime(), true /* include sec*/)); +} + +void +TimeEdit::slotValueChanged(const QTime&) +{ + emit valueChanged(this); +} + +void +TimeEdit::setReadOnlyInternal(bool readOnly) +{ + setVisibleFlag(!readOnly); +} + +#include "timeedit.moc" diff --git a/lib/koproperty/editors/timeedit.h b/lib/koproperty/editors/timeedit.h new file mode 100644 index 00000000..d41f4633 --- /dev/null +++ b/lib/koproperty/editors/timeedit.h @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_TIMEEDIT_H +#define KPROPERTY_TIMEEDIT_H + +#include "../widget.h" + +class QTimeEdit; + +namespace KoProperty { + +class KOPROPERTY_EXPORT TimeEdit : public Widget +{ + Q_OBJECT + + public: + TimeEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~TimeEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + + protected slots: + void slotValueChanged(const QTime &time); + + private: + QTimeEdit *m_edit; +}; + +} + +#endif diff --git a/lib/koproperty/editors/urledit.cpp b/lib/koproperty/editors/urledit.cpp new file mode 100644 index 00000000..41cd5efe --- /dev/null +++ b/lib/koproperty/editors/urledit.cpp @@ -0,0 +1,96 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "urledit.h" + +#include +#include + +#include +#include + +#include "property.h" + + +using namespace KoProperty; + +URLEdit::URLEdit(Property *property, QWidget *parent, const char *name) + : Widget(property, parent, name) +{ + QHBoxLayout *l = new QHBoxLayout(this, 0, 0); + m_edit = new KURLRequester(this); + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setMinimumHeight(5); + l->addWidget(m_edit); + + setProperty(property); + + connect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(slotValueChanged(const QString&))); + m_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); +} + +URLEdit::~URLEdit() +{} + +QVariant +URLEdit::value() const +{ + return m_edit->url(); +} + +void +URLEdit::setValue(const QVariant &value, bool emitChange) +{ + m_edit->blockSignals(true); + m_edit->setURL(value.toString()); + m_edit->blockSignals(false); + if (emitChange) + emit valueChanged(this); +} + +void +URLEdit::slotValueChanged(const QString&) +{ + emit valueChanged(this); +} + +void +URLEdit::setProperty(Property *property) +{ + int mode; + if(property) { + switch(property->type()) { + case DirectoryURL: mode = KFile::Directory|KFile::ExistingOnly; break; + case FileURL: case PictureFileURL: default: mode = KFile::File|KFile::ExistingOnly; + } + m_edit->setMode(mode); + } + + Widget::setProperty(property); +} + +void +URLEdit::setReadOnlyInternal(bool readOnly) +{ + m_edit->lineEdit()->setReadOnly(readOnly); + m_edit->button()->setEnabled(!readOnly); +} + +#include "urledit.moc" diff --git a/lib/koproperty/editors/urledit.h b/lib/koproperty/editors/urledit.h new file mode 100644 index 00000000..7bebf7b1 --- /dev/null +++ b/lib/koproperty/editors/urledit.h @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_URLEDIT_H +#define KPROPERTY_URLEDIT_H + +#include "../widget.h" + +class KURLRequester; + +namespace KoProperty { + +class KOPROPERTY_EXPORT URLEdit : public Widget +{ + Q_OBJECT + + public: + URLEdit(Property *property, QWidget *parent=0, const char *name=0); + virtual ~URLEdit(); + + virtual QVariant value() const; + virtual void setValue(const QVariant &value, bool emitChange=true); + + virtual void setProperty(Property *property); + + protected: + virtual void setReadOnlyInternal(bool readOnly); + + protected slots: + void slotValueChanged(const QString &url); + + private: + KURLRequester *m_edit; +}; + +} + +#endif diff --git a/lib/koproperty/factory.cpp b/lib/koproperty/factory.cpp new file mode 100644 index 00000000..9b05552d --- /dev/null +++ b/lib/koproperty/factory.cpp @@ -0,0 +1,265 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "factory.h" +#include "property.h" +#include "customproperty.h" + +#include "booledit.h" +#include "combobox.h" +#include "coloredit.h" +#include "cursoredit.h" +#include "dateedit.h" +#include "datetimeedit.h" +#include "dummywidget.h" +#include "fontedit.h" +#include "linestyleedit.h" +#include "pixmapedit.h" +#include "pointedit.h" +#include "rectedit.h" +#include "sizeedit.h" +#include "sizepolicyedit.h" +#include "spinbox.h" +#include "stringlistedit.h" +#include "stringedit.h" +#include "symbolcombo.h" +#include "timeedit.h" +#include "urledit.h" + +#include +#include + +#include + +static KStaticDeleter m_managerDeleter; +static KoProperty::FactoryManager* m_manager = 0; + +namespace KoProperty { + +CustomPropertyFactory::CustomPropertyFactory(QObject *parent) + : QObject(parent) +{ +} + +CustomPropertyFactory::~CustomPropertyFactory() +{ +} + + +//! @internal +class FactoryManagerPrivate +{ + public: + FactoryManagerPrivate() {} + ~FactoryManagerPrivate() {} + + //registered widgets for property types + QIntDict registeredWidgets; + QIntDict registeredCustomProperties; +}; +} + +using namespace KoProperty; + +FactoryManager::FactoryManager() +: QObject(0, "KoProperty::FactoryManager") +{ + d = new FactoryManagerPrivate(); +} + +FactoryManager::~FactoryManager() +{ + delete d; +} + +FactoryManager* +FactoryManager::self() +{ + if(!m_manager) + m_managerDeleter.setObject( m_manager, new FactoryManager() ); + return m_manager; +} + +/////////////////// Functions related to widgets ///////////////////////////////////// + +void +FactoryManager::registerFactoryForEditor(int editorType, CustomPropertyFactory *widgetFactory) +{ + if(!widgetFactory) + return; + if(d->registeredWidgets.find(editorType)) + kopropertywarn << "FactoryManager::registerFactoryForEditor(): " + "Overriding already registered custom widget type \"" << editorType << "\"" << endl; + d->registeredWidgets.replace(editorType, widgetFactory); +} + +void +FactoryManager::registerFactoryForEditors(const QValueList &editorTypes, CustomPropertyFactory *factory) +{ + QValueList::ConstIterator endIt = editorTypes.constEnd(); + for(QValueList::ConstIterator it = editorTypes.constBegin(); it != endIt; ++it) + registerFactoryForEditor(*it, factory); +} + +CustomPropertyFactory * +FactoryManager::factoryForEditorType(int type) +{ + return d->registeredWidgets.find(type); +} + +Widget* +FactoryManager::createWidgetForProperty(Property *property) +{ + if(!property) + return 0; + + const int type = property->type(); + + CustomPropertyFactory *factory = d->registeredWidgets.find(type); + if (factory) + return factory->createCustomWidget(property); + + //handle combobox-based widgets: + if (type==Cursor) + return new CursorEdit(property); + + if (property->listData()) { + return new ComboBox(property); + } + + //handle other widget types: + switch(type) + { + // Default QVariant types + case String: + case CString: + return new StringEdit(property); + case Rect_X: + case Rect_Y: + case Rect_Width: + case Rect_Height: + case Point_X: + case Point_Y: + case Size_Width: + case Size_Height: + case SizePolicy_HorStretch: + case SizePolicy_VerStretch: + case Integer: + return new IntEdit(property); + case Double: + return new DoubleEdit(property); + case Boolean: { + //boolean editors can optionally accept 3rd state: + QVariant thirdState = property ? property->option("3rdState") : QVariant(); + if (thirdState.toString().isEmpty()) + return new BoolEdit(property); + else + return new ThreeStateBoolEdit(property); + } + case Date: + return new DateEdit(property); + case Time: + return new TimeEdit(property); + case DateTime: + return new DateTimeEdit(property); + case StringList: + return new StringListEdit(property); + case Color: + return new ColorButton(property); + case Font: + return new FontEdit(property); + case Pixmap: + return new PixmapEdit(property); + + // Other default types + case Symbol: + return new SymbolCombo(property); + //case FontName: + // return new FontCombo(property); + case FileURL: + case DirectoryURL: + return new URLEdit(property); + case LineStyle: + return new LineStyleEdit(property); + + // Composed types + case Size: + return new SizeEdit(property); + case Point: + return new PointEdit(property); + case Rect: + return new RectEdit(property); + case SizePolicy: + return new SizePolicyEdit(property); + + case List: + case Map: + default: + kopropertywarn << "No editor for property " << property->name() << " of type " << property->type() << endl; + return new DummyWidget(property); + } +} + +/////////////////// Functions related to custom properties ///////////////////////////////////// + +void +FactoryManager::registerFactoryForProperty(int propertyType, CustomPropertyFactory *factory) +{ + if(!factory) + return; + if(d->registeredCustomProperties.find(propertyType)) + kopropertywarn << "FactoryManager::registerFactoryForProperty(): " + "Overriding already registered custom property type \"" << propertyType << "\"" << endl; + + d->registeredCustomProperties.replace(propertyType, factory); +} + +void +FactoryManager::registerFactoryForProperties(const QValueList &propertyTypes, + CustomPropertyFactory *factory) +{ + QValueList::ConstIterator endIt = propertyTypes.constEnd(); + for(QValueList::ConstIterator it = propertyTypes.constBegin(); it != endIt; ++it) + registerFactoryForProperty(*it, factory); +} + +CustomProperty* +FactoryManager::createCustomProperty(Property *parent) +{ + const int type = parent->type(); + CustomPropertyFactory *factory = d->registeredWidgets.find(type); + if (factory) + return factory->createCustomProperty(parent); + + switch(type) { + case Size: case Size_Width: case Size_Height: + return new SizeCustomProperty(parent); + case Point: case Point_X: case Point_Y: + return new PointCustomProperty(parent); + case Rect: case Rect_X: case Rect_Y: case Rect_Width: case Rect_Height: + return new RectCustomProperty(parent); + case SizePolicy: case SizePolicy_HorStretch: case SizePolicy_VerStretch: + case SizePolicy_HorData: case SizePolicy_VerData: + return new SizePolicyCustomProperty(parent); + default: + return 0; + } +} + diff --git a/lib/koproperty/factory.h b/lib/koproperty/factory.h new file mode 100644 index 00000000..eba55f62 --- /dev/null +++ b/lib/koproperty/factory.h @@ -0,0 +1,168 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2005 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_FACTORY_H +#define KPROPERTY_FACTORY_H + +#include "koproperty_global.h" +#include +#include + +template class QValueList; + +namespace KoProperty { + +class Widget; +class CustomProperty; +class Property; +class FactoryManagerPrivate; + +///*! A pointer to factory function which creates and returns widget for a given property type.*/ +//typedef Widget *(*createWidget) (Property*); +//typedef CustomProperty *(*createCustomProperty) (Property*); + +//! \brief A prototype for custom property factory +class KOPROPERTY_EXPORT CustomPropertyFactory : public QObject +{ + public: + CustomPropertyFactory(QObject *parent); + virtual ~CustomPropertyFactory(); + + /*! \return a new instance of custom property for \a parent. + Implement this for property types you want to support. + Use parent->type() to get type of the property. */ + virtual CustomProperty* createCustomProperty(Property *parent) = 0; + + /*! \return a new instance of custom property for \a property. + Implement this for property editor types you want to support. + Use parent->type() to get type of the property. */ + virtual Widget* createCustomWidget(Property *property) = 0; +}; + +//! \brief Manages factories providing custom editors and properties. +/*! This class is static, you don't need to create an instance of it. It's used to enable the + custom property/editors system. + You may want to create your own property types and/or editors to: + + - Create your own editors for some special kind of properties, not included in + KProperty basic editors; + + - Create composed properties, which contain more than one value. Child + items will then be created in the Editor (that's how rect, size properties are created). + + \section custom_prop Using Custom Properties + To create a custom property, create a subclass of \ref CustomProperty class. You need to implement + some virtual functions, to customize the behaviour of your property + (see \ref CustomProperty api doc).\n + Then, you need to register the new created type, using \ref registerFactoryForProperty(). + The second parameter is an instance of CustomPropertyFactory-derived class + implementing CustomPropertyFactory::createCustomProperty() method.\n + To create a property of this type, just use the normal constructor, overriding + the type parameter with the type you registered. + + \section custom_prop_composed Using Custom Properties to create composed properties + Use a composed property when you need more than one editor for a property. Examples + are rect, size or point properties. + If you create a composed property, both parent and children properties must have custom + (different) types. + Child properties are created in CustomProperty constructor of the parent type, + by adding CustomProperty::property() as parent in Property constructor.\n + Child properties should return handleValue() == true and in CustomProperty::setValue(), + parent's Property::setValue() should be called, making sure that useCustomProperty argument is set + to false.\n + Parent's handleValue() should be set to false, unless you cannot store the property in a QVariant. + You just need to update children's value, making sure that useCustomProperty argument is set + to false. + + \section custom_editor Using Custom Editors + First, create a subclass of Widget, and implement all the virtuals you need to tweak + the property editor. You can find examples of editors in the src/editors/ directory.\n + Then, register it using \ref registerFactoryForEditor(), as for properties (see test/ dir + for an example of custom editor). You can also override the editor provided by KoProperty, + if it doesn't fit your needs (if you have created a better editor, + send us the code, and it may get included in KProperty library).\n + To use your new editor, just create properties with the type number you registered using + \ref registerFactoryForEditor() . Your editor will automatically appear in the Editor. + + \section custom_prop_composed Using Custom Properties with value that cannot be stored in a QVariant + You then need to set handleValue() to true. The Widget you create also have + to call directly CustomProperty member to store the value. just make sure you call emitPropertyChanged() + when the proerty value changes. Also make sure to avoid infinite recursion if you use children properties. + + \author Cedric Pasteur + \author Alexander Dymo + */ +class KOPROPERTY_EXPORT FactoryManager : public QObject +{ + public: + /*! Registers a custom factory \a factory for handling property editor for \a editorType. + This custom factory will be used before defaults when widgetForProperty() is called. + \a creator is not owned by this Factory object, but it's good idea + to instantiate CustomPropertyFactory object itself as a child of Factory parent. For example: + \code + MyCustomPropertyFactory *f = new MyCustomPropertyFactory(KoProperty::Factory::self()); + KoProperty::Factory::self()->registerEditor( MyCustomType, f ); + \endcode */ + void registerFactoryForEditor(int editorType, CustomPropertyFactory *factory); + + /*! Registers custom factory \a factory for handling property editors for \a editorTypes. + @see registerFactoryForEditor(). */ + void registerFactoryForEditors(const QValueList &editorTypes, CustomPropertyFactory *factory); + + /*! \return custom factory for type \a type or NULL if there + is no such property type registered. + To create a custom widget createWidgetForProperty() should be rather used. */ + CustomPropertyFactory *factoryForEditorType(int type); + + /*! 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. + If \a createWidget is false, just create child properties, not widget.*/ + Widget* createWidgetForProperty(Property *property); + + /*! Registers a custom factory that handles a CustomProperty of a type \a type. + This function will be called every time a property of \a type is created. */ + void registerFactoryForProperty(int propertyType, CustomPropertyFactory *factory); + + /*! Registers a custom property factory that handles a CustomProperty for \a types. + @see registerFactoryForProperty() */ + void registerFactoryForProperties(const QValueList &propertyTypes, + CustomPropertyFactory *factory); + + /*! This function is called in Property::Property() to create (optional) + custom property. It creates the custom property for built-in types, or + calls one of createCustomProperty function previously registered for other types. */ + CustomProperty* createCustomProperty(Property *parent); + + /*! \return a pointer to a property factory instance.*/ + static FactoryManager* self(); + + private: + FactoryManager(); + ~FactoryManager(); + + FactoryManagerPrivate *d; + friend class KStaticDeleter; +}; + +} + +#endif diff --git a/lib/koproperty/koproperty_global.h b/lib/koproperty/koproperty_global.h new file mode 100644 index 00000000..de232dee --- /dev/null +++ b/lib/koproperty/koproperty_global.h @@ -0,0 +1,29 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_GLOBAL_H +#define KPROPERTY_GLOBAL_H + +#include + +//convenience defines +#define kopropertydbg kdDebug(30007) +#define kopropertywarn kdWarning(30007) + +#endif diff --git a/lib/koproperty/property.cpp b/lib/koproperty/property.cpp new file mode 100644 index 00000000..9d677bd8 --- /dev/null +++ b/lib/koproperty/property.cpp @@ -0,0 +1,778 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2004-2006 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "property.h" +#include "customproperty.h" +#include "set.h" +#include "factory.h" + +#include + +#include +#include +#include +#include + +namespace KoProperty { + +QT_STATIC_CONST_IMPL Property Property::null; + +//! @internal +class PropertyPrivate +{ + public: + PropertyPrivate() + : caption(0), listData(0), changed(false), storable(true), + readOnly(false), visible(true), + autosync(-1), custom(0), useCustomProperty(true), + sets(0), parent(0), children(0), relatedProperties(0), + sortingKey(0) + { + } + + inline void setCaptionForDisplaying(const QString& captionForDisplaying) + { + delete caption; + if (captionForDisplaying.simplifyWhiteSpace()!=captionForDisplaying) + caption = new QString(captionForDisplaying.simplifyWhiteSpace()); + else + caption = 0; + this->captionForDisplaying = captionForDisplaying; + } + + ~PropertyPrivate() + { + delete caption; + caption = 0; + delete listData; + delete children; + delete relatedProperties; + delete custom; + delete sets; + } + + int type; + QCString name; + QString captionForDisplaying; + QString* caption; + QString description; + QVariant value; + QVariant oldValue; + /*! The string-to-value correspondence list of the property.*/ + Property::ListData* listData; +// QMap *valueList; + QString icon; + + bool changed : 1; + bool storable : 1; + bool readOnly : 1; + bool visible : 1; + int autosync; + QMap options; + + CustomProperty *custom; + //! Flag used to allow CustomProperty to use setValue() + bool useCustomProperty; + + //! Used when a single set is assigned for the property + QGuardedPtr set; + //! Used when multiple sets are assigned for the property + QPtrDict< QGuardedPtr > *sets; +// QValueList sets; + + Property *parent; + QValueList *children; + //! list of properties with the same name (when intersecting buffers) + QValueList *relatedProperties; + + int sortingKey; +}; +} + +using namespace KoProperty; + +///////////////////////////////////////////////////////////////// + +Property::ListData::ListData(const QStringList& keys_, const QStringList& names_) + : names(names_) +// , fixed(true) +{ + setKeysAsStringList(keys_); +} + +Property::ListData::ListData(const QValueList keys_, const QStringList& names_) + : keys(keys_), names(names_) +// , fixed(true) +{ +} + +Property::ListData::ListData() +// : fixed(true) +{ +} + +Property::ListData::~ListData() +{ +} + +void Property::ListData::setKeysAsStringList(const QStringList& list) +{ + keys.clear(); + for (QStringList::ConstIterator it = list.constBegin(); it!=list.constEnd(); ++it) { + keys.append(*it); + } +} + +QStringList Property::ListData::keysAsStringList() const +{ + QStringList result; + for (QValueList::ConstIterator it = keys.constBegin(); it!=keys.constEnd(); ++it) { + result.append((*it).toString()); + } + return result; +} + +///////////////////////////////////////////////////////////////// + +/* +KOPROPERTY_EXPORT QMap +KoProperty::createValueListFromStringLists(const QStringList &keys, const QStringList &values) +{ + QMap map; + if(keys.count() != values.count()) + return map; + + QStringList::ConstIterator valueIt = values.begin(); + QStringList::ConstIterator endIt = keys.constEnd(); + for(QStringList::ConstIterator it = keys.begin(); it != endIt; ++it, ++valueIt) + map.insert( *it, *valueIt); + + return map; +} +*/ + + +Property::Property(const QCString &name, const QVariant &value, + const QString &caption, const QString &description, + int type, Property* parent) + : d( new PropertyPrivate() ) +{ + d->name = name; + d->setCaptionForDisplaying(caption); + d->description = description; + + if(type == Auto) + d->type = value.type(); + else + d->type = type; + + d->custom = FactoryManager::self()->createCustomProperty(this); + + if (parent) + parent->addChild(this); + setValue(value, false); +} + +Property::Property(const QCString &name, const QStringList &keys, const QStringList &strings, + const QVariant &value, const QString &caption, const QString &description, + int type, Property* parent) + : d( new PropertyPrivate() ) +{ + d->name = name; + d->setCaptionForDisplaying(caption); + d->description = description; + d->type = type; + setListData(keys, strings); + + d->custom = FactoryManager::self()->createCustomProperty(this); + + if (parent) + parent->addChild(this); + setValue(value, false); +} + +Property::Property(const QCString &name, ListData* listData, + const QVariant &value, const QString &caption, const QString &description, + int type, Property* parent) + : d( new PropertyPrivate() ) +{ + d->name = name; + d->setCaptionForDisplaying(caption); + d->description = description; + d->type = type; + d->listData = listData; + + d->custom = FactoryManager::self()->createCustomProperty(this); + + if (parent) + parent->addChild(this); + setValue(value, false); +} + +Property::Property() + : d( new PropertyPrivate() ) +{ +} + +Property::Property(const Property &prop) + : d( new PropertyPrivate() ) +{ + *this = prop; +} + +Property::~Property() +{ + delete d; + d = 0; +} + +QCString +Property::name() const +{ + return d->name; +} + +void +Property::setName(const QCString &name) +{ + d->name = name; +} + +QString +Property::caption() const +{ + return d->caption ? *d->caption : d->captionForDisplaying; +} + +QString +Property::captionForDisplaying() const +{ + return d->captionForDisplaying; +} + +void +Property::setCaption(const QString &caption) +{ + d->setCaptionForDisplaying(caption); +} + +QString +Property::description() const +{ + return d->description; +} + +void +Property::setDescription(const QString &desc) +{ + d->description = desc; +} + +int +Property::type() const +{ + return d->type; +} + +void +Property::setType(int type) +{ + d->type = type; +} + +QString +Property::icon() const +{ + return d->icon; +} + +void +Property::setIcon(const QString &icon) +{ + d->icon = icon; +} + +QVariant +Property::value() const +{ + if(d->custom && d->custom->handleValue()) + return d->custom->value(); + return d->value; +} + +QVariant +Property::oldValue() const +{ +/* if(d->oldValue.isNull()) + return value(); + else*/ + return d->oldValue; +} + +void +Property::setValue(const QVariant &value, bool rememberOldValue, bool useCustomProperty) +{ + if (d->name.isEmpty()) { + kopropertywarn << "Property::setValue(): COULD NOT SET value to a null property" << endl; + return; + } + QVariant currentValue = this->value(); + const QVariant::Type t = currentValue.type(); + const QVariant::Type newt = value.type(); +// kopropertydbg << d->name << " : setValue('" << value.toString() << "' type=" << type() << ")" << endl; + if (t != newt && !currentValue.isNull() && !value.isNull() + && !( (t==QVariant::Int && newt==QVariant::UInt) + || (t==QVariant::UInt && newt==QVariant::Int) + || (t==QVariant::CString && newt==QVariant::String) + || (t==QVariant::String && newt==QVariant::CString) + || (t==QVariant::ULongLong && newt==QVariant::LongLong) + || (t==QVariant::LongLong && newt==QVariant::ULongLong) + )) { + kopropertywarn << "Property::setValue(): INCOMPATIBLE TYPES! old=" << currentValue + << " new=" << value << endl; + } + + //1. Check if the value should be changed + bool ch; + if (t == QVariant::DateTime + || t == QVariant::Time) { + //for date and datetime types: compare with strings, because there + //can be miliseconds difference + ch = (currentValue.toString() != value.toString()); + } + else if (t == QVariant::String || t==QVariant::CString) { + //property is changed for string type, + //if one of value is empty and other isn't.. + ch = ( (currentValue.toString().isEmpty() != value.toString().isEmpty()) + //..or both are not empty and values differ + || (!currentValue.toString().isEmpty() && !value.toString().isEmpty() && currentValue != value) ); + } + else if (t == QVariant::Invalid && newt == QVariant::Invalid) + ch = false; + else + ch = (currentValue != value); + + if (!ch) + return; + + //2. Then change it, and store old value if necessary + if(rememberOldValue) { + if(!d->changed) + d->oldValue = currentValue; + d->changed = true; + } + else { + d->oldValue = QVariant(); // clear old value + d->changed = false; + } + QVariant prevValue; + if(d->custom && useCustomProperty) { + d->custom->setValue(value, rememberOldValue); + prevValue = d->custom->value(); + } + else + prevValue = currentValue; + + if (!d->custom || !useCustomProperty || !d->custom->handleValue()) + d->value = value; + + emitPropertyChanged(); // called as last step in this method! +} + +void +Property::resetValue() +{ + d->changed = false; + bool cleared = false; + if (d->set) + d->set->informAboutClearing(cleared); //inform me about possibly clearing the property sets + setValue(oldValue(), false); + if (cleared) + return; //property set has been cleared: no further actions make sense as 'this' is dead + + // maybe parent prop is also unchanged now + if(d->parent && d->parent->value() == d->parent->oldValue()) + d->parent->d->changed = false; + + if (d->sets) { + for (QPtrDictIterator< QGuardedPtr > it(*d->sets); it.current(); ++it) { + if (it.current()) //may be destroyed in the meantime + emit (*it.current())->propertyReset(**it.current(), *this); + } + } + else if (d->set) { + emit d->set->propertyReset(*d->set, *this); + } +} + +//const QMap* +Property::ListData* +Property::listData() const +{ + return d->listData; +} + +void +Property::setListData(ListData* list) //const QMap &list) +{ +// if(!d->valueList) +// d->valueList = new QMap(); + if (list == d->listData) + return; + delete d->listData; + d->listData = list; +} + +void +Property::setListData(const QStringList &keys, const QStringList &names) +{ + ListData* list = new ListData(keys, names); + setListData(list); + +// if(!d->valueList) +// d->valueList = new QMap(); +// *(d->valueList) = createValueListFromStringLists(keys, values); +} + +//////////////////////////////////////////////////////////////// + +bool +Property::isNull() const +{ + return d->name.isEmpty(); +} + +bool +Property::isModified() const +{ + return d->changed; +} + +void +Property::clearModifiedFlag() +{ + d->changed = false; +} + +bool +Property::isReadOnly() const +{ + return d->readOnly; +} + +void +Property::setReadOnly(bool readOnly) +{ + d->readOnly = readOnly; +} + +bool +Property::isVisible() const +{ + return d->visible; +} + +void +Property::setVisible(bool visible) +{ + d->visible = visible; +} + +int +Property::autoSync() const +{ + return d->autosync; +} + +void +Property::setAutoSync(int sync) +{ + d->autosync = sync; +} + +bool +Property::isStorable() const +{ + return d->storable; +} + +void +Property::setStorable(bool storable) +{ + d->storable = storable; +} + +void +Property::setOption(const char* name, const QVariant& val) +{ + d->options[name] = val; +} + +QVariant +Property::option(const char* name) const +{ + if (d->options.contains(name)) + return d->options[name]; + return QVariant(); +} + +bool +Property::hasOptions() const +{ + return !d->options.isEmpty(); +} + +///////////////////////////////////////////////////////////////// + +Property::operator bool () const +{ + return !isNull(); +} + +const Property& +Property::operator= (const QVariant& val) +{ + setValue(val); + return *this; +} + +const Property& +Property::operator= (const Property &property) +{ + if(&property == this) + return *this; + + if(d->listData) { + delete d->listData; + d->listData = 0; + } + if(d->children) { + delete d->children; + d->children = 0; + } + if(d->relatedProperties) { + delete d->relatedProperties; + d->relatedProperties = 0; + } + if(d->custom) { + delete d->custom; + d->custom = 0; + } + + d->name = property.d->name; + d->setCaptionForDisplaying(property.captionForDisplaying()); + d->description = property.d->description; + d->type = property.d->type; + + d->icon = property.d->icon; + d->autosync = property.d->autosync; + d->visible = property.d->visible; + d->storable = property.d->storable; + d->readOnly = property.d->readOnly; + d->options = property.d->options; + + if(property.d->listData) { + d->listData = new ListData(*property.d->listData); //QMap(*(property.d->valueList)); + } + if(property.d->custom) { + d->custom = FactoryManager::self()->createCustomProperty(this); + // updates all children value, using CustomProperty + setValue(property.value()); + } + else { + d->value = property.d->value; + if(property.d->children) { + // no CustomProperty (should never happen), simply copy all children + d->children = new QValueList(); + QValueList::ConstIterator endIt = property.d->children->constEnd(); + for(QValueList::ConstIterator it = property.d->children->constBegin(); it != endIt; ++it) { + Property *child = new Property( *(*it) ); + addChild(child); + } + } + } + + if(property.d->relatedProperties) { + d->relatedProperties = new QValueList( *(property.d->relatedProperties)); + } + + // update these later because they may have been changed when creating children + d->oldValue = property.d->oldValue; + d->changed = property.d->changed; + d->sortingKey = property.d->sortingKey; + + return *this; +} + +bool +Property::operator ==(const Property &prop) const +{ + return ((d->name == prop.d->name) && (value() == prop.value())); +} + +///////////////////////////////////////////////////////////////// + +const QValueList* +Property::children() const +{ + return d->children; +} + +Property* +Property::child(const QCString &name) +{ + QValueList::ConstIterator endIt = d->children->constEnd(); + for(QValueList::ConstIterator it = d->children->constBegin(); it != endIt; ++it) { + if((*it)->name() == name) + return *it; + } + return 0; +} + +Property* +Property::parent() const +{ + return d->parent; +} + +void +Property::addChild(Property *prop) +{ + if (!prop) + return; + + if(!d->children || qFind( d->children->begin(), d->children->end(), prop) == d->children->end()) { // not in our list + if(!d->children) + d->children = new QValueList(); + d->children->append(prop); + prop->setSortingKey(d->children->count()); + prop->d->parent = this; + } + else { + kopropertywarn << "Property::addChild(): property \"" << name() + << "\": child property \"" << prop->name() << "\" already added" << endl; + return; + } +} + +void +Property::addSet(Set *set) +{ + if (!set) + return; + + if (!d->set) {//simple case + d->set = set; + return; + } + if ((Set*)d->set==set) + return; + QGuardedPtr *pset = d->sets ? d->sets->find(set) : 0; + if (pset && (Set*)*pset == set) + return; + if (!d->sets) { + d->sets = new QPtrDict< QGuardedPtr >( 101 ); + d->sets->setAutoDelete(true); + } + + d->sets->replace(set, new QGuardedPtr( set )); + +// QValueList::iterator it = qFind( d->sets.begin(), d->sets.end(), set); +// if(it == d->sets.end()) // not in our list +// d->sets.append(set); +} + +const QValueList* +Property::related() const +{ + return d->relatedProperties; +} + +void +Property::addRelatedProperty(Property *property) +{ + if(!d->relatedProperties) + d->relatedProperties = new QValueList(); + + QValueList::iterator it = qFind( d->relatedProperties->begin(), d->relatedProperties->end(), property); + if(it == d->relatedProperties->end()) // not in our list + d->relatedProperties->append(property); +} + +CustomProperty* +Property::customProperty() const +{ + return d->custom; +} + +void +Property::setCustomProperty(CustomProperty *prop) +{ + d->custom = prop; +} + +int Property::sortingKey() const +{ + return d->sortingKey; +} + +void Property::setSortingKey(int key) +{ + d->sortingKey = key; +} + +void Property::emitPropertyChanged() +{ + if (d->sets) { + for (QPtrDictIterator< QGuardedPtr > it(*d->sets); it.current(); ++it) { + if (it.current()) {//may be destroyed in the meantime + emit (*it.current())->propertyChangedInternal(**it.current(), *this); + emit (*it.current())->propertyChanged(**it.current(), *this); + } + } + } + else if (d->set) { + //if the slot connect with that signal may call set->clear() - that's + //the case e.g. at kexi/plugins/{macros|scripting}/* - this Property + //may got destroyed ( see Set::removeProperty(Property*) ) while we are + //still on it. So, if we try to access ourself/this once the signal + //got emitted we may end in a very hard to reproduce crash. So, the + //emit should happen as last step in this method! + emit d->set->propertyChangedInternal(*d->set, *this); + emit d->set->propertyChanged(*d->set, *this); + } +} + +///////////////////////////////////////////////////////////////// + +void +Property::debug() +{ + QString dbg = "Property( name='" + QString(d->name) + "' desc='" + d->description + + "' val=" + (value().isValid() ? value().toString() : ""); + if (!d->oldValue.isValid()) + dbg += (", oldVal='" + d->oldValue.toString() + '\''); + dbg += (QString(d->changed ? " " : " un") + "changed"); + dbg += (d->visible ? " visible" : " hidden"); + dbg+=" )"; + + kopropertydbg << dbg << endl; +} diff --git a/lib/koproperty/property.h b/lib/koproperty/property.h new file mode 100644 index 00000000..cce3f087 --- /dev/null +++ b/lib/koproperty/property.h @@ -0,0 +1,443 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2004-2006 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_PROPERTY_H +#define KPROPERTY_PROPERTY_H + +#include +#include "koproperty_global.h" + +template class QAsciiDict; +template class QAsciiDictIterator; + +/*! \brief Namespace for a set of classes implementing generic properties framework. + + Main classes of this framework are: + - Property, representing a single property with its own type and value + - Set, a set of properties + - Editor, a widget for displaying and editing properties provided by a Set object. + Every property has its own row displayed using EditorItem object, within Editor widget. + Widget class provides editing feature for EditorItem objects if a user selects a given item. + + KoProperty framework also supports adding custom property types + and custom property editor types using Custom Property and CustomPropertyFactory. + If you cannot store your value type in a QVariant, consider using composed properties + (see FactoryManager for more information) or storing it in CustomProperty yourself with handleValue() + set to true. + + Take a look at the test application, available in /koproperty/test to see how to use KoProperty. + + \author Cedric Pasteur + \author Alexander Dymo + \author Jaroslaw Staniek +*/ +namespace KoProperty { + +class PropertyPrivate; +class CustomProperty; +class Set; + +///*! Helper function to create a value list from two string lists. */ +//KOPROPERTY_EXPORT QMap createValueListFromStringLists( +// const QStringList &keys, const QStringList &values); + +/*! PropertyType. +Integers that represent the type of the property. Plugin defined properties +should have a type number >= UserDefined .*/ +enum PropertyType { + //standard supported QVariant types + Auto = QVariant::Invalid - 1, + Invalid = QVariant::Invalid /***/, + List = QVariant::List /***/, + String = QVariant::String /** keys2; + keys2.append(1); + keys2.append(2); + keys2.append(3); + Property::ListData listData(keys2, strings); + m_set->addProperty(new Property("List2", listData, "otheritem", "List2"), group); + \endcode + + Note that you need to use QVariant(bool, int) to create a boolean property value. + See QVariant docs for more details. + + Sometimes, for longer property captions or these with more words, e.g. "Allow Zero Size", + it's usable to provide newline characters, e.g. "Allow Zero\nSize". + If caption argument of the constructors contains newline characters, + caption() will return this text with substituted these characters with spaces. + In such cases, captionForDisplaying() is used to get the original caption text usable + (with newline, if any) for displaying within a property editor. + + \author Cedric Pasteur + \author Alexander Dymo + \author Jaroslaw Staniek +*/ +class KOPROPERTY_EXPORT Property +{ + public: + //! A contant for null property + QT_STATIC_CONST Property null; + + typedef QAsciiDict Dict; + typedef QAsciiDictIterator DictIterator; + + /*! Data container for properties of list type. */ + class KOPROPERTY_EXPORT ListData + { + public: + /*! Data container for list-value property. + We will be able to choose an item from this list. */ + ListData(const QStringList& keys_, const QStringList& names_); + ListData(const QValueList keys_, const QStringList& names_); + ListData(); + ~ListData(); + + void setKeysAsStringList(const QStringList& list); + QStringList keysAsStringList() const; + + /*! The string list containing all possible keys for this property + or NULL if this is not a property of type 'list'. The values in this list are ordered, + so the first key element is associated with first element from + the 'names' list, and so on. */ + QValueList keys; +// QStringList keys; + +//! @todo what about using QValueList here too? + /*! The list of i18n'ed names that will be visible on the screen. + First value is referenced by first key, and so on. */ + QStringList names; + +//unused for now /*! True (the default), if the list has fixed number of possible +//unused for now items (keys). If this is false, user can add or enter own values. */ +//unused for now bool fixed : 1; + }; + + /*! Constructs a null property. */ + Property(); + + /*! Constructs property of simple type. + If \a caption contains newline characters, caption() will return \a caption with substituted + these with spaces. captionForDisplaying() is used to get original caption text usable + (with newline, if any) for displaying within a property editor. */ + Property(const QCString &name, const QVariant &value = QVariant(), + const QString &caption = QString::null, const QString &description = QString::null, + int type = Auto, Property* parent = 0); + + /*! Constructs property of \ref ValueFromList type. */ + Property(const QCString &name, const QStringList &keys, const QStringList &strings, + const QVariant &value = QVariant(), + const QString &caption = QString::null, const QString &description = QString::null, + int type = ValueFromList, Property* parent = 0); + + /*! Constructs property of \ref ValueFromList type. + This is overload of the above ctor added for convenience. */ + Property(const QCString &name, ListData* listData, + const QVariant &value = QVariant(), + const QString &caption = QString::null, const QString &description = QString::null, + int type = ValueFromList, Property* parent = 0); + + /*! Constructs a deep copy of \a prop property. */ + Property(const Property &prop); + + ~Property(); + + /*! \return the internal name of the property (that's used in List).*/ + QCString name() const; + + /*! Sets the internal name of the property.*/ + void setName(const QCString &name); + + /*! \return the caption of the property.*/ + QString caption() const; + + /*! \return the caption text of the property for displaying. + It is similar to caption() but if the property caption contains newline characters, + these are not substituted with spaces. */ + QString captionForDisplaying() const; + + /*! Sets the name of the property. If the caption contains newline characters, + these are replaced by spaces. You can use captionForDisplaying() + to access the original caption text you passed here.*/ + void setCaption(const QString &caption); + + /*! \return the description of the property.*/ + QString description() const; + + /*! Sets the description of the property.*/ + void setDescription(const QString &description); + + /*! \return the type of the property.*/ + int type() const; + + /*! Sets the type of the property.*/ + void setType(int type); + + /*! \return the value of the property.*/ + QVariant value() const; + + /*! Gets the previous property value.*/ + QVariant oldValue() const; + + /*! Sets the value of the property.*/ + void setValue(const QVariant &value, bool rememberOldValue = true, bool useCustomProperty=true); + + /*! Resets the value of the property to the old value. + @see oldValue() */ + void resetValue(); + + /*! \return the qstring-to-value correspondence list of the property. + used to create comboboxes-like property editors.*/ + ListData* listData() const; + + /*! Sets the qstring-to-value correspondence list of the property. + This is used to create comboboxes-like property editors.*/ + void setListData(ListData* list); + + /*! Sets the string-to-value correspondence list of the property. + This is used to create comboboxes-like property editors. + This is overload of the above ctor added for convenience. */ + void setListData(const QStringList &keys, const QStringList &names); + + /*! Sets icon by \a name for this property. Icons are optional and are used e.g. + in property editor - displayed at the left hand. */ + void setIcon(const QString &icon); + + /*! \return property icon's string. Can be empty. */ + QString icon() const; + + /*! \return a list of all children for this property, or NULL of there + is no children for this property */ + const QValueList* children() const; + + /*! \return a child property for \a name, or NULL if there is no property with that name. */ + Property* child(const QCString &name); + + /*! \return parent property for this property, or NULL if there is no parent property. */ + Property* parent() const; + + /*! \return the custom property for this property.or NULL if there was + no custom property defined. */ + CustomProperty* customProperty() const; + + /*! Sets custom property \a prop for this property. + @see CustomPropertyFactory */ + void setCustomProperty(CustomProperty *prop); + + /*! \return true if this property is null. Null properties have empty names. */ + bool isNull() const; + + /*! Equivalent to !isNull() */ + operator bool () const; + + //! \return true if this property value is changed. + bool isModified() const; + + //! Clears "modified" flag, so isModified() will return false. + void clearModifiedFlag(); + + /*! \return true if the property is read-only. + The property can be read-write but still not editable because the property + set containing it may be set to read-only. + By default the property is read-write. + See Set::isReadOnly() for more details. */ + bool isReadOnly() const; + + /*! Sets this property to be read-only. + @see isReadOnly() */ + void setReadOnly(bool readOnly); + + /*! \return true if the property is visible.*/ + bool isVisible() const; + + /*! Set the visibility.*/ + void setVisible(bool visible); + + /*! \return true 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.*/ + bool isStorable() const; + + /*! Sets "storable" flag for this property. @see isStorable() */ + void setStorable(bool storable); + + /*! \return 1 if the property should be synced automatically in Property Editor + as soon as editor contents change (e.g. when the user types text). + If autoSync() == 0, property value will be updated when the user presses Enter + or when another editor gets the focus. + Property follows Property Editor's global rule if autoSync() !=0 and !=1 (the default). + */ + int autoSync() const; + + /*! if \a sync is 1, the property will be synced automatically in the Property Editor + as soon as editor's contents change (e.g. when the user types text). + If \a sync is 0, property value will be updated when the user presses + Enter or when another editor gets the focus. + Property follows Property Editor's global rule if sync !=0 and !=1 (the default). + */ + void setAutoSync(int sync); + + /*! Sets value \a val for option \a name. + Options are used to describe additional details for property behaviour, + e.g. within Editor. See Editor ctor documentation for + the list of supported options. + */ + void setOption(const char* name, const QVariant& val); + + /*! \return a value for option \a name or null value if there is no such option set. */ + QVariant option(const char* name) const; + + /*! \return true if at least one option is defined for this property. */ + bool hasOptions() const; + + /*! Equivalent to setValue(const QVariant &) */ + const Property& operator= (const QVariant& val); + + /*! Assigns a deep copy of all attributes of \a property to this property. */ + const Property& operator= (const Property &property); + + /*! Compares two properties.*/ + bool operator ==(const Property &prop) const; + + /*! \return a key used for sorting. + Usually it's set by Set::addProperty() and Property::addChild() t oa unique value, + so that this property can be sorted in a property editor in original order. + \see EditorItem::compare() */ + int sortingKey() const; + + protected: + /*! Adds \a prop as a child of this property. + The children will be owned by this property. */ + void addChild(Property *prop); + + /*! Adds \a set to this property. */ + void addSet(Set *set); + + /*! Sets a key used for sorting. */ + void setSortingKey(int key); + + /*! \return a list of related properties for this property. */ + const QValueList* related() const; + + /*! Adds related property for this property. */ + void addRelatedProperty(Property *property); + + /*! This method emits the \a Set::propertyChanged() signal for all + sets this property is registered in. The \a value() method above + calls this method of the value changed. */ + void emitPropertyChanged(); + + /*! Outputs debug string for this property. */ + void debug(); + + //! @internal + PropertyPrivate *d; + + friend class Set; + friend class Buffer; + friend class CustomProperty; +}; + +} + +#endif diff --git a/lib/koproperty/set.cpp b/lib/koproperty/set.cpp new file mode 100644 index 00000000..2e016b64 --- /dev/null +++ b/lib/koproperty/set.cpp @@ -0,0 +1,535 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2004-2006 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "set.h" +#include "property.h" +#include "utils.h" + +#include +#include +//#include + +#include +#include + +typedef QMap > StringListMap; +typedef QMapIterator StringListMapIterator; + +namespace KoProperty { + +//! @internal +static Property Set_nonConstNull; + +//! @internal +class SetPrivate +{ + public: + SetPrivate() : + dict(101, false), + readOnly(false), + informAboutClearing(0) + {} + ~SetPrivate(){} + + //dict of properties in form name: property + Property::Dict dict; +// PropertyList properties; + //groups of properties: + // list of group name: (list of property names) + StringListMap propertiesOfGroup; + QValueList groupNames; + QMap groupDescriptions; + QMap groupIcons; + // map of property: group + QMap groupForProperty; + + bool ownProperty : 1; + bool readOnly : 1; +// static Property nonConstNull; + QCString prevSelection; + QString typeName; + + //! Used in Set::informAboutClearing(Property*) to declare that the property wants + //! to be informed that the set has been cleared (all properties are deleted) + bool* informAboutClearing; + + inline KoProperty::Property& property(const QCString &name) const + { + KoProperty::Property *p = dict.find(name); + if (p) + return *p; + Set_nonConstNull.setName(0); //to ensure returned property is null + kopropertywarn << "Set::property(): PROPERTY \"" << name << "\" NOT FOUND" << endl; + return Set_nonConstNull; + } +}; + +} + +using namespace KoProperty; + +//Set::Iterator class +Set::Iterator::Iterator(const Set &set) +{ + iterator = new Property::DictIterator(set.d->dict); +} + +Set::Iterator::~Iterator() +{ + delete iterator; +} + +void +Set::Iterator::operator ++() +{ + ++(*iterator); +} + +Property* +Set::Iterator::operator *() const +{ + return current(); +} + +QCString +Set::Iterator::currentKey() const +{ + if (iterator) + return iterator->currentKey(); + + return QCString(); +} + +Property* +Set::Iterator::current() const +{ + if(iterator) + return iterator->current(); + + return 0; +} + +////////////////////////////////////////////// + +Set::Set(QObject *parent, const QString &typeName) +: QObject(parent, typeName.latin1()) +{ + d = new SetPrivate(); + d->ownProperty = true; + d->groupDescriptions.insert("common", i18n("General properties", "General")); + d->typeName = typeName; +} + + +Set::Set(const Set &set) + : QObject(0 /* implicit sharing the parent is dangerous */, set.name()) +{ + d = new SetPrivate(); + *this = set; +} + +Set::Set(bool propertyOwner) + : QObject(0, 0) +{ + d = new SetPrivate(); + d->ownProperty = propertyOwner; + d->groupDescriptions.insert("common", i18n("General properties", "General")); +} + +Set::~Set() +{ + emit aboutToBeCleared(); + emit aboutToBeDeleted(); + clear(); + delete d; +} + +///////////////////////////////////////////////////// + +void +Set::addPropertyInternal(Property *property, QCString group, bool updateSortingKey) +{ + if (group.isEmpty()) + group = "common"; + if (property == 0) { + kopropertywarn << "Set::addProperty(): property == 0" << endl; + return; + } + if (property->name().isEmpty()) { + kopropertywarn << "Set::addProperty(): COULD NOT ADD NULL PROPERTY" << endl; + return; + } + + Property *p = d->dict.find(property->name()); + if(p) { + p->addRelatedProperty(property); + } + else { + d->dict.insert(property->name(), property); + addToGroup(group, property); + } + + property->addSet(this); + if (updateSortingKey) + property->setSortingKey( d->dict.count() ); +} + +void +Set::addProperty(Property *property, QCString group) +{ + addPropertyInternal(property, group, true); +} + +void +Set::removeProperty(Property *property) +{ + if(!property) + return; + + Property *p = d->dict.take(property->name()); + removeFromGroup(p); + if(d->ownProperty) { + emit aboutToDeleteProperty(*this, *p); + delete p; + } +} + +void +Set::removeProperty(const QCString &name) +{ + if(name.isNull()) + return; + + Property *p = d->dict.find(name); + removeProperty(p); +} + +void +Set::clear() +{ + if (d->informAboutClearing) + *d->informAboutClearing = true; + d->informAboutClearing = 0; + aboutToBeCleared(); + d->propertiesOfGroup.clear(); + d->groupNames.clear(); + d->groupForProperty.clear(); + d->groupDescriptions.clear(); + d->groupIcons.clear(); + Property::DictIterator it(d->dict); + while (it.current()) + removeProperty( it.current() ); +} + +void +Set::informAboutClearing(bool& cleared) +{ + cleared = false; + d->informAboutClearing = &cleared; +} + +///////////////////////////////////////////////////// + +void +Set::addToGroup(const QCString &group, Property *property) +{ + if(!property) + return; + + //do not add the same property to the group twice + if(d->groupForProperty.contains(property) && (d->groupForProperty[property] == group)) + return; + + if(!d->propertiesOfGroup.contains(group)) { // group doesn't exist + QValueList l; + l.append(property->name()); + d->propertiesOfGroup.insert(group, l); + d->groupNames.append(group); + } + else { + d->propertiesOfGroup[group].append(property->name()); + } + d->groupForProperty.insert(property, group); +} + +void +Set::removeFromGroup(Property *property) +{ + if(!property) + return; + QCString group = d->groupForProperty[property]; + d->propertiesOfGroup[group].remove(property->name()); + if (d->propertiesOfGroup[group].isEmpty()) { + //remove group as well + d->propertiesOfGroup.remove(group); + QValueListIterator it = d->groupNames.find(group); + if (it != d->groupNames.end()) { + d->groupNames.remove(it); + } + } + d->groupForProperty.remove(property); +} + +const QValueList& +Set::groupNames() const +{ + return d->groupNames; +} + +const QValueList& +Set::propertyNamesForGroup(const QCString &group) const +{ + return d->propertiesOfGroup[group]; +} + +void +Set::setGroupDescription(const QCString &group, const QString& desc) +{ + d->groupDescriptions[group] = desc; +} + +QString +Set::groupDescription(const QCString &group) const +{ + if(d->groupDescriptions.contains(group)) + return d->groupDescriptions[group]; + return group; +} + +void +Set::setGroupIcon(const QCString &group, const QString& icon) +{ + d->groupIcons[group] = icon; +} + +QString +Set::groupIcon(const QCString &group) const +{ + return d->groupIcons[group]; +} + +///////////////////////////////////////////////////// + +uint +Set::count() const +{ + return d->dict.count(); +} + +bool +Set::isEmpty() const +{ + return d->dict.isEmpty(); +} + +bool +Set::isReadOnly() const +{ + return d->readOnly; +} + +void +Set::setReadOnly(bool readOnly) +{ + d->readOnly = readOnly; +} + +bool +Set::contains(const QCString &name) const +{ + return d->dict.find(name); +} + +Property& +Set::property(const QCString &name) const +{ + return d->property(name); +} + +Property& +Set::operator[](const QCString &name) const +{ + return d->property(name); +} + +const Set& +Set::operator= (const Set &set) +{ + if(&set == this) + return *this; + + clear(); + + d->ownProperty = set.d->ownProperty; + d->prevSelection = set.d->prevSelection; + d->groupDescriptions = set.d->groupDescriptions; + + // Copy all properties in the list + for(Property::DictIterator it(set.d->dict); it.current(); ++it) { + Property *prop = new Property( *it.current() ); + addPropertyInternal(prop, set.d->groupForProperty[ it.current() ], + false /*!updateSortingKey, because the key is already set in Property copy ctor.*/ ); + } + + return *this; +} + +void +Set::changeProperty(const QCString &property, const QVariant &value) +{ + Property *p = d->dict[property]; + if(p) + p->setValue(value); +} + +///////////////////////////////////////////////////// + +void +Set::debug() +{ + //kopropertydbg << "List: typeName='" << m_typeName << "'" << endl; + if(d->dict.isEmpty()) { + kopropertydbg << "" << endl; + return; + } + kopropertydbg << d->dict.count() << " properties:" << endl; + + for(Property::DictIterator it(d->dict); it.current(); ++it) + it.current()->debug(); +} + +QCString +Set::prevSelection() const +{ + return d->prevSelection; +} + +void +Set::setPrevSelection(const QCString &prevSelection) +{ + d->prevSelection = prevSelection; +} + +QString +Set::typeName() const +{ + return d->typeName; +} + +///////////////////////////////////////////////////// + +Buffer::Buffer() + :Set(false) +{ + connect( this, SIGNAL( propertyChanged( KoProperty::Set&, KoProperty::Property& ) ), + this, SLOT(intersectedChanged( KoProperty::Set&, KoProperty::Property& ) ) ); + + connect( this, SIGNAL( propertyReset( KoProperty::Set&, KoProperty::Property& ) ), + this, SLOT(intersectedReset( KoProperty::Set&, KoProperty::Property& ) ) ); +} + +Buffer::Buffer(const Set *set) + :Set(false) +{ + connect( this, SIGNAL( propertyChanged( KoProperty::Set&, KoProperty::Property& ) ), + this, SLOT(intersectedChanged( KoProperty::Set&, KoProperty::Property& ) ) ); + + connect( this, SIGNAL( propertyReset( KoProperty::Set&, KoProperty::Property& ) ), + this, SLOT(intersectedReset( KoProperty::Set&, KoProperty::Property& ) ) ); + + initialSet( set ); +} + +void Buffer::initialSet(const Set *set) +{ + //deep copy of set + for(Property::DictIterator it(set->d->dict); it.current(); ++it) { + Property *prop = new Property( *it.current() ); + QCString group = set->d->groupForProperty[it.current()]; + QString groupDesc = set->d->groupDescriptions[ group ]; + setGroupDescription( group, groupDesc ); + addProperty( prop, group ); + prop->addRelatedProperty( it.current() ); + } +} + +void Buffer::intersect(const Set *set) +{ + if ( d->dict.isEmpty() ) + { + initialSet( set ); + return; + } + + for(Property::DictIterator it(d->dict); it.current(); ++it) { + const char* key = it.current()->name(); + if ( Property *property = set->d->dict[ key ] ) + { + blockSignals( true ); + it.current()->resetValue(); + it.current()->addRelatedProperty( property ); + blockSignals( false ); + } + else + removeProperty( key ); + } +} + +void Buffer::intersectedChanged(KoProperty::Set& set, KoProperty::Property& prop) +{ + Q_UNUSED(set); + QCString propertyName = prop.name(); + if ( !contains( propertyName ) ) + return; + + const QValueList *props = prop.related(); + QValueList::const_iterator it = props->begin(); + for ( ; it != props->end(); ++it ) { + ( *it )->setValue( prop.value(), false ); + } +} + +void Buffer::intersectedReset(KoProperty::Set& set, KoProperty::Property& prop) +{ + Q_UNUSED(set); + QCString propertyName = prop.name(); + if ( !contains( propertyName ) ) + return; + + const QValueList *props = prop.related(); + QValueList::const_iterator it = props->begin(); + for ( ; it != props->end(); ++it ) { + ( *it )->setValue( prop.value(), false ); + } +} + +////////////////////////////////////////////// + +QMap KoProperty::propertyValues(const Set& set) +{ + QMap result; + for (Set::Iterator it(set); it.current(); ++it) + result.insert( it.currentKey(), it.current()->value() ); + + return result; +} + +#include "set.moc" diff --git a/lib/koproperty/set.h b/lib/koproperty/set.h new file mode 100644 index 00000000..f7c455ed --- /dev/null +++ b/lib/koproperty/set.h @@ -0,0 +1,254 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + Copyright (C) 2004-2006 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_SET_H +#define KPROPERTY_SET_H + +#include "koproperty_global.h" +#include +#include + +namespace KoProperty { + +class Property; +class SetPrivate; + +/*! \brief Lists holding properties in groups + + \author Cedric Pasteur + \author Alexander Dymo + \author Jaroslaw Staniek + */ +class KOPROPERTY_EXPORT Set : public QObject +{ + Q_OBJECT + + public: + /*! \brief A class to iterate over a Set. + It behaves like a QDictIterator. To use it: + \code for(Set::Iterator it(set); it.current(); ++it) { .... } + \endcode + \author Cedric Pasteur + \author Alexander Dymo */ + class KOPROPERTY_EXPORT Iterator { + public: + Iterator(const Set &set); + ~Iterator(); + + void operator ++(); + Property* operator *() const; + + QCString currentKey() const; + Property* current() const; + + private: + QAsciiDictIterator *iterator; + friend class Set; + }; + + explicit Set(QObject *parent=0, const QString &typeName=QString::null); + + /*! Constructs a deep copy of \a set. + The new object will not have a QObject parent even if \a set has such parent. */ + explicit Set(const Set& set); + + virtual ~Set(); + + /*! Adds the property to the set, in the group. You can use any group name, except "common" + (which is already used for basic group). */ + void addProperty(Property *property, QCString group = "common"); + + /*! Removes property from the set. Emits aboutToDeleteProperty before removing.*/ + void removeProperty(Property *property); + + /*! Removes property with the given name from the set. + Emits aboutToDeleteProperty() before removing.*/ + void removeProperty(const QCString &name); + + /*! Removes all properties from the property set and destroys them. */ + virtual void clear(); + + /*! \return the number of items in the set. */ + uint count() const; + + /*! \return true if the set is empty, i.e. count() == 0; otherwise returns false. */ + bool isEmpty() const; + + /*! \return true if the set is read-only. + In read-only property set, + no property can be modified regardless of read-only flag of any + property (see Property::isReadOnly()). On the other hand, if Property::isReadOnly() + is true of a property and Set::isReadOnly() is false, the property is still read-only. + Read-only property set prevents editing in the property editor. + By default the set is read-write. */ + bool isReadOnly() const; + + /*! Sets this set to be read-only. + @see isReadOnly */ + void setReadOnly(bool readOnly); + + /*! \return true if the set contains property names \a name. */ + bool contains(const QCString &name) const; + + /*! \return property named with \a name. If no such property is found, + null property (Property::null) is returned. */ + Property& property( const QCString &name) const; + + /*! Accesses a property by it's name. + Property reference is returned, so all property modifications are allowed. + If there is no such property, null property is returned, + so it's good practice to use contains() is you're unsure if the property exists. + For example, to set a value of a property, use: + /code + Set set; + ... + if (!set.contains("myProperty")) { + dosomething; + } + set["myProperty"].setValue("My Value"); + /endcode + \return \ref Property with given name. */ + Property& operator[](const QCString &name) const; + + /*! Creates a deep copy of \a set and assigns it to this property set. */ + const Set& operator= (const Set &set); + + /*! Change the value of property whose key is \a property to \a value. + By default, it only calls Property::setValue(). */ + void changeProperty(const QCString &property, const QVariant &value); + + /*! Sets the i18n'ed string that will be shown in Editor to represent + \a group. */ + void setGroupDescription(const QCString &group, const QString& desc); + + /*! \return the i18n'ed description string for \a group that will + be shown in Editor to represent \a group. If there is no special + description set for the group, \a group is just returned. */ + QString groupDescription(const QCString &group) const; + + /*! Sets the icon name \a icon to be displayed for \a group. */ + void setGroupIcon(const QCString &group, const QString& icon); + + /*! \return the icons name for \a group. */ + QString groupIcon(const QCString &group) const; + + /*! \return a list of all group names. The order is the same as the order + of creation. */ + const QValueList& groupNames() const; + + /*! \return a list of all property names. The order is the same as the order + of creation. */ + const QValueList& propertyNamesForGroup(const QCString &group) const; + + /*! Used by property editor to preserve previous selection when this set + is assigned again. */ + QCString prevSelection() const; + + void setPrevSelection(const QCString& prevSelection); + + /*! A name of this property set type, that is usable when + we want to know if two property set objects have the same type. + This avoids e.g. reloading of all Editor's contents. + Also, this allows to know if two property set objects are compatible + by their property sets. + For comparing purposes, type names are case insensitive.*/ + QString typeName() const; + + /*! Prints debug output for this set. */ + void debug(); + + protected: + /*! Constructs a set which owns or does not own it's properties.*/ + Set(bool propertyOwner); + + /*! Adds property to a group.*/ + void addToGroup(const QCString &group, Property *property); + + /*! Removes property from a group.*/ + void removeFromGroup(Property *property); + + /*! Adds the property to the set, in the group. You can use any group name, except "common" + (which is already used for basic group). If \a updateSortingKey is true, the sorting key + will be set automatically to count(). + @internal */ + void addPropertyInternal(Property *property, QCString group, bool updateSortingKey); + + /*! @internal used to declare that \a property wants to be informed + that the set has been cleared (all properties are deleted) */ + void informAboutClearing(bool& cleared); + + signals: + /*! Emitted when the value of the property is changed.*/ + void propertyChanged(KoProperty::Set& set, KoProperty::Property& property); + + /*! @internal Exists to be sure that we emitted it before propertyChanged(), + so Editor object can handle this. */ + void propertyChangedInternal(KoProperty::Set& set, KoProperty::Property& property); + + /*! Emitted when the value of the property is reset.*/ + void propertyReset(KoProperty::Set& set, KoProperty::Property& property); + + /*! Emitted when property is about to be deleted.*/ + void aboutToDeleteProperty(KoProperty::Set& set, KoProperty::Property& property); + + /*! Emitted when property set object is about to be cleared (using clear()). + This signal is also emmited from destructor before emitting aboutToBeDeleted(). */ + void aboutToBeCleared(); + + /*! Emitted when property set object is about to be deleted.*/ + void aboutToBeDeleted(); + + protected: + SetPrivate *d; + + friend class Iterator; + friend class Property; + friend class Buffer; +}; + +/*! \brief + \todo find a better name to show it's a set that doesn't own property + \author Cedric Pasteur + \author Alexander Dymo + \author Adam Treat + */ +class KOPROPERTY_EXPORT Buffer : public Set +{ + Q_OBJECT + + public: + Buffer(); + Buffer(const Set *set); + + /*! Intersects with other Set.*/ + virtual void intersect(const Set *set); + + protected slots: + void intersectedChanged(KoProperty::Set& set, KoProperty::Property& prop); + void intersectedReset(KoProperty::Set& set, KoProperty::Property& prop); + + private: + void initialSet(const Set *set); +}; + +} + +#endif diff --git a/lib/koproperty/test/Makefile.am b/lib/koproperty/test/Makefile.am new file mode 100644 index 00000000..2bcf7993 --- /dev/null +++ b/lib/koproperty/test/Makefile.am @@ -0,0 +1,17 @@ +noinst_HEADERS = test.h + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + +noinst_PROGRAMS = propertytest + +propertytest_SOURCES = main.cpp test.cpp +propertytest_LDFLAGS = $(all_libraries) $(KDE_RPATH) +propertytest_LDADD = $(LIB_KOPROPERTY) + +# this is where the shell's XML-GUI resource file goes +#shellrcdir = $(kde_datadir)/test +#shellrc_DATA = testui.rc + +INCLUDES= $(KOPROPERTY_INCLUDES) $(KOFFICE_INCLUDES) $(all_includes) + diff --git a/lib/koproperty/test/main.cpp b/lib/koproperty/test/main.cpp new file mode 100644 index 00000000..83370cfd --- /dev/null +++ b/lib/koproperty/test/main.cpp @@ -0,0 +1,68 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "test.h" +#include +#include +#include +#include + +static const char description[] = "A test application for the KoProperty library"; + +static const char version[] = "0.2"; + +static KCmdLineOptions options[] = +{ + { "flat", "Flat display: don't display groups\n(useful for testing)", 0 }, + { "ro", "Set all properties as read-only:\n(useful for testing read-only mode)", 0 }, + KCmdLineLastOption +}; + +int main(int argc, char **argv) +{ + KAboutData about("proptest", "KoProperty Test", version, description, + KAboutData::License_GPL, "(C) 2005 Cedric Pasteur", 0, 0, "cedric.pasteur@free.fr"); + about.addAuthor( "Cedric Pasteur", 0, "cedric.pasteur@free.fr" ); + KCmdLineArgs::init(argc, argv, &about); + KCmdLineArgs::addCmdLineOptions( options ); + KApplication app; + Test *mainWin = 0; + + if (app.isRestored()) + { + RESTORE(Test); + } + else + { + // no session.. just start up normally + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + /// @todo do something with the command line args here + + mainWin = new Test(); + app.setMainWidget( mainWin ); + mainWin->show(); + + args->clear(); + } + + // mainWin has WDestructiveClose flag by default, so it will delete itself. + return app.exec(); +} + diff --git a/lib/koproperty/test/test.cpp b/lib/koproperty/test/test.cpp new file mode 100644 index 00000000..2c7c7561 --- /dev/null +++ b/lib/koproperty/test/test.cpp @@ -0,0 +1,126 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "test.h" + +using namespace KoProperty; + +Test::Test() + : KMainWindow(0,"koproperty_test") +{ + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + const bool flat = args->isSet("flat"); + const bool readOnly = args->isSet("ro"); + +// setXMLFile("testui.rc"); + QFont f; + f.setPixelSize(f.pixelSize()*2/3); + setFont(f); + +/* First, create the Set which will hold the properties. */ + Property *p = 0; + m_set = new Set(this, "test"); + m_set->setReadOnly(readOnly); + QCString group; + if (!flat) { + group = "SimpleGroup"; + m_set->setGroupDescription(group, "Simple Group"); + } + m_set->addProperty(new Property("Name", "Name"), group); + (*m_set)["Name"].setAutoSync(1); + + m_set->addProperty(new Property("Int", 2, "Int"), group); + m_set->addProperty(new Property("Double", 3.1415,"Double"), group); + m_set->addProperty(new Property("Bool", QVariant(true, 4), "Bool"), group); + m_set->addProperty(p = new Property("3 States", QVariant(), "3 States", "", Boolean), group); + p->setOption("3rdState", "None"); + m_set->addProperty(p = new Property("Date", QDate::currentDate(),"Date"), group); + p->setIcon("date"); + m_set->addProperty(new Property("Time", QTime::currentTime(),"Time"), group); + m_set->addProperty(new Property("DateTime", QDateTime::currentDateTime(),"Date/Time"), group); + + QStringList list;//keys + list << "myitem" << "otheritem" << "3rditem"; + QStringList name_list; //strings + name_list << "My Item" << "Other Item" << "Third Item"; + m_set->addProperty(new Property("List", list, name_list, "otheritem", "List"), group); + + // A valueFromList property matching strings with ints (could be any type supported by QVariant) + QValueList keys; + keys.append(1); + keys.append(2); + keys.append(3); + Property::ListData *listData = new Property::ListData(keys, name_list); + m_set->addProperty(new Property("List2", listData, 3, "List 2"), group); + +// Complex + if (!flat) { + group = "ComplexGroup"; + m_set->setGroupDescription(group, "Complex Group"); + } + m_set->addProperty(new Property("Rect", this->geometry(),"Rect"), group); + m_set->addProperty(new Property("Point", QPoint(3,4), "Point"), group); + m_set->addProperty(new Property("Size", QPoint(3,4), "Size"), group); + +// Appearance + if (!flat) { + group = "Appearance Group"; + m_set->setGroupDescription(group, "Appearance Group"); + m_set->setGroupIcon(group, "appearance"); + } + m_set->addProperty(new Property("Color", this->paletteBackgroundColor(),"Color"), group); + QPixmap pm(DesktopIcon("network")); + m_set->addProperty(p = new Property("Pixmap", pm,"Pixmap"), group); + p->setIcon("kpaint"); + m_set->addProperty(p = new Property("Font", this->font(),"Font"), group); + p->setIcon("fonts"); + m_set->addProperty(new Property("Cursor", QCursor(Qt::WaitCursor),"Cursor"), group); + m_set->addProperty(new Property("LineStyle", 3, "Line Style", "", LineStyle), group); + m_set->addProperty(new Property("SizePolicy", sizePolicy(), "Size Policy"), group); + +// kdDebug() << m_set->groupNames() << endl; + + Editor *edit = new Editor(this,true/*autosync*/); + setCentralWidget(edit); + edit->changeSet(m_set); + resize(400,qApp->desktop()->height()-200); + move(x(),5); + edit->setFocus(); +} + +Test::~Test() +{ +} + +#include "test.moc" diff --git a/lib/koproperty/test/test.h b/lib/koproperty/test/test.h new file mode 100644 index 00000000..cef6e97a --- /dev/null +++ b/lib/koproperty/test/test.h @@ -0,0 +1,47 @@ +/* This file is part of the KDE project + Copyright (C) 2004-2005 Cedric Pasteur + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef TEST_H +#define TEST_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include + +/*! + * @short KoProperty test appliation main window + * @author Cedric Pasteur + * @version 0.1 + */ +class Test : public KMainWindow +{ + Q_OBJECT + public: + Test(); + virtual ~Test(); + + private: + KoProperty::Set *m_set; +}; + +#endif diff --git a/lib/koproperty/utils.h b/lib/koproperty/utils.h new file mode 100644 index 00000000..ee583508 --- /dev/null +++ b/lib/koproperty/utils.h @@ -0,0 +1,49 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Jaroslaw Staniek + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KOPROPERTY_UTILS_H +#define KOPROPERTY_UTILS_H + +#include +#include + +namespace KoProperty { + +//! @short A container widget that can be used to split information into hideable sections +//! for a property editor-like panes. +class KOPROPERTY_EXPORT GroupContainer : public QWidget +{ + public: + GroupContainer(const QString& title, QWidget* parent); + ~GroupContainer(); + + void setContents( QWidget* contents ); + + protected: + virtual bool event( QEvent * e ); + + class Private; + Private *d; +}; + +KOPROPERTY_EXPORT QMap propertyValues(const Set& set); + +} + +#endif diff --git a/lib/koproperty/widget.cpp b/lib/koproperty/widget.cpp new file mode 100644 index 00000000..2584477e --- /dev/null +++ b/lib/koproperty/widget.cpp @@ -0,0 +1,232 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "widget.h" +#include "property.h" +#include "editoritem.h" +#include "editor.h" + +#include +#include + +#include +#include + +using namespace KoProperty; + +namespace KoProperty { +class WidgetPrivate +{ + public: + WidgetPrivate() + : property(0) + , editor(0) + , leaveTheSpaceForRevertButton(false) + , hasBorders(true) + , readOnly(false) + , visibleFlag(true) + { + } + ~WidgetPrivate() {} + + Property *property; + QWidget *editor; + bool leaveTheSpaceForRevertButton : 1; + bool hasBorders : 1; + bool readOnly : 1; + bool visibleFlag : 1; +}; +} + +Widget::Widget(Property *property, QWidget *parent, const char *name) + : QWidget(parent, name) +{ + d = new WidgetPrivate(); + d->property = property; +} + +Widget::~Widget() +{ + delete d; + d = 0; +} + +Property* +Widget::property() const +{ + return d ? d->property : 0; //for sanity +} + +void +Widget::setProperty(Property *property) +{ + d->property = property; + if(property) + setValue(property->value(), false); + //if(property->type() == ValueFromList) + // setValueList(property->valueList()); +} + +void +Widget::drawViewer(QPainter *p, const QColorGroup &, const QRect &r, const QVariant &value) +{ + p->eraseRect(r); + QRect rect(r); + rect.setLeft(rect.left()+KPROPEDITOR_ITEM_MARGIN); +// if (d->hasBorders) +// rect.setTop(rect.top()+1); //+1 to have the same vertical position as editor +// else +// rect.setHeight(rect.height()-1); //don't place over listviews's border + p->drawText(rect, Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, value.toString()); +} + +void +Widget::undo() +{ + if(d->property) + d->property->resetValue(); +} + +bool +Widget::eventFilter(QObject*, QEvent* e) +{ + if(e->type() == QEvent::KeyPress) + { + QKeyEvent* ev = static_cast(e); + if(ev->key() == Key_Escape) + { + emit rejectInput(this); + return true; + } + else if((ev->key() == Key_Return) || (ev->key() == Key_Enter)) + { + // should apply when autosync == false + emit acceptInput(this); + return true; + } + else { + Editor *list = static_cast(parentWidget()->parentWidget()); + if (!list) + return false; //for sanity + return list->handleKeyPress(ev); + } + + /* moved in Editor + if (item) { + if(ev->key() == Key_Up && ev->state() != ControlButton) + { + if(item->itemAbove()) + list->setCurrentItem(item->itemAbove()); + return true; + } + else if(ev->key() == Key_Down && ev->state() != ControlButton) + { + if(item->itemBelow()) + list->setCurrentItem(item->itemBelow()); + return true; + } + }*/ + } + + return false; +} + +void +Widget::setFocusWidget(QWidget*focusProxy) +{ + if (focusProxy) { + if (focusProxy->focusPolicy() != NoFocus) + setFocusProxy(focusProxy); + focusProxy->installEventFilter(this); + } + else if (this->focusProxy()) { + this->focusProxy()->removeEventFilter(this); + setFocusProxy(0); + } +} + +bool +Widget::leavesTheSpaceForRevertButton() const +{ + return d->leaveTheSpaceForRevertButton; +} + +void +Widget::setLeavesTheSpaceForRevertButton(bool set) +{ + d->leaveTheSpaceForRevertButton = set; +} + +void +Widget::setHasBorders(bool set) +{ + d->hasBorders = set; +} + +bool +Widget::hasBorders() const +{ + return d->hasBorders; +} + +void +Widget::setEditor(QWidget* editor) +{ + d->editor = editor; + if (!d->editor) + return; + d->editor->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + d->editor->move(0,0); +} + +void +Widget::resizeEvent(QResizeEvent *e) +{ + QWidget::resizeEvent(e); + if (d->editor) + d->editor->resize(size()); +} + +bool +Widget::isReadOnly() const +{ + return d->readOnly; +} + +void +Widget::setReadOnly(bool readOnly) +{ + d->readOnly = readOnly; + setReadOnlyInternal(readOnly); +} + +bool +Widget::visibleFlag() const +{ + return d->visibleFlag; +} + +void +Widget::setVisibleFlag(bool visible) +{ + d->visibleFlag = visible; +} + +#include "widget.moc" diff --git a/lib/koproperty/widget.h b/lib/koproperty/widget.h new file mode 100644 index 00000000..a758589e --- /dev/null +++ b/lib/koproperty/widget.h @@ -0,0 +1,120 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_PROPERTYWIDGET_H +#define KPROPERTY_PROPERTYWIDGET_H + +#include +#include "koproperty_global.h" + +namespace KoProperty { + +class WidgetPrivate; +class Property; + +/*! \brief The base class for all item editors used in Editor. + \author Cedric Pasteur + \author Alexander Dymo +*/ +class KOPROPERTY_EXPORT Widget : public QWidget +{ + Q_OBJECT + + public: + Widget(Property *property, QWidget *parent, const char *name="property_editor"); + virtual ~Widget(); + + /*! \return the value currently entered in the item editor widget.*/ + virtual QVariant value() const = 0; + + /*! Sets the value shown in the item 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 edited property. */ + virtual Property* property() const; + + /*! Sets the name of edited property.*/ + virtual void setProperty(Property *property); + + /*! Function to draw a property viewer when the item 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(); + + /*! Sets the widget that will receive focus when the Widget is selected. */ + void setFocusWidget(QWidget*focusProxy); + + //! \sa d->leaveTheSpaceForRevertButton description + bool leavesTheSpaceForRevertButton() const; + + /*! \return true if this editor has borders. + Editors with borders have slightly larger height and width set by property editor widget. */ + bool hasBorders() const; + + /*! \return true if the widget is read-only. + Read-only property widget does not allow to change its property value. + The flag is inherited from the underlying property and property set. + Editor::setValue() method will still work, however. + @see Set::isReadOnly(). */ + bool isReadOnly() const; + + /*! Sets this widget to be read-only. + Disables or enables editing in the appropriate widget(s). + @see isReadOnly() */ + void setReadOnly(bool readOnly); + + /*! @internal + This flag is checked by Editor when the widget is about to show. */ + bool visibleFlag() const; + + signals: + void valueChanged(Widget *widget); + void acceptInput(Widget *widget); + void rejectInput(Widget *widget); + + protected: + void setEditor(QWidget* editor); + + /*! Filters some event for main widget, eg Enter or Esc key presses. */ + virtual bool eventFilter(QObject* watched, QEvent* e); + + virtual void resizeEvent(QResizeEvent *e); + + void setLeavesTheSpaceForRevertButton(bool set); + void setHasBorders(bool set); + + /*! Called by setReadOnly(bool). + For implementation: for read-only you should disable editing in the appropriate widget(s). */ + virtual void setReadOnlyInternal(bool readOnly) = 0; + + /*! Used only in setReadOnlyInternal() to make the widget visible or invisible. + This flag is checked by Editor when the widget is about to show. + By default widgets are visible. */ + void setVisibleFlag(bool visible); + + protected: + WidgetPrivate *d; +}; + +} + +#endif diff --git a/lib/koproperty/widgetproxy.cpp b/lib/koproperty/widgetproxy.cpp new file mode 100644 index 00000000..a98f57a1 --- /dev/null +++ b/lib/koproperty/widgetproxy.cpp @@ -0,0 +1,125 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ +#include "widgetproxy.h" +#include "property.h" +#include "widget.h" +#include "factory.h" + +#include +#include + +namespace KoProperty { +class WidgetProxyPrivate +{ + public: + WidgetProxyPrivate() + : property(0), widget(0), type(Invalid), layout(0) + {} + ~WidgetProxyPrivate() {} + + Property *property; + Widget *widget; + PropertyType type; + + QHBoxLayout *layout; +}; +} + +using namespace KoProperty; + +WidgetProxy::WidgetProxy(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + d = new WidgetProxyPrivate(); + d->property = new Property(); + d->layout = new QHBoxLayout(this, 0, 0); +} + +WidgetProxy::~WidgetProxy() +{ + delete d->property; +} + +void +WidgetProxy::setPropertyType(int propertyType) +{ + d->type = propertyType; + setWidget(); +} + +int +WidgetProxy::propertyType() const +{ + return d->type; +} + +QVariant +WidgetProxy::value() const +{ + if (m_editor) + return m_editor->value(); + else + return QVariant(); +} + +void +WidgetProxy::setValue(const QVariant &value) +{ + if (d->widget) + d->widget->setValue(value, false); +} + +bool +WidgetProxy::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 +WidgetProxy::property(const char *name) const +{ + if( strcmp( name, "value") == 0 ) + return value( ); + else + return QWidget::property(name); +} + +void +WidgetProxy::setWidget() +{ + if (d->widget) + delete d->widget; + + p->setType(d->type); + d->widget = Factory::getInstance()->widgetForProperty(p); + + if (d->widget) { + d->widget->reparent(this, QPoint(0,0), true); + d->layout->addWidget(d->widget); + } +} + +#include "widgetproxy.moc" diff --git a/lib/koproperty/widgetproxy.h b/lib/koproperty/widgetproxy.h new file mode 100644 index 00000000..17c9b4ff --- /dev/null +++ b/lib/koproperty/widgetproxy.h @@ -0,0 +1,63 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPROPERTY_PROPERTYWIDGETPROXY_H +#define KPROPERTY_PROPERTYWIDGETPROXY_H + +#include +#include "koproperty_global.h" + +class QVariant; + +namespace KoProperty { + +class WidgetProxyPrivate; + +/*! \brief + \author Cedric Pasteur + \author Alexander Dymo +*/ +class KOPROPERTY_EXPORT WidgetProxy : public QWidget +{ + Q_OBJECT + + public: + WidgetProxy(QWidget *parent, const char *name=0); + WidgetProxy(); + + void setPropertyType(int propertyType); + int propertyType() const; + + QVariant value() const; + void setValue(const QVariant &value); + + virtual bool setProperty( const char *name, const QVariant &value); + virtual QVariant property( const char *name) const; + + protected: + void setWidget(); + + private: + WidgetProxyPrivate *d; +}; + +} + +#endif -- cgit v1.2.1