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-2007 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 
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                     // Special case: the property value of type enum (set) but is saved as a string list,
00350                     // not as int, so we need to translate it to int. It's been created as such
00351                     // by FormIO::readPropertyValue(). Example: "alignment" property.
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             }//for
00364         }
00365     }
00366 }
00367 
00368 void
00369 KexiFormView::loadForm()
00370 {
00371 //@todo also load m_resizeMode !
00372 
00373     kexipluginsdbg << "KexiFormView::loadForm() Loading the form with id : " << parentDialog()->id() << endl;
00374     // If we are previewing the Form, use the tempData instead of the form stored in the db
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     // normal load
00384     QString data;
00385     loadDataBlock(data);
00386     KFormDesigner::FormIO::loadFormFromString(form(), m_dbform, data);
00387 
00388     //"autoTabStops" property is loaded -set it within the form tree as well
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 //  if (set && parentDialog()!=parentDialog()->mainWin()->currentDialog())
00399     if (form() != KFormDesigner::FormManager::self()->activeForm())
00400         return; //this is not the current form view
00401     m_propertySet = set;
00402     if (forceReload)
00403         propertySetReloaded(true/*preservePrevSelection*/, 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             //remember our pos
00422             tempData()->scrollViewContentsPos
00423                 = QPoint(m_scrollView->contentsX(), m_scrollView->contentsY());
00424         }
00425     }
00426 
00427     // we don't store on db, but in our TempData
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             //m_delayedFormContentsResizeOnShow = false;
00446         }
00447     }
00448 
00449     if (mode != 0 && mode != Kexi::DesignViewMode) {
00450         //preserve contents pos after switching to other view
00451         m_scrollView->setContentsPos(tempData()->scrollViewContentsPos.x(),
00452             tempData()->scrollViewContentsPos.y());
00453     }
00454 //  if (mode == Kexi::DesignViewMode) {
00455         //m_scrollView->move(0,0);
00456         //m_scrollView->setContentsPos(0,0);
00457         //m_scrollView->moveChild(m_dbform, 0, 0);
00458 //  }
00459 
00460     if((mode == Kexi::DesignViewMode) && viewMode()==Kexi::DataViewMode) {
00461         // The form may have been modified, so we must recreate the preview
00462         delete m_dbform; // also deletes form()
00463         m_dbform = new KexiDBForm(m_scrollView->viewport(), m_scrollView, "KexiDBForm");
00464         m_scrollView->setWidget(m_dbform);
00465 
00466         initForm();
00467 //moved to formmanager      slotNoFormSelected();
00468 
00469         //reset position
00470         m_scrollView->setContentsPos(0,0);
00471         m_dbform->move(0,0);
00472 
00473     }
00474 
00475     //update tab stops if needed
00476     if (viewMode()==Kexi::DataViewMode) {
00477 //      //propagate current "autoTabStops" property value to the form tree
00478 //      form()->setAutoTabStops( m_dbform->autoTabStops() );
00479 
00480 //      if(form()->autoTabStops())
00481 //          form()->autoAssignTabStops();
00482     }
00483     else {
00484         //set "autoTabStops" property
00485         m_dbform->setAutoTabStops( form()->autoTabStops() );
00486     }
00487 
00488     if (viewMode() == Kexi::DataViewMode) {
00489 //TMP!!
00490         initDataSource();
00491 
00492         //handle events for this form
00493         m_scrollView->setMainWidgetForEventHandling(parentDialog()->mainWin(), m_dbform);
00494 
00495         //set focus on 1st focusable widget which has valid dataSource property set
00496         if (!m_dbform->orderedFocusWidgets()->isEmpty()) {
00497 //          QWidget *www = focusWidget();
00498             //if (Kexi::hasParent(this, qApp->focusWidget())) {
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                     /* also skip autoincremented fields:*/
00513                     && !iface->columnInfo()->field->isAutoIncrement()) 
00514                     break;
00515             }
00516             if (!it.current()) //eventually, focus first available widget if nothing other is available
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     //dirty only if it's a new object
00529     if (mode == 0)
00530         setDirty( parentDialog()->partItem()->neverSaved() );
00531 
00532     if (mode==Kexi::DataViewMode && viewMode()==Kexi::DesignViewMode) {
00533 //      slotPropertySetSwitched
00534 //      emit KFormDesigner::FormManager::self()->propertySetSwitched( KFormDesigner::FormManager::self()->propertySet()->set(), true );
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 /*          if (m_previousDataSourceString.lower()==dataSourceString.lower() && !m_cursor) {
00549             //data source changed: delete previous cursor
00550             m_conn->deleteCursor(m_cursor);
00551             m_cursor = 0;
00552         }*/
00553 
00554     KexiDB::TableSchema *tableSchema = 0;
00555     KexiDB::Connection *conn = 0;
00556     QStringList sources;
00557     bool forceReadOnlyDataSource = false;
00558 
00559     if (ok) {
00560 //      m_previousDataSourceString = dataSourceString;
00561 
00562         //collect all data-aware widgets and create query schema
00563         m_scrollView->setMainDataSourceWidget(m_dbform);
00564         sources = m_scrollView->usedDataSources();
00565         conn = parentDialog()->mainWin()->project()->dbConnection();
00566         if (dataSourceMimeTypeString.isEmpty() /*table type is the default*/ 
00567             || dataSourceMimeTypeString=="kexi/table")
00568         {
00569             tableSchema = conn->tableSchema( dataSourceString );
00570             if (tableSchema) {
00571                 /* We will build a _minimum_ query schema from selected table fields. */
00572                 m_query = new KexiDB::QuerySchema();
00573                 m_queryIsOwned = true;
00574 
00575                 if (dataSourceMimeTypeString.isEmpty())
00576                     m_dbform->setDataSourceMimeType("kexi/table"); //update for compatibility
00577             }
00578         }
00579         
00580         if (!tableSchema) {
00581             if (dataSourceMimeTypeString.isEmpty() /*also try to find a query (for compatibility with Kexi<=0.9)*/ 
00582                 || dataSourceMimeTypeString=="kexi/query")
00583             {
00584                 //try to find predefined query schema.
00585                 //Note: In general, we could not skip unused fields within this query because
00586                 //      it can have GROUP BY clause.
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"); //update for compatibility
00593                 // query results are read-only
00595                 forceReadOnlyDataSource = true;
00596             }
00597             else //no other mime types supported
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             //always add all fields from table's primary key
00607             // (don't worry about duplicates, unique list will be computed later)
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             //remove "tablename." if it was prepended
00619             if (tableSchema && fieldName.startsWith( tableSchema->name().lower()+"." ))
00620                 fieldName = fieldName.mid(tableSchema->name().length()+1);
00621             //remove "queryname." if it was prepended
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                 //remove this widget from the set of data widgets in the provider
00629                 invalidSources.insert( fieldName, (const char*)1 ); // += index;
00630                 kexipluginsdbg << "KexiFormView::initDataSource(): invalidSources+=" << index << " (" 
00631                     << (*it) << ")" << endl;
00632                 continue;
00633             }
00634             if (tableSchema) {
00635                 if (!m_query->hasField( f )) {
00636                     //we're building a new query: add this field
00637                     m_query->addField( f );
00638                 }
00639             }
00640         }
00641         if (invalidSources.count()==sources.count()) {
00642             //all data sources are invalid! don't execute the query
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 //          int resultCount = -1;
00665 //          if (ok) {
00666 //              resultCount = m_conn->resultCount(m_conn->selectStatement(*m_query));
00667 //              ok = m_cursor->reopen();
00668 //          }
00669 //          if (ok)
00670 //              ok = ! (!m_cursor->moveFirst() && m_cursor->error());
00671 
00672         m_scrollView->setData( data, true /*owner*/ );
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         //failure: remove object's schema data to avoid garbage
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     //-- first, store local BLOBs, so identifiers can be updated
00714     KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00715     KexiDB::TableSchema *blobsTable = conn->tableSchema("kexi__blobs");
00716     if (!blobsTable) { //compatibility check for older Kexi project versions
00718         return false;
00719     }
00720     // Not all engines accept passing NULL to PKEY o_id, so we're omitting it.
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 //#if 0 
00729     if (!st) {
00730         delete blobsFieldsWithoutID;
00732         return false;
00733     }
00734 //#endif
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; //no BLOB assigned
00747 
00748         QString originalFileName(h.originalFileName());
00749         QFileInfo fi(originalFileName);
00750         QString caption(fi.baseName().replace('_', " ").simplifyWhiteSpace());
00752 
00753 //      KexiDB::PreparedStatement st(KexiDB::PreparedStatement::InsertStatement, *conn, *blobsTable);
00754         if (st) {
00755             *st /* << NO, (pgsql doesn't support this):QVariant()*/ /*id*/ 
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 /*unsafe - will be fixed in Qt4*/)storedBLOBID);
00781         //set widget's internal property so it can be saved...
00782         const QVariant oldStoredPixmapId( it.key()->property("storedPixmapId") );
00783         it.key()->setProperty("storedPixmapId", 
00784             QVariant((uint /* KexiBLOBBuffer::Id_t is unsafe and unsupported by QVariant - will be fixed in Qt4*/)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 //TODO: forall it.key()->setProperty(
00792 
00793     //-- now, save form's XML
00794     QString data;
00795     if (!KFormDesigner::FormIO::saveFormToString(tempData()->form, data))
00796         return false;
00797     if (!storeDataBlock(data))
00798         return false;
00799 
00800     //all blobs are now saved
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     // Enable edit actions
00817     setAvailable("edit_copy", true);
00818     setAvailable("edit_cut", true);
00819     setAvailable("edit_clear", true);
00820 
00821     // 'Align Widgets' menu
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     // If the widgets selected is a container, we enable layout actions
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     // Layout actions
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     // Layout actions
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() // == form in preview mode
00872 {
00873     disableWidgetActions();
00874 
00875     // Disable paste action
00876     setAvailable("edit_paste", false);
00877     setAvailable("edit_undo", false);
00878     setAvailable("edit_redo", false);
00879 
00880     // Disable 'Tools' actions
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     // Enable 'Tools' actions
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     // Disable edit actions
00902     setAvailable("edit_copy", false);
00903     setAvailable("edit_cut", false);
00904     setAvailable("edit_clear", false);
00905 
00906     // Disable format functions
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         //ignore otherSize if possible
00946 //      return KexiViewBase::preferredSizeHint( (parentDialog() && parentDialog()->mdiParent()) ? QSize(10000,10000) : otherSize);
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) { // && isVisible()) {
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             //better-looking focus
00978             if (m_setFocusInternalOnce) {
00979                 SET_FOCUS_USING_REASON(m_setFocusInternalOnce, QFocusEvent::Other);//Tab);
00980                 m_setFocusInternalOnce = 0;
00981             }
00982             else {
00983                 //ok? SET_FOCUS_USING_REASON(m_dbform->focusWidget(), QFocusEvent::Other);//Tab);
00984             }
00985             return;
00986         }
00987     }
00988     QWidget::setFocus();
00989 }
00990 
00991 void
00992 KexiFormView::show()
00993 {
00994     KexiDataAwareView::show();
00995 
00996 //moved from KexiFormScrollView::show():
00997 
00998     //now get resize mode settings for entire form
00999     //  if (resizeMode() == KexiFormView::ResizeAuto)
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         //dirty:    drawRect(QRect( e->pos(), QSize(50, 20)), 2);
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     //if pos is not specified, compute a new position:
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); //start here
01075         }
01076     }
01077 
01078     // there will be many actions performed, do not update property pane until all that's finished
01079     KFormDesigner::FormManager::self()->blockPropertyEditorUpdating(this);
01080 
01082 
01083 //      KFormDesigner::WidgetList* prevSelection = form()->selectedWidgets();
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/*don't exec twice*/);
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 //#if 0
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/*will not be executed on CommandGroup::execute()*/ );
01136 
01137 //#endif
01138         //set data source and caption
01139         //-we don't need to use PropertyCommand here beacause we don't need UNDO 
01140         // for these single commands
01141 //      newWidget->setDataSource(column->aliasOrName());
01142 //      newWidget->setFieldTypeInternal((int)column->field->type());
01143 //      newWidget->setFieldCaptionInternal(column->captionOrAliasOrName());
01144         //resize again because autofield's type changed what can lead to changed sizeHint() 
01145 //      newWidget->resize(newWidget->sizeHint());
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/*will not be executed on CommandGroup::execute()*/
01154         );
01155 
01156         if (newWidget) {//move position down for next widget
01157             pos.setY( pos.y() + newWidget->height() + form()->gridSize());
01158         }
01159     }
01160     if (widgetsToSelect.last()) {
01161         //resize form if needed
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             //1. resize by hand
01168             m_dbform->setGeometry( newFormRect );
01169             //2. store information about resize
01170             KFormDesigner::PropertyCommand *resizeFormCommand = new KFormDesigner::PropertyCommand(
01171                 KFormDesigner::FormManager::self()->propertySet(), m_dbform->name(),
01172                 oldFormRect, newFormRect, "geometry"); 
01173             group->addCommand(resizeFormCommand, true/*will be executed on CommandGroup::execute()*/);
01174         }
01175 
01176         //remember geometry of the last inserted widget
01177         m_widgetGeometryForRecentInsertAutoFields = widgetsToSelect.last()->geometry();
01178     }
01179 
01180     //eventually, add entire command group to active form
01181     form()->addCommand( group, true/*exec*/ );
01182 
01183 //  group->debug();
01184 
01185     //enable proper REDO usage
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     //select all inserted widgets, if multiple
01196     if (widgetsToSelect.count()>1) {
01197         form()->setSelectedWidget(0);
01198         foreach_list (KFormDesigner::WidgetListIterator, it, widgetsToSelect)
01199             form()->setSelectedWidget(it.current(), true/*add*/, true/*dontRaise*/);
01200     }
01201 
01202     // eventually, update property pane
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 todo
01218 void KexiFormView::updateActions(bool activated)
01219 {
01220     if (viewMode()==Kexi::DesignViewMode) {
01221         if (form()->selectedWidget()) {
01222             if (form()->widget() == form()->selectedWidget())
01223                 KFormDesigner::FormManager::self()->emitFormWidgetSelected( form() );
01224             else
01225                 KFormDesigner::FormManager::self()->emitWidgetSelected( form(), false );
01226         }
01227         else if (form()->selectedWidgets()) {
01228             KFormDesigner::FormManager::self()->emitWidgetSelected( form(), true );
01229         }
01230     }
01231     KexiDataAwareView::updateActions(activated);
01232 }*/
01233 
01234 /*
01235 void KexiFormView::parentDialogDetached()
01236 {
01237     m_dbform->updateTabStopsOrder(form());
01238 }
01239 
01240 void KexiFormView::parentDialogAttached(KMdiChildFrm *)
01241 {
01242     m_dbform->updateTabStopsOrder(form());
01243 }*/
01244 
01245 #include "kexiformview.moc"
01246 
KDE Home | KDE Accessibility Home | Description of Access Keys