kexi

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