Skip to content

Commit 0cc7389

Browse files
committedMay 6, 2013
Merge pull request #579 from nyalldawson/blend_warning
Show warning when printing or pdfing a composition when blend modes are present
2 parents a5a7c1c + 5c240bc commit 0cc7389

File tree

8 files changed

+151
-4
lines changed

8 files changed

+151
-4
lines changed
 

‎src/app/composer/qgscomposer.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
330330

331331
QgsCompositionWidget* compositionWidget = new QgsCompositionWidget( mGeneralDock, mComposition );
332332
connect( mComposition, SIGNAL( paperSizeChanged() ), compositionWidget, SLOT( displayCompositionWidthHeight() ) );
333+
connect( this, SIGNAL( printAsRasterChanged( bool ) ), compositionWidget, SLOT( setPrintAsRasterCheckBox( bool ) ) );
333334
mGeneralDock->setWidget( compositionWidget );
334335

335336
//undo widget
@@ -631,6 +632,11 @@ void QgsComposer::on_mActionExportAsPDF_triggered()
631632
showWMSPrintingWarning();
632633
}
633634

635+
if ( containsBlendModes() )
636+
{
637+
showBlendModePrintingWarning();
638+
}
639+
634640
bool hasAnAtlas = mComposition->atlasComposition().enabled();
635641
bool atlasOnASingleFile = hasAnAtlas && mComposition->atlasComposition().singleFile();
636642
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
@@ -805,6 +811,11 @@ void QgsComposer::on_mActionPrint_triggered()
805811
showWMSPrintingWarning();
806812
}
807813

814+
if ( containsBlendModes() )
815+
{
816+
showBlendModePrintingWarning();
817+
}
818+
808819
//orientation and page size are already set to QPrinter in the page setup dialog
809820
QPrintDialog printDialog( &mPrinter, 0 );
810821
if ( printDialog.exec() != QDialog::Accepted )
@@ -1808,6 +1819,7 @@ void QgsComposer::readXML( const QDomElement& composerElem, const QDomDocument&
18081819
//create compositionwidget
18091820
QgsCompositionWidget* compositionWidget = new QgsCompositionWidget( mGeneralDock, mComposition );
18101821
QObject::connect( mComposition, SIGNAL( paperSizeChanged() ), compositionWidget, SLOT( displayCompositionWidthHeight() ) );
1822+
QObject::connect( this, SIGNAL( printAsRasterChanged( bool ) ), compositionWidget, SLOT( setPrintAsRasterCheckBox( bool ) ) );
18111823
mGeneralDock->setWidget( compositionWidget );
18121824

18131825
//read and restore all the items
@@ -2010,6 +2022,42 @@ bool QgsComposer::containsWMSLayer() const
20102022
return false;
20112023
}
20122024

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

2080+
void QgsComposer::showBlendModePrintingWarning()
2081+
{
2082+
if ( ! mComposition->printAsRaster() )
2083+
{
2084+
QgsMessageViewer* m = new QgsMessageViewer( this, QgisGui::ModalDialogFlags, false );
2085+
m->setWindowTitle( tr( "Project contains blend modes" ) );
2086+
m->setMessage( tr( "Blend modes are enabled in this project, which cannot be printed as vectors. Printing as a raster is recommended." ), QgsMessageOutput::MessageText );
2087+
m->setCheckBoxText( tr( "Print as raster" ) );
2088+
m->setCheckBoxState( Qt::Checked );
2089+
m->setCheckBoxVisible( true );
2090+
m->showMessage( true );
2091+
2092+
if ( m->checkBoxState() == Qt::Checked )
2093+
{
2094+
mComposition->setPrintAsRaster( true );
2095+
//make sure print as raster checkbox is updated
2096+
emit printAsRasterChanged( true );
2097+
}
2098+
else
2099+
{
2100+
mComposition->setPrintAsRaster( false );
2101+
emit printAsRasterChanged( false );
2102+
}
2103+
2104+
delete m;
2105+
}
2106+
}
2107+
20322108
void QgsComposer::cleanupAfterTemplateRead()
20332109
{
20342110
QMap<QgsComposerItem*, QWidget*>::const_iterator itemIt = mItemWidgetMap.constBegin();

‎src/app/composer/qgscomposer.h

Lines changed: 9 additions & 0 deletions
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

@@ -391,6 +397,9 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
391397
//! @note added in 1.9
392398
QMenu* mHelpMenu;
393399

400+
signals:
401+
void printAsRasterChanged( bool state );
402+
394403
private slots:
395404

396405
//! Populate Print Composers menu from main app's

‎src/app/composer/qgscompositionwidget.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,13 @@ void QgsCompositionWidget::displayCompositionWidthHeight()
377377
}
378378
}
379379

380+
void QgsCompositionWidget::setPrintAsRasterCheckBox( bool state )
381+
{
382+
mPrintAsRasterGroupCheckBox->blockSignals( true );
383+
mPrintAsRasterGroupCheckBox->setChecked( state );
384+
mPrintAsRasterGroupCheckBox->blockSignals( false );
385+
}
386+
380387
void QgsCompositionWidget::displaySnapingSettings()
381388
{
382389
if ( !mComposition )

‎src/app/composer/qgscompositionwidget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ class QgsCompositionWidget: public QWidget, private Ui::QgsCompositionWidgetBase
6262

6363
/**Sets GUI elements to width/height from composition*/
6464
void displayCompositionWidthHeight();
65+
/**Sets Print as raster checkbox value*/
66+
void setPrintAsRasterCheckBox( bool state );
6567

6668
private:
6769
QgsComposition* mComposition;

‎src/core/composer/qgscomposermap.cpp

Lines changed: 48 additions & 0 deletions
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

Lines changed: 3 additions & 0 deletions
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

‎src/gui/qgsmessageviewer.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
#include "qgsmessageviewer.h"
1919
#include <QSettings>
2020

21-
QgsMessageViewer::QgsMessageViewer( QWidget *parent, Qt::WFlags fl )
21+
QgsMessageViewer::QgsMessageViewer( QWidget *parent, Qt::WFlags fl, bool deleteOnClose )
2222
: QDialog( parent, fl )
2323
{
2424
setupUi( this );
25-
setAttribute( Qt::WA_DeleteOnClose );
26-
25+
if ( deleteOnClose )
26+
{
27+
setAttribute( Qt::WA_DeleteOnClose );
28+
}
2729
// Default state for the checkbox
2830
setCheckBoxVisible( false );
2931
setCheckBoxState( Qt::Unchecked );

‎src/gui/qgsmessageviewer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class GUI_EXPORT QgsMessageViewer: public QDialog, public QgsMessageOutput, priv
3131
{
3232
Q_OBJECT
3333
public:
34-
QgsMessageViewer( QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags );
34+
QgsMessageViewer( QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags, bool deleteOnClose = true );
3535
~QgsMessageViewer();
3636

3737
virtual void setMessage( const QString& message, MessageType msgType );

0 commit comments

Comments
 (0)
Please sign in to comment.