commands.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
3 Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19*/
20#include <tqdom.h>
21#include <tqwidget.h>
22#include <tqlayout.h>
23#include <tqlabel.h>
24#include <tqsplitter.h>
25#include <tqmetaobject.h>
26
27#include <kdebug.h>
28#include <tdelocale.h>
29#include <tdepopupmenu.h>
30#include <tdemessagebox.h>
31#include <tdeaccelmanager.h>
32
33#include "formIO.h"
34#include "container.h"
35#include "objecttree.h"
36#include "formmanager.h"
37#include "form.h"
38#include "widgetlibrary.h"
39#include "events.h"
40#include "utils.h"
41#include "widgetpropertyset.h"
42#include "widgetwithsubpropertiesinterface.h"
43#include <koproperty/property.h>
44
45#include "commands.h"
46
47using namespace KFormDesigner;
48
49// Command
50
51Command::Command()
52 : KCommand()
53{
54}
55
56Command::~Command()
57{
58}
59
60// PropertyCommand
61
62PropertyCommand::PropertyCommand(WidgetPropertySet *set, const TQCString &wname,
63 const TQVariant &oldValue, const TQVariant &value, const TQCString &property)
64 : Command(), m_propSet(set), m_value(value), m_property(property)
65{
66 m_oldvalues.insert(wname, oldValue);
67}
68
69PropertyCommand::PropertyCommand(WidgetPropertySet *set, const TQMap<TQCString, TQVariant> &oldvalues,
70 const TQVariant &value, const TQCString &property)
71 : Command(), m_propSet(set), m_value(value), m_oldvalues(oldvalues), m_property(property)
72{
73}
74
75/*
76MultiCommand::MultiCommand()
77{
78}
79
80MultiCommandGroup::addSubCommand(PropertyCommand* subCommand)
81 : Command(), m_propSet(set), m_value(value), m_oldvalues(oldvalues), m_property(property)
82{
83}
84*/
85
86void
87PropertyCommand::setValue(const TQVariant &value)
88{
89 m_value = value;
91}
92
93void
94PropertyCommand::execute()
95{
97 m_propSet->setUndoing(true);
98
99 TQMap<TQCString, TQVariant>::ConstIterator endIt = m_oldvalues.constEnd();
100 for(TQMap<TQCString, TQVariant>::ConstIterator it = m_oldvalues.constBegin(); it != endIt; ++it)
101 {
103 if (item) {//we're checking for item!=0 because the name could be of a form widget
104 FormManager::self()->activeForm()->setSelectedWidget(item->widget(), true);
105 }
106 }
107
108 (*m_propSet)[m_property] = m_value;
109 m_propSet->setUndoing(false);
110}
111
112void
113PropertyCommand::unexecute()
114{
116 m_propSet->setUndoing(true);
117
118 TQMap<TQCString, TQVariant>::ConstIterator endIt = m_oldvalues.constEnd();
119 for(TQMap<TQCString, TQVariant>::ConstIterator it = m_oldvalues.constBegin(); it != endIt; ++it)
120 {
122 if (!item)
123 continue; //better this than a crash
124 TQWidget *widg = item->widget();
126 //m_propSet->setSelectedWidget(widg, true);
127
129 TQWidget *subWidget = (subpropIface && subpropIface->subwidget()) ? subpropIface->subwidget() : widg;
130 if (-1!=subWidget->metaObject()->findProperty( m_property, true ))
131 subWidget->setProperty(m_property, it.data());
132 }
133
134 (*m_propSet)[m_property] = m_oldvalues.begin().data();
135 m_propSet->setUndoing(false);
136}
137
138TQString
139PropertyCommand::name() const
140{
141 if(m_oldvalues.count() >= 2)
142 return i18n("Change \"%1\" property for multiple widgets" ).arg(TQString(m_property));
143 else
144 return i18n("Change \"%1\" property for widget \"%2\"" ).arg(TQString(m_property)).arg(TQString(m_oldvalues.begin().key()));
145}
146
147void
148PropertyCommand::debug()
149{
150 kdDebug() << "PropertyCommand: name=\"" << name() << "\" widgets=" << m_oldvalues.keys()
151 << " value=" << m_value << " oldValues=" << m_oldvalues.values() << endl;
152}
153
154// GeometryPropertyCommand (for multiples widgets)
155
156GeometryPropertyCommand::GeometryPropertyCommand(WidgetPropertySet *set,
157 const TQStringList &names, const TQPoint& oldPos)
158 : Command(), m_propSet(set), m_names(names), m_oldPos(oldPos)
159{
160}
161
162void
163GeometryPropertyCommand::execute()
164{
165 m_propSet->setUndoing(true);
166 int dx = m_pos.x() - m_oldPos.x();
167 int dy = m_pos.y() - m_oldPos.y();
168
169 TQStringList::ConstIterator endIt = m_names.constEnd();
170 // We move every widget in our list by (dx, dy)
171 for(TQStringList::ConstIterator it = m_names.constBegin(); it != endIt; ++it)
172 {
174 if (!item)
175 continue; //better this than a crash
176 TQWidget *w = item->widget();
177 w->move(w->x() + dx, w->y() + dy);
178 }
179 m_propSet->setUndoing(false);
180}
181
182void
183GeometryPropertyCommand::unexecute()
184{
185 m_propSet->setUndoing(true);
186 int dx = m_pos.x() - m_oldPos.x();
187 int dy = m_pos.y() - m_oldPos.y();
188
189 TQStringList::ConstIterator endIt = m_names.constEnd();
190 // We move every widget in our list by (-dx, -dy) to undo the move
191 for(TQStringList::ConstIterator it = m_names.constBegin(); it != endIt; ++it)
192 {
194 if (!item)
195 continue; //better this than a crash
196 TQWidget *w = item->widget();
197 w->move(w->x() - dx, w->y() - dy);
198 }
199 m_propSet->setUndoing(false);
200}
201
202void
203GeometryPropertyCommand::setPos(const TQPoint& pos)
204{
205 m_pos = pos;
206 emit FormManager::self()->dirty(FormManager::self()->activeForm());
207}
208
209TQString
210GeometryPropertyCommand::name() const
211{
212 return i18n("Move multiple widgets");
213}
214
215void
216GeometryPropertyCommand::debug()
217{
218 kdDebug() << "GeometryPropertyCommand: pos=" << m_pos << " oldPos=" << m_oldPos
219 << " widgets=" << m_names << endl;
220}
221
223
224AlignWidgetsCommand::AlignWidgetsCommand(int type, WidgetList &list, Form *form)
225: Command(), m_form(form), m_type(type)
226{
227 for(TQWidget *w = list.first(); w; w = list.next())
228 m_pos.insert(w->name(), w->pos());
229}
230
231void
232AlignWidgetsCommand::execute()
233{
234 // To avoid creation of GeometryPropertyCommand
235 m_form->selectFormWidget();
236
237 int gridX = m_form->gridSize();
238 int gridY = m_form->gridSize();
239 TQWidget *parentWidget = m_form->selectedWidgets()->first()->parentWidget();
240 int tmpx, tmpy;
241
242 WidgetList list;
243 TQMap<TQCString, TQPoint>::ConstIterator endIt = m_pos.constEnd();
244 for(TQMap<TQCString, TQPoint>::ConstIterator it = m_pos.constBegin(); it != endIt; ++it)
245 {
246 ObjectTreeItem *item = m_form->objectTree()->lookup(it.key());
247 if(item && item->widget())
248 list.append(item->widget());
249 }
250
251 switch(m_type)
252 {
253 case AlignToGrid:
254 {
255 for(TQWidget *w = list.first(); w; w = list.next())
256 {
257 tmpx = int( (float)w->x() / ((float)gridX) + 0.5 ) * gridX;
258 tmpy = int( (float)w->y() / ((float)gridY) + 0.5 ) * gridY;
259
260 if((tmpx != w->x()) || (tmpy != w->y()))
261 w->move(tmpx, tmpy);
262 }
263 break;
264 }
265
266 case AlignToLeft:
267 {
268 tmpx = parentWidget->width();
269 for(TQWidget *w = list.first(); w; w = list.next())
270 {
271 if(w->x() < tmpx)
272 tmpx = w->x();
273 }
274
275 for(TQWidget *w = list.first(); w; w = list.next())
276 w->move(tmpx, w->y());
277 break;
278 }
279
280 case AlignToRight:
281 {
282 tmpx = 0;
283 for(TQWidget *w = list.first(); w; w = list.next())
284 {
285 if(w->x() + w->width() > tmpx)
286 tmpx = w->x() + w->width();
287 }
288
289 for(TQWidget *w = list.first(); w; w = list.next())
290 w->move(tmpx - w->width(), w->y());
291 break;
292 }
293
294 case AlignToTop:
295 {
296 tmpy = parentWidget->height();
297 for(TQWidget *w = list.first(); w; w = list.next())
298 {
299 if(w->y() < tmpy)
300 tmpy = w->y();
301 }
302
303 for(TQWidget *w = list.first(); w; w = list.next())
304 w->move(w->x(), tmpy);
305 break;
306 }
307
308 case AlignToBottom:
309 {
310 tmpy = 0;
311 for(TQWidget *w = list.first(); w; w = list.next())
312 {
313 if(w->y() + w->height() > tmpy)
314 tmpy = w->y() + w->height();
315 }
316
317 for(TQWidget *w = list.first(); w; w = list.next())
318 w->move(w->x(), tmpy - w->height());
319 break;
320 }
321
322 default:
323 return;
324 }
325
326 // We restore selection
327 for(TQWidget *w = list.first(); w; w = list.next())
328 m_form->setSelectedWidget(w, true);
329}
330
331void
332AlignWidgetsCommand::unexecute()
333{
334 // To avoid creation of GeometryPropertyCommand
335 m_form->selectFormWidget();
336 // We move widgets to their original pos
337 TQMap<TQCString, TQPoint>::ConstIterator endIt = m_pos.constEnd();
338 for(TQMap<TQCString, TQPoint>::ConstIterator it = m_pos.constBegin(); it != endIt; ++it)
339 {
340 ObjectTreeItem *item = m_form->objectTree()->lookup(it.key());
341 if(item && item->widget())
342 item->widget()->move( m_pos[item->widget()->name()] );
343 m_form->setSelectedWidget(item->widget(), true); // We restore selection
344 }
345}
346
347TQString
348AlignWidgetsCommand::name() const
349{
350 switch(m_type)
351 {
352 case AlignToGrid:
353 return i18n("Align Widgets to Grid");
354 case AlignToLeft:
355 return i18n("Align Widgets to Left");
356 case AlignToRight:
357 return i18n("Align Widgets to Right");
358 case AlignToTop:
359 return i18n("Align Widgets to Top");
360 case AlignToBottom:
361 return i18n("Align Widgets to Bottom");
362 default:
363 return TQString();
364 }
365}
366
367void
368AlignWidgetsCommand::debug()
369{
370 kdDebug() << "AlignWidgetsCommand: name=\"" << name() << "\" form=" << m_form->widget()->name()
371 << " widgets=" << m_pos.keys() << endl;
372}
373
375
376AdjustSizeCommand::AdjustSizeCommand(int type, WidgetList &list, Form *form)
377: Command(), m_form(form), m_type(type)
378{
379 for(TQWidget *w = list.first(); w; w = list.next())
380 {
381 if(w->parentWidget() && w->parentWidget()->isA("TQWidgetStack"))
382 {
383 w = w->parentWidget(); // widget is WidgetStack page
384 if(w->parentWidget() && w->parentWidget()->inherits("TQTabWidget")) // widget is tabwidget page
385 w = w->parentWidget();
386 }
387
388 m_sizes.insert(w->name(), w->size());
389 if(m_type == SizeToGrid) // SizeToGrid also move widgets
390 m_pos.insert(w->name(), w->pos());
391 }
392}
393
394void
395AdjustSizeCommand::execute()
396{
397 // To avoid creation of GeometryPropertyCommand
398 m_form->selectFormWidget();
399
400 int gridX = m_form->gridSize();
401 int gridY = m_form->gridSize();
402 int tmpw=0, tmph=0;
403
404 WidgetList list;
405 TQMap<TQCString, TQSize>::ConstIterator endIt = m_sizes.constEnd();
406 for(TQMap<TQCString, TQSize>::ConstIterator it = m_sizes.constBegin(); it != endIt; ++it)
407 {
408 ObjectTreeItem *item = m_form->objectTree()->lookup(it.key());
409 if(item && item->widget())
410 list.append(item->widget());
411 }
412
413 switch(m_type)
414 {
415 case SizeToGrid:
416 {
417 int tmpx=0, tmpy=0;
418 // same as in 'Align to Grid' + for the size
419 for(TQWidget *w = list.first(); w; w = list.next())
420 {
421 tmpx = int( (float)w->x() / ((float)gridX) + 0.5 ) * gridX;
422 tmpy = int( (float)w->y() / ((float)gridY) + 0.5 ) * gridY;
423 tmpw = int( (float)w->width() / ((float)gridX) + 0.5 ) * gridX;
424 tmph = int( (float)w->height() / ((float)gridY) + 0.5 ) * gridY;
425
426 if((tmpx != w->x()) || (tmpy != w->y()))
427 w->move(tmpx, tmpy);
428 if((tmpw != w->width()) || (tmph != w->height()))
429 w->resize(tmpw, tmph);
430 }
431 break;
432 }
433
434 case SizeToFit:
435 {
436 for(TQWidget *w = list.first(); w; w = list.next()) {
437 ObjectTreeItem *item = m_form->objectTree()->lookup(w->name());
438 if(item && !item->children()->isEmpty()) { // container
439 TQSize s;
440 if(item->container() && item->container()->layout())
441 s = w->sizeHint();
442 else
443 s = getSizeFromChildren(item);
444 // minimum size for containers
445 if(s.width() < 30)
446 s.setWidth(30);
447 if(s.height() < 30)
448 s.setHeight(30);
449 // small hack for flow layouts
450 int type = item->container() ? item->container()->layoutType() : Container::NoLayout;
451 if(type == Container::HFlow)
452 s.setWidth(s.width() + 5);
453 else if(type == Container::VFlow)
454 s.setHeight(s.height() + 5);
455 w->resize(s);
456 }
457 else if(item && item->container()) // empty container
458 w->resize(item->container()->form()->gridSize() * 5, item->container()->form()->gridSize() * 5); // basic size
459 else {
460 TQSize sizeHint(w->sizeHint());
461 if (sizeHint.isValid())
462 w->resize(sizeHint);
463 }
464 }
465 break;
466 }
467
468 case SizeToSmallWidth:
469 {
470 for(TQWidget *w = list.first(); w; w = list.next())
471 {
472 if((tmpw == 0) || (w->width() < tmpw))
473 tmpw = w->width();
474 }
475
476 for(TQWidget *w = list.first(); w; w = list.next())
477 {
478 if(tmpw != w->width())
479 w->resize(tmpw, w->height());
480 }
481 break;
482 }
483
484 case SizeToBigWidth:
485 {
486 for(TQWidget *w = list.first(); w; w = list.next())
487 {
488 if(w->width() > tmpw)
489 tmpw = w->width();
490 }
491
492 for(TQWidget *w = list.first(); w; w = list.next())
493 {
494 if(tmpw != w->width())
495 w->resize(tmpw, w->height());
496 }
497 break;
498 }
499
500 case SizeToSmallHeight:
501 {
502 for(TQWidget *w = list.first(); w; w = list.next())
503 {
504 if((tmph == 0) || (w->height() < tmph))
505 tmph = w->height();
506 }
507
508 for(TQWidget *w = list.first(); w; w = list.next())
509 {
510 if(tmph != w->height())
511 w->resize(w->width(), tmph);
512 }
513 break;
514 }
515
516 case SizeToBigHeight:
517 {
518 for(TQWidget *w = list.first(); w; w = list.next())
519 {
520 if(w->height() > tmph)
521 tmph = w->height();
522 }
523
524 for(TQWidget *w = list.first(); w; w = list.next())
525 {
526 if(tmph != w->height())
527 w->resize(w->width(), tmph);
528 }
529 break;
530 }
531
532 default:
533 break;
534 }
535
536 // We restore selection
537 for(TQWidget *w = list.first(); w; w = list.next())
538 m_form->setSelectedWidget(w, true);
539}
540
541TQSize
542AdjustSizeCommand::getSizeFromChildren(ObjectTreeItem *item)
543{
544 if(!item->container()) // multi pages containers (eg tabwidget)
545 {
546 TQSize s;
547 // get size for each container, and keep the biggest one
548 for(ObjectTreeItem *tree = item->children()->first(); tree; tree = item->children()->next())
549 s = s.expandedTo(getSizeFromChildren(tree));
550 return s;
551 }
552
553 int tmpw = 0, tmph = 0;
554 for(ObjectTreeItem *tree = item->children()->first(); tree; tree = item->children()->next()) {
555 if(!tree->widget())
556 continue;
557 tmpw = TQMAX(tmpw, tree->widget()->geometry().right());
558 tmph = TQMAX(tmph, tree->widget()->geometry().bottom());
559 }
560
561 return TQSize(tmpw, tmph) + TQSize(10, 10);
562}
563
564void
565AdjustSizeCommand::unexecute()
566{
567 // To avoid creation of GeometryPropertyCommand
568 m_form->selectFormWidget();
569 // We resize widgets to their original size
570 TQMap<TQCString, TQSize>::ConstIterator endIt = m_sizes.constEnd();
571 for(TQMap<TQCString, TQSize>::ConstIterator it = m_sizes.constBegin(); it != endIt; ++it)
572 {
573 ObjectTreeItem *item = m_form->objectTree()->lookup(it.key());
574 if(item && item->widget())
575 {
576 item->widget()->resize( m_sizes[item->widget()->name()] );
577 if(m_type == SizeToGrid)
578 item->widget()->move( m_pos[item->widget()->name()] );
579 m_form->setSelectedWidget(item->widget(), true); // We restore selection
580 }
581 }
582}
583
584TQString
585AdjustSizeCommand::name() const
586{
587 switch(m_type)
588 {
589 case SizeToGrid:
590 return i18n("Resize Widgets to Grid");
591 case SizeToFit:
592 return i18n("Resize Widgets to Fit Contents");
593 case SizeToSmallWidth:
594 return i18n("Resize Widgets to Narrowest");
595 case SizeToBigWidth:
596 return i18n("Resize Widgets to Widest");
597 case SizeToSmallHeight:
598 return i18n("Resize Widgets to Shortest");
599 case SizeToBigHeight:
600 return i18n("Resize Widgets to Tallest");
601 default:
602 return TQString();
603 }
604}
605
606void
607AdjustSizeCommand::debug()
608{
609 kdDebug() << "AdjustSizeCommand: name=\"" << name() << "\" form=" << m_form->widget()->name()
610 << " widgets=" << m_sizes.keys() << endl;
611}
612
613// LayoutPropertyCommand
614
615LayoutPropertyCommand::LayoutPropertyCommand(WidgetPropertySet *buf, const TQCString &wname,
616 const TQVariant &oldValue, const TQVariant &value)
617 : PropertyCommand(buf, wname, oldValue, value, "layout")
618{
619 m_form = FormManager::self()->activeForm();
620 ObjectTreeItem* titem = m_form->objectTree()->lookup(wname);
621 if (!titem)
622 return; //better this than a crash
623 Container *m_container = titem->container();
624 // We save the geometry of each wigdet
625 for(ObjectTreeItem *it = m_container->objectTree()->children()->first(); it; it = m_container->objectTree()->children()->next())
626 m_geometries.insert(it->name().latin1(), it->widget()->geometry());
627}
628
629void
630LayoutPropertyCommand::execute()
631{
632 PropertyCommand::execute();
633}
634
635void
636LayoutPropertyCommand::unexecute()
637{
638 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_oldvalues.begin().key());
639 if (!titem)
640 return; //better this than a crash
641 Container *m_container = titem->container();
642 m_container->setLayout(Container::NoLayout);
643 // We put every widget back in its old location
644 TQMap<TQCString,TQRect>::ConstIterator endIt = m_geometries.constEnd();
645 for(TQMap<TQCString,TQRect>::ConstIterator it = m_geometries.constBegin(); it != endIt; ++it)
646 {
647 ObjectTreeItem *tree = m_container->form()->objectTree()->lookup(it.key());
648 if(tree)
649 tree->widget()->setGeometry(it.data());
650 }
651
652 PropertyCommand::unexecute();
653}
654
655TQString
656LayoutPropertyCommand::name() const
657{
658 return i18n("Change layout of widget \"%1\"").arg(TQString(m_oldvalues.begin().key()));
659}
660
661void
662LayoutPropertyCommand::debug()
663{
664 kdDebug() << "LayoutPropertyCommand: name=\"" << name() << "\" oldValue=" << m_oldvalues.keys()
665 << " value=" << m_value << endl;
666}
667
668// InsertWidgetCommand
669
671 : Command()
672{
673 m_containername = container->widget()->name();
674 m_form = container->form();
675 m_class = FormManager::self()->selectedClass();
676 m_insertRect = container->m_insertRect;
677 m_point = container->m_insertBegin;
678 m_name = container->form()->objectTree()->generateUniqueName(
679 container->form()->library()->namePrefix(m_class).latin1(),
false);
681}
682
684 const TQCString& className, const TQPoint& pos, const TQCString& namePrefix)
685 : Command()
686{
687 m_containername = container->widget()->name();
688 m_form = container->form();
689 m_class = className;
690 //m_insertRect is null (default)
691 m_point = pos;
692 if (namePrefix.isEmpty()) {
693 m_name = container->form()->objectTree()->generateUniqueName(
694 container->form()->library()->namePrefix(m_class).latin1() );
695 }
696 else {
697 m_name = container->form()->objectTree()->generateUniqueName(
698 namePrefix, false );
699 }
700}
701
702void
704{
705 if (!m_form->objectTree())
706 return;
707 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_containername);
708 if (!titem)
709 return; //better this than a crash
710 Container *m_container = titem->container();
712 if (m_container->form()->library()->internalProperty(m_class, "orientationSelectionPopup")=="1") {
713 if(m_insertRect.isValid()) {
714 if (m_insertRect.width() < m_insertRect.height()) {
717 }
718 else if (m_insertRect.width() > m_insertRect.height()) {
721 }
722 }
723 if (options & WidgetFactory::AnyOrientation) {
725 options |= m_container->form()->library()->showOrientationSelectionPopup(
726 m_class, m_container->m_container,
727 m_container->form()->widget()->mapToGlobal(m_point));
728 if (options & WidgetFactory::AnyOrientation)
729 return; //cancelled
730 }
731 }
732 else
734
735 TQWidget *w = m_container->form()->library()->createWidget(m_class, m_container->m_container, m_name,
736 m_container, options);
737
738 if(!w) {
740 WidgetInfo *winfo = m_container->form()->library()->widgetInfoForClassName(m_class);
741 KMessageBox::sorry(FormManager::self()->activeForm() ? FormManager::self()->activeForm()->widget() : 0,
742 i18n("Could not insert widget of type \"%1\". A problem with widget's creation encountered.")
743 .arg(winfo ? winfo->name() : TQString()));
744 kdWarning() << "InsertWidgetCommand::execute() ERROR: widget creation failed" << endl;
745 return;
746 }
747#if TDE_VERSION >= TDE_MAKE_VERSION(3,4,0)
749 if (m_form->designMode()) {
750 //don't generate accelerators for widgets in design mode
751 TDEAcceleratorManager::setNoAccel(w);
752 }
753#endif
754
755 // if the insertRect is invalid (ie only one point), we use widget' size hint
756 if(( (m_insertRect.width() < 21) && (m_insertRect.height() < 21)))
757 {
758 TQSize s = w->sizeHint();
759
760 if(s.isEmpty())
761 s = TQSize(20, 20); // Minimum size to avoid creating a (0,0) widget
762 int x, y;
763 if(m_insertRect.isValid())
764 {
765 x = m_insertRect.x();
766 y = m_insertRect.y();
767 }
768 else
769 {
770 x = m_point.x();
771 y = m_point.y();
772 }
773 m_insertRect = TQRect(x, y, s.width() + 16/* add some space so more text can be entered*/,
774 s.height());
775 }
776 w->move(m_insertRect.x(), m_insertRect.y());
777 w->resize(m_insertRect.width()-1, m_insertRect.height()-1); // -1 is not to hide dots
778 w->setStyle(&(m_container->widget()->style()));
779 w->setBackgroundOrigin(TQWidget::ParentOrigin);
780 w->show();
781
783
784 // ObjectTreeItem object already exists for widgets which corresponds to a Container
785 // it's already created in Container's constructor
786 ObjectTreeItem *item = m_container->form()->objectTree()->lookup(m_name);
787 if (!item) { //not yet created...
788 m_container->form()->objectTree()->addItem(m_container->m_tree,
789 item = new ObjectTreeItem(m_container->form()->library()->displayName(m_class), m_name, w, m_container)
790 );
791 }
792 //assign item for its widget if it supports DesignTimeDynamicChildWidgetHandler interface
793 //(e.g. KexiDBAutoField)
794 if (m_form->designMode() && dynamic_cast<DesignTimeDynamicChildWidgetHandler*>(w)) {
795 dynamic_cast<DesignTimeDynamicChildWidgetHandler*>(w)->assignItem(item);
796 }
797
798 // We add the autoSaveProperties in the modifProp list of the ObjectTreeItem, so that they are saved later
799 TQValueList<TQCString> list(m_container->form()->library()->autoSaveProperties(w->className()));
800
801 TQValueList<TQCString>::ConstIterator endIt = list.constEnd();
802 for(TQValueList<TQCString>::ConstIterator it = list.constBegin(); it != endIt; ++it)
803 item->addModifiedProperty(*it, w->property(*it));
804
805 m_container->reloadLayout(); // reload the layout to take the new wigdet into account
806
807 m_container->setSelectedWidget(w, false);
808 if (m_container->form()->library()->internalProperty(w->className(),
809 "dontStartEditingOnInserting").isEmpty())
810 {
811 m_container->form()->library()->startEditing(
812 w->className(), w, item->container() ? item->container() : m_container); // we edit the widget on creation
813 }
815 kdDebug() << "Container::eventFilter(): widget added " << this << endl;
816}
817
818void
819InsertWidgetCommand::unexecute()
820{
821 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_name);
822 if (!titem)
823 return; //better this than a crash
824 TQWidget *m_widget = titem->widget();
825 Container *m_container = m_form->objectTree()->lookup(m_containername)->container();
826 m_container->deleteWidget(m_widget);
827}
828
829TQString
830InsertWidgetCommand::name() const
831{
832 if(!m_name.isEmpty())
833 return i18n("Insert widget \"%1\"").arg(TQString(m_name));
834 else
835 return i18n("Insert widget");
836}
837
838void
839InsertWidgetCommand::debug()
840{
841 kdDebug() << "InsertWidgetCommand: name=\"" << name() << "\" generatedName=" << m_name
842 << " container=" << m_containername
843 << " form=" << m_form->widget()->name() << " class=" << m_class
844 << " rect=" << m_insertRect << " pos=" << m_point << endl;
845}
846
848
849CreateLayoutCommand::CreateLayoutCommand(int layoutType, WidgetList &list, Form *form)
850 : m_form(form), m_type(layoutType)
851{
852 WidgetList *m_list=0;
853 switch(layoutType)
854 {
855 case Container::HBox:
856 case Container::Grid:
857 case Container::HSplitter:
858 case Container::HFlow:
859 m_list = new HorWidgetList(form->toplevelContainer()->widget()); break;
860 case Container::VBox:
861 case Container::VSplitter:
862 case Container::VFlow:
863 m_list = new VerWidgetList(form->toplevelContainer()->widget()); break;
864 }
865 for(TQWidget *w = list.first(); w; w = list.next())
866 m_list->append(w);
867 m_list->sort(); // we sort them now, before creating the layout
868
869 for(TQWidget *w = m_list->first(); w; w = m_list->next())
870 m_pos.insert(w->name(), w->geometry());
871 ObjectTreeItem *item = form->objectTree()->lookup(m_list->first()->name());
872 if(item && item->parent()->container())
873 m_containername = item->parent()->name();
874 delete m_list;
875}
876
877void
879{
880 WidgetLibrary *lib = m_form->library();
881 if(!lib)
882 return;
883 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_containername);
884 Container *container = titem ? titem->container() : 0;
885 if(!container)
886 container = m_form->toplevelContainer(); // use toplevelContainer by default
887
888 TQCString classname;
889 switch(m_type) {
890 case Container::HSplitter: case Container::VSplitter:
891 classname = "TQSplitter"; break;
892 default:
893 classname = Container::layoutTypeToString(m_type).latin1();
894 }
895
896 if(m_name.isEmpty())// the name must be generated only once
897 m_name = m_form->objectTree()->generateUniqueName(classname);
898
899 TQWidget *w = lib->createWidget(classname, container->widget(), m_name.latin1(), container);
900#if TDE_VERSION >= TDE_MAKE_VERSION(3,4,0)
902 if (w) {
903 if (m_form->designMode()) {
904 //don't generate accelerators for widgets in design mode
905 TDEAcceleratorManager::setNoAccel(w);
906 }
907 }
908#endif
909 ObjectTreeItem *tree = w ? m_form->objectTree()->lookup(w->name()) : 0;
910 if(!tree)
911 return;
912
913 container->setSelectedWidget(0, false);
914 w->move(m_pos.begin().data().topLeft()); // we move the layout at the position of the topleft widget
915 // sizeHint of these widgets depends on geometry, so give them appropriate geometry
916 if(m_type == Container::HFlow)
917 w->resize( TQSize(700, 20) );
918 else if(m_type == Container::VFlow)
919 w->resize( TQSize(20, 700));
920 w->show();
921
922 // We reparent every widget to the Layout and insert them into it
923 TQMap<TQCString,TQRect>::ConstIterator endIt = m_pos.constEnd();
924 for(TQMap<TQCString,TQRect>::ConstIterator it = m_pos.constBegin(); it != endIt; ++it)
925 {
926 ObjectTreeItem *item = m_form->objectTree()->lookup(it.key());
927 if(item && item->widget())
928 {
929 item->widget()->reparent(w, item->widget()->pos(), true);
930 item->eventEater()->setContainer(tree->container());
931 m_form->objectTree()->reparent(item->name(), m_name);
932 }
933 }
934
935 if(m_type == Container::HSplitter)
936 ((TQSplitter*)w)->setOrientation(TQt::Horizontal);
937 else if(m_type == Container::VSplitter)
938 ((TQSplitter*)w)->setOrientation(TQt::Vertical);
939 else if(tree->container()) {
940 tree->container()->setLayout((Container::LayoutType)m_type);
941 w->resize(tree->container()->layout()->sizeHint()); // the layout doesn't have its own size
942 }
943
944 container->setSelectedWidget(w, false);
945 FormManager::self()->windowChanged(m_form->widget()); // to reload the ObjectTreeView
946}
947
948void
949CreateLayoutCommand::unexecute()
950{
951 ObjectTreeItem *parent = m_form->objectTree()->lookup(m_containername);
952 if(!parent)
953 parent = m_form->objectTree();
954
955 // We reparent every widget to the Container and take them out of the layout
956 TQMap<TQCString,TQRect>::ConstIterator endIt = m_pos.constEnd();
957 for(TQMap<TQCString,TQRect>::ConstIterator it = m_pos.constBegin(); it != endIt; ++it)
958 {
959 ObjectTreeItem *item = m_form->objectTree()->lookup(it.key());
960 if(item && item->widget())
961 {
962 item->widget()->reparent(parent->widget(), TQPoint(0,0), true);
963 item->eventEater()->setContainer(parent->container());
964 if(m_pos[it.key()].isValid())
965 item->widget()->setGeometry(m_pos[it.key()]);
966 m_form->objectTree()->reparent(item->name(), m_containername);
967 }
968 }
969
970 if(!parent->container())
971 return;
972 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_name);
973 if (!titem)
974 return; //better this than a crash
975 TQWidget *w = titem->widget();
976 parent->container()->deleteWidget(w); // delete the layout widget
977 FormManager::self()->windowChanged(m_form->widget()); // to reload ObjectTreeView
978}
979
980TQString
981CreateLayoutCommand::name() const
982{
983 switch(m_type)
984 {
985 case Container::HBox:
986 return i18n("Group Widgets Horizontally");
987 case Container::VBox:
988 return i18n("Group Widgets Vertically");
989 case Container::Grid:
990 return i18n("Group Widgets in a Grid");
991 case Container::HSplitter:
992 return i18n("Group Widgets Horizontally in a Splitter");
993 case Container::VSplitter:
994 return i18n("Group Widgets Vertically in a Splitter");
995 case Container::HFlow:
996 return i18n("Group Widgets By Rows");
997 case Container::VFlow:
998 return i18n("Group Widgets Vertically By Columns");
999 default:
1000 return i18n("Group widgets");
1001 }
1002}
1003
1004void
1005CreateLayoutCommand::debug()
1006{
1007 kdDebug() << "CreateLayoutCommand: name=\"" << name() << "\" generatedName=" << m_name
1008 << " widgets=" << m_pos.keys() << " container=" << m_containername
1009 << " form=" << m_form->widget()->name() << endl;
1010}
1011
1013
1016{
1017 m_containername = container->toplevel()->widget()->name();
1018 m_name = container->widget()->name();
1019 m_form = container->form();
1020 m_type = container->layoutType();
1021
1022 for(ObjectTreeItem *tree = container->objectTree()->children()->first(); tree; tree = container->objectTree()->children()->next())
1023 {
1024 TQRect r(container->widget()->mapTo(container->widget()->parentWidget(), tree->widget()->pos()), tree->widget()->size());
1025 m_pos.insert(tree->widget()->name(), r);
1026 }
1027}
1028
1029void
1030BreakLayoutCommand::execute()
1031{
1032 CreateLayoutCommand::unexecute();
1033}
1034
1035void
1036BreakLayoutCommand::unexecute()
1037{
1039}
1040
1041TQString
1042BreakLayoutCommand::name() const
1043{
1044 return i18n("Break Layout: \"%1\"").arg(m_name);
1045}
1046
1047void
1048BreakLayoutCommand::debug()
1049{
1050 kdDebug() << "BreakLayoutCommand: name=\"" << name()
1051 << " widgets=" << m_pos.keys() << " container=" << m_containername
1052 << " form=" << m_form->widget()->name() << endl;
1053}
1054
1055// PasteWidgetCommand
1056
1057PasteWidgetCommand::PasteWidgetCommand(TQDomDocument &domDoc, Container *container, const TQPoint& p)
1058 : m_point(p)
1059{
1060 m_data = domDoc.toCString();
1061 m_containername = container->widget()->name();
1062 m_form = container->form();
1063
1064 if(domDoc.namedItem("UI").firstChild().nextSibling().toElement().tagName() != "widget")
1065 return;
1066
1067 TQRect boundingRect;
1068 for(TQDomNode n = domDoc.namedItem("UI").firstChild(); !n.isNull(); n = n.nextSibling()) // more than one widget
1069 {
1070 if(n.toElement().tagName() != "widget")
1071 continue;
1072 TQDomElement el = n.toElement();
1073
1075 for(TQDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
1076 {
1077 if((n.toElement().tagName() == "property") && (n.toElement().attribute("name") == "geometry"))
1078 rect = n.firstChild().toElement();
1079 }
1080
1081 TQDomElement x = rect.namedItem("x").toElement();
1082 TQDomElement y = rect.namedItem("y").toElement();
1083 TQDomElement wi = rect.namedItem("width").toElement();
1084 TQDomElement h = rect.namedItem("height").toElement();
1085
1086 int rx = x.text().toInt();
1087 int ry = y.text().toInt();
1088 int rw = wi.text().toInt();
1089 int rh = h.text().toInt();
1090 TQRect r(rx, ry, rw, rh);
1091 boundingRect = boundingRect.unite(r);
1092 }
1093
1094 m_point = m_point - boundingRect.topLeft();
1095}
1096
1097void
1098PasteWidgetCommand::execute()
1099{
1100 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_containername);
1101 if (!titem)
1102 return; //better this than a crash
1103 Container *container = titem->container();
1104 TQString errMsg;
1105 int errLine;
1106 int errCol;
1107 TQDomDocument domDoc("UI");
1108 bool parsed = domDoc.setContent(m_data, false, &errMsg, &errLine, &errCol);
1109
1110 if(!parsed)
1111 {
1112 kdDebug() << "WidgetWatcher::load(): " << errMsg << endl;
1113 kdDebug() << "WidgetWatcher::load(): line: " << errLine << " col: " << errCol << endl;
1114 return;
1115 }
1116
1117 //FormIO::setCurrentForm(m_container->form());
1118
1119 kdDebug() << domDoc.toString() << endl;
1120 if(!domDoc.namedItem("UI").hasChildNodes()) // nothing in the doc
1121 return;
1122 if(domDoc.namedItem("UI").firstChild().nextSibling().toElement().tagName() != "widget") // only one widget, so we can paste it at cursor pos
1123 {
1124 TQDomElement el = domDoc.namedItem("UI").firstChild().toElement();
1125 fixNames(el);
1126 if(m_point.isNull())
1127 fixPos(el, container);
1128 else
1129 changePos(el, m_point);
1130
1131 m_form->setInteractiveMode(false);
1132 FormIO::loadWidget(container, el);
1133 m_form->setInteractiveMode(true);
1134 }
1135 else for(TQDomNode n = domDoc.namedItem("UI").firstChild(); !n.isNull(); n = n.nextSibling()) // more than one widget
1136 {
1137 if(n.toElement().tagName() != "widget")
1138 continue;
1139 TQDomElement el = n.toElement();
1140 fixNames(el);
1141 if(!m_point.isNull())
1142 moveWidgetBy(el, container, m_point);
1143 else {
1144 fixPos(el, container);
1145 kdDebug() << "jdkjfldfksmfkdfjmqdsklfjdkkfmsqfksdfsm" << endl;
1146 }
1147
1148 m_form->setInteractiveMode(false);
1149 FormIO::loadWidget(container, el);
1150 m_form->setInteractiveMode(true);
1151 }
1152
1153 //FormIO::setCurrentForm(0);
1154 m_names.clear();
1155 // We store the names of all the created widgets, to delete them later
1156 for(TQDomNode n = domDoc.namedItem("UI").firstChild(); !n.isNull(); n = n.nextSibling())
1157 {
1158 if(n.toElement().tagName() != "widget")
1159 continue;
1160 for(TQDomNode m = n.firstChild(); !m.isNull(); n = m.nextSibling())
1161 {
1162 if((m.toElement().tagName() == "property") && (m.toElement().attribute("name") == "name"))
1163 {
1164 m_names.append(m.toElement().text());
1165 break;
1166 }
1167 }
1168 }
1169
1170 container->form()->selectFormWidget();
1171 TQStringList::ConstIterator endIt = m_names.constEnd();
1172 for(TQStringList::ConstIterator it = m_names.constBegin(); it != endIt; ++it) // We select all the pasted widgets
1173 {
1174 ObjectTreeItem *item = m_form->objectTree()->lookup(*it);
1175 if(item)
1176 container->setSelectedWidget(item->widget(), true);
1177 }
1178}
1179
1180void
1181PasteWidgetCommand::unexecute()
1182{
1183 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_containername);
1184 if (!titem)
1185 return; //better this than a crash
1186 Container *container = titem->container();
1187 // We just delete all the widgets we have created
1188 TQStringList::ConstIterator endIt = m_names.constEnd();
1189 for(TQStringList::ConstIterator it = m_names.constBegin(); it != endIt; ++it)
1190 {
1191 ObjectTreeItem* titem = container->form()->objectTree()->lookup(*it);
1192 if (!titem)
1193 continue; //better this than a crash
1194 TQWidget *w = titem->widget();
1195 container->deleteWidget(w);
1196 }
1197}
1198
1199TQString
1200PasteWidgetCommand::name() const
1201{
1202 return i18n("Paste");
1203}
1204
1205void
1206//TQDomElement
1208{
1209 //TQDomElement el = widg.cloneNode(true).toElement();
1211 // Find the widget geometry if there is one
1212 for(TQDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
1213 {
1214 if((n.toElement().tagName() == "property") && (n.toElement().attribute("name") == "geometry"))
1215 rect = n.firstChild().toElement();
1216 }
1217
1218 TQDomElement x = rect.namedItem("x").toElement();
1219 x.removeChild(x.firstChild());
1220 TQDomText valueX = el.ownerDocument().createTextNode(TQString::number(newpos.x()));
1221 x.appendChild(valueX);
1222
1223 TQDomElement y = rect.namedItem("y").toElement();
1224 y.removeChild(y.firstChild());
1225 TQDomText valueY = el.ownerDocument().createTextNode(TQString::number(newpos.y()));
1226 y.appendChild(valueY);
1227
1228 //return el;
1229}
1230
1231void
1233{
1234/* TQDomElement rect;
1235 for(TQDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
1236 {
1237 if((n.toElement().tagName() == "property") && (n.toElement().attribute("name") == "geometry"))
1238 rect = n.firstChild().toElement();
1239 }
1240
1241 TQDomElement x = rect.namedItem("x").toElement();
1242 TQDomElement y = rect.namedItem("y").toElement();
1243 TQDomElement wi = rect.namedItem("width").toElement();
1244 TQDomElement h = rect.namedItem("height").toElement();
1245
1246 int rx = x.text().toInt();
1247 int ry = y.text().toInt();
1248 int rw = wi.text().toInt();
1249 int rh = h.text().toInt();
1250 TQRect r(rx, ry, rw, rh);
1251
1252 TQWidget *w = m_form->widget()->childAt(r.x() + 6, r.y() + 6, false);
1253 if(!w)
1254 return;
1255
1256 while((w->geometry() == r) && (w != 0))// there is already a widget there, with the same size
1257 {
1258 w = m_form->widget()->childAt(w->x() + 16, w->y() + 16, false);
1259 r.moveBy(10,10);
1260 }
1261
1262 // the pasted wigdet should stay inside container's boundaries
1263 if(r.x() < 0)
1264 r.moveLeft(0);
1265 else if(r.right() > container->widget()->width())
1266 r.moveLeft(container->widget()->width() - r.width());
1267
1268 if(r.y() < 0)
1269 r.moveTop(0);
1270 else if(r.bottom() > container->widget()->height())
1271 r.moveTop(container->widget()->height() - r.height());
1272
1273 if(r != TQRect(rx, ry, rw, rh))
1274 //return el;
1275 //else
1276 changePos(el, TQPoint(r.x(), r.y()));
1277*/
1278 moveWidgetBy(el, container, TQPoint(0, 0));
1279}
1280
1281void
1282PasteWidgetCommand::moveWidgetBy(TQDomElement &el, Container *container, const TQPoint &p)
1283{
1285 for(TQDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
1286 {
1287 if((n.toElement().tagName() == "property") && (n.toElement().attribute("name") == "geometry"))
1288 rect = n.firstChild().toElement();
1289 }
1290
1291 TQDomElement x = rect.namedItem("x").toElement();
1292 TQDomElement y = rect.namedItem("y").toElement();
1293 TQDomElement wi = rect.namedItem("width").toElement();
1294 TQDomElement h = rect.namedItem("height").toElement();
1295
1296 int rx = x.text().toInt();
1297 int ry = y.text().toInt();
1298 int rw = wi.text().toInt();
1299 int rh = h.text().toInt();
1300 TQRect r(rx + p.x(), ry + p.y(), rw, rh);
1301 kdDebug() << "Moving widget by " << p << " from " << rx << " " << ry << " to " << r.topLeft() << endl;
1302
1303 TQWidget *w = m_form->widget()->childAt(r.x() + 6, r.y() + 6, false);
1304
1305 while(w && (w->geometry() == r))// there is already a widget there, with the same size
1306 {
1307 w = m_form->widget()->childAt(w->x() + 16, w->y() + 16, false);
1308 r.moveBy(10,10);
1309 }
1310
1311 // the pasted wigdet should stay inside container's boundaries
1312 if(r.x() < 0)
1313 r.moveLeft(0);
1314 else if(r.right() > container->widget()->width())
1315 r.moveLeft(container->widget()->width() - r.width());
1316
1317 if(r.y() < 0)
1318 r.moveTop(0);
1319 else if(r.bottom() > container->widget()->height())
1320 r.moveTop(container->widget()->height() - r.height());
1321
1322 if(r != TQRect(rx, ry, rw, rh))
1323 //return el;
1324 //else
1325 changePos(el, TQPoint(r.x(), r.y()));
1326}
1327
1328void
1330{
1331 TQString wname;
1332 for(TQDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
1333 {
1334 if((n.toElement().tagName() == "property") && (n.toElement().attribute("name") == "name"))
1335 {
1336 wname = n.toElement().text();
1337 while(m_form->objectTree()->lookup(wname)) // name already exists
1338 {
1339 bool ok;
1340 int num = wname.right(1).toInt(&ok, 10);
1341 if(ok)
1342 wname = wname.left(wname.length()-1) + TQString::number(num+1);
1343 else
1344 wname += "2";
1345 }
1346 if(wname != n.toElement().text()) // we change the name, so we recreate the element
1347 {
1348 n.removeChild(n.firstChild());
1349 TQDomElement type = el.ownerDocument().createElement("string");
1350 TQDomText valueE = el.ownerDocument().createTextNode(wname);
1351 type.appendChild(valueE);
1352 n.toElement().appendChild(type);
1353 }
1354
1355 }
1356 if(n.toElement().tagName() == "widget") // fix child widgets names
1357 {
1358 TQDomElement child = n.toElement();
1359 fixNames(child);
1360 }
1361 }
1362}
1363
1364void
1365PasteWidgetCommand::debug()
1366{
1367 kdDebug() << "PasteWidgetCommand: pos=" << m_point
1368 << " widgets=" << m_names << " container=" << m_containername
1369 << " form=" << m_form->widget()->name()
1370 << " data=\"" << m_data.left(80) << "...\"" << endl;
1371}
1372
1373// DeleteWidgetCommand
1374
1375DeleteWidgetCommand::DeleteWidgetCommand(WidgetList &list, Form *form)
1376 : Command(), m_form(form)
1377{
1378 m_domDoc = TQDomDocument("UI");
1379 m_domDoc.appendChild(m_domDoc.createElement("UI"));
1380
1381 TQDomElement parent = m_domDoc.namedItem("UI").toElement();
1382
1383 //for(TQWidget *w = list.first(); w; w = list.next())
1384 /*for(WidgetListIterator it(list); it.current() != 0; ++it)
1385 {
1386 TQWidget *w = it.current();
1387 // Don't delete tabwidget or widgetstack pages
1388 if(w->parentWidget()->inherits("TQWidgetStack"))
1389 {
1390 list.remove(w);
1391 continue;
1392 }
1393 }*/
1395
1396 for(WidgetListIterator it(list); it.current() != 0; ++it)
1397 {
1398 ObjectTreeItem *item = m_form->objectTree()->lookup(it.current()->name());
1399 if (!item)
1400 return;
1401
1402 // We need to store both parentContainer and parentWidget as they may be different (eg for TabWidget page)
1403 m_containers.insert(item->name().latin1(), m_form->parentContainer(item->widget())->widget()->name());
1404 m_parents.insert(item->name().latin1(), item->parent()->name().latin1());
1405 FormIO::saveWidget(item, parent, m_domDoc);
1406 form->connectionBuffer()->saveAllConnectionsForWidget(item->widget()->name(), m_domDoc);
1407 }
1408
1409 FormIO::cleanClipboard(parent);
1410}
1411
1412void
1413DeleteWidgetCommand::execute()
1414{
1416
1417 TQMap<TQCString,TQCString>::ConstIterator endIt = m_containers.constEnd();
1418 for(TQMap<TQCString,TQCString>::ConstIterator it = m_containers.constBegin(); it != endIt; ++it)
1419 {
1420 ObjectTreeItem *item = m_form->objectTree()->lookup(it.key());
1421 if (!item || !item->widget())
1422 continue;
1423
1424 Container *cont = m_form->parentContainer(item->widget());
1425 if (!containerToSelect)
1427 cont->deleteWidget(item->widget());
1428 }
1429 //now we've nothing selecte: select parent container
1431 m_form->setSelectedWidget( containerToSelect->widget() );
1432}
1433
1434void
1435DeleteWidgetCommand::unexecute()
1436{
1437 TQCString wname;
1438 m_form->setInteractiveMode(false);
1439 for(TQDomNode n = m_domDoc.namedItem("UI").firstChild(); !n.isNull(); n = n.nextSibling())
1440 {
1441 if(n.toElement().tagName() == "connections") // restore the widget connections
1442 m_form->connectionBuffer()->load(n);
1443 if(n.toElement().tagName() != "widget")
1444 continue;
1445 // We need first to know the name of the widget
1446 for(TQDomNode m = n.firstChild(); !m.isNull(); n = m.nextSibling())
1447 {
1448 if((m.toElement().tagName() == "property") && (m.toElement().attribute("name") == "name"))
1449 {
1450 wname = m.toElement().text().latin1();
1451 break;
1452 }
1453 }
1454
1455 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_containers[wname]);
1456 if (!titem)
1457 return; //better this than a crash
1458 Container *cont = titem->container();
1459 ObjectTreeItem *parent = m_form->objectTree()->lookup(m_parents[wname]);
1460 TQDomElement widg = n.toElement();
1461 if(parent)
1462 FormIO::loadWidget(cont, widg, parent->widget());
1463 else
1464 FormIO::loadWidget(cont, widg);
1465 }
1466 m_form->setInteractiveMode(true);
1467}
1468
1469TQString
1470DeleteWidgetCommand::name() const
1471{
1472 return i18n("Delete widget");
1473}
1474
1475void
1476DeleteWidgetCommand::debug()
1477{
1478 kdDebug() << "DeleteWidgetCommand: containers=" << m_containers.keys()
1479 << " parents=" << m_parents.keys() << " form=" << m_form->widget()->name() << endl;
1480}
1481
1482// CutWidgetCommand
1483
1484CutWidgetCommand::CutWidgetCommand(WidgetList &list, Form *form)
1485 : DeleteWidgetCommand(list, form)
1486{}
1487
1488void
1489CutWidgetCommand::execute()
1490{
1491 DeleteWidgetCommand::execute();
1492 m_data = FormManager::self()->m_domDoc.toCString();
1493 FormManager::self()->m_domDoc.setContent(m_domDoc.toCString());
1494}
1495
1496void
1497CutWidgetCommand::unexecute()
1498{
1499 DeleteWidgetCommand::unexecute();
1500 FormManager::self()->m_domDoc.setContent(m_data);
1501}
1502
1503TQString
1504CutWidgetCommand::name() const
1505{
1506 return i18n("Cut");
1507}
1508
1509void
1510CutWidgetCommand::debug()
1511{
1512 kdDebug() << "CutWidgetCommand: containers=" << m_containers.keys()
1513 << " parents=" << m_parents.keys() << " form=" << m_form->widget()->name()
1514 << " data=\"" << m_data.left(80) << "...\"" << endl;
1515}
1516
1517// CommandGroup
1518
1519namespace KFormDesigner {
1520class CommandGroup::SubCommands : public KMacroCommand
1521{
1522 public:
1523 SubCommands( const TQString & name )
1524 : KMacroCommand(name)
1525 {
1526 }
1527 const TQPtrList<KCommand>& commands() const { return m_commands; }
1528};
1529}
1530
1531CommandGroup::CommandGroup( const TQString & name, WidgetPropertySet *propSet )
1532 : Command()
1533 , m_subCommands(new SubCommands(name))
1534 , m_propSet(propSet)
1535{
1536}
1537
1538CommandGroup::~CommandGroup()
1539{
1540 delete m_subCommands;
1541}
1542
1544{
1545 return m_subCommands->commands();
1546}
1547
1549{
1550 if (!command)
1551 return;
1552
1553 m_subCommands->addCommand(command);
1554 if (!allowExecute)
1555 m_commandsShouldntBeExecuted.insert(command, (char*)1);
1556}
1557
1559{
1560 FormManager::self()->blockPropertyEditorUpdating(this);
1561 for (TQPtrListIterator<KCommand> it(m_subCommands->commands()); it.current(); ++it) {
1562 if (!m_commandsShouldntBeExecuted[it.current()])
1563 it.current()->execute();
1564 }
1565 FormManager::self()->unblockPropertyEditorUpdating(this, m_propSet);
1566}
1567
1569{
1570 FormManager::self()->blockPropertyEditorUpdating(this);
1571 m_subCommands->unexecute();
1572 FormManager::self()->unblockPropertyEditorUpdating(this, m_propSet);
1573}
1574
1575TQString CommandGroup::name() const
1576{
1577 return m_subCommands->name();
1578}
1579
1584
1585void
1586CommandGroup::debug()
1587{
1588 kdDebug() << "*CommandGroup: name=\"" << name() << "\" #=" << m_subCommands->commands().count() << endl;
1589 uint i = 1;
1590 for (TQPtrListIterator<KCommand> it(m_subCommands->commands()); it.current(); ++it, i++) {
1591 kdDebug() << "#" << i << ":"
1592 << (m_commandsShouldntBeExecuted[it.current()] ? "!" : "") << "allowExecute:" << endl;
1593 if (dynamic_cast<Command*>(it.current()))
1594 dynamic_cast<Command*>(it.current())->debug();
1595 else if (dynamic_cast<CommandGroup*>(it.current()))
1596 dynamic_cast<CommandGroup*>(it.current())->debug();
1597 else
1598 kdDebug() << "(other KCommand)" << endl;
1599 }
1600 kdDebug() << "End of CommandGroup" << endl;
1601}
BreakLayoutCommand(Container *container)
BreakLayoutCommand ///////////////.
const TQPtrList< KCommand > & commands() const
TQPtrDict< char > m_commandsShouldntBeExecuted
Used to store pointers to subcommands that shouldn't be executed on CommandGroup::execute()
Definition commands.h:374
void addCommand(KCommand *command, bool allowExecute)
Base class for KFormDesigner's commands.
Definition commands.h:49
This class makes a container out of any TQWidget.
Definition container.h:74
void setLayout(LayoutType type)
Layout functions.
void deleteWidget(TQWidget *w)
TQWidget * widget() const
Definition container.h:94
void setSelectedWidget(TQWidget *selected, bool add, bool dontRaise=false, bool moreWillBeSelected=false)
ObjectTreeItem * objectTree() const
Definition container.h:97
LayoutType layoutType() const
Definition container.h:110
static TQString layoutTypeToString(int type)
TQLayout * layout() const
Definition container.h:107
Form * form() const
Definition container.h:91
Interface for adding dynamically created (at design time) widget to event eater.
Definition container.h:233
void setContainer(TQObject *container)
Sets the object which will receive the events.
Definition container.h:60
void dirty(KFormDesigner::Form *form, bool isDirty=true)
static FormManager * self()
Access to FormManager singleton.
TQCString selectedClass() const
void windowChanged(TQWidget *w)
A simple class representing a form.
Definition form.h:136
void selectFormWidget()
Definition form.cpp:296
void setSelectedWidget(TQWidget *selected, bool add=false, bool dontRaise=false, bool moreWillBeSelected=false)
Definition form.cpp:237
Container * toplevelContainer() const
Definition form.h:161
WidgetLibrary * library() const
Definition form.h:147
Container * parentContainer(TQWidget *w=0)
Definition form.cpp:196
WidgetList * selectedWidgets() const
Definition form.h:192
ObjectTree * objectTree() const
Definition form.h:167
bool designMode() const
Definition form.h:226
TQWidget * widget() const
Definition form.cpp:114
void setInteractiveMode(bool interactive)
Definition form.h:210
A helper for sorting widgets horizontally.
InsertWidgetCommand(Container *container)
Definition commands.cpp:670
An item representing a widget Holds the properties of a widget (classname, name, parent,...
Definition objecttree.h:59
Container * container() const
Definition objecttree.h:76
void addModifiedProperty(const TQCString &property, const TQVariant &oldValue)
TQCString generateUniqueName(const TQCString &prefix, bool numberSuffixRequired=true)
ObjectTreeItem * lookup(const TQString &name)
bool reparent(const TQString &name, const TQString &newparent)
void fixNames(TQDomElement &el)
void fixPos(TQDomElement &el, Container *container)
void changePos(TQDomElement &widg, const TQPoint &newpos)
A helper for sorting widgets vertically.
@ DesignViewMode
create widget in design view mode, otherwise preview mode
@ VerticalOrientation
vertical orientation hint
@ HorizontalOrientation
horizontal orientation hint
@ AnyOrientation
any orientation hint
This class holds properties of widget classes provided by a factory.
This class searches for factories and provides TDEActions for widget creation.
TQWidget * createWidget(const TQCString &classname, TQWidget *parent, const char *name, Container *c, int options=WidgetFactory::DefaultOptions)
searches the right factory and creates a widget.
WidgetFactory::CreateWidgetOptions showOrientationSelectionPopup(const TQCString &classname, TQWidget *parent, const TQPoint &pos)
Shows orientation selection popup.
An interface for declaring form widgets to have subproperties.
TQPtrList< TQWidget > WidgetList
A list of widget pointers.
TQPtrListIterator< TQWidget > WidgetListIterator
An iterator for WidgetList.
KFORMEDITOR_EXPORT void removeChildrenFromList(WidgetList &list)
type * findParent(TQObject *o, const char *className, TQObject *&prevPrev)