20 #include <QStringList>
22 #include <QHeaderView>
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 );
144 void 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() ) );
155 void 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 );
208 bool 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 ) )
229 bool 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 ) )
250 QList<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() );
262 QList<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 >() ) );
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 );
1251 QgsTableEditorTextEdit::QgsTableEditorTextEdit( QWidget *parent )
1252 : QPlainTextEdit( parent )
1255 document()->setDocumentMargin( document()->documentMargin() / 2 );
1257 connect(
this, &QPlainTextEdit::textChanged,
this, &QgsTableEditorTextEdit::resizeToContents );
1258 updateMinimumSize();
1261 void 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 );
1320 void 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() );
1333 void QgsTableEditorTextEdit::setWeakEditorMode(
bool weakEditorMode )
1335 mWeakEditorMode = weakEditorMode;
1338 void 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 );
1381 void 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 );
1396 QgsTableEditorDelegate::QgsTableEditorDelegate( QObject *parent )
1397 : QStyledItemDelegate( parent )
1402 void QgsTableEditorDelegate::setWeakEditorMode(
bool weakEditorMode )
1404 mWeakEditorMode = weakEditorMode;
1407 QWidget *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 );
1420 void 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();
1434 void 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 );