kexiformview.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
3 Copyright (C) 2004-2007 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 "kexiformview.h"
22
23#include <tqobjectlist.h>
24#include <tqfileinfo.h>
25
26#include <formeditor/form.h>
27#include <formeditor/formIO.h>
28#include <formeditor/formmanager.h>
29#include <formeditor/objecttree.h>
30#include <formeditor/container.h>
31#include <formeditor/widgetpropertyset.h>
32#include <formeditor/commands.h>
33#include <formeditor/widgetwithsubpropertiesinterface.h>
34#include <formeditor/objecttree.h>
35
36#include <kexi.h>
37#include <kexidialogbase.h>
38#include <kexidragobjects.h>
39#include <kexidb/field.h>
40#include <kexidb/fieldlist.h>
41#include <kexidb/connection.h>
42#include <kexidb/cursor.h>
43#include <kexidb/utils.h>
44#include <kexidb/preparedstatement.h>
45#include <tableview/kexitableitem.h>
46#include <tableview/kexitableviewdata.h>
47#include <widget/kexipropertyeditorview.h>
48#include <widget/kexiqueryparameters.h>
49#include <kexiutils/utils.h>
50
51#include <koproperty/set.h>
52#include <koproperty/property.h>
53
54#include "widgets/kexidbform.h"
55#include "kexiformscrollview.h"
56#include "kexidatasourcepage.h"
57#include "widgets/kexidbautofield.h"
58
59#define NO_DSWIZARD
60
62
63KexiFormView::KexiFormView(KexiMainWindow *mainWin, TQWidget *parent,
64 const char *name, bool /*dbAware*/)
65 : KexiDataAwareView( mainWin, parent, name )
66 , m_propertySet(0)
67 , m_resizeMode(KexiFormView::ResizeDefault)
68 , m_query(0)
69 , m_queryIsOwned(false)
70 , m_cursor(0)
71// , m_firstFocusWidget(0)
72{
74
75 TQHBoxLayout *l = new TQHBoxLayout(this);
76 l->setAutoAdd(true);
77
78 m_scrollView = new KexiFormScrollView(this, viewMode()==Kexi::DataViewMode);
79
80//moved setViewWidget(m_scrollView);
81// m_scrollView->show();
82
83 m_dbform = new KexiDBForm(m_scrollView->viewport(), m_scrollView, name/*, conn*/);
84// m_dbform->resize( m_scrollView->viewport()->size() - TQSize(20, 20) );
85// m_dbform->resize(TQSize(400, 300));
86 m_scrollView->setWidget(m_dbform);
87 m_scrollView->setResizingEnabled(viewMode()!=Kexi::DataViewMode);
88
89// initForm();
90
91 if (viewMode()==Kexi::DataViewMode) {
92 m_scrollView->recordNavigator()->setRecordHandler( m_scrollView );
93 m_scrollView->viewport()->setPaletteBackgroundColor(m_dbform->palette().active().background());
94//moved to formmanager connect(formPart()->manager(), TQ_SIGNAL(noFormSelected()), TQ_SLOT(slotNoFormSelected()));
95 }
96 else
97 {
98 connect(KFormDesigner::FormManager::self(), TQ_SIGNAL(propertySetSwitched(KoProperty::Set*, bool, const TQCString&)),
99 this, TQ_SLOT(slotPropertySetSwitched(KoProperty::Set*, bool, const TQCString&)));
100 connect(KFormDesigner::FormManager::self(), TQ_SIGNAL(dirty(KFormDesigner::Form *, bool)),
101 this, TQ_SLOT(slotDirty(KFormDesigner::Form *, bool)));
102
103 connect(m_dbform, TQ_SIGNAL(handleDragMoveEvent(TQDragMoveEvent*)),
104 this, TQ_SLOT(slotHandleDragMoveEvent(TQDragMoveEvent*)));
105 connect(m_dbform, TQ_SIGNAL(handleDropEvent(TQDropEvent*)),
106 this, TQ_SLOT(slotHandleDropEvent(TQDropEvent*)));
107
108 // action stuff
109 plugSharedAction("formpart_taborder", KFormDesigner::FormManager::self(), TQ_SLOT(editTabOrder()));
110 plugSharedAction("formpart_adjust_size", KFormDesigner::FormManager::self(), TQ_SLOT(adjustWidgetSize()));
111//TODO plugSharedAction("formpart_pixmap_collection", formPart()->manager(), TQ_SLOT(editFormPixmapCollection()));
112//TODO plugSharedAction("formpart_connections", formPart()->manager(), TQ_SLOT(editConnections()));
113
114 plugSharedAction("edit_copy", KFormDesigner::FormManager::self(), TQ_SLOT(copyWidget()));
115 plugSharedAction("edit_cut", KFormDesigner::FormManager::self(), TQ_SLOT(cutWidget()));
116 plugSharedAction("edit_paste", KFormDesigner::FormManager::self(), TQ_SLOT(pasteWidget()));
117 plugSharedAction("edit_delete", KFormDesigner::FormManager::self(), TQ_SLOT(deleteWidget()));
118 plugSharedAction("edit_select_all", KFormDesigner::FormManager::self(), TQ_SLOT(selectAll()));
119 plugSharedAction("formpart_clear_contents", KFormDesigner::FormManager::self(), TQ_SLOT(clearWidgetContent()));
120 plugSharedAction("edit_undo", KFormDesigner::FormManager::self(), TQ_SLOT(undo()));
121 plugSharedAction("edit_redo", KFormDesigner::FormManager::self(), TQ_SLOT(redo()));
122
123 plugSharedAction("formpart_layout_menu", KFormDesigner::FormManager::self(), 0 );
124 plugSharedAction("formpart_layout_hbox", KFormDesigner::FormManager::self(), TQ_SLOT(layoutHBox()) );
125 plugSharedAction("formpart_layout_vbox", KFormDesigner::FormManager::self(), TQ_SLOT(layoutVBox()) );
126 plugSharedAction("formpart_layout_grid", KFormDesigner::FormManager::self(), TQ_SLOT(layoutGrid()) );
127#ifdef KEXI_SHOW_SPLITTER_WIDGET
128 plugSharedAction("formpart_layout_hsplitter", KFormDesigner::FormManager::self(), TQ_SLOT(layoutHSplitter()) );
129 plugSharedAction("formpart_layout_vsplitter", KFormDesigner::FormManager::self(), TQ_SLOT(layoutVSplitter()) );
130#endif
131 plugSharedAction("formpart_break_layout", KFormDesigner::FormManager::self(), TQ_SLOT(breakLayout()) );
132
133 plugSharedAction("formpart_format_raise", KFormDesigner::FormManager::self(), TQ_SLOT(bringWidgetToFront()) );
134 plugSharedAction("formpart_format_lower", KFormDesigner::FormManager::self(), TQ_SLOT(sendWidgetToBack()) );
135
136 plugSharedAction("other_widgets_menu", KFormDesigner::FormManager::self(), 0 );
137 setAvailable("other_widgets_menu", true);
138
139 plugSharedAction("formpart_align_menu", KFormDesigner::FormManager::self(), 0 );
140 plugSharedAction("formpart_align_to_left", KFormDesigner::FormManager::self(),TQ_SLOT(alignWidgetsToLeft()) );
141 plugSharedAction("formpart_align_to_right", KFormDesigner::FormManager::self(), TQ_SLOT(alignWidgetsToRight()) );
142 plugSharedAction("formpart_align_to_top", KFormDesigner::FormManager::self(), TQ_SLOT(alignWidgetsToTop()) );
143 plugSharedAction("formpart_align_to_bottom", KFormDesigner::FormManager::self(), TQ_SLOT(alignWidgetsToBottom()) );
144 plugSharedAction("formpart_align_to_grid", KFormDesigner::FormManager::self(), TQ_SLOT(alignWidgetsToGrid()) );
145
146 plugSharedAction("formpart_adjust_size_menu", KFormDesigner::FormManager::self(), 0 );
147 plugSharedAction("formpart_adjust_to_fit", KFormDesigner::FormManager::self(), TQ_SLOT(adjustWidgetSize()) );
148 plugSharedAction("formpart_adjust_size_grid", KFormDesigner::FormManager::self(), TQ_SLOT(adjustSizeToGrid()) );
149 plugSharedAction("formpart_adjust_height_small", KFormDesigner::FormManager::self(), TQ_SLOT(adjustHeightToSmall()) );
150 plugSharedAction("formpart_adjust_height_big", KFormDesigner::FormManager::self(), TQ_SLOT(adjustHeightToBig()) );
151 plugSharedAction("formpart_adjust_width_small", KFormDesigner::FormManager::self(), TQ_SLOT(adjustWidthToSmall()) );
152 plugSharedAction("formpart_adjust_width_big", KFormDesigner::FormManager::self(), TQ_SLOT(adjustWidthToBig()) );
153
154 plugSharedAction("format_font", KFormDesigner::FormManager::self(), TQ_SLOT(changeFont()) );
155 }
156
157 initForm();
158
159 KexiDataAwareView::init( m_scrollView, m_scrollView, m_scrollView,
160 /* skip data-awarness if design mode */ viewMode()==Kexi::DesignViewMode );
161
162 connect(this, TQ_SIGNAL(focus(bool)), this, TQ_SLOT(slotFocus(bool)));
164// m_dbform->resize( m_dbform->size()+TQSize(m_scrollView->verticalScrollBar()->width(), m_scrollView->horizontalScrollBar()->height()) );
165}
166
167KexiFormView::~KexiFormView()
168{
169 if (m_cursor) {
170 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
171 conn->deleteCursor(m_cursor);
172 m_cursor = 0;
173 }
174 deleteQuery();
175
176 // Important: form window is closed.
177 // Set property set to 0 because there is *only one* instance of a property set class
178 // in Kexi, so the main window wouldn't know the set in fact has been changed.
179 m_propertySet = 0;
181}
182
183void
185{
186 if (m_cursor) {
187 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
188 conn->deleteCursor(m_cursor);
189 m_cursor = 0;
190 }
191
192 if (m_queryIsOwned) {
193 delete m_query;
194 } else {
196 }
197 m_query = 0;
198}
199
201KexiFormView::form() const
202{
203 if(viewMode()==Kexi::DataViewMode)
204 return tempData()->previewForm;
205 else
206 return tempData()->form;
207}
208
209void
210KexiFormView::setForm(KFormDesigner::Form *f)
211{
212 if(viewMode()==Kexi::DataViewMode)
213 tempData()->previewForm = f;
214 else
215 tempData()->form = f;
216}
217
218void
220{
221 setForm( new KFormDesigner::Form(KexiFormPart::library(), 0, viewMode()==Kexi::DesignViewMode) );
222// if (viewMode()==Kexi::DataViewMode)
223 //form()->setDesignMode(false);
225
226 if (viewMode()==Kexi::DesignViewMode) {
227 //we want to be informed about executed commands
228 connect(form()->commandHistory(), TQ_SIGNAL(commandExecuted()),
229 KFormDesigner::FormManager::self(), TQ_SLOT(slotHistoryCommandExecuted()));
230 }
231
232 const bool newForm = parentDialog()->id() < 0;
233
234 KexiDB::FieldList *fields = 0;
235 if (newForm) {
236 // Show the form wizard if this is a new Form
237#ifndef NO_DSWIZARD
238 KexiDataSourceWizard *w = new KexiDataSourceWizard(mainWin(), (TQWidget*)mainWin(), "datasource_wizard");
239 if(!w->exec())
240 fields = 0;
241 else
242 fields = w->fields();
243 delete w;
244#endif
245 }
246
247 if(fields)
248 {
249 TQDomDocument dom;
250 formPart()->generateForm(fields, dom);
251 KFormDesigner::FormIO::loadFormFromDom(form(), m_dbform, dom);
253 }
254 else
255 loadForm();
256
257 if(form()->autoTabStops())
258 form()->autoAssignTabStops();
259
260 //collect tab order information
262
263// if (m_dbform->orderedFocusWidgets()->first())
264 // m_scrollView->setFocusProxy( m_dbform->orderedFocusWidgets()->first() );
265
266 KFormDesigner::FormManager::self()->importForm(form(), viewMode()==Kexi::DataViewMode);
267 m_scrollView->setForm(form());
268
269// m_dbform->updateTabStopsOrder(form());
270// TQSize s = m_dbform->size();
271// TQApplication::sendPostedEvents();
272// m_scrollView->resize( s );
273// m_dbform->resize(s);
274 m_scrollView->refreshContentsSize();
275// m_scrollView->refreshContentsSizeLater(true,true);
276
277 if (newForm && !fields) {
278 /* Our form's area will be resized more than once.
279 Let's resize form widget itself later. */
281 }
282
283 updateDataSourcePage();
284
285 if (!newForm && viewMode()==Kexi::DesignViewMode) {
286 form()->clearCommandHistory();
287 }
288}
289
291{
293 //update autofields:
294 //-inherit captions
295 //-inherit data types
296 //(this data has not been stored in the form)
297 TQString dataSourceString( m_dbform->dataSource() );
298 TQCString dataSourceMimeTypeString( m_dbform->dataSourceMimeType() );
299 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
300 KexiDB::TableOrQuerySchema tableOrQuery(
301 conn, dataSourceString.latin1(), dataSourceMimeTypeString=="kexi/table");
302 if (!tableOrQuery.table() && !tableOrQuery.query())
303 return;
304 for (KFormDesigner::ObjectTreeDictIterator it(*form()->objectTree()->dict());
305 it.current(); ++it)
306 {
307 KexiDBAutoField *afWidget = dynamic_cast<KexiDBAutoField*>( it.current()->widget() );
308 if (afWidget) {
309 KexiDB::QueryColumnInfo *colInfo = tableOrQuery.columnInfo( afWidget->dataSource() );
310 if (colInfo) {
311 afWidget->setColumnInfo(colInfo);
312 //setFieldTypeInternal((int)colInfo->field->type());
313 //afWidget->setFieldCaptionInternal(colInfo->captionOrAliasOrName());
314 }
315 }
316 }
317}
318
320{
322 //update autofields:
323 //-inherit captions
324 //-inherit data types
325 //(this data has not been stored in the form)
326 TQString dataSourceString( m_dbform->dataSource() );
327 TQCString dataSourceMimeTypeString( m_dbform->dataSourceMimeType() );
328 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
329 KexiDB::TableOrQuerySchema tableOrQuery(
330 conn, dataSourceString.latin1(), dataSourceMimeTypeString=="kexi/table");
331 if (!tableOrQuery.table() && !tableOrQuery.query())
332 return;
333
334 for (KFormDesigner::ObjectTreeDictIterator it(*form()->objectTree()->dict());
335 it.current(); ++it)
336 {
337 // (delayed) set values for subproperties
340 = dynamic_cast<KFormDesigner::WidgetWithSubpropertiesInterface*>( it.current()->widget() );
341 if (subpropIface && subpropIface->subwidget() && it.current()->subproperties() ) {
342 TQWidget *subwidget = subpropIface->subwidget();
343 TQStringVariantMap* subprops = it.current()->subproperties();
344 for (TQStringVariantMapConstIterator subpropIt = subprops->constBegin(); subpropIt!=subprops->constEnd(); ++subpropIt) {
345 kexipluginsdbg << "KexiFormView::loadForm(): delayed setting of the subproperty: widget="
346 << it.current()->widget()->name() << " prop=" << subpropIt.key() << " val=" << subpropIt.data() << endl;
347
348 const int count = subwidget->metaObject()->findProperty(subpropIt.key().latin1(), true);
349 const TQMetaProperty *meta = count!=-1 ? subwidget->metaObject()->property(count, true) : 0;
350 if (meta) {
351 // Special case: the property value of type enum (set) but is saved as a string list,
352 // not as int, so we need to translate it to int. It's been created as such
353 // by FormIO::readPropertyValue(). Example: "alignment" property.
354 if (meta->isSetType() && subpropIt.data().type()==TQVariant::StringList) {
355 TQStrList keys;
356 const TQStringList list( subpropIt.data().toStringList() );
357 for (TQStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it)
358 keys.append((*it).latin1());
359 subwidget->setProperty( subpropIt.key().latin1(), meta->keysToValue(keys) );
360 }
361 else {
362 subwidget->setProperty( subpropIt.key().latin1(), subpropIt.data() );
363 }
364 }
365 }//for
366 }
367 }
368}
369
371static void setUnsavedBLOBIdsForDataViewMode(
372 TQWidget* widget, const TQMap<TQCString, KexiBLOBBuffer::Id_t>& unsavedLocalBLOBsByName)
373{
374 if (-1 != widget->metaObject()->findProperty("pixmapId")) {
375 const KexiBLOBBuffer::Id_t blobID = unsavedLocalBLOBsByName[ widget->name() ];
376 if (blobID > 0)
377 widget->setProperty("pixmapId", (uint)blobID);
378 }
379 const TQObjectList list = widget->childrenListObject();
380 if (list.isEmpty())
381 return;
382 for (TQObjectListIterator it(list); it.current(); ++it) {
383 if (dynamic_cast<TQWidget*>(it.current()))
384 setUnsavedBLOBIdsForDataViewMode(dynamic_cast<TQWidget*>(it.current()), unsavedLocalBLOBsByName);
385 }
386}
387
388void
389KexiFormView::loadForm()
390{
391//@todo also load m_resizeMode !
392
393 kexipluginsdbg << "KexiFormView::loadForm() Loading the form with id : " << parentDialog()->id() << endl;
394 // If we are previewing the Form, use the tempData instead of the form stored in the db
395 if(viewMode()==Kexi::DataViewMode && !tempData()->tempForm.isNull() )
396 {
397 KFormDesigner::FormIO::loadFormFromString(form(), m_dbform, tempData()->tempForm);
398 setUnsavedBLOBIdsForDataViewMode( m_dbform, tempData()->unsavedLocalBLOBsByName );
401 return;
402 }
403
404 // normal load
405 TQString data;
406 loadDataBlock(data);
407 KFormDesigner::FormIO::loadFormFromString(form(), m_dbform, data);
408
409 //"autoTabStops" property is loaded -set it within the form tree as well
410 form()->setAutoTabStops( m_dbform->autoTabStops() );
411
414}
415
416void
417KexiFormView::slotPropertySetSwitched(KoProperty::Set *set, bool forceReload, const TQCString& propertyToSelect)
418{
419// if (set && parentDialog()!=parentDialog()->mainWin()->currentDialog())
420 if (form() != KFormDesigner::FormManager::self()->activeForm())
421 return; //this is not the current form view
422 m_propertySet = set;
423 if (forceReload)
424 propertySetReloaded(true/*preservePrevSelection*/, propertyToSelect);
425 else
427
428 formPart()->dataSourcePage()->assignPropertySet(m_propertySet);
429}
430
432KexiFormView::beforeSwitchTo(int mode, bool &dontStore)
433{
434 if (mode!=viewMode()) {
435 if (viewMode()==Kexi::DataViewMode) {
436 if (!m_scrollView->acceptRowEdit())
437 return cancelled;
438
439 m_scrollView->beforeSwitchView();
440 }
441 else {
442 //remember our pos
443 tempData()->scrollViewContentsPos
444 = TQPoint(m_scrollView->contentsX(), m_scrollView->contentsY());
445 }
446 }
447
448 // we don't store on db, but in our TempData
449 dontStore = true;
450 if(dirty() && (mode == Kexi::DataViewMode) && form()->objectTree()) {
451 KexiFormPart::TempData* temp = tempData();
452 if (!KFormDesigner::FormIO::saveFormToString(form(), temp->tempForm))
453 return false;
454
455 //collect blobs from design mode by name for use in data view mode
456 temp->unsavedLocalBLOBsByName.clear();
457 for (TQMapConstIterator<TQWidget*, KexiBLOBBuffer::Id_t> it = temp->unsavedLocalBLOBs.constBegin();
458 it!=temp->unsavedLocalBLOBs.constEnd(); ++it)
459 {
460 if (!it.key())
461 continue;
462 temp->unsavedLocalBLOBsByName.insert( it.key()->name(), it.data() );
463 }
464 }
465
466 return true;
467}
468
471{
472 if (mode == 0 || mode == Kexi::DesignViewMode) {
473 if (parentDialog()->neverSaved()) {
474 m_dbform->resize(TQSize(400, 300));
475 m_scrollView->refreshContentsSizeLater(true,true);
476 //m_delayedFormContentsResizeOnShow = false;
477 }
478 }
479
480 if (mode != 0 && mode != Kexi::DesignViewMode) {
481 //preserve contents pos after switching to other view
482 m_scrollView->setContentsPos(tempData()->scrollViewContentsPos.x(),
483 tempData()->scrollViewContentsPos.y());
484 }
485// if (mode == Kexi::DesignViewMode) {
486 //m_scrollView->move(0,0);
487 //m_scrollView->setContentsPos(0,0);
488 //m_scrollView->moveChild(m_dbform, 0, 0);
489// }
490
491 if((mode == Kexi::DesignViewMode) && viewMode()==Kexi::DataViewMode) {
492 // The form may have been modified, so we must recreate the preview
493 delete m_dbform; // also deletes form()
494 m_dbform = new KexiDBForm(m_scrollView->viewport(), m_scrollView, "KexiDBForm");
495 m_scrollView->setWidget(m_dbform);
496
497 initForm();
498//moved to formmanager slotNoFormSelected();
499
500 //reset position
501 m_scrollView->setContentsPos(0,0);
502 m_dbform->move(0,0);
503
504 }
505
506 //update tab stops if needed
507 if (viewMode()==Kexi::DataViewMode) {
508// //propagate current "autoTabStops" property value to the form tree
509// form()->setAutoTabStops( m_dbform->autoTabStops() );
510
511// if(form()->autoTabStops())
512// form()->autoAssignTabStops();
513 }
514 else {
515 //set "autoTabStops" property
516 m_dbform->setAutoTabStops( form()->autoTabStops() );
517 }
518
519 if (viewMode() == Kexi::DataViewMode) {
520//TMP!!
522
523 //handle events for this form
525
526 //set focus on 1st focusable widget which has valid dataSource property set
527 if (!m_dbform->orderedFocusWidgets()->isEmpty()) {
528// TQWidget *www = focusWidget();
529 //if (Kexi::hasParent(this, tqApp->focusWidget())) {
530 KexiUtils::unsetFocusWithReason(tqApp->focusWidget(), TQFocusEvent::Tab);
531 //}
532
533 TQPtrListIterator<TQWidget> it(*m_dbform->orderedFocusWidgets());
534 for (;it.current(); ++it) {
535 KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>(it.current());
536 if (iface)
537 kexipluginsdbg << iface->dataSource() << endl;
538 if (iface && iface->columnInfo() && !iface->isReadOnly()
540 /* also skip autoincremented fields:*/
541 && !iface->columnInfo()->field->isAutoIncrement())
542 break;
543 }
544 if (!it.current()) //eventually, focus first available widget if nothing other is available
545 it.toFirst();
546
547 it.current()->setFocus();
548 KexiUtils::setFocusWithReason(it.current(), TQFocusEvent::Tab);
549 m_setFocusInternalOnce = it.current();
550 }
551
552 if (m_query)
553 m_scrollView->selectFirstRow();
554 }
555
556 //dirty only if it's a new object
557 if (mode == 0)
558 setDirty( parentDialog()->partItem()->neverSaved() );
559
560 if (mode==Kexi::DataViewMode && viewMode()==Kexi::DesignViewMode) {
561// slotPropertySetSwitched
562// emit KFormDesigner::FormManager::self()->propertySetSwitched( KFormDesigner::FormManager::self()->propertySet()->set(), true );
563 }
564
565 return true;
566}
567
569{
570 deleteQuery();
571 TQString dataSourceString( m_dbform->dataSource() );
572 TQCString dataSourceMimeTypeString( m_dbform->dataSourceMimeType() );
574 bool ok = !dataSourceString.isEmpty();
575
576/* if (m_previousDataSourceString.lower()==dataSourceString.lower() && !m_cursor) {
577 //data source changed: delete previous cursor
578 m_conn->deleteCursor(m_cursor);
579 m_cursor = 0;
580 }*/
581
582 KexiDB::TableSchema *tableSchema = 0;
583 KexiDB::Connection *conn = 0;
584 TQStringList sources;
585 bool forceReadOnlyDataSource = false;
586
587 if (ok) {
588// m_previousDataSourceString = dataSourceString;
589
590 //collect all data-aware widgets and create query schema
591 m_scrollView->setMainDataSourceWidget(m_dbform);
592 sources = m_scrollView->usedDataSources();
593 conn = parentDialog()->mainWin()->project()->dbConnection();
594 if (dataSourceMimeTypeString.isEmpty() /*table type is the default*/
595 || dataSourceMimeTypeString=="kexi/table")
596 {
597 tableSchema = conn->tableSchema( dataSourceString );
598 if (tableSchema) {
599 /* We will build a _minimum_ query schema from selected table fields. */
600 m_query = new KexiDB::QuerySchema();
601 m_queryIsOwned = true;
602
603 if (dataSourceMimeTypeString.isEmpty())
604 m_dbform->setDataSourceMimeType("kexi/table"); //update for compatibility
605 }
606 }
607
608 if (!tableSchema) {
609 if (dataSourceMimeTypeString.isEmpty() /*also try to find a query (for compatibility with Kexi<=0.9)*/
610 || dataSourceMimeTypeString=="kexi/query")
611 {
612 //try to find predefined query schema.
613 //Note: In general, we could not skip unused fields within this query because
614 // it can have GROUP BY clause.
616 m_query = conn->querySchema( dataSourceString );
617 m_queryIsOwned = false;
618 ok = m_query != 0;
619 if (ok && dataSourceMimeTypeString.isEmpty())
620 m_dbform->setDataSourceMimeType("kexi/query"); //update for compatibility
621 // query results are read-only
623 forceReadOnlyDataSource = true;
624 }
625 else //no other mime types supported
626 ok = false;
627 }
628 }
629
630 TQDict<char> invalidSources(997);
631 if (ok) {
632 KexiDB::IndexSchema *pkey = tableSchema ? tableSchema->primaryKey() : 0;
633 if (pkey) {
634 //always add all fields from table's primary key
635 // (don't worry about duplicates, unique list will be computed later)
636 sources += pkey->names();
637 kexipluginsdbg << "KexiFormView::initDataSource(): pkey added to data sources: " << pkey->names() << endl;
638 }
639 kexipluginsdbg << "KexiFormView::initDataSource(): sources=" << sources << endl;
640
641 uint index = 0;
642 for (TQStringList::ConstIterator it = sources.constBegin();
643 it!=sources.constEnd(); ++it, index++) {
645 TQString fieldName( (*it).lower() );
646 //remove "tablename." if it was prepended
647 if (tableSchema && fieldName.startsWith( tableSchema->name().lower()+"." ))
648 fieldName = fieldName.mid(tableSchema->name().length()+1);
649 //remove "queryname." if it was prepended
650 if (!tableSchema && fieldName.startsWith( m_query->name().lower()+"." ))
651 fieldName = fieldName.mid(m_query->name().length()+1);
652 KexiDB::Field *f = tableSchema ? tableSchema->field(fieldName) : m_query->field(fieldName);
653 if (!f) {
655 //remove this widget from the set of data widgets in the provider
657 invalidSources.insert( fieldName, (const char*)1 ); // += index;
658 kexipluginsdbg << "KexiFormView::initDataSource(): invalidSources+=" << index << " ("
659 << (*it) << ")" << endl;
660 continue;
661 }
662 if (tableSchema) {
663 if (!m_query->hasField( f )) {
664 //we're building a new query: add this field
665 m_query->addField( f );
666 }
667 }
668 }
669 if (invalidSources.count()==sources.count()) {
670 //all data sources are invalid! don't execute the query
671 deleteQuery();
672 }
673 else {
674 KexiDB::debug( m_query->parameters() );
675 // like in KexiQueryView::executeQuery()
676 TQValueList<TQVariant> params;
677 {
679 params = KexiQueryParameters::getParameters(this, *conn->driver(), *m_query, ok);
680 }
681 if (ok) //input cancelled
682 m_cursor = conn->executeQuery( *m_query, params );
683 }
684 m_scrollView->invalidateDataSources( invalidSources, m_query );
685 ok = m_cursor!=0;
686 }
687
688 if (!invalidSources.isEmpty())
690
691 if (ok) {
694 KexiTableViewData* data = new KexiTableViewData(m_cursor);
695 if (forceReadOnlyDataSource)
696 data->setReadOnly(true);
697 data->preloadAllRows();
698
700// int resultCount = -1;
701// if (ok) {
702// resultCount = m_conn->resultCount(m_conn->selectStatement(*m_query));
703// ok = m_cursor->reopen();
704// }
705// if (ok)
706// ok = ! (!m_cursor->moveFirst() && m_cursor->error());
707
708 m_scrollView->setData( data, true /*owner*/ );
709 }
710 else
711 m_scrollView->setData( 0, false );
712}
713
714void
715KexiFormView::slotDirty(KFormDesigner::Form *dirtyForm, bool isDirty)
716{
717 if(dirtyForm == form())
718 KexiViewBase::setDirty(isDirty);
719}
720
723{
725 kexipluginsdbg << "KexiDBForm::storeNewData(): new id:" << s->id() << endl;
726
727 if (!s || cancel) {
728 delete s;
729 return 0;
730 }
731 if (!storeData()) {
732 //failure: remove object's schema data to avoid garbage
733 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
734 conn->removeObject( s->id() );
735 delete s;
736 return 0;
737 }
738 return s;
739}
740
743{
744 Q_UNUSED(dontAsk);
745 kexipluginsdbg << "KexiDBForm::storeData(): " << parentDialog()->partItem()->name()
746 << " [" << parentDialog()->id() << "]" << endl;
747
748 //-- first, store local BLOBs, so identifiers can be updated
750 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
751 KexiDB::TableSchema *blobsTable = conn->tableSchema("kexi__blobs");
752 if (!blobsTable) { //compatibility check for older Kexi project versions
754 return false;
755 }
756 // Not all engines accept passing NULL to PKEY o_id, so we're omitting it.
757 TQStringList blobsFieldNamesWithoutID(blobsTable->names());
758 blobsFieldNamesWithoutID.pop_front();
759 KexiDB::FieldList *blobsFieldsWithoutID = blobsTable->subList(blobsFieldNamesWithoutID);
760
761 KexiDB::PreparedStatement::Ptr st = conn->prepareStatement(
762 KexiDB::PreparedStatement::InsertStatement, *blobsFieldsWithoutID);
763 if (!st) {
764 delete blobsFieldsWithoutID;
766 return false;
767 }
769 KexiFormView *designFormView
770 = dynamic_cast<KexiFormView*>( parentDialog()->viewForMode(Kexi::DesignViewMode) );
771 if (designFormView) {
772 for (TQMapConstIterator<TQWidget*, KexiBLOBBuffer::Id_t> it = tempData()->unsavedLocalBLOBs.constBegin();
773 it!=tempData()->unsavedLocalBLOBs.constEnd(); ++it)
774 {
775 if (!it.key()) {
776 kexipluginswarn << "KexiFormView::storeData(): it.key()==0 !" << endl;
777 continue;
778 }
779 kexipluginsdbg << "name=" << it.key()->name() << " dataID=" << it.data() << endl;
780 KexiBLOBBuffer::Handle h( blobBuf->objectForId(it.data(), false) );
781 if (!h)
782 continue; //no BLOB assigned
783
784 TQString originalFileName(h.originalFileName());
785 TQFileInfo fi(originalFileName);
786 TQString caption(fi.baseName().replace('_', " ").simplifyWhiteSpace());
787
788 if (st) {
789 *st /* << NO, (pgsql doesn't support this):TQVariant()*/ /*id*/
790 << h.data() << originalFileName << caption
791 << h.mimeType() << (uint)h.folderId();
792 if (!st->execute()) {
793 delete blobsFieldsWithoutID;
794 kexipluginsdbg << " execute error" << endl;
795 return false;
796 }
797 }
798 delete blobsFieldsWithoutID;
799 blobsFieldsWithoutID=0;
800 const TQ_ULLONG storedBLOBID = conn->lastInsertedAutoIncValue("o_id", "kexi__blobs");
801 if ((TQ_ULLONG)-1 == storedBLOBID) {
803 return false;
804 }
805 kexipluginsdbg << " storedDataID=" << storedBLOBID << endl;
806 h.setStoredWidthID((KexiBLOBBuffer::Id_t)storedBLOBID);
807 //set widget's internal property so it can be saved...
808 const TQVariant oldStoredPixmapId( it.key()->property("storedPixmapId") );
809 it.key()->setProperty("storedPixmapId",
810 TQVariant((uint)storedBLOBID));
811 KFormDesigner::ObjectTreeItem *widgetItem = designFormView->form()->objectTree()->lookup(it.key()->name()); //form()->objectTree()->lookup(it.key()->name());
812 if (widgetItem)
813 widgetItem->addModifiedProperty( "storedPixmapId", oldStoredPixmapId );
814 else
815 kexipluginswarn << "KexiFormView::storeData(): no '" << widgetItem->name() << "' widget found within a form" << endl;
816 }
817 }
818
819 //-- now, save form's XML
820 TQString data;
821 if (!KFormDesigner::FormIO::saveFormToString(tempData()->form, data))
822 return false;
823 if (!storeDataBlock(data))
824 return false;
825
826 //all blobs are now saved
827 tempData()->unsavedLocalBLOBs.clear();
828
829 tempData()->tempForm = TQString();
830 return true;
831}
832
833#if 0
835void
836KexiFormView::slotWidgetSelected(KFormDesigner::Form *f, bool multiple)
837{
838 if(f != form())
839 return;
840
841 enableFormActions();
842 // Enable edit actions
843 setAvailable("edit_copy", true);
844 setAvailable("edit_cut", true);
845 setAvailable("edit_clear", true);
846
847 // 'Align Widgets' menu
848 setAvailable("formpart_align_menu", multiple);
849 setAvailable("formpart_align_to_left", multiple);
850 setAvailable("formpart_align_to_right", multiple);
851 setAvailable("formpart_align_to_top", multiple);
852 setAvailable("formpart_align_to_bottom", multiple);
853
854 setAvailable("formpart_adjust_size_menu", true);
855 setAvailable("formpart_adjust_width_small", multiple);
856 setAvailable("formpart_adjust_width_big", multiple);
857 setAvailable("formpart_adjust_height_small", multiple);
858 setAvailable("formpart_adjust_height_big", multiple);
859
860 setAvailable("formpart_format_raise", true);
861 setAvailable("formpart_format_lower", true);
862
863 // If the widgets selected is a container, we enable layout actions
864 if(!multiple)
865 {
866 KFormDesigner::ObjectTreeItem *item = f->objectTree()->lookup( f->selectedWidgets()->first()->name() );
867 if(item && item->container())
868 multiple = true;
869 }
870 // Layout actions
871 setAvailable("formpart_layout_hbox", multiple);
872 setAvailable("formpart_layout_vbox", multiple);
873 setAvailable("formpart_layout_grid", multiple);
874
876 setAvailable("formpart_break_layout", container ?
877 (container->layoutType() != KFormDesigner::Container::NoLayout) : false );
878}
879
880void
881KexiFormView::slotFormWidgetSelected(KFormDesigner::Form *f)
882{
883 if(f != form())
884 return;
885
886 disableWidgetActions();
887 enableFormActions();
888
889 // Layout actions
890 setAvailable("formpart_layout_hbox", true);
891 setAvailable("formpart_layout_vbox", true);
892 setAvailable("formpart_layout_grid", true);
893 setAvailable("formpart_break_layout", (f->toplevelContainer()->layoutType() != KFormDesigner::Container::NoLayout));
894}
895
896void
897KexiFormView::slotNoFormSelected() // == form in preview mode
898{
899 disableWidgetActions();
900
901 // Disable paste action
902 setAvailable("edit_paste", false);
903 setAvailable("edit_undo", false);
904 setAvailable("edit_redo", false);
905
906 // Disable 'Tools' actions
907 setAvailable("formpart_pixmap_collection", false);
908 setAvailable("formpart_connections", false);
909 setAvailable("formpart_taborder", false);
910 setAvailable("formpart_change_style", false);
911}
912
913void
914KexiFormView::enableFormActions()
915{
916 // Enable 'Tools' actions
917 setAvailable("formpart_pixmap_collection", true);
918 setAvailable("formpart_connections", true);
919 setAvailable("formpart_taborder", true);
920
921 setAvailable("edit_paste", KFormDesigner::FormManager::self()->isPasteEnabled());
922}
923
924void
925KexiFormView::disableWidgetActions()
926{
927 // Disable edit actions
928 setAvailable("edit_copy", false);
929 setAvailable("edit_cut", false);
930 setAvailable("edit_clear", false);
931
932 // Disable format functions
933 setAvailable("formpart_align_menu", false);
934 setAvailable("formpart_align_to_left", false);
935 setAvailable("formpart_align_to_right", false);
936 setAvailable("formpart_align_to_top", false);
937 setAvailable("formpart_align_to_bottom", false);
938
939 setAvailable("formpart_adjust_size_menu", false);
940 setAvailable("formpart_adjust_width_small", false);
941 setAvailable("formpart_adjust_width_big", false);
942 setAvailable("formpart_adjust_height_small", false);
943 setAvailable("formpart_adjust_height_big", false);
944
945 setAvailable("formpart_format_raise", false);
946 setAvailable("formpart_format_lower", false);
947
948 setAvailable("formpart_layout_hbox", false);
949 setAvailable("formpart_layout_vbox", false);
950 setAvailable("formpart_layout_grid", false);
951 setAvailable("formpart_break_layout", false);
952}
953
954void
955KexiFormView::setUndoEnabled(bool enabled)
956{
957 setAvailable("edit_undo", enabled);
958}
959
960void
961KexiFormView::setRedoEnabled(bool enabled)
962{
963 setAvailable("edit_redo", enabled);
964}
965#endif //0
966
967TQSize
968KexiFormView::preferredSizeHint(const TQSize& otherSize)
969{
970 if (parentDialog()->neverSaved()) {
971 //ignore otherSize if possible
972// return KexiViewBase::preferredSizeHint( (parentDialog() && parentDialog()->mdiParent()) ? TQSize(10000,10000) : otherSize);
973 }
974
975 return (m_dbform->size()
976 +TQSize(m_scrollView->verticalScrollBar()->isVisible() ? m_scrollView->verticalScrollBar()->width()*3/2 : 10,
977 m_scrollView->horizontalScrollBar()->isVisible() ? m_scrollView->horizontalScrollBar()->height()*3/2 : 10))
978 .expandedTo( KexiViewBase::preferredSizeHint(otherSize) );
979}
980
981void
982KexiFormView::resizeEvent( TQResizeEvent *e )
983{
984 if (viewMode()==Kexi::DataViewMode) {
985 m_scrollView->refreshContentsSizeLater(
986 e->size().width()!=e->oldSize().width(),
987 e->size().height()!=e->oldSize().height()
988 );
989 }
990 KexiViewBase::resizeEvent(e);
991 m_scrollView->updateNavPanelGeometry();
992 if (m_delayedFormContentsResizeOnShow>0) { // && isVisible()) {
994 m_dbform->resize( e->size() - TQSize(30, 30) );
995 }
996}
997
998void
999KexiFormView::setFocusInternal()
1000{
1001 if (viewMode() == Kexi::DataViewMode) {
1002 if (m_dbform->focusWidget()) {
1003 //better-looking focus
1005 KexiUtils::setFocusWithReason(m_setFocusInternalOnce, TQFocusEvent::Other);//Tab);
1007 }
1008 else {
1009 //ok? SET_FOCUS_USING_REASON(m_dbform->focusWidget(), TQFocusEvent::Other);//Tab);
1010 }
1011 return;
1012 }
1013 }
1014 TQWidget::setFocus();
1015}
1016
1017void
1019{
1020 KexiDataAwareView::show();
1021
1022//moved from KexiFormScrollView::show():
1023
1024 //now get resize mode settings for entire form
1025 // if (resizeMode() == KexiFormView::ResizeAuto)
1026 if (viewMode()==Kexi::DataViewMode) {
1027 if (resizeMode() == KexiFormView::ResizeAuto)
1028 m_scrollView->setResizePolicy(TQScrollView::AutoOneFit);
1029 }
1030}
1031
1032void
1033KexiFormView::slotFocus(bool in)
1034{
1035 if(in && form() && KFormDesigner::FormManager::self() && KFormDesigner::FormManager::self()->activeForm() != form()) {
1037 updateDataSourcePage();
1038 }
1039}
1040
1041void
1042KexiFormView::updateDataSourcePage()
1043{
1044 if (viewMode()==Kexi::DesignViewMode) {
1045 TQCString dataSourceMimeType, dataSource;
1046 KFormDesigner::WidgetPropertySet *set = KFormDesigner::FormManager::self()->propertySet();
1047 if (set->contains("dataSourceMimeType"))
1048 dataSourceMimeType = (*set)["dataSourceMimeType"].value().toCString();
1049 if (set->contains("dataSource"))
1050 dataSource = (*set)["dataSource"].value().toCString();
1051
1052 formPart()->dataSourcePage()->setDataSource(dataSourceMimeType, dataSource);
1053 }
1054}
1055
1056void
1057KexiFormView::slotHandleDragMoveEvent(TQDragMoveEvent* e)
1058{
1060 e->accept(true);
1061 //dirty: drawRect(TQRect( e->pos(), TQSize(50, 20)), 2);
1062 }
1063}
1064
1065void
1067{
1068 const TQWidget *targetContainerWidget = dynamic_cast<const TQWidget*>(sender());
1069 KFormDesigner::ObjectTreeItem *targetContainerWidgetItem = targetContainerWidget
1070 ? form()->objectTree()->lookup( targetContainerWidget->name() ) : 0;
1071 if (targetContainerWidgetItem && targetContainerWidgetItem->container()
1073 {
1074 TQString sourceMimeType, sourceName;
1075 TQStringList fields;
1076 if (!KexiFieldDrag::decodeMultiple( e, sourceMimeType, sourceName, fields ))
1077 return;
1078 insertAutoFields(sourceMimeType, sourceName, fields,
1079 targetContainerWidgetItem->container(), e->pos());
1080 }
1081}
1082
1083void
1084KexiFormView::insertAutoFields(const TQString& sourceMimeType, const TQString& sourceName,
1085 const TQStringList& fields, KFormDesigner::Container* targetContainer, const TQPoint& _pos)
1086{
1087 if (fields.isEmpty())
1088 return;
1089
1090 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
1091 KexiDB::TableOrQuerySchema tableOrQuery(conn, sourceName.latin1(), sourceMimeType=="kexi/table");
1092 if (!tableOrQuery.table() && !tableOrQuery.query()) {
1093 kexipluginswarn << "KexiFormView::insertAutoFields(): no such table/query \""
1094 << sourceName << "\"" << endl;
1095 return;
1096 }
1097
1098 TQPoint pos(_pos);
1099 //if pos is not specified, compute a new position:
1100 if (pos==TQPoint(-1,-1)) {
1103 + TQPoint(0,form()->gridSize());
1104 }
1105 else {
1106 pos = TQPoint(40, 40); //start here
1107 }
1108 }
1109
1110 // there will be many actions performed, do not update property pane until all that's finished
1111 KFormDesigner::FormManager::self()->blockPropertyEditorUpdating(this);
1112
1114
1115// KFormDesigner::WidgetList* prevSelection = form()->selectedWidgets();
1116 KFormDesigner::WidgetList widgetsToSelect;
1118 fields.count()==1 ? i18n("Insert AutoField widget") : i18n("Insert %1 AutoField widgets").arg(fields.count()),
1120 );
1121
1122 foreach( TQStringList::ConstIterator, it, fields ) {
1123 KexiDB::QueryColumnInfo* column = tableOrQuery.columnInfo(*it);
1124 if (!column) {
1125 kexipluginswarn << "KexiFormView::insertAutoFields(): no such field \""
1126 << *it << "\" in table/query \"" << sourceName << "\"" << endl;
1127 continue;
1128 }
1130 //KFormDesigner::Container *targetContainer;
1131/* TQWidget* targetContainerWidget = TQApplication::widgetAt(pos, true);
1132 while (targetContainerWidget
1133 && !dynamic_cast<KFormDesigner::Container*>(targetContainerWidget))
1134 {
1135 targetContainerWidget = targetContainerWidget->parentWidget();
1136 }
1137 if (dynamic_cast<KFormDesigner::Container*>(targetContainerWidget))
1138 targetContainer = dynamic_cast<KFormDesigner::Container*>(targetContainerWidget);
1139 else
1140 targetContainer = form()->toplevelContainer();*/
1142 = new KFormDesigner::InsertWidgetCommand(targetContainer,
1144 "KexiDBAutoField",
1146 pos, column->aliasOrName()
1147 );
1148 insertCmd->execute();
1149 group->addCommand(insertCmd, false/*don't exec twice*/);
1150
1151 KFormDesigner::ObjectTreeItem *newWidgetItem
1152 = form()->objectTree()->dict()->find(insertCmd->widgetName());
1153 KexiDBAutoField* newWidget
1154 = newWidgetItem ? dynamic_cast<KexiDBAutoField*>(newWidgetItem->widget()) : 0;
1155 widgetsToSelect.append(newWidget);
1156//#if 0
1159 TQMap<TQCString, TQVariant> propValues;
1160 propValues.insert("dataSource", column->aliasOrName());
1161 propValues.insert("fieldTypeInternal", (int)column->field->type());
1162 propValues.insert("fieldCaptionInternal", column->captionOrAliasOrName());
1163 KFormDesigner::FormManager::self()->propertySet()->createPropertyCommandsInDesignMode(
1164 newWidget, propValues, subGroup, false,
1165 true );
1166 subGroup->execute();
1167 group->addCommand( subGroup, false/*will not be executed on CommandGroup::execute()*/ );
1168
1169//#endif
1170 //set data source and caption
1171 //-we don't need to use PropertyCommand here beacause we don't need UNDO
1172 // for these single commands
1173// newWidget->setDataSource(column->aliasOrName());
1174// newWidget->setFieldTypeInternal((int)column->field->type());
1175// newWidget->setFieldCaptionInternal(column->captionOrAliasOrName());
1176 //resize again because autofield's type changed what can lead to changed sizeHint()
1177// newWidget->resize(newWidget->sizeHint());
1179 list.append(newWidget);
1180 KFormDesigner::AdjustSizeCommand *adjustCommand
1181 = new KFormDesigner::AdjustSizeCommand(KFormDesigner::AdjustSizeCommand::SizeToFit,
1182 list, form());
1183 adjustCommand->execute();
1184 group->addCommand( adjustCommand,
1185 false/*will not be executed on CommandGroup::execute()*/
1186 );
1187
1188 if (newWidget) {//move position down for next widget
1189 pos.setY( pos.y() + newWidget->height() + form()->gridSize());
1190 }
1191 }
1192 if (widgetsToSelect.last()) {
1193 //resize form if needed
1194 TQRect oldFormRect( m_dbform->geometry() );
1195 TQRect newFormRect( oldFormRect );
1196 newFormRect.setWidth(TQMAX(m_dbform->width(), widgetsToSelect.last()->geometry().right()+1));
1197 newFormRect.setHeight(TQMAX(m_dbform->height(), widgetsToSelect.last()->geometry().bottom()+1));
1198 if (newFormRect != oldFormRect) {
1199 //1. resize by hand
1200 m_dbform->setGeometry( newFormRect );
1201 //2. store information about resize
1204 oldFormRect, newFormRect, "geometry");
1205 group->addCommand(resizeFormCommand, true/*will be executed on CommandGroup::execute()*/);
1206 }
1207
1208 //remember geometry of the last inserted widget
1209 m_widgetGeometryForRecentInsertAutoFields = widgetsToSelect.last()->geometry();
1210 }
1211
1212 //eventually, add entire command group to active form
1213 form()->addCommand( group, true/*exec*/ );
1214
1215// group->debug();
1216
1217 //enable proper REDO usage
1218 group->resetAllowExecuteFlags();
1219
1220 m_scrollView->repaint();
1221 m_scrollView->viewport()->repaint();
1222 m_scrollView->repaintContents();
1223 m_scrollView->updateContents();
1224 m_scrollView->clipper()->repaint();
1225 m_scrollView->refreshContentsSize();
1226
1227 //select all inserted widgets, if multiple
1228 if (widgetsToSelect.count()>1) {
1229 form()->setSelectedWidget(0);
1230 foreach_list (KFormDesigner::WidgetListIterator, it, widgetsToSelect)
1231 form()->setSelectedWidget(it.current(), true/*add*/, true/*dontRaise*/);
1232 }
1233
1234 // eventually, update property pane
1235 KFormDesigner::FormManager::self()->unblockPropertyEditorUpdating(this, KFormDesigner::FormManager::self()->propertySet());
1236}
1237
1238void
1240{
1242 if (id==0)
1243 tempData()->unsavedLocalBLOBs.remove(widget);
1244 else
1245 tempData()->unsavedLocalBLOBs.insert(widget, id);
1246}
1247
1248/*
1249todo
1250void KexiFormView::updateActions(bool activated)
1251{
1252 if (viewMode()==Kexi::DesignViewMode) {
1253 if (form()->selectedWidget()) {
1254 if (form()->widget() == form()->selectedWidget())
1255 KFormDesigner::FormManager::self()->emitFormWidgetSelected( form() );
1256 else
1257 KFormDesigner::FormManager::self()->emitWidgetSelected( form(), false );
1258 }
1259 else if (form()->selectedWidgets()) {
1260 KFormDesigner::FormManager::self()->emitWidgetSelected( form(), true );
1261 }
1262 }
1263 KexiDataAwareView::updateActions(activated);
1264}*/
1265
1266/*
1267void KexiFormView::parentDialogDetached()
1268{
1269 m_dbform->updateTabStopsOrder(form());
1270}
1271
1272void KexiFormView::parentDialogAttached(KMdiChildFrm *)
1273{
1274 m_dbform->updateTabStopsOrder(form());
1275}*/
1276
1277#include "kexiformview.moc"
1278
void addCommand(KCommand *command, bool allowExecute)
This class makes a container out of any TQWidget.
Definition container.h:74
LayoutType layoutType() const
Definition container.h:110
void importForm(Form *form=0, bool preview=false)
static FormManager * self()
Access to FormManager singleton.
void windowChanged(TQWidget *w)
WidgetPropertySet * propertySet() const
A simple class representing a form.
Definition form.h:136
void addCommand(KCommand *command, bool execute)
Definition form.cpp:401
void setAutoTabStops(bool autoTab)
Definition form.h:286
void setSelectedWidget(TQWidget *selected, bool add=false, bool dontRaise=false, bool moreWillBeSelected=false)
Definition form.cpp:237
Container * toplevelContainer() const
Definition form.h:161
void autoAssignTabStops()
Definition form.cpp:507
WidgetList * selectedWidgets() const
Definition form.h:192
Container * activeContainer()
Definition form.cpp:151
ObjectTree * objectTree() const
Definition form.h:167
void clearCommandHistory()
Definition form.cpp:411
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
void addModifiedProperty(const TQCString &property, const TQVariant &oldValue)
ObjectTreeItem * lookup(const TQString &name)
ObjectTreeDict * dict()
Definition objecttree.h:157
An interface for declaring form widgets to have subproperties.
void plugSharedAction(const char *action_name, TQObject *receiver, const char *slot)
Object handle used by KexiBLOBBuffer.
void setStoredWidthID(Id_t id)
Application-wide buffer for local BLOB data like pixmaps.
long Id_t
long integer for unique identifying blobs
Handle objectForId(Id_t id, bool stored)
static KexiBLOBBuffer * self()
Access to KexiBLOBBuffer singleton.
Universal "Auto Field" widget for Kexi forms.
virtual void setColumnInfo(KexiDB::QueryColumnInfo *cinfo)
A DB-aware form widget, acting as form's toplevel widget.
Definition kexidbform.h:44
void updateTabStopsOrder(KFormDesigner::Form *form)
Provides database connection, allowing queries and data modification.
Definition connection.h:62
TQ_ULLONG lastInsertedAutoIncValue(const TQString &aiFieldName, const TQString &tableName, TQ_ULLONG *ROWID=0)
TableSchema * tableSchema(int tableId)
bool deleteCursor(Cursor *cursor)
bool removeObject(uint objId)
QuerySchema * querySchema(int queryId)
virtual PreparedStatement::Ptr prepareStatement(PreparedStatement::StatementType type, FieldList &fields)=0
Cursor * executeQuery(const TQString &statement, uint cursor_options=0)
Driver * driver() const
Definition connection.h:78
FieldList * subList(const TQString &n1, const TQString &n2=TQString(), const TQString &n3=TQString(), const TQString &n4=TQString(), const TQString &n5=TQString(), const TQString &n6=TQString(), const TQString &n7=TQString(), const TQString &n8=TQString(), const TQString &n9=TQString(), const TQString &n10=TQString(), const TQString &n11=TQString(), const TQString &n12=TQString(), const TQString &n13=TQString(), const TQString &n14=TQString(), const TQString &n15=TQString(), const TQString &n16=TQString(), const TQString &n17=TQString(), const TQString &n18=TQString())
bool hasField(const Field *field)
Definition fieldlist.h:82
Field * field(uint id)
Definition fieldlist.h:76
TQStringList names() const
Meta-data for a field.
Definition field.h:73
Type type() const
Definition field.cpp:134
bool isAutoIncrement() const
Definition field.h:231
Provides information about database index that can be created for a database table.
Definition indexschema.h:44
@ InsertStatement
INSERT statement will be prepared end executed.
Helper class that assigns additional information for the column in a query.
Definition queryschema.h:49
TQCString aliasOrName() const
Definition queryschema.h:59
TQString captionOrAliasOrName() const
Definition queryschema.h:65
KexiDB::QuerySchema provides information about database query.
virtual Field * field(const TQString &name, bool expanded=true)
FieldList & addField(Field *field, bool visible=true)
QuerySchemaParameterList parameters()
QueryColumnInfo * columnInfo(const TQString &name)
QuerySchema * query() const
TableSchema * table() const
IndexSchema * primaryKey() const
Definition tableschema.h:76
void setData(KexiTableViewData *data, bool owner=true)
Provides a view displaying record-based data.
void init(TQWidget *viewWidget, KexiSharedActionClient *actionClient, KexiDataAwareObjectInterface *dataAwareObject, bool noDataAware=false)
virtual bool isReadOnly() const
void assignPropertySet(KoProperty::Set *propertySet)
Receives a pointer to a new property set (from KexiFormView::managerPropertyChanged())
void setDataSource(const TQCString &mimeType, const TQCString &name)
Sets data source of a currently selected form.
KexiViewBase * viewForMode(int mode) const
KexiPart::Item * partItem() const
static bool canDecodeMultiple(TQMimeSource *e)
static bool decodeMultiple(TQDropEvent *e, TQString &sourceMimeType, TQString &sourceName, TQStringList &fields)
An interface for declaring form widgets to be data-aware.
virtual KexiDB::QueryColumnInfo * columnInfo() const
void setMainDataSourceWidget(TQWidget *mainWidget)
void invalidateDataSources(const TQDict< char > &invalidSources, KexiDB::QuerySchema *query=0)
void setMainWidgetForEventHandling(KexiMainWindow *mainWin, TQWidget *mainWidget)
static KFormDesigner::WidgetLibrary * library()
void generateForm(KexiDB::FieldList *list, TQDomDocument &domDoc)
KexiFormScrollView class provides a widget for displaying data in a form view.
virtual void refreshContentsSize()
virtual TQScrollBar * verticalScrollBar() const
The KexiFormView lass provides a data-driven (record-based) form view .
virtual KexiDB::SchemaData * storeNewData(const KexiDB::SchemaData &sdata, bool &cancel)
virtual tristate afterSwitchFrom(int mode)
void updateValuesForSubproperties()
Used in loadForm()
virtual KoProperty::Set * propertySet()
void insertAutoFields(const TQString &sourceMimeType, const TQString &sourceName, const TQStringList &fields, KFormDesigner::Container *targetContainerWidget, const TQPoint &pos=TQPoint(-1,-1))
void initDataSource()
KexiDBForm * m_dbform
virtual void show()
void setUnsavedLocalBLOB(TQWidget *widget, KexiBLOBBuffer::Id_t id)
void updateAutoFieldsDataSource()
Used in loadForm()
TQGuardedPtr< TQWidget > m_setFocusInternalOnce
Used in setFocusInternal()
virtual tristate beforeSwitchTo(int mode, bool &dontStore)
void slotHandleDropEvent(TQDropEvent *e)
Handles field(s) dropping from the data source pane onto the form.
KexiFormView(KexiMainWindow *mainWin, TQWidget *parent, const char *name=0, bool dbAware=true)
virtual TQSize preferredSizeHint(const TQSize &otherSize)
int m_delayedFormContentsResizeOnShow
TQRect m_widgetGeometryForRecentInsertAutoFields
virtual tristate storeData(bool dontAsk=false)
Kexi's main window interface This interface is implemented by KexiMainWindowImpl class.
virtual KexiProject * project()=0
Project data of currently opened project or NULL if no project here yet.
KexiDB::Connection * dbConnection() const
static TQValueList< TQVariant > getParameters(TQWidget *parent, const KexiDB::Driver &driver, KexiDB::QuerySchema &querySchema, bool &ok)
void setRecordHandler(KexiRecordNavigatorHandler *handler)
virtual void setReadOnly(bool set)
virtual bool dirty() const
virtual KexiDB::SchemaData * storeNewData(const KexiDB::SchemaData &sdata, bool &cancel)
virtual void setAvailable(const char *action_name, bool set)
virtual void propertySetSwitched()
void propertySetReloaded(bool preservePrevSelection=false, const TQCString &propertyToSelect=TQCString())
int viewMode() const
bool storeDataBlock(const TQString &dataString, const TQString &dataID=TQString())
bool loadDataBlock(TQString &dataString, const TQString &dataID=TQString(), bool canBeEmpty=false)
KexiDialogBase * parentDialog() const
virtual TQSize preferredSizeHint(const TQSize &otherSize)
KexiMainWindow * mainWin() const
3-state logical type with three values: true, false and cancelled and convenient operators.
Definition tristate.h:100
TQPtrList< TQWidget > WidgetList
A list of widget pointers.
TQDictIterator< ObjectTreeItem > ObjectTreeDictIterator
An iterator for ObjectTreeDict.
Definition objecttree.h:51
TQPtrListIterator< TQWidget > WidgetListIterator
An iterator for WidgetList.
KEXI_DB_EXPORT void debug(const QuerySchemaParameterList &list)
Shows debug information for list.
KEXIUTILS_EXPORT void unsetFocusWithReason(TQWidget *widget, TQFocusEvent::Reason reason)
Unsets focus for widget widget with reason reason.
KEXIUTILS_EXPORT void setFocusWithReason(TQWidget *widget, TQFocusEvent::Reason reason)
Sets focus for widget widget with reason reason.