Skip to content

Commit

Permalink
Allow editing of row/column width/height in manual tables
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jan 14, 2020
1 parent 781712f commit 62efbeb
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 15 deletions.
46 changes: 46 additions & 0 deletions python/core/auto_generated/layout/qgslayoutitemmanualtable.sip.in
Expand Up @@ -55,6 +55,50 @@ Sets the ``contents`` of the table.
Returns the contents of the table.

.. seealso:: :py:func:`contents`
%End

QList< double > rowHeights() const;
%Docstring
Returns the list of row heights (in millimeters) to use when rendering the table.

A height of 0 indicates that the row height should be automatically calculated.

.. seealso:: :py:func:`setRowHeights`

.. seealso:: :py:func:`columnWidths`
%End

void setRowHeights( const QList< double > &heights );
%Docstring
Sets the list of row ``heights`` (in millimeters) to use when rendering the table.

A height of 0 indicates that the row height should be automatically calculated.

.. seealso:: :py:func:`rowHeights`

.. seealso:: :py:func:`setColumnWidths`
%End

QList< double > columnWidths() const;
%Docstring
Returns the list of column widths (in millimeters) to use when rendering the table.

A width of 0 indicates that the column width should be automatically calculated.

.. seealso:: :py:func:`setColumnWidths`

.. seealso:: :py:func:`rowHeights`
%End

void setColumnWidths( const QList< double > &widths );
%Docstring
Sets the list of column ``widths`` (in millimeters) to use when rendering the table.

A width of 0 indicates that the column width should be automatically calculated.

.. seealso:: :py:func:`columnWidths`

.. seealso:: :py:func:`setColumnWidths`
%End

protected:
Expand All @@ -63,6 +107,8 @@ Returns the contents of the table.

virtual bool readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context );

virtual bool calculateMaxRowHeights();


};

Expand Down
37 changes: 37 additions & 0 deletions src/app/layout/qgslayoutmanualtablewidget.cpp
Expand Up @@ -166,12 +166,49 @@ void QgsLayoutManualTableWidget::setTableContents()
connect( this, &QWidget::destroyed, mEditorDialog, &QMainWindow::close );

mEditorDialog->setTableContents( mTable->tableContents() );
int row = 0;
const QList< double > rowHeights = mTable->rowHeights();
for ( double height : rowHeights )
{
mEditorDialog->setTableRowHeight( row, height );
row++;
}
int col = 0;
const QList< double > columnWidths = mTable->columnWidths();
for ( double width : columnWidths )
{
mEditorDialog->setTableColumnWidth( col, width );
col++;
}

connect( mEditorDialog, &QgsTableEditorDialog::tableChanged, this, [ = ]
{
if ( mTable )
{
mTable->beginCommand( tr( "Change Table Contents" ) );
mTable->setTableContents( mEditorDialog->tableContents() );

const int rowCount = mTable->tableContents().size();
QList< double > rowHeights;
rowHeights.reserve( rowCount );
for ( int row = 0; row < rowCount; ++row )
{
rowHeights << mEditorDialog->tableRowHeight( row );
}
mTable->setRowHeights( rowHeights );

if ( !mTable->tableContents().empty() )
{
const int columnCount = mTable->tableContents().at( 0 ).size();
QList< double > columnWidths;
columnWidths.reserve( columnCount );
for ( int col = 0; col < columnCount; ++col )
{
columnWidths << mEditorDialog->tableColumnWidth( col );
}
mTable->setColumnWidths( columnWidths );
}

mTable->endCommand();
}
} );
Expand Down
107 changes: 93 additions & 14 deletions src/core/layout/qgslayoutitemmanualtable.cpp
Expand Up @@ -107,20 +107,7 @@ void QgsLayoutItemManualTable::setTableContents( const QgsTableContents &content
{
mContents = contents;

// refresh columns
QgsLayoutTableColumns columns;
if ( !mContents.empty() )
{
const QgsTableRow &firstRow = mContents[ 0 ];
columns.reserve( firstRow.size() );
for ( const QgsTableCell &cell : firstRow )
{
( void )cell;
columns << new QgsLayoutTableColumn( QString() );
}
}
setColumns( columns );

refreshColumns();
refreshAttributes();
}

Expand All @@ -129,6 +116,21 @@ QgsTableContents QgsLayoutItemManualTable::tableContents() const
return mContents;
}

void QgsLayoutItemManualTable::setRowHeights( const QList<double> &heights )
{
mRowHeights = heights;

refreshAttributes();
}

void QgsLayoutItemManualTable::setColumnWidths( const QList<double> &widths )
{
mColumnWidths = widths;

refreshColumns();
refreshAttributes();
}

bool QgsLayoutItemManualTable::writePropertiesToElement( QDomElement &tableElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
{
if ( !QgsLayoutTable::writePropertiesToElement( tableElem, doc, context ) )
Expand All @@ -149,6 +151,24 @@ bool QgsLayoutItemManualTable::writePropertiesToElement( QDomElement &tableElem,
}
tableElem.appendChild( contentsElement );

QDomElement rowHeightsElement = doc.createElement( QStringLiteral( "rowHeights" ) );
for ( double height : mRowHeights )
{
QDomElement rowElement = doc.createElement( QStringLiteral( "row" ) );
rowElement.setAttribute( QStringLiteral( "height" ), height );
rowHeightsElement.appendChild( rowElement );
}
tableElem.appendChild( rowHeightsElement );

QDomElement columnWidthsElement = doc.createElement( QStringLiteral( "columnWidths" ) );
for ( double width : mColumnWidths )
{
QDomElement columnElement = doc.createElement( QStringLiteral( "column" ) );
columnElement.setAttribute( QStringLiteral( "width" ), width );
columnWidthsElement.appendChild( columnElement );
}
tableElem.appendChild( columnWidthsElement );

return true;
}

Expand All @@ -157,6 +177,24 @@ bool QgsLayoutItemManualTable::readPropertiesFromElement( const QDomElement &ite
if ( !QgsLayoutTable::readPropertiesFromElement( itemElem, doc, context ) )
return false;

mRowHeights.clear();
const QDomNodeList rowHeightNodeList = itemElem.firstChildElement( QStringLiteral( "rowHeights" ) ).childNodes();
mRowHeights.reserve( rowHeightNodeList.size() );
for ( int r = 0; r < rowHeightNodeList.size(); ++r )
{
const QDomElement rowHeightElement = rowHeightNodeList.at( r ).toElement();
mRowHeights.append( rowHeightElement.attribute( QStringLiteral( "height" ) ).toDouble() );
}

mColumnWidths.clear();
const QDomNodeList columnWidthNodeList = itemElem.firstChildElement( QStringLiteral( "columnWidths" ) ).childNodes();
mColumnWidths.reserve( columnWidthNodeList.size() );
for ( int r = 0; r < columnWidthNodeList.size(); ++r )
{
const QDomElement columnWidthElement = columnWidthNodeList.at( r ).toElement();
mColumnWidths.append( columnWidthElement.attribute( QStringLiteral( "width" ) ).toDouble() );
}

QgsTableContents newContents;
const QDomElement contentsElement = itemElem.firstChildElement( QStringLiteral( "contents" ) );
const QDomNodeList rowNodeList = contentsElement.childNodes();
Expand All @@ -181,3 +219,44 @@ bool QgsLayoutItemManualTable::readPropertiesFromElement( const QDomElement &ite
emit changed();
return true;
}

bool QgsLayoutItemManualTable::calculateMaxRowHeights()
{
if ( !QgsLayoutTable::calculateMaxRowHeights() )
return false;

QMap<int, double> newHeights;
for ( auto it = mMaxRowHeightMap.constBegin(); it != mMaxRowHeightMap.constEnd(); ++it )
{
// first row in mMaxRowHeightMap correponds to header, which we ignore here
const int row = it.key() - 1;
const double presetHeight = mRowHeights.value( row );
double thisRowHeight = it.value();
if ( presetHeight > 0 )
thisRowHeight = presetHeight;
newHeights.insert( row + 1, thisRowHeight );
}
mMaxRowHeightMap = newHeights;
return true;
}

void QgsLayoutItemManualTable::refreshColumns()
{
// refresh columns
QgsLayoutTableColumns columns;
if ( !mContents.empty() )
{
int colIndex = 0;
const QgsTableRow &firstRow = mContents[ 0 ];
columns.reserve( firstRow.size() );
for ( const QgsTableCell &cell : firstRow )
{
( void )cell;
std::unique_ptr< QgsLayoutTableColumn > newCol = qgis::make_unique< QgsLayoutTableColumn >( QString() );
newCol->setWidth( mColumnWidths.value( colIndex ) );
columns << newCol.release();
colIndex++;
}
}
setColumns( columns );
}
46 changes: 46 additions & 0 deletions src/core/layout/qgslayoutitemmanualtable.h
Expand Up @@ -66,15 +66,61 @@ class CORE_EXPORT QgsLayoutItemManualTable: public QgsLayoutTable
*/
QgsTableContents tableContents() const;

/**
* Returns the list of row heights (in millimeters) to use when rendering the table.
*
* A height of 0 indicates that the row height should be automatically calculated.
*
* \see setRowHeights()
* \see columnWidths()
*/
QList< double > rowHeights() const { return mRowHeights; }

/**
* Sets the list of row \a heights (in millimeters) to use when rendering the table.
*
* A height of 0 indicates that the row height should be automatically calculated.
*
* \see rowHeights()
* \see setColumnWidths()
*/
void setRowHeights( const QList< double > &heights );

/**
* Returns the list of column widths (in millimeters) to use when rendering the table.
*
* A width of 0 indicates that the column width should be automatically calculated.
*
* \see setColumnWidths()
* \see rowHeights()
*/
QList< double > columnWidths() const { return mColumnWidths; }

/**
* Sets the list of column \a widths (in millimeters) to use when rendering the table.
*
* A width of 0 indicates that the column width should be automatically calculated.
*
* \see columnWidths()
* \see setColumnWidths()
*/
void setColumnWidths( const QList< double > &widths );

protected:

bool writePropertiesToElement( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const override;
bool readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context ) override;
bool calculateMaxRowHeights() override;

private:

QgsTableContents mContents;

QList< double > mRowHeights;
QList< double > mColumnWidths;

void refreshColumns();

};

#endif // QGSLAYOUTITEMMANUALTABLE_H
2 changes: 1 addition & 1 deletion src/gui/tableeditor/qgstableeditorwidget.cpp
Expand Up @@ -492,7 +492,7 @@ double QgsTableEditorWidget::selectionColumnWidth()
const QModelIndexList selection = selectedIndexes();
for ( const QModelIndex &index : selection )
{
double thisWidth = tableColumnWidth( index.row() );
double thisWidth = tableColumnWidth( index.column() );
if ( first )
width = thisWidth;
else if ( thisWidth != width )
Expand Down

0 comments on commit 62efbeb

Please sign in to comment.