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