Skip to content

Commit 2479d83

Browse files
committed
Add warning for printing and pdf export with blend modes with option to print as raster
1 parent 471dab1 commit 2479d83

File tree

4 files changed

+128
-0
lines changed

4 files changed

+128
-0
lines changed

src/app/composer/qgscomposer.cpp

+71
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,11 @@ void QgsComposer::on_mActionExportAsPDF_triggered()
631631
showWMSPrintingWarning();
632632
}
633633

634+
if ( containsBlendModes() )
635+
{
636+
showBlendModePrintingWarning();
637+
}
638+
634639
bool hasAnAtlas = mComposition->atlasComposition().enabled();
635640
bool atlasOnASingleFile = hasAnAtlas && mComposition->atlasComposition().singleFile();
636641
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
@@ -805,6 +810,11 @@ void QgsComposer::on_mActionPrint_triggered()
805810
showWMSPrintingWarning();
806811
}
807812

813+
if ( containsBlendModes() )
814+
{
815+
showBlendModePrintingWarning();
816+
}
817+
808818
//orientation and page size are already set to QPrinter in the page setup dialog
809819
QPrintDialog printDialog( &mPrinter, 0 );
810820
if ( printDialog.exec() != QDialog::Accepted )
@@ -2010,6 +2020,42 @@ bool QgsComposer::containsWMSLayer() const
20102020
return false;
20112021
}
20122022

2023+
bool QgsComposer::containsBlendModes() const
2024+
{
2025+
// Check if composer contains any blend modes
2026+
QMap<QgsComposerItem*, QWidget*>::const_iterator item_it = mItemWidgetMap.constBegin();
2027+
QgsComposerItem* currentItem = 0;
2028+
QgsComposerMap* currentMap = 0;
2029+
2030+
for ( ; item_it != mItemWidgetMap.constEnd(); ++item_it )
2031+
{
2032+
currentItem = item_it.key();
2033+
// Check composer item's blend mode
2034+
if ( currentItem->blendMode() != QPainter::CompositionMode_SourceOver )
2035+
{
2036+
return true;
2037+
}
2038+
// If item is a composer map, check if it contains any blended layers
2039+
currentMap = dynamic_cast<QgsComposerMap *>( currentItem );
2040+
if ( currentMap )
2041+
{
2042+
if ( currentMap->containsBlendModes() )
2043+
{
2044+
return true;
2045+
}
2046+
if ( currentMap->overviewFrameMapId() != -1 )
2047+
{
2048+
// map contains an overview, check its blend mode
2049+
if ( currentMap->overviewBlendMode() != QPainter::CompositionMode_SourceOver )
2050+
{
2051+
return true;
2052+
}
2053+
}
2054+
}
2055+
}
2056+
return false;
2057+
}
2058+
20132059
void QgsComposer::showWMSPrintingWarning()
20142060
{
20152061
QString myQSettingsLabel = "/UI/displayComposerWMSWarning";
@@ -2029,6 +2075,31 @@ void QgsComposer::showWMSPrintingWarning()
20292075
}
20302076
}
20312077

2078+
void QgsComposer::showBlendModePrintingWarning()
2079+
{
2080+
if ( ! mComposition->printAsRaster() )
2081+
{
2082+
QgsMessageViewer* m = new QgsMessageViewer( this );
2083+
m->setWindowTitle( tr( "Project contains blend modes" ) );
2084+
m->setMessage( tr( "Blend modes are enabled in this project, which cannot be printed as vectors. Printing as a raster is recommended." ), QgsMessageOutput::MessageText );
2085+
m->setCheckBoxText( tr( "Print as raster" ) );
2086+
m->setCheckBoxState( Qt::Checked );
2087+
m->setCheckBoxVisible( true );
2088+
m->showMessage( true );
2089+
2090+
// TODO - fix this - checkBoxState is never true
2091+
// also need to make sure composer print as raster checkbox is updated
2092+
if ( m->checkBoxState() == Qt::Checked )
2093+
{
2094+
mComposition->setPrintAsRaster( true );
2095+
}
2096+
else
2097+
{
2098+
mComposition->setPrintAsRaster( true );
2099+
}
2100+
}
2101+
}
2102+
20322103
void QgsComposer::cleanupAfterTemplateRead()
20332104
{
20342105
QMap<QgsComposerItem*, QWidget*>::const_iterator itemIt = mItemWidgetMap.constBegin();

src/app/composer/qgscomposer.h

+6
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,15 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
309309
//! True if a composer map contains a WMS layer
310310
bool containsWMSLayer() const;
311311

312+
//! True if a composer contains blend modes
313+
bool containsBlendModes() const;
314+
312315
//! Displays a warning because of possible min/max size in WMS
313316
void showWMSPrintingWarning();
314317

318+
//! Displays a warning because of incompatibility between blend modes and QPrinter
319+
void showBlendModePrintingWarning();
320+
315321
//! Changes elements that are not suitable for this project
316322
void cleanupAfterTemplateRead();
317323

src/core/composer/qgscomposermap.cpp

+48
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "qgsrendercontext.h"
2828
#include "qgsscalecalculator.h"
2929
#include "qgsvectorlayer.h"
30+
#include "qgspallabeling.h"
3031

3132
#include "qgslabel.h"
3233
#include "qgslabelattributes.h"
@@ -627,6 +628,53 @@ bool QgsComposerMap::containsWMSLayer() const
627628
return false;
628629
}
629630

631+
bool QgsComposerMap::containsBlendModes() const
632+
{
633+
if ( !mMapRenderer )
634+
{
635+
return false;
636+
}
637+
638+
QStringList layers = mMapRenderer->layerSet();
639+
640+
//Also need to check PAL labeling for blend modes
641+
QgsPalLabeling* lbl = dynamic_cast<QgsPalLabeling*>( mMapRenderer->labelingEngine() );
642+
643+
QStringList::const_iterator layer_it = layers.constBegin();
644+
QgsMapLayer* currentLayer = 0;
645+
646+
for ( ; layer_it != layers.constEnd(); ++layer_it )
647+
{
648+
currentLayer = QgsMapLayerRegistry::instance()->mapLayer( *layer_it );
649+
if ( currentLayer )
650+
{
651+
if ( currentLayer->blendMode() != QPainter::CompositionMode_SourceOver )
652+
{
653+
return true;
654+
}
655+
// if vector layer and has labels, check label blend modes
656+
QgsVectorLayer* currentVectorLayer = qobject_cast<QgsVectorLayer *>( currentLayer );
657+
if ( currentVectorLayer )
658+
{
659+
if ( lbl->willUseLayer( currentVectorLayer ) )
660+
{
661+
// Check all label blending properties
662+
QgsPalLayerSettings& layerSettings = lbl->layer( currentVectorLayer->id() );
663+
if (( layerSettings.blendMode != QPainter::CompositionMode_SourceOver ) ||
664+
( layerSettings.bufferSize != 0 && layerSettings.bufferBlendMode != QPainter::CompositionMode_SourceOver ) ||
665+
( layerSettings.shadowDraw && layerSettings.shadowBlendMode != QPainter::CompositionMode_SourceOver ) ||
666+
( layerSettings.shapeDraw && layerSettings.shapeBlendMode != QPainter::CompositionMode_SourceOver ) )
667+
{
668+
return true;
669+
}
670+
}
671+
}
672+
}
673+
}
674+
675+
return false;
676+
}
677+
630678
void QgsComposerMap::connectUpdateSlot()
631679
{
632680
//connect signal from layer registry to update in case of new or deleted layers

src/core/composer/qgscomposermap.h

+3
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
183183
/**True if composer map renders a WMS layer*/
184184
bool containsWMSLayer() const;
185185

186+
/**True if composer map contains layers with blend modes*/
187+
bool containsBlendModes() const;
188+
186189
/** stores state in Dom node
187190
* @param elem is Dom element corresponding to 'Composer' tag
188191
* @param doc Dom document

0 commit comments

Comments
 (0)