24#include <QPlainTextEdit>
27 : QTableWidget( parent )
29 mHeaderMenu =
new QMenu(
this );
32 connect(
this, &QgsTableEditorWidget::cellChanged,
this, [ = ]
38 horizontalHeader()->setContextMenuPolicy( Qt::CustomContextMenu );
39 connect( horizontalHeader(), &QWidget::customContextMenuRequested,
this, [ = ](
const QPoint & point )
41 const int column = horizontalHeader()->logicalIndexAt( point.x() );
43 QSet< int > selectedColumns;
44 for (
const QModelIndex &index : selectedIndexes() )
46 selectedColumns.insert( index.column() );
50 bool isConsecutive = collectConsecutiveColumnRange( selectedIndexes(), minCol, maxCol );
53 if ( selectedIndexes().count() == 1 )
56 selectColumn( column );
59 else if ( !selectedColumns.contains( column ) )
62 selectColumn( column );
69 QAction *insertBefore = mHeaderMenu->addAction( selectedColumns.size() > 1 ? tr(
"Insert %n Column(s) Before",
nullptr, selectedColumns.size() ) : tr(
"Insert Column Before" ) );
71 QAction *insertAfter = mHeaderMenu->addAction( selectedColumns.size() > 1 ? tr(
"Insert %n Column(s) After",
nullptr, selectedColumns.size() ) : tr(
"Insert Column After" ) );
74 QAction *deleteSelected = mHeaderMenu->addAction( selectedColumns.size() > 1 ? tr(
"Delete %n Column(s)",
nullptr, selectedColumns.size() ) : tr(
"Delete Column" ) );
77 mHeaderMenu->popup( horizontalHeader()->mapToGlobal( point ) );
80 verticalHeader()->setContextMenuPolicy( Qt::CustomContextMenu );
81 connect( verticalHeader(), &QWidget::customContextMenuRequested,
this, [ = ](
const QPoint & point )
83 const int row = verticalHeader()->logicalIndexAt( point.y() );
85 QSet< int > selectedRows;
86 for (
const QModelIndex &index : selectedIndexes() )
88 selectedRows.insert( index.row() );
92 bool isConsecutive = collectConsecutiveRowRange( selectedIndexes(), minRow, maxRow );
95 if ( selectedIndexes().count() == 1 )
101 else if ( !selectedRows.contains( row ) )
105 isConsecutive =
true;
108 mHeaderMenu->clear();
111 QAction *insertBefore = mHeaderMenu->addAction( selectedRows.size() > 1 ? tr(
"Insert %n Row(s) Above",
nullptr, selectedRows.size() ) : tr(
"Insert Row Above" ) );
113 QAction *insertAfter = mHeaderMenu->addAction( selectedRows.size() > 1 ? tr(
"Insert %n Row(s) Below",
nullptr, selectedRows.size() ) : tr(
"Insert Row Below" ) );
116 QAction *deleteSelected = mHeaderMenu->addAction( selectedRows.size() > 1 ? tr(
"Delete %n Row(s)",
nullptr, selectedRows.size() ) : tr(
"Delete Row" ) );
119 mHeaderMenu->popup( verticalHeader()->mapToGlobal( point ) );
124 connect( delegate, &QgsTableEditorDelegate::updateNumericFormatForIndex,
this, &QgsTableEditorWidget::updateNumericFormatForIndex );
125 setItemDelegate( delegate );
128 connect(
this, &QTableWidget::cellDoubleClicked,
this, [ = ]
132 d->setWeakEditorMode(
false );
141 qDeleteAll( mNumericFormats );
144void QgsTableEditorWidget::updateNumericFormatForIndex(
const QModelIndex &index )
146 if ( QTableWidgetItem *i = item( index.row(), index.column() ) )
150 i->setData( Qt::DisplayRole, format->formatDouble( index.data( CellContent ).toDouble(),
QgsNumericFormatContext() ) );
155void QgsTableEditorWidget::updateHeaders()
163 for (
char c =
'A';
c <=
'Z';
c++ )
165 letters.push_back( QString(
c ) );
168 int len = letters.length();
172 for (
int i = 0; i < 1000; i++ )
178 first = letters.at( fIndex );
188 current += letters.at( index );
189 headers.push_back( current );
195 setHorizontalHeaderLabels( headers );
198 if ( mIncludeHeader )
199 headers << tr(
"Header" );
200 for (
int i = 1; i <= 1000; i++ )
202 headers << QString::number( i );
205 setVerticalHeaderLabels( headers );
208bool QgsTableEditorWidget::collectConsecutiveRowRange(
const QModelIndexList &list,
int &minRow,
int &maxRow )
const
210 QSet< int > includedRows;
211 minRow = std::numeric_limits< int >::max();
213 for (
const QModelIndex &index : list )
215 includedRows.insert( index.row() );
216 minRow = std::min( minRow, index.row() );
217 maxRow = std::max( maxRow, index.row() );
221 for (
int r = minRow + 1; r < maxRow; r++ )
223 if ( !includedRows.contains( r ) )
229bool QgsTableEditorWidget::collectConsecutiveColumnRange(
const QModelIndexList &list,
int &minColumn,
int &maxColumn )
const
231 QSet< int > includedColumns;
232 minColumn = std::numeric_limits< int >::max();
234 for (
const QModelIndex &index : list )
236 includedColumns.insert( index.column() );
237 minColumn = std::min( minColumn, index.column() );
238 maxColumn = std::max( maxColumn, index.column() );
242 for (
int r = minColumn + 1; r < maxColumn; r++ )
244 if ( !includedColumns.contains( r ) )
250QList<int> QgsTableEditorWidget::collectUniqueRows(
const QModelIndexList &list )
const
253 for (
const QModelIndex &index : list )
255 if ( !res.contains( index.row() ) )
258 std::sort( res.begin(), res.end() );
262QList<int> QgsTableEditorWidget::collectUniqueColumns(
const QModelIndexList &list )
const
265 for (
const QModelIndex &index : list )
267 if ( !res.contains( index.column() ) )
268 res << index.column();
270 std::sort( res.begin(), res.end() );
276 switch ( event->key() )
282 QTableWidget::keyPressEvent( event );
283 setCurrentCell( currentRow() + 1, currentColumn() );
294 QTableWidget::keyPressEvent( event );
298 d->setWeakEditorMode(
true );
305 qDeleteAll( mNumericFormats );
306 mNumericFormats.clear();
309 int rowNumber = mIncludeHeader ? 1 : 0;
311 setRowCount( contents.size() + rowNumber );
316 setColumnCount( row.size() );
324 item->setData( CellContent, col.content() );
325 item->setData( Qt::BackgroundRole, col.backgroundColor().isValid() ? col.backgroundColor() : QColor( 255, 255, 255 ) );
326 item->setData( PresetBackgroundColorRole, col.backgroundColor().isValid() ? col.backgroundColor() : QVariant() );
327 item->setData( Qt::ForegroundRole, col.textFormat().isValid() ? col.textFormat().color() : QVariant() );
328 item->setData( TextFormat, QVariant::fromValue( col.textFormat() ) );
329 item->setData( HorizontalAlignment,
static_cast< int >( col.horizontalAlignment() ) );
330 item->setData( VerticalAlignment,
static_cast< int >( col.verticalAlignment() ) );
331 item->setData( CellProperty, QVariant::fromValue( col.content().value<
QgsProperty >() ) );
333 if ( col.content().value<
QgsProperty >().isActive() )
334 item->setFlags( item->flags() & ( ~Qt::ItemIsEditable ) );
336 if (
auto *lNumericFormat = col.numericFormat() )
338 mNumericFormats.insert( item, lNumericFormat->clone() );
339 item->setData( Qt::DisplayRole, mNumericFormats.value( item )->formatDouble( col.content().toDouble(), numericContext ) );
341 setItem( rowNumber, colNumber, item );
352 resizeColumnsToContents();
353 resizeRowsToContents();
362 items.reserve( rowCount() );
364 for (
int r = mIncludeHeader ? 1 : 0; r < rowCount(); r++ )
367 row.reserve( columnCount() );
368 for (
int c = 0;
c < columnCount();
c++ )
371 if ( QTableWidgetItem *i = item( r,
c ) )
373 cell.
setContent( i->data( CellProperty ).value<
QgsProperty >().isActive() ? i->data( CellProperty ) : i->data( CellContent ) );
377 cell.
setVerticalAlignment(
static_cast< Qt::Alignment
>( i->data( VerticalAlignment ).toInt() ) );
379 if ( mNumericFormats.value( i ) )
384 row.push_back( cell );
386 items.push_back( row );
394 bool changed =
false;
396 std::unique_ptr< QgsNumericFormat > newFormat( format );
397 const QModelIndexList selection = selectedIndexes();
399 for (
const QModelIndex &index : selection )
401 if ( index.row() == 0 && mIncludeHeader )
404 QTableWidgetItem *i = item( index.row(), index.column() );
407 i =
new QTableWidgetItem();
408 setItem( index.row(), index.column(), i );
410 if ( !mNumericFormats.value( i ) && newFormat )
413 mNumericFormats.insert( i, newFormat->clone() );
415 else if ( mNumericFormats.value( i ) && !newFormat )
418 delete mNumericFormats.value( i );
419 mNumericFormats.remove( i );
421 else if ( newFormat && *newFormat != *mNumericFormats.value( i ) )
424 delete mNumericFormats.value( i );
425 mNumericFormats.insert( i, newFormat->clone() );
427 i->setData( Qt::DisplayRole, newFormat ? mNumericFormats.value( i )->formatDouble( i->data( CellContent ).toDouble(), numericContext ) : i->data( CellContent ) );
430 if ( changed && !mBlockSignals )
438 const QModelIndexList selection = selectedIndexes();
439 for (
const QModelIndex &index : selection )
441 if ( QTableWidgetItem *i = item( index.row(), index.column() ) )
445 f = mNumericFormats.value( i );
448 else if ( ( !f && !mNumericFormats.value( i ) )
449 || ( f && mNumericFormats.value( i ) && *f == *mNumericFormats.value( i ) ) )
468 const QModelIndexList selection = selectedIndexes();
469 for (
const QModelIndex &index : selection )
471 if ( QTableWidgetItem *i = item( index.row(), index.column() ) )
475 f = mNumericFormats.value( i );
478 else if ( ( !f && !mNumericFormats.value( i ) )
479 || ( f && mNumericFormats.value( i ) && *f == *mNumericFormats.value( i ) ) )
504 const QModelIndexList selection = selectedIndexes();
505 for (
const QModelIndex &index : selection )
507 QColor indexColor = model()->data( index, PresetBackgroundColorRole ).isValid() ? model()->data( index, PresetBackgroundColorRole ).value< QColor >() : QColor();
513 else if ( indexColor ==
c )
525 Qt::Alignment alignment = Qt::AlignLeft;
527 const QModelIndexList selection = selectedIndexes();
528 for (
const QModelIndex &index : selection )
530 Qt::Alignment cellAlign =
static_cast< Qt::Alignment
>( model()->data( index, HorizontalAlignment ).toInt() );
533 alignment = cellAlign;
536 else if ( cellAlign == alignment )
540 return Qt::AlignLeft | Qt::AlignTop;
548 Qt::Alignment alignment = Qt::AlignVCenter;
550 const QModelIndexList selection = selectedIndexes();
551 for (
const QModelIndex &index : selection )
553 Qt::Alignment cellAlign =
static_cast< Qt::Alignment
>( model()->data( index, VerticalAlignment ).toInt() );
556 alignment = cellAlign;
559 else if ( cellAlign == alignment )
563 return Qt::AlignLeft | Qt::AlignTop;
573 const QModelIndexList selection = selectedIndexes();
574 for (
const QModelIndex &index : selection )
579 property = cellProperty;
582 else if ( cellProperty == property )
596 const QModelIndexList selection = selectedIndexes();
597 for (
const QModelIndex &index : selection )
599 if ( !model()->data( index, TextFormat ).isValid() )
608 else if ( cellFormat == format )
620 const QModelIndexList selection = selectedIndexes();
621 for (
const QModelIndex &index : selection )
626 else if ( thisHeight != height )
639 const QModelIndexList selection = selectedIndexes();
640 for (
const QModelIndex &index : selection )
645 else if ( thisWidth != width )
657 for (
int col = 0; col < columnCount(); ++col )
659 double thisHeight = model()->data( model()->index( row + ( mIncludeHeader ? 1 : 0 ), col ), RowHeight ).toDouble();
660 height = std::max( thisHeight, height );
668 for (
int row = 0; row < rowCount(); ++row )
670 double thisWidth = model()->data( model()->index( row, column ), ColumnWidth ).toDouble();
671 width = std::max( thisWidth, width );
678 if ( row == 0 && mIncludeHeader )
681 bool changed =
false;
684 for (
int col = 0; col < columnCount(); ++col )
686 if ( QTableWidgetItem *i = item( row + ( mIncludeHeader ? 1 : 0 ), col ) )
688 if ( i->data( RowHeight ).toDouble() != height )
690 i->setData( RowHeight, height );
696 QTableWidgetItem *newItem =
new QTableWidgetItem();
697 newItem->setData( RowHeight, height );
698 setItem( row + ( mIncludeHeader ? 1 : 0 ), col, newItem );
704 if ( changed && !mBlockSignals )
710 bool changed =
false;
712 for (
int row = 0; row < rowCount(); ++row )
714 if ( QTableWidgetItem *i = item( row, col ) )
716 if ( i->data( ColumnWidth ).toDouble() != width )
718 i->setData( ColumnWidth, width );
724 QTableWidgetItem *newItem =
new QTableWidgetItem();
725 newItem->setData( ColumnWidth, width );
726 setItem( row, col, newItem );
731 if ( changed && !mBlockSignals )
737 return collectUniqueRows( selectedIndexes() );
742 return collectUniqueColumns( selectedIndexes() );
747 if ( !mIncludeHeader )
748 return QVariantList();
751 res.reserve( columnCount() );
752 for (
int col = 0; col < columnCount(); ++col )
754 if ( QTableWidgetItem *i = item( 0, col ) )
756 res << i->data( CellContent );
768 if ( !mIncludeHeader )
771 return collectUniqueRows( selectedIndexes() ).contains( 0 );
776 if ( rowCount() == 0 )
784 if ( !collectConsecutiveRowRange( selectedIndexes(), minRow, maxRow ) )
787 const int rowsToInsert = maxRow - minRow + 1;
788 for (
int i = 0; i < rowsToInsert; ++i )
789 insertRow( maxRow + 1 );
792 if ( !mBlockSignals )
798 if ( rowCount() == 0 )
806 if ( !collectConsecutiveRowRange( selectedIndexes(), minRow, maxRow ) )
809 const int rowsToInsert = maxRow - minRow + 1;
810 for (
int i = 0; i < rowsToInsert; ++i )
814 if ( !mBlockSignals )
820 if ( columnCount() == 0 )
828 if ( !collectConsecutiveColumnRange( selectedIndexes(), minColumn, maxColumn ) )
831 const int columnsToInsert = maxColumn - minColumn + 1;
832 for (
int i = 0; i < columnsToInsert; ++i )
833 insertColumn( minColumn );
836 if ( !mBlockSignals )
842 if ( columnCount() == 0 )
850 if ( !collectConsecutiveColumnRange( selectedIndexes(), minColumn, maxColumn ) )
853 const int columnsToInsert = maxColumn - minColumn + 1;
854 for (
int i = 0; i < columnsToInsert; ++i )
855 insertColumn( maxColumn + 1 );
858 if ( !mBlockSignals )
868 bool changed =
false;
869 for (
int i = rows.size() - 1; i >= 0 && rowCount() > 1; i-- )
871 removeRow( rows.at( i ) );
875 if ( changed && !mBlockSignals )
882 if ( columns.empty() )
885 bool changed =
false;
886 for (
int i = columns.size() - 1; i >= 0 && columnCount() > 1; i-- )
888 removeColumn( columns.at( i ) );
892 if ( !mBlockSignals && changed )
898 const QModelIndexList s = selectedIndexes();
899 for (
const QModelIndex &index : s )
901 selectionModel()->select( index, QItemSelectionModel::Rows | QItemSelectionModel::Select );
907 const QModelIndexList s = selectedIndexes();
908 for (
const QModelIndex &index : s )
910 selectionModel()->select( index, QItemSelectionModel::Columns | QItemSelectionModel::Select );
916 const QModelIndexList selection = selectedIndexes();
917 bool changed =
false;
919 for (
const QModelIndex &index : selection )
921 if ( QTableWidgetItem *i = item( index.row(), index.column() ) )
923 i->setText( QString() );
924 i->setData( CellContent, QVariant() );
929 if ( changed && !mBlockSignals )
935 const QModelIndexList selection = selectedIndexes();
936 bool changed =
false;
938 for (
const QModelIndex &index : selection )
940 if ( index.row() == 0 && mIncludeHeader )
943 if ( QTableWidgetItem *i = item( index.row(), index.column() ) )
945 if ( i->data( Qt::ForegroundRole ).value< QColor >() != color )
947 i->setData( Qt::ForegroundRole, color.isValid() ? color : QVariant() );
950 i->setData( TextFormat, QVariant::fromValue( f ) );
956 QTableWidgetItem *newItem =
new QTableWidgetItem();
957 newItem->setData( Qt::ForegroundRole, color.isValid() ? color : QVariant() );
960 newItem->setData( TextFormat, QVariant::fromValue( f ) );
961 setItem( index.row(), index.column(), newItem );
966 if ( changed && !mBlockSignals )
972 const QModelIndexList selection = selectedIndexes();
973 bool changed =
false;
975 for (
const QModelIndex &index : selection )
977 if ( index.row() == 0 && mIncludeHeader )
980 if ( QTableWidgetItem *i = item( index.row(), index.column() ) )
982 if ( i->data( PresetBackgroundColorRole ).value< QColor >() != color )
984 i->setData( Qt::BackgroundRole, color.isValid() ? color : QVariant() );
985 i->setData( PresetBackgroundColorRole, color.isValid() ? color : QVariant() );
991 QTableWidgetItem *newItem =
new QTableWidgetItem();
992 newItem->setData( Qt::BackgroundRole, color.isValid() ? color : QVariant() );
993 newItem->setData( PresetBackgroundColorRole, color.isValid() ? color : QVariant() );
994 setItem( index.row(), index.column(), newItem );
999 if ( changed && !mBlockSignals )
1005 const QModelIndexList selection = selectedIndexes();
1006 bool changed =
false;
1008 for (
const QModelIndex &index : selection )
1010 if ( index.row() == 0 && mIncludeHeader )
1013 if ( QTableWidgetItem *i = item( index.row(), index.column() ) )
1015 if (
static_cast< Qt::Alignment
>( i->data( HorizontalAlignment ).toInt() ) != alignment )
1017 i->setData( HorizontalAlignment,
static_cast< int >( alignment ) );
1023 QTableWidgetItem *newItem =
new QTableWidgetItem();
1024 newItem->setData( HorizontalAlignment,
static_cast< int >( alignment ) );
1025 setItem( index.row(), index.column(), newItem );
1030 if ( changed && !mBlockSignals )
1036 const QModelIndexList selection = selectedIndexes();
1037 bool changed =
false;
1039 for (
const QModelIndex &index : selection )
1041 if ( index.row() == 0 && mIncludeHeader )
1044 if ( QTableWidgetItem *i = item( index.row(), index.column() ) )
1046 if (
static_cast< Qt::Alignment
>( i->data( HorizontalAlignment ).toInt() ) != alignment )
1048 i->setData( VerticalAlignment,
static_cast< int >( alignment ) );
1054 QTableWidgetItem *newItem =
new QTableWidgetItem();
1055 newItem->setData( VerticalAlignment,
static_cast< int >( alignment ) );
1056 setItem( index.row(), index.column(), newItem );
1061 if ( changed && !mBlockSignals )
1067 const QModelIndexList selection = selectedIndexes();
1068 bool changed =
false;
1070 for (
const QModelIndex &index : selection )
1072 if ( index.row() == 0 && mIncludeHeader )
1075 if ( QTableWidgetItem *i = item( index.row(), index.column() ) )
1077 if ( i->data( CellProperty ).value<
QgsProperty >() != property )
1081 i->setData( CellProperty, QVariant::fromValue( property ) );
1083 i->setFlags( i->flags() & ( ~Qt::ItemIsEditable ) );
1087 i->setData( CellProperty, QVariant() );
1088 i->setText( QString() );
1089 i->setFlags( i->flags() | Qt::ItemIsEditable );
1096 QTableWidgetItem *newItem =
new QTableWidgetItem( property.
asExpression() );
1099 newItem->setData( CellProperty, QVariant::fromValue( property ) );
1100 newItem->setFlags( newItem->flags() & ( ~Qt::ItemIsEditable ) );
1104 newItem->setData( CellProperty, QVariant() );
1105 newItem->setFlags( newItem->flags() | Qt::ItemIsEditable );
1107 setItem( index.row(), index.column(), newItem );
1112 if ( changed && !mBlockSignals )
1118 const QModelIndexList selection = selectedIndexes();
1119 bool changed =
false;
1121 for (
const QModelIndex &index : selection )
1123 if ( index.row() == 0 && mIncludeHeader )
1126 if ( QTableWidgetItem *i = item( index.row(), index.column() ) )
1128 i->setData( TextFormat, QVariant::fromValue( format ) );
1129 i->setData( Qt::ForegroundRole, format.
color() );
1134 QTableWidgetItem *newItem =
new QTableWidgetItem();
1135 newItem->setData( TextFormat, QVariant::fromValue( format ) );
1136 newItem->setData( Qt::ForegroundRole, format.
color() );
1137 setItem( index.row(), index.column(), newItem );
1142 if ( changed && !mBlockSignals )
1148 bool changed =
false;
1151 for (
int row : rows )
1153 if ( row == 0 && mIncludeHeader )
1156 for (
int col = 0; col < columnCount(); ++col )
1158 if ( QTableWidgetItem *i = item( row, col ) )
1160 if ( i->data( RowHeight ).toDouble() != height )
1162 i->setData( RowHeight, height );
1168 QTableWidgetItem *newItem =
new QTableWidgetItem();
1169 newItem->setData( RowHeight, height );
1170 setItem( row, col, newItem );
1176 if ( changed && !mBlockSignals )
1182 bool changed =
false;
1185 for (
int col : cols )
1187 for (
int row = 0; row < rowCount(); ++row )
1189 if ( QTableWidgetItem *i = item( row, col ) )
1191 if ( i->data( ColumnWidth ).toDouble() != width )
1193 i->setData( ColumnWidth, width );
1199 QTableWidgetItem *newItem =
new QTableWidgetItem();
1200 newItem->setData( ColumnWidth, width );
1201 setItem( row, col, newItem );
1207 if ( changed && !mBlockSignals )
1213 if ( included == mIncludeHeader )
1216 mIncludeHeader = included;
1218 if ( mIncludeHeader )
1227 if ( !mIncludeHeader )
1232 for (
int col = 0; col < columnCount(); ++col )
1234 if ( QTableWidgetItem *i = item( 0, col ) )
1236 i->setText( headers.value( col ).toString() );
1237 i->setData( CellContent, headers.value( col ) );
1241 QTableWidgetItem *item =
new QTableWidgetItem( headers.value( col ).toString() );
1242 item->setData( CellContent, headers.value( col ) );
1243 setItem( 0, col, item );
1251QgsTableEditorTextEdit::QgsTableEditorTextEdit( QWidget *parent )
1252 : QPlainTextEdit( parent )
1255 document()->setDocumentMargin( document()->documentMargin() / 2 );
1257 connect(
this, &QPlainTextEdit::textChanged,
this, &QgsTableEditorTextEdit::resizeToContents );
1258 updateMinimumSize();
1261void QgsTableEditorTextEdit::keyPressEvent( QKeyEvent *event )
1263 switch ( event->key() )
1266 case Qt::Key_Return:
1268 if ( event->modifiers() & Qt::ControlModifier )
1271 insertPlainText( QString(
'\n' ) );
1287 if ( mWeakEditorMode )
1294 QPlainTextEdit::keyPressEvent( event );
1301 if ( event->modifiers() & Qt::ControlModifier )
1305 insertPlainText( QString(
'\t' ) );
1316 QPlainTextEdit::keyPressEvent( event );
1320void QgsTableEditorTextEdit::updateMinimumSize()
1322 const double tm = document()->documentMargin();
1323 const QMargins cm = contentsMargins();
1324 const int width = tm * 2 + cm.left() + cm.right() + 30;
1325 const int height = tm * 2 + cm.top() + cm.bottom() + 4;
1326 QStyleOptionFrame opt;
1327 initStyleOption( &opt );
1328 const QSize sizeFromContent = style()->sizeFromContents( QStyle::CT_LineEdit, &opt, QSize( width, height ),
this );
1329 setMinimumWidth( sizeFromContent.width() );
1330 setMinimumHeight( sizeFromContent.height() );
1333void QgsTableEditorTextEdit::setWeakEditorMode(
bool weakEditorMode )
1335 mWeakEditorMode = weakEditorMode;
1338void QgsTableEditorTextEdit::resizeToContents()
1340 int oldWidth = width();
1341 int oldHeight = height();
1342 if ( mOriginalWidth == -1 )
1343 mOriginalWidth = oldWidth;
1344 if ( mOriginalHeight == -1 )
1345 mOriginalHeight = oldHeight;
1347 if ( QWidget *parent = parentWidget() )
1349 QPoint position = pos();
1350 QFontMetrics fm( font() );
1352 const QStringList lines = toPlainText().split(
'\n' );
1353 int maxTextLineWidth = 0;
1354 int totalTextHeight = 0;
1355 for (
const QString &line : lines )
1357 const QRect bounds = fontMetrics().boundingRect( line );
1358 maxTextLineWidth = std::max( maxTextLineWidth, bounds.width() );
1359 totalTextHeight += fm.height();
1362 int hintWidth = minimumWidth() + maxTextLineWidth;
1363 int hintHeight = minimumHeight() + totalTextHeight;
1364 int parentWidth = parent->width();
1365 int maxWidth = isRightToLeft() ? position.x() + oldWidth : parentWidth - position.x();
1366 int maxHeight = parent->height() - position.y();
1367 int newWidth = std::clamp( hintWidth, mOriginalWidth, maxWidth );
1368 int newHeight = std::clamp( hintHeight, mOriginalHeight, maxHeight );
1370 if ( mWidgetOwnsGeometry )
1372 setMaximumWidth( newWidth );
1373 setMaximumHeight( newHeight );
1375 if ( isRightToLeft() )
1376 move( position.x() - newWidth + oldWidth, position.y() );
1377 resize( newWidth, newHeight );
1381void QgsTableEditorTextEdit::changeEvent( QEvent *e )
1383 switch ( e->type() )
1385 case QEvent::FontChange:
1386 case QEvent::StyleChange:
1387 case QEvent::ContentsRectChange:
1388 updateMinimumSize();
1393 QPlainTextEdit::changeEvent( e );
1396QgsTableEditorDelegate::QgsTableEditorDelegate( QObject *parent )
1397 : QStyledItemDelegate( parent )
1402void QgsTableEditorDelegate::setWeakEditorMode(
bool weakEditorMode )
1404 mWeakEditorMode = weakEditorMode;
1407QWidget *QgsTableEditorDelegate::createEditor( QWidget *parent,
const QStyleOptionViewItem &,
const QModelIndex & )
const
1409 QgsTableEditorTextEdit *w =
new QgsTableEditorTextEdit( parent );
1410 w->setWeakEditorMode( mWeakEditorMode );
1412 if ( !w->style()->styleHint( QStyle::SH_ItemView_DrawDelegateFrame, 0, w ) )
1413 w->setFrameShape( QFrame::NoFrame );
1414 if ( !w->style()->styleHint( QStyle::SH_ItemView_ShowDecorationSelected, 0, w ) )
1415 w->setWidgetOwnsGeometry(
true );
1420void QgsTableEditorDelegate::setEditorData( QWidget *editor,
const QModelIndex &index )
const
1422 QVariant value = index.model()->data( index, QgsTableEditorWidget::CellContent );
1423 if ( QgsTableEditorTextEdit *lineEdit = qobject_cast<QgsTableEditorTextEdit * >( editor ) )
1425 if ( index != mLastIndex || lineEdit->toPlainText() != value.toString() )
1427 lineEdit->setPlainText( value.toString() );
1428 lineEdit->selectAll();
1434void QgsTableEditorDelegate::setModelData( QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index )
const
1436 if ( QgsTableEditorTextEdit *lineEdit = qobject_cast<QgsTableEditorTextEdit * >( editor ) )
1438 const QString text = lineEdit->toPlainText();
1439 if ( text != model->data( index, QgsTableEditorWidget::CellContent ).toString() && !model->data( index, QgsTableEditorWidget::CellProperty ).value<
QgsProperty >().
isActive() )
1441 model->setData( index, text, QgsTableEditorWidget::CellContent );
1442 model->setData( index, text, Qt::DisplayRole );
1443 emit updateNumericFormatForIndex( index );
A context for numeric formats.
A store for object properties.
QString asExpression() const
Returns an expression string representing the state of the property, or an empty string if the proper...
QVariant value(const QgsExpressionContext &context, const QVariant &defaultValue=QVariant(), bool *ok=nullptr) const
Calculates the current value of the property, including any transforms which are set for the property...
bool isActive() const
Returns whether the property is currently active.
Encapsulates the contents and formatting of a single table cell.
void setHorizontalAlignment(Qt::Alignment alignment)
Sets the horizontal alignment for text in the cell.
void setVerticalAlignment(Qt::Alignment alignment)
Sets the vertical alignment for text in the cell.
void setBackgroundColor(const QColor &color)
Sets the cell's background color.
void setTextFormat(const QgsTextFormat &format)
Sets the cell's text format.
void setContent(const QVariant &content)
Sets the cell's content.
void setNumericFormat(QgsNumericFormat *format)
Sets the numeric format used for numbers in the cell, or nullptr if no specific format is set.
Container for all settings relating to text rendering.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
bool isValid() const
Returns true if the format is valid.
QColor color() const
Returns the color that text will be rendered in.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QVector< QgsTableRow > QgsTableContents
A set of table rows.
QVector< QgsTableCell > QgsTableRow
A row of table cells.