📄 q3datatable.cpp
字号:
d->editBuffer = 0; updateRow( d->editRow ); d->editRow = -1; d->editCol = -1; setEditMode( NotEditing, -1, -1 );}/*! Protected virtual function called when editing is about to begin on a new record. If the table is read-only, or if there's no cursor or the cursor does not allow inserts, nothing happens and false is returned. Otherwise returns true. Editing takes place using the cursor's edit buffer(see Q3SqlCursor::editBuffer()). When editing begins, a new row is created in the table marked with an asterisk '*' in the row's vertical header column, i.e. at the left of the row.*/bool Q3DataTable::beginInsert(){ if ( !sqlCursor() || isReadOnly() || !numCols() ) return false; if ( !sqlCursor()->canInsert() ) return false; int i = 0; int row = currentRow(); d->insertPreRows = numRows(); if ( row < 0 || numRows() < 1 ) row = 0; setNumRows( d->insertPreRows + 1 ); setCurrentCell( row, 0 ); d->editBuffer = sqlCursor()->primeInsert(); emit primeInsert( d->editBuffer ); d->dat.setMode( QSql::Insert ); int lastRow = row; int lastY = contentsY() + visibleHeight(); for ( i = row; i < numRows() ; ++i ) { QRect cg = cellGeometry( i, 0 ); if ( (cg.y()+cg.height()) > lastY ) { lastRow = i; break; } } if ( lastRow == row && ( numRows()-1 > row ) ) lastRow = numRows() - 1; d->insertRowLast = lastRow; d->insertHeaderLabelLast = verticalHeader()->label( d->insertRowLast ); verticalHeader()->setLabel( row, QString(QLatin1Char('*')) ); d->editRow = row; // in the db world it's common to allow inserting new records // into a table that has read-only columns - temporarily // switch off read-only mode for such columns bool fakeReadOnly = isColumnReadOnly( 0 ); setColumnReadOnly( 0, false ); if ( Q3Table::beginEdit( row, 0, false ) ) setEditMode( Editing, row, 0 ); setColumnReadOnly( 0, fakeReadOnly ); return true;}/*! Protected virtual function called when editing is about to begin on an existing row. If the table is read-only, or if there's no cursor, nothing happens. Editing takes place using the cursor's edit buffer (see Q3SqlCursor::editBuffer()). \a row and \a col refer to the row and column in the Q3DataTable. (\a replace is provided for reimplementors and reflects the API of Q3Table::beginEdit().)*/QWidget* Q3DataTable::beginUpdate ( int row, int col, bool replace ){ if ( !sqlCursor() || isReadOnly() || isColumnReadOnly( col ) ) return 0; setCurrentCell( row, col ); d->dat.setMode( QSql::Update ); if ( sqlCursor()->seek( row ) ) { d->editBuffer = sqlCursor()->primeUpdate(); sqlCursor()->seek( currentRow() ); emit primeUpdate( d->editBuffer ); return Q3Table::beginEdit( row, col, replace ); } return 0;}/*! For an editable table, issues an insert on the current cursor using the values in the cursor's edit buffer. If there is no current cursor or there is no current "insert" row, nothing happens. If confirmEdits() or confirmInsert() is true, confirmEdit() is called to confirm the insert. Returns true if the insert succeeded; otherwise returns false. The underlying cursor must have a valid primary index to ensure that a unique record is inserted within the database otherwise the database may be changed to an inconsistent state.*/bool Q3DataTable::insertCurrent(){ if ( d->dat.mode() != QSql::Insert || ! numCols() ) return false; if ( !sqlCursor()->canInsert() ) {#ifdef QT_CHECK_RANGE qWarning("Q3DataTable::insertCurrent: insert not allowed for %s", sqlCursor()->name().latin1() );#endif endInsert(); return false; } int b = 0; int conf = QSql::Yes; if ( confirmEdits() || confirmInsert() ) conf = confirmEdit( QSql::Insert ); switch ( conf ) { case QSql::Yes: {#ifndef QT_NO_CURSOR QApplication::setOverrideCursor( Qt::waitCursor );#endif emit beforeInsert( d->editBuffer ); b = sqlCursor()->insert();#ifndef QT_NO_CURSOR QApplication::restoreOverrideCursor();#endif if ( ( !b && !sqlCursor()->isActive() ) || !sqlCursor()->isActive() ) { handleError( sqlCursor()->lastError() ); endInsert(); // cancel the insert if anything goes wrong refresh(); } else { endInsert(); refresh(); QSqlIndex idx = sqlCursor()->primaryIndex(); findBuffer( idx, d->lastAt ); repaintContents( contentsX(), contentsY(), visibleWidth(), visibleHeight(), false ); emit cursorChanged( QSql::Insert ); } break; } case QSql::No: endInsert(); break; case QSql::Cancel: if ( Q3Table::beginEdit( currentRow(), currentColumn(), false ) ) setEditMode( Editing, currentRow(), currentColumn() ); break; } return ( b > 0 );}/*! \internal Updates the row \a row.*/void Q3DataTable::updateRow( int row ){ for ( int i = 0; i < numCols(); ++i ) updateCell( row, i );}/*! For an editable table, issues an update using the cursor's edit buffer. If there is no current cursor or there is no current selection, nothing happens. If confirmEdits() or confirmUpdate() is true, confirmEdit() is called to confirm the update. Returns true if the update succeeded; otherwise returns false. The underlying cursor must have a valid primary index to ensure that a unique record is updated within the database otherwise the database may be changed to an inconsistent state.*/bool Q3DataTable::updateCurrent(){ if ( d->dat.mode() != QSql::Update ) return false; if ( sqlCursor()->primaryIndex().count() == 0 ) {#ifdef QT_CHECK_RANGE qWarning("Q3DataTable::updateCurrent: no primary index for %s", sqlCursor()->name().latin1() );#endif endUpdate(); return false; } if ( !sqlCursor()->canUpdate() ) {#ifdef QT_CHECK_RANGE qWarning("Q3DataTable::updateCurrent: updates not allowed for %s", sqlCursor()->name().latin1() );#endif endUpdate(); return false; } int b = 0; int conf = QSql::Yes; if ( confirmEdits() || confirmUpdate() ) conf = confirmEdit( QSql::Update ); switch ( conf ) { case QSql::Yes: {#ifndef QT_NO_CURSOR QApplication::setOverrideCursor( Qt::waitCursor );#endif emit beforeUpdate( d->editBuffer ); b = sqlCursor()->update();#ifndef QT_NO_CURSOR QApplication::restoreOverrideCursor();#endif if ( ( !b && !sqlCursor()->isActive() ) || !sqlCursor()->isActive() ) { handleError( sqlCursor()->lastError() ); endUpdate(); refresh(); setCurrentCell( d->editRow, d->editCol ); if ( Q3Table::beginEdit( d->editRow, d->editCol, false ) ) setEditMode( Editing, d->editRow, d->editCol ); } else { emit cursorChanged( QSql::Update ); refresh(); endUpdate(); } break; } case QSql::No: endUpdate(); setEditMode( NotEditing, -1, -1 ); break; case QSql::Cancel: setCurrentCell( d->editRow, d->editCol ); if ( Q3Table::beginEdit( d->editRow, d->editCol, false ) ) setEditMode( Editing, d->editRow, d->editCol ); break; } return ( b > 0 );}/*! For an editable table, issues a delete on the current cursor's primary index using the values of the currently selected row. If there is no current cursor or there is no current selection, nothing happens. If confirmEdits() or confirmDelete() is true, confirmEdit() is called to confirm the delete. Returns true if the delete succeeded; otherwise false. The underlying cursor must have a valid primary index to ensure that a unique record is deleted within the database otherwise the database may be changed to an inconsistent state.*/bool Q3DataTable::deleteCurrent(){ if ( !sqlCursor() || isReadOnly() ) return false; if ( sqlCursor()->primaryIndex().count() == 0 ) {#ifdef QT_CHECK_RANGE qWarning("Q3DataTable::deleteCurrent: no primary index %s", sqlCursor()->name().latin1() );#endif return false; } if ( !sqlCursor()->canDelete() ) return false; int b = 0; int conf = QSql::Yes; if ( confirmEdits() || confirmDelete() ) conf = confirmEdit( QSql::Delete ); // Have to have this here - the confirmEdit() might pop up a // dialog that causes a repaint which the cursor to the // record it has to repaint. if ( !sqlCursor()->seek( currentRow() ) ) return false; switch ( conf ) { case QSql::Yes:{#ifndef QT_NO_CURSOR QApplication::setOverrideCursor( Qt::waitCursor );#endif sqlCursor()->primeDelete(); emit primeDelete( sqlCursor()->editBuffer() ); emit beforeDelete( sqlCursor()->editBuffer() ); b = sqlCursor()->del();#ifndef QT_NO_CURSOR QApplication::restoreOverrideCursor();#endif if ( !b ) handleError( sqlCursor()->lastError() ); refresh(); emit cursorChanged( QSql::Delete ); setCurrentCell( currentRow(), currentColumn() ); repaintContents( contentsX(), contentsY(), visibleWidth(), visibleHeight(), false ); verticalHeader()->repaint(); // get rid of trailing garbage } break; case QSql::No: setEditMode( NotEditing, -1, -1 ); break; } return ( b > 0 );}/*! Protected virtual function which returns a confirmation for an edit of mode \a m. Derived classes can reimplement this function to provide their own confirmation dialog. The default implementation uses a message box which prompts the user to confirm the edit action.*/QSql::Confirm Q3DataTable::confirmEdit( QSql::Op m ){ return d->dat.confirmEdit( this, m );}/*! Protected virtual function which returns a confirmation for canceling an edit mode of \a m. Derived classes can reimplement this function to provide their own cancel dialog. The default implementation uses a message box which prompts the user to confirm the cancel.*/QSql::Confirm Q3DataTable::confirmCancel( QSql::Op m ){ return d->dat.confirmCancel( this, m );}/*! Searches the current cursor for a cell containing the string \a str starting at the current cell and working forwards (or backwards if \a backwards is true). If the string is found, the cell containing the string is set as the current cell. If \a caseSensitive is false the case of \a str will be ignored. The search will wrap, i.e. if the first (or if backwards is true, last) cell is reached without finding \a str the search will continue until it reaches the starting cell. If \a str is not found the search will fail and the current cell will remain unchanged.*/void Q3DataTable::find( const QString & str, bool caseSensitive, bool backwards ){ if ( !sqlCursor() ) return; Q3SqlCursor * r = sqlCursor(); QString tmp, text; uint row = currentRow(), startRow = row, col = backwards ? currentColumn() - 1 : currentColumn() + 1; bool wrap = true, found = false; if( str.isEmpty() || str.isNull() ) return; if( !caseSensitive ) tmp = str.lower(); else tmp = str;#ifndef QT_NO_CURSOR QApplication::setOverrideCursor( Qt::waitCursor );#endif while( wrap ){ while( !found && r->seek( row ) ){ for( int i = col; backwards ? (i >= 0) : (i < (int) numCols()); backwards ? i-- : i++ ) { text = r->value( indexOf( i ) ).toString(); if( !caseSensitive ){ text = text.lower(); } if( text.contains( tmp ) ){ setCurrentCell( row, i ); col = i; found = true; } } if( !backwards ){ col = 0; row++; } else { col = numCols() - 1; row--; } } if( !backwards ){ if( startRow != 0 ){ startRow = 0; } else { wrap = false; } r->first(); row = 0; } else { if( startRow != (uint) (numRows() - 1) ){ startRow = numRows() - 1; } else { wrap = false; } r->last(); row = numRows() - 1; } }#ifndef QT_NO_CURSOR QApplication::restoreOverrideCursor();#endif}/*! Resets the table so that it displays no data. \sa setSqlCursor()*/void Q3DataTable::reset(){ clearCellWidget( currentRow(), currentColumn() ); switch ( d->dat.mode() ) { case QSql::Insert: endInsert(); break; case QSql::Update: endUpdate(); break; default: break; } ensureVisible( 0, 0 ); verticalScrollBar()->setValue(0); setNumRows(0); d->haveAllRows = false; d->continuousEdit = false; d->dat.setMode( QSql::None ); d->editRow = -1; d->editCol = -1; d->insertRowLast = -1; d->insertHeaderLabelLast.clear(); d->cancelMode = false; d->lastAt = -1; d->fld.clear(); d->fldLabel.clear(); d->fldWidth.clear(); d->fldIcon.clear(); d->fldHidden.clear(); if ( sorting() ) horizontalHeader()->setSortIndicator( -1 );}/*! Returns the index of the field within the current SQL query that is displayed in column \a i.*/int Q3DataTable::indexOf( uint i ) const{ Q3DataTablePrivate::ColIndex::ConstIterator it = d->colIndex.at( i ); if ( it != d->colIndex.end() ) return *it; return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -