• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • KDevelop Property Editing Library
 

KDevelop Property Editing Library

  • lib
  • widgets
  • propeditor
propertyeditor.cpp
1 /***************************************************************************
2  * Copyright (C) 2002-2004 by Alexander Dymo *
3  * cloudtemple@mskat.net *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU Library General Public License as *
7  * published by the Free Software Foundation; either version 2 of the *
8  * License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU Library General Public *
16  * License along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19  ***************************************************************************/
20 #include "propertyeditor.h"
21 
22 #ifndef PURE_QT
23 #include <tdelocale.h>
24 #include <kdebug.h>
25 #include <kiconloader.h>
26 #else
27 #include "compat_tools.h"
28 #endif
29 
30 #include <tqtable.h>
31 #include <tqlayout.h>
32 #include <tqpainter.h>
33 #include <tqptrlist.h>
34 #include <tqvaluelist.h>
35 #include <tqpushbutton.h>
36 
37 #include "property.h"
38 #include "multiproperty.h"
39 #include "propertymachinefactory.h"
40 
41 namespace PropertyLib{
42 
43 class PropertyItem: public TDEListViewItem{
44 public:
45  PropertyItem(PropertyEditor *parent, MultiProperty *property)
46  :TDEListViewItem(parent, property->description()), m_editor(parent), m_property(property),
47  m_changed(false)
48  {
49  }
50 
51  PropertyItem(PropertyEditor *editor, TDEListViewItem *parent, MultiProperty *property)
52  :TDEListViewItem(parent, property->description()), m_editor(editor),
53  m_property(property), m_changed(false)
54  {
55  }
56 
57 /* int type() const
58  {
59  return m_property->type();
60  }
61 
62  TQString name() const
63  {
64  return m_property->name();
65  }
66  */
67  MultiProperty *property() const
68  {
69  return m_property;
70  }
71 
72  virtual void paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int align)
73  {
74  if ((column == 0) && m_changed)
75  {
76  TQFont font;
77  font.setBold(true);
78  p->setFont(font);
79  p->setBrush(cg.highlight());
80  p->setPen(cg.highlightedText());
81  }
82  if (column == 1)
83  {
84  TQRect r(0, 0, m_editor->header()->sectionSize(1), height());
85  //FIXME: this is ugly, but how else can we deal with ValueFromList properties?
86  TQVariant valueToDraw;
87  if (m_property->type() == Property::ValueFromList)
88  valueToDraw = m_property->findValueDescription();
89  else
90  valueToDraw = m_property->value();
91  TQColorGroup icg(cg);
92 #ifndef PURE_QT
93  icg.setColor(TQColorGroup::Background, backgroundColor(column));
94 #else
95  icg.setColor(TQColorGroup::Background, white);
96 #endif
97  m_editor->machine(m_property)->propertyEditor->drawViewer(p, icg, r, valueToDraw);
98  return;
99  }
100  TDEListViewItem::paintCell(p, cg, column, width, align);
101  }
102 
103  virtual void setup()
104  {
105  TDEListViewItem::setup();
106  setHeight(static_cast<int>(height()*1.5));
107  }
108 
109  void setChanged(bool changed)
110  {
111  m_changed = changed;
112  }
113 
114 private:
115  PropertyEditor *m_editor;
116  MultiProperty *m_property;
117  bool m_changed;
118 };
119 
120 
121 class PropertyGroupItem: public TDEListViewItem{
122 public:
123  PropertyGroupItem(TDEListView *parent, const TQString &name)
124  :TDEListViewItem(parent, name)
125  {
126  init();
127  }
128  PropertyGroupItem(TDEListViewItem *parent, const TQString &name)
129  :TDEListViewItem(parent, name)
130  {
131  init();
132  }
133 
134  virtual void paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int align)
135  {
136  if (column == 0)
137  {
138  TQFont font;
139  font.setBold(true);
140  p->setFont(font);
141  p->setBrush(cg.highlight());
142  p->setPen(cg.highlightedText());
143  }
144  TDEListViewItem::paintCell(p, cg, column, width, align);
145  }
146  virtual void setup()
147  {
148  TDEListViewItem::setup();
149  setHeight(static_cast<int>(height()*1.4));
150  }
151 
152 private:
153  void init()
154  {
155  setOpen(true);
156  }
157 };
158 
159 class SeparatorItem: public TDEListViewItem{
160 public:
161  SeparatorItem(TDEListView *parent)
162  :TDEListViewItem(parent)
163  {
164  setSelectable(false);
165  }
166 };
167 PropertyEditor::PropertyEditor(TQWidget *parent, const char *name)
168  :TDEListView(parent, name)
169 {
170  setSorting(-1);
171 
172  addColumn(i18n("Name"));
173  addColumn(i18n("Value"));
174  setAllColumnsShowFocus(true);
175  setColumnWidthMode(0, TQListView::Maximum);
176  setResizeMode(TQListView::LastColumn);
177 
178  header()->setClickEnabled(false);
179 
180  connect(header(), TQT_SIGNAL(sizeChange(int, int, int)),
181  this, TQT_SLOT(updateEditorSize()));
182  connect(this, TQT_SIGNAL(currentChanged(TQListViewItem*)),
183  this, TQT_SLOT(slotClicked(TQListViewItem*)));
184 
185  m_currentEditItem = 0;
186  m_doubleClickForEdit = true;
187  m_lastClickedItem = 0;
188  m_currentEditWidget = 0;
189  m_list = 0;
190 
191  m_currentEditArea = new TQWidget(viewport());
192  m_currentEditArea->hide();
193  m_undoButton = new TQPushButton(m_currentEditArea);
194 #ifndef PURE_QT
195  m_undoButton->setPixmap(SmallIcon("edit-undo"));
196 #else
197  m_undoButton->setPixmap( TQPixmap("undo.xpm") );
198 #endif
199  m_undoButton->setSizePolicy(TQSizePolicy::Maximum, TQSizePolicy::MinimumExpanding);
200  m_undoButton->resize(m_undoButton->height(), m_undoButton->height());
201  m_undoButton->hide();
202  connect(m_undoButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(undo()));
203  m_currentEditLayout = new TQGridLayout(m_currentEditArea, 1, 2, 0, 0);
204 // m_currentEditLayout->addWidget(m_undoButton, 0, 1);
205 }
206 
207 PropertyEditor::~PropertyEditor()
208 {
209  clearMachineCache();
210 }
211 
212 void PropertyEditor::populateProperties(PropertyList *list)
213 {
214  if (list == 0)
215  return;
216  m_list = list;
217  connect(m_list, TQT_SIGNAL(propertyValueChanged(Property*)), this, TQT_SLOT(propertyValueChanged(Property*)));
218  const TQValueList<TQPair<TQString, TQValueList<TQString> > >& groups = m_list->propertiesOfGroup();
219  for (TQValueList<TQPair<TQString, TQValueList<TQString> > >::const_iterator it = groups.begin();
220  it != groups.end(); ++it)
221  {
222 // tqWarning("PropertyEditor::populateProperties: adding group %s", (*it).first.ascii());
223  PropertyGroupItem *group = 0;
224  if ( (!(*it).first.isEmpty()) && ((*it).second.count() > 0) )
225  group = new PropertyGroupItem(this, (*it).first);
226  const TQValueList<TQString> &properties = (*it).second;
227  for (TQValueList<TQString>::const_iterator it2 = properties.begin(); it2 != properties.end(); ++it2)
228  {
229 // tqWarning("PropertyEditor::populateProperties: adding property %s", (*it2).ascii());
230  if (group)
231  addProperty(group, *it2);
232  else
233  addProperty(*it2);
234  }
235  }
236  if (firstChild())
237  {
238  setCurrentItem(firstChild());
239  setSelected(firstChild(), true);
240  slotClicked(firstChild());
241  }
242 }
243 
244 void PropertyEditor::addProperty(PropertyGroupItem *group, const TQString &name)
245 {
246  if ((*m_list)[name] == 0)
247  return;
248 // tqWarning("%s = name : object null ", name.ascii());
249  PropertyItem *pitem = new PropertyItem(this, group, (*m_list)[name]);
250  addChildProperties(pitem);
251 }
252 
253 void PropertyEditor::addProperty(const TQString &name)
254 {
255  if ((*m_list)[name] == 0)
256  return;
257 // tqWarning("%s = name : object null ", name.ascii());
258  PropertyItem *pitem = new PropertyItem(this, (*m_list)[name]);
259  addChildProperties(pitem);
260 }
261 
262 void PropertyEditor::addChildProperties(PropertyItem *parent)
263 {
264  MultiProperty *prop = parent->property();
265  //force machine creation to get detailed properties appended to current multiproperty
266  if ( !m_registeredForType.contains(prop->name())
267  && (PropertyMachineFactory::getInstance()->hasDetailedEditors(prop->type())) )
268  {
269  //FIXME: find better solution
270  machine(prop);
271  }
272 
273 // tqWarning("seeking children: count: %d", prop->details.count());
274 
275  parent->setOpen(true);
276  for (TQValueList<ChildProperty>::iterator it = prop->details.begin(); it != prop->details.end(); ++it)
277  {
278 // tqWarning("found child %s", (*it).name().ascii());
279  new PropertyItem(this, parent, new MultiProperty(&m_detailedList, &(*it)));
280  }
281 }
282 
283 void PropertyEditor::clearProperties()
284 {
285  m_detailedList.clear();
286  if (!m_list)
287  return;
288 
289  hideEditor();
290 
291  disconnect(m_list, TQT_SIGNAL(propertyValueChanged(Property*)), this, TQT_SLOT(propertyValueChanged(Property*)));
292  clear();
293  delete m_list;
294  m_list = 0;
295 }
296 
297 void PropertyEditor::propertyValueChanged(Property *property)
298 {
299 // tqWarning("PropertyEditor::propertyValueChanged");
300  if (m_currentEditWidget->propertyName() == property->name())
301  m_currentEditWidget->setValue(property->value(), false);
302  else
303  {
304 // repaint all items
305  TQListViewItemIterator it(this);
306  while (it.current())
307  {
308  repaintItem(it.current());
309  ++it;
310  }
311  }
312 }
313 
314 void PropertyEditor::propertyChanged(MultiProperty *property, const TQVariant &value)
315 {
316  if (!property)
317  return;
318 
319  tqWarning("editor: assign %s to %s", property->name().latin1(), value.toString().latin1());
320  property->setValue(value, false);
321 
322  //highlight changed properties
323  if (m_currentEditItem && (m_currentEditItem->property() == property))
324  {
325  m_currentEditItem->setChanged(true);
326  repaintItem(m_currentEditItem);
327  }
328 
329  emit changed();
330 
331 /* if (m_list->contains(name))
332  {
333  (*m_list)[name]->setValue(value, false);
334 // else if (m_detailedList->contains(*/
335 }
336 
337 void PropertyEditor::hideEditor()
338 {
339  m_lastClickedItem = 0;
340  m_currentEditItem = 0;
341  if (m_currentEditWidget)
342  {
343  m_currentEditLayout->remove(m_currentEditWidget);
344  m_currentEditWidget->hide();
345  }
346  m_currentEditLayout->remove(m_undoButton);
347  m_undoButton->hide();
348  m_currentEditArea->hide();
349  m_currentEditWidget = 0;
350 }
351 
352 void PropertyEditor::showEditor(PropertyItem *item)
353 {
354  m_currentEditItem = item;
355  placeEditor(item);
356  m_currentEditWidget->show();
357  m_undoButton->show();
358  m_currentEditArea->show();
359 }
360 
361 void PropertyEditor::placeEditor(PropertyItem *item)
362 {
363  TQRect r = itemRect(item);
364  if (!r.size().isValid())
365  {
366  ensureItemVisible(item);
367  r = itemRect(item);
368  }
369 
370  r.setX(header()->sectionPos(1));
371  r.setWidth(header()->sectionSize(1));
372 
373  // check if the column is fully visible
374  if (visibleWidth() < r.right())
375  r.setRight(visibleWidth());
376 
377  r = TQRect(viewportToContents(r.topLeft()), r.size());
378 
379  if (item->pixmap(1))
380  {
381  r.setX(r.x() + item->pixmap(1)->width());
382  }
383 
384  if (PropertyWidget* editor = prepareEditor(item))
385  {
386  m_currentEditLayout->addWidget(editor, 0, 0);
387  m_currentEditLayout->addWidget(m_undoButton, 0, 1);
388  m_currentEditArea->resize(r.size());
389 // m_currentEditLayout->invalidate();
390  moveChild(m_currentEditArea, r.x(), r.y());
391  m_currentEditWidget = editor;
392  }
393 }
394 
395 PropertyWidget* PropertyEditor::prepareEditor(PropertyItem *item)
396 {
397  PropertyWidget *editorWidget = 0;
398 /* if (item->depth() >= 2)
399  {
400  editorWidget = machine(item->name())->propertyEditor;
401  editorWidget->setValue(m_accessor->value(item->name()), false);
402  }
403  else
404  {*/
405  editorWidget = machine(item->property())->propertyEditor;
406  editorWidget->setProperty(item->property());
407  if (item->property()->type() == Property::ValueFromList)
408  editorWidget->setValueList(item->property()->valueList());
409  editorWidget->setValue(item->property()->value(), false);
410  //}
411  return editorWidget;
412 }
413 
414 void PropertyEditor::updateEditorSize()
415 {
416  if (m_currentEditItem)
417  placeEditor(m_currentEditItem);
418 }
419 
420 void PropertyEditor::slotClicked(TQListViewItem *item)
421 {
422  if (item == 0)
423  {
424  hideEditor();
425  return;
426  }
427  if (item != m_lastClickedItem)
428  {
429  hideEditor();
430  PropertyItem *it = dynamic_cast<PropertyItem*>(item);
431  if (it)
432  {
433  showEditor(it);
434  }
435  }
436 
437  m_lastClickedItem = item;
438 }
439 
440 Machine *PropertyEditor::machine(MultiProperty *property)
441 {
442 // int type = property->type();
443  TQString name = property->name();
444  TQMap<TQString, TQVariant> values = property->valueList();
445  if (m_registeredForType[name] == 0)
446  {
447  m_registeredForType[name] = PropertyMachineFactory::getInstance()->machineForProperty(property);
448  connect(m_registeredForType[name]->propertyEditor, TQT_SIGNAL(propertyChanged(MultiProperty*, const TQVariant&)),
449  this, TQT_SLOT(propertyChanged(MultiProperty*, const TQVariant&)));
450  m_registeredForType[name]->propertyEditor->reparent(m_currentEditArea, 0, m_currentEditArea->childrenRect().topLeft());
451  m_registeredForType[name]->propertyEditor->hide();
452  }
453  return m_registeredForType[name];
454 }
455 
456 void PropertyEditor::clearMachineCache()
457 {
458  for (TQMap<TQString, Machine* >::iterator it = m_registeredForType.begin(); it != m_registeredForType.end(); ++it)
459  {
460  delete it.data();
461  }
462  m_registeredForType.clear();
463 }
464 
465 void PropertyEditor::undo()
466 {
467  if ((m_currentEditItem == 0) || (m_currentEditWidget == 0)
468  || (!m_currentEditWidget->isVisible()))
469  return;
470 
471  m_currentEditWidget->undo();
472  m_currentEditItem->setChanged(false);
473  repaintItem(m_currentEditItem);
474 }
475 
476 }
477 
478 #ifndef PURE_QT
479 #include "propertyeditor.moc"
480 #endif
PropertyLib::PropertyEditor::clearProperties
void clearProperties()
Clears property list, disconnects accessor from the editor and deletes it.
Definition: propertyeditor.cpp:283
PropertyLib::PropertyWidget::undo
virtual void undo()
Reverts the property value to previous setting.
Definition: propertywidget.cpp:55
PropertyLib::PropertyEditor::clearMachineCache
void clearMachineCache()
Deletes cached machines.
Definition: propertyeditor.cpp:456
PropertyLib::PropertyWidget::propertyName
virtual TQString propertyName() const
Definition: propertywidget.cpp:31
PropertyLib::PropertyList::propertiesOfGroup
virtual const TQValueList< TQPair< TQString, TQValueList< TQString > > > & propertiesOfGroup() const
Definition: propertylist.cpp:149
PropertyLib
Namespace which contain property editing classes.
Definition: childproperty.cpp:29
propertymachinefactory.h
Contains PropertyLib::PropertyMachineFactory class and PropertyLib::Machine structure.
PropertyLib::PropertyEditor::propertyValueChanged
void propertyValueChanged(Property *property)
Updates property widget in the editor.
Definition: propertyeditor.cpp:297
PropertyLib::MultiProperty::type
int type() const
Returns the type of a property.
Definition: multiproperty.cpp:53
PropertyLib::PropertyWidget::setValue
virtual void setValue(const TQVariant &value, bool emitChange=true)=0
Sets the value shown in the editor widget.
multiproperty.h
Contains PropertyLib::MultiProperty class.
property.h
Contains PropertyLib::Property class and PropertyLib::Property::PropertyType enum.
PropertyLib::MultiProperty::details
TQValueList< ChildProperty > details
The list of child properties.
Definition: multiproperty.h:113
PropertyLib::PropertyMachineFactory::getInstance
static PropertyMachineFactory * getInstance()
Definition: propertymachinefactory.cpp:192
PropertyLib::PropertyEditor::slotClicked
void slotClicked(TQListViewItem *item)
Shows property editor.
Definition: propertyeditor.cpp:420
PropertyLib::PropertyEditor::undo
void undo()
Undoes the last change in property editor.
Definition: propertyeditor.cpp:465
PropertyLib::MultiProperty::name
TQString name() const
Returns the name of a property.
Definition: multiproperty.cpp:46
PropertyLib::PropertyWidget
An abstract base class of property viewer and editor vidget.
Definition: propertywidget.h:49
PropertyLib::Property::value
virtual TQVariant value() const
Definition: property.cpp:77
PropertyLib::PropertyEditor::populateProperties
void populateProperties(PropertyList *list)
Shows properties from a list.
Definition: propertyeditor.cpp:212
propertyeditor.h
Contains PropertyLib::PropertyEditor class.
PropertyLib::Property::ValueFromList
string value from a list
Definition: property.h:107
PropertyLib::PropertyList
The list of properties.
Definition: propertylist.h:55
PropertyLib::PropertyEditor::propertyChanged
void propertyChanged(MultiProperty *property, const TQVariant &value)
Updates property in the list when new value is selected in the editor.
Definition: propertyeditor.cpp:314
PropertyLib::PropertyList::clear
virtual void clear()
Clears the list of properties.
Definition: propertylist.cpp:214
PropertyLib::PropertyEditor::PropertyEditor
PropertyEditor(TQWidget *parent=0, const char *name=0)
Constructs the property editor.
Definition: propertyeditor.cpp:167
PropertyLib::PropertyWidget::setValueList
virtual void setValueList(const TQMap< TQString, TQVariant > &valueList)
Sets the list of possible values shown in the editor widget.
Definition: propertywidget.cpp:49
PropertyLib::Property
Property.
Definition: property.h:62
PropertyLib::PropertyWidget::setProperty
virtual void setProperty(MultiProperty *property)
Sets the name of edited property.
Definition: propertywidget.cpp:36
PropertyLib::MultiProperty
Holds a list of properties with the same name and type.
Definition: multiproperty.h:49
PropertyLib::PropertyMachineFactory::machineForProperty
Machine * machineForProperty(MultiProperty *property)
Creates and returns the editor for given property type.
Definition: propertymachinefactory.cpp:73
PropertyLib::Machine
Machine for a property type.
Definition: propertymachinefactory.h:46
PropertyLib::PropertyEditor::machine
Machine * machine(MultiProperty *property)
Definition: propertyeditor.cpp:440
PropertyLib::PropertyEditor::changed
void changed()
Emitted when something is changed in property editor.

KDevelop Property Editing Library

Skip menu "KDevelop Property Editing Library"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

KDevelop Property Editing Library

Skip menu "KDevelop Property Editing Library"
  • buildtools
  •   lib
  •     base
  •     parsers
  •       autotools
  •       qmake
  •     widgets
  •   api
  • languages
  •   lib
  •     debugger
  •     designer_integration
  •     interfaces
  • lib
  •   catalog
  •   interfaces
  •     extensions
  •     external
  •     extras
  •   util
  •   widgets
  •     propeditor
  • parts
  •   documentation
  •     interfaces
  • src
  •   profileengine
  •     lib
Generated for KDevelop Property Editing Library by doxygen 1.8.13
This website is maintained by Timothy Pearson.