00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kexiformview.h"
00022
00023 #include <qobjectlist.h>
00024 #include <qfileinfo.h>
00025
00026 #include <formeditor/form.h>
00027 #include <formeditor/formIO.h>
00028 #include <formeditor/formmanager.h>
00029 #include <formeditor/objecttree.h>
00030 #include <formeditor/container.h>
00031 #include <formeditor/widgetpropertyset.h>
00032 #include <formeditor/commands.h>
00033 #include <formeditor/widgetwithsubpropertiesinterface.h>
00034 #include <formeditor/objecttree.h>
00035
00036 #include <kexi.h>
00037 #include <kexidialogbase.h>
00038 #include <kexidragobjects.h>
00039 #include <kexidb/field.h>
00040 #include <kexidb/fieldlist.h>
00041 #include <kexidb/connection.h>
00042 #include <kexidb/cursor.h>
00043 #include <kexidb/utils.h>
00044 #include <kexidb/preparedstatement.h>
00045 #include <tableview/kexitableitem.h>
00046 #include <tableview/kexitableviewdata.h>
00047 #include <widget/kexipropertyeditorview.h>
00048 #include <widget/kexiqueryparameters.h>
00049 #include <kexiutils/utils.h>
00050
00051 #include <koproperty/set.h>
00052 #include <koproperty/property.h>
00053
00054 #include "widgets/kexidbform.h"
00055 #include "kexiformscrollview.h"
00056 #include "kexidatasourcepage.h"
00057 #include "widgets/kexidbautofield.h"
00058
00059 #define NO_DSWIZARD
00060
00062
00063 KexiFormView::KexiFormView(KexiMainWindow *mainWin, QWidget *parent,
00064 const char *name, bool )
00065 : KexiDataAwareView( mainWin, parent, name )
00066 , m_propertySet(0)
00067 , m_resizeMode(KexiFormView::ResizeDefault)
00068 , m_query(0)
00069 , m_queryIsOwned(false)
00070 , m_cursor(0)
00071
00072 {
00073 m_delayedFormContentsResizeOnShow = 0;
00074
00075 QHBoxLayout *l = new QHBoxLayout(this);
00076 l->setAutoAdd(true);
00077
00078 m_scrollView = new KexiFormScrollView(this, viewMode()==Kexi::DataViewMode);
00079
00080
00081
00082
00083 m_dbform = new KexiDBForm(m_scrollView->viewport(), m_scrollView, name);
00084
00085
00086 m_scrollView->setWidget(m_dbform);
00087 m_scrollView->setResizingEnabled(viewMode()!=Kexi::DataViewMode);
00088
00089
00090
00091 if (viewMode()==Kexi::DataViewMode) {
00092 m_scrollView->recordNavigator()->setRecordHandler( m_scrollView );
00093 m_scrollView->viewport()->setPaletteBackgroundColor(m_dbform->palette().active().background());
00094
00095 }
00096 else
00097 {
00098 connect(KFormDesigner::FormManager::self(), SIGNAL(propertySetSwitched(KoProperty::Set*, bool, const QCString&)),
00099 this, SLOT(slotPropertySetSwitched(KoProperty::Set*, bool, const QCString&)));
00100 connect(KFormDesigner::FormManager::self(), SIGNAL(dirty(KFormDesigner::Form *, bool)),
00101 this, SLOT(slotDirty(KFormDesigner::Form *, bool)));
00102
00103 connect(m_dbform, SIGNAL(handleDragMoveEvent(QDragMoveEvent*)),
00104 this, SLOT(slotHandleDragMoveEvent(QDragMoveEvent*)));
00105 connect(m_dbform, SIGNAL(handleDropEvent(QDropEvent*)),
00106 this, SLOT(slotHandleDropEvent(QDropEvent*)));
00107
00108
00109 plugSharedAction("formpart_taborder", KFormDesigner::FormManager::self(), SLOT(editTabOrder()));
00110 plugSharedAction("formpart_adjust_size", KFormDesigner::FormManager::self(), SLOT(adjustWidgetSize()));
00111
00112
00113
00114 plugSharedAction("edit_copy", KFormDesigner::FormManager::self(), SLOT(copyWidget()));
00115 plugSharedAction("edit_cut", KFormDesigner::FormManager::self(), SLOT(cutWidget()));
00116 plugSharedAction("edit_paste", KFormDesigner::FormManager::self(), SLOT(pasteWidget()));
00117 plugSharedAction("edit_delete", KFormDesigner::FormManager::self(), SLOT(deleteWidget()));
00118 plugSharedAction("edit_select_all", KFormDesigner::FormManager::self(), SLOT(selectAll()));
00119 plugSharedAction("formpart_clear_contents", KFormDesigner::FormManager::self(), SLOT(clearWidgetContent()));
00120 plugSharedAction("edit_undo", KFormDesigner::FormManager::self(), SLOT(undo()));
00121 plugSharedAction("edit_redo", KFormDesigner::FormManager::self(), SLOT(redo()));
00122
00123 plugSharedAction("formpart_layout_menu", KFormDesigner::FormManager::self(), 0 );
00124 plugSharedAction("formpart_layout_hbox", KFormDesigner::FormManager::self(), SLOT(layoutHBox()) );
00125 plugSharedAction("formpart_layout_vbox", KFormDesigner::FormManager::self(), SLOT(layoutVBox()) );
00126 plugSharedAction("formpart_layout_grid", KFormDesigner::FormManager::self(), SLOT(layoutGrid()) );
00127 #ifdef KEXI_SHOW_SPLITTER_WIDGET
00128 plugSharedAction("formpart_layout_hsplitter", KFormDesigner::FormManager::self(), SLOT(layoutHSplitter()) );
00129 plugSharedAction("formpart_layout_vsplitter", KFormDesigner::FormManager::self(), SLOT(layoutVSplitter()) );
00130 #endif
00131 plugSharedAction("formpart_break_layout", KFormDesigner::FormManager::self(), SLOT(breakLayout()) );
00132
00133 plugSharedAction("formpart_format_raise", KFormDesigner::FormManager::self(), SLOT(bringWidgetToFront()) );
00134 plugSharedAction("formpart_format_lower", KFormDesigner::FormManager::self(), SLOT(sendWidgetToBack()) );
00135
00136 plugSharedAction("other_widgets_menu", KFormDesigner::FormManager::self(), 0 );
00137 setAvailable("other_widgets_menu", true);
00138
00139 plugSharedAction("formpart_align_menu", KFormDesigner::FormManager::self(), 0 );
00140 plugSharedAction("formpart_align_to_left", KFormDesigner::FormManager::self(),SLOT(alignWidgetsToLeft()) );
00141 plugSharedAction("formpart_align_to_right", KFormDesigner::FormManager::self(), SLOT(alignWidgetsToRight()) );
00142 plugSharedAction("formpart_align_to_top", KFormDesigner::FormManager::self(), SLOT(alignWidgetsToTop()) );
00143 plugSharedAction("formpart_align_to_bottom", KFormDesigner::FormManager::self(), SLOT(alignWidgetsToBottom()) );
00144 plugSharedAction("formpart_align_to_grid", KFormDesigner::FormManager::self(), SLOT(alignWidgetsToGrid()) );
00145
00146 plugSharedAction("formpart_adjust_size_menu", KFormDesigner::FormManager::self(), 0 );
00147 plugSharedAction("formpart_adjust_to_fit", KFormDesigner::FormManager::self(), SLOT(adjustWidgetSize()) );
00148 plugSharedAction("formpart_adjust_size_grid", KFormDesigner::FormManager::self(), SLOT(adjustSizeToGrid()) );
00149 plugSharedAction("formpart_adjust_height_small", KFormDesigner::FormManager::self(), SLOT(adjustHeightToSmall()) );
00150 plugSharedAction("formpart_adjust_height_big", KFormDesigner::FormManager::self(), SLOT(adjustHeightToBig()) );
00151 plugSharedAction("formpart_adjust_width_small", KFormDesigner::FormManager::self(), SLOT(adjustWidthToSmall()) );
00152 plugSharedAction("formpart_adjust_width_big", KFormDesigner::FormManager::self(), SLOT(adjustWidthToBig()) );
00153
00154 plugSharedAction("format_font", KFormDesigner::FormManager::self(), SLOT(changeFont()) );
00155 }
00156
00157 initForm();
00158
00159 KexiDataAwareView::init( m_scrollView, m_scrollView, m_scrollView,
00160 viewMode()==Kexi::DesignViewMode );
00161
00162 connect(this, SIGNAL(focus(bool)), this, SLOT(slotFocus(bool)));
00164
00165 }
00166
00167 KexiFormView::~KexiFormView()
00168 {
00169 if (m_cursor) {
00170 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00171 conn->deleteCursor(m_cursor);
00172 m_cursor = 0;
00173 }
00174 deleteQuery();
00175
00176
00177
00178
00179 m_propertySet = 0;
00180 propertySetSwitched();
00181 }
00182
00183 void
00184 KexiFormView::deleteQuery()
00185 {
00186 if (m_cursor) {
00187 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00188 conn->deleteCursor(m_cursor);
00189 m_cursor = 0;
00190 }
00191
00192 if (m_queryIsOwned) {
00193 delete m_query;
00194 } else {
00196 }
00197 m_query = 0;
00198 }
00199
00200 KFormDesigner::Form*
00201 KexiFormView::form() const
00202 {
00203 if(viewMode()==Kexi::DataViewMode)
00204 return tempData()->previewForm;
00205 else
00206 return tempData()->form;
00207 }
00208
00209 void
00210 KexiFormView::setForm(KFormDesigner::Form *f)
00211 {
00212 if(viewMode()==Kexi::DataViewMode)
00213 tempData()->previewForm = f;
00214 else
00215 tempData()->form = f;
00216 }
00217
00218 void
00219 KexiFormView::initForm()
00220 {
00221 setForm( new KFormDesigner::Form(KexiFormPart::library(), 0, viewMode()==Kexi::DesignViewMode) );
00222
00223
00224 form()->createToplevel(m_dbform, m_dbform);
00225
00226 if (viewMode()==Kexi::DesignViewMode) {
00227
00228 connect(form()->commandHistory(), SIGNAL(commandExecuted()),
00229 KFormDesigner::FormManager::self(), SLOT(slotHistoryCommandExecuted()));
00230 }
00231
00232 const bool newForm = parentDialog()->id() < 0;
00233
00234 KexiDB::FieldList *fields = 0;
00235 if (newForm) {
00236
00237 #ifndef NO_DSWIZARD
00238 KexiDataSourceWizard *w = new KexiDataSourceWizard(mainWin(), (QWidget*)mainWin(), "datasource_wizard");
00239 if(!w->exec())
00240 fields = 0;
00241 else
00242 fields = w->fields();
00243 delete w;
00244 #endif
00245 }
00246
00247 if(fields)
00248 {
00249 QDomDocument dom;
00250 formPart()->generateForm(fields, dom);
00251 KFormDesigner::FormIO::loadFormFromDom(form(), m_dbform, dom);
00253 }
00254 else
00255 loadForm();
00256
00257 if(form()->autoTabStops())
00258 form()->autoAssignTabStops();
00259
00260
00261 m_dbform->updateTabStopsOrder(form());
00262
00263
00264
00265
00266 KFormDesigner::FormManager::self()->importForm(form(), viewMode()==Kexi::DataViewMode);
00267 m_scrollView->setForm(form());
00268
00269
00270
00271
00272
00273
00274 m_scrollView->refreshContentsSize();
00275
00276
00277 if (newForm && !fields) {
00278
00279
00280 m_delayedFormContentsResizeOnShow = 3;
00281 }
00282
00283 updateDataSourcePage();
00284
00285 if (!newForm && viewMode()==Kexi::DesignViewMode) {
00286 form()->clearCommandHistory();
00287 }
00288 }
00289
00290 void KexiFormView::updateAutoFieldsDataSource()
00291 {
00293
00294
00295
00296
00297 QString dataSourceString( m_dbform->dataSource() );
00298 QCString dataSourceMimeTypeString( m_dbform->dataSourceMimeType() );
00299 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00300 KexiDB::TableOrQuerySchema tableOrQuery(
00301 conn, dataSourceString.latin1(), dataSourceMimeTypeString=="kexi/table");
00302 if (!tableOrQuery.table() && !tableOrQuery.query())
00303 return;
00304 for (KFormDesigner::ObjectTreeDictIterator it(*form()->objectTree()->dict());
00305 it.current(); ++it)
00306 {
00307 KexiDBAutoField *afWidget = dynamic_cast<KexiDBAutoField*>( it.current()->widget() );
00308 if (afWidget) {
00309 KexiDB::QueryColumnInfo *colInfo = tableOrQuery.columnInfo( afWidget->dataSource() );
00310 if (colInfo) {
00311 afWidget->setColumnInfo(colInfo);
00312
00313
00314 }
00315 }
00316 }
00317 }
00318
00319 void KexiFormView::updateValuesForSubproperties()
00320 {
00322
00323
00324
00325
00326 QString dataSourceString( m_dbform->dataSource() );
00327 QCString dataSourceMimeTypeString( m_dbform->dataSourceMimeType() );
00328 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00329 KexiDB::TableOrQuerySchema tableOrQuery(
00330 conn, dataSourceString.latin1(), dataSourceMimeTypeString=="kexi/table");
00331 if (!tableOrQuery.table() && !tableOrQuery.query())
00332 return;
00333
00334 for (KFormDesigner::ObjectTreeDictIterator it(*form()->objectTree()->dict());
00335 it.current(); ++it)
00336 {
00337
00339 KFormDesigner::WidgetWithSubpropertiesInterface* subpropIface
00340 = dynamic_cast<KFormDesigner::WidgetWithSubpropertiesInterface*>( it.current()->widget() );
00341 if (subpropIface && subpropIface->subwidget() && it.current()->subproperties() ) {
00342 QWidget *subwidget = subpropIface->subwidget();
00343 QMap<QString, QVariant>* subprops = it.current()->subproperties();
00344 for (QMapConstIterator<QString, QVariant> subpropIt = subprops->constBegin(); subpropIt!=subprops->constEnd(); ++subpropIt) {
00345 kexipluginsdbg << "KexiFormView::loadForm(): delayed setting of the subproperty: widget="
00346 << it.current()->widget()->name() << " prop=" << subpropIt.key() << " val=" << subpropIt.data() << endl;
00347
00348 const int count = subwidget->metaObject()->findProperty(subpropIt.key().latin1(), true);
00349 const QMetaProperty *meta = count!=-1 ? subwidget->metaObject()->property(count, true) : 0;
00350 if (meta) {
00351
00352
00353
00354 if (meta->isSetType() && subpropIt.data().type()==QVariant::StringList) {
00355 QStrList keys;
00356 const QStringList list( subpropIt.data().toStringList() );
00357 for (QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it)
00358 keys.append((*it).latin1());
00359 subwidget->setProperty( subpropIt.key().latin1(), meta->keysToValue(keys) );
00360 }
00361 else {
00362 subwidget->setProperty( subpropIt.key().latin1(), subpropIt.data() );
00363 }
00364 }
00365 }
00366 }
00367 }
00368 }
00369
00371 static void setUnsavedBLOBIdsForDataViewMode(
00372 QWidget* widget, const QMap<QCString, KexiBLOBBuffer::Id_t>& unsavedLocalBLOBsByName)
00373 {
00374 if (-1 != widget->metaObject()->findProperty("pixmapId")) {
00375 const KexiBLOBBuffer::Id_t blobID = unsavedLocalBLOBsByName[ widget->name() ];
00376 if (blobID > 0)
00377 widget->setProperty("pixmapId", (uint )blobID);
00378 }
00379 const QObjectList *list = widget->children();
00380 if (!list)
00381 return;
00382 for (QObjectListIterator it(*list); it.current(); ++it) {
00383 if (dynamic_cast<QWidget*>(it.current()))
00384 setUnsavedBLOBIdsForDataViewMode(dynamic_cast<QWidget*>(it.current()), unsavedLocalBLOBsByName);
00385 }
00386 }
00387
00388 void
00389 KexiFormView::loadForm()
00390 {
00391
00392
00393 kexipluginsdbg << "KexiFormView::loadForm() Loading the form with id : " << parentDialog()->id() << endl;
00394
00395 if(viewMode()==Kexi::DataViewMode && !tempData()->tempForm.isNull() )
00396 {
00397 KFormDesigner::FormIO::loadFormFromString(form(), m_dbform, tempData()->tempForm);
00398 setUnsavedBLOBIdsForDataViewMode( m_dbform, tempData()->unsavedLocalBLOBsByName );
00399 updateAutoFieldsDataSource();
00400 updateValuesForSubproperties();
00401 return;
00402 }
00403
00404
00405 QString data;
00406 loadDataBlock(data);
00407 KFormDesigner::FormIO::loadFormFromString(form(), m_dbform, data);
00408
00409
00410 form()->setAutoTabStops( m_dbform->autoTabStops() );
00411
00412 updateAutoFieldsDataSource();
00413 updateValuesForSubproperties();
00414 }
00415
00416 void
00417 KexiFormView::slotPropertySetSwitched(KoProperty::Set *set, bool forceReload, const QCString& propertyToSelect)
00418 {
00419
00420 if (form() != KFormDesigner::FormManager::self()->activeForm())
00421 return;
00422 m_propertySet = set;
00423 if (forceReload)
00424 propertySetReloaded(true, propertyToSelect);
00425 else
00426 propertySetSwitched();
00427
00428 formPart()->dataSourcePage()->assignPropertySet(m_propertySet);
00429 }
00430
00431 tristate
00432 KexiFormView::beforeSwitchTo(int mode, bool &dontStore)
00433 {
00434 if (mode!=viewMode()) {
00435 if (viewMode()==Kexi::DataViewMode) {
00436 if (!m_scrollView->acceptRowEdit())
00437 return cancelled;
00438
00439 m_scrollView->beforeSwitchView();
00440 }
00441 else {
00442
00443 tempData()->scrollViewContentsPos
00444 = QPoint(m_scrollView->contentsX(), m_scrollView->contentsY());
00445 }
00446 }
00447
00448
00449 dontStore = true;
00450 if(dirty() && (mode == Kexi::DataViewMode) && form()->objectTree()) {
00451 KexiFormPart::TempData* temp = tempData();
00452 if (!KFormDesigner::FormIO::saveFormToString(form(), temp->tempForm))
00453 return false;
00454
00455
00456 temp->unsavedLocalBLOBsByName.clear();
00457 for (QMapConstIterator<QWidget*, KexiBLOBBuffer::Id_t> it = temp->unsavedLocalBLOBs.constBegin();
00458 it!=temp->unsavedLocalBLOBs.constEnd(); ++it)
00459 {
00460 if (!it.key())
00461 continue;
00462 temp->unsavedLocalBLOBsByName.insert( it.key()->name(), it.data() );
00463 }
00464 }
00465
00466 return true;
00467 }
00468
00469 tristate
00470 KexiFormView::afterSwitchFrom(int mode)
00471 {
00472 if (mode == 0 || mode == Kexi::DesignViewMode) {
00473 if (parentDialog()->neverSaved()) {
00474 m_dbform->resize(QSize(400, 300));
00475 m_scrollView->refreshContentsSizeLater(true,true);
00476
00477 }
00478 }
00479
00480 if (mode != 0 && mode != Kexi::DesignViewMode) {
00481
00482 m_scrollView->setContentsPos(tempData()->scrollViewContentsPos.x(),
00483 tempData()->scrollViewContentsPos.y());
00484 }
00485
00486
00487
00488
00489
00490
00491 if((mode == Kexi::DesignViewMode) && viewMode()==Kexi::DataViewMode) {
00492
00493 delete m_dbform;
00494 m_dbform = new KexiDBForm(m_scrollView->viewport(), m_scrollView, "KexiDBForm");
00495 m_scrollView->setWidget(m_dbform);
00496
00497 initForm();
00498
00499
00500
00501 m_scrollView->setContentsPos(0,0);
00502 m_dbform->move(0,0);
00503
00504 }
00505
00506
00507 if (viewMode()==Kexi::DataViewMode) {
00508
00509
00510
00511
00512
00513 }
00514 else {
00515
00516 m_dbform->setAutoTabStops( form()->autoTabStops() );
00517 }
00518
00519 if (viewMode() == Kexi::DataViewMode) {
00520
00521 initDataSource();
00522
00523
00524 m_scrollView->setMainWidgetForEventHandling(parentDialog()->mainWin(), m_dbform);
00525
00526
00527 if (!m_dbform->orderedFocusWidgets()->isEmpty()) {
00528
00529
00530 KexiUtils::unsetFocusWithReason(qApp->focusWidget(), QFocusEvent::Tab);
00531
00532
00533 QPtrListIterator<QWidget> it(*m_dbform->orderedFocusWidgets());
00534 for (;it.current(); ++it) {
00535 KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>(it.current());
00536 if (iface)
00537 kexipluginsdbg << iface->dataSource() << endl;
00538 if (iface && iface->columnInfo() && !iface->isReadOnly()
00540
00541 && !iface->columnInfo()->field->isAutoIncrement())
00542 break;
00543 }
00544 if (!it.current())
00545 it.toFirst();
00546
00547 it.current()->setFocus();
00548 KexiUtils::setFocusWithReason(it.current(), QFocusEvent::Tab);
00549 m_setFocusInternalOnce = it.current();
00550 }
00551
00552 if (m_query)
00553 m_scrollView->selectFirstRow();
00554 }
00555
00556
00557 if (mode == 0)
00558 setDirty( parentDialog()->partItem()->neverSaved() );
00559
00560 if (mode==Kexi::DataViewMode && viewMode()==Kexi::DesignViewMode) {
00561
00562
00563 }
00564
00565 return true;
00566 }
00567
00568 void KexiFormView::initDataSource()
00569 {
00570 deleteQuery();
00571 QString dataSourceString( m_dbform->dataSource() );
00572 QCString dataSourceMimeTypeString( m_dbform->dataSourceMimeType() );
00574 bool ok = !dataSourceString.isEmpty();
00575
00576
00577
00578
00579
00580
00581
00582 KexiDB::TableSchema *tableSchema = 0;
00583 KexiDB::Connection *conn = 0;
00584 QStringList sources;
00585 bool forceReadOnlyDataSource = false;
00586
00587 if (ok) {
00588
00589
00590
00591 m_scrollView->setMainDataSourceWidget(m_dbform);
00592 sources = m_scrollView->usedDataSources();
00593 conn = parentDialog()->mainWin()->project()->dbConnection();
00594 if (dataSourceMimeTypeString.isEmpty()
00595 || dataSourceMimeTypeString=="kexi/table")
00596 {
00597 tableSchema = conn->tableSchema( dataSourceString );
00598 if (tableSchema) {
00599
00600 m_query = new KexiDB::QuerySchema();
00601 m_queryIsOwned = true;
00602
00603 if (dataSourceMimeTypeString.isEmpty())
00604 m_dbform->setDataSourceMimeType("kexi/table");
00605 }
00606 }
00607
00608 if (!tableSchema) {
00609 if (dataSourceMimeTypeString.isEmpty()
00610 || dataSourceMimeTypeString=="kexi/query")
00611 {
00612
00613
00614
00616 m_query = conn->querySchema( dataSourceString );
00617 m_queryIsOwned = false;
00618 ok = m_query != 0;
00619 if (ok && dataSourceMimeTypeString.isEmpty())
00620 m_dbform->setDataSourceMimeType("kexi/query");
00621
00623 forceReadOnlyDataSource = true;
00624 }
00625 else
00626 ok = false;
00627 }
00628 }
00629
00630 QDict<char> invalidSources(997);
00631 if (ok) {
00632 KexiDB::IndexSchema *pkey = tableSchema ? tableSchema->primaryKey() : 0;
00633 if (pkey) {
00634
00635
00636 sources += pkey->names();
00637 kexipluginsdbg << "KexiFormView::initDataSource(): pkey added to data sources: " << pkey->names() << endl;
00638 }
00639 kexipluginsdbg << "KexiFormView::initDataSource(): sources=" << sources << endl;
00640
00641 uint index = 0;
00642 for (QStringList::ConstIterator it = sources.constBegin();
00643 it!=sources.constEnd(); ++it, index++) {
00645 QString fieldName( (*it).lower() );
00646
00647 if (tableSchema && fieldName.startsWith( tableSchema->name().lower()+"." ))
00648 fieldName = fieldName.mid(tableSchema->name().length()+1);
00649
00650 if (!tableSchema && fieldName.startsWith( m_query->name().lower()+"." ))
00651 fieldName = fieldName.mid(m_query->name().length()+1);
00652 KexiDB::Field *f = tableSchema ? tableSchema->field(fieldName) : m_query->field(fieldName);
00653 if (!f) {
00655
00657 invalidSources.insert( fieldName, (const char*)1 );
00658 kexipluginsdbg << "KexiFormView::initDataSource(): invalidSources+=" << index << " ("
00659 << (*it) << ")" << endl;
00660 continue;
00661 }
00662 if (tableSchema) {
00663 if (!m_query->hasField( f )) {
00664
00665 m_query->addField( f );
00666 }
00667 }
00668 }
00669 if (invalidSources.count()==sources.count()) {
00670
00671 deleteQuery();
00672 }
00673 else {
00674 KexiDB::debug( m_query->parameters() );
00675
00676 QValueList<QVariant> params;
00677 {
00678 KexiUtils::WaitCursorRemover remover;
00679 params = KexiQueryParameters::getParameters(this, *conn->driver(), *m_query, ok);
00680 }
00681 if (ok)
00682 m_cursor = conn->executeQuery( *m_query, params );
00683 }
00684 m_scrollView->invalidateDataSources( invalidSources, m_query );
00685 ok = m_cursor!=0;
00686 }
00687
00688 if (!invalidSources.isEmpty())
00689 m_dbform->updateTabStopsOrder();
00690
00691 if (ok) {
00694 KexiTableViewData* data = new KexiTableViewData(m_cursor);
00695 if (forceReadOnlyDataSource)
00696 data->setReadOnly(true);
00697 data->preloadAllRows();
00698
00700
00701
00702
00703
00704
00705
00706
00707
00708 m_scrollView->setData( data, true );
00709 }
00710 else
00711 m_scrollView->setData( 0, false );
00712 }
00713
00714 void
00715 KexiFormView::slotDirty(KFormDesigner::Form *dirtyForm, bool isDirty)
00716 {
00717 if(dirtyForm == form())
00718 KexiViewBase::setDirty(isDirty);
00719 }
00720
00721 KexiDB::SchemaData*
00722 KexiFormView::storeNewData(const KexiDB::SchemaData& sdata, bool &cancel)
00723 {
00724 KexiDB::SchemaData *s = KexiViewBase::storeNewData(sdata, cancel);
00725 kexipluginsdbg << "KexiDBForm::storeNewData(): new id:" << s->id() << endl;
00726
00727 if (!s || cancel) {
00728 delete s;
00729 return 0;
00730 }
00731 if (!storeData()) {
00732
00733 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00734 conn->removeObject( s->id() );
00735 delete s;
00736 return 0;
00737 }
00738 return s;
00739 }
00740
00741 tristate
00742 KexiFormView::storeData(bool dontAsk)
00743 {
00744 Q_UNUSED(dontAsk);
00745 kexipluginsdbg << "KexiDBForm::storeData(): " << parentDialog()->partItem()->name()
00746 << " [" << parentDialog()->id() << "]" << endl;
00747
00748
00750 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00751 KexiDB::TableSchema *blobsTable = conn->tableSchema("kexi__blobs");
00752 if (!blobsTable) {
00754 return false;
00755 }
00756
00757 QStringList blobsFieldNamesWithoutID(blobsTable->names());
00758 blobsFieldNamesWithoutID.pop_front();
00759 KexiDB::FieldList *blobsFieldsWithoutID = blobsTable->subList(blobsFieldNamesWithoutID);
00760
00761 KexiDB::PreparedStatement::Ptr st = conn->prepareStatement(
00762 KexiDB::PreparedStatement::InsertStatement, *blobsFieldsWithoutID);
00763 if (!st) {
00764 delete blobsFieldsWithoutID;
00766 return false;
00767 }
00768 KexiBLOBBuffer *blobBuf = KexiBLOBBuffer::self();
00769 KexiFormView *designFormView
00770 = dynamic_cast<KexiFormView*>( parentDialog()->viewForMode(Kexi::DesignViewMode) );
00771 if (designFormView) {
00772 for (QMapConstIterator<QWidget*, KexiBLOBBuffer::Id_t> it = tempData()->unsavedLocalBLOBs.constBegin();
00773 it!=tempData()->unsavedLocalBLOBs.constEnd(); ++it)
00774 {
00775 if (!it.key()) {
00776 kexipluginswarn << "KexiFormView::storeData(): it.key()==0 !" << endl;
00777 continue;
00778 }
00779 kexipluginsdbg << "name=" << it.key()->name() << " dataID=" << it.data() << endl;
00780 KexiBLOBBuffer::Handle h( blobBuf->objectForId(it.data(), false) );
00781 if (!h)
00782 continue;
00783
00784 QString originalFileName(h.originalFileName());
00785 QFileInfo fi(originalFileName);
00786 QString caption(fi.baseName().replace('_', " ").simplifyWhiteSpace());
00787
00788 if (st) {
00789 *st
00790 << h.data() << originalFileName << caption
00791 << h.mimeType() << (uint)h.folderId();
00792 if (!st->execute()) {
00793 delete blobsFieldsWithoutID;
00794 kexipluginsdbg << " execute error" << endl;
00795 return false;
00796 }
00797 }
00798 delete blobsFieldsWithoutID;
00799 blobsFieldsWithoutID=0;
00800 const Q_ULLONG storedBLOBID = conn->lastInsertedAutoIncValue("o_id", "kexi__blobs");
00801 if ((Q_ULLONG)-1 == storedBLOBID) {
00803 return false;
00804 }
00805 kexipluginsdbg << " storedDataID=" << storedBLOBID << endl;
00806 h.setStoredWidthID((KexiBLOBBuffer::Id_t )storedBLOBID);
00807
00808 const QVariant oldStoredPixmapId( it.key()->property("storedPixmapId") );
00809 it.key()->setProperty("storedPixmapId",
00810 QVariant((uint )storedBLOBID));
00811 KFormDesigner::ObjectTreeItem *widgetItem = designFormView->form()->objectTree()->lookup(it.key()->name());
00812 if (widgetItem)
00813 widgetItem->addModifiedProperty( "storedPixmapId", oldStoredPixmapId );
00814 else
00815 kexipluginswarn << "KexiFormView::storeData(): no '" << widgetItem->name() << "' widget found within a form" << endl;
00816 }
00817 }
00818
00819
00820 QString data;
00821 if (!KFormDesigner::FormIO::saveFormToString(tempData()->form, data))
00822 return false;
00823 if (!storeDataBlock(data))
00824 return false;
00825
00826
00827 tempData()->unsavedLocalBLOBs.clear();
00828
00829 tempData()->tempForm = QString::null;
00830 return true;
00831 }
00832
00833 #if 0
00835 void
00836 KexiFormView::slotWidgetSelected(KFormDesigner::Form *f, bool multiple)
00837 {
00838 if(f != form())
00839 return;
00840
00841 enableFormActions();
00842
00843 setAvailable("edit_copy", true);
00844 setAvailable("edit_cut", true);
00845 setAvailable("edit_clear", true);
00846
00847
00848 setAvailable("formpart_align_menu", multiple);
00849 setAvailable("formpart_align_to_left", multiple);
00850 setAvailable("formpart_align_to_right", multiple);
00851 setAvailable("formpart_align_to_top", multiple);
00852 setAvailable("formpart_align_to_bottom", multiple);
00853
00854 setAvailable("formpart_adjust_size_menu", true);
00855 setAvailable("formpart_adjust_width_small", multiple);
00856 setAvailable("formpart_adjust_width_big", multiple);
00857 setAvailable("formpart_adjust_height_small", multiple);
00858 setAvailable("formpart_adjust_height_big", multiple);
00859
00860 setAvailable("formpart_format_raise", true);
00861 setAvailable("formpart_format_lower", true);
00862
00863
00864 if(!multiple)
00865 {
00866 KFormDesigner::ObjectTreeItem *item = f->objectTree()->lookup( f->selectedWidgets()->first()->name() );
00867 if(item && item->container())
00868 multiple = true;
00869 }
00870
00871 setAvailable("formpart_layout_hbox", multiple);
00872 setAvailable("formpart_layout_vbox", multiple);
00873 setAvailable("formpart_layout_grid", multiple);
00874
00875 KFormDesigner::Container *container = f->activeContainer();
00876 setAvailable("formpart_break_layout", container ?
00877 (container->layoutType() != KFormDesigner::Container::NoLayout) : false );
00878 }
00879
00880 void
00881 KexiFormView::slotFormWidgetSelected(KFormDesigner::Form *f)
00882 {
00883 if(f != form())
00884 return;
00885
00886 disableWidgetActions();
00887 enableFormActions();
00888
00889
00890 setAvailable("formpart_layout_hbox", true);
00891 setAvailable("formpart_layout_vbox", true);
00892 setAvailable("formpart_layout_grid", true);
00893 setAvailable("formpart_break_layout", (f->toplevelContainer()->layoutType() != KFormDesigner::Container::NoLayout));
00894 }
00895
00896 void
00897 KexiFormView::slotNoFormSelected()
00898 {
00899 disableWidgetActions();
00900
00901
00902 setAvailable("edit_paste", false);
00903 setAvailable("edit_undo", false);
00904 setAvailable("edit_redo", false);
00905
00906
00907 setAvailable("formpart_pixmap_collection", false);
00908 setAvailable("formpart_connections", false);
00909 setAvailable("formpart_taborder", false);
00910 setAvailable("formpart_change_style", false);
00911 }
00912
00913 void
00914 KexiFormView::enableFormActions()
00915 {
00916
00917 setAvailable("formpart_pixmap_collection", true);
00918 setAvailable("formpart_connections", true);
00919 setAvailable("formpart_taborder", true);
00920
00921 setAvailable("edit_paste", KFormDesigner::FormManager::self()->isPasteEnabled());
00922 }
00923
00924 void
00925 KexiFormView::disableWidgetActions()
00926 {
00927
00928 setAvailable("edit_copy", false);
00929 setAvailable("edit_cut", false);
00930 setAvailable("edit_clear", false);
00931
00932
00933 setAvailable("formpart_align_menu", false);
00934 setAvailable("formpart_align_to_left", false);
00935 setAvailable("formpart_align_to_right", false);
00936 setAvailable("formpart_align_to_top", false);
00937 setAvailable("formpart_align_to_bottom", false);
00938
00939 setAvailable("formpart_adjust_size_menu", false);
00940 setAvailable("formpart_adjust_width_small", false);
00941 setAvailable("formpart_adjust_width_big", false);
00942 setAvailable("formpart_adjust_height_small", false);
00943 setAvailable("formpart_adjust_height_big", false);
00944
00945 setAvailable("formpart_format_raise", false);
00946 setAvailable("formpart_format_lower", false);
00947
00948 setAvailable("formpart_layout_hbox", false);
00949 setAvailable("formpart_layout_vbox", false);
00950 setAvailable("formpart_layout_grid", false);
00951 setAvailable("formpart_break_layout", false);
00952 }
00953
00954 void
00955 KexiFormView::setUndoEnabled(bool enabled)
00956 {
00957 setAvailable("edit_undo", enabled);
00958 }
00959
00960 void
00961 KexiFormView::setRedoEnabled(bool enabled)
00962 {
00963 setAvailable("edit_redo", enabled);
00964 }
00965 #endif //0
00966
00967 QSize
00968 KexiFormView::preferredSizeHint(const QSize& otherSize)
00969 {
00970 if (parentDialog()->neverSaved()) {
00971
00972
00973 }
00974
00975 return (m_dbform->size()
00976 +QSize(m_scrollView->verticalScrollBar()->isVisible() ? m_scrollView->verticalScrollBar()->width()*3/2 : 10,
00977 m_scrollView->horizontalScrollBar()->isVisible() ? m_scrollView->horizontalScrollBar()->height()*3/2 : 10))
00978 .expandedTo( KexiViewBase::preferredSizeHint(otherSize) );
00979 }
00980
00981 void
00982 KexiFormView::resizeEvent( QResizeEvent *e )
00983 {
00984 if (viewMode()==Kexi::DataViewMode) {
00985 m_scrollView->refreshContentsSizeLater(
00986 e->size().width()!=e->oldSize().width(),
00987 e->size().height()!=e->oldSize().height()
00988 );
00989 }
00990 KexiViewBase::resizeEvent(e);
00991 m_scrollView->updateNavPanelGeometry();
00992 if (m_delayedFormContentsResizeOnShow>0) {
00993 m_delayedFormContentsResizeOnShow--;
00994 m_dbform->resize( e->size() - QSize(30, 30) );
00995 }
00996 }
00997
00998 void
00999 KexiFormView::setFocusInternal()
01000 {
01001 if (viewMode() == Kexi::DataViewMode) {
01002 if (m_dbform->focusWidget()) {
01003
01004 if (m_setFocusInternalOnce) {
01005 KexiUtils::setFocusWithReason(m_setFocusInternalOnce, QFocusEvent::Other);
01006 m_setFocusInternalOnce = 0;
01007 }
01008 else {
01009
01010 }
01011 return;
01012 }
01013 }
01014 QWidget::setFocus();
01015 }
01016
01017 void
01018 KexiFormView::show()
01019 {
01020 KexiDataAwareView::show();
01021
01022
01023
01024
01025
01026 if (viewMode()==Kexi::DataViewMode) {
01027 if (resizeMode() == KexiFormView::ResizeAuto)
01028 m_scrollView->setResizePolicy(QScrollView::AutoOneFit);
01029 }
01030 }
01031
01032 void
01033 KexiFormView::slotFocus(bool in)
01034 {
01035 if(in && form() && KFormDesigner::FormManager::self() && KFormDesigner::FormManager::self()->activeForm() != form()) {
01036 KFormDesigner::FormManager::self()->windowChanged(m_dbform);
01037 updateDataSourcePage();
01038 }
01039 }
01040
01041 void
01042 KexiFormView::updateDataSourcePage()
01043 {
01044 if (viewMode()==Kexi::DesignViewMode) {
01045 QCString dataSourceMimeType, dataSource;
01046 KFormDesigner::WidgetPropertySet *set = KFormDesigner::FormManager::self()->propertySet();
01047 if (set->contains("dataSourceMimeType"))
01048 dataSourceMimeType = (*set)["dataSourceMimeType"].value().toCString();
01049 if (set->contains("dataSource"))
01050 dataSource = (*set)["dataSource"].value().toCString();
01051
01052 formPart()->dataSourcePage()->setDataSource(dataSourceMimeType, dataSource);
01053 }
01054 }
01055
01056 void
01057 KexiFormView::slotHandleDragMoveEvent(QDragMoveEvent* e)
01058 {
01059 if (KexiFieldDrag::canDecodeMultiple( e )) {
01060 e->accept(true);
01061
01062 }
01063 }
01064
01065 void
01066 KexiFormView::slotHandleDropEvent(QDropEvent* e)
01067 {
01068 const QWidget *targetContainerWidget = dynamic_cast<const QWidget*>(sender());
01069 KFormDesigner::ObjectTreeItem *targetContainerWidgetItem = targetContainerWidget
01070 ? form()->objectTree()->lookup( targetContainerWidget->name() ) : 0;
01071 if (targetContainerWidgetItem && targetContainerWidgetItem->container()
01072 && KexiFieldDrag::canDecodeMultiple( e ))
01073 {
01074 QString sourceMimeType, sourceName;
01075 QStringList fields;
01076 if (!KexiFieldDrag::decodeMultiple( e, sourceMimeType, sourceName, fields ))
01077 return;
01078 insertAutoFields(sourceMimeType, sourceName, fields,
01079 targetContainerWidgetItem->container(), e->pos());
01080 }
01081 }
01082
01083 void
01084 KexiFormView::insertAutoFields(const QString& sourceMimeType, const QString& sourceName,
01085 const QStringList& fields, KFormDesigner::Container* targetContainer, const QPoint& _pos)
01086 {
01087 if (fields.isEmpty())
01088 return;
01089
01090 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
01091 KexiDB::TableOrQuerySchema tableOrQuery(conn, sourceName.latin1(), sourceMimeType=="kexi/table");
01092 if (!tableOrQuery.table() && !tableOrQuery.query()) {
01093 kexipluginswarn << "KexiFormView::insertAutoFields(): no such table/query \""
01094 << sourceName << "\"" << endl;
01095 return;
01096 }
01097
01098 QPoint pos(_pos);
01099
01100 if (pos==QPoint(-1,-1)) {
01101 if (m_widgetGeometryForRecentInsertAutoFields.isValid()) {
01102 pos = m_widgetGeometryForRecentInsertAutoFields.bottomLeft()
01103 + QPoint(0,form()->gridSize());
01104 }
01105 else {
01106 pos = QPoint(40, 40);
01107 }
01108 }
01109
01110
01111 KFormDesigner::FormManager::self()->blockPropertyEditorUpdating(this);
01112
01114
01115
01116 KFormDesigner::WidgetList widgetsToSelect;
01117 KFormDesigner::CommandGroup *group = new KFormDesigner::CommandGroup(
01118 fields.count()==1 ? i18n("Insert AutoField widget") : i18n("Insert %1 AutoField widgets").arg(fields.count()),
01119 KFormDesigner::FormManager::self()->propertySet()
01120 );
01121
01122 foreach( QStringList::ConstIterator, it, fields ) {
01123 KexiDB::QueryColumnInfo* column = tableOrQuery.columnInfo(*it);
01124 if (!column) {
01125 kexipluginswarn << "KexiFormView::insertAutoFields(): no such field \""
01126 << *it << "\" in table/query \"" << sourceName << "\"" << endl;
01127 continue;
01128 }
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 KFormDesigner::InsertWidgetCommand *insertCmd
01142 = new KFormDesigner::InsertWidgetCommand(targetContainer,
01144 "KexiDBAutoField",
01146 pos, column->aliasOrName()
01147 );
01148 insertCmd->execute();
01149 group->addCommand(insertCmd, false);
01150
01151 KFormDesigner::ObjectTreeItem *newWidgetItem
01152 = form()->objectTree()->dict()->find(insertCmd->widgetName());
01153 KexiDBAutoField* newWidget
01154 = newWidgetItem ? dynamic_cast<KexiDBAutoField*>(newWidgetItem->widget()) : 0;
01155 widgetsToSelect.append(newWidget);
01156
01157 KFormDesigner::CommandGroup *subGroup
01158 = new KFormDesigner::CommandGroup("", KFormDesigner::FormManager::self()->propertySet());
01159 QMap<QCString, QVariant> propValues;
01160 propValues.insert("dataSource", column->aliasOrName());
01161 propValues.insert("fieldTypeInternal", (int)column->field->type());
01162 propValues.insert("fieldCaptionInternal", column->captionOrAliasOrName());
01163 KFormDesigner::FormManager::self()->propertySet()->createPropertyCommandsInDesignMode(
01164 newWidget, propValues, subGroup, false,
01165 true );
01166 subGroup->execute();
01167 group->addCommand( subGroup, false );
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178 KFormDesigner::WidgetList list;
01179 list.append(newWidget);
01180 KFormDesigner::AdjustSizeCommand *adjustCommand
01181 = new KFormDesigner::AdjustSizeCommand(KFormDesigner::AdjustSizeCommand::SizeToFit,
01182 list, form());
01183 adjustCommand->execute();
01184 group->addCommand( adjustCommand,
01185 false
01186 );
01187
01188 if (newWidget) {
01189 pos.setY( pos.y() + newWidget->height() + form()->gridSize());
01190 }
01191 }
01192 if (widgetsToSelect.last()) {
01193
01194 QRect oldFormRect( m_dbform->geometry() );
01195 QRect newFormRect( oldFormRect );
01196 newFormRect.setWidth(QMAX(m_dbform->width(), widgetsToSelect.last()->geometry().right()+1));
01197 newFormRect.setHeight(QMAX(m_dbform->height(), widgetsToSelect.last()->geometry().bottom()+1));
01198 if (newFormRect != oldFormRect) {
01199
01200 m_dbform->setGeometry( newFormRect );
01201
01202 KFormDesigner::PropertyCommand *resizeFormCommand = new KFormDesigner::PropertyCommand(
01203 KFormDesigner::FormManager::self()->propertySet(), m_dbform->name(),
01204 oldFormRect, newFormRect, "geometry");
01205 group->addCommand(resizeFormCommand, true);
01206 }
01207
01208
01209 m_widgetGeometryForRecentInsertAutoFields = widgetsToSelect.last()->geometry();
01210 }
01211
01212
01213 form()->addCommand( group, true );
01214
01215
01216
01217
01218 group->resetAllowExecuteFlags();
01219
01220 m_scrollView->repaint();
01221 m_scrollView->viewport()->repaint();
01222 m_scrollView->repaintContents();
01223 m_scrollView->updateContents();
01224 m_scrollView->clipper()->repaint();
01225 m_scrollView->refreshContentsSize();
01226
01227
01228 if (widgetsToSelect.count()>1) {
01229 form()->setSelectedWidget(0);
01230 foreach_list (KFormDesigner::WidgetListIterator, it, widgetsToSelect)
01231 form()->setSelectedWidget(it.current(), true, true);
01232 }
01233
01234
01235 KFormDesigner::FormManager::self()->unblockPropertyEditorUpdating(this, KFormDesigner::FormManager::self()->propertySet());
01236 }
01237
01238 void
01239 KexiFormView::setUnsavedLocalBLOB(QWidget *widget, KexiBLOBBuffer::Id_t id)
01240 {
01242 if (id==0)
01243 tempData()->unsavedLocalBLOBs.remove(widget);
01244 else
01245 tempData()->unsavedLocalBLOBs.insert(widget, id);
01246 }
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277 #include "kexiformview.moc"
01278