formmanager.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
21#include <kdebug.h>
22
23#include <tqworkspace.h>
24#include <tqcursor.h>
25#include <tqstring.h>
26#include <tqlabel.h>
27#include <tqobjectlist.h>
28#include <tqstylefactory.h>
29#include <tqmetaobject.h>
30#include <tqregexp.h>
31#include <tqvaluevector.h>
32#include <tqvbox.h>
33
34#include <tdelocale.h>
35#include <kiconloader.h>
36#include <tdepopupmenu.h>
37#include <kstdaction.h>
38#include <tdeaction.h>
39#include <kxmlguiclient.h>
40#include <tdemainwindow.h>
41#include <tdemessagebox.h>
42#include <tdeconfig.h>
43#include <tdestyle.h>
44#include <tdeactionclasses.h>
45#include <tdeapplication.h>
46#include <tdeglobal.h>
47#include <tdeglobalsettings.h>
48#include <kdialogbase.h>
49#include <ktextedit.h>
50#include <ktabwidget.h>
51#include <tdefontdialog.h>
52
53#include <tdeversion.h>
54#if TDE_VERSION >= TDE_MAKE_VERSION(3,1,9) && !defined(TQ_WS_WIN)
55# include <tdeactioncollection.h>
56#endif
57
58#include "widgetpropertyset.h"
59#include "objecttree.h"
60#include "widgetlibrary.h"
61#include "form.h"
62#include "container.h"
63#include "formIO.h"
64#include "objecttreeview.h"
65#include "commands.h"
66#include "tabstopdialog.h"
67#include "connectiondialog.h"
68#include "pixmapcollection.h"
69#include "events.h"
70#include "utils.h"
71#include "kfdpixmapedit.h"
72#include <koproperty/editor.h>
73#include <koproperty/property.h>
74#include <koproperty/factory.h>
75
76#include "formmanager.h"
77
78#define KFD_NO_STYLES //disables; styles support needs improvements
79
80namespace KFormDesigner {
81
83class PropertyFactory : public KoProperty::CustomPropertyFactory
84{
85 public:
86 PropertyFactory(TQObject *parent)
87 : KoProperty::CustomPropertyFactory(parent)
88// m_manager(manager)
89 {
90 }
91 virtual ~PropertyFactory() {}
92
93 KoProperty::CustomProperty* createCustomProperty(KoProperty::Property *) { return 0;}
94
95 KoProperty::Widget* createCustomWidget(KoProperty::Property *prop)
96 {
97 return new KFDPixmapEdit(prop);
98 }
99};
100
101}
102
103using namespace KFormDesigner;
104
105static KStaticDeleter<FormManager> m_managerDeleter;
106FormManager* FormManager::_self = 0L;
107
108FormManager::FormManager(TQObject *parent, int options, const char *name)
109 : TQObject(parent, name)
111 , m_uiCodeDialog(0)
112 , m_options(options)
113#endif
114 , m_objectBlockingPropertyEditorUpdating(0)
115 , m_isRedoing(false)
116{
117 Q_UNUSED(options);
118#ifdef KEXI_STANDALONE
119 TDEGlobal::locale()->insertCatalogue("standalone_kformdesigner");
120#else
121 TDEGlobal::locale()->insertCatalogue("kformdesigner");
122#endif
123
124 connect( kapp, TQ_SIGNAL( settingsChanged(int) ), TQ_SLOT( slotSettingsChanged(int) ) );
125 slotSettingsChanged(TDEApplication::SETTINGS_SHORTCUTS);
126
127//moved to createWidgetLibrary() m_lib = new WidgetLibrary(this, supportedFactoryGroups);
128 m_propSet = new WidgetPropertySet(this);
129
130 //unused m_editor = 0;
131 m_active = 0;
132 m_inserting = false;
133 m_drawingSlot = false;
134 m_collection = 0;
135 m_connection = 0;
136 m_popup = 0;
137 m_treeview = 0;
139 m_domDoc.appendChild(m_domDoc.createElement("UI"));
140
141 m_deleteWidgetLater_list.setAutoDelete(true);
142 connect( &m_deleteWidgetLater_timer, TQ_SIGNAL(timeout()), this, TQ_SLOT(deleteWidgetLaterTimeout()));
143 connect( this, TQ_SIGNAL(connectionCreated(KFormDesigner::Form*, KFormDesigner::Connection&)),
144 this, TQ_SLOT(slotConnectionCreated(KFormDesigner::Form*, KFormDesigner::Connection&)));
145
146 // register kfd custom editors
147 KoProperty::FactoryManager::self()->registerFactoryForEditor(KoProperty::Pixmap,
148 new PropertyFactory(KoProperty::FactoryManager::self()));
149}
150
151FormManager::~FormManager()
152{
153 m_managerDeleter.setObject(_self, 0, false); //safe
154 delete m_popup;
155 delete m_connection;
156#ifdef KEXI_DEBUG_GUI
157 delete m_uiCodeDialog;
158#endif
159// delete m_propFactory;
160}
161
162
164{
165 return _self;
166}
167
169FormManager::createWidgetLibrary(FormManager* m, const TQStringList& supportedFactoryGroups)
170{
171 if(!_self)
172 m_managerDeleter.setObject( _self, m );
173 return new WidgetLibrary(_self, supportedFactoryGroups);
174}
175
176void
177FormManager::setEditor(KoProperty::Editor *editor)
178{
179 m_editor = editor;
180
181 if(editor)
182 editor->changeSet(m_propSet->set());
183}
184
185void
187{
188 m_treeview = treeview;
189 if (m_treeview)
190 connect(m_propSet, TQ_SIGNAL(widgetNameChanged(const TQCString&, const TQCString&)),
191 m_treeview, TQ_SLOT(renameItem(const TQCString&, const TQCString&)));
192}
193
194ActionList
195FormManager::createActions(WidgetLibrary *lib, TDEActionCollection* collection, KXMLGUIClient* client)
196{
197 m_collection = collection;
198
199 ActionList actions = lib->createWidgetActions(client, m_collection, this, TQ_SLOT(insertWidget(const TQCString &)));
200
201 if (m_options & HideSignalSlotConnections)
202 m_dragConnection = 0;
203 else {
204 m_dragConnection = new TDEToggleAction(i18n("Connect Signals/Slots"),
205 "signalslot", TDEShortcut(0), this, TQ_SLOT(startCreatingConnection()), m_collection,
206 "drag_connection");
207 //to be exclusive with any 'widget' action
208 m_dragConnection->setExclusiveGroup("LibActionWidgets");
209 m_dragConnection->setChecked(false);
210 actions.append(m_dragConnection);
211 }
212
213 m_pointer = new TDEToggleAction(i18n("Pointer"), "mouse_pointer", TDEShortcut(0),
214 this, TQ_SLOT(slotPointerClicked()), m_collection, "pointer");
215 m_pointer->setExclusiveGroup("LibActionWidgets"); //to be exclusive with any 'widget' action
216 m_pointer->setChecked(true);
217 actions.append(m_pointer);
218
219 m_snapToGrid = new TDEToggleAction(i18n("Snap to Grid"), TQString(), TDEShortcut(0),
220 0, 0, m_collection, "snap_to_grid");
221 m_snapToGrid->setChecked(true);
222 actions.append(m_snapToGrid);
223
224 // Create the Style selection action (with a combo box in toolbar and submenu items)
225 TDESelectAction *m_style = new TDESelectAction( i18n("Style"), TDEShortcut(0),
226 this, TQ_SLOT(slotStyle()), m_collection, "change_style");
227 m_style->setEditable(false);
228
229 TDEGlobal::config()->setGroup("General");
230 TQString currentStyle = TQString::fromLatin1(kapp->style().name()).lower();
231 const TQStringList styles = TQStyleFactory::keys();
232 m_style->setItems(styles);
233 m_style->setCurrentItem(0);
234
235 TQStringList::ConstIterator endIt = styles.constEnd();
236 int idx = 0;
237 for (TQStringList::ConstIterator it = styles.constBegin(); it != endIt; ++it, ++idx)
238 {
239 if ((*it).lower() == currentStyle) {
240 m_style->setCurrentItem(idx);
241 break;
242 }
243 }
244
245 m_style->setToolTip(i18n("Set the current view style."));
246 m_style->setMenuAccelsEnabled(true);
247 actions.append(m_style);
248
249 lib->addCustomWidgetActions(m_collection);
250
251 return actions;
252}
253
254bool
255FormManager::isPasteEnabled()
256{
257 return m_domDoc.namedItem("UI").hasChildNodes();
258}
259
260void
261FormManager::undo()
262{
263 if(!activeForm() || !activeForm()->objectTree())
264 return;
265
266 activeForm()->commandHistory()->undo();
267}
268
269void
270FormManager::redo()
271{
272 if(!activeForm() || !activeForm()->objectTree())
273 return;
274
275 m_isRedoing = true;
276 activeForm()->commandHistory()->redo();
277 m_isRedoing = false;
278}
279
280void
282{
283 if(m_drawingSlot)
285
286 m_inserting = true;
287
288 Form *form;
289 for(form = m_forms.first(); form; form = m_forms.next())
290 {
291// form->d->cursors = new TQMap<TQString, TQCursor>();
292 if (form->toplevelContainer())
293 form->widget()->setCursor(TQCursor(CrossCursor));
294 TQObjectList *l = form->widget()->queryList( "TQWidget" );
295 for(TQObject *o = l->first(); o; o = l->next())
296 {
297 if( ((TQWidget*)o)->ownCursor() )
298 {
299// form->d->cursors->insert(o->name(), ((TQWidget*)o)->cursor());
300 form->d->cursors.insert(o, static_cast<TQWidget*>(o)->cursor());
301 static_cast<TQWidget*>(o)->setCursor(TQCursor(TQt::CrossCursor));
302 }
303
304 }
305 delete l;
306 }
307
308 m_selectedClass = classname;
309 m_pointer->setChecked(false);
310}
311
312void
314{
315 if(m_drawingSlot)
317 if(!m_inserting)
318 return;
319
320//#ifndef KEXI_NO_CURSOR_PROPERTY
321 Form *form;
322 for(form = m_forms.first(); form; form = m_forms.next())
323 {
324 form->widget()->unsetCursor();
325 TQObjectList *l = form->widget()->queryList( "TQWidget" );
326 for(TQObject *o = l->first(); o; o = l->next())
327 {
328 static_cast<TQWidget*>(o)->unsetCursor();
329#if 0
330 if( ((TQWidget*)o)->ownCursor()) {
331 TQMap<TQObject*,TQCursor>::ConstIterator curIt( form->d->cursors.find(o) );
332 if (curIt!=form->d->cursors.constEnd())
333 static_cast<TQWidget*>(o)->setCursor( *curIt );
334// ((TQWidget*)o)->setCursor( (*(form->d->cursors))[o->name()] ) ;
335 }
336#endif
337 }
338 delete l;
339// delete (form->d->cursors);
340// form->d->cursors = 0;
341 }
342//#endif
343 m_inserting = false;
344 m_pointer->setChecked(true);
345}
346
347void
349{
350 if(m_inserting)
351 stopInsert();
352 else if(m_dragConnection)
354}
355
356void
358{
359 if (m_options & HideSignalSlotConnections)
360 return;
361
362 if(m_inserting)
363 stopInsert();
364
365 // We set a Pointing hand cursor while drawing the connection
366 Form *form;
367 for(form = m_forms.first(); form; form = m_forms.next())
368 {
369// form->d->cursors = new TQMap<TQString, TQCursor>();
370 form->d->mouseTrackers = new TQStringList();
371 if (form->toplevelContainer())
372 {
373 form->widget()->setCursor(TQCursor(PointingHandCursor));
374 form->widget()->setMouseTracking(true);
375 }
376 TQObjectList *l = form->widget()->queryList( "TQWidget" );
377 for(TQObject *o = l->first(); o; o = l->next())
378 {
379 TQWidget *w = static_cast<TQWidget*>(o);
380 if( w->ownCursor() )
381 {
382 form->d->cursors.insert(w, w->cursor());
383// form->d->cursors->insert(w->name(), w->cursor());
384 w->setCursor(TQCursor(PointingHandCursor ));
385 }
386 if(w->hasMouseTracking())
387 form->d->mouseTrackers->append(w->name());
388 w->setMouseTracking(true);
389 }
390 delete l;
391 }
392 delete m_connection;
393 m_connection = new Connection();
394 m_drawingSlot = true;
395 if (m_dragConnection)
396 m_dragConnection->setChecked(true);
397}
398
399void
401{
402 if (m_options & HideSignalSlotConnections)
403 return;
404
405 delete m_connection;
406 m_connection = new Connection();
407
408 if(m_active && m_active->formWidget()) {
409 Form *ff = (Form*)m_active;
410 FormWidget *fw = 0;
411 if (ff)
412 fw = ff->formWidget();
413 m_active->formWidget()->clearForm();
414 }
415 if (m_active && m_active->widget())
416 m_active->widget()->repaint();
417}
418
419void
421{
422 if (m_options & HideSignalSlotConnections)
423 return;
424 if(!m_drawingSlot)
425 return;
426
427 if(m_active && m_active->formWidget())
428 m_active->formWidget()->clearForm();
429
430 Form *form;
431 for(form = m_forms.first(); form; form = m_forms.next())
432 {
433 form->widget()->unsetCursor();
434 form->widget()->setMouseTracking(false);
435 TQObjectList *l = form->widget()->queryList( "TQWidget" );
436 for(TQObject *o = l->first(); o; o = l->next())
437 {
438 TQWidget *w = (TQWidget*)o;
439 if( w->ownCursor()) {
440 TQMap<TQObject*,TQCursor>::ConstIterator curIt( form->d->cursors.find(o) );
441 if (curIt!=form->d->cursors.constEnd())
442 static_cast<TQWidget*>(o)->setCursor( *curIt );
443 }
444// w->setCursor( (*(form->d->cursors))[o->name()] ) ;
445 w->setMouseTracking( !form->d->mouseTrackers->grep(w->name()).isEmpty() );
446 }
447 delete l;
448// delete (form->d->cursors);
449// form->d->cursors = 0;
450 delete (form->d->mouseTrackers);
451 form->d->mouseTrackers = 0;
452 }
453
454 if(m_connection->slot().isNull())
456 delete m_connection;
457 m_connection = 0;
458 m_drawingSlot = false;
459 m_pointer->setChecked(true);
460}
461
462bool
464{
465 return m_snapToGrid->isChecked();
466}
467
468void
470{
471 kdDebug() << "FormManager::windowChanged("
472 << (w ? (TQString(w->className())+" "+w->name()) : TQString("0")) << ")" << endl;
473
474 if(!w)
475 {
476 m_active = 0;
477 if(m_treeview)
478 m_treeview->setForm(0);
482
483 emitNoFormSelected();
484 return;
485 }
486
487 Form *previousActive = m_active;
488 Form *form;
489 for(form = m_forms.first(); form; form = m_forms.next())
490 {
491 if(form->toplevelContainer() && form->widget() == w)
492 {
493 if(m_treeview)
494 m_treeview->setForm(form);
495 //if(m_propSet)
496 // m_propList->setCollection(form->pixmapCollection());
497
498 kdDebug() << "FormManager::windowChanged() active form is " << form->objectTree()->name() << endl;
499
500 if(m_collection)
501 {
502#ifndef KFD_NO_STYLES
503 // update the 'style' action
504 TDESelectAction *m_style = (TDESelectAction*)m_collection->action("change_style", "TDESelectAction");
505 const TQString currentStyle = form->widget()->style().name();
506 const TQStringList styles = m_style->items();
507
508 int idx = 0;
509 TQStringList::ConstIterator endIt = styles.constEnd();
510 for (TQStringList::ConstIterator it = styles.constBegin(); it != endIt; ++it, ++idx)
511 {
512 if ((*it).lower() == currentStyle) {
513 kdDebug() << "Updating the style to " << currentStyle << endl;
514 m_style->setCurrentItem(idx);
515 break;
516 }
517 }
518#endif
519 }
520
521 if((form != previousActive) && isCreatingConnection())
523
524 m_active = form;
525
526 emit dirty(form, form->isModified());
527 // update actions state
528 m_active->emitActionSignals();
529 //update the buffer too
530 form->emitSelectionSignals();
532 showPropertySet( propertySet(), true );
533 return;
534 }
535 }
536
537 for(form = m_preview.first(); form; form = m_preview.next())
538 {
539 kdDebug() << (form->widget() ? form->widget()->name() : "") << endl;
540 if(form->toplevelContainer() && form->widget() == w) {
541 kdDebug() << "FormManager::windowChanged() active preview form is " << form->widget()->name() << endl;
542
543 if(m_collection)
544 {
545#ifndef KFD_NO_STYLES
546 // update the 'style' action
547 TDESelectAction *m_style = (TDESelectAction*)m_collection->action("change_style", "TDESelectAction");
548 const TQString currentStyle = form->widget()->style().name();
549 const TQStringList styles = m_style->items();
550
551 int idx = 0;
552 TQStringList::ConstIterator endIt = styles.constEnd();
553 for (TQStringList::ConstIterator it = styles.constBegin(); it != endIt; ++it, ++idx)
554 {
555 if ((*it).lower() == currentStyle) {
556 kdDebug() << "Updating the style to " << currentStyle << endl;
557 m_style->setCurrentItem(idx);
558 break;
559 }
560 }
561#endif
562
564 m_active = form;
565
566 emit dirty(form, false);
567 emitNoFormSelected();
569 return;
570 }
571 }
572 }
573 //m_active = 0;
574}
575
576Form*
578{
579 return m_active;
580}
581
582Form*
584{
585 for(Form *form = m_forms.first(); form; form = m_forms.next()) {
586 if(form->toplevelContainer() && form->widget() == w)
587 return form;
588 }
589
590 return 0; // not one of toplevel widgets
591}
592
593void
595{
596 if (!form)
597 return;
598 if(m_forms.find(form) == -1)
599 m_preview.remove(form);
600 else
601 m_forms.remove(form);
602
603 if(m_forms.count() == 0) {
604 m_active = 0;
606 }
607}
608
609void
610FormManager::importForm(Form *form, bool preview)
611{
612 if(!preview)
613 initForm(form);
614 else
615 {
616 m_preview.append(form);
617 form->setDesignMode(false);
618 }
619}
620
621void
623{
624 m_forms.append(form);
625
626 if(m_treeview)
627 m_treeview->setForm(form);
628
629 m_active = form;
630
631 connect(form, TQ_SIGNAL(selectionChanged(TQWidget*, bool, bool)),
632 m_propSet, TQ_SLOT(setSelectedWidgetWithoutReload(TQWidget*, bool, bool)));
633 if(m_treeview)
634 {
635 connect(form, TQ_SIGNAL(selectionChanged(TQWidget*, bool, bool)),
636 m_treeview, TQ_SLOT(setSelectedWidget(TQWidget*, bool)));
637 connect(form, TQ_SIGNAL(childAdded(ObjectTreeItem* )), m_treeview, TQ_SLOT(addItem(ObjectTreeItem*)));
638 connect(form, TQ_SIGNAL(childRemoved(ObjectTreeItem* )), m_treeview, TQ_SLOT(removeItem(ObjectTreeItem*)));
639 }
640 connect(m_propSet, TQ_SIGNAL(widgetNameChanged(const TQCString&, const TQCString&)),
641 form, TQ_SLOT(changeName(const TQCString&, const TQCString&)));
642
643 form->setSelectedWidget(form->widget());
644 windowChanged(form->widget());
645}
646
647void
648FormManager::previewForm(Form *form, TQWidget *container, Form *toForm)
649{
650 if(!form || !container || !form->objectTree())
651 return;
652 TQDomDocument domDoc;
653 if (!FormIO::saveFormToDom(form, domDoc))
654 return;
655
656 Form *myform;
657 if(!toForm)
658 myform = new Form(form->library(), form->objectTree()->name().latin1(),
659 false);
660 else
661 myform = toForm;
662 myform->createToplevel(container);
663 container->setStyle( &(form->widget()->style()) );
664
665 if (!FormIO::loadFormFromDom(myform, container, domDoc)) {
666 delete myform;
667 return;
668 }
669
670 myform->setDesignMode(false);
671 m_preview.append(myform);
672 container->show();
673}
674
675/*
676bool
677FormManager::loadFormFromDomInternal(Form *form, TQWidget *container, TQDomDocument &inBuf)
678{
679 return FormIO::loadFormFromDom(myform, container, domDoc);
680}
681
682bool
683FormManager::saveFormToStringInternal(Form *form, TQString &dest, int indent)
684{
685 return KFormDesigner::FormIO::saveFormToString(form, dest, indent);
686}*/
687
688bool
690{
691 if(!activeForm() || !activeForm()->objectTree())
692 return false;
693
694// kdDebug() << "FormManager::isTopLevel(): for: " << w->name() << " = "
695// << activeForm()->objectTree()->lookup(w->name())<< endl;
696
697 ObjectTreeItem *item = activeForm()->objectTree()->lookup(w->name());
698 if(!item)
699 return true;
700
701 return (!item->parent());
702}
703
704void
706{
707 if(!activeForm() || !activeForm()->objectTree())
708 return;
709
710 TQPtrList<TQWidget> *list = activeForm()->selectedWidgets();
711 if(list->isEmpty())
712 return;
713
714 if (activeForm()->widget() == list->first()) {
715 //toplevel form is selected, cannot delete it
716 return;
717 }
718
719 KCommand *com = new DeleteWidgetCommand(*list, activeForm());
720 activeForm()->addCommand(com, true);
721}
722
723void
725{
726 if (!activeForm() || !activeForm()->objectTree())
727 return;
728
729 TQPtrList<TQWidget> *list = activeForm()->selectedWidgets();
730 if(list->isEmpty())
731 return;
732
734
735 // We clear the current clipboard
736 m_domDoc.setContent(TQString(), true);
737 TQDomElement parent = m_domDoc.createElement("UI");
738 m_domDoc.appendChild(parent);
739
740 TQWidget *w;
741 for(w = list->first(); w; w = list->next())
742 {
743 ObjectTreeItem *it = activeForm()->objectTree()->lookup(w->name());
744 if (!it)
745 continue;
746
747 FormIO::saveWidget(it, parent, m_domDoc);
748 }
749
750 FormIO::cleanClipboard(parent);
751
752 activeForm()->emitActionSignals(); // to update 'Paste' item state
753}
754
755void
757{
758 if(!activeForm() || !activeForm()->objectTree())
759 return;
760
761 TQPtrList<TQWidget> *list = activeForm()->selectedWidgets();
762 if(list->isEmpty())
763 return;
764
765 KCommand *com = new CutWidgetCommand(*list, activeForm());
766 activeForm()->addCommand(com, true);
767}
768
769void
771{
772 if(!m_domDoc.namedItem("UI").hasChildNodes())
773 return;
774 if(!activeForm() || !activeForm()->objectTree())
775 return;
776
777 KCommand *com = new PasteWidgetCommand(m_domDoc, activeForm()->activeContainer(), m_insertPoint);
778 activeForm()->addCommand(com, true);
779}
780
781void
783{
784 m_insertPoint = p;
785}
786
787void
789{
790 m_sigSlotMenu = new TDEPopupMenu();
791 m_sigSlotMenu->insertTitle(SmallIcon("connection"), i18n("Signals"));
792
793 TQStrList list = w->metaObject()->signalNames(true);
794 TQStrListIterator it(list);
795 for(; it.current() != 0; ++it)
796 m_sigSlotMenu->insertItem(*it);
797
798 int result = m_sigSlotMenu->exec(TQCursor::pos());
799 if(result == -1)
801 else
802 menuSignalChosen(result);
803
804 delete m_sigSlotMenu;
805 m_sigSlotMenu = 0;
806}
807
808void
810{
811 m_sigSlotMenu = new TDEPopupMenu();
812 m_sigSlotMenu->insertTitle(SmallIcon("connection"), i18n("Slots"));
813
814 TQString signalArg( m_connection->signal().remove( TQRegExp(".*[(]|[)]") ) );
815
816 TQStrList list = w->metaObject()->slotNames(true);
817 TQStrListIterator it(list);
818 for(; it.current() != 0; ++it)
819 {
820 // we add the slot only if it is compatible with the signal
821 TQString slotArg(*it);
822 slotArg = slotArg.remove( TQRegExp(".*[(]|[)]") );
823 if(!signalArg.startsWith(slotArg, true)) // args not compatible
824 continue;
825
826 m_sigSlotMenu->insertItem(*it);
827 }
828
829 int result = m_sigSlotMenu->exec(TQCursor::pos());
830 if(result == -1)
832 else
833 menuSignalChosen(result);
834
835 delete m_sigSlotMenu;
836 m_sigSlotMenu = 0;
837}
838
839void
841{
842 if(!activeForm() || !activeForm()->widget())
843 return;
844 const bool toplevelWidgetSelected = activeForm()->widget() == w;
845 const uint widgetsCount = container->form()->selectedWidgets()->count();
846 const bool multiple = widgetsCount > 1;
847 //const bool enableRemove = w != m_active->widget();
848 // We only enablelayout creation if more than one widget with the same parent are selected
849 const bool enableLayout = multiple || w == container->widget();
850
851 m_menuWidget = w;
852 TQString n = container->form()->library()->displayName(w->className());
853// TQValueVector<int> menuIds();
854
855 if (!m_popup) {
856 m_popup = new TDEPopupMenu();
857 }
858 else {
859 m_popup->clear();
860 }
861
862 //set title
863 if(!multiple)
864 {
865 if(w == container->form()->widget())
866 m_popup->insertTitle(SmallIcon("form"), i18n("%1 : Form").arg(w->name()) );
867 else
868 m_popup->insertTitle( SmallIcon(
869 container->form()->library()->iconName(w->className())), TQString(w->name()) + " : " + n );
870 }
871 else
872 m_popup->insertTitle(SmallIcon("multiple_obj"), i18n("Multiple Widgets")
873 + TQString(" (%1)").arg(widgetsCount));
874
875 TDEAction *a;
876#define PLUG_ACTION(_name, forceVisible) \
877 { a = action(_name); \
878 if (a && (forceVisible || a->isEnabled())) { \
879 if (separatorNeeded) \
880 m_popup->insertSeparator(); \
881 separatorNeeded = false; \
882 a->plug(m_popup); \
883 } \
884 }
885
886 bool separatorNeeded = false;
887
888 PLUG_ACTION("edit_cut", !toplevelWidgetSelected);
889 PLUG_ACTION("edit_copy", !toplevelWidgetSelected);
890 PLUG_ACTION("edit_paste", true);
891 PLUG_ACTION("edit_delete", !toplevelWidgetSelected);
892 separatorNeeded = true;
893 PLUG_ACTION("layout_menu", enableLayout);
894 PLUG_ACTION("break_layout", enableLayout);
895 separatorNeeded = true;
896 PLUG_ACTION("align_menu", !toplevelWidgetSelected);
897 PLUG_ACTION("adjust_size_menu", !toplevelWidgetSelected);
898 separatorNeeded = true;
899
900 // We create the buddy menu
901 if(!multiple && w->inherits("TQLabel") && ((TQLabel*)w)->text().contains("&") && (((TQLabel*)w)->textFormat() != RichText))
902 {
903 if (separatorNeeded)
904 m_popup->insertSeparator();
905
906 TDEPopupMenu *sub = new TDEPopupMenu(w);
907 TQWidget *buddy = ((TQLabel*)w)->buddy();
908
909 sub->insertItem(i18n("No Buddy"), MenuNoBuddy);
910 if(!buddy)
911 sub->setItemChecked(MenuNoBuddy, true);
912 sub->insertSeparator();
913
914 // add all the widgets that can have focus
915 for(ObjectTreeListIterator it( container->form()->tabStopsIterator() ); it.current(); ++it)
916 {
917 int index = sub->insertItem(
918 SmallIcon(container->form()->library()->iconName(it.current()->className().latin1())),
919 it.current()->name());
920 if(it.current()->widget() == buddy)
921 sub->setItemChecked(index, true);
922 }
923
924 /*int id =*/ m_popup->insertItem(i18n("Choose Buddy..."), sub);
925// menuIds->append(id);
926 connect(sub, TQ_SIGNAL(activated(int)), this, TQ_SLOT(buddyChosen(int)));
927
928 separatorNeeded = true;
929 }
930
931 //int sigid=0;
932#ifdef KEXI_DEBUG_GUI
933 if(!multiple && !(m_options & HideEventsInPopupMenu))
934 {
935 if (separatorNeeded)
936 m_popup->insertSeparator();
937
938 // We create the signals menu
939 TDEPopupMenu *sigMenu = new TDEPopupMenu();
940 TQStrList list = w->metaObject()->signalNames(true);
941 TQStrListIterator it(list);
942 for(; it.current() != 0; ++it)
943 sigMenu->insertItem(*it);
944
945 int id = m_popup->insertItem(SmallIconSet(""), i18n("Events"), sigMenu);
946// menuIds->append(id);
947 if(list.isEmpty())
948 m_popup->setItemEnabled(id, false);
949 connect(sigMenu, TQ_SIGNAL(activated(int)), this, TQ_SLOT(menuSignalChosen(int)));
950 separatorNeeded = true;
951 }
952#endif
953
954 // Other items
955 if(!multiple)
956 {
957 int lastID = -1;
958 if (separatorNeeded) {
959 lastID = m_popup->insertSeparator();
960 }
961 const uint oldIndex = m_popup->count()-1;
962 container->form()->library()->createMenuActions(w->className(), w, m_popup, container);
963 if (oldIndex == (m_popup->count()-1)) {
964// for (uint i=oldIndex; i<m_popup->count(); i++) {
965// int id = m_popup->idAt( i );
966// if (id!=-1)
967// menuIds->append( id );
968// }
969 //nothing added
970 if (separatorNeeded) {
971 m_popup->removeItem( lastID );
972// menuIds->pop_back();
973 }
974 }
975 }
976
977 //show the popup at the selected widget
978 TQPoint popupPos;
979 if (popupAtCursor) {
980 popupPos = TQCursor::pos();
981 }
982 else {
983 WidgetList *lst = container->form()->selectedWidgets();
984 TQWidget * sel_w = lst ? lst->first() : container->form()->selectedWidget();
985 popupPos = sel_w ? sel_w->mapToGlobal(TQPoint(sel_w->width()/2, sel_w->height()/2)) : TQCursor::pos();
986 }
987 m_insertPoint = container->widget()->mapFromGlobal(popupPos);
988 m_popup->exec(popupPos);//TQCursor::pos());
989 m_insertPoint = TQPoint();
990
991// TQValueVector<int>::iterator it;
992// for(it = menuIds->begin(); it != menuIds->end(); ++it)
993// m_popup->removeItem(*it);
994}
995
996void
998{
999 if(!m_menuWidget)
1000 return;
1001 TQLabel *label = static_cast<TQLabel*>((TQWidget*)m_menuWidget);
1002
1003 if(id == MenuNoBuddy)
1004 {
1005 label->setBuddy(0);
1006 return;
1007 }
1008
1009 ObjectTreeItem *item = activeForm()->objectTree()->lookup(m_popup->text(id));
1010 if(!item || !item->widget())
1011 return;
1012 label->setBuddy(item->widget());
1013}
1014
1015void
1017{
1018 if (m_options & HideSignalSlotConnections)
1019 return;
1020
1021 //if(!m_menuWidget)
1022 // return;
1023 if(m_drawingSlot && m_sigSlotMenu)
1024 {
1025 if( m_connection->receiver().isNull() )
1026 m_connection->setSignal(m_sigSlotMenu->text(id));
1027 else
1028 {
1029 m_connection->setSlot(m_sigSlotMenu->text(id));
1030 kdDebug() << "Finished creating the connection: sender=" << m_connection->sender() << "; signal=" << m_connection->signal() <<
1031 "; receiver=" << m_connection->receiver() << "; slot=" << m_connection->slot() << endl;
1032 emit connectionCreated(activeForm(), *m_connection);
1034 }
1035 }
1036 else if(m_menuWidget)
1037 emit createFormSlot(m_active, m_menuWidget->name(), m_popup->text(id));
1038}
1039
1040void
1041FormManager::slotConnectionCreated(Form *form, Connection &connection)
1042{
1043 if (m_options & HideSignalSlotConnections)
1044 return;
1045 if(!form)
1046 return;
1047
1048 Connection *c = new Connection(connection);
1049 form->connectionBuffer()->append(c);
1050}
1051
1052void
1054{
1055 createLayout(Container::HBox);
1056}
1057
1058void
1060{
1061 createLayout(Container::VBox);
1062}
1063
1064void
1066{
1067 createLayout(Container::Grid);
1068}
1069
1070void
1072{
1073 createLayout(Container::HSplitter);
1074}
1075
1076void
1078{
1079 createLayout(Container::VSplitter);
1080}
1081
1082void
1084{
1085 createLayout(Container::HFlow);
1086}
1087
1088void
1090{
1091 createLayout(Container::VFlow);
1092}
1093
1094void
1096{
1097 WidgetList *list = m_active->selectedWidgets();
1098 // if only one widget is selected (a container), we modify its layout
1099 if (list->isEmpty()) {//sanity check
1100 kdWarning() << "FormManager::createLayout(): list is empty!" << endl;
1101 return;
1102 }
1103 if(list->count() == 1)
1104 {
1105 ObjectTreeItem *item = m_active->objectTree()->lookup(list->first()->name());
1106 if(!item || !item->container() || !m_propSet->contains("layout"))
1107 return;
1108 (*m_propSet)["layout"] = Container::layoutTypeToString(layoutType);
1109 return;
1110 }
1111
1112 TQWidget *parent = list->first()->parentWidget();
1113 for(TQWidget *w = list->first(); w; w = list->next())
1114 {
1115 kdDebug() << "comparing widget " << w->name() << " whose parent is " << w->parentWidget()->name() << " insteaed of " << parent->name() << endl;
1116 if(w->parentWidget() != parent)
1117 {
1118 KMessageBox::sorry(m_active->widget()->topLevelWidget(), i18n("<b>Cannot create the layout.</b>\n"
1119 "All selected widgets must have the same parent."));
1120 kdDebug() << "FormManager::createLayout() widgets don't have the same parent widget" << endl;
1121 return;
1122 }
1123 }
1124
1125 KCommand *com = new CreateLayoutCommand(layoutType, *list, m_active);
1126 m_active->addCommand(com, true);
1127}
1128
1129void
1131{
1132 if(!activeForm() || !activeForm()->objectTree())
1133 return;
1134
1135 Container *container = activeForm()->activeContainer();
1136 TQCString c( container->widget()->className() );
1137
1138 if((c == "Grid") || (c == "VBox") || (c == "HBox") || (c == "HFlow") || (c == "VFlow"))
1139 {
1140 KCommand *com = new BreakLayoutCommand(container);
1141 m_active->addCommand(com, true);
1142 }
1143 else // normal container
1144 {
1145 if(activeForm()->selectedWidgets()->count() == 1)
1146 (*m_propSet)["layout"] = "NoLayout";
1147 else
1148 container->setLayout(Container::NoLayout);
1149 }
1150}
1151
1152void
1153FormManager::showPropertySet(WidgetPropertySet *set, bool forceReload, const TQCString& propertyToSelect)
1154{
1155 if (m_objectBlockingPropertyEditorUpdating)
1156 return;
1157
1158/*unused if(m_editor) {
1159 if (propertyToSelect.isEmpty() && forceReload)
1160 m_editor->changeSet(set ? set->set() : 0, propertyToSelect);
1161 else
1162 m_editor->changeSet(set ? set->set() : 0);
1163 }*/
1164
1165 emit propertySetSwitched(set ? set->set(): 0, /*preservePrevSelection*/forceReload, propertyToSelect);
1166}
1167
1168void
1169FormManager::blockPropertyEditorUpdating(void *blockingObject)
1170{
1171 if (!blockingObject || m_objectBlockingPropertyEditorUpdating)
1172 return;
1173 m_objectBlockingPropertyEditorUpdating = blockingObject;
1174}
1175
1176void
1177FormManager::unblockPropertyEditorUpdating(void *blockingObject, WidgetPropertySet *set)
1178{
1179 if (!blockingObject || m_objectBlockingPropertyEditorUpdating!=blockingObject)
1180 return;
1181
1182 m_objectBlockingPropertyEditorUpdating = 0;
1183 showPropertySet(set, true/*forceReload*/);
1184}
1185
1186void
1188{
1189 if(!activeForm() || !activeForm()->objectTree())
1190 return;
1191 TQWidget *topLevel = m_active->widget()->topLevelWidget();
1193 //const bool oldAutoTabStops = m_active->autoTabStops();
1194 if (dlg.exec(m_active) == TQDialog::Accepted) {
1195 //inform about changing "autoTabStop" property
1196 // -- this will be received eg. by Kexi, so custom "autoTabStop" property can be updated
1197 emit autoTabStopsSet(m_active, dlg.autoTabStops());
1198 //force set dirty
1199 emit dirty(m_active, true);
1200 }
1201}
1202
1203void
1205{
1206 if(!activeForm())
1207 return;
1208
1209 TDESelectAction *m_style = (TDESelectAction*)m_collection->action("change_style", "TDESelectAction");
1210 TQString style = m_style->currentText();
1211 activeForm()->widget()->setStyle( style );
1212
1213 TQObjectList *l = activeForm()->widget()->queryList( "TQWidget" );
1214 for(TQObject *o = l->first(); o; o = l->next())
1215 (static_cast<TQWidget*>(o))->setStyle( style );
1216 delete l;
1217}
1218
1219void
1221{
1222 if(!activeForm() || !activeForm()->objectTree())
1223 return;
1224
1225 PixmapCollectionEditor dialog(activeForm()->pixmapCollection(), activeForm()->widget()->topLevelWidget());
1226 dialog.exec();
1227}
1228
1229void
1231{
1232 if (m_options & HideSignalSlotConnections)
1233 return;
1234 if(!activeForm() || !activeForm()->objectTree())
1235 return;
1236
1238 dialog.exec(activeForm());
1239}
1240
1241void
1243{
1244 if(!activeForm() || !activeForm()->objectTree() || (activeForm()->selectedWidgets()->count() < 2))
1245 return;
1246
1247 TQWidget *parentWidget = activeForm()->selectedWidgets()->first()->parentWidget();
1248
1249 for(TQWidget *w = activeForm()->selectedWidgets()->first(); w; w = activeForm()->selectedWidgets()->next())
1250 {
1251 if(w->parentWidget() != parentWidget)
1252 {
1253 kdDebug() << "FormManager::alignWidgets() type ==" << type << " widgets don't have the same parent widget" << endl;
1254 return;
1255 }
1256 }
1257
1258 KCommand *com = new AlignWidgetsCommand(type, *(activeForm()->selectedWidgets()), activeForm());
1259 activeForm()->addCommand(com, true);
1260}
1261
1262void
1263FormManager::alignWidgetsToLeft()
1264{
1265 alignWidgets(AlignWidgetsCommand::AlignToLeft);
1266}
1267
1268void
1269FormManager::alignWidgetsToRight()
1270{
1271 alignWidgets(AlignWidgetsCommand::AlignToRight);
1272}
1273
1274void
1275FormManager::alignWidgetsToTop()
1276{
1277 alignWidgets(AlignWidgetsCommand::AlignToTop);
1278}
1279
1280void
1281FormManager::alignWidgetsToBottom()
1282{
1283 alignWidgets(AlignWidgetsCommand::AlignToBottom);
1284}
1285
1286void
1288{
1289 if(!activeForm() || !activeForm()->objectTree())
1290 return;
1291
1292 KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToFit, *(activeForm()->selectedWidgets()), activeForm());
1293 activeForm()->addCommand(com, true);
1294}
1295
1296void
1297FormManager::alignWidgetsToGrid()
1298{
1299 if(!activeForm() || !activeForm()->objectTree())
1300 return;
1301
1302 KCommand *com = new AlignWidgetsCommand(AlignWidgetsCommand::AlignToGrid, *(activeForm()->selectedWidgets()), activeForm());
1303 activeForm()->addCommand(com, true);
1304}
1305
1306void
1307FormManager::adjustSizeToGrid()
1308{
1309 if(!activeForm() || !activeForm()->objectTree())
1310 return;
1311
1312 KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToGrid, *(activeForm()->selectedWidgets()), activeForm());
1313 activeForm()->addCommand(com, true);
1314}
1315
1316void
1318{
1319 if(!activeForm() || !activeForm()->objectTree())
1320 return;
1321
1322 KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToSmallWidth, *(activeForm()->selectedWidgets()), activeForm());
1323 activeForm()->addCommand(com, true);
1324}
1325
1326void
1328{
1329 if(!activeForm() || !activeForm()->objectTree())
1330 return;
1331
1332 KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToBigWidth, *(activeForm()->selectedWidgets()), activeForm());
1333 activeForm()->addCommand(com, true);
1334}
1335
1336void
1338{
1339 if(!activeForm() || !activeForm()->objectTree())
1340 return;
1341
1342 KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToSmallHeight, *(activeForm()->selectedWidgets()), activeForm());
1343 activeForm()->addCommand(com, true);
1344}
1345
1346void
1348{
1349 if(!activeForm() || !activeForm()->objectTree())
1350 return;
1351
1352 KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToBigHeight, *(activeForm()->selectedWidgets()), activeForm());
1353 activeForm()->addCommand(com, true);
1354}
1355
1356void
1357FormManager::bringWidgetToFront()
1358{
1359 if(!activeForm() || !activeForm()->objectTree())
1360 return;
1361
1362 for(TQWidget *w = activeForm()->selectedWidgets()->first(); w; w = activeForm()->selectedWidgets()->next())
1363 w->raise();
1364}
1365
1366void
1367FormManager::sendWidgetToBack()
1368{
1369 if(!activeForm() || !activeForm()->objectTree())
1370 return;
1371
1372 for(TQWidget *w = activeForm()->selectedWidgets()->first(); w; w = activeForm()->selectedWidgets()->next())
1373 w->lower();
1374}
1375
1376void
1378{
1379 if(!activeForm() || !activeForm()->objectTree())
1380 return;
1381
1383 uint count = activeForm()->objectTree()->children()->count();
1384 for(ObjectTreeItem *it = activeForm()->objectTree()->children()->first(); it;
1385 it = activeForm()->objectTree()->children()->next(), count--)
1386 {
1387 activeForm()->setSelectedWidget(it->widget(), /*add*/true, /*raise*/false, /*moreWillBeSelected*/count>1);
1388 }
1389}
1390
1391void
1393{
1394 if(!activeForm() || !activeForm()->objectTree())
1395 return;
1396
1397 for(TQWidget *w = activeForm()->selectedWidgets()->first(); w; w = activeForm()->selectedWidgets()->next())
1398 activeForm()->library()->clearWidgetContent(w->className(), w);
1399}
1400
1401void
1403{
1404 w->hide();
1405 w->reparent(0, WType_TopLevel, TQPoint(0,0));
1406 m_deleteWidgetLater_list.append( w );
1407 m_deleteWidgetLater_timer.start( 100, true );
1408}
1409
1410void
1411FormManager::deleteWidgetLaterTimeout()
1412{
1413 m_deleteWidgetLater_list.clear();
1414}
1415
1416void
1418{
1419#ifdef KEXI_DEBUG_GUI
1420 if(!activeForm())
1421 return;
1422
1423 TQString uiCode;
1424 if (!FormIO::saveFormToString(activeForm(), uiCode, 3)) {
1426 return;
1427 }
1428
1429 if (!m_uiCodeDialog) {
1430 m_uiCodeDialog = new KDialogBase(0, "uiwindow", true, i18n("Form's UI Code"),
1431 KDialogBase::Close, KDialogBase::Close);
1432 m_uiCodeDialog->resize(700, 600);
1433 TQVBox *box = m_uiCodeDialog->makeVBoxMainWidget();
1434 KTabWidget* tab = new KTabWidget(box);
1435
1436 m_currentUICodeDialogEditor = new KTextEdit(TQString(), TQString(), tab);
1437 tab->addTab( m_currentUICodeDialogEditor, i18n("Current"));
1438 m_currentUICodeDialogEditor->setReadOnly(true);
1439 TQFont f( m_currentUICodeDialogEditor->font() );
1440 f.setFamily("courier");
1441 m_currentUICodeDialogEditor->setFont(f);
1442 m_currentUICodeDialogEditor->setTextFormat(TQt::PlainText);
1443
1444 m_originalUICodeDialogEditor = new KTextEdit(TQString(), TQString(), tab);
1445 tab->addTab( m_originalUICodeDialogEditor, i18n("Original"));
1446 m_originalUICodeDialogEditor->setReadOnly(true);
1447 m_originalUICodeDialogEditor->setFont(f);
1448 m_originalUICodeDialogEditor->setTextFormat(TQt::PlainText);
1449 }
1451 //indent and set our original doc as well:
1452 TQDomDocument doc;
1453 doc.setContent( activeForm()->m_recentlyLoadedUICode );
1454 m_originalUICodeDialogEditor->setText( doc.toString( 3 ) );
1455 m_uiCodeDialog->show();
1456#endif
1457}
1458
1459void
1460FormManager::slotSettingsChanged(int category)
1461{
1462 if (category==TDEApplication::SETTINGS_SHORTCUTS) {
1463 m_contextMenuKey = TDEGlobalSettings::contextMenuKey();
1464 }
1465}
1466
1467void
1468FormManager::emitWidgetSelected( KFormDesigner::Form* form, bool multiple )
1469{
1470 enableFormActions();
1471 // Enable edit actions
1472 enableAction("edit_copy", true);
1473 enableAction("edit_cut", true);
1474 enableAction("edit_delete", true);
1475 enableAction("clear_contents", true);
1476
1477 // 'Align Widgets' menu
1478 enableAction("align_menu", multiple);
1479 enableAction("align_to_left", multiple);
1480 enableAction("align_to_right", multiple);
1481 enableAction("align_to_top", multiple);
1482 enableAction("align_to_bottom", multiple);
1483
1484 enableAction("adjust_size_menu", true);
1485 enableAction("adjust_width_small", multiple);
1486 enableAction("adjust_width_big", multiple);
1487 enableAction("adjust_height_small", multiple);
1488 enableAction("adjust_height_big", multiple);
1489
1490 enableAction("format_raise", true);
1491 enableAction("format_lower", true);
1492
1493 WidgetList *wlist = form->selectedWidgets();
1494 bool fontEnabled = false;
1495 for (WidgetListIterator it(*wlist); it.current(); ++it) {
1496 if (-1 != it.current()->metaObject()->findProperty("font", true)) {
1497 fontEnabled = true;
1498 break;
1499 }
1500 }
1501 enableAction("format_font", fontEnabled);
1502
1503 // If the widgets selected is a container, we enable layout actions
1504 bool containerSelected = false;
1505 if(!multiple)
1506 {
1508 if (form->selectedWidgets()->first())
1509 form->objectTree()->lookup( form->selectedWidgets()->first()->name() );
1510 if(item && item->container())
1511 containerSelected = true;
1512 }
1513 const bool twoSelected = form->selectedWidgets()->count()==2;
1514 // Layout actions
1515 enableAction("layout_menu", multiple || containerSelected);
1516 enableAction("layout_hbox", multiple || containerSelected);
1517 enableAction("layout_vbox", multiple || containerSelected);
1518 enableAction("layout_grid", multiple || containerSelected);
1519 enableAction("layout_hsplitter", twoSelected);
1520 enableAction("layout_vsplitter", twoSelected);
1521
1523 if (container)
1524 enableAction("break_layout", (container->layoutType() != KFormDesigner::Container::NoLayout));
1525
1526 emit widgetSelected(form, true);
1527}
1528
1529void
1530FormManager::emitFormWidgetSelected( KFormDesigner::Form* form )
1531{
1532// disableWidgetActions();
1533 enableAction("edit_copy", false);
1534 enableAction("edit_cut", false);
1535 enableAction("edit_delete", false);
1536 enableAction("clear_contents", false);
1537
1538 // Disable format functions
1539 enableAction("align_menu", false);
1540 enableAction("align_to_left", false);
1541 enableAction("align_to_right", false);
1542 enableAction("align_to_top", false);
1543 enableAction("align_to_bottom", false);
1544 enableAction("adjust_size_menu", false);
1545 enableAction("format_raise", false);
1546 enableAction("format_lower", false);
1547
1548 enableAction("format_font", false);
1549
1550 enableFormActions();
1551
1552 const bool twoSelected = form->selectedWidgets()->count()==2;
1553 const bool hasChildren = !form->objectTree()->children()->isEmpty();
1554
1555 // Layout actions
1556 enableAction("layout_menu", hasChildren);
1557 enableAction("layout_hbox", hasChildren);
1558 enableAction("layout_vbox", hasChildren);
1559 enableAction("layout_grid", hasChildren);
1560 enableAction("layout_hsplitter", twoSelected);
1561 enableAction("layout_vsplitter", twoSelected);
1562 enableAction("break_layout", (form->toplevelContainer()->layoutType() != KFormDesigner::Container::NoLayout));
1563
1564 emit formWidgetSelected( form );
1565}
1566
1567void
1568FormManager::emitNoFormSelected()
1569{
1570 disableWidgetActions();
1571
1572 // Disable edit actions
1573// enableAction("edit_paste", false);
1574// enableAction("edit_undo", false);
1575// enableAction("edit_redo", false);
1576
1577 // Disable 'Tools' actions
1578 enableAction("pixmap_collection", false);
1579 if (!(m_options & HideSignalSlotConnections))
1580 enableAction("form_connections", false);
1581 enableAction("taborder", false);
1582 enableAction("change_style", activeForm()!=0);
1583
1584 // Disable items in 'File'
1585 if (!(m_options & SkipFileActions)) {
1586 enableAction("file_save", false);
1587 enableAction("file_save_as", false);
1588 enableAction("preview_form", false);
1589 }
1590
1592}
1593
1594void
1595FormManager::enableFormActions()
1596{
1597 // Enable 'Tools' actions
1598 enableAction("pixmap_collection", true);
1599 if (!(m_options & HideSignalSlotConnections))
1600 enableAction("form_connections", true);
1601 enableAction("taborder", true);
1602 enableAction("change_style", true);
1603
1604 // Enable items in 'File'
1605 if (!(m_options & SkipFileActions)) {
1606 enableAction("file_save", true);
1607 enableAction("file_save_as", true);
1608 enableAction("preview_form", true);
1609 }
1610
1611 enableAction("edit_paste", isPasteEnabled());
1612 enableAction("edit_select_all", true);
1613}
1614
1615void
1616FormManager::disableWidgetActions()
1617{
1618 // Disable edit actions
1619 enableAction("edit_copy", false);
1620 enableAction("edit_cut", false);
1621 enableAction("edit_delete", false);
1622 enableAction("clear_contents", false);
1623
1624 // Disable format functions
1625 enableAction("align_menu", false);
1626 enableAction("align_to_left", false);
1627 enableAction("align_to_right", false);
1628 enableAction("align_to_top", false);
1629 enableAction("align_to_bottom", false);
1630 enableAction("adjust_size_menu", false);
1631 enableAction("format_raise", false);
1632 enableAction("format_lower", false);
1633
1634 enableAction("layout_menu", false);
1635 enableAction("layout_hbox", false);
1636 enableAction("layout_vbox", false);
1637 enableAction("layout_grid", false);
1638 enableAction("layout_hsplitter", false);
1639 enableAction("layout_vsplitter", false);
1640 enableAction("break_layout", false);
1641}
1642
1643void
1644FormManager::emitUndoEnabled(bool enabled, const TQString &text)
1645{
1646 enableAction("edit_undo", enabled);
1647 emit undoEnabled(enabled, text);
1648}
1649
1650void
1651FormManager::emitRedoEnabled(bool enabled, const TQString &text)
1652{
1653 enableAction("edit_redo", enabled);
1654 emit redoEnabled(enabled, text);
1655}
1656
1657void
1659{
1660 if (!m_active)
1661 return;
1662 WidgetList *wlist = m_active->selectedWidgets();
1664 TQWidget *widget;
1665 TQFont font;
1666 bool oneFontSelected = true;
1667 for (WidgetListIterator it(*wlist); (widget = it.current()); ++it) {
1668 if (m_active->library()->isPropertyVisible(widget->className(), widget, "font")) {
1669 widgetsWithFontProperty.append(widget);
1670 if (oneFontSelected) {
1671 if (widgetsWithFontProperty.count()==1)
1672 font = widget->font();
1673 else if (font != widget->font())
1674 oneFontSelected = false;
1675 }
1676 }
1677 }
1678 if (widgetsWithFontProperty.isEmpty())
1679 return;
1680 if (!oneFontSelected) //many different fonts selected: pick a font from toplevel conatiner
1681 font = m_active->widget()->font();
1682
1683 if (1==widgetsWithFontProperty.count()) {
1684 //single widget's settings
1685 widget = widgetsWithFontProperty.first();
1686 KoProperty::Property &fontProp = m_propSet->property("font");
1687 if (TQDialog::Accepted != TDEFontDialog::getFont(font, false, m_active->widget()))
1688 return;
1689 fontProp = font;
1690 return;
1691 }
1692 //multiple widgets
1693 int diffFlags=0;
1694 if (TQDialog::Accepted != TDEFontDialog::getFontDiff(font, diffFlags, false, m_active->widget())
1695 || 0==diffFlags)
1696 return;
1697 //update font
1698 for (WidgetListIterator it(widgetsWithFontProperty); (widget = it.current()); ++it) {
1699 TQFont prevFont( widget->font() );
1700 if (diffFlags & TDEFontChooser::FontDiffFamily)
1701 prevFont.setFamily( font.family() );
1702 if (diffFlags & TDEFontChooser::FontDiffStyle) {
1703 prevFont.setBold( font.bold() );
1704 prevFont.setItalic( font.italic() );
1705 }
1706 if (diffFlags & TDEFontChooser::FontDiffSize)
1707 prevFont.setPointSize( font.pointSize() );
1710 widget->setFont( prevFont );
1711 //temporary fix for dirty flag:
1712 emit dirty(m_active, true);
1713 }
1714}
1715
1716#include "formmanager.moc"
This class makes a container out of any TQWidget.
Definition container.h:74
void setLayout(LayoutType type)
Layout functions.
TQWidget * widget() const
Definition container.h:94
LayoutType layoutType() const
Definition container.h:110
static TQString layoutTypeToString(int type)
Form * form() const
Definition container.h:91
A class to manage (create/load/save) Forms.
Definition formmanager.h:73
void importForm(Form *form=0, bool preview=false)
void setInsertPoint(const TQPoint &p)
void dirty(KFormDesigner::Form *form, bool isDirty=true)
void createLayout(int layoutType)
void createFormSlot(KFormDesigner::Form *form, const TQString &widget, const TQString &signal)
void connectionAborted(KFormDesigner::Form *form)
void adjustHeightToBig()
Resize all selected widgets to the height of the tallest widget.
void adjustHeightToSmall()
Resize all selected widgets to the height of the shortest widget.
void breakLayout()
Breaks selected layout(calls BreakLayoutCommand).
void autoTabStopsSet(KFormDesigner::Form *form, bool set)
static FormManager * self()
Access to FormManager singleton.
void undoEnabled(bool enabled, const TQString &text=TQString())
Form * formForWidget(TQWidget *w)
void layoutHBox()
Lay out selected widgets using HBox layout (calls CreateLayoutCommand).
void propertySetSwitched(KoProperty::Set *set, bool forceReload=false, const TQCString &propertyToSelect=TQCString())
bool isTopLevel(TQWidget *w)
virtual void showPropertySet(WidgetPropertySet *set, bool forceReload=false, const TQCString &propertyToSelect=TQCString())
void layoutHSplitter()
Lay out selected widgets in an horizontal splitter.
void adjustWidthToSmall()
Resize all selected widgets to the width of the narrowest widget.
void setEditor(KoProperty::Editor *editor)
void deleteForm(Form *form)
void stopCreatingConnection()
Leave the Connection creation mode.
void adjustWidthToBig()
Resize all selected widgets to the width of the widest widget.
void windowChanged(TQWidget *w)
WidgetPropertySet * propertySet() const
FormManager(TQObject *parent=0, int options=0, const char *name=0)
void setObjectTreeView(ObjectTreeView *treeview)
void createSignalMenu(TQWidget *w)
Creates and display a menu with all the signals of widget w.
void startCreatingConnection()
Enter the Connection creation mode.
void createSlotMenu(TQWidget *w)
Creates and display a menu with all the slots of widget w.
void previewForm(Form *form, TQWidget *w, Form *toForm=0)
void createContextMenu(TQWidget *w, Container *container, bool popupAtCursor=true)
void layoutVSplitter()
Lay out selected widgets in a verticak splitter.
void insertWidget(const TQCString &classname)
void connectionCreated(KFormDesigner::Form *form, KFormDesigner::Connection &connection)
void layoutVBox()
Lay out selected widgets using VBox layout.
void deleteWidgetLater(TQWidget *w)
Used to delayed widgets' deletion (in Container::deleteItem())
void formWidgetSelected(KFormDesigner::Form *form)
static WidgetLibrary * createWidgetLibrary(FormManager *m, const TQStringList &supportedFactoryGroups)
Creates widget library for supportedFactoryGroups and initializes FormManager singleton.
virtual void enableAction(const char *name, bool enable)=0
void widgetSelected(KFormDesigner::Form *form, bool multiple)
void redoEnabled(bool enabled, const TQString &text=TQString())
void slotPointerClicked()
Slot called when the user presses 'Pointer' icon. Switch to Default mode.
void layoutHFlow()
Lay out selected widgets using HFlow layout.
ActionList createActions(WidgetLibrary *lib, TDEActionCollection *collection, KXMLGUIClient *client)
void layoutGrid()
Lay out selected widgets using Grid layout.
void layoutVFlow()
Lay out selected widgets using VFlow layout.
Base (virtual) class for all form widgets.
Definition form.h:54
A simple class representing a form.
Definition form.h:136
void selectFormWidget()
Definition form.cpp:296
void addCommand(KCommand *command, bool execute)
Definition form.cpp:401
void setSelectedWidget(TQWidget *selected, bool add=false, bool dontRaise=false, bool moreWillBeSelected=false)
Definition form.cpp:237
TQWidget * selectedWidget() const
Definition form.h:197
Container * toplevelContainer() const
Definition form.h:161
void emitSelectionSignals()
Definition form.cpp:334
WidgetLibrary * library() const
Definition form.h:147
WidgetList * selectedWidgets() const
Definition form.h:192
Container * activeContainer()
Definition form.cpp:151
ObjectTree * objectTree() const
Definition form.h:167
void emitActionSignals(bool withUndoAction=true)
Definition form.cpp:311
void setDesignMode(bool design)
Definition form.cpp:214
TQWidget * widget() const
Definition form.cpp:114
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
A graphical view of Form's ObjectTree. This is a TDEListView which represents an item for each widget...
ObjectTreeItem * lookup(const TQString &name)
A dialog to edit Form tab stops.
This class searches for factories and provides TDEActions for widget creation.
A dialog to edit the contents of a PixmapCollection.
TQPtrList< TQWidget > WidgetList
A list of widget pointers.
TQPtrListIterator< TQWidget > WidgetListIterator
An iterator for WidgetList.
KFORMEDITOR_EXPORT void removeChildrenFromList(WidgetList &list)
TQPtrListIterator< ObjectTreeItem > ObjectTreeListIterator
An iterator for ObjectTreeList.
Definition objecttree.h:45
type * findParent(TQObject *o, const char *className, TQObject *&prevPrev)