kexi

kexiformscrollview.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 "kexiformscrollview.h"
00022 //#include "kexiformview.h"
00023 
00024 #include <formeditor/form.h>
00025 #include <formeditor/formmanager.h>
00026 #include <formeditor/objecttree.h>
00027 #include <formeditor/commands.h>
00028 #include <widget/utils/kexirecordmarker.h>
00029 
00030 #include <kpopupmenu.h>
00031 
00032 KexiFormScrollView::KexiFormScrollView(QWidget *parent, bool preview)
00033  : KexiScrollView(parent, preview)
00034  , KexiRecordNavigatorHandler()
00035  , KexiSharedActionClient()
00036  , KexiDataAwareObjectInterface()
00037  , KexiFormDataProvider()
00038  , KexiFormEventHandler()
00039 {
00040     m_currentLocalSortColumn = -1; /* no column */
00041     m_localSortingOrder = -1; /* no sorting */
00042     m_previousItem = 0;
00043     m_navPanel = m_scrollViewNavPanel; //copy this pointer from KexiScrollView
00044     if (preview) {
00045         setRecordNavigatorVisible(true);
00046 //tmp
00047 //      recordNavigator()->setEditingIndicatorEnabled(true);
00048 //      recordNavigator()->showEditingIndicator(true);
00049     }
00050 
00051     connect(this, SIGNAL(resizingStarted()), this, SLOT(slotResizingStarted()));
00052 
00053     m_popup = new KPopupMenu(this, "contextMenu");
00054 
00055 //  setFocusPolicy(NoFocus);
00056 }
00057 
00058 KexiFormScrollView::~KexiFormScrollView()
00059 {
00060     if (m_owner)
00061         delete m_data;
00062     m_data = 0;
00063 }
00064 
00065 void
00066 KexiFormScrollView::show()
00067 {
00068     KexiScrollView::show();
00069 
00070 #if 0 //moved to KexiFormView, OK?
00071     //now get resize mode settings for entire form
00072     if (m_preview) {
00073         KexiFormView* fv = dynamic_cast<KexiFormView*>(parent());
00074         int resizeMode = fv ? fv->resizeMode() : KexiFormView::ResizeAuto;
00075         if (resizeMode == KexiFormView::ResizeAuto)
00076             setResizePolicy(AutoOneFit);
00077     }
00078 #endif
00079 }
00080 
00081 void
00082 KexiFormScrollView::slotResizingStarted()
00083 {
00084     if(m_form && KFormDesigner::FormManager::self())
00085         setSnapToGrid(KFormDesigner::FormManager::self()->snapWidgetsToGrid(), m_form->gridSize());
00086     else
00087         setSnapToGrid(false);
00088 }
00089 
00090 int KexiFormScrollView::rowsPerPage() const
00091 {
00093     return 10;
00094 }
00095 
00096 void KexiFormScrollView::selectCellInternal()
00097 {
00098     //m_currentItem is already set by KexiDataAwareObjectInterface::setCursorPosition()
00099     if (m_currentItem) {
00100         if (m_currentItem!=m_previousItem) {
00101             fillDataItems(*m_currentItem);
00102             m_previousItem = m_currentItem;
00103         }
00104     }
00105     else
00106             m_previousItem = 0;
00107 }
00108 
00109 void KexiFormScrollView::ensureCellVisible(int row, int col/*=-1*/)
00110 {
00111     Q_UNUSED( row );
00112     Q_UNUSED( col );
00114 //  if (m_currentItem)
00115         //fillDataItems(*m_currentItem);
00116 
00117 //  if (m_form->tabStops()->first() && m_form->tabStops()->first()->widget())
00118 //      m_form->tabStops()->first()->widget()->setFocus();
00119 }
00120 
00121 void KexiFormScrollView::moveToRecordRequested(uint r)
00122 {
00124     selectRow(r);
00125 }
00126 
00127 void KexiFormScrollView::moveToLastRecordRequested()
00128 {
00130     selectLastRow();
00131 }
00132 
00133 void KexiFormScrollView::moveToPreviousRecordRequested()
00134 {
00136     selectPrevRow();
00137 }
00138 
00139 void KexiFormScrollView::moveToNextRecordRequested()
00140 {
00142     selectNextRow();
00143 }
00144 
00145 void KexiFormScrollView::moveToFirstRecordRequested()
00146 {
00148     selectFirstRow();
00149 }
00150 
00151 /*
00152 void KexiFormScrollView::addNewRecordRequested()
00153 {
00155 }*/
00156 
00157 void KexiFormScrollView::clearColumnsInternal(bool repaint)
00158 {
00159     Q_UNUSED( repaint );
00161 }
00162 
00163 void KexiFormScrollView::addHeaderColumn(const QString& caption, const QString& description, int width)
00164 {
00165     Q_UNUSED( caption );
00166     Q_UNUSED( description );
00167     Q_UNUSED( width );
00168 
00170 }
00171 
00172 int KexiFormScrollView::currentLocalSortingOrder() const
00173 {
00175     return m_localSortingOrder;
00176 }
00177 
00178 int KexiFormScrollView::currentLocalSortColumn() const
00179 {
00180     return m_currentLocalSortColumn;
00181 }
00182 
00183 void KexiFormScrollView::setLocalSortingOrder(int col, int order)
00184 {
00186     m_currentLocalSortColumn = col;
00187     m_localSortingOrder = order;
00188 }
00189 
00190 void KexiFormScrollView::sortColumnInternal(int col, int order)
00191 {
00192     Q_UNUSED( col );
00193     Q_UNUSED( order );
00195 }
00196 
00197 void KexiFormScrollView::updateGUIAfterSorting()
00198 {
00200 }
00201 
00202 void KexiFormScrollView::createEditor(int row, int col, const QString& addText, 
00203     bool removeOld)
00204 {
00205     Q_UNUSED( row );
00206     Q_UNUSED( addText );
00207     Q_UNUSED( removeOld );
00208 
00209     if (isReadOnly()) {
00210         kexipluginsdbg << "KexiFormScrollView::createEditor(): DATA IS READ ONLY!"<<endl;
00211         return;
00212     }
00213     if (column( col )->isReadOnly()) {
00214         kexipluginsdbg << "KexiFormScrollView::createEditor(): COL IS READ ONLY!"<<endl;
00215         return;
00216     }
00217 
00219     const bool startRowEdit = !m_rowEditing; //remember if we're starting row edit
00220 
00221     if (!m_rowEditing) {
00222         //we're starting row editing session
00223         m_data->clearRowEditBuffer();
00224         
00225         m_rowEditing = true;
00226         //indicate on the vheader that we are editing:
00227         if (m_verticalHeader)
00228             m_verticalHeader->setEditRow(m_curRow);
00229         if (isInsertingEnabled() && m_currentItem==m_insertItem) {
00230             //we should know that we are in state "new row editing"
00231             m_newRowEditing = true;
00232             //'insert' row editing: show another row after that:
00233             m_data->append( m_insertItem );
00234             //new empty insert item
00235             m_insertItem = m_data->createItem(); //new KexiTableItem(dataColumns());
00236 //          updateContents();
00237             if (m_verticalHeader)
00238                 m_verticalHeader->addLabel();
00239 //          m_verticalHeaderAlreadyAdded = true;
00240             updateWidgetContentsSize();
00241             //refr. current and next row
00242 //          updateContents(columnPos(0), rowPos(row), viewport()->width(), d->rowHeight*2);
00243 //js: warning this breaks behaviour (cursor is skipping, etc.): qApp->processEvents(500);
00244 //          ensureVisible(columnPos(m_curCol), rowPos(row+1)+d->rowHeight-1, columnWidth(m_curCol), d->rowHeight);
00245 
00246 //          m_verticalHeader->setOffset(contentsY());
00247         }
00248     }   
00249 
00250     m_editor = editor(col); //m_dataItems.at(col);
00251     if (!m_editor)
00252         return;
00253 
00254     if (startRowEdit) {
00255         recordNavigator()->showEditingIndicator(true);
00256 //      recordNavigator()->updateButtons(); //refresh 'next btn'
00257 
00258         emit rowEditStarted(m_curRow);
00259     }
00260 }
00261 
00262 KexiDataItemInterface *KexiFormScrollView::editor( int col, bool ignoreMissingEditor )
00263 {
00264     Q_UNUSED( ignoreMissingEditor );
00265 
00266     if (!m_data || col<0 || col>=columns())
00267         return 0;
00268 
00269     return dynamic_cast<KexiFormDataItemInterface*>(dbFormWidget()->orderedDataAwareWidgets()->at( col ));
00270 //  KexiFormDataItemInterface *item = m_dataItems.at(col);
00271     //return item;
00272 
00273 /*
00274     KexiTableViewColumn *tvcol = m_data->column(col);
00275 //  int t = tvcol->field->type();
00276 
00277     //find the editor for this column
00278     KexiDataItemInterface *editor = d->editors[ tvcol ];
00279     if (editor)
00280         return editor;
00281 
00282     //not found: create
00283 //  editor = KexiCellEditorFactory::createEditor(*m_data->column(col)->field, this);
00284     editor = KexiCellEditorFactory::createEditor(*m_data->column(col), this);
00285     if (!editor) {//create error!
00286         if (!ignoreMissingEditor) {
00287             //js TODO: show error???
00288             cancelRowEdit();
00289         }
00290         return 0;
00291     }
00292     editor->hide();
00293     connect(editor,SIGNAL(editRequested()),this,SLOT(slotEditRequested()));
00294     connect(editor,SIGNAL(cancelRequested()),this,SLOT(cancelEditor()));
00295     connect(editor,SIGNAL(acceptRequested()),this,SLOT(acceptEditor()));
00296 
00297     editor->resize(columnWidth(col)-1, rowHeight()-1);
00298     editor->installEventFilter(this);
00299     if (editor->widget())
00300         editor->widget()->installEventFilter(this);
00301     //store
00302     d->editors.insert( tvcol, editor );
00303     return editor;*/
00304 }
00305 
00306 void KexiFormScrollView::editorShowFocus( int row, int col )
00307 {
00308     Q_UNUSED( row );
00309     Q_UNUSED( col );
00311 //  if (m_currentItem)
00312 //      m_provider->fillDataItems(*m_currentItem);
00313 }
00314 
00315 void KexiFormScrollView::updateCell(int row, int col)
00316 {
00317     Q_UNUSED( row );
00318     Q_UNUSED( col );
00320 }
00321 
00322 void KexiFormScrollView::updateRow(int row)
00323 {
00324     Q_UNUSED(row)
00326 }
00327 
00328 void KexiFormScrollView::updateWidgetContents()
00329 {
00331 }
00332 
00333 void KexiFormScrollView::updateWidgetContentsSize()
00334 {
00336 }
00337 
00338 void KexiFormScrollView::updateWidgetScrollBars()
00339 {
00341 }
00342 
00343 void KexiFormScrollView::slotRowRepaintRequested(KexiTableItem& item)
00344 {
00345     Q_UNUSED( item );
00347 }
00348 
00349 /*void KexiFormScrollView::slotAboutToDeleteRow(KexiTableItem& item, 
00350     KexiDB::ResultInfo* result, bool repaint)
00351 {
00353 }*/
00354 
00355 /*void KexiFormScrollView::slotRowDeleted()
00356 {
00358 }*/
00359 
00360 void KexiFormScrollView::slotRowInserted(KexiTableItem *item, bool repaint)
00361 {
00362     Q_UNUSED( item );
00363     Q_UNUSED( repaint );
00365 }
00366 
00367 void KexiFormScrollView::slotRowInserted(KexiTableItem *item, uint row, bool repaint)
00368 {
00369     Q_UNUSED( item );
00370     Q_UNUSED( row );
00371     Q_UNUSED( repaint );
00373 }
00374 
00375 void KexiFormScrollView::slotRowsDeleted( const QValueList<int> & )
00376 {
00378 }
00379 
00380 KexiDBForm* KexiFormScrollView::dbFormWidget() const
00381 {
00382     return dynamic_cast<KexiDBForm*>(m_widget);
00383 }
00384 
00385 int KexiFormScrollView::columns() const
00386 {
00387     return dbFormWidget()->orderedDataAwareWidgets()->count(); //m_dataItems.count();
00388 }
00389 
00390 /*uint KexiFormScrollView::fieldNumberForColumn(int col)
00391 {
00392     KexiFormDataItemInterface *item = dynamic_cast<KexiFormDataItemInterface*>(dbFormWidget()->orderedDataAwareWidgets()->at( col ));
00393     if (!item)
00394         return -1;
00395     KexiFormDataItemInterfaceToIntMap::ConstIterator it(m_fieldNumbersForDataItems.find( item ));
00396     return it!=m_fieldNumbersForDataItems.constEnd() ? it.data() : -1;
00397 }*/
00398 
00399 bool KexiFormScrollView::columnEditable(int col)
00400 {
00401     kexipluginsdbg << "KexiFormScrollView::columnEditable(" << col << ")" << endl;
00402     foreach_list (QPtrListIterator<KexiFormDataItemInterface>, it, m_dataItems) {
00403         kexipluginsdbg << (dynamic_cast<QWidget*>(it.current()) ? dynamic_cast<QWidget*>(it.current())->name() : "" ) 
00404             << " " << it.current()->dataSource() << endl;
00405     }
00406     kexipluginsdbg << "-- focus widgets --" << endl;
00407     foreach_list (QPtrListIterator<QWidget>, it, *dbFormWidget()->orderedFocusWidgets()) {
00408         kexipluginsdbg << it.current()->name() << endl;
00409     }
00410     kexipluginsdbg << "-- data-aware widgets --" << endl;
00411     foreach_list (QPtrListIterator<QWidget>, it, *dbFormWidget()->orderedDataAwareWidgets()) {
00412         kexipluginsdbg << it.current()->name() << endl;
00413     }
00414 
00415     //int index = dbFormWidget()->indexForDataItem( item );
00416 //  KexiFormDataItemInterface *item1 = dynamic_cast<KexiFormDataItemInterface*>(dbFormWidget()->orderedFocusWidgets()->at( col ));
00417     KexiFormDataItemInterface *item = dynamic_cast<KexiFormDataItemInterface*>(dbFormWidget()->orderedDataAwareWidgets()->at( col ));
00418 
00419     if (!item || item->isReadOnly())
00420         return false;
00421 
00422 //  KexiFormDataItemInterfaceToIntMap::ConstIterator it(m_fieldNumbersForDataItems.find( item ));
00423 //  return KexiDataAwareObjectInterface::columnEditable( it!=m_fieldNumbersForDataItems.constEnd() ? it.data() : -1 );
00424     return KexiDataAwareObjectInterface::columnEditable( col );
00425 }
00426 
00427 void KexiFormScrollView::valueChanged(KexiDataItemInterface* item)
00428 {
00429     if (!item)
00430         return;
00431     //only signal start editing when no row editing was started already
00432     kexipluginsdbg << "** KexiFormScrollView::valueChanged(): editedItem=" 
00433         << (dbFormWidget()->editedItem ? dbFormWidget()->editedItem->value().toString() : QString::null)
00434         << ", "
00435         << (item ? item->value().toString() : QString::null)
00436         << endl;
00437     if (dbFormWidget()->editedItem!=item) {
00438         kexipluginsdbg << "**>>>    dbFormWidget()->editedItem = dynamic_cast<KexiFormDataItemInterface*>(item)" << endl;
00439         dbFormWidget()->editedItem = dynamic_cast<KexiFormDataItemInterface*>(item);
00440         startEditCurrentCell();
00441     }
00442     fillDuplicatedDataItems(dynamic_cast<KexiFormDataItemInterface*>(item), item->value());
00443 }
00444 
00445 bool KexiFormScrollView::cursorAtNewRow()
00446 {
00447     return isInsertingEnabled() && ( m_currentItem==m_insertItem || m_newRowEditing );
00448 }
00449 
00450 void KexiFormScrollView::initDataContents()
00451 {
00452     KexiDataAwareObjectInterface::initDataContents();
00453 
00454     if (m_preview) {
00456         setRecordNavigatorVisible(m_data);
00457         recordNavigator()->setEnabled(m_data);
00458         if (m_data) {
00459             recordNavigator()->setEditingIndicatorEnabled( !isReadOnly() );
00460             recordNavigator()->showEditingIndicator(false);
00461         }
00462     }
00463 }
00464 
00465 KexiTableViewColumn* KexiFormScrollView::column(int col)
00466 {
00467     const int id = fieldNumberForColumn(col);
00468     return (id >= 0) ? m_data->column( id ) : 0;
00469 }
00470 
00471 void KexiFormScrollView::cancelEditor()
00472 {
00473     if (!dynamic_cast<KexiFormDataItemInterface*>(m_editor))
00474         return;
00475 
00476     dynamic_cast<KexiFormDataItemInterface*>(m_editor)->undoChanges();
00477     m_editor = 0;
00478 }
00479 
00480 void KexiFormScrollView::updateAfterCancelRowEdit()
00481 {
00482     for (QPtrListIterator<KexiFormDataItemInterface> it(m_dataItems); it.current(); ++it) {
00483         it.current()->undoChanges();
00484     }
00485     recordNavigator()->showEditingIndicator(false);
00486     dbFormWidget()->editedItem = 0;
00487 }
00488 
00489 void KexiFormScrollView::updateAfterAcceptRowEdit()
00490 {
00491     if (!m_currentItem)
00492         return;
00493     recordNavigator()->showEditingIndicator(false);
00494     dbFormWidget()->editedItem = 0;
00495     //update visible data because there could be auto-filled (eg. autonumber) fields
00496     fillDataItems(*m_currentItem);
00497     m_previousItem = m_currentItem;
00498 }
00499 
00500 void KexiFormScrollView::beforeSwitchView()
00501 {
00502     m_editor = 0;
00503 }
00504 
00505 void KexiFormScrollView::refreshContentsSize()
00506 {
00507     KexiScrollView::refreshContentsSize();
00508     //only clear cmd history when KexiScrollView::refreshContentsSizeLater() has been called
00509     if (!m_preview && sender()==&m_delayedResize) {
00510         if (m_form)
00511             m_form->clearCommandHistory();
00512     }
00513 }
00514 
00515 #include "kexiformscrollview.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys