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-2005 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 
00034 #include <kexi.h>
00035 #include <kexidialogbase.h>
00036 #include <kexidragobjects.h>
00037 #include <kexidb/field.h>
00038 #include <kexidb/fieldlist.h>
00039 #include <kexidb/connection.h>
00040 #include <kexidb/cursor.h>
00041 #include <kexidb/utils.h>
00042 #include <kexidb/preparedstatement.h>
00043 #include <tableview/kexitableitem.h>
00044 #include <tableview/kexitableviewdata.h>
00045 #include <widget/kexipropertyeditorview.h>
00046 #include <formeditor/objecttree.h>
00047 
00048 #include <koproperty/set.h>
00049 #include <koproperty/property.h>
00050 
00051 #include "widgets/kexidbform.h"
00052 #include "kexiformscrollview.h"
00053 #include "kexidatasourcepage.h"
00054 #include "widgets/kexidbautofield.h"
00055 
00056 #define NO_DSWIZARD
00057 
00059 
00060 KexiFormView::KexiFormView(KexiMainWindow *mainWin, QWidget *parent,
00061     const char *name, bool /*dbAware*/)
00062  : KexiDataAwareView( mainWin, parent, name )
00063  , m_propertySet(0)
00064  , m_resizeMode(KexiFormView::ResizeDefault)
00065  , m_query(0)
00066  , m_queryIsOwned(false)
00067  , m_cursor(0)
00068 // , m_firstFocusWidget(0)
00069 {
00070     m_delayedFormContentsResizeOnShow = 0;
00071 
00072     QHBoxLayout *l = new QHBoxLayout(this);
00073     l->setAutoAdd(true);
00074 
00075     m_scrollView = new KexiFormScrollView(this, viewMode()==Kexi::DataViewMode);
00076 
00077 //moved setViewWidget(m_scrollView);
00078 //  m_scrollView->show();
00079 
00080     m_dbform = new KexiDBForm(m_scrollView->viewport(), m_scrollView, name/*, conn*/);
00081 //  m_dbform->resize( m_scrollView->viewport()->size() - QSize(20, 20) );
00082 //  m_dbform->resize(QSize(400, 300));
00083     m_scrollView->setWidget(m_dbform);
00084     m_scrollView->setResizingEnabled(viewMode()!=Kexi::DataViewMode);
00085 
00086 //  initForm();
00087 
00088     if (viewMode()==Kexi::DataViewMode) {
00089         m_scrollView->recordNavigator()->setRecordHandler( m_scrollView );
00090         m_scrollView->viewport()->setPaletteBackgroundColor(m_dbform->palette().active().background());
00091 //moved to formmanager      connect(formPart()->manager(), SIGNAL(noFormSelected()), SLOT(slotNoFormSelected()));
00092     }
00093     else
00094     {
00095         connect(KFormDesigner::FormManager::self(), SIGNAL(propertySetSwitched(KoProperty::Set*, bool)),
00096             this, SLOT(slotPropertySetSwitched(KoProperty::Set*, bool)));
00097         connect(KFormDesigner::FormManager::self(), SIGNAL(dirty(KFormDesigner::Form *, bool)),
00098             this, SLOT(slotDirty(KFormDesigner::Form *, bool)));
00099 
00100         connect(m_dbform, SIGNAL(handleDragMoveEvent(QDragMoveEvent*)), 
00101             this, SLOT(slotHandleDragMoveEvent(QDragMoveEvent*)));
00102         connect(m_dbform, SIGNAL(handleDropEvent(QDropEvent*)), 
00103             this, SLOT(slotHandleDropEvent(QDropEvent*)));
00104 
00105         // action stuff
00106         plugSharedAction("formpart_taborder", KFormDesigner::FormManager::self(), SLOT(editTabOrder()));
00107         plugSharedAction("formpart_adjust_size", KFormDesigner::FormManager::self(), SLOT(adjustWidgetSize()));
00108 //TODO      plugSharedAction("formpart_pixmap_collection", formPart()->manager(), SLOT(editFormPixmapCollection()));
00109 //TODO      plugSharedAction("formpart_connections", formPart()->manager(), SLOT(editConnections()));
00110 
00111         plugSharedAction("edit_copy", KFormDesigner::FormManager::self(), SLOT(copyWidget()));
00112         plugSharedAction("edit_cut", KFormDesigner::FormManager::self(), SLOT(cutWidget()));
00113         plugSharedAction("edit_paste", KFormDesigner::FormManager::self(), SLOT(pasteWidget()));
00114         plugSharedAction("edit_delete", KFormDesigner::FormManager::self(), SLOT(deleteWidget()));
00115         plugSharedAction("edit_select_all", KFormDesigner::FormManager::self(), SLOT(selectAll()));
00116         plugSharedAction("formpart_clear_contents", KFormDesigner::FormManager::self(), SLOT(clearWidgetContent()));
00117         plugSharedAction("edit_undo", KFormDesigner::FormManager::self(), SLOT(undo()));
00118         plugSharedAction("edit_redo", KFormDesigner::FormManager::self(), SLOT(redo()));
00119 
00120         plugSharedAction("formpart_layout_menu", KFormDesigner::FormManager::self(), 0 );
00121         plugSharedAction("formpart_layout_hbox", KFormDesigner::FormManager::self(), SLOT(layoutHBox()) );
00122         plugSharedAction("formpart_layout_vbox", KFormDesigner::FormManager::self(), SLOT(layoutVBox()) );
00123         plugSharedAction("formpart_layout_grid", KFormDesigner::FormManager::self(), SLOT(layoutGrid()) );
00124 #ifdef KEXI_SHOW_SPLITTER_WIDGET
00125         plugSharedAction("formpart_layout_hsplitter", KFormDesigner::FormManager::self(), SLOT(layoutHSplitter()) );
00126         plugSharedAction("formpart_layout_vsplitter", KFormDesigner::FormManager::self(), SLOT(layoutVSplitter()) );
00127 #endif
00128         plugSharedAction("formpart_break_layout", KFormDesigner::FormManager::self(), SLOT(breakLayout()) );
00129 
00130         plugSharedAction("formpart_format_raise", KFormDesigner::FormManager::self(), SLOT(bringWidgetToFront()) );
00131         plugSharedAction("formpart_format_lower", KFormDesigner::FormManager::self(), SLOT(sendWidgetToBack()) );
00132 
00133         plugSharedAction("other_widgets_menu", KFormDesigner::FormManager::self(), 0 );
00134         setAvailable("other_widgets_menu", true);
00135 
00136         plugSharedAction("formpart_align_menu", KFormDesigner::FormManager::self(), 0 );
00137         plugSharedAction("formpart_align_to_left", KFormDesigner::FormManager::self(),SLOT(alignWidgetsToLeft()) );
00138         plugSharedAction("formpart_align_to_right", KFormDesigner::FormManager::self(), SLOT(alignWidgetsToRight()) );
00139         plugSharedAction("formpart_align_to_top", KFormDesigner::FormManager::self(), SLOT(alignWidgetsToTop()) );
00140         plugSharedAction("formpart_align_to_bottom", KFormDesigner::FormManager::self(), SLOT(alignWidgetsToBottom()) );
00141         plugSharedAction("formpart_align_to_grid", KFormDesigner::FormManager::self(), SLOT(alignWidgetsToGrid()) );
00142 
00143         plugSharedAction("formpart_adjust_size_menu", KFormDesigner::FormManager::self(), 0 );
00144         plugSharedAction("formpart_adjust_to_fit", KFormDesigner::FormManager::self(), SLOT(adjustWidgetSize()) );
00145         plugSharedAction("formpart_adjust_size_grid", KFormDesigner::FormManager::self(), SLOT(adjustSizeToGrid()) );
00146         plugSharedAction("formpart_adjust_height_small", KFormDesigner::FormManager::self(),  SLOT(adjustHeightToSmall()) );
00147         plugSharedAction("formpart_adjust_height_big", KFormDesigner::FormManager::self(), SLOT(adjustHeightToBig()) );
00148         plugSharedAction("formpart_adjust_width_small", KFormDesigner::FormManager::self(), SLOT(adjustWidthToSmall()) );
00149         plugSharedAction("formpart_adjust_width_big", KFormDesigner::FormManager::self(), SLOT(adjustWidthToBig()) );
00150 
00151         plugSharedAction("format_font", KFormDesigner::FormManager::self(), SLOT(changeFont()) );
00152     }
00153 
00154     initForm();
00155 
00156     KexiDataAwareView::init( m_scrollView, m_scrollView, m_scrollView,
00157         /* skip data-awarness if design mode */ viewMode()==Kexi::DesignViewMode );
00158 
00159     connect(this, SIGNAL(focus(bool)), this, SLOT(slotFocus(bool)));
00161 //  m_dbform->resize( m_dbform->size()+QSize(m_scrollView->verticalScrollBar()->width(), m_scrollView->horizontalScrollBar()->height()) );
00162 }
00163 
00164 KexiFormView::~KexiFormView()
00165 {
00166     if (m_cursor) {
00167         KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00168         conn->deleteCursor(m_cursor);
00169     }
00170     deleteQuery();
00171 
00172     // Important: form window is closed.
00173     // Set property set to 0 because there is *only one* instance of a property set class
00174     // in Kexi, so the main window wouldn't know the set in fact has been changed.
00175     m_propertySet = 0;
00176     propertySetSwitched();
00177 }
00178 
00179 void
00180 KexiFormView::deleteQuery()
00181 {
00182     if (m_queryIsOwned) {
00183         delete m_query;
00184     } else {
00186     }
00187     m_query = 0;
00188 }
00189 
00190 KFormDesigner::Form*
00191 KexiFormView::form() const
00192 {
00193     if(viewMode()==Kexi::DataViewMode)
00194         return tempData()->previewForm;
00195     else
00196         return tempData()->form;
00197 }
00198 
00199 void
00200 KexiFormView::setForm(KFormDesigner::Form *f)
00201 {
00202     if(viewMode()==Kexi::DataViewMode)
00203         tempData()->previewForm = f;
00204     else
00205         tempData()->form = f;
00206 }
00207 
00208 void
00209 KexiFormView::initForm()
00210 {
00211     setForm( new KFormDesigner::Form(KexiFormPart::library(), 0, viewMode()==Kexi::DesignViewMode) );
00212 //  if (viewMode()==Kexi::DataViewMode)
00213         //form()->setDesignMode(false);
00214     form()->createToplevel(m_dbform, m_dbform);
00215 
00216     if (viewMode()==Kexi::DesignViewMode) {
00217         //we want to be informed about executed commands
00218         connect(form()->commandHistory(), SIGNAL(commandExecuted()),
00219             KFormDesigner::FormManager::self(), SLOT(slotHistoryCommandExecuted()));
00220     }
00221 
00222     const bool newForm = parentDialog()->id() < 0;
00223 
00224     KexiDB::FieldList *fields = 0;
00225     if (newForm) {
00226         // Show the form wizard if this is a new Form
00227 #ifndef NO_DSWIZARD
00228         KexiDataSourceWizard *w = new KexiDataSourceWizard(mainWin(), (QWidget*)mainWin(), "datasource_wizard");
00229         if(!w->exec())
00230             fields = 0;
00231         else
00232             fields = w->fields();
00233         delete w;
00234 #endif
00235     }
00236 
00237     if(fields)
00238     {
00239         QDomDocument dom;
00240         formPart()->generateForm(fields, dom);
00241         KFormDesigner::FormIO::loadFormFromDom(form(), m_dbform, dom);
00243     }
00244     else
00245         loadForm();
00246 
00247     if(form()->autoTabStops())
00248         form()->autoAssignTabStops();
00249 
00250     //collect tab order information
00251     m_dbform->updateTabStopsOrder(form());
00252 
00253 //  if (m_dbform->orderedFocusWidgets()->first())
00254     //  m_scrollView->setFocusProxy( m_dbform->orderedFocusWidgets()->first() );
00255 
00256     KFormDesigner::FormManager::self()->importForm(form(), viewMode()==Kexi::DataViewMode);
00257     m_scrollView->setForm(form());
00258 
00259 //  m_dbform->updateTabStopsOrder(form());
00260 //  QSize s = m_dbform->size();
00261 //  QApplication::sendPostedEvents();
00262 //  m_scrollView->resize( s );
00263 //  m_dbform->resize(s);
00264     m_scrollView->refreshContentsSize();
00265 //  m_scrollView->refreshContentsSizeLater(true,true);
00266 
00267     if (newForm && !fields) {
00268         /* Our form's area will be resized more than once.
00269         Let's resize form widget itself later. */
00270         m_delayedFormContentsResizeOnShow = 3;
00271     }
00272 
00273     updateDataSourcePage();
00274 
00275     if (!newForm && viewMode()==Kexi::DesignViewMode) {
00276         form()->clearCommandHistory();
00277     }
00278 }
00279 
00280 void KexiFormView::updateAutoFieldsDataSource()
00281 {
00283     //update autofields: 
00284     //-inherit captions
00285     //-inherit data types
00286     //(this data has not been stored in the form)
00287     QString dataSourceString( m_dbform->dataSource() );
00288     QCString dataSourceMimeTypeString( m_dbform->dataSourceMimeType() );
00289     KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00290     KexiDB::TableOrQuerySchema tableOrQuery(
00291         conn, dataSourceString.latin1(), dataSourceMimeTypeString=="kexi/table");
00292     if (!tableOrQuery.table() && !tableOrQuery.query())
00293         return;
00294     for (KFormDesigner::ObjectTreeDictIterator it(*form()->objectTree()->dict());
00295         it.current(); ++it)
00296     {
00297         KexiDBAutoField *afWidget = dynamic_cast<KexiDBAutoField*>( it.current()->widget() );
00298         if (afWidget) {
00299             KexiDB::QueryColumnInfo *colInfo = tableOrQuery.columnInfo( afWidget->dataSource() );
00300             if (colInfo) {
00301                 afWidget->setColumnInfo(colInfo);
00302                     //setFieldTypeInternal((int)colInfo->field->type());
00303                     //afWidget->setFieldCaptionInternal(colInfo->captionOrAliasOrName());
00304             }
00305         }
00306     }
00307 }
00308 
00309 void
00310 KexiFormView::loadForm()
00311 {
00312 //@todo also load m_resizeMode !
00313 
00314     kexipluginsdbg << "KexiFormView::loadForm() Loading the form with id : " << parentDialog()->id() << endl;
00315     // If we are previewing the Form, use the tempData instead of the form stored in the db
00316     if(viewMode()==Kexi::DataViewMode && !tempData()->tempForm.isNull() )
00317     {
00318         KFormDesigner::FormIO::loadFormFromString(form(), m_dbform, tempData()->tempForm);
00319         updateAutoFieldsDataSource();
00320         return;
00321     }
00322 
00323     // normal load
00324     QString data;
00325     loadDataBlock(data);
00326     KFormDesigner::FormIO::loadFormFromString(form(), m_dbform, data);
00327 
00328     //"autoTabStops" property is loaded -set it within the form tree as well
00329     form()->setAutoTabStops( m_dbform->autoTabStops() );
00330 
00331     updateAutoFieldsDataSource();
00332 }
00333 
00334 void
00335 KexiFormView::slotPropertySetSwitched(KoProperty::Set *set, bool forceReload)
00336 {
00337     //if (m_buffer == b)
00338     //  return;
00339     m_propertySet = set;
00340     if (forceReload)
00341         propertySetReloaded(true/*preservePrevSelection*/);
00342     else
00343         propertySetSwitched();
00344 
00345     formPart()->dataSourcePage()->assignPropertySet(m_propertySet);
00346 }
00347 
00348 tristate
00349 KexiFormView::beforeSwitchTo(int mode, bool &dontStore)
00350 {
00351     if (mode!=viewMode()) {
00352         if (viewMode()==Kexi::DataViewMode) {
00353             if (!m_scrollView->acceptRowEdit())
00354                 return cancelled;
00355 
00356             m_scrollView->beforeSwitchView();
00357         }
00358         else {
00359             //remember our pos
00360             tempData()->scrollViewContentsPos
00361                 = QPoint(m_scrollView->contentsX(), m_scrollView->contentsY());
00362         }
00363     }
00364 
00365     // we don't store on db, but in our TempData
00366     dontStore = true;
00367     if(dirty() && (mode == Kexi::DataViewMode) && form()->objectTree()) {
00368         KexiFormPart::TempData* temp = tempData();
00369         if (!KFormDesigner::FormIO::saveFormToString(form(), temp->tempForm))
00370             return false;
00371     }
00372 
00373     return true;
00374 }
00375 
00376 tristate
00377 KexiFormView::afterSwitchFrom(int mode)
00378 {
00379     if (mode == 0 || mode == Kexi::DesignViewMode) {
00380         if (parentDialog()->neverSaved()) {
00381             m_dbform->resize(QSize(400, 300));
00382             m_scrollView->refreshContentsSizeLater(true,true);
00383             //m_delayedFormContentsResizeOnShow = false;
00384         }
00385     }
00386 
00387     if (mode != 0 && mode != Kexi::DesignViewMode) {
00388         //preserve contents pos after switching to other view
00389         m_scrollView->setContentsPos(tempData()->scrollViewContentsPos.x(),
00390             tempData()->scrollViewContentsPos.y());
00391     }
00392 //  if (mode == Kexi::DesignViewMode) {
00393         //m_scrollView->move(0,0);
00394         //m_scrollView->setContentsPos(0,0);
00395         //m_scrollView->moveChild(m_dbform, 0, 0);
00396 //  }
00397 
00398     if((mode == Kexi::DesignViewMode) && viewMode()==Kexi::DataViewMode) {
00399         // The form may have been modified, so we must recreate the preview
00400         delete m_dbform; // also deletes form()
00401         m_dbform = new KexiDBForm(m_scrollView->viewport(), m_scrollView, "KexiDBForm");
00402         m_scrollView->setWidget(m_dbform);
00403 
00404         initForm();
00405 //moved to formmanager      slotNoFormSelected();
00406 
00407         //reset position
00408         m_scrollView->setContentsPos(0,0);
00409         m_dbform->move(0,0);
00410 
00411     }
00412 
00413     //update tab stops if needed
00414     if (viewMode()==Kexi::DataViewMode) {
00415 //      //propagate current "autoTabStops" property value to the form tree
00416 //      form()->setAutoTabStops( m_dbform->autoTabStops() );
00417 
00418 //      if(form()->autoTabStops())
00419 //          form()->autoAssignTabStops();
00420     }
00421     else {
00422         //set "autoTabStops" property
00423         m_dbform->setAutoTabStops( form()->autoTabStops() );
00424     }
00425 
00426     if (viewMode() == Kexi::DataViewMode) {
00427 //TMP!!
00428         initDataSource();
00429 
00430         //handle events for this form
00431         m_scrollView->setMainWidgetForEventHandling(parentDialog()->mainWin(), m_dbform);
00432 
00433         //set focus on 1st focusable widget which has valid dataSource property set
00434         if (!m_dbform->orderedFocusWidgets()->isEmpty()) {
00435 //          QWidget *www = focusWidget();
00436             //if (Kexi::hasParent(this, qApp->focusWidget())) {
00437                 QEvent fe( QEvent::FocusOut );
00438                 QFocusEvent::setReason(QFocusEvent::Tab);
00439                 QApplication::sendEvent( qApp->focusWidget(), &fe );
00440                 QFocusEvent::resetReason();
00441             //}
00442 
00443             QPtrListIterator<QWidget> it(*m_dbform->orderedFocusWidgets());
00444             for (;it.current(); ++it) {
00445                 KexiFormDataItemInterface *iface = dynamic_cast<KexiFormDataItemInterface*>(it.current());
00446                 if (iface)
00447                     kexipluginsdbg << iface->dataSource() << endl;
00448                 if (iface && iface->columnInfo() && !iface->isReadOnly()
00450                     /* also skip autoincremented fields:*/
00451                     && !iface->columnInfo()->field->isAutoIncrement()) 
00452                     break;
00453             }
00454             if (!it.current()) //eventually, focus first available widget if nothing other is available
00455                 it.toFirst();
00456 
00457             it.current()->setFocus();
00458             SET_FOCUS_USING_REASON(it.current(), QFocusEvent::Tab);
00459             m_setFocusInternalOnce = it.current();
00460         }
00461 
00462         if (m_query)
00463             m_scrollView->selectFirstRow();
00464     }
00465 
00466     //dirty only if it's a new object
00467     if (mode == 0)
00468         setDirty( parentDialog()->partItem()->neverSaved() );
00469 
00470     if (mode==Kexi::DataViewMode && viewMode()==Kexi::DesignViewMode) {
00471 //      slotPropertySetSwitched
00472 //      emit KFormDesigner::FormManager::self()->propertySetSwitched( KFormDesigner::FormManager::self()->propertySet()->set(), true );
00473     }
00474 
00475     return true;
00476 }
00477 
00478 void KexiFormView::initDataSource()
00479 {
00480     deleteQuery();
00481     QString dataSourceString( m_dbform->dataSource() );
00482     QCString dataSourceMimeTypeString( m_dbform->dataSourceMimeType() );
00484     bool ok = !dataSourceString.isEmpty();
00485 
00486 /*          if (m_previousDataSourceString.lower()==dataSourceString.lower() && !m_cursor) {
00487             //data source changed: delete previous cursor
00488             m_conn->deleteCursor(m_cursor);
00489             m_cursor = 0;
00490         }*/
00491 
00492     KexiDB::TableSchema *tableSchema = 0;
00493     KexiDB::Connection *conn = 0;
00494     QStringList sources;
00495     bool forceReadOnlyDataSource = false;
00496 
00497     if (ok) {
00498 //      m_previousDataSourceString = dataSourceString;
00499 
00500         //collect all data-aware widgets and create query schema
00501         m_scrollView->setMainDataSourceWidget(m_dbform);
00502         sources = m_scrollView->usedDataSources();
00503         conn = parentDialog()->mainWin()->project()->dbConnection();
00504         if (dataSourceMimeTypeString.isEmpty() /*table type is the default*/ 
00505             || dataSourceMimeTypeString=="kexi/table")
00506         {
00507             tableSchema = conn->tableSchema( dataSourceString );
00508             if (tableSchema) {
00509                 /* We will build a _minimum_ query schema from selected table fields. */
00510                 m_query = new KexiDB::QuerySchema();
00511                 m_queryIsOwned = true;
00512 
00513                 if (dataSourceMimeTypeString.isEmpty())
00514                     m_dbform->setDataSourceMimeType("kexi/table"); //update for compatibility
00515             }
00516         }
00517         
00518         if (!tableSchema) {
00519             if (dataSourceMimeTypeString.isEmpty() /*also try to find a query (for compatibility with Kexi<=0.9)*/ 
00520                 || dataSourceMimeTypeString=="kexi/query")
00521             {
00522                 //try to find predefined query schema.
00523                 //Note: In general, we could not skip unused fields within this query because
00524                 //      it can have GROUP BY clause.
00526                 m_query = conn->querySchema( dataSourceString );
00527                 m_queryIsOwned = false;
00528                 ok = m_query != 0;
00529                 if (ok && dataSourceMimeTypeString.isEmpty())
00530                     m_dbform->setDataSourceMimeType("kexi/query"); //update for compatibility
00531                 // query results are read-only
00533                 forceReadOnlyDataSource = true;
00534             }
00535             else //no other mime types supported
00536                 ok = false;
00537         }
00538     }
00539 
00540     QValueList<uint> invalidSources;
00541     if (ok) {
00542         KexiDB::IndexSchema *pkey = tableSchema ? tableSchema->primaryKey() : 0;
00543         if (pkey) {
00544             //always add all fields from table's primary key
00545             // (don't worry about duplicated, unique list will be computed later)
00546             sources += pkey->names();
00547             KexiDBDbg << "KexiFormView::initDataSource(): pkey added to data sources: " << pkey->names() << endl;
00548         }
00549 
00550         uint index = 0;
00551         for (QStringList::ConstIterator it = sources.constBegin();
00552             it!=sources.constEnd(); ++it, index++) {
00554             QString fieldName( (*it).lower() );
00555             //remove "tablename." if it was prepended
00556             if (tableSchema && fieldName.startsWith( tableSchema->name().lower()+"." ))
00557                 fieldName = fieldName.mid(tableSchema->name().length()+1);
00558             //remove "queryname." if it was prepended
00559             if (!tableSchema && fieldName.startsWith( m_query->name().lower()+"." ))
00560                 fieldName = fieldName.mid(m_query->name().length()+1);
00561             KexiDB::Field *f = tableSchema ? tableSchema->field(fieldName) : m_query->field(fieldName);
00562             if (!f) {
00564                 //remove this widget from the set of data widgets in the provider
00565                 invalidSources += index;
00566                 continue;
00567             }
00568             if (tableSchema) {
00569                 if (!m_query->hasField( f )) {
00570                     //we're building a new query: add this field
00571                     m_query->addField( f );
00572                 }
00573             }
00574         }
00575         if (invalidSources.count()==sources.count()) {
00576             //all data sources are invalid! don't execute the query
00577             deleteQuery();
00578         }
00579         else {
00580             m_cursor = conn->executeQuery( *m_query );
00581         }
00582         m_scrollView->invalidateDataSources( invalidSources, m_query );
00583         ok = m_cursor!=0;
00584     }
00585 
00586     if (!invalidSources.isEmpty())
00587         m_dbform->updateTabStopsOrder();
00588 
00589     if (ok) {
00592         KexiTableViewData* data = new KexiTableViewData(m_cursor);
00593         if (forceReadOnlyDataSource)
00594             data->setReadOnly(true);
00595         data->preloadAllRows();
00596 
00598 //          int resultCount = -1;
00599 //          if (ok) {
00600 //              resultCount = m_conn->resultCount(m_conn->selectStatement(*m_query));
00601 //              ok = m_cursor->reopen();
00602 //          }
00603 //          if (ok)
00604 //              ok = ! (!m_cursor->moveFirst() && m_cursor->error());
00605 
00606         m_scrollView->setData( data, true /*owner*/ );
00607     }
00608     else
00609         m_scrollView->setData( 0, false );
00610 }
00611 
00612 void
00613 KexiFormView::slotDirty(KFormDesigner::Form *dirtyForm, bool isDirty)
00614 {
00615     if(dirtyForm == form())
00616         KexiViewBase::setDirty(isDirty);
00617 }
00618 
00619 KexiDB::SchemaData*
00620 KexiFormView::storeNewData(const KexiDB::SchemaData& sdata, bool &cancel)
00621 {
00622     KexiDB::SchemaData *s = KexiViewBase::storeNewData(sdata, cancel);
00623     kexipluginsdbg << "KexiDBForm::storeNewData(): new id:" << s->id() << endl;
00624 
00625     if (!s || cancel) {
00626         delete s;
00627         return 0;
00628     }
00629     if (!storeData()) {
00630         //failure: remove object's schema data to avoid garbage
00631         KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00632         conn->removeObject( s->id() );
00633         delete s;
00634         return 0;
00635     }
00636     return s;
00637 }
00638 
00639 tristate
00640 KexiFormView::storeData(bool dontAsk)
00641 {
00642     Q_UNUSED(dontAsk);
00643     kexipluginsdbg << "KexiDBForm::storeData(): " << parentDialog()->partItem()->name() 
00644         << " [" << parentDialog()->id() << "]" << endl;
00645 
00646     //-- first, store local BLOBs, so identifiers can be updated
00648     KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00649     KexiDB::TableSchema *blobsTable = conn->tableSchema("kexi__blobs");
00650     if (!blobsTable) { //compatibility check for older Kexi project versions
00652         return false;
00653     }
00654     // Not all engines accept passing NULL to PKEY o_id, so we're omitting it.
00655     QStringList blobsFieldNamesWithoutID(blobsTable->names());
00656     blobsFieldNamesWithoutID.pop_front();
00657     KexiDB::FieldList *blobsFieldsWithoutID = blobsTable->subList(blobsFieldNamesWithoutID);
00658     
00659     KexiDB::PreparedStatement::Ptr st = conn->prepareStatement(
00660         KexiDB::PreparedStatement::InsertStatement, *blobsFieldsWithoutID);
00661 //#if 0 
00663     if (!st) {
00664         delete blobsFieldsWithoutID;
00666         return false;
00667     }
00668 //#endif
00669     KexiBLOBBuffer *blobBuf = KexiBLOBBuffer::self();
00670     for (QMapConstIterator<QWidget*, KexiBLOBBuffer::Id_t> it = m_unsavedLocalBLOBs.constBegin(); 
00671         it!=m_unsavedLocalBLOBs.constEnd(); ++it)
00672     {
00673         if (!it.key()) {
00674             kexipluginswarn << "KexiFormView::storeData(): it.key()==0 !" << endl;
00675             continue;
00676         }
00677         kexipluginsdbg << "name=" << it.key()->name() << " dataID=" << it.data() << endl;
00678         KexiBLOBBuffer::Handle h( blobBuf->objectForId(it.data(), false) );
00679         if (!h)
00680             continue; //no BLOB assigned
00681 
00682         QString originalFileName(h.originalFileName());
00683         QFileInfo fi(originalFileName);
00684         QString caption(fi.baseName().replace('_', " ").simplifyWhiteSpace());
00686 
00687 //      KexiDB::PreparedStatement st(KexiDB::PreparedStatement::InsertStatement, *conn, *blobsTable);
00688         if (st) {
00689             *st /* << NO, (pgsql doesn't support this):QVariant()*/ /*id*/ 
00690                 << h.data() << originalFileName << caption 
00691                 << h.mimeType() << (uint)h.folderId();
00692             if (!st->execute()) {
00693                 delete blobsFieldsWithoutID;
00694                 kexipluginsdbg << " execute error" << endl;
00695                 return false;
00696             }
00697         }
00699 #if 0
00700         if (!conn->insertRecord(*blobsFieldsWithoutID, h.data(), originalFileName, caption, h.mimeType())) {
00701             delete blobsFieldsWithoutID;
00703             return false;
00704         }
00705 #endif
00706         delete blobsFieldsWithoutID;
00707         blobsFieldsWithoutID=0;
00708         const Q_ULLONG storedBLOBID = conn->lastInsertedAutoIncValue("o_id", "kexi__blobs");
00709         if ((Q_ULLONG)-1 == storedBLOBID) {
00711             return false;
00712         }
00713         kexipluginsdbg << " storedDataID=" << storedBLOBID << endl;
00714         h.setStoredWidthID((KexiBLOBBuffer::Id_t /*unsafe - will be fixed in Qt4*/)storedBLOBID);
00715         //set widget's internal property so it can be saved...
00716         const QVariant oldStoredPixmapId( it.key()->property("storedPixmapId") );
00717         it.key()->setProperty("storedPixmapId", 
00718             QVariant((uint /* KexiBLOBBuffer::Id_t is unsafe and unsupported by QVariant - will be fixed in Qt4*/)storedBLOBID));
00719         KFormDesigner::ObjectTreeItem *widgetItem = form()->objectTree()->lookup(it.key()->name());
00720         if (widgetItem)
00721             widgetItem->addModifiedProperty( "storedPixmapId", oldStoredPixmapId );
00722         else
00723             kexipluginswarn << "KexiFormView::storeData(): no '" << widgetItem->name() << "' widget found within a form" << endl;
00724     }
00725 //TODO: forall it.key()->setProperty(
00726 
00727     //-- now, save form's XML
00728     QString data;
00729     if (!KFormDesigner::FormIO::saveFormToString(tempData()->form, data))
00730         return false;
00731     if (!storeDataBlock(data))
00732         return false;
00733 
00734     //all blobs are now saved
00735     m_unsavedLocalBLOBs.clear();
00736 
00737     tempData()->tempForm = QString::null;
00738     return true;
00739 }
00740 
00741 #if 0
00743 void
00744 KexiFormView::slotWidgetSelected(KFormDesigner::Form *f, bool multiple)
00745 {
00746     if(f != form())
00747         return;
00748 
00749     enableFormActions();
00750     // Enable edit actions
00751     setAvailable("edit_copy", true);
00752     setAvailable("edit_cut", true);
00753     setAvailable("edit_clear", true);
00754 
00755     // 'Align Widgets' menu
00756     setAvailable("formpart_align_menu", multiple);
00757     setAvailable("formpart_align_to_left", multiple);
00758     setAvailable("formpart_align_to_right", multiple);
00759     setAvailable("formpart_align_to_top", multiple);
00760     setAvailable("formpart_align_to_bottom", multiple);
00761 
00762     setAvailable("formpart_adjust_size_menu", true);
00763     setAvailable("formpart_adjust_width_small", multiple);
00764     setAvailable("formpart_adjust_width_big", multiple);
00765     setAvailable("formpart_adjust_height_small", multiple);
00766     setAvailable("formpart_adjust_height_big", multiple);
00767 
00768     setAvailable("formpart_format_raise", true);
00769     setAvailable("formpart_format_lower", true);
00770 
00771     // If the widgets selected is a container, we enable layout actions
00772     if(!multiple)
00773     {
00774         KFormDesigner::ObjectTreeItem *item = f->objectTree()->lookup( f->selectedWidgets()->first()->name() );
00775         if(item && item->container())
00776             multiple = true;
00777     }
00778     // Layout actions
00779     setAvailable("formpart_layout_hbox", multiple);
00780     setAvailable("formpart_layout_vbox", multiple);
00781     setAvailable("formpart_layout_grid", multiple);
00782 
00783     KFormDesigner::Container *container = f->activeContainer();
00784     setAvailable("formpart_break_layout", container ?
00785         (container->layoutType() != KFormDesigner::Container::NoLayout) : false );
00786 }
00787 
00788 void
00789 KexiFormView::slotFormWidgetSelected(KFormDesigner::Form *f)
00790 {
00791     if(f != form())
00792         return;
00793 
00794     disableWidgetActions();
00795     enableFormActions();
00796 
00797     // Layout actions
00798     setAvailable("formpart_layout_hbox", true);
00799     setAvailable("formpart_layout_vbox", true);
00800     setAvailable("formpart_layout_grid", true);
00801     setAvailable("formpart_break_layout", (f->toplevelContainer()->layoutType() != KFormDesigner::Container::NoLayout));
00802 }
00803 
00804 void
00805 KexiFormView::slotNoFormSelected() // == form in preview mode
00806 {
00807     disableWidgetActions();
00808 
00809     // Disable paste action
00810     setAvailable("edit_paste", false);
00811     setAvailable("edit_undo", false);
00812     setAvailable("edit_redo", false);
00813 
00814     // Disable 'Tools' actions
00815     setAvailable("formpart_pixmap_collection", false);
00816     setAvailable("formpart_connections", false);
00817     setAvailable("formpart_taborder", false);
00818     setAvailable("formpart_change_style", false);
00819 }
00820 
00821 void
00822 KexiFormView::enableFormActions()
00823 {
00824     // Enable 'Tools' actions
00825     setAvailable("formpart_pixmap_collection", true);
00826     setAvailable("formpart_connections", true);
00827     setAvailable("formpart_taborder", true);
00828 
00829     setAvailable("edit_paste", KFormDesigner::FormManager::self()->isPasteEnabled());
00830 }
00831 
00832 void
00833 KexiFormView::disableWidgetActions()
00834 {
00835     // Disable edit actions
00836     setAvailable("edit_copy", false);
00837     setAvailable("edit_cut", false);
00838     setAvailable("edit_clear", false);
00839 
00840     // Disable format functions
00841     setAvailable("formpart_align_menu", false);
00842     setAvailable("formpart_align_to_left", false);
00843     setAvailable("formpart_align_to_right", false);
00844     setAvailable("formpart_align_to_top", false);
00845     setAvailable("formpart_align_to_bottom", false);
00846 
00847     setAvailable("formpart_adjust_size_menu", false);
00848     setAvailable("formpart_adjust_width_small", false);
00849     setAvailable("formpart_adjust_width_big", false);
00850     setAvailable("formpart_adjust_height_small", false);
00851     setAvailable("formpart_adjust_height_big", false);
00852 
00853     setAvailable("formpart_format_raise", false);
00854     setAvailable("formpart_format_lower", false);
00855 
00856     setAvailable("formpart_layout_hbox", false);
00857     setAvailable("formpart_layout_vbox", false);
00858     setAvailable("formpart_layout_grid", false);
00859     setAvailable("formpart_break_layout", false);
00860 }
00861 
00862 void
00863 KexiFormView::setUndoEnabled(bool enabled)
00864 {
00865     setAvailable("edit_undo", enabled);
00866 }
00867 
00868 void
00869 KexiFormView::setRedoEnabled(bool enabled)
00870 {
00871     setAvailable("edit_redo", enabled);
00872 }
00873 #endif //0
00874 
00875 QSize
00876 KexiFormView::preferredSizeHint(const QSize& otherSize)
00877 {
00878     if (parentDialog()->neverSaved()) {
00879         //ignore otherSize if possible
00880 //      return KexiViewBase::preferredSizeHint( (parentDialog() && parentDialog()->mdiParent()) ? QSize(10000,10000) : otherSize);
00881     }
00882 
00883     return (m_dbform->size()
00884             +QSize(m_scrollView->verticalScrollBar()->isVisible() ? m_scrollView->verticalScrollBar()->width()*3/2 : 10,
00885              m_scrollView->horizontalScrollBar()->isVisible() ? m_scrollView->horizontalScrollBar()->height()*3/2 : 10))
00886         .expandedTo( KexiViewBase::preferredSizeHint(otherSize) );
00887 }
00888 
00889 void
00890 KexiFormView::resizeEvent( QResizeEvent *e )
00891 {
00892     if (viewMode()==Kexi::DataViewMode) {
00893         m_scrollView->refreshContentsSizeLater(
00894             e->size().width()!=e->oldSize().width(),
00895             e->size().height()!=e->oldSize().height()
00896         );
00897     }
00898     KexiViewBase::resizeEvent(e);
00899     m_scrollView->updateNavPanelGeometry();
00900     if (m_delayedFormContentsResizeOnShow>0) { // && isVisible()) {
00901         m_delayedFormContentsResizeOnShow--;
00902         m_dbform->resize( e->size() - QSize(30, 30) );
00903     }
00904 }
00905 
00906 void
00907 KexiFormView::setFocusInternal()
00908 {
00909     if (viewMode() == Kexi::DataViewMode) {
00910         if (m_dbform->focusWidget()) {
00911             //better-looking focus
00912             if (m_setFocusInternalOnce) {
00913                 SET_FOCUS_USING_REASON(m_setFocusInternalOnce, QFocusEvent::Tab);
00914             }
00915             else {
00916                 SET_FOCUS_USING_REASON(m_dbform->focusWidget(), QFocusEvent::Tab);
00917             }
00918             return;
00919         }
00920     }
00921     QWidget::setFocus();
00922 }
00923 
00924 void
00925 KexiFormView::show()
00926 {
00927     KexiDataAwareView::show();
00928 
00929 //moved from KexiFormScrollView::show():
00930 
00931     //now get resize mode settings for entire form
00932     //  if (resizeMode() == KexiFormView::ResizeAuto)
00933     if (viewMode()==Kexi::DataViewMode) {
00934         if (resizeMode() == KexiFormView::ResizeAuto)
00935             m_scrollView->setResizePolicy(QScrollView::AutoOneFit);
00936     }
00937 }
00938 
00939 void
00940 KexiFormView::slotFocus(bool in)
00941 {
00942     if(in && form() && KFormDesigner::FormManager::self() && KFormDesigner::FormManager::self()->activeForm() != form()) {
00943         KFormDesigner::FormManager::self()->windowChanged(m_dbform);
00944         updateDataSourcePage();
00945     }
00946 }
00947 
00948 void
00949 KexiFormView::updateDataSourcePage()
00950 {
00951     if (viewMode()==Kexi::DesignViewMode) {
00952         QCString dataSourceMimeType, dataSource;
00953         KFormDesigner::WidgetPropertySet *set = KFormDesigner::FormManager::self()->propertySet();
00954         if (set->contains("dataSourceMimeType"))
00955             dataSourceMimeType = (*set)["dataSourceMimeType"].value().toCString();
00956         if (set->contains("dataSource"))
00957             dataSource = (*set)["dataSource"].value().toCString();
00958 
00959         formPart()->dataSourcePage()->setDataSource(dataSourceMimeType, dataSource);
00960     }
00961 }
00962 
00963 void
00964 KexiFormView::slotHandleDragMoveEvent(QDragMoveEvent* e)
00965 {
00966     if (KexiFieldDrag::canDecodeMultiple( e )) {
00967         e->accept(true);
00968         //dirty:    drawRect(QRect( e->pos(), QSize(50, 20)), 2);
00969     }
00970 }
00971 
00972 void
00973 KexiFormView::slotHandleDropEvent(QDropEvent* e)
00974 {
00975     if (KexiFieldDrag::canDecodeMultiple( e )) {
00976         QString sourceMimeType, sourceName;
00977         QStringList fields;
00978         if (!KexiFieldDrag::decodeMultiple( e, sourceMimeType, sourceName, fields ))
00979             return;
00980         insertAutoFields(sourceMimeType, sourceName, fields, e->pos());
00981     }
00982 }
00983 
00984 void
00985 KexiFormView::insertAutoFields(const QString& sourceMimeType, const QString& sourceName,
00986     const QStringList& fields, const QPoint& _pos)
00987 {
00988     if (fields.isEmpty())
00989         return;
00990 
00991     KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection();
00992     KexiDB::TableOrQuerySchema tableOrQuery(conn, sourceName.latin1(), sourceMimeType=="kexi/table");
00993     if (!tableOrQuery.table() && !tableOrQuery.query()) {
00994         kexipluginswarn << "KexiFormView::insertAutoFields(): no such table/query \""
00995             << sourceName << "\"" << endl;
00996         return;
00997     }
00998 
00999     QPoint pos(_pos);
01000     //if pos is not specified, compute a new position:
01001     if (pos==QPoint(-1,-1)) {
01002         if (m_widgetGeometryForRecentInsertAutoFields.isValid()) {
01003             pos = m_widgetGeometryForRecentInsertAutoFields.bottomLeft() 
01004                 + QPoint(0,form()->gridSize());
01005         }
01006         else {
01007             pos = QPoint(40, 40); //start here
01008         }
01009     }
01010 
01012 
01013 //      KFormDesigner::WidgetList* prevSelection = form()->selectedWidgets();
01014     KFormDesigner::WidgetList widgetsToSelect;
01015     KFormDesigner::CommandGroup *group = new KFormDesigner::CommandGroup(
01016         fields.count()==1 ? i18n("Insert AutoField widget") : i18n("Insert %1 AutoField widgets").arg(fields.count()),
01017         KFormDesigner::FormManager::self()->propertySet()
01018     );
01019 
01020     foreach( QStringList::ConstIterator, it, fields ) {
01021         KexiDB::QueryColumnInfo* column = tableOrQuery.columnInfo(*it);
01022         if (!column) {
01023             kexipluginswarn << "KexiFormView::insertAutoFields(): no such field \""
01024                 << *it << "\" in table/query \"" << sourceName << "\"" << endl;
01025             continue;
01026         }
01028         KFormDesigner::InsertWidgetCommand *insertCmd
01029             = new KFormDesigner::InsertWidgetCommand(form()->toplevelContainer(),
01031                 "KexiDBAutoField",
01033             pos, column->aliasOrName()
01034         );
01035         insertCmd->execute();
01036         group->addCommand(insertCmd, false/*don't exec twice*/);
01037 
01038         KFormDesigner::ObjectTreeItem *newWidgetItem 
01039             = form()->objectTree()->dict()->find(insertCmd->widgetName());
01040         KexiDBAutoField* newWidget 
01041             = newWidgetItem ? dynamic_cast<KexiDBAutoField*>(newWidgetItem->widget()) : 0;
01042         widgetsToSelect.append(newWidget);
01043 //#if 0
01044         KFormDesigner::CommandGroup *subGroup 
01045             = new KFormDesigner::CommandGroup("", KFormDesigner::FormManager::self()->propertySet());
01046         QMap<QCString, QVariant> propValues;
01047         propValues.insert("dataSource", column->aliasOrName());
01048         propValues.insert("fieldTypeInternal", (int)column->field->type());
01049         propValues.insert("fieldCaptionInternal", column->captionOrAliasOrName());
01050         KFormDesigner::FormManager::self()->propertySet()->createPropertyCommandsInDesignMode(
01051             newWidget, propValues, subGroup, false, 
01052             true );
01053         subGroup->execute();
01054         group->addCommand( subGroup, false/*will not be executed on CommandGroup::execute()*/ );
01055 
01056 //#endif
01057         //set data source and caption
01058         //-we don't need to use PropertyCommand here beacause we don't need UNDO 
01059         // for these single commands
01060 //      newWidget->setDataSource(column->aliasOrName());
01061 //      newWidget->setFieldTypeInternal((int)column->field->type());
01062 //      newWidget->setFieldCaptionInternal(column->captionOrAliasOrName());
01063         //resize again because autofield's type changed what can lead to changed sizeHint() 
01064 //      newWidget->resize(newWidget->sizeHint());
01065         KFormDesigner::WidgetList list;
01066         list.append(newWidget);
01067         KFormDesigner::AdjustSizeCommand *adjustCommand 
01068             =   new KFormDesigner::AdjustSizeCommand(KFormDesigner::AdjustSizeCommand::SizeToFit,
01069                 list, form());
01070         adjustCommand->execute();
01071         group->addCommand( adjustCommand,
01072             false/*will not be executed on CommandGroup::execute()*/
01073         );
01074 
01075         if (newWidget) {//move position down for next widget
01076             pos.setY( pos.y() + newWidget->height() + form()->gridSize());
01077         }
01078     }
01079     if (widgetsToSelect.last()) {
01080         //resize form if needed
01081         QRect oldFormRect( m_dbform->geometry() );
01082         QRect newFormRect( oldFormRect );
01083         newFormRect.setWidth(QMAX(m_dbform->width(), widgetsToSelect.last()->geometry().right()+1));
01084         newFormRect.setHeight(QMAX(m_dbform->height(), widgetsToSelect.last()->geometry().bottom()+1));
01085         if (newFormRect != oldFormRect) {
01086             //1. resize by hand
01087             m_dbform->setGeometry( newFormRect );
01088             //2. store information about resize
01089             KFormDesigner::PropertyCommand *resizeFormCommand = new KFormDesigner::PropertyCommand(
01090                 KFormDesigner::FormManager::self()->propertySet(), m_dbform->name(),
01091                 oldFormRect, newFormRect, "geometry"); 
01092             group->addCommand(resizeFormCommand, true/*will be executed on CommandGroup::execute()*/);
01093         }
01094 
01095         //remember geometry of the last inserted widget
01096         m_widgetGeometryForRecentInsertAutoFields = widgetsToSelect.last()->geometry();
01097     }
01098 
01099     //eventually, add entire command group to active form
01100     form()->addCommand( group, true/*exec*/ );
01101 
01102 //  group->debug();
01103 
01104     //enable proper REDO usage
01105     group->resetAllowExecuteFlags();
01106 
01107     m_scrollView->repaint();
01108     m_scrollView->viewport()->repaint();
01109     m_scrollView->repaintContents();
01110     m_scrollView->updateContents();
01111     m_scrollView->clipper()->repaint();
01112     m_scrollView->refreshContentsSize();
01113 
01114     //select all inserted widgets, if multiple
01115     if (widgetsToSelect.count()>1) {
01116         form()->setSelectedWidget(0);
01117         foreach_list (KFormDesigner::WidgetListIterator, it, widgetsToSelect)
01118             form()->setSelectedWidget(it.current(), true/*add*/, true/*dontRaise*/);
01119     }
01120 }
01121 
01122 void
01123 KexiFormView::setUnsavedLocalBLOB(QWidget *widget, KexiBLOBBuffer::Id_t id)
01124 {
01126     if (id==0) 
01127         m_unsavedLocalBLOBs.remove(widget);
01128     else
01129         m_unsavedLocalBLOBs.insert(widget, id);
01130 }
01131 
01132 /*
01133 todo
01134 void KexiFormView::updateActions(bool activated)
01135 {
01136     if (viewMode()==Kexi::DesignViewMode) {
01137         if (form()->selectedWidget()) {
01138             if (form()->widget() == form()->selectedWidget())
01139                 KFormDesigner::FormManager::self()->emitFormWidgetSelected( form() );
01140             else
01141                 KFormDesigner::FormManager::self()->emitWidgetSelected( form(), false );
01142         }
01143         else if (form()->selectedWidgets()) {
01144             KFormDesigner::FormManager::self()->emitWidgetSelected( form(), true );
01145         }
01146     }
01147     KexiDataAwareView::updateActions(activated);
01148 }*/
01149 
01150 /*
01151 void KexiFormView::parentDialogDetached()
01152 {
01153     m_dbform->updateTabStopsOrder(form());
01154 }
01155 
01156 void KexiFormView::parentDialogAttached(KMdiChildFrm *)
01157 {
01158     m_dbform->updateTabStopsOrder(form());
01159 }*/
01160 
01161 #include "kexiformview.moc"
01162 
KDE Home | KDE Accessibility Home | Description of Access Keys