kexi

kexiformview.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
00003    Copyright (C) 2004-2006 Jaroslaw Staniek <js@iidea.pl>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
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 /*dbAware*/)
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 // , m_firstFocusWidget(0)
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 //moved setViewWidget(m_scrollView);
00079 //  m_scrollView->show();
00080 
00081     m_dbform = new KexiDBForm(m_scrollView->viewport(), m_scrollView, name/*, conn*/);
00082 //  m_dbform->resize( m_scrollView->viewport()->size() - QSize(20, 20) );
00083 //  m_dbform->resize(QSize(400, 300));
00084     m_scrollView->setWidget(m_dbform);
00085     m_scrollView->setResizingEnabled(viewMode()!=Kexi::DataViewMode);
00086 
00087 //  initForm();
00088 
00089     if (viewMode()==Kexi::DataViewMode) {
00090         m_scrollView->recordNavigator()->setRecordHandler( m_scrollView );
00091         m_scrollView->viewport()->setPaletteBackgroundColor(m_dbform->palette().active().background());
00092 //moved to formmanager      connect(formPart()->manager(), SIGNAL(noFormSelected()), SLOT(slotNoFormSelected()));
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         // action stuff
00107         plugSharedAction("formpart_taborder", KFormDesigner::FormManager::self(), SLOT(editTabOrder()));
00108         plugSharedAction("formpart_adjust_size", KFormDesigner::FormManager::self(), SLOT(adjustWidgetSize()));
00109 //TODO      plugSharedAction("formpart_pixmap_collection", formPart()->manager(), SLOT(editFormPixmapCollection()));
00110 //TODO      plugSharedAction("formpart_connections", formPart()->manager(), SLOT(editConnections()));
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         /* skip data-awarness if design mode */ viewMode()==Kexi::DesignViewMode );
00159 
00160     connect(this, SIGNAL(focus(bool)), this, SLOT(slotFocus(bool)));
00162 //  m_dbform->resize( m_dbform->size()+QSize(m_scrollView->verticalScrollBar()->width(), m_scrollView->horizontalScrollBar()->height()) );
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     // Important: form window is closed.
00175     // Set property set to 0 because there is *only one* instance of a property set class
00176     // in Kexi, so the main window wouldn't know the set in fact has been changed.
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 //  if (viewMode()==Kexi::DataViewMode)
00221         //form()->setDesignMode(false);
00222     form()->createToplevel(m_dbform, m_dbform);
00223 
00224     if (viewMode()==Kexi::DesignViewMode) {
00225         //we want to be informed about executed commands
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         // Show the form wizard if this is a new Form
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     //collect tab order information
00259     m_dbform->updateTabStopsOrder(form());
00260 
00261 //  if (m_dbform->orderedFocusWidgets()->first())
00262     //  m_scrollView->setFocusProxy( m_dbform->orderedFocusWidgets()->first() );
00263 
00264     KFormDesigner::FormManager::self()->importForm(form(), viewMode()==Kexi::DataViewMode);
00265     m_scrollView->setForm(form());
00266 
00267 //  m_dbform->updateTabStopsOrder(form());
00268 //  QSize s = m_dbform->size();
00269 //  QApplication::sendPostedEvents();
00270 //  m_scrollView->resize( s );
00271 //  m_dbform->resize(s);
00272     m_scrollView->refreshContentsSize();
00273 //  m_scrollView->refreshContentsSizeLater(true,true);
00274 
00275     if (newForm && !fields) {
00276         /* Our form's area will be resized more than once.
00277         Let's resize form widget itself later. */
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     //update autofields: 
00292     //-inherit captions
00293     //-inherit data types
00294     //(this data has not been stored in the form)
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                     //setFieldTypeInternal((int)colInfo->field->type());
00311                     //afWidget->setFieldCaptionInternal(colInfo->captionOrAliasOrName());
00312             }
00313         }
00314     }
00315 }
00316 
00317 void KexiFormView::updateValuesForSubproperties()
00318 {
00320     //update autofields: 
00321     //-inherit captions
00322     //-inherit data types
00323     //(this data has not been stored in the form)
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         // (delayed) set values for subproperties
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 //@todo also load m_resizeMode !
00355 
00356     kexipluginsdbg << "KexiFormView::loadForm() Loading the form with id : " << parentDialog()->id() << endl;
00357     // If we are previewing the Form, use the tempData instead of the form stored in the db
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     // normal load
00367     QString data;
00368     loadDataBlock(data);
00369     KFormDesigner::FormIO::loadFormFromString(form(), m_dbform, data);
00370 
00371     //"autoTabStops" property is loaded -set it within the form tree as well
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 //  if (set && parentDialog()!=parentDialog()->mainWin()->currentDialog())
00382     if (form() != KFormDesigner::FormManager::self()->activeForm())
00383         return; //this is not the current form view
00384     m_propertySet = set;
00385     if (forceReload)
00386         propertySetReloaded(true/*preservePrevSelection*/, 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             //remember our pos
00405             tempData()->scrollViewContentsPos
00406                 = QPoint(m_scrollView->contentsX(), m_scrollView->contentsY());
00407         }
00408     }
00409 
00410     // we don't store on db, but in our TempData
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             //m_delayedFormContentsResizeOnShow = false;
00429         }
00430     }
00431 
00432     if (mode != 0 && mode != Kexi::DesignViewMode) {
00433         //preserve contents pos after switching to other view
00434         m_scrollView->setContentsPos(tempData()->scrollViewContentsPos.x(),
00435             tempData()->scrollViewContentsPos.y());
00436     }
00437 //  if (mode == Kexi::DesignViewMode) {
00438         //m_scrollView->move(0,0);
00439         //m_scrollView->setContentsPos(0,0);
00440         //m_scrollView->moveChild(m_dbform, 0, 0);
00441 //  }
00442 
00443     if((mode == Kexi::DesignViewMode) && viewMode()==Kexi::DataViewMode) {
00444         // The form may have been modified, so we must recreate the preview
00445         delete m_dbform; // also deletes form()
00446         m_dbform = new KexiDBForm(m_scrollView->viewport(), m_scrollView, "KexiDBForm");
00447         m_scrollView->setWidget(m_dbform);
00448 
00449         initForm();
00450 //moved to formmanager      slotNoFormSelected();
00451 
00452         //reset position
00453         m_scrollView->setContentsPos(0,0);
00454         m_dbform->move(0,0);
00455 
00456     }
00457 
00458     //update tab stops if needed
00459     if (viewMode()==Kexi::DataViewMode) {
00460 //      //propagate current "autoTabStops" property value to the form tree
00461 //      form()->setAutoTabStops( m_dbform->autoTabStops() );
00462 
00463 //      if(form()->autoTabStops())
00464 //          form()->autoAssignTabStops();
00465     }
00466     else {
00467         //set "autoTabStops" property
00468         m_dbform->setAutoTabStops( form()->autoTabStops() );
00469     }
00470 
00471     if (viewMode() == Kexi::DataViewMode) {
00472 //TMP!!
00473         initDataSource();
00474 
00475         //handle events for this form
00476         m_scrollView->setMainWidgetForEventHandling(parentDialog()->mainWin(), m_dbform);
00477 
00478         //set focus on 1st focusable widget which has valid dataSource property set
00479         if (!m_dbform->orderedFocusWidgets()->isEmpty()) {
00480 //          QWidget *www = focusWidget();
00481             //if (Kexi::hasParent(this, qApp->focusWidget())) {
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                     /* also skip autoincremented fields:*/
00496                     && !iface->columnInfo()->field->isAutoIncrement()) 
00497                     break;
00498             }
00499             if (!it.current()) //eventually, focus first available widget if nothing other is available
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     //dirty only if it's a new object
00512     if (mode == 0)
00513         setDirty( parentDialog()->partItem()->neverSaved() );
00514 
00515     if (mode==Kexi::DataViewMode && viewMode()==Kexi::DesignViewMode) {
00516 //      slotPropertySetSwitched
00517 //      emit KFormDesigner::FormManager::self()->propertySetSwitched( KFormDesigner::FormManager::self()->propertySet()->set(), true );
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 /*          if (m_previousDataSourceString.lower()==dataSourceString.lower() && !m_cursor) {
00532             //data source changed: delete previous cursor
00533             m_conn->deleteCursor(m_cursor);
00534             m_cursor = 0;
00535         }*/
00536 
00537     KexiDB::TableSchema *tableSchema = 0;
00538     KexiDB::Connection *conn = 0;
00539     QStringList sources;
00540     bool forceReadOnlyDataSource = false;
00541 
00542     if (ok) {
00543 //      m_previousDataSourceString = dataSourceString;
00544 
00545         //collect all data-aware widgets and create query schema
00546         m_scrollView->setMainDataSourceWidget(m_dbform);
00547         sources = m_scrollView->usedDataSources();
00548         conn = parentDialog()->mainWin()->project()->dbConnection();
00549         if (dataSourceMimeTypeString.isEmpty() /*table type is the default*/ 
00550             || dataSourceMimeTypeString=="kexi/table")
00551         {
00552             tableSchema = conn->tableSchema( dataSourceString );
00553             if (tableSchema) {
00554                 /* We will build a _minimum_ query schema from selected table fields. */
00555                 m_query = new KexiDB::QuerySchema();
00556                 m_queryIsOwned = true;
00557 
00558                 if (dataSourceMimeTypeString.isEmpty())
00559                     m_dbform->setDataSourceMimeType("kexi/table"); //update for compatibility
00560             }
00561         }
00562         
00563         if (!tableSchema) {
00564             if (dataSourceMimeTypeString.isEmpty() /*also try to find a query (for compatibility with Kexi<=0.9)*/ 
00565                 || dataSourceMimeTypeString=="kexi/query")
00566             {
00567                 //try to find predefined query schema.
00568                 //Note: In general, we could not skip unused fields within this query because
00569                 //      it can have GROUP BY clause.
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"); //update for compatibility
00576                 // query results are read-only
00578                 forceReadOnlyDataSource = true;
00579             }
00580             else //no other mime types supported
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             //always add all fields from table's primary key
00590             // (don't worry about duplicates, unique list will be computed later)
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             //remove "tablename." if it was prepended
00602             if (tableSchema && fieldName.startsWith( tableSchema->name().lower()+"." ))
00603                 fieldName = fieldName.mid(tableSchema->name().length()+1);
00604             //remove "queryname." if it was prepended
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                 //remove this widget from the set of data widgets in the provider
00612                 invalidSources.insert( fieldName, (const char*)1 ); // += index;
00613                 kexipluginsdbg << "KexiFormView::initDataSource(): invalidSources+=" << index << " (" 
00614                     << (*it) << ")" << endl;
00615                 continue;
00616             }
00617             if (tableSchema) {
00618                 if (!m_query->hasField( f )) {
00619                     //we're building a new query: add this field
00620                     m_query->addField( f );
00621                 }
00622             }
00623         }
00624         if (invalidSources.count()==sources.count()) {
00625             //all data sources are invalid! don't execute the query
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 //          int resultCount = -1;
00648 //          if (ok) {
00649 //              resultCount = m_conn->resultCount(m_conn->selectStatement(*m_query));
00650 //              ok = m_cursor->reopen();
00651 //          }
00652 //          if (ok)
00653 //              ok = ! (!m_cursor->moveFirst() && m_cursor->error());
00654 
00655         m_scrollView->setData( data, true /*owner*/ );
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         //failure: remove object's schema data to avoid garbage
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     //-- first, store local BLOBs, so identifiers can be updated
00697     KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00698     KexiDB::TableSchema *blobsTable = conn->tableSchema("kexi__blobs");
00699     if (!blobsTable) { //compatibility check for older Kexi project versions
00701         return false;
00702     }
00703     // Not all engines accept passing NULL to PKEY o_id, so we're omitting it.
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 //#if 0 
00712     if (!st) {
00713         delete blobsFieldsWithoutID;
00715         return false;
00716     }
00717 //#endif
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; //no BLOB assigned
00730 
00731         QString originalFileName(h.originalFileName());
00732         QFileInfo fi(originalFileName);
00733         QString caption(fi.baseName().replace('_', " ").simplifyWhiteSpace());
00735 
00736 //      KexiDB::PreparedStatement st(KexiDB::PreparedStatement::InsertStatement, *conn, *blobsTable);
00737         if (st) {
00738             *st /* << NO, (pgsql doesn't support this):QVariant()*/ /*id*/ 
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 /*unsafe - will be fixed in Qt4*/)storedBLOBID);
00764         //set widget's internal property so it can be saved...
00765         const QVariant oldStoredPixmapId( it.key()->property("storedPixmapId") );
00766         it.key()->setProperty("storedPixmapId", 
00767             QVariant((uint /* KexiBLOBBuffer::Id_t is unsafe and unsupported by QVariant - will be fixed in Qt4*/)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 //TODO: forall it.key()->setProperty(
00775 
00776     //-- now, save form's XML
00777     QString data;
00778     if (!KFormDesigner::FormIO::saveFormToString(tempData()->form, data))
00779         return false;
00780     if (!storeDataBlock(data))
00781         return false;
00782 
00783     //all blobs are now saved
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     // Enable edit actions
00800     setAvailable("edit_copy", true);
00801     setAvailable("edit_cut", true);
00802     setAvailable("edit_clear", true);
00803 
00804     // 'Align Widgets' menu
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     // If the widgets selected is a container, we enable layout actions
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     // Layout actions
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     // Layout actions
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() // == form in preview mode
00855 {
00856     disableWidgetActions();
00857 
00858     // Disable paste action
00859     setAvailable("edit_paste", false);
00860     setAvailable("edit_undo", false);
00861     setAvailable("edit_redo", false);
00862 
00863     // Disable 'Tools' actions
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     // Enable 'Tools' actions
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     // Disable edit actions
00885     setAvailable("edit_copy", false);
00886     setAvailable("edit_cut", false);
00887     setAvailable("edit_clear", false);
00888 
00889     // Disable format functions
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         //ignore otherSize if possible
00929 //      return KexiViewBase::preferredSizeHint( (parentDialog() && parentDialog()->mdiParent()) ? QSize(10000,10000) : otherSize);
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) { // && isVisible()) {
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             //better-looking focus
00961             if (m_setFocusInternalOnce) {
00962                 SET_FOCUS_USING_REASON(m_setFocusInternalOnce, QFocusEvent::Other);//Tab);
00963                 m_setFocusInternalOnce = 0;
00964             }
00965             else {
00966                 //ok? SET_FOCUS_USING_REASON(m_dbform->focusWidget(), QFocusEvent::Other);//Tab);
00967             }
00968             return;
00969         }
00970     }
00971     QWidget::setFocus();
00972 }
00973 
00974 void
00975 KexiFormView::show()
00976 {
00977     KexiDataAwareView::show();
00978 
00979 //moved from KexiFormScrollView::show():
00980 
00981     //now get resize mode settings for entire form
00982     //  if (resizeMode() == KexiFormView::ResizeAuto)
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         //dirty:    drawRect(QRect( e->pos(), QSize(50, 20)), 2);
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     //if pos is not specified, compute a new position:
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); //start here
01058         }
01059     }
01060 
01061     // there will be many actions performed, do not update property pane until all that's finished
01062     KFormDesigner::FormManager::self()->blockPropertyEditorUpdating(this);
01063 
01065 
01066 //      KFormDesigner::WidgetList* prevSelection = form()->selectedWidgets();
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/*don't exec twice*/);
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 //#if 0
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/*will not be executed on CommandGroup::execute()*/ );
01108 
01109 //#endif
01110         //set data source and caption
01111         //-we don't need to use PropertyCommand here beacause we don't need UNDO 
01112         // for these single commands
01113 //      newWidget->setDataSource(column->aliasOrName());
01114 //      newWidget->setFieldTypeInternal((int)column->field->type());
01115 //      newWidget->setFieldCaptionInternal(column->captionOrAliasOrName());
01116         //resize again because autofield's type changed what can lead to changed sizeHint() 
01117 //      newWidget->resize(newWidget->sizeHint());
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/*will not be executed on CommandGroup::execute()*/
01126         );
01127 
01128         if (newWidget) {//move position down for next widget
01129             pos.setY( pos.y() + newWidget->height() + form()->gridSize());
01130         }
01131     }
01132     if (widgetsToSelect.last()) {
01133         //resize form if needed
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             //1. resize by hand
01140             m_dbform->setGeometry( newFormRect );
01141             //2. store information about resize
01142             KFormDesigner::PropertyCommand *resizeFormCommand = new KFormDesigner::PropertyCommand(
01143                 KFormDesigner::FormManager::self()->propertySet(), m_dbform->name(),
01144                 oldFormRect, newFormRect, "geometry"); 
01145             group->addCommand(resizeFormCommand, true/*will be executed on CommandGroup::execute()*/);
01146         }
01147 
01148         //remember geometry of the last inserted widget
01149         m_widgetGeometryForRecentInsertAutoFields = widgetsToSelect.last()->geometry();
01150     }
01151 
01152     //eventually, add entire command group to active form
01153     form()->addCommand( group, true/*exec*/ );
01154 
01155 //  group->debug();
01156 
01157     //enable proper REDO usage
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     //select all inserted widgets, if multiple
01168     if (widgetsToSelect.count()>1) {
01169         form()->setSelectedWidget(0);
01170         foreach_list (KFormDesigner::WidgetListIterator, it, widgetsToSelect)
01171             form()->setSelectedWidget(it.current(), true/*add*/, true/*dontRaise*/);
01172     }
01173 
01174     // eventually, update property pane
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 todo
01190 void KexiFormView::updateActions(bool activated)
01191 {
01192     if (viewMode()==Kexi::DesignViewMode) {
01193         if (form()->selectedWidget()) {
01194             if (form()->widget() == form()->selectedWidget())
01195                 KFormDesigner::FormManager::self()->emitFormWidgetSelected( form() );
01196             else
01197                 KFormDesigner::FormManager::self()->emitWidgetSelected( form(), false );
01198         }
01199         else if (form()->selectedWidgets()) {
01200             KFormDesigner::FormManager::self()->emitWidgetSelected( form(), true );
01201         }
01202     }
01203     KexiDataAwareView::updateActions(activated);
01204 }*/
01205 
01206 /*
01207 void KexiFormView::parentDialogDetached()
01208 {
01209     m_dbform->updateTabStopsOrder(form());
01210 }
01211 
01212 void KexiFormView::parentDialogAttached(KMdiChildFrm *)
01213 {
01214     m_dbform->updateTabStopsOrder(form());
01215 }*/
01216 
01217 #include "kexiformview.moc"
01218 
KDE Home | KDE Accessibility Home | Description of Access Keys