00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "keximacroproperty.h"
00019
00020 #include <qlayout.h>
00021 #include <qlineedit.h>
00022 #include <qlistbox.h>
00023 #include <qpainter.h>
00024
00025 #include <kcombobox.h>
00026 #include <kpushbutton.h>
00027 #include <klocale.h>
00028 #include <kiconloader.h>
00029 #include <kdebug.h>
00030
00031 #include "../lib/variable.h"
00032 #include "../lib/macroitem.h"
00033
00034 #define KEXIMACRO_PROPERTYEDITORTYPE 5682
00035
00036
00037
00038
00039
00044 class KexiMacroProperty::Private
00045 {
00046 public:
00050 KSharedPtr<KoMacro::MacroItem> macroitem;
00053 QString name;
00054 };
00055
00056 KexiMacroProperty::KexiMacroProperty(KoProperty::Property* parent, KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name)
00057 : KoProperty::CustomProperty(parent)
00058 , d( new Private() )
00059 {
00060 d->macroitem = macroitem;
00061 d->name = name;
00062 init();
00063 }
00064
00065 KexiMacroProperty::~KexiMacroProperty()
00066 {
00067 delete d;
00068 }
00069
00070 void KexiMacroProperty::init()
00071 {
00072 Q_ASSERT( d->macroitem != 0 );
00073
00074
00075 KSharedPtr<KoMacro::Action> action = d->macroitem->action();
00076 KSharedPtr<KoMacro::Variable> actionvariable = action->variable(d->name);
00077 if(! actionvariable.data()) {
00078 kdDebug() << "KexiMacroProperty::createProperty() Skipped cause there exists no such action=" << d->name << endl;
00079 return;
00080 }
00081
00082 KSharedPtr<KoMacro::Variable> variable = d->macroitem->variable(d->name, true);
00083 if(! variable.data()) {
00084 kdDebug() << "KexiMacroProperty::createProperty() Skipped cause there exists no such variable=" << d->name << endl;
00085 return;
00086 }
00087
00088
00089
00090
00091 Q_ASSERT(! d->name.isNull());
00092 m_property->setName( d->name.latin1() );
00093 m_property->setCaption( actionvariable->text() );
00094 m_property->setDescription( action->comment() );
00095 m_property->setValue( variable->variant(), true );
00096 m_property->setType( KEXIMACRO_PROPERTYEDITORTYPE );
00097 }
00098
00099 KoProperty::Property* KexiMacroProperty::parentProperty() const
00100 {
00101 return m_property;
00102 }
00103
00104 void KexiMacroProperty::setValue(const QVariant &value, bool rememberOldValue)
00105 {
00106 Q_UNUSED(rememberOldValue);
00107 kdDebug()<<"KexiMacroProperty::setValue name="<<d->name<<" value="<<value<<" rememberOldValue="<<rememberOldValue<<endl;
00108 if(! d->macroitem->setVariant(d->name, value)) {
00109 kdDebug()<<"KexiMacroProperty::setValue Update failed !!!"<<endl;
00110 return;
00111 }
00112
00113
00114
00115
00116
00117
00118
00119 emit valueChanged();
00120 }
00121
00122 QVariant KexiMacroProperty::value() const
00123 {
00124 KSharedPtr<KoMacro::Variable> variable = d->macroitem->variable(d->name, true);
00125 Q_ASSERT( variable.data() != 0 );
00126 return variable.data() ? variable->variant() : QVariant();
00127 }
00128
00129 bool KexiMacroProperty::handleValue() const
00130 {
00131 return true;
00132 }
00133
00134 KSharedPtr<KoMacro::MacroItem> KexiMacroProperty::macroItem() const
00135 {
00136 return d->macroitem;
00137 }
00138
00139 QString KexiMacroProperty::name() const
00140 {
00141 return d->name;
00142 }
00143
00144 KSharedPtr<KoMacro::Variable> KexiMacroProperty::variable() const
00145 {
00146 return d->macroitem->variable(d->name, true);
00147 }
00148
00149 KoProperty::Property* KexiMacroProperty::createProperty(KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name)
00150 {
00151 KoProperty::Property* property = new KoProperty::Property();
00152 KexiMacroProperty* customproperty = new KexiMacroProperty(property, macroitem, name);
00153 if(! customproperty->variable().data()) {
00154 kdWarning() << "KexiMacroProperty::createProperty() No such variable" << endl;
00155 delete customproperty; customproperty = 0;
00156 delete property; property = 0;
00157 return 0;
00158 }
00159 property->setCustomProperty(customproperty);
00160 return property;
00161 }
00162
00163
00164
00165
00166
00167 KexiMacroPropertyFactory::KexiMacroPropertyFactory(QObject* parent)
00168 : KoProperty::CustomPropertyFactory(parent)
00169 {
00170 }
00171
00172 KexiMacroPropertyFactory::~KexiMacroPropertyFactory()
00173 {
00174 }
00175
00176 KoProperty::CustomProperty* KexiMacroPropertyFactory::createCustomProperty(KoProperty::Property* parent)
00177 {
00178 kdDebug()<<"KexiMacroPropertyFactory::createCustomProperty parent="<<parent->name()<<endl;
00179
00180 KoProperty::CustomProperty* customproperty = parent->customProperty();
00181 KexiMacroProperty* parentcustomproperty = dynamic_cast<KexiMacroProperty*>(customproperty);
00182 if(! parentcustomproperty) {
00183 kdWarning() << "KexiMacroPropertyFactory::createCustomProperty() parent=" << parent->name() << " has an invalid customproperty." << endl;
00184 return 0;
00185 }
00186
00187 KSharedPtr<KoMacro::MacroItem> macroitem = parentcustomproperty->macroItem();
00188 Q_ASSERT( macroitem.data() != 0 );
00189 const QString name = parentcustomproperty->name();
00190 Q_ASSERT(! name.isEmpty());
00191
00192 KexiMacroProperty* macroproperty = new KexiMacroProperty(parent, macroitem, name);
00193 if(! macroproperty->variable().data()) {
00194 delete macroproperty; macroproperty = 0;
00195 return 0;
00196 }
00197
00198 return macroproperty;
00199 }
00200
00201 KoProperty::Widget* KexiMacroPropertyFactory::createCustomWidget(KoProperty::Property* property)
00202 {
00203 kdDebug()<<"KexiMacroPropertyFactory::createCustomWidget property="<<property->name()<<endl;
00204 return new KexiMacroPropertyWidget(property);
00205 }
00206
00207 void KexiMacroPropertyFactory::initFactory()
00208 {
00209 CustomPropertyFactory* factory = KoProperty::FactoryManager::self()->factoryForEditorType(KEXIMACRO_PROPERTYEDITORTYPE);
00210 if(! factory) {
00211 factory = new KexiMacroPropertyFactory( KoProperty::FactoryManager::self() );
00212 KoProperty::FactoryManager::self()->registerFactoryForEditor(KEXIMACRO_PROPERTYEDITORTYPE, factory);
00213 }
00214 }
00215
00216
00217
00218
00219
00225 class ListBoxItem : public QListBoxText
00226 {
00227 public:
00228 ListBoxItem(QListBox* listbox)
00229 : QListBoxText(listbox), m_enabled(true) {}
00230 ListBoxItem(QListBox* listbox, const QString& text, QListBoxItem* after)
00231 : QListBoxText(listbox, text, after), m_enabled(true) {}
00232 virtual ~ListBoxItem() {}
00233 void setEnabled(bool enabled) { m_enabled = enabled; }
00234 virtual int width(const QListBox* lb) const {
00235 Q_ASSERT( dynamic_cast<KComboBox*>( lb->parent() ) );
00236 return static_cast<KComboBox*>( lb->parent() )->lineEdit()->width() + 2;
00237 }
00238 virtual int height(const QListBox* lb) const {
00239 Q_ASSERT( dynamic_cast<KComboBox*>( lb->parent() ) );
00240 return m_enabled ? static_cast<KComboBox*>( lb->parent() )->height() + 2 : 0;
00241 }
00242 private:
00243 bool m_enabled;
00244 };
00245
00250 class EditListBoxItem : public ListBoxItem
00251 {
00252 public:
00253
00254 EditListBoxItem(QListBox* listbox, KexiMacroProperty* macroproperty)
00255 : ListBoxItem(listbox)
00256 , m_macroproperty(macroproperty)
00257 , m_prop(0)
00258 , m_widget(0)
00259 {
00260 init();
00261 }
00262
00263 virtual ~EditListBoxItem() {
00264 delete m_widget;
00265 delete m_prop;
00266 }
00267
00268 virtual QString text() const {
00269 KSharedPtr<KoMacro::Variable> variable = m_macroproperty->variable();
00270 Q_ASSERT( variable.data() );
00271
00272 Q_ASSERT( variable->toString() != QString::null );
00273 return variable->toString();
00274 }
00275
00276 KoProperty::Widget* widget() const { return m_widget; }
00277 KSharedPtr<KoMacro::MacroItem> macroItem() const { return m_macroproperty->macroItem(); }
00278 KSharedPtr<KoMacro::Variable> variable() const { return m_macroproperty->variable(); }
00279 KSharedPtr<KoMacro::Action> action() const { return m_macroproperty->macroItem()->action(); }
00280
00281 protected:
00282 virtual void paint(QPainter* p) {
00283 if(! m_widget) return;
00284 Q_ASSERT( dynamic_cast<KComboBox*>( listBox()->parent() ) );
00285 const int w = width(listBox());
00286 const int h = height(listBox());
00287 m_widget->setFixedSize(w - 2, h - 2);
00288 p->drawPixmap(0, 0, QPixmap::grabWidget(m_widget), 1, 1, w - 1, h - 1);
00289 }
00290
00291 private:
00292 void init() {
00293 KSharedPtr<KoMacro::MacroItem> macroitem = m_macroproperty->macroItem();
00294 Q_ASSERT( macroitem.data() );
00295 KSharedPtr<KoMacro::Action> action = m_macroproperty->macroItem()->action();
00296 if(! action.data()) {
00297 kdWarning() << "EditListBoxItem::EditListBoxItem() Skipped cause there exists no action for macroproperty=" << m_macroproperty->name() << endl;
00298 return;
00299 }
00300 KoProperty::Property* parentproperty = m_macroproperty->parentProperty();
00301 if(! parentproperty) {
00302 kdWarning() << "EditListBoxItem::EditListBoxItem() No parentproperty defined" << endl;
00303 return;
00304 }
00305 KSharedPtr<KoMacro::Variable> variable = m_macroproperty->variable();
00306 if(! variable.data()) {
00307 kdWarning() << "EditListBoxItem::EditListBoxItem() No variable defined for property=" << parentproperty->name() << endl;
00308 return;
00309 }
00310
00311 QVariant variant = variable->variant();
00312
00313 KSharedPtr<KoMacro::Variable> actionvariable = action->variable(m_macroproperty->name());
00314 if(actionvariable.data()) {
00315 QVariant actionvariant = actionvariable->variant();
00316 Q_ASSERT( ! actionvariant.isNull() );
00317 Q_ASSERT( variant.canCast(actionvariant.type()) );
00318 variant.cast( actionvariant.type() );
00319 }
00320
00321 int type = KoProperty::Auto;
00322 switch(variant.type()) {
00323 case QVariant::UInt:
00324 case QVariant::Int: {
00325 type = KoProperty::Integer;
00326 } break;
00327 case QVariant::CString:
00328 case QVariant::String: {
00329 type = KoProperty::String;
00330 } break;
00331 default: {
00332 kdWarning() << "EditListBoxItem::EditListBoxItem() name=" << variable->name() << " type=" << QVariant::typeToName(variant.type()) << endl;
00333 } break;
00334 }
00335
00336 QString name = variable->name();
00337 Q_ASSERT(! name.isNull());
00338
00339 m_prop = new KoProperty::Property(
00340 name.latin1(),
00341 variant,
00342 variable->text(),
00343 QString::null,
00344 type,
00345 0
00346 );
00347
00348 m_widget = KoProperty::FactoryManager::self()->createWidgetForProperty(m_prop);
00349 Q_ASSERT( m_widget != 0 );
00350
00351 m_widget->reparent(listBox(), 0, QPoint(1,1));
00352
00353 m_widget->setMinimumHeight(5);
00354 m_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00355 }
00356
00357 private:
00358 KexiMacroProperty* m_macroproperty;
00359 KoProperty::Property* m_prop;
00360 KoProperty::Widget* m_widget;
00361 };
00362
00367 class ListBox : public QListBox
00368 {
00369 public:
00370 ListBox(KComboBox* parent, KexiMacroProperty* macroproperty)
00371 : QListBox(parent)
00372 , m_macroproperty(macroproperty)
00373 , m_edititem(0)
00374 {
00375 viewport()->setBackgroundMode(PaletteBackground);
00376 setVariableHeight(true);
00377 update();
00378 }
00379
00380 virtual ~ListBox() {}
00381
00382 void update() {
00383 m_items.clear();
00384 delete m_edititem;
00385 m_edititem = 0;
00386 clear();
00387
00388 m_edititem = new EditListBoxItem(this, m_macroproperty);
00389 Q_ASSERT( m_edititem->widget() != 0 );
00390
00391 const QString name = m_macroproperty->name();
00392 KoMacro::Variable::List children;
00393 {
00394 KoMacro::Variable::List actionchildren;
00395
00396 KSharedPtr<KoMacro::Variable> itemvar = m_macroproperty->macroItem()->variable(name,false);
00397
00398 if(itemvar.data())
00399 actionchildren = itemvar->children();
00400
00401 KSharedPtr<KoMacro::Action> action = m_edititem->action();
00402 KSharedPtr<KoMacro::Variable> actionvar = action.data() ? action->variable(name) : KSharedPtr<KoMacro::Variable>();
00403
00404 if(actionvar.data())
00405 actionchildren += actionvar->children();
00406
00407 KoMacro::Variable::List::ConstIterator it(actionchildren.constBegin()), end(actionchildren.constEnd());
00408 for(; it != end; ++it) {
00409 if(name == (*it)->name()) {
00410 KoMacro::Variable::List list = (*it)->children();
00411 KoMacro::Variable::List::ConstIterator listit(list.constBegin()), listend(list.constEnd());
00412 for(; listit != listend; ++listit)
00413 children.append( *listit );
00414 }
00415 }
00416
00417 if(children.count() <= 0)
00418 children = actionchildren;
00419 }
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 if(children.count() > 0) {
00430 KoMacro::Variable::List::Iterator childit(children.begin()), childend(children.end());
00431 for(; childit != childend; ++childit) {
00432 const QString n = (*childit)->name();
00433
00434 const QVariant v = (*childit)->variant();
00435
00436
00437 switch( v.type() ) {
00438
00439
00440
00441
00442
00443 case QVariant::List: {
00444 const QValueList<QVariant> list = v.toList();
00445 for(QValueList<QVariant>::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it) {
00446 const QString s = (*it).toString().stripWhiteSpace();
00447 if(! s.isEmpty())
00448 m_items.append(s);
00449 }
00450 } break;
00451 case QVariant::StringList: {
00452 const QStringList list = v.toStringList();
00453 for(QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it)
00454 if(! (*it).isEmpty())
00455 m_items.append(*it);
00456 } break;
00457 default: {
00458 const QString s = v.toString().stripWhiteSpace();
00459 if(! s.isEmpty())
00460 m_items.append(s);
00461 } break;
00462 }
00463 }
00464 }
00465
00466 QListBoxItem* item = m_edititem;
00467 const uint count = m_items.count();
00468 for(uint i = 0; i < count; i++)
00469 item = new ListBoxItem(this, m_items[i], item);
00470 }
00471
00472 EditListBoxItem* editItem() const { return m_edititem; }
00473 QStringList items() const { return m_items; }
00474
00475 virtual void hide () {
00476 QListBox::hide();
00477 for(uint i = 0; i < count(); i++)
00478 static_cast<ListBoxItem*>( item(i) )->setEnabled(false);
00479 }
00480 virtual void show() {
00481 update();
00482 adjustSize();
00483 QListBox::show();
00484 }
00485
00486 private:
00487 KexiMacroProperty* m_macroproperty;
00488 EditListBoxItem* m_edititem;
00489 QStringList m_items;
00490 };
00491
00496 class KexiMacroPropertyWidget::Private
00497 {
00498 public:
00499 KexiMacroProperty* macroproperty;
00500 KComboBox* combobox;
00501 ListBox* listbox;
00502 };
00503
00504 KexiMacroPropertyWidget::KexiMacroPropertyWidget(KoProperty::Property* property, QWidget* parent)
00505 : KoProperty::Widget(property, parent)
00506 , d( new Private() )
00507 {
00508 kdDebug() << "KexiMacroPropertyWidget::KexiMacroPropertyWidget() Ctor" << endl;
00509
00510 QHBoxLayout* layout = new QHBoxLayout(this, 0, 0);
00511
00512 d->macroproperty = dynamic_cast<KexiMacroProperty*>( property->customProperty() );
00513 if(! d->macroproperty) {
00514 kdWarning() << "KexiMacroPropertyWidget::KexiMacroPropertyWidget() Missing macroproperty for property=" << property->name() << endl;
00515 return;
00516 }
00517
00518 d->combobox = new KComboBox(this);
00519 layout->addWidget(d->combobox);
00520 d->listbox = new ListBox(d->combobox, d->macroproperty);
00521 d->combobox->setEditable(true);
00522 d->combobox->setListBox(d->listbox);
00523 d->combobox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00524 d->combobox->setMinimumHeight(5);
00525 d->combobox->setInsertionPolicy(QComboBox::NoInsertion);
00526 d->combobox->setMinimumSize(10, 0);
00527 d->combobox->setAutoCompletion(false);
00528 d->combobox->setContextMenuEnabled(false);
00529
00530 QVariant value = d->macroproperty->value();
00531 int index = d->listbox->items().findIndex( value.toString() );
00532 if(index >= 0) {
00533 d->combobox->setCurrentItem(index + 1);
00534 d->listbox->setCurrentItem(index + 1);
00535 }
00536 else {
00537 Q_ASSERT( d->listbox->editItem()->widget() != 0 );
00538 d->listbox->editItem()->widget()->setValue( d->macroproperty->value(), true );
00539
00540 }
00541 kdDebug() << ">>> KexiMacroPropertyWidget::KexiMacroPropertyWidget() CurrentItem=" << d->combobox->currentItem() << endl;
00542
00543 d->combobox->setFocusProxy( d->listbox->editItem()->widget() );
00544 setFocusWidget( d->combobox->lineEdit() );
00545
00546 connect(d->combobox, SIGNAL(textChanged(const QString&)),
00547 this, SLOT(slotComboBoxChanged()));
00548 connect(d->combobox, SIGNAL(activated(int)),
00549 this, SLOT(slotComboBoxActivated()));
00550 connect(d->listbox->editItem()->widget(), SIGNAL(valueChanged(Widget*)),
00551 this, SLOT(slotWidgetValueChanged()));
00552 connect(d->macroproperty, SIGNAL(valueChanged()),
00553 this, SLOT(slotPropertyValueChanged()));
00554 }
00555
00556 KexiMacroPropertyWidget::~KexiMacroPropertyWidget()
00557 {
00558 kdDebug() << "KexiMacroPropertyWidget::~KexiMacroPropertyWidget() Dtor" << endl;
00559 delete d;
00560 }
00561
00562 QVariant KexiMacroPropertyWidget::value() const
00563 {
00564 kdDebug()<<"KexiMacroPropertyWidget::value() value="<<d->macroproperty->value()<<endl;
00565 return d->macroproperty->value();
00566
00567
00568
00569 }
00570
00571 void KexiMacroPropertyWidget::setValue(const QVariant& value, bool emitChange)
00572 {
00573 kdDebug()<<"KexiMacroPropertyWidget::setValue() value="<<value<<" emitChange="<<emitChange<<endl;
00574
00575 if(! emitChange)
00576 d->combobox->blockSignals(true);
00577
00578 const QString s = value.toString();
00579 d->combobox->setCurrentText( s.isNull() ? "" : s );
00580
00581 if(emitChange)
00582 emit valueChanged(this);
00583 else
00584 d->combobox->blockSignals(false);
00585 }
00586
00587 void KexiMacroPropertyWidget::setReadOnlyInternal(bool readOnly)
00588 {
00589 Q_UNUSED(readOnly);
00590
00591 }
00592
00593 void KexiMacroPropertyWidget::slotComboBoxChanged()
00594 {
00595 kdDebug()<<"KexiMacroPropertyWidget::slotComboBoxChanged()"<<endl;
00596 const QVariant v = d->combobox->currentText();
00597 d->macroproperty->setValue(v, true);
00598
00599 }
00600
00601 void KexiMacroPropertyWidget::slotComboBoxActivated()
00602 {
00603 Q_ASSERT( d->listbox->editItem()->widget() );
00604 const int index = d->combobox->currentItem();
00605 QString text = (index == 0)
00606 ? d->listbox->editItem()->widget()->value().toString()
00607 : d->combobox->text(index);
00608 kdDebug()<<"KexiMacroPropertyWidget::slotComboBoxActivated() index="<<index<<" text="<<text<<endl;
00609 d->combobox->setCurrentText(text);
00610 slotWidgetValueChanged();
00611 }
00612
00613 void KexiMacroPropertyWidget::slotWidgetValueChanged()
00614 {
00615 d->macroproperty->emitPropertyChanged();
00616 }
00617
00618 void KexiMacroPropertyWidget::slotPropertyValueChanged()
00619 {
00620 Q_ASSERT( d->listbox->editItem()->widget() );
00621 const QVariant v = d->macroproperty->value();
00622 kdDebug()<<"KexiMacroPropertyWidget::slotPropertyValueChanged() value="<<v<<endl;
00623 d->listbox->editItem()->widget()->setValue(v, true);
00624 }
00625
00626 #include "keximacroproperty.moc"