KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1717 lines
45KB

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