• 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
41namespace PropertyLib{
42
43class PropertyItem: public TDEListViewItem{
44public:
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
114private:
115 PropertyEditor *m_editor;
116 MultiProperty *m_property;
117 bool m_changed;
118};
119
120
121class PropertyGroupItem: public TDEListViewItem{
122public:
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
152private:
153 void init()
154 {
155 setOpen(true);
156 }
157};
158
159class SeparatorItem: public TDEListViewItem{
160public:
161 SeparatorItem(TDEListView *parent)
162 :TDEListViewItem(parent)
163 {
164 setSelectable(false);
165 }
166};
167PropertyEditor::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(), TQ_SIGNAL(sizeChange(int, int, int)),
181 this, TQ_SLOT(updateEditorSize()));
182 connect(this, TQ_SIGNAL(currentChanged(TQListViewItem*)),
183 this, TQ_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, TQ_SIGNAL(clicked()), this, TQ_SLOT(undo()));
203 m_currentEditLayout = new TQGridLayout(m_currentEditArea, 1, 2, 0, 0);
204// m_currentEditLayout->addWidget(m_undoButton, 0, 1);
205}
206
207PropertyEditor::~PropertyEditor()
208{
209 clearMachineCache();
210}
211
212void PropertyEditor::populateProperties(PropertyList *list)
213{
214 if (list == 0)
215 return;
216 m_list = list;
217 connect(m_list, TQ_SIGNAL(propertyValueChanged(Property*)), this, TQ_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
244void 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
253void 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
262void 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
283void PropertyEditor::clearProperties()
284{
285 m_detailedList.clear();
286 if (!m_list)
287 return;
288
289 hideEditor();
290
291 disconnect(m_list, TQ_SIGNAL(propertyValueChanged(Property*)), this, TQ_SLOT(propertyValueChanged(Property*)));
292 clear();
293 delete m_list;
294 m_list = 0;
295}
296
297void 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
314void 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
337void 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
352void 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
361void 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
395PropertyWidget* 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
414void PropertyEditor::updateEditorSize()
415{
416 if (m_currentEditItem)
417 placeEditor(m_currentEditItem);
418}
419
420void 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
440Machine *PropertyEditor::machine(MultiProperty *property)
441{
442// int type = property->type();
443 TQString name = property->name();
444 TQStringVariantMap values = property->valueList();
445 if (m_registeredForType[name] == 0)
446 {
447 m_registeredForType[name] = PropertyMachineFactory::getInstance()->machineForProperty(property);
448 connect(m_registeredForType[name]->propertyEditor, TQ_SIGNAL(propertyChanged(MultiProperty*, const TQVariant&)),
449 this, TQ_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
456void 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
465void 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::MultiProperty
Holds a list of properties with the same name and type.
Definition multiproperty.h:50
PropertyLib::MultiProperty::name
TQString name() const
Returns the name of a property.
Definition multiproperty.cpp:46
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::PropertyEditor::clearMachineCache
void clearMachineCache()
Deletes cached machines.
Definition propertyeditor.cpp:456
PropertyLib::PropertyEditor::populateProperties
void populateProperties(PropertyList *list)
Shows properties from a list.
Definition propertyeditor.cpp:212
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::PropertyEditor::propertyValueChanged
void propertyValueChanged(Property *property)
Updates property widget in the editor.
Definition propertyeditor.cpp:297
PropertyLib::PropertyEditor::PropertyEditor
PropertyEditor(TQWidget *parent=0, const char *name=0)
Constructs the property editor.
Definition propertyeditor.cpp:167
PropertyLib::PropertyEditor::clearProperties
void clearProperties()
Clears property list, disconnects accessor from the editor and deletes it.
Definition propertyeditor.cpp:283
PropertyLib::PropertyEditor::changed
void changed()
Emitted when something is changed in property editor.
PropertyLib::PropertyEditor::machine
Machine * machine(MultiProperty *property)
Definition propertyeditor.cpp:440
PropertyLib::PropertyList
The list of properties.
Definition propertylist.h:56
PropertyLib::PropertyMachineFactory::machineForProperty
Machine * machineForProperty(MultiProperty *property)
Creates and returns the editor for given property type.
Definition propertymachinefactory.cpp:73
PropertyLib::PropertyMachineFactory::getInstance
static PropertyMachineFactory * getInstance()
Definition propertymachinefactory.cpp:192
PropertyLib::PropertyWidget
An abstract base class of property viewer and editor vidget.
Definition propertywidget.h:49
PropertyLib::PropertyWidget::setProperty
virtual void setProperty(MultiProperty *property)
Sets the name of edited property.
Definition propertywidget.cpp:36
PropertyLib::Property
Property.
Definition property.h:62
PropertyLib::Property::name
virtual TQString name() const
Definition property.cpp:57
PropertyLib::Property::value
virtual TQVariant value() const
Definition property.cpp:77
PropertyLib::Property::ValueFromList
@ ValueFromList
string value from a list
Definition property.h:107
multiproperty.h
Contains PropertyLib::MultiProperty class.
PropertyLib
Namespace which contain property editing classes.
Definition childproperty.cpp:29
property.h
Contains PropertyLib::Property class and PropertyLib::Property::PropertyType enum.
propertyeditor.h
Contains PropertyLib::PropertyEditor class.
propertymachinefactory.h
Contains PropertyLib::PropertyMachineFactory class and PropertyLib::Machine structure.
PropertyLib::Machine
Machine for a property type.
Definition propertymachinefactory.h:46
PropertyLib::Machine::propertyEditor
PropertyWidget * propertyEditor
Property viewer and editor widget.
Definition propertymachinefactory.h:60

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.15.0
This website is maintained by Timothy Pearson.