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
00346 const int count = subwidget->metaObject()->findProperty(subpropIt.key().latin1(), true);
00347 const QMetaProperty *meta = count!=-1 ? subwidget->metaObject()->property(count, true) : 0;
00348 if (meta) {
00349
00350
00351
00352 if (meta->isSetType() && subpropIt.data().type()==QVariant::StringList) {
00353 QStrList keys;
00354 const QStringList list( subpropIt.data().toStringList() );
00355 for (QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it)
00356 keys.append((*it).latin1());
00357 subwidget->setProperty( subpropIt.key().latin1(), meta->keysToValue(keys) );
00358 }
00359 else {
00360 subwidget->setProperty( subpropIt.key().latin1(), subpropIt.data() );
00361 }
00362 }
00363 }
00364 }
00365 }
00366 }
00367
00368 void
00369 KexiFormView::loadForm()
00370 {
00371
00372
00373 kexipluginsdbg << "KexiFormView::loadForm() Loading the form with id : " << parentDialog()->id() << endl;
00374
00375 if(viewMode()==Kexi::DataViewMode && !tempData()->tempForm.isNull() )
00376 {
00377 KFormDesigner::FormIO::loadFormFromString(form(), m_dbform, tempData()->tempForm);
00378 updateAutoFieldsDataSource();
00379 updateValuesForSubproperties();
00380 return;
00381 }
00382
00383
00384 QString data;
00385 loadDataBlock(data);
00386 KFormDesigner::FormIO::loadFormFromString(form(), m_dbform, data);
00387
00388
00389 form()->setAutoTabStops( m_dbform->autoTabStops() );
00390
00391 updateAutoFieldsDataSource();
00392 updateValuesForSubproperties();
00393 }
00394
00395 void
00396 KexiFormView::slotPropertySetSwitched(KoProperty::Set *set, bool forceReload, const QCString& propertyToSelect)
00397 {
00398
00399 if (form() != KFormDesigner::FormManager::self()->activeForm())
00400 return;
00401 m_propertySet = set;
00402 if (forceReload)
00403 propertySetReloaded(true, propertyToSelect);
00404 else
00405 propertySetSwitched();
00406
00407 formPart()->dataSourcePage()->assignPropertySet(m_propertySet);
00408 }
00409
00410 tristate
00411 KexiFormView::beforeSwitchTo(int mode, bool &dontStore)
00412 {
00413 if (mode!=viewMode()) {
00414 if (viewMode()==Kexi::DataViewMode) {
00415 if (!m_scrollView->acceptRowEdit())
00416 return cancelled;
00417
00418 m_scrollView->beforeSwitchView();
00419 }
00420 else {
00421
00422 tempData()->scrollViewContentsPos
00423 = QPoint(m_scrollView->contentsX(), m_scrollView->contentsY());
00424 }
00425 }
00426
00427
00428 dontStore = true;
00429 if(dirty() && (mode == Kexi::DataViewMode) && form()->objectTree()) {
00430 KexiFormPart::TempData* temp = tempData();
00431 if (!KFormDesigner::FormIO::saveFormToString(form(), temp->tempForm))
00432 return false;
00433 }
00434
00435 return true;
00436 }
00437
00438 tristate
00439 KexiFormView::afterSwitchFrom(int mode)
00440 {
00441 if (mode == 0 || mode == Kexi::DesignViewMode) {
00442 if (parentDialog()->neverSaved()) {
00443 m_dbform->resize(QSize(400, 300));
00444 m_scrollView->refreshContentsSizeLater(true,true);
00445
00446 }
00447 }
00448
00449 if (mode != 0 && mode != Kexi::DesignViewMode) {
00450
00451 m_scrollView->setContentsPos(tempData()->scrollViewContentsPos.x(),
00452 tempData()->scrollViewContentsPos.y());
00453 }
00454
00455
00456
00457
00458
00459
00460 if((mode == Kexi::DesignViewMode) && viewMode()==Kexi::DataViewMode) {
00461
00462 delete m_dbform;
00463 m_dbform = new KexiDBForm(m_scrollView->viewport(), m_scrollView, "KexiDBForm");
00464 m_scrollView->setWidget(m_dbform);
00465
00466 initForm();
00467
00468
00469
00470 m_scrollView->setContentsPos(0,0);
00471 m_dbform->move(0,0);
00472
00473 }
00474
00475
00476 if (viewMode()==Kexi::DataViewMode) {
00477
00478
00479
00480
00481
00482 }
00483 else {
00484
00485 m_dbform->setAutoTabStops( form()->autoTabStops() );
00486 }
00487
00488 if (viewMode() == Kexi::DataViewMode) {
00489
00490 initDataSource();
00491
00492
00493 m_scrollView->setMainWidgetForEventHandling(parentDialog()->mainWin(), m_dbform);
00494
00495
00496 if (!m_dbform->orderedFocusWidgets()->isEmpty()) {
00497
00498
00499 QEvent fe( QEvent::FocusOut );
00500 QFocusEvent::setReason(QFocusEvent::Tab);
00501 QApplication::sendEvent( qApp->focusWidget(), &fe );
00502 QFocusEvent::resetReason();
00503
00504
00505 QPtrListIterator<QWidget> it(*m_dbform->orderedFocusWidgets());
00506 for (;it.current(); ++it) {
00507 KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>(it.current());
00508 if (iface)
00509 kexipluginsdbg << iface->dataSource() << endl;
00510 if (iface && iface->columnInfo() && !iface->isReadOnly()
00512
00513 && !iface->columnInfo()->field->isAutoIncrement())
00514 break;
00515 }
00516 if (!it.current())
00517 it.toFirst();
00518
00519 it.current()->setFocus();
00520 SET_FOCUS_USING_REASON(it.current(), QFocusEvent::Tab);
00521 m_setFocusInternalOnce = it.current();
00522 }
00523
00524 if (m_query)
00525 m_scrollView->selectFirstRow();
00526 }
00527
00528
00529 if (mode == 0)
00530 setDirty( parentDialog()->partItem()->neverSaved() );
00531
00532 if (mode==Kexi::DataViewMode && viewMode()==Kexi::DesignViewMode) {
00533
00534
00535 }
00536
00537 return true;
00538 }
00539
00540 void KexiFormView::initDataSource()
00541 {
00542 deleteQuery();
00543 QString dataSourceString( m_dbform->dataSource() );
00544 QCString dataSourceMimeTypeString( m_dbform->dataSourceMimeType() );
00546 bool ok = !dataSourceString.isEmpty();
00547
00548
00549
00550
00551
00552
00553
00554 KexiDB::TableSchema *tableSchema = 0;
00555 KexiDB::Connection *conn = 0;
00556 QStringList sources;
00557 bool forceReadOnlyDataSource = false;
00558
00559 if (ok) {
00560
00561
00562
00563 m_scrollView->setMainDataSourceWidget(m_dbform);
00564 sources = m_scrollView->usedDataSources();
00565 conn = parentDialog()->mainWin()->project()->dbConnection();
00566 if (dataSourceMimeTypeString.isEmpty()
00567 || dataSourceMimeTypeString=="kexi/table")
00568 {
00569 tableSchema = conn->tableSchema( dataSourceString );
00570 if (tableSchema) {
00571
00572 m_query = new KexiDB::QuerySchema();
00573 m_queryIsOwned = true;
00574
00575 if (dataSourceMimeTypeString.isEmpty())
00576 m_dbform->setDataSourceMimeType("kexi/table");
00577 }
00578 }
00579
00580 if (!tableSchema) {
00581 if (dataSourceMimeTypeString.isEmpty()
00582 || dataSourceMimeTypeString=="kexi/query")
00583 {
00584
00585
00586
00588 m_query = conn->querySchema( dataSourceString );
00589 m_queryIsOwned = false;
00590 ok = m_query != 0;
00591 if (ok && dataSourceMimeTypeString.isEmpty())
00592 m_dbform->setDataSourceMimeType("kexi/query");
00593
00595 forceReadOnlyDataSource = true;
00596 }
00597 else
00598 ok = false;
00599 }
00600 }
00601
00602 QDict<char> invalidSources(997);
00603 if (ok) {
00604 KexiDB::IndexSchema *pkey = tableSchema ? tableSchema->primaryKey() : 0;
00605 if (pkey) {
00606
00607
00608 sources += pkey->names();
00609 kexipluginsdbg << "KexiFormView::initDataSource(): pkey added to data sources: " << pkey->names() << endl;
00610 }
00611 kexipluginsdbg << "KexiFormView::initDataSource(): sources=" << sources << endl;
00612
00613 uint index = 0;
00614 for (QStringList::ConstIterator it = sources.constBegin();
00615 it!=sources.constEnd(); ++it, index++) {
00617 QString fieldName( (*it).lower() );
00618
00619 if (tableSchema && fieldName.startsWith( tableSchema->name().lower()+"." ))
00620 fieldName = fieldName.mid(tableSchema->name().length()+1);
00621
00622 if (!tableSchema && fieldName.startsWith( m_query->name().lower()+"." ))
00623 fieldName = fieldName.mid(m_query->name().length()+1);
00624 KexiDB::Field *f = tableSchema ? tableSchema->field(fieldName) : m_query->field(fieldName);
00625 if (!f) {
00627
00629 invalidSources.insert( fieldName, (const char*)1 );
00630 kexipluginsdbg << "KexiFormView::initDataSource(): invalidSources+=" << index << " ("
00631 << (*it) << ")" << endl;
00632 continue;
00633 }
00634 if (tableSchema) {
00635 if (!m_query->hasField( f )) {
00636
00637 m_query->addField( f );
00638 }
00639 }
00640 }
00641 if (invalidSources.count()==sources.count()) {
00642
00643 deleteQuery();
00644 }
00645 else {
00646 m_cursor = conn->executeQuery( *m_query );
00647 }
00648 m_scrollView->invalidateDataSources( invalidSources, m_query );
00649 ok = m_cursor!=0;
00650 }
00651
00652 if (!invalidSources.isEmpty())
00653 m_dbform->updateTabStopsOrder();
00654
00655 if (ok) {
00658 KexiTableViewData* data = new KexiTableViewData(m_cursor);
00659 if (forceReadOnlyDataSource)
00660 data->setReadOnly(true);
00661 data->preloadAllRows();
00662
00664
00665
00666
00667
00668
00669
00670
00671
00672 m_scrollView->setData( data, true );
00673 }
00674 else
00675 m_scrollView->setData( 0, false );
00676 }
00677
00678 void
00679 KexiFormView::slotDirty(KFormDesigner::Form *dirtyForm, bool isDirty)
00680 {
00681 if(dirtyForm == form())
00682 KexiViewBase::setDirty(isDirty);
00683 }
00684
00685 KexiDB::SchemaData*
00686 KexiFormView::storeNewData(const KexiDB::SchemaData& sdata, bool &cancel)
00687 {
00688 KexiDB::SchemaData *s = KexiViewBase::storeNewData(sdata, cancel);
00689 kexipluginsdbg << "KexiDBForm::storeNewData(): new id:" << s->id() << endl;
00690
00691 if (!s || cancel) {
00692 delete s;
00693 return 0;
00694 }
00695 if (!storeData()) {
00696
00697 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00698 conn->removeObject( s->id() );
00699 delete s;
00700 return 0;
00701 }
00702 return s;
00703 }
00704
00705 tristate
00706 KexiFormView::storeData(bool dontAsk)
00707 {
00708 Q_UNUSED(dontAsk);
00709 kexipluginsdbg << "KexiDBForm::storeData(): " << parentDialog()->partItem()->name()
00710 << " [" << parentDialog()->id() << "]" << endl;
00711
00712
00714 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00715 KexiDB::TableSchema *blobsTable = conn->tableSchema("kexi__blobs");
00716 if (!blobsTable) {
00718 return false;
00719 }
00720
00721 QStringList blobsFieldNamesWithoutID(blobsTable->names());
00722 blobsFieldNamesWithoutID.pop_front();
00723 KexiDB::FieldList *blobsFieldsWithoutID = blobsTable->subList(blobsFieldNamesWithoutID);
00724
00725 KexiDB::PreparedStatement::Ptr st = conn->prepareStatement(
00726 KexiDB::PreparedStatement::InsertStatement, *blobsFieldsWithoutID);
00727
00729 if (!st) {
00730 delete blobsFieldsWithoutID;
00732 return false;
00733 }
00734
00735 KexiBLOBBuffer *blobBuf = KexiBLOBBuffer::self();
00736 for (QMapConstIterator<QWidget*, KexiBLOBBuffer::Id_t> it = m_unsavedLocalBLOBs.constBegin();
00737 it!=m_unsavedLocalBLOBs.constEnd(); ++it)
00738 {
00739 if (!it.key()) {
00740 kexipluginswarn << "KexiFormView::storeData(): it.key()==0 !" << endl;
00741 continue;
00742 }
00743 kexipluginsdbg << "name=" << it.key()->name() << " dataID=" << it.data() << endl;
00744 KexiBLOBBuffer::Handle h( blobBuf->objectForId(it.data(), false) );
00745 if (!h)
00746 continue;
00747
00748 QString originalFileName(h.originalFileName());
00749 QFileInfo fi(originalFileName);
00750 QString caption(fi.baseName().replace('_', " ").simplifyWhiteSpace());
00752
00753
00754 if (st) {
00755 *st
00756 << h.data() << originalFileName << caption
00757 << h.mimeType() << (uint)h.folderId();
00758 if (!st->execute()) {
00759 delete blobsFieldsWithoutID;
00760 kexipluginsdbg << " execute error" << endl;
00761 return false;
00762 }
00763 }
00765 #if 0
00766 if (!conn->insertRecord(*blobsFieldsWithoutID, h.data(), originalFileName, caption, h.mimeType())) {
00767 delete blobsFieldsWithoutID;
00769 return false;
00770 }
00771 #endif
00772 delete blobsFieldsWithoutID;
00773 blobsFieldsWithoutID=0;
00774 const Q_ULLONG storedBLOBID = conn->lastInsertedAutoIncValue("o_id", "kexi__blobs");
00775 if ((Q_ULLONG)-1 == storedBLOBID) {
00777 return false;
00778 }
00779 kexipluginsdbg << " storedDataID=" << storedBLOBID << endl;
00780 h.setStoredWidthID((KexiBLOBBuffer::Id_t )storedBLOBID);
00781
00782 const QVariant oldStoredPixmapId( it.key()->property("storedPixmapId") );
00783 it.key()->setProperty("storedPixmapId",
00784 QVariant((uint )storedBLOBID));
00785 KFormDesigner::ObjectTreeItem *widgetItem = form()->objectTree()->lookup(it.key()->name());
00786 if (widgetItem)
00787 widgetItem->addModifiedProperty( "storedPixmapId", oldStoredPixmapId );
00788 else
00789 kexipluginswarn << "KexiFormView::storeData(): no '" << widgetItem->name() << "' widget found within a form" << endl;
00790 }
00791
00792
00793
00794 QString data;
00795 if (!KFormDesigner::FormIO::saveFormToString(tempData()->form, data))
00796 return false;
00797 if (!storeDataBlock(data))
00798 return false;
00799
00800
00801 m_unsavedLocalBLOBs.clear();
00802
00803 tempData()->tempForm = QString::null;
00804 return true;
00805 }
00806
00807 #if 0
00809 void
00810 KexiFormView::slotWidgetSelected(KFormDesigner::Form *f, bool multiple)
00811 {
00812 if(f != form())
00813 return;
00814
00815 enableFormActions();
00816
00817 setAvailable("edit_copy", true);
00818 setAvailable("edit_cut", true);
00819 setAvailable("edit_clear", true);
00820
00821
00822 setAvailable("formpart_align_menu", multiple);
00823 setAvailable("formpart_align_to_left", multiple);
00824 setAvailable("formpart_align_to_right", multiple);
00825 setAvailable("formpart_align_to_top", multiple);
00826 setAvailable("formpart_align_to_bottom", multiple);
00827
00828 setAvailable("formpart_adjust_size_menu", true);
00829 setAvailable("formpart_adjust_width_small", multiple);
00830 setAvailable("formpart_adjust_width_big", multiple);
00831 setAvailable("formpart_adjust_height_small", multiple);
00832 setAvailable("formpart_adjust_height_big", multiple);
00833
00834 setAvailable("formpart_format_raise", true);
00835 setAvailable("formpart_format_lower", true);
00836
00837
00838 if(!multiple)
00839 {
00840 KFormDesigner::ObjectTreeItem *item = f->objectTree()->lookup( f->selectedWidgets()->first()->name() );
00841 if(item && item->container())
00842 multiple = true;
00843 }
00844
00845 setAvailable("formpart_layout_hbox", multiple);
00846 setAvailable("formpart_layout_vbox", multiple);
00847 setAvailable("formpart_layout_grid", multiple);
00848
00849 KFormDesigner::Container *container = f->activeContainer();
00850 setAvailable("formpart_break_layout", container ?
00851 (container->layoutType() != KFormDesigner::Container::NoLayout) : false );
00852 }
00853
00854 void
00855 KexiFormView::slotFormWidgetSelected(KFormDesigner::Form *f)
00856 {
00857 if(f != form())
00858 return;
00859
00860 disableWidgetActions();
00861 enableFormActions();
00862
00863
00864 setAvailable("formpart_layout_hbox", true);
00865 setAvailable("formpart_layout_vbox", true);
00866 setAvailable("formpart_layout_grid", true);
00867 setAvailable("formpart_break_layout", (f->toplevelContainer()->layoutType() != KFormDesigner::Container::NoLayout));
00868 }
00869
00870 void
00871 KexiFormView::slotNoFormSelected()
00872 {
00873 disableWidgetActions();
00874
00875
00876 setAvailable("edit_paste", false);
00877 setAvailable("edit_undo", false);
00878 setAvailable("edit_redo", false);
00879
00880
00881 setAvailable("formpart_pixmap_collection", false);
00882 setAvailable("formpart_connections", false);
00883 setAvailable("formpart_taborder", false);
00884 setAvailable("formpart_change_style", false);
00885 }
00886
00887 void
00888 KexiFormView::enableFormActions()
00889 {
00890
00891 setAvailable("formpart_pixmap_collection", true);
00892 setAvailable("formpart_connections", true);
00893 setAvailable("formpart_taborder", true);
00894
00895 setAvailable("edit_paste", KFormDesigner::FormManager::self()->isPasteEnabled());
00896 }
00897
00898 void
00899 KexiFormView::disableWidgetActions()
00900 {
00901
00902 setAvailable("edit_copy", false);
00903 setAvailable("edit_cut", false);
00904 setAvailable("edit_clear", false);
00905
00906
00907 setAvailable("formpart_align_menu", false);
00908 setAvailable("formpart_align_to_left", false);
00909 setAvailable("formpart_align_to_right", false);
00910 setAvailable("formpart_align_to_top", false);
00911 setAvailable("formpart_align_to_bottom", false);
00912
00913 setAvailable("formpart_adjust_size_menu", false);
00914 setAvailable("formpart_adjust_width_small", false);
00915 setAvailable("formpart_adjust_width_big", false);
00916 setAvailable("formpart_adjust_height_small", false);
00917 setAvailable("formpart_adjust_height_big", false);
00918
00919 setAvailable("formpart_format_raise", false);
00920 setAvailable("formpart_format_lower", false);
00921
00922 setAvailable("formpart_layout_hbox", false);
00923 setAvailable("formpart_layout_vbox", false);
00924 setAvailable("formpart_layout_grid", false);
00925 setAvailable("formpart_break_layout", false);
00926 }
00927
00928 void
00929 KexiFormView::setUndoEnabled(bool enabled)
00930 {
00931 setAvailable("edit_undo", enabled);
00932 }
00933
00934 void
00935 KexiFormView::setRedoEnabled(bool enabled)
00936 {
00937 setAvailable("edit_redo", enabled);
00938 }
00939 #endif //0
00940
00941 QSize
00942 KexiFormView::preferredSizeHint(const QSize& otherSize)
00943 {
00944 if (parentDialog()->neverSaved()) {
00945
00946
00947 }
00948
00949 return (m_dbform->size()
00950 +QSize(m_scrollView->verticalScrollBar()->isVisible() ? m_scrollView->verticalScrollBar()->width()*3/2 : 10,
00951 m_scrollView->horizontalScrollBar()->isVisible() ? m_scrollView->horizontalScrollBar()->height()*3/2 : 10))
00952 .expandedTo( KexiViewBase::preferredSizeHint(otherSize) );
00953 }
00954
00955 void
00956 KexiFormView::resizeEvent( QResizeEvent *e )
00957 {
00958 if (viewMode()==Kexi::DataViewMode) {
00959 m_scrollView->refreshContentsSizeLater(
00960 e->size().width()!=e->oldSize().width(),
00961 e->size().height()!=e->oldSize().height()
00962 );
00963 }
00964 KexiViewBase::resizeEvent(e);
00965 m_scrollView->updateNavPanelGeometry();
00966 if (m_delayedFormContentsResizeOnShow>0) {
00967 m_delayedFormContentsResizeOnShow--;
00968 m_dbform->resize( e->size() - QSize(30, 30) );
00969 }
00970 }
00971
00972 void
00973 KexiFormView::setFocusInternal()
00974 {
00975 if (viewMode() == Kexi::DataViewMode) {
00976 if (m_dbform->focusWidget()) {
00977
00978 if (m_setFocusInternalOnce) {
00979 SET_FOCUS_USING_REASON(m_setFocusInternalOnce, QFocusEvent::Other);
00980 m_setFocusInternalOnce = 0;
00981 }
00982 else {
00983
00984 }
00985 return;
00986 }
00987 }
00988 QWidget::setFocus();
00989 }
00990
00991 void
00992 KexiFormView::show()
00993 {
00994 KexiDataAwareView::show();
00995
00996
00997
00998
00999
01000 if (viewMode()==Kexi::DataViewMode) {
01001 if (resizeMode() == KexiFormView::ResizeAuto)
01002 m_scrollView->setResizePolicy(QScrollView::AutoOneFit);
01003 }
01004 }
01005
01006 void
01007 KexiFormView::slotFocus(bool in)
01008 {
01009 if(in && form() && KFormDesigner::FormManager::self() && KFormDesigner::FormManager::self()->activeForm() != form()) {
01010 KFormDesigner::FormManager::self()->windowChanged(m_dbform);
01011 updateDataSourcePage();
01012 }
01013 }
01014
01015 void
01016 KexiFormView::updateDataSourcePage()
01017 {
01018 if (viewMode()==Kexi::DesignViewMode) {
01019 QCString dataSourceMimeType, dataSource;
01020 KFormDesigner::WidgetPropertySet *set = KFormDesigner::FormManager::self()->propertySet();
01021 if (set->contains("dataSourceMimeType"))
01022 dataSourceMimeType = (*set)["dataSourceMimeType"].value().toCString();
01023 if (set->contains("dataSource"))
01024 dataSource = (*set)["dataSource"].value().toCString();
01025
01026 formPart()->dataSourcePage()->setDataSource(dataSourceMimeType, dataSource);
01027 }
01028 }
01029
01030 void
01031 KexiFormView::slotHandleDragMoveEvent(QDragMoveEvent* e)
01032 {
01033 if (KexiFieldDrag::canDecodeMultiple( e )) {
01034 e->accept(true);
01035
01036 }
01037 }
01038
01039 void
01040 KexiFormView::slotHandleDropEvent(QDropEvent* e)
01041 {
01042 if (KexiFieldDrag::canDecodeMultiple( e )) {
01043 QString sourceMimeType, sourceName;
01044 QStringList fields;
01045 if (!KexiFieldDrag::decodeMultiple( e, sourceMimeType, sourceName, fields ))
01046 return;
01047 insertAutoFields(sourceMimeType, sourceName, fields, e->pos());
01048 }
01049 }
01050
01051 void
01052 KexiFormView::insertAutoFields(const QString& sourceMimeType, const QString& sourceName,
01053 const QStringList& fields, const QPoint& _pos)
01054 {
01055 if (fields.isEmpty())
01056 return;
01057
01058 KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
01059 KexiDB::TableOrQuerySchema tableOrQuery(conn, sourceName.latin1(), sourceMimeType=="kexi/table");
01060 if (!tableOrQuery.table() && !tableOrQuery.query()) {
01061 kexipluginswarn << "KexiFormView::insertAutoFields(): no such table/query \""
01062 << sourceName << "\"" << endl;
01063 return;
01064 }
01065
01066 QPoint pos(_pos);
01067
01068 if (pos==QPoint(-1,-1)) {
01069 if (m_widgetGeometryForRecentInsertAutoFields.isValid()) {
01070 pos = m_widgetGeometryForRecentInsertAutoFields.bottomLeft()
01071 + QPoint(0,form()->gridSize());
01072 }
01073 else {
01074 pos = QPoint(40, 40);
01075 }
01076 }
01077
01078
01079 KFormDesigner::FormManager::self()->blockPropertyEditorUpdating(this);
01080
01082
01083
01084 KFormDesigner::WidgetList widgetsToSelect;
01085 KFormDesigner::CommandGroup *group = new KFormDesigner::CommandGroup(
01086 fields.count()==1 ? i18n("Insert AutoField widget") : i18n("Insert %1 AutoField widgets").arg(fields.count()),
01087 KFormDesigner::FormManager::self()->propertySet()
01088 );
01089
01090 foreach( QStringList::ConstIterator, it, fields ) {
01091 KexiDB::QueryColumnInfo* column = tableOrQuery.columnInfo(*it);
01092 if (!column) {
01093 kexipluginswarn << "KexiFormView::insertAutoFields(): no such field \""
01094 << *it << "\" in table/query \"" << sourceName << "\"" << endl;
01095 continue;
01096 }
01098 KFormDesigner::Container *targetContainer;
01099 QWidget* targetContainerWidget = QApplication::widgetAt(pos, true);
01100 while (targetContainerWidget
01101 && !dynamic_cast<KFormDesigner::Container*>(targetContainerWidget))
01102 {
01103 targetContainerWidget = targetContainerWidget->parentWidget();
01104 }
01105 if (dynamic_cast<KFormDesigner::Container*>(targetContainerWidget))
01106 targetContainer = dynamic_cast<KFormDesigner::Container*>(targetContainerWidget);
01107 else
01108 targetContainer = form()->toplevelContainer();
01109 KFormDesigner::InsertWidgetCommand *insertCmd
01110 = new KFormDesigner::InsertWidgetCommand(targetContainer,
01112 "KexiDBAutoField",
01114 pos, column->aliasOrName()
01115 );
01116 insertCmd->execute();
01117 group->addCommand(insertCmd, false);
01118
01119 KFormDesigner::ObjectTreeItem *newWidgetItem
01120 = form()->objectTree()->dict()->find(insertCmd->widgetName());
01121 KexiDBAutoField* newWidget
01122 = newWidgetItem ? dynamic_cast<KexiDBAutoField*>(newWidgetItem->widget()) : 0;
01123 widgetsToSelect.append(newWidget);
01124
01125 KFormDesigner::CommandGroup *subGroup
01126 = new KFormDesigner::CommandGroup("", KFormDesigner::FormManager::self()->propertySet());
01127 QMap<QCString, QVariant> propValues;
01128 propValues.insert("dataSource", column->aliasOrName());
01129 propValues.insert("fieldTypeInternal", (int)column->field->type());
01130 propValues.insert("fieldCaptionInternal", column->captionOrAliasOrName());
01131 KFormDesigner::FormManager::self()->propertySet()->createPropertyCommandsInDesignMode(
01132 newWidget, propValues, subGroup, false,
01133 true );
01134 subGroup->execute();
01135 group->addCommand( subGroup, false );
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146 KFormDesigner::WidgetList list;
01147 list.append(newWidget);
01148 KFormDesigner::AdjustSizeCommand *adjustCommand
01149 = new KFormDesigner::AdjustSizeCommand(KFormDesigner::AdjustSizeCommand::SizeToFit,
01150 list, form());
01151 adjustCommand->execute();
01152 group->addCommand( adjustCommand,
01153 false
01154 );
01155
01156 if (newWidget) {
01157 pos.setY( pos.y() + newWidget->height() + form()->gridSize());
01158 }
01159 }
01160 if (widgetsToSelect.last()) {
01161
01162 QRect oldFormRect( m_dbform->geometry() );
01163 QRect newFormRect( oldFormRect );
01164 newFormRect.setWidth(QMAX(m_dbform->width(), widgetsToSelect.last()->geometry().right()+1));
01165 newFormRect.setHeight(QMAX(m_dbform->height(), widgetsToSelect.last()->geometry().bottom()+1));
01166 if (newFormRect != oldFormRect) {
01167
01168 m_dbform->setGeometry( newFormRect );
01169
01170 KFormDesigner::PropertyCommand *resizeFormCommand = new KFormDesigner::PropertyCommand(
01171 KFormDesigner::FormManager::self()->propertySet(), m_dbform->name(),
01172 oldFormRect, newFormRect, "geometry");
01173 group->addCommand(resizeFormCommand, true);
01174 }
01175
01176
01177 m_widgetGeometryForRecentInsertAutoFields = widgetsToSelect.last()->geometry();
01178 }
01179
01180
01181 form()->addCommand( group, true );
01182
01183
01184
01185
01186 group->resetAllowExecuteFlags();
01187
01188 m_scrollView->repaint();
01189 m_scrollView->viewport()->repaint();
01190 m_scrollView->repaintContents();
01191 m_scrollView->updateContents();
01192 m_scrollView->clipper()->repaint();
01193 m_scrollView->refreshContentsSize();
01194
01195
01196 if (widgetsToSelect.count()>1) {
01197 form()->setSelectedWidget(0);
01198 foreach_list (KFormDesigner::WidgetListIterator, it, widgetsToSelect)
01199 form()->setSelectedWidget(it.current(), true, true);
01200 }
01201
01202
01203 KFormDesigner::FormManager::self()->unblockPropertyEditorUpdating(this, KFormDesigner::FormManager::self()->propertySet());
01204 }
01205
01206 void
01207 KexiFormView::setUnsavedLocalBLOB(QWidget *widget, KexiBLOBBuffer::Id_t id)
01208 {
01210 if (id==0)
01211 m_unsavedLocalBLOBs.remove(widget);
01212 else
01213 m_unsavedLocalBLOBs.insert(widget, id);
01214 }
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245 #include "kexiformview.moc"
01246