Skip to content

Commit

Permalink
PyQGIS syntatic sugar, start on tests for QgsTextDocument
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed May 12, 2020
1 parent 27d40f7 commit 180bbec
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 3 deletions.
35 changes: 35 additions & 0 deletions python/core/auto_generated/textrenderer/qgstextblock.sip.in
Expand Up @@ -54,6 +54,41 @@ Clears the block, removing all its contents.
Returns ``True`` if the block is empty.
%End

int size() const;
%Docstring
Returns the number of fragments in the block.
%End

int __len__() const;
%MethodCode
sipRes = sipCpp->size();
%End

const QgsTextFragment &at( int index ) const /Factory/;
%Docstring
Returns the fragment at the specified ``index``.
%End
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->size() )
{
PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
sipRes = new QgsTextFragment( sipCpp->at( a0 ) );
}
%End

QgsTextFragment &operator[]( int index ) /Factory/;
%MethodCode
SIP_SSIZE_T idx = sipConvertFromSequenceIndex( a0, sipCpp->size() );
if ( idx < 0 )
sipIsErr = 1;
else
sipRes = new QgsTextFragment( sipCpp->operator[]( idx ) );
%End


};

Expand Down
32 changes: 31 additions & 1 deletion python/core/auto_generated/textrenderer/qgstextdocument.sip.in
Expand Up @@ -62,9 +62,39 @@ Appends a ``block`` to the document.
Reserves the specified ``count`` of blocks for optimised block appending.
%End

const QgsTextBlock &at( int index ) const;
const QgsTextBlock &at( int index ) const /Factory/;
%Docstring
Returns the block at the specified ``index``.
%End
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->size() )
{
PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
sipRes = new QgsTextBlock( sipCpp->at( a0 ) );
}
%End

QgsTextBlock &operator[]( int index ) /Factory/;
%MethodCode
SIP_SSIZE_T idx = sipConvertFromSequenceIndex( a0, sipCpp->size() );
if ( idx < 0 )
sipIsErr = 1;
else
sipRes = new QgsTextBlock( sipCpp->operator[]( idx ) );
%End

int size() const;
%Docstring
Returns the number of blocks in the document.
%End

int __len__() const;
%MethodCode
sipRes = sipCpp->size();
%End

QStringList toPlainText() const;
Expand Down
15 changes: 15 additions & 0 deletions src/core/textrenderer/qgstextblock.cpp
Expand Up @@ -41,6 +41,21 @@ bool QgsTextBlock::empty() const
return mFragments.empty();
}

int QgsTextBlock::size() const
{
return mFragments.size();
}

const QgsTextFragment &QgsTextBlock::at( int index ) const
{
return mFragments.at( index );
}

QgsTextFragment &QgsTextBlock::operator[]( int index )
{
return mFragments[ index ];
}

QVector< QgsTextFragment >::const_iterator QgsTextBlock::begin() const
{
return mFragments.begin();
Expand Down
44 changes: 44 additions & 0 deletions src/core/textrenderer/qgstextblock.h
Expand Up @@ -67,6 +67,50 @@ class CORE_EXPORT QgsTextBlock
*/
bool empty() const;

/**
* Returns the number of fragments in the block.
*/
int size() const;

#ifdef SIP_RUN
int __len__() const;
% MethodCode
sipRes = sipCpp->size();
% End
#endif

/**
* Returns the fragment at the specified \a index.
*/
const QgsTextFragment &at( int index ) const SIP_FACTORY;
#ifdef SIP_RUN
% MethodCode
if ( a0 < 0 || a0 >= sipCpp->size() )
{
PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
sipRes = new QgsTextFragment( sipCpp->at( a0 ) );
}
% End
#endif

/**
* Returns the fragment at the specified index.
*/
QgsTextFragment &operator[]( int index ) SIP_FACTORY;
#ifdef SIP_RUN
% MethodCode
SIP_SSIZE_T idx = sipConvertFromSequenceIndex( a0, sipCpp->size() );
if ( idx < 0 )
sipIsErr = 1;
else
sipRes = new QgsTextFragment( sipCpp->operator[]( idx ) );
% End
#endif

#ifndef SIP_RUN
///@cond PRIVATE
QVector< QgsTextFragment >::const_iterator begin() const;
Expand Down
14 changes: 13 additions & 1 deletion src/core/textrenderer/qgstextdocument.cpp
Expand Up @@ -102,6 +102,16 @@ const QgsTextBlock &QgsTextDocument::at( int i ) const
return mBlocks.at( i );
}

QgsTextBlock &QgsTextDocument::operator[]( int i )
{
return mBlocks[i];
}

int QgsTextDocument::size() const
{
return mBlocks.size();
}

QStringList QgsTextDocument::toPlainText() const
{
QStringList textLines;
Expand Down Expand Up @@ -161,7 +171,9 @@ void QgsTextDocument::splitLines( const QString &wrapCharacter, int autoWrapLeng
destinationBlock.append( fragment );
else
{
destinationBlock.append( QgsTextFragment( thisParts.at( 0 ), fragment.characterFormat() ) );
if ( !thisParts.at( 0 ).isEmpty() )
destinationBlock.append( QgsTextFragment( thisParts.at( 0 ), fragment.characterFormat() ) );

append( destinationBlock );
destinationBlock.clear();
for ( int i = 1 ; i < thisParts.size() - 1; ++i )
Expand Down
41 changes: 40 additions & 1 deletion src/core/textrenderer/qgstextdocument.h
Expand Up @@ -79,7 +79,46 @@ class CORE_EXPORT QgsTextDocument
/**
* Returns the block at the specified \a index.
*/
const QgsTextBlock &at( int index ) const;
const QgsTextBlock &at( int index ) const SIP_FACTORY;
#ifdef SIP_RUN
% MethodCode
if ( a0 < 0 || a0 >= sipCpp->size() )
{
PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
sipIsErr = 1;
}
else
{
sipRes = new QgsTextBlock( sipCpp->at( a0 ) );
}
% End
#endif

/**
* Returns the block at the specified index.
*/
QgsTextBlock &operator[]( int index ) SIP_FACTORY;
#ifdef SIP_RUN
% MethodCode
SIP_SSIZE_T idx = sipConvertFromSequenceIndex( a0, sipCpp->size() );
if ( idx < 0 )
sipIsErr = 1;
else
sipRes = new QgsTextBlock( sipCpp->operator[]( idx ) );
% End
#endif

/**
* Returns the number of blocks in the document.
*/
int size() const;

#ifdef SIP_RUN
int __len__() const;
% MethodCode
sipRes = sipCpp->size();
% End
#endif

/**
* Returns a list of plain text lines of text representing the document.
Expand Down
1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Expand Up @@ -255,6 +255,7 @@ ADD_PYTHON_TEST(PyQgsSymbol test_qgssymbol.py)
ADD_PYTHON_TEST(PyQgsSymbolLayerUtils test_qgssymbollayerutils.py)
ADD_PYTHON_TEST(PyQgsTaskManager test_qgstaskmanager.py)
ADD_PYTHON_TEST(PyQgsTemporalUtils test_qgstemporalutils.py)
ADD_PYTHON_TEST(PyQgsTextDocument test_qgstextdocument.py)
ADD_PYTHON_TEST(PyQgsTextFormatWidget test_qgstextformatwidget.py)
ADD_PYTHON_TEST(PyQgsTreeWidgetItem test_qgstreewidgetitem.py)
ADD_PYTHON_TEST(PyQgsUnitTypes test_qgsunittypes.py)
Expand Down
68 changes: 68 additions & 0 deletions tests/src/python/test_qgstextdocument.py
@@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsTextDocument.
Run with: ctest -V -R QgsTextDocument
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Nyall Dawson'
__date__ = '12/05/2020'
__copyright__ = 'Copyright 2020, The QGIS Project'

import qgis # NOQA

from qgis.core import QgsTextDocument
from qgis.testing import start_app, unittest

start_app()


class TestQgsTextDocument(unittest.TestCase):

def testSplitLines(self):
doc = QgsTextDocument.fromHtml(['abc def'])
self.assertEqual(len(doc), 1)
self.assertEqual(len(doc[0]), 1)
self.assertEqual(doc[0][0].text(), 'abc def')
doc.splitLines(' ')
self.assertEqual(len(doc), 2)
self.assertEqual(len(doc[0]), 1)
self.assertEqual(doc[0][0].text(), 'abc')
self.assertEqual(len(doc[1]), 1)
self.assertEqual(doc[1][0].text(), 'def')

doc = QgsTextDocument.fromHtml(['<span style="color: red">R_ED</span> not <div>red</div>'])
self.assertEqual(len(doc), 2)
self.assertEqual(len(doc[0]), 2)
self.assertEqual(doc[0][0].text(), 'R_ED')
self.assertEqual(doc[0][1].text(), ' not ')
self.assertEqual(len(doc[1]), 1)
self.assertEqual(doc[1][0].text(), 'red')
doc.splitLines(' ')
self.assertEqual(len(doc), 4)
self.assertEqual(len(doc[0]), 1)
self.assertEqual(doc[0][0].text(), 'R_ED')
self.assertEqual(len(doc[1]), 1)
self.assertEqual(doc[1][0].text(), 'not')
self.assertEqual(len(doc[2]), 1)
self.assertEqual(doc[2][0].text(), '')
self.assertEqual(len(doc[3]), 1)
self.assertEqual(doc[3][0].text(), 'red')

doc = QgsTextDocument.fromHtml(['<span style="color: red">R_ED</span> not <div>red</div>'])
doc.splitLines('_')
self.assertEqual(len(doc), 3)
self.assertEqual(len(doc[0]), 1)
self.assertEqual(doc[0][0].text(), 'R')
self.assertEqual(len(doc[1]), 2)
self.assertEqual(doc[1][0].text(), 'ED')
self.assertEqual(doc[1][1].text(), ' not ')
self.assertEqual(len(doc[2]), 1)
self.assertEqual(doc[2][0].text(), 'red')


if __name__ == '__main__':
unittest.main()

0 comments on commit 180bbec

Please sign in to comment.