kexi

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;
90 emit FormManager::self()->dirty(FormManager::self()->activeForm());
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 {
102 ObjectTreeItem* item = FormManager::self()->activeForm()->objectTree()->lookup(it.key());
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 {
121 ObjectTreeItem* item = FormManager::self()->activeForm()->objectTree()->lookup(it.key());
122 if (!item)
123 continue; //better this than a crash
124 TQWidget *widg = item->widget();
126 //m_propSet->setSelectedWidget(widg, true);
127
128 WidgetWithSubpropertiesInterface* subpropIface = dynamic_cast<WidgetWithSubpropertiesInterface*>(widg);
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 {
173 ObjectTreeItem* item = FormManager::self()->activeForm()->objectTree()->lookup(*it);
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 {
193 ObjectTreeItem* item = FormManager::self()->activeForm()->objectTree()->lookup(*it);
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 }
748 if (m_form->designMode()) {
749 //don't generate accelerators for widgets in design mode
750 TDEAcceleratorManager::setNoAccel(w);
751 }
752
753 // if the insertRect is invalid (ie only one point), we use widget' size hint
754 if(( (m_insertRect.width() < 21) && (m_insertRect.height() < 21)))
755 {
756 TQSize s = w->sizeHint();
757
758 if(s.isEmpty())
759 s = TQSize(20, 20); // Minimum size to avoid creating a (0,0) widget
760 int x, y;
761 if(m_insertRect.isValid())
762 {
763 x = m_insertRect.x();
764 y = m_insertRect.y();
765 }
766 else
767 {
768 x = m_point.x();
769 y = m_point.y();
770 }
771 m_insertRect = TQRect(x, y, s.width() + 16/* add some space so more text can be entered*/,
772 s.height());
773 }
774 w->move(m_insertRect.x(), m_insertRect.y());
775 w->resize(m_insertRect.width()-1, m_insertRect.height()-1); // -1 is not to hide dots
776 w->setStyle(&(m_container->widget()->style()));
777 w->setBackgroundOrigin(TQWidget::ParentOrigin);
778 w->show();
779
781
782 // ObjectTreeItem object already exists for widgets which corresponds to a Container
783 // it's already created in Container's constructor
784 ObjectTreeItem *item = m_container->form()->objectTree()->lookup(m_name);
785 if (!item) { //not yet created...
786 m_container->form()->objectTree()->addItem(m_container->m_tree,
787 item = new ObjectTreeItem(m_container->form()->library()->displayName(m_class), m_name, w, m_container)
788 );
789 }
790 //assign item for its widget if it supports DesignTimeDynamicChildWidgetHandler interface
791 //(e.g. KexiDBAutoField)
792 if (m_form->designMode() && dynamic_cast<DesignTimeDynamicChildWidgetHandler*>(w)) {
793 dynamic_cast<DesignTimeDynamicChildWidgetHandler*>(w)->assignItem(item);
794 }
795
796 // We add the autoSaveProperties in the modifProp list of the ObjectTreeItem, so that they are saved later
797 TQValueList<TQCString> list(m_container->form()->library()->autoSaveProperties(w->className()));
798
799 TQValueList<TQCString>::ConstIterator endIt = list.constEnd();
800 for(TQValueList<TQCString>::ConstIterator it = list.constBegin(); it != endIt; ++it)
801 item->addModifiedProperty(*it, w->property(*it));
802
803 m_container->reloadLayout(); // reload the layout to take the new wigdet into account
804
805 m_container->setSelectedWidget(w, false);
806 if (m_container->form()->library()->internalProperty(w->className(),
807 "dontStartEditingOnInserting").isEmpty())
808 {
809 m_container->form()->library()->startEditing(
810 w->className(), w, item->container() ? item->container() : m_container); // we edit the widget on creation
811 }
813 kdDebug() << "Container::eventFilter(): widget added " << this << endl;
814}
815
816void
817InsertWidgetCommand::unexecute()
818{
819 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_name);
820 if (!titem)
821 return; //better this than a crash
822 TQWidget *m_widget = titem->widget();
823 Container *m_container = m_form->objectTree()->lookup(m_containername)->container();
824 m_container->deleteWidget(m_widget);
825}
826
827TQString
828InsertWidgetCommand::name() const
829{
830 if(!m_name.isEmpty())
831 return i18n("Insert widget \"%1\"").arg(TQString(m_name));
832 else
833 return i18n("Insert widget");
834}
835
836void
837InsertWidgetCommand::debug()
838{
839 kdDebug() << "InsertWidgetCommand: name=\"" << name() << "\" generatedName=" << m_name
840 << " container=" << m_containername
841 << " form=" << m_form->widget()->name() << " class=" << m_class
842 << " rect=" << m_insertRect << " pos=" << m_point << endl;
843}
844
846
848 : m_form(form), m_type(layoutType)
849{
850 WidgetList *m_list=0;
851 switch(layoutType)
852 {
853 case Container::HBox:
854 case Container::Grid:
855 case Container::HSplitter:
856 case Container::HFlow:
857 m_list = new HorWidgetList(form->toplevelContainer()->widget()); break;
858 case Container::VBox:
859 case Container::VSplitter:
860 case Container::VFlow:
861 m_list = new VerWidgetList(form->toplevelContainer()->widget()); break;
862 }
863 for(TQWidget *w = list.first(); w; w = list.next())
864 m_list->append(w);
865 m_list->sort(); // we sort them now, before creating the layout
866
867 for(TQWidget *w = m_list->first(); w; w = m_list->next())
868 m_pos.insert(w->name(), w->geometry());
869 ObjectTreeItem *item = form->objectTree()->lookup(m_list->first()->name());
870 if(item && item->parent()->container())
871 m_containername = item->parent()->name();
872 delete m_list;
873}
874
875void
877{
878 WidgetLibrary *lib = m_form->library();
879 if(!lib)
880 return;
881 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_containername);
882 Container *container = titem ? titem->container() : 0;
883 if(!container)
884 container = m_form->toplevelContainer(); // use toplevelContainer by default
885
886 TQCString classname;
887 switch(m_type) {
888 case Container::HSplitter: case Container::VSplitter:
889 classname = "TQSplitter"; break;
890 default:
891 classname = Container::layoutTypeToString(m_type).latin1();
892 }
893
894 if(m_name.isEmpty())// the name must be generated only once
895 m_name = m_form->objectTree()->generateUniqueName(classname);
896
897 TQWidget *w = lib->createWidget(classname, container->widget(), m_name.latin1(), container);
899 if (w) {
900 if (m_form->designMode()) {
901 //don't generate accelerators for widgets in design mode
902 TDEAcceleratorManager::setNoAccel(w);
903 }
904 }
905 ObjectTreeItem *tree = w ? m_form->objectTree()->lookup(w->name()) : 0;
906 if(!tree)
907 return;
908
909 container->setSelectedWidget(0, false);
910 w->move(m_pos.begin().data().topLeft()); // we move the layout at the position of the topleft widget
911 // sizeHint of these widgets depends on geometry, so give them appropriate geometry
912 if(m_type == Container::HFlow)
913 w->resize( TQSize(700, 20) );
914 else if(m_type == Container::VFlow)
915 w->resize( TQSize(20, 700));
916 w->show();
917
918 // We reparent every widget to the Layout and insert them into it
919 TQMap<TQCString,TQRect>::ConstIterator endIt = m_pos.constEnd();
920 for(TQMap<TQCString,TQRect>::ConstIterator it = m_pos.constBegin(); it != endIt; ++it)
921 {
922 ObjectTreeItem *item = m_form->objectTree()->lookup(it.key());
923 if(item && item->widget())
924 {
925 item->widget()->reparent(w, item->widget()->pos(), true);
926 item->eventEater()->setContainer(tree->container());
927 m_form->objectTree()->reparent(item->name(), m_name);
928 }
929 }
930
931 if(m_type == Container::HSplitter)
932 ((TQSplitter*)w)->setOrientation(TQt::Horizontal);
933 else if(m_type == Container::VSplitter)
934 ((TQSplitter*)w)->setOrientation(TQt::Vertical);
935 else if(tree->container()) {
936 tree->container()->setLayout((Container::LayoutType)m_type);
937 w->resize(tree->container()->layout()->sizeHint()); // the layout doesn't have its own size
938 }
939
940 container->setSelectedWidget(w, false);
941 FormManager::self()->windowChanged(m_form->widget()); // to reload the ObjectTreeView
942}
943
944void
945CreateLayoutCommand::unexecute()
946{
947 ObjectTreeItem *parent = m_form->objectTree()->lookup(m_containername);
948 if(!parent)
949 parent = m_form->objectTree();
950
951 // We reparent every widget to the Container and take them out of the layout
952 TQMap<TQCString,TQRect>::ConstIterator endIt = m_pos.constEnd();
953 for(TQMap<TQCString,TQRect>::ConstIterator it = m_pos.constBegin(); it != endIt; ++it)
954 {
955 ObjectTreeItem *item = m_form->objectTree()->lookup(it.key());
956 if(item && item->widget())
957 {
958 item->widget()->reparent(parent->widget(), TQPoint(0,0), true);
959 item->eventEater()->setContainer(parent->container());
960 if(m_pos[it.key()].isValid())
961 item->widget()->setGeometry(m_pos[it.key()]);
962 m_form->objectTree()->reparent(item->name(), m_containername);
963 }
964 }
965
966 if(!parent->container())
967 return;
968 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_name);
969 if (!titem)
970 return; //better this than a crash
971 TQWidget *w = titem->widget();
972 parent->container()->deleteWidget(w); // delete the layout widget
973 FormManager::self()->windowChanged(m_form->widget()); // to reload ObjectTreeView
974}
975
976TQString
977CreateLayoutCommand::name() const
978{
979 switch(m_type)
980 {
981 case Container::HBox:
982 return i18n("Group Widgets Horizontally");
983 case Container::VBox:
984 return i18n("Group Widgets Vertically");
985 case Container::Grid:
986 return i18n("Group Widgets in a Grid");
987 case Container::HSplitter:
988 return i18n("Group Widgets Horizontally in a Splitter");
989 case Container::VSplitter:
990 return i18n("Group Widgets Vertically in a Splitter");
991 case Container::HFlow:
992 return i18n("Group Widgets By Rows");
993 case Container::VFlow:
994 return i18n("Group Widgets Vertically By Columns");
995 default:
996 return i18n("Group widgets");
997 }
998}
999
1000void
1001CreateLayoutCommand::debug()
1002{
1003 kdDebug() << "CreateLayoutCommand: name=\"" << name() << "\" generatedName=" << m_name
1004 << " widgets=" << m_pos.keys() << " container=" << m_containername
1005 << " form=" << m_form->widget()->name() << endl;
1006}
1007
1009
1012{
1013 m_containername = container->toplevel()->widget()->name();
1014 m_name = container->widget()->name();
1015 m_form = container->form();
1016 m_type = container->layoutType();
1017
1018 for(ObjectTreeItem *tree = container->objectTree()->children()->first(); tree; tree = container->objectTree()->children()->next())
1019 {
1020 TQRect r(container->widget()->mapTo(container->widget()->parentWidget(), tree->widget()->pos()), tree->widget()->size());
1021 m_pos.insert(tree->widget()->name(), r);
1022 }
1023}
1024
1025void
1027{
1028 CreateLayoutCommand::unexecute();
1029}
1030
1031void
1032BreakLayoutCommand::unexecute()
1033{
1035}
1036
1037TQString
1038BreakLayoutCommand::name() const
1039{
1040 return i18n("Break Layout: \"%1\"").arg(m_name);
1041}
1042
1043void
1044BreakLayoutCommand::debug()
1045{
1046 kdDebug() << "BreakLayoutCommand: name=\"" << name()
1047 << " widgets=" << m_pos.keys() << " container=" << m_containername
1048 << " form=" << m_form->widget()->name() << endl;
1049}
1050
1051// PasteWidgetCommand
1052
1053PasteWidgetCommand::PasteWidgetCommand(TQDomDocument &domDoc, Container *container, const TQPoint& p)
1054 : m_point(p)
1055{
1056 m_data = domDoc.toCString();
1057 m_containername = container->widget()->name();
1058 m_form = container->form();
1059
1060 if(domDoc.namedItem("UI").firstChild().nextSibling().toElement().tagName() != "widget")
1061 return;
1062
1063 TQRect boundingRect;
1064 for(TQDomNode n = domDoc.namedItem("UI").firstChild(); !n.isNull(); n = n.nextSibling()) // more than one widget
1065 {
1066 if(n.toElement().tagName() != "widget")
1067 continue;
1068 TQDomElement el = n.toElement();
1069
1070 TQDomElement rect;
1071 for(TQDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
1072 {
1073 if((n.toElement().tagName() == "property") && (n.toElement().attribute("name") == "geometry"))
1074 rect = n.firstChild().toElement();
1075 }
1076
1077 TQDomElement x = rect.namedItem("x").toElement();
1078 TQDomElement y = rect.namedItem("y").toElement();
1079 TQDomElement wi = rect.namedItem("width").toElement();
1080 TQDomElement h = rect.namedItem("height").toElement();
1081
1082 int rx = x.text().toInt();
1083 int ry = y.text().toInt();
1084 int rw = wi.text().toInt();
1085 int rh = h.text().toInt();
1086 TQRect r(rx, ry, rw, rh);
1087 boundingRect = boundingRect.unite(r);
1088 }
1089
1090 m_point = m_point - boundingRect.topLeft();
1091}
1092
1093void
1094PasteWidgetCommand::execute()
1095{
1096 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_containername);
1097 if (!titem)
1098 return; //better this than a crash
1099 Container *container = titem->container();
1100 TQString errMsg;
1101 int errLine;
1102 int errCol;
1103 TQDomDocument domDoc("UI");
1104 bool parsed = domDoc.setContent(m_data, false, &errMsg, &errLine, &errCol);
1105
1106 if(!parsed)
1107 {
1108 kdDebug() << "WidgetWatcher::load(): " << errMsg << endl;
1109 kdDebug() << "WidgetWatcher::load(): line: " << errLine << " col: " << errCol << endl;
1110 return;
1111 }
1112
1113 //FormIO::setCurrentForm(m_container->form());
1114
1115 kdDebug() << domDoc.toString() << endl;
1116 if(!domDoc.namedItem("UI").hasChildNodes()) // nothing in the doc
1117 return;
1118 if(domDoc.namedItem("UI").firstChild().nextSibling().toElement().tagName() != "widget") // only one widget, so we can paste it at cursor pos
1119 {
1120 TQDomElement el = domDoc.namedItem("UI").firstChild().toElement();
1121 fixNames(el);
1122 if(m_point.isNull())
1123 fixPos(el, container);
1124 else
1125 changePos(el, m_point);
1126
1127 m_form->setInteractiveMode(false);
1128 FormIO::loadWidget(container, el);
1129 m_form->setInteractiveMode(true);
1130 }
1131 else for(TQDomNode n = domDoc.namedItem("UI").firstChild(); !n.isNull(); n = n.nextSibling()) // more than one widget
1132 {
1133 if(n.toElement().tagName() != "widget")
1134 continue;
1135 TQDomElement el = n.toElement();
1136 fixNames(el);
1137 if(!m_point.isNull())
1138 moveWidgetBy(el, container, m_point);
1139 else {
1140 fixPos(el, container);
1141 kdDebug() << "jdkjfldfksmfkdfjmqdsklfjdkkfmsqfksdfsm" << endl;
1142 }
1143
1144 m_form->setInteractiveMode(false);
1145 FormIO::loadWidget(container, el);
1146 m_form->setInteractiveMode(true);
1147 }
1148
1149 //FormIO::setCurrentForm(0);
1150 m_names.clear();
1151 // We store the names of all the created widgets, to delete them later
1152 for(TQDomNode n = domDoc.namedItem("UI").firstChild(); !n.isNull(); n = n.nextSibling())
1153 {
1154 if(n.toElement().tagName() != "widget")
1155 continue;
1156 for(TQDomNode m = n.firstChild(); !m.isNull(); n = m.nextSibling())
1157 {
1158 if((m.toElement().tagName() == "property") && (m.toElement().attribute("name") == "name"))
1159 {
1160 m_names.append(m.toElement().text());
1161 break;
1162 }
1163 }
1164 }
1165
1166 container->form()->selectFormWidget();
1167 TQStringList::ConstIterator endIt = m_names.constEnd();
1168 for(TQStringList::ConstIterator it = m_names.constBegin(); it != endIt; ++it) // We select all the pasted widgets
1169 {
1170 ObjectTreeItem *item = m_form->objectTree()->lookup(*it);
1171 if(item)
1172 container->setSelectedWidget(item->widget(), true);
1173 }
1174}
1175
1176void
1177PasteWidgetCommand::unexecute()
1178{
1179 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_containername);
1180 if (!titem)
1181 return; //better this than a crash
1182 Container *container = titem->container();
1183 // We just delete all the widgets we have created
1184 TQStringList::ConstIterator endIt = m_names.constEnd();
1185 for(TQStringList::ConstIterator it = m_names.constBegin(); it != endIt; ++it)
1186 {
1187 ObjectTreeItem* titem = container->form()->objectTree()->lookup(*it);
1188 if (!titem)
1189 continue; //better this than a crash
1190 TQWidget *w = titem->widget();
1191 container->deleteWidget(w);
1192 }
1193}
1194
1195TQString
1196PasteWidgetCommand::name() const
1197{
1198 return i18n("Paste");
1199}
1200
1201void
1202//TQDomElement
1203PasteWidgetCommand::changePos(TQDomElement &el, const TQPoint &newpos)
1204{
1205 //TQDomElement el = widg.cloneNode(true).toElement();
1206 TQDomElement rect;
1207 // Find the widget geometry if there is one
1208 for(TQDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
1209 {
1210 if((n.toElement().tagName() == "property") && (n.toElement().attribute("name") == "geometry"))
1211 rect = n.firstChild().toElement();
1212 }
1213
1214 TQDomElement x = rect.namedItem("x").toElement();
1215 x.removeChild(x.firstChild());
1216 TQDomText valueX = el.ownerDocument().createTextNode(TQString::number(newpos.x()));
1217 x.appendChild(valueX);
1218
1219 TQDomElement y = rect.namedItem("y").toElement();
1220 y.removeChild(y.firstChild());
1221 TQDomText valueY = el.ownerDocument().createTextNode(TQString::number(newpos.y()));
1222 y.appendChild(valueY);
1223
1224 //return el;
1225}
1226
1227void
1228PasteWidgetCommand::fixPos(TQDomElement &el, Container *container)
1229{
1230/* TQDomElement rect;
1231 for(TQDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
1232 {
1233 if((n.toElement().tagName() == "property") && (n.toElement().attribute("name") == "geometry"))
1234 rect = n.firstChild().toElement();
1235 }
1236
1237 TQDomElement x = rect.namedItem("x").toElement();
1238 TQDomElement y = rect.namedItem("y").toElement();
1239 TQDomElement wi = rect.namedItem("width").toElement();
1240 TQDomElement h = rect.namedItem("height").toElement();
1241
1242 int rx = x.text().toInt();
1243 int ry = y.text().toInt();
1244 int rw = wi.text().toInt();
1245 int rh = h.text().toInt();
1246 TQRect r(rx, ry, rw, rh);
1247
1248 TQWidget *w = m_form->widget()->childAt(r.x() + 6, r.y() + 6, false);
1249 if(!w)
1250 return;
1251
1252 while((w->geometry() == r) && (w != 0))// there is already a widget there, with the same size
1253 {
1254 w = m_form->widget()->childAt(w->x() + 16, w->y() + 16, false);
1255 r.moveBy(10,10);
1256 }
1257
1258 // the pasted wigdet should stay inside container's boundaries
1259 if(r.x() < 0)
1260 r.moveLeft(0);
1261 else if(r.right() > container->widget()->width())
1262 r.moveLeft(container->widget()->width() - r.width());
1263
1264 if(r.y() < 0)
1265 r.moveTop(0);
1266 else if(r.bottom() > container->widget()->height())
1267 r.moveTop(container->widget()->height() - r.height());
1268
1269 if(r != TQRect(rx, ry, rw, rh))
1270 //return el;
1271 //else
1272 changePos(el, TQPoint(r.x(), r.y()));
1273*/
1274 moveWidgetBy(el, container, TQPoint(0, 0));
1275}
1276
1277void
1278PasteWidgetCommand::moveWidgetBy(TQDomElement &el, Container *container, const TQPoint &p)
1279{
1280 TQDomElement rect;
1281 for(TQDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
1282 {
1283 if((n.toElement().tagName() == "property") && (n.toElement().attribute("name") == "geometry"))
1284 rect = n.firstChild().toElement();
1285 }
1286
1287 TQDomElement x = rect.namedItem("x").toElement();
1288 TQDomElement y = rect.namedItem("y").toElement();
1289 TQDomElement wi = rect.namedItem("width").toElement();
1290 TQDomElement h = rect.namedItem("height").toElement();
1291
1292 int rx = x.text().toInt();
1293 int ry = y.text().toInt();
1294 int rw = wi.text().toInt();
1295 int rh = h.text().toInt();
1296 TQRect r(rx + p.x(), ry + p.y(), rw, rh);
1297 kdDebug() << "Moving widget by " << p << " from " << rx << " " << ry << " to " << r.topLeft() << endl;
1298
1299 TQWidget *w = m_form->widget()->childAt(r.x() + 6, r.y() + 6, false);
1300
1301 while(w && (w->geometry() == r))// there is already a widget there, with the same size
1302 {
1303 w = m_form->widget()->childAt(w->x() + 16, w->y() + 16, false);
1304 r.moveBy(10,10);
1305 }
1306
1307 // the pasted wigdet should stay inside container's boundaries
1308 if(r.x() < 0)
1309 r.moveLeft(0);
1310 else if(r.right() > container->widget()->width())
1311 r.moveLeft(container->widget()->width() - r.width());
1312
1313 if(r.y() < 0)
1314 r.moveTop(0);
1315 else if(r.bottom() > container->widget()->height())
1316 r.moveTop(container->widget()->height() - r.height());
1317
1318 if(r != TQRect(rx, ry, rw, rh))
1319 //return el;
1320 //else
1321 changePos(el, TQPoint(r.x(), r.y()));
1322}
1323
1324void
1326{
1327 TQString wname;
1328 for(TQDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
1329 {
1330 if((n.toElement().tagName() == "property") && (n.toElement().attribute("name") == "name"))
1331 {
1332 wname = n.toElement().text();
1333 while(m_form->objectTree()->lookup(wname)) // name already exists
1334 {
1335 bool ok;
1336 int num = wname.right(1).toInt(&ok, 10);
1337 if(ok)
1338 wname = wname.left(wname.length()-1) + TQString::number(num+1);
1339 else
1340 wname += "2";
1341 }
1342 if(wname != n.toElement().text()) // we change the name, so we recreate the element
1343 {
1344 n.removeChild(n.firstChild());
1345 TQDomElement type = el.ownerDocument().createElement("string");
1346 TQDomText valueE = el.ownerDocument().createTextNode(wname);
1347 type.appendChild(valueE);
1348 n.toElement().appendChild(type);
1349 }
1350
1351 }
1352 if(n.toElement().tagName() == "widget") // fix child widgets names
1353 {
1354 TQDomElement child = n.toElement();
1355 fixNames(child);
1356 }
1357 }
1358}
1359
1360void
1361PasteWidgetCommand::debug()
1362{
1363 kdDebug() << "PasteWidgetCommand: pos=" << m_point
1364 << " widgets=" << m_names << " container=" << m_containername
1365 << " form=" << m_form->widget()->name()
1366 << " data=\"" << m_data.left(80) << "...\"" << endl;
1367}
1368
1369// DeleteWidgetCommand
1370
1371DeleteWidgetCommand::DeleteWidgetCommand(WidgetList &list, Form *form)
1372 : Command(), m_form(form)
1373{
1374 m_domDoc = TQDomDocument("UI");
1375 m_domDoc.appendChild(m_domDoc.createElement("UI"));
1376
1377 TQDomElement parent = m_domDoc.namedItem("UI").toElement();
1378
1379 //for(TQWidget *w = list.first(); w; w = list.next())
1380 /*for(WidgetListIterator it(list); it.current() != 0; ++it)
1381 {
1382 TQWidget *w = it.current();
1383 // Don't delete tabwidget or widgetstack pages
1384 if(w->parentWidget()->inherits("TQWidgetStack"))
1385 {
1386 list.remove(w);
1387 continue;
1388 }
1389 }*/
1391
1392 for(WidgetListIterator it(list); it.current() != 0; ++it)
1393 {
1394 ObjectTreeItem *item = m_form->objectTree()->lookup(it.current()->name());
1395 if (!item)
1396 return;
1397
1398 // We need to store both parentContainer and parentWidget as they may be different (eg for TabWidget page)
1399 m_containers.insert(item->name().latin1(), m_form->parentContainer(item->widget())->widget()->name());
1400 m_parents.insert(item->name().latin1(), item->parent()->name().latin1());
1401 FormIO::saveWidget(item, parent, m_domDoc);
1402 form->connectionBuffer()->saveAllConnectionsForWidget(item->widget()->name(), m_domDoc);
1403 }
1404
1405 FormIO::cleanClipboard(parent);
1406}
1407
1408void
1409DeleteWidgetCommand::execute()
1410{
1411 Container *containerToSelect = 0;
1412
1413 TQMap<TQCString,TQCString>::ConstIterator endIt = m_containers.constEnd();
1414 for(TQMap<TQCString,TQCString>::ConstIterator it = m_containers.constBegin(); it != endIt; ++it)
1415 {
1416 ObjectTreeItem *item = m_form->objectTree()->lookup(it.key());
1417 if (!item || !item->widget())
1418 continue;
1419
1420 Container *cont = m_form->parentContainer(item->widget());
1421 if (!containerToSelect)
1422 containerToSelect = cont;
1423 cont->deleteWidget(item->widget());
1424 }
1425 //now we've nothing selecte: select parent container
1426 if (containerToSelect)
1427 m_form->setSelectedWidget( containerToSelect->widget() );
1428}
1429
1430void
1431DeleteWidgetCommand::unexecute()
1432{
1433 TQCString wname;
1434 m_form->setInteractiveMode(false);
1435 for(TQDomNode n = m_domDoc.namedItem("UI").firstChild(); !n.isNull(); n = n.nextSibling())
1436 {
1437 if(n.toElement().tagName() == "connections") // restore the widget connections
1438 m_form->connectionBuffer()->load(n);
1439 if(n.toElement().tagName() != "widget")
1440 continue;
1441 // We need first to know the name of the widget
1442 for(TQDomNode m = n.firstChild(); !m.isNull(); n = m.nextSibling())
1443 {
1444 if((m.toElement().tagName() == "property") && (m.toElement().attribute("name") == "name"))
1445 {
1446 wname = m.toElement().text().latin1();
1447 break;
1448 }
1449 }
1450
1451 ObjectTreeItem* titem = m_form->objectTree()->lookup(m_containers[wname]);
1452 if (!titem)
1453 return; //better this than a crash
1454 Container *cont = titem->container();
1455 ObjectTreeItem *parent = m_form->objectTree()->lookup(m_parents[wname]);
1456 TQDomElement widg = n.toElement();
1457 if(parent)
1458 FormIO::loadWidget(cont, widg, parent->widget());
1459 else
1460 FormIO::loadWidget(cont, widg);
1461 }
1462 m_form->setInteractiveMode(true);
1463}
1464
1465TQString
1466DeleteWidgetCommand::name() const
1467{
1468 return i18n("Delete widget");
1469}
1470
1471void
1472DeleteWidgetCommand::debug()
1473{
1474 kdDebug() << "DeleteWidgetCommand: containers=" << m_containers.keys()
1475 << " parents=" << m_parents.keys() << " form=" << m_form->widget()->name() << endl;
1476}
1477
1478// CutWidgetCommand
1479
1480CutWidgetCommand::CutWidgetCommand(WidgetList &list, Form *form)
1481 : DeleteWidgetCommand(list, form)
1482{}
1483
1484void
1485CutWidgetCommand::execute()
1486{
1487 DeleteWidgetCommand::execute();
1488 m_data = FormManager::self()->m_domDoc.toCString();
1489 FormManager::self()->m_domDoc.setContent(m_domDoc.toCString());
1490}
1491
1492void
1493CutWidgetCommand::unexecute()
1494{
1495 DeleteWidgetCommand::unexecute();
1496 FormManager::self()->m_domDoc.setContent(m_data);
1497}
1498
1499TQString
1500CutWidgetCommand::name() const
1501{
1502 return i18n("Cut");
1503}
1504
1505void
1506CutWidgetCommand::debug()
1507{
1508 kdDebug() << "CutWidgetCommand: containers=" << m_containers.keys()
1509 << " parents=" << m_parents.keys() << " form=" << m_form->widget()->name()
1510 << " data=\"" << m_data.left(80) << "...\"" << endl;
1511}
1512
1513// CommandGroup
1514
1515namespace KFormDesigner {
1516class CommandGroup::SubCommands : public KMacroCommand
1517{
1518 public:
1519 SubCommands( const TQString & name )
1520 : KMacroCommand(name)
1521 {
1522 }
1523 const TQPtrList<KCommand>& commands() const { return m_commands; }
1524};
1525}
1526
1527CommandGroup::CommandGroup( const TQString & name, WidgetPropertySet *propSet )
1528 : Command()
1529 , m_subCommands(new SubCommands(name))
1530 , m_propSet(propSet)
1531{
1532}
1533
1534CommandGroup::~CommandGroup()
1535{
1536 delete m_subCommands;
1537}
1538
1539const TQPtrList<KCommand>& CommandGroup::commands() const
1540{
1541 return m_subCommands->commands();
1542}
1543
1544void CommandGroup::addCommand(KCommand *command, bool allowExecute)
1545{
1546 if (!command)
1547 return;
1548
1549 m_subCommands->addCommand(command);
1550 if (!allowExecute)
1551 m_commandsShouldntBeExecuted.insert(command, (char*)1);
1552}
1553
1555{
1556 FormManager::self()->blockPropertyEditorUpdating(this);
1557 for (TQPtrListIterator<KCommand> it(m_subCommands->commands()); it.current(); ++it) {
1558 if (!m_commandsShouldntBeExecuted[it.current()])
1559 it.current()->execute();
1560 }
1561 FormManager::self()->unblockPropertyEditorUpdating(this, m_propSet);
1562}
1563
1565{
1566 FormManager::self()->blockPropertyEditorUpdating(this);
1567 m_subCommands->unexecute();
1568 FormManager::self()->unblockPropertyEditorUpdating(this, m_propSet);
1569}
1570
1571TQString CommandGroup::name() const
1572{
1573 return m_subCommands->name();
1574}
1575
1580
1581void
1582CommandGroup::debug()
1583{
1584 kdDebug() << "*CommandGroup: name=\"" << name() << "\" #=" << m_subCommands->commands().count() << endl;
1585 uint i = 1;
1586 for (TQPtrListIterator<KCommand> it(m_subCommands->commands()); it.current(); ++it, i++) {
1587 kdDebug() << "#" << i << ":"
1588 << (m_commandsShouldntBeExecuted[it.current()] ? "!" : "") << "allowExecute:" << endl;
1589 if (dynamic_cast<Command*>(it.current()))
1590 dynamic_cast<Command*>(it.current())->debug();
1591 else if (dynamic_cast<CommandGroup*>(it.current()))
1592 dynamic_cast<CommandGroup*>(it.current())->debug();
1593 else
1594 kdDebug() << "(other KCommand)" << endl;
1595 }
1596 kdDebug() << "End of CommandGroup" << endl;
1597}
BreakLayoutCommand(Container *container)
BreakLayoutCommand ///////////////.
const TQPtrList< KCommand > & commands() const
TQPtrDict< char > m_commandsShouldntBeExecuted
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
CreateLayoutCommand(int layoutType, WidgetList &list, Form *form)
CreateLayoutCommand ///////////////.
Definition commands.cpp:847
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
static void cleanClipboard(TQDomElement &uiElement)
Definition formIO.cpp:1106
static void saveWidget(ObjectTreeItem *item, TQDomElement &parent, TQDomDocument &domDoc, bool insideGridLayout=false)
Definition formIO.cpp:912
static void loadWidget(Container *container, const TQDomElement &el, TQWidget *parent=0)
Definition formIO.cpp:1119
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
ObjectTree * objectTree() const
Definition form.h:167
TQWidget * widget() const
Definition form.cpp:114
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.
TQPtrList< TQWidget > WidgetList
A list of widget pointers.
TQPtrListIterator< TQWidget > WidgetListIterator
An iterator for WidgetList.
KFORMEDITOR_EXPORT void removeChildrenFromList(WidgetList &list)