Merge branch 'master' of github.com:timlinux/Quantum-GIS

This commit is contained in:
Tim Sutton 2012-09-19 22:58:30 +02:00
commit 8f3027b80f
13 changed files with 1597 additions and 1772 deletions

3
debian/changelog vendored
View File

@ -7,9 +7,10 @@ qgis (1.9.0) UNRELEASED; urgency=low
* include cpt-city files
* support DEB_BUILD_OPTIONS' parallel=n
* add python-unittest2 build dependency for maverick and squeeze
* disable PyQgsRectangle test on lucid (depends on unittest2)
* add python-qscintilla2 dependency to python-qgis
-- Jürgen E. Fischer <jef@norbit.de> Mon, 17 Sep 2012 18:08:47 +0200
-- Jürgen E. Fischer <jef@norbit.de> Tue, 18 Sep 2012 22:18:25 +0200
qgis (1.8.0) UNRELEASED; urgency=low

4
debian/rules vendored
View File

@ -27,6 +27,10 @@ TESTMAKE=xvfb-run -a -n 1 -s "-screen 0 1280x1024x24 -dpi 96" $(MAKE)
else
TESTMAKE=$(MAKE)
endif
ifneq (,$(findstring $(DISTRIBUTION),"lucid"))
# excludes tests requiring unittest2 not available on lucid
TESTMAKE += ARGS="-E PyQgsRectangle"
endif
QGIS_MAJOR=$(shell sed -ne 's/SET(CPACK_PACKAGE_VERSION_MAJOR "\([0-9]*\)")/\1/p' CMakeLists.txt)
QGIS_MINOR=$(shell sed -ne 's/SET(CPACK_PACKAGE_VERSION_MINOR "\([0-9]*\)")/\1/p' CMakeLists.txt)

View File

@ -1,36 +1,36 @@
<style>table {font-size:80%;}th {text-align:left; }.bartodo{ background-color:red;width:100px;height:20px;}.bardone{ background-color:green;width:80px;height:20px;font-size:80%;text-align:center;padding-top:4px;height:16px;color:white;}</style><table><tr><th colspan="2" style="width:250px;">Language</th><th>Finished %</th><th>Translators</th></tr>
<tr><td><img src="qrc:/images/flags/de.png"></td><td>German</td><td><div title="finished:8454 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:99px">99.9</div></div></td><td>Jürgen E. Fischer, Stephan Holl, Otto Dassau, Werner Macho</td></tr>
<tr><td><img src="qrc:/images/flags/de.png"></td><td>German</td><td><div title="finished:8466 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:100px">100.0</div></div></td><td>Jürgen E. Fischer, Stephan Holl, Otto Dassau, Werner Macho</td></tr>
<tr><td><img src="qrc:/images/flags/gl_ES.png"></td><td>Galician (Spain)</td><td><div title="finished:8111 unfinished:114 untranslated:195" class="bartodo"><div class="bardone" style="width:96px">96.5</div></div></td><td>Xan Vieiro</td></tr>
<tr><td><img src="qrc:/images/flags/it.png"></td><td>Italian</td><td><div title="finished:7741 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:91px">91.5</div></div></td><td>Paolo Cavallini, Flavio Rigolon, Maurizio Napolitano, Roberto Angeletti, Alessandro Fanna, Michele Beneventi, Marco Braida, Luca Casagrande, Luca Delucchi, Anne Gishla</td></tr>
<tr><td><img src="qrc:/images/flags/ja.png"></td><td>Japanese</td><td><div title="finished:7741 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:91px">91.5</div></div></td><td>BABA Yoshihiko, Yoichi Kayama</td></tr>
<tr><td><img src="qrc:/images/flags/nl.png"></td><td>Dutch</td><td><div title="finished:7741 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:91px">91.5</div></div></td><td>Richard Duivenvoorde, Raymond Nijssen, Carlo van Rijswijk</td></tr>
<tr><td><img src="qrc:/images/flags/pl_PL.png"></td><td>Polish (Poland)</td><td><div title="finished:7741 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:91px">91.5</div></div></td><td>Robert Szczepanek, Milena Nowotarska, Borys Jurgiel, Mateusz Loskot, Tomasz Paul, Andrzej Swiader </td></tr>
<tr><td><img src="qrc:/images/flags/pt_BR.png"></td><td>Portuguese (Brazil)</td><td><div title="finished:7741 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:91px">91.5</div></div></td><td>Arthur Nanni</td></tr>
<tr><td><img src="qrc:/images/flags/ru.png"></td><td>Russian</td><td><div title="finished:7741 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:91px">91.5</div></div></td><td>Artem Popov</td></tr>
<tr><td><img src="qrc:/images/flags/it.png"></td><td>Italian</td><td><div title="finished:7741 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:91px">91.4</div></div></td><td>Paolo Cavallini, Flavio Rigolon, Maurizio Napolitano, Roberto Angeletti, Alessandro Fanna, Michele Beneventi, Marco Braida, Luca Casagrande, Luca Delucchi, Anne Gishla</td></tr>
<tr><td><img src="qrc:/images/flags/ja.png"></td><td>Japanese</td><td><div title="finished:7741 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:91px">91.4</div></div></td><td>BABA Yoshihiko, Yoichi Kayama</td></tr>
<tr><td><img src="qrc:/images/flags/nl.png"></td><td>Dutch</td><td><div title="finished:7741 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:91px">91.4</div></div></td><td>Richard Duivenvoorde, Raymond Nijssen, Carlo van Rijswijk</td></tr>
<tr><td><img src="qrc:/images/flags/pl_PL.png"></td><td>Polish (Poland)</td><td><div title="finished:7741 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:91px">91.4</div></div></td><td>Robert Szczepanek, Milena Nowotarska, Borys Jurgiel, Mateusz Loskot, Tomasz Paul, Andrzej Swiader </td></tr>
<tr><td><img src="qrc:/images/flags/pt_BR.png"></td><td>Portuguese (Brazil)</td><td><div title="finished:7741 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:91px">91.4</div></div></td><td>Arthur Nanni</td></tr>
<tr><td><img src="qrc:/images/flags/ru.png"></td><td>Russian</td><td><div title="finished:7741 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:91px">91.4</div></div></td><td>Artem Popov</td></tr>
<tr><td><img src="qrc:/images/flags/fr.png"></td><td>French</td><td><div title="finished:7736 unfinished:0 untranslated:5" class="bartodo"><div class="bardone" style="width:91px">91.4</div></div></td><td>Eve Rousseau, Marc Monnerat, Lionel Roubeyrie, Jean Roc Morreale, Benjamin Bohard, Jeremy Garniaux, Yves Jacolin, Benjamin Lerre, Stéphane Morel, Marie Silvestre, Tahir Tamba, Xavier M, Mayeul Kauffmann, Mehdi Semchaoui, Robin Cura, Etienne Tourigny, Mathieu Bossaert</td></tr>
<tr><td><img src="qrc:/images/flags/et_EE.png"></td><td>Estonian (Estonia)</td><td><div title="finished:7639 unfinished:159 untranslated:92" class="bartodo"><div class="bardone" style="width:91px">91.2</div></div></td><td>Veiko Viil</td></tr>
<tr><td><img src="qrc:/images/flags/es.png"></td><td>Spanish</td><td><div title="finished:7686 unfinished:1 untranslated:54" class="bartodo"><div class="bardone" style="width:90px">90.8</div></div></td><td>Carlos Dávila, Javier César Aldariz, Gabriela Awad, Edwin Amado, Mayeul Kauffmann</td></tr>
<tr><td><img src="qrc:/images/flags/cs_CZ.png"></td><td>Czech (Czech Republic)</td><td><div title="finished:7666 unfinished:0 untranslated:75" class="bartodo"><div class="bardone" style="width:90px">90.6</div></div></td><td>Martin Landa, Peter Antolik, Martin Dzurov, Jan Helebrant</td></tr>
<tr><td><img src="qrc:/images/flags/hu.png"></td><td>Hungarian</td><td><div title="finished:7576 unfinished:6 untranslated:159" class="bartodo"><div class="bardone" style="width:89px">89.6</div></div></td><td>Zoltan Siki</td></tr>
<tr><td><img src="qrc:/images/flags/hu.png"></td><td>Hungarian</td><td><div title="finished:7576 unfinished:6 untranslated:159" class="bartodo"><div class="bardone" style="width:89px">89.5</div></div></td><td>Zoltan Siki</td></tr>
<tr><td><img src="qrc:/images/flags/ko_KR.png"></td><td>Korean (Korea, Republic of)</td><td><div title="finished:7432 unfinished:149 untranslated:271" class="bartodo"><div class="bardone" style="width:88px">88.7</div></div></td><td>BJ Jang</td></tr>
<tr><td><img src="qrc:/images/flags/sl_SI.png"></td><td>Slovenian (Slovenia)</td><td><div title="finished:7214 unfinished:16 untranslated:511" class="bartodo"><div class="bardone" style="width:85px">85.4</div></div></td><td>Jože Detečnik, Dejan Gregor</td></tr>
<tr><td><img src="qrc:/images/flags/zh_CN.png"></td><td>Chinese (China)</td><td><div title="finished:6676 unfinished:99 untranslated:1211" class="bartodo"><div class="bardone" style="width:79px">79.5</div></div></td><td>Calvin Ngei, Zhang Jun</td></tr>
<tr><td><img src="qrc:/images/flags/sl_SI.png"></td><td>Slovenian (Slovenia)</td><td><div title="finished:7214 unfinished:16 untranslated:511" class="bartodo"><div class="bardone" style="width:85px">85.3</div></div></td><td>Jože Detečnik, Dejan Gregor</td></tr>
<tr><td><img src="qrc:/images/flags/zh_CN.png"></td><td>Chinese (China)</td><td><div title="finished:6676 unfinished:99 untranslated:1211" class="bartodo"><div class="bardone" style="width:79px">79.4</div></div></td><td>Calvin Ngei, Zhang Jun</td></tr>
<tr><td><img src="qrc:/images/flags/lv.png"></td><td>Latvian</td><td><div title="finished:6053 unfinished:437 untranslated:1496" class="bartodo"><div class="bardone" style="width:74px">74.1</div></div></td><td>Maris Nartiss, Pēteris Brūns</td></tr>
<tr><td><img src="qrc:/images/flags/id.png"></td><td>Indonesian</td><td><div title="finished:5027 unfinished:588 untranslated:2126" class="bartodo"><div class="bardone" style="width:62px">62.9</div></div></td><td>Januar V. Simarmata, I Made Anombawa</td></tr>
<tr><td><img src="qrc:/images/flags/hr_HR.png"></td><td>Croatian (Croatia)</td><td><div title="finished:5157 unfinished:172 untranslated:2412" class="bartodo"><div class="bardone" style="width:61px">62.0</div></div></td><td>Zoran Jankovic</td></tr>
<tr><td><img src="qrc:/images/flags/hr_HR.png"></td><td>Croatian (Croatia)</td><td><div title="finished:5157 unfinished:172 untranslated:2412" class="bartodo"><div class="bardone" style="width:61px">61.9</div></div></td><td>Zoran Jankovic</td></tr>
<tr><td><img src="qrc:/images/flags/sr_CS-Latn.png"></td><td>Serbian ()</td><td><div title="finished:4776 unfinished:844 untranslated:2121" class="bartodo"><div class="bardone" style="width:61px">61.4</div></div></td><td></td></tr>
<tr><td><img src="qrc:/images/flags/th.png"></td><td>Thai</td><td><div title="finished:4321 unfinished:800 untranslated:2620" class="bartodo"><div class="bardone" style="width:55px">55.8</div></div></td><td>Man Chao</td></tr>
<tr><td><img src="qrc:/images/flags/pt_PT.png"></td><td>Portuguese (Portugal)</td><td><div title="finished:2634 unfinished:3944 untranslated:1640" class="bartodo"><div class="bardone" style="width:54px">54.4</div></div></td><td>Giovanni Manghi, Joana Simoes, Duarte Carreira, Alexandre Neto, Pedro Pereira, Pedro Palheiro</td></tr>
<tr><td><img src="qrc:/images/flags/uk.png"></td><td>Ukrainian</td><td><div title="finished:3710 unfinished:1008 untranslated:3023" class="bartodo"><div class="bardone" style="width:49px">49.8</div></div></td><td>Сергей Якунин</td></tr>
<tr><td><img src="qrc:/images/flags/tr.png"></td><td>Turkish</td><td><div title="finished:3875 unfinished:613 untranslated:3253" class="bartodo"><div class="bardone" style="width:49px">49.4</div></div></td><td>Osman Yilmaz</td></tr>
<tr><td><img src="qrc:/images/flags/zh_TW.png"></td><td>Chinese (Taiwan, Province of China)</td><td><div title="finished:2545 unfinished:2466 untranslated:2903" class="bartodo"><div class="bardone" style="width:44px">44.7</div></div></td><td>Nung-yao Lin</td></tr>
<tr><td><img src="qrc:/images/flags/zh_TW.png"></td><td>Chinese (Taiwan, Province of China)</td><td><div title="finished:2545 unfinished:2466 untranslated:2903" class="bartodo"><div class="bardone" style="width:44px">44.6</div></div></td><td>Nung-yao Lin</td></tr>
<tr><td><img src="qrc:/images/flags/vi.png"></td><td>Vietnamese</td><td><div title="finished:2936 unfinished:1309 untranslated:3496" class="bartodo"><div class="bardone" style="width:42px">42.4</div></div></td><td>Bùi Hữu Mạnh</td></tr>
<tr><td><img src="qrc:/images/flags/el_GR.png"></td><td>Greek, Modern (1453-) (Greece)</td><td><div title="finished:3053 unfinished:730 untranslated:3958" class="bartodo"><div class="bardone" style="width:40px">40.4</div></div></td><td>Evripidis Argyropoulos, Mike Pegnigiannis, Nikos Ves</td></tr>
<tr><td><img src="qrc:/images/flags/is.png"></td><td>Icelandic</td><td><div title="finished:2966 unfinished:418 untranslated:4357" class="bartodo"><div class="bardone" style="width:37px">37.5</div></div></td><td>Thordur Ivarsson</td></tr>
<tr><td><img src="qrc:/images/flags/mn.png"></td><td>Mongolian</td><td><div title="finished:2609 unfinished:861 untranslated:4271" class="bartodo"><div class="bardone" style="width:35px">35.9</div></div></td><td>Bayarmaa Enkhtur</td></tr>
<tr><td><img src="qrc:/images/flags/sv.png"></td><td>Swedish</td><td><div title="finished:1934 unfinished:1629 untranslated:4898" class="bartodo"><div class="bardone" style="width:32px">32.5</div></div></td><td>Lars Luthman, Magnus Homann</td></tr>
<tr><td><img src="qrc:/images/flags/fi.png"></td><td>Finnish</td><td><div title="finished:1586 unfinished:1085 untranslated:5070" class="bartodo"><div class="bardone" style="width:25px">25.2</div></div></td><td>Marko Jarvenpaa</td></tr>
<tr><td><img src="qrc:/images/flags/fi.png"></td><td>Finnish</td><td><div title="finished:1586 unfinished:1085 untranslated:5070" class="bartodo"><div class="bardone" style="width:25px">25.1</div></div></td><td>Marko Jarvenpaa</td></tr>
<tr><td><img src="qrc:/images/flags/da_DK.png"></td><td>Danish (Denmark)</td><td><div title="finished:1767 unfinished:708 untranslated:5511" class="bartodo"><div class="bardone" style="width:25px">25.1</div></div></td><td>Preben Lisby</td></tr>
<tr><td><img src="qrc:/images/flags/ka_GE.png"></td><td>Georgian (Georgia)</td><td><div title="finished:1372 unfinished:1296 untranslated:5073" class="bartodo"><div class="bardone" style="width:23px">23.9</div></div></td><td>Shota Murtskhvaladze, George Machitidze</td></tr>
<tr><td><img src="qrc:/images/flags/bg.png"></td><td>Bulgarian</td><td><div title="finished:1075 unfinished:1513 untranslated:5458" class="bartodo"><div class="bardone" style="width:21px">21.6</div></div></td><td>Захари Савов, Jordan Tzvetkov</td></tr>

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,10 @@ public:
/**Removes and deletes all frames from mComposition*/
void deleteFrames();
int nFrames() const;
int nFrames() const /Deprecated/;
/** Return the number of frames associated with this multiframeset.
@note added in 2.0, replaces nFrames
**/
int frameCount() const;
QgsComposerFrame* frame( int i );
};

View File

@ -102,8 +102,6 @@ void QgsMeasureTool::deactivate()
void QgsMeasureTool::restart()
{
mPoints.clear();
// Append point we will move
// mPoints.append( QgsPoint( 0, 0 ) );
mRubberBand->reset( mMeasureArea );
@ -179,6 +177,7 @@ void QgsMeasureTool::canvasReleaseEvent( QMouseEvent * e )
}
else if ( e->button() == Qt::LeftButton )
{
// Append point we will move
addPoint( point );
mDialog->show();
}

View File

@ -660,21 +660,24 @@ void QgsRasterLayerProperties::apply()
*/
//set NoDataValue
bool myDoubleOk = false;
QList<QgsRasterInterface::Range> myNoDataRangeList;
if ( "" != leNoDataValue->text() )
{
QList<QgsRasterInterface::Range> myNoDataRangeList;
bool myDoubleOk = false;
double myNoDataValue = leNoDataValue->text().toDouble( &myDoubleOk );
if ( myDoubleOk )
{
mRasterLayer->setNoDataValue( myNoDataValue );
//mRasterLayer->setNoDataValue( myNoDataValue );
QgsRasterInterface::Range myNoDataRange;
myNoDataRange.min = myNoDataValue;
myNoDataRange.max = myNoDataValue;
myNoDataRangeList << myNoDataRange;
}
mRasterLayer->dataProvider()->setUserNoDataValue( 1, myNoDataRangeList );
}
for ( int bandNo = 1; bandNo <= mRasterLayer->dataProvider()->bandCount(); bandNo++ )
{
mRasterLayer->dataProvider()->setUserNoDataValue( bandNo, myNoDataRangeList );
}
//set renderer from widget

View File

@ -238,7 +238,7 @@ void QgsComposerMultiFrame::deleteFrames()
mResizeMode = bkResizeMode;
}
QgsComposerFrame* QgsComposerMultiFrame::frame( int i )
QgsComposerFrame* QgsComposerMultiFrame::frame( int i ) const
{
if ( i >= mFrameItems.size() )
{

View File

@ -69,8 +69,14 @@ class CORE_EXPORT QgsComposerMultiFrame: public QObject
/**Removes and deletes all frames from mComposition*/
void deleteFrames();
int nFrames() const { return mFrameItems.size(); }
QgsComposerFrame* frame( int i );
/** Deprecated in 2.0 use frameCount rather. **/
Q_DECL_DEPRECATED int nFrames() const { return mFrameItems.size(); }
/** Return the number of frames associated with this multiframeset.
@note added in 2.0, replaces nFrames
**/
int frameCount() const { return mFrameItems.size(); }
QgsComposerFrame* frame( int i ) const;
protected:
QgsComposition* mComposition;

View File

@ -185,8 +185,6 @@ QList<const QgsComposerMap*> QgsComposition::composerMapItems() const
const QgsComposerMap* QgsComposition::getComposerMapById( int id ) const
{
QList<const QgsComposerMap*> resultList;
QList<QGraphicsItem *> itemList = items();
QList<QGraphicsItem *>::iterator itemIt = itemList.begin();
for ( ; itemIt != itemList.end(); ++itemIt )
@ -200,7 +198,47 @@ const QgsComposerMap* QgsComposition::getComposerMapById( int id ) const
}
}
}
return 0;
}
const QgsComposerHtml* QgsComposition::getComposerHtmlByItem( QgsComposerItem *item ) const
{
QList<QGraphicsItem *> itemList = items();
QList<QGraphicsItem *>::iterator itemIt = itemList.begin();
for ( ; itemIt != itemList.end(); ++itemIt )
{
const QgsComposerHtml* composerHtml = dynamic_cast<const QgsComposerHtml *>( *itemIt );
if ( composerHtml )
{
//Now cycle through the items associated with this html composer
//and return the composer if the item matches any of them
for ( int i=0; i<composerHtml->frameCount(); i++ )
{
if ( composerHtml->frame(i)->id() == item->id() )
{
return composerHtml;
}
}
}
}
return 0;
}
const QgsComposerItem* QgsComposition::getComposerItemById( QString theId ) const
{
QList<QGraphicsItem *> itemList = items();
QList<QGraphicsItem *>::iterator itemIt = itemList.begin();
for ( ; itemIt != itemList.end(); ++itemIt )
{
const QgsComposerItem* mypItem = dynamic_cast<const QgsComposerItem *>( *itemIt );
if ( mypItem )
{
if ( mypItem->id() == theId )
{
return mypItem;
}
}
}
return 0;
}
@ -1282,7 +1320,7 @@ void QgsComposition::removeComposerItem( QgsComposerItem* item, bool createComma
//check if there are frames left. If not, remove the multi frame
if ( frameItem && multiFrame )
{
if ( multiFrame->nFrames() < 1 )
if ( multiFrame->frameCount() < 1 )
{
removeMultiFrame( multiFrame );
if ( createCommand )

View File

@ -124,9 +124,25 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
template<class T> void composerItems( QList<T*>& itemList );
/**Returns the composer map with specified id
@return id or 0 pointer if the composer map item does not exist*/
@return QgsComposerMap or 0 pointer if the composer map item does not exist*/
const QgsComposerMap* getComposerMapById( int id ) const;
/*Returns the composer html with specified id (a string as named in the
composer user interface item properties).
@note Added in QGIS 2.0
@param id - A QString representing the id of the item.
@return QgsComposerHtml pointer or 0 pointer if no such item exists.
*/
const QgsComposerHtml* getComposerHtmlByItem( QgsComposerItem *item ) const;
/**Returns a composer item given its text identifier.
@note added in 2.0
@param theId - A QString representing the identifier of the item to
retrieve.
@return QgsComposerItem pointer or 0 pointer if no such item exists.
**/
const QgsComposerItem* getComposerItemById( QString theId ) const;
int printResolution() const {return mPrintResolution;}
void setPrintResolution( int dpi ) {mPrintResolution = dpi;}

View File

@ -14,7 +14,7 @@ qgscompositionchecker.py - check rendering of Qgscomposition against an expected
* *
***************************************************************************/
'''
from PyQt4.QtCore import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
@ -22,17 +22,18 @@ class QgsCompositionChecker:
def testComposition(self, mTestName, mComposition, mExpectedImageFile, page=0 ):
if ( mComposition == None):
return false
myMessage = "Composition not valid"
return False, myMessage
#load expected image
expectedImage = QImage( mExpectedImageFile )
#get width/height, create image and render the composition to it
width = expectedImage.width();
height = expectedImage.height();
outputImage = QImage( QSize( width, height ), QImage.Format_ARGB32 )
mComposition.setPlotStyle( QgsComposition.Print )
outputImage.setDotsPerMeterX( expectedImage.dotsPerMeterX() )
outputImage.setDotsPerMeterY( expectedImage.dotsPerMeterX() )
@ -40,29 +41,47 @@ class QgsCompositionChecker:
p = QPainter( outputImage )
mComposition.renderPage( p, page )
p.end()
renderedFilePath = QDir.tempPath() + QDir.separator() + QFileInfo( mExpectedImageFile ).baseName() + "_rendered_python.png"
outputImage.save( renderedFilePath, "PNG" )
diffFilePath = QDir.tempPath() + QDir.separator() + QFileInfo( mExpectedImageFile ).baseName() + "_diff_python.png"
testResult = self.compareImages( expectedImage, outputImage, diffFilePath )
myDashMessage = "<DartMeasurementFile name=\"Rendered Image " + mTestName + "\"" + " type=\"image/png\">" + renderedFilePath + "</DartMeasurementFile>" + "\n" + "<DartMeasurementFile name=\"Expected Image " + mTestName + "\"" + " type=\"image/png\">" + mExpectedImageFile + "</DartMeasurementFile>" + "\n" + "<DartMeasurementFile name=\"Difference Image " + mTestName + "\"" + " type=\"image/png\">" + diffFilePath + "</DartMeasurementFile>"
myDashMessage = (('<DartMeasurementFile name="Rendered Image '
'%s" type="image/png">'
'%s</DartMeasurementFile>'
'<DartMeasurementFile name="Expected Image '
'%s" type="image/png">'
'%s</DartMeasurementFile>\n'
'<DartMeasurementFile name="Difference Image '
'%s" type="image/png">'
'%s</DartMeasurementFile>') %
(mTestName, renderedFilePath, mTestName,
mExpectedImageFile, mTestName, diffFilePath )
)
qDebug( myDashMessage )
return testResult
if not testResult:
myMessage = ('Expected: %s\nGot: %s\nDifference: %s\n' %
(mExpectedImageFile, renderedFilePath, diffFilePath))
else:
myMessage = 'Control and test images matched.'
return testResult, myMessage
def compareImages( self, imgExpected, imgRendered, differenceImagePath ):
if ( imgExpected.width() != imgRendered.width() or imgExpected.height() != imgRendered.height() ):
return false
if ( imgExpected.width() != imgRendered.width()
or imgExpected.height() != imgRendered.height() ):
return False
imageWidth = imgExpected.width()
imageHeight = imgExpected.height()
mismatchCount = 0
differenceImage = QImage( imageWidth, imageHeight, QImage.Format_ARGB32_Premultiplied )
differenceImage = QImage(
imageWidth, imageHeight, QImage.Format_ARGB32_Premultiplied )
differenceImage.fill( qRgb( 152, 219, 249 ) )
pixel1 = QColor().rgb()
pixel2 = QColor().rgb()
for i in range( imageHeight ):
@ -72,13 +91,12 @@ class QgsCompositionChecker:
if ( pixel1 != pixel2 ):
mismatchCount = mismatchCount + 1
differenceImage.setPixel( j, i, qRgb( 255, 0, 0 ) )
if not differenceImagePath.isEmpty():
differenceImage.save( differenceImagePath, "PNG" )
#allow pixel deviation of 1 percent
pixelCount = imageWidth * imageHeight;
# print "MismatchCount: "+str(mismatchCount)
# print "PixelCount: "+str(pixelCount)
return (float(mismatchCount) / float(pixelCount) ) < 0.01

View File

@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
'''
test_qgscomposerhtml.py
test_qgscomposerhtml.py
--------------------------------------
Date : August 2012
Copyright : (C) 2012 by Dr. Horst Düster / Dr. Marco Hugentobler
Copyright : (C) 2012 by Dr. Horst Düster /
Dr. Marco Hugentobler
Tim Sutton
email : marco@sourcepole.ch
***************************************************************************
* *
@ -13,66 +15,107 @@ test_qgscomposerhtml.py
* (at your option) any later version. *
* *
***************************************************************************/
'''
'''
import unittest
from utilities import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
import os
from utilities import unitTestDataPath, getQgisTestApp
from PyQt4.QtCore import QUrl, QString, qDebug
from qgis.core import (QgsComposition,
QgsComposerHtml,
QgsComposerFrame,
QgsComposerMultiFrame)
from qgscompositionchecker import QgsCompositionChecker
QGISAPP, CANVAS, IFACE, PARENT = getQgisTestApp()
TEST_DATA_DIR = unitTestDataPath()
class TestQgsComposerMap(unittest.TestCase):
def testCase(self):
self.mComposition = QgsComposition( None )
self.mComposition.setPaperSize( 297, 210 ) #A4 landscape
self.table()
self.tableMultiFrame()
def table(self):
TEST_DATA_DIR = unitTestDataPath()
htmlItem = QgsComposerHtml( self.mComposition, False )
htmlFrame = QgsComposerFrame( self.mComposition, htmlItem, 0, 0, 100, 200 )
htmlFrame.setFrameEnabled( True )
htmlItem.addFrame( htmlFrame )
htmlItem.setUrl( QUrl( QString( "file:///%1" ).arg( QString( TEST_DATA_DIR ) + QDir.separator() + "html_table.html" ) ) );
checker = QgsCompositionChecker( )
result = checker.testComposition( "Composer html table", self.mComposition, QString( TEST_DATA_DIR + QDir.separator().toAscii() + "control_images" + QDir.separator().toAscii() + "expected_composerhtml" + QDir.separator().toAscii() + "composerhtml_table.png" ) )
self.mComposition.removeMultiFrame( htmlItem )
del htmlItem
assert result == True
def tableMultiFrame(self):
TEST_DATA_DIR = unitTestDataPath()
htmlItem = QgsComposerHtml( self.mComposition, False )
htmlFrame = QgsComposerFrame( self.mComposition, htmlItem, 10, 10, 100, 50 )
htmlItem.addFrame( htmlFrame )
htmlItem.setResizeMode( QgsComposerMultiFrame.RepeatUntilFinished )
htmlItem.setUrl( QUrl( QString( "file:///%1" ).arg( QString( TEST_DATA_DIR ) + QDir.separator() + "html_table.html" ) ) )
htmlItem.frame( 0 ).setFrameEnabled( True )
def setUp(self):
"""Run before each test."""
self.mComposition = QgsComposition(None)
self.mComposition.setPaperSize(297, 210) #A4 landscape
self.htmlItem = QgsComposerHtml(self.mComposition, False)
def tearDown(self):
"""Run after each test."""
print "Tear down"
if self.htmlItem:
self.mComposition.removeMultiFrame(self.htmlItem)
del self.htmlItem
def controlImagePath(self, theImageName):
"""Helper to get the path to a control image."""
myPath = os.path.join(TEST_DATA_DIR,
"control_images",
"expected_composerhtml",
theImageName)
assert os.path.exists(myPath)
return myPath
def htmlUrl(self):
"""Helper to get the url of the html doc."""
myPath = os.path.join(TEST_DATA_DIR, "html_table.html")
myUrl = QUrl(QString("file:///%1").arg(myPath))
return myUrl
def testTable(self):
"""Test we can render a html table in a single frame."""
htmlFrame = QgsComposerFrame(self.mComposition,
self.htmlItem, 0, 0, 100, 200)
htmlFrame.setFrameEnabled(True)
self.htmlItem.addFrame(htmlFrame)
self.htmlItem.setUrl(self.htmlUrl())
checker = QgsCompositionChecker()
myResult, myMessage = checker.testComposition(
"Composer html table",
self.mComposition,
self.controlImagePath("composerhtml_table.png"))
qDebug(myMessage)
assert myResult, myMessage
def testTableMultiFrame(self):
"""Test we can render to multiframes."""
htmlFrame = QgsComposerFrame(self.mComposition, self.htmlItem,
10, 10, 100, 50)
self.htmlItem.addFrame(htmlFrame)
self.htmlItem.setResizeMode(QgsComposerMultiFrame.RepeatUntilFinished)
self.htmlItem.setUrl(self.htmlUrl())
self.htmlItem.frame(0).setFrameEnabled(True)
result = True
#page 1
checker1 = QgsCompositionChecker( )
if not checker1.testComposition( "Composer html table", self.mComposition, QString( QString( TEST_DATA_DIR ) + QDir.separator() + "control_images" + QDir.separator() + "expected_composerhtml" + QDir.separator() + "composerhtml_table_multiframe1.png" ), 0 ):
result = False
checker2 = QgsCompositionChecker( )
if not checker2.testComposition( "Composer html table", self.mComposition, QString( QString( TEST_DATA_DIR ) + QDir.separator() + "control_images" + QDir.separator() + "expected_composerhtml" + QDir.separator() + "composerhtml_table_multiframe2.png" ) , 1 ):
result = False
checker3 = QgsCompositionChecker( )
if not checker3.testComposition( "Composer html table", self.mComposition, QString( QString( TEST_DATA_DIR ) + QDir.separator() + "control_images" + QDir.separator() + "expected_composerhtml" + QDir.separator() + "composerhtml_table_multiframe3.png" ), 2 ):
result = False
self.mComposition.removeMultiFrame( htmlItem )
del htmlItem
assert result == True
myPage = 0
checker1 = QgsCompositionChecker()
myControlImage = self.controlImagePath(
"composerhtml_table_multiframe1.png")
print "Checking page 1"
myResult, myMessage = checker1.testComposition("Composer html table",
self.mComposition,
myControlImage,
myPage)
assert myResult, myMessage
myPage = 1
checker2 = QgsCompositionChecker()
myControlImage = self.controlImagePath(
"composerhtml_table_multiframe2.png")
myResult, myMessage = checker2.testComposition("Composer html table",
self.mComposition,
myControlImage,
myPage)
assert myResult, myMessage
myPage = 2
checker3 = QgsCompositionChecker()
myControlImage = self.controlImagePath(
"composerhtml_table_multiframe3.png")
myResult, myMessage = checker3.testComposition("Composer html table",
self.mComposition,
myControlImage,
myPage)
assert myResult, myMessage
if __name__ == '__main__':
unittest.main()