1
/***************************************************************************
2
qgscomposer.cpp - description
5
copyright : (C) 2005 by Radim Blazek
7
***************************************************************************/
9
/***************************************************************************
11
* This program is free software; you can redistribute it and/or modify *
12
* it under the terms of the GNU General Public License as published by *
13
* the Free Software Foundation; either version 2 of the License, or *
14
* (at your option) any later version. *
16
***************************************************************************/
17
#include "qgscomposer.h"
20
#include "qgsapplication.h"
21
#include "qgscomposerview.h"
22
#include "qgscomposition.h"
23
#include "qgsexception.h"
24
#include "qgsproject.h"
25
#include "qgsmessageviewer.h"
26
#include "qgscontexthelp.h"
28
#include <QDesktopWidget>
29
#include <QFileDialog>
32
#include <QMessageBox>
36
#include <QPrintDialog>
41
#include <QImageWriter>
47
QgsComposer::QgsComposer( QgisApp *qgis): QMainWindow()
51
setWindowTitle(tr("QGIS - print composer"));
53
// Template save and load is not yet implemented, so disable those actions
54
mActionOpenTemplate->setEnabled(false);
55
mActionSaveTemplateAs->setEnabled(false);
61
std::cout << "QgsComposer::QgsComposer" << std::endl;
64
mView = new QgsComposerView ( this, mViewFrame);
67
QGridLayout *l = new QGridLayout(mViewFrame, 1, 1 );
68
l->addWidget( mView, 0, 0 );
70
mCompositionOptionsLayout = new QGridLayout( mCompositionOptionsFrame, 1, 1 );
71
mItemOptionsLayout = new QGridLayout( mItemOptionsFrame, 1, 1 );
73
mCompositionNameComboBox->insertItem( tr("Map 1") );
75
mComposition = new QgsComposition( this, 1 );
76
mComposition->setActive ( true );
78
// Create size grip (needed by Mac OS X for QMainWindow if QStatusBar is not visible)
79
mSizeGrip = new QSizeGrip(this);
80
mSizeGrip->resize(mSizeGrip->sizeHint());
81
mSizeGrip->move(rect().bottomRight() - mSizeGrip->rect().bottomRight());
83
if ( ! connect( mQgis, SIGNAL( projectRead() ), this, SLOT( projectRead()) ) ) {
84
qDebug( "unable to connect to projectRead" );
86
if ( ! connect( mQgis, SIGNAL( newProject() ), this, SLOT(newProject()) ) ) {
87
qDebug( "unable to connect to newProject" );
90
if ( ! connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(saveWindowState()) ) ) {
91
qDebug( "unable to connect to aboutToQuit" );
95
selectItem(); // Set selection tool
98
QgsComposer::~QgsComposer()
102
void QgsComposer::setupTheme()
104
//calculate the active theme path
105
QString myThemePath= QgsApplication::themePath();
108
//now set all the icons
109
mActionOpenTemplate->setIconSet(QIcon(QPixmap(myThemePath + "/mActionFileOpen.png")));
110
mActionSaveTemplateAs->setIconSet(QIcon(QPixmap(myThemePath + "/mActionFileSaveAs.png")));
111
mActionExportAsImage->setIconSet(QIcon(QPixmap(myThemePath + "/mActionExportMapServer.png")));
112
mActionExportAsSVG->setIconSet(QIcon(QPixmap(myThemePath + "/mActionSaveAsSVG.png")));
113
mActionPrint->setIconSet(QIcon(QPixmap(myThemePath + "/mActionFilePrint.png")));
114
mActionZoomAll->setIconSet(QIcon(QPixmap(myThemePath + "/mActionZoomFullExtent.png")));
115
mActionZoomIn->setIconSet(QIcon(QPixmap(myThemePath + "/mActionZoomIn.png")));
116
mActionZoomOut->setIconSet(QIcon(QPixmap(myThemePath + "/mActionZoomOut.png")));
117
mActionRefreshView->setIconSet(QIcon(QPixmap(myThemePath + "/mActionDraw.png")));
118
mActionAddImage->setIconSet(QIcon(QPixmap(myThemePath + "/mActionSaveMapAsImage.png")));
119
mActionAddNewMap->setIconSet(QIcon(QPixmap(myThemePath + "/mActionAddRasterLayer.png")));
120
mActionAddNewLabel->setIconSet(QIcon(QPixmap(myThemePath + "/mActionLabel.png")));
121
mActionAddNewVectLegend->setIconSet(QIcon(QPixmap(myThemePath + "/mActionAddLegend.png")));
122
mActionAddNewScalebar->setIconSet(QIcon(QPixmap(myThemePath + "/mActionScaleBar.png")));
123
mActionSelectMoveItem->setIconSet(QIcon(QPixmap(myThemePath + "/mActionPan.png")));
126
void QgsComposer::open ( void )
129
mComposition->createDefault();
136
void QgsComposer::removeWidgetChildren ( QWidget *w )
139
std::cout << "QgsComposer::removeWidgetChildren" << std::endl;
142
const QObjectList ol = mItemOptionsFrame->children();
145
QListIterator<QObject*> olit( ol );
147
while( olit.hasNext() )
150
if( ob->isWidgetType() )
152
QWidget *ow = (QWidget *) ob;
154
// The following line is legacy Qt3, is not supported in Qt4
155
// and can cause a SIGABRT
156
//w->removeChild ( ob );
159
// TODO: Eventually mItemOptionsFrame should be made
160
// a Qt4 QStackedWidget and all this removeWidgetChildren
161
// shenanigans can alledgedly go away
169
void QgsComposer::showCompositionOptions ( QWidget *w ) {
171
std::cout << "QgsComposer::showCompositionOptions" << std::endl;
173
removeWidgetChildren ( mCompositionOptionsFrame );
176
w->reparent ( mCompositionOptionsFrame, QPoint(0,0), TRUE );
177
mCompositionOptionsLayout->addWidget( w, 0, 0 );
181
void QgsComposer::showItemOptions ( QWidget *w )
184
std::cout << "QgsComposer::showItemOptions" << std::endl;
186
removeWidgetChildren ( mItemOptionsFrame );
188
// NOTE: It is better to leave there the tab with item options if w is NULL
191
w->reparent ( mItemOptionsFrame, QPoint(0,0), TRUE );
193
mItemOptionsLayout->addWidget( w, 0, 0 );
194
mOptionsTabWidget->setCurrentPage (1);
198
QgsMapCanvas *QgsComposer::mapCanvas(void)
200
return mQgis->getMapCanvas();
203
QgsComposerView *QgsComposer::view(void)
208
QgsComposition *QgsComposer::composition(void)
213
void QgsComposer::zoomFull(void)
218
double xscale = 1.0 * (mView->width()-10) / mComposition->canvas()->width();
219
double yscale = 1.0 * (mView->height()-10) / mComposition->canvas()->height();
220
double scale = ( xscale < yscale ? xscale : yscale );
223
double dx = ( mView->width() - scale * mComposition->canvas()->width() ) / 2;
224
double dy = ( mView->height() - scale * mComposition->canvas()->height() ) / 2;
226
m.translate ( dx, dy );
227
m.scale( scale, scale );
229
mView->setWorldMatrix( m );
230
mView->repaintContents();
233
void QgsComposer::on_mActionZoomAll_activated(void)
238
QMatrix QgsComposer::updateMatrix(double scaleChange)
240
double scale = mView->worldMatrix().m11() * scaleChange; // get new scale
242
double dx = ( mView->width() - scale * mComposition->canvas()->width() ) / 2;
243
double dy = ( mView->height() - scale * mComposition->canvas()->height() ) / 2;
245
// don't translate if composition is bigger than view
249
// create new world matrix:
251
m.translate ( dx, dy );
252
m.scale ( scale, scale );
256
void QgsComposer::on_mActionZoomIn_activated(void)
258
QMatrix m = updateMatrix(2);
259
mView->setWorldMatrix( m );
260
mView->repaintContents();
263
void QgsComposer::on_mActionZoomOut_activated(void)
265
QMatrix m = updateMatrix(0.5);
266
mView->setWorldMatrix( m );
267
mView->repaintContents();
270
void QgsComposer::on_mActionRefreshView_activated(void)
272
mComposition->refresh();
273
mView->repaintContents();
276
void QgsComposer::on_mActionPrint_activated(void)
278
/* Uff!!! It is impossible to set a custom page size for QPrinter.
279
* Only the sizes hardcoded in Qt library can be used.
280
* 'Fortunately', it seems that everything is written to postscript output file,
281
* regardless the pages size ->
283
* 1) outputToFile == false: If the output page size doesn't match the user defined size
284
* (in QgsComposer) the output is rescaled and centered so that
285
* it fit to the select output page size.
286
* a warning is displayed, that the map was rescaled.
288
* 2) outputToFile == true: the output postscript file is written (page size is not
289
* important but bigger is better because it lefts enough space
290
* in BoundingBox definition), then the file is reopened,
291
* and the BoundingBox is redefined.
294
// NOTE: QT 3.2 has QPrinter::setOptionEnabled but only for three options
297
mPrinter = new QPrinter ( QPrinter::PrinterResolution );
298
//mPrinter = new QPrinter ( QPrinter::HighResolution );
299
//mPrinter = new QPrinter ( QPrinter::ScreenResolution );
300
mPrinter->setFullPage ( true );
302
// For Qt/Mac 3, don't set outputToFile to true before calling setup
303
// because it wiil suppress the Print dialog and output to file without
304
// giving the user a chance to select a printer instead.
305
// The Mac Print dialog provides an option to create a pdf which is
306
// intended to be invisible to the application. If an eps is desired,
307
// a custom Mac Print dialog is needed.
309
// There is a bug in Qt<=4.2.2 (dialog is not correct) if output is set to file
310
// => disable until they fix it
311
//mPrinter->setOutputToFile (true ) ;
312
//mPrinter->setOutputFileName ( QDir::convertSeparators ( QDir::home().path() + "/" + "qgis.eps") );
315
if ( mComposition->paperOrientation() == QgsComposition::Portrait ) {
316
mPrinter->setOrientation ( QPrinter::Portrait );
318
mPrinter->setOrientation ( QPrinter::Landscape );
320
mPrinter->setColorMode ( QPrinter::Color );
321
mPrinter->setPageSize ( QPrinter::A4 );
325
// Because of bug in Qt<=4.2.2 (dialog is not correct) we have to reset always
326
// to printer otherwise print to file is checked but printer combobox is in dialog
327
mPrinter->setOutputToFile (false) ;
330
mPrinter->setResolution ( mComposition->resolution() );
332
//if ( mPrinter->setup(this) ) {
333
QPrintDialog printDialog ( mPrinter, this);
334
if ( printDialog.exec() == QDialog::Accepted )
336
// TODO: mPrinter->setup() moves the composer under Qgisapp, get it to foreground somehow
337
// raise() for now, is it something better?
340
// TODO: Qt does not add pagesize to output file, it can cause problems if ps2pdf is used
341
// or if default page on printer is different.
342
// We should add somewhere in output file:
343
// << /PageSize [ %d %d ] >> setpagedevice
344
// %d %d is width and height in points
346
// WARNING: If QCanvasView recieves repaint signal during the printing
347
// (e.g. covered by QPrinter::setup dialog) it breaks somehow drawing of QCanvas items
348
// (for example not all features in the map are drawn.
349
// I don't know how to stop temporarily updating, (I don't want to reimplement
350
// repaint in QCanvasView, so I unset the view, print and reset.
353
int resolution = mPrinter->resolution();
355
std::cout << "Resolution = " << resolution << std::endl;
357
double scale = resolution / 25.4 / mComposition->scale();
359
mComposition->setPlotStyle ( QgsComposition::Postscript );
361
if ( !mPrinter->outputFileName().isNull() ) {
363
std::cout << "Print to file" << std::endl;
365
QPrinter::PageSize psize;
367
// WARNING mPrinter->outputFormat() returns always 0 in Qt 4.2.2
368
// => we have to check extension
370
if ( mPrinter->outputFileName().right(3).toLower() == ".ps"
371
|| mPrinter->outputFileName().right(4).toLower() == ".eps" )
375
//if ( mPrinter->outputFormat() == QPrinter::PostScriptFormat )
378
// NOTE: setPageSize after setup() works, but setOrientation does not
379
// -> the BoundingBox must follow the orientation
381
psize = mPrinter->pageSize();
382
// B0 ( 1000x1414mm = 2835x4008pt ) is the biggest defined in Qt, a map can be bigger
383
// but probably not bigger than 9999x9999pt = 3527x3527mm
384
mPrinter->setPageSize ( QPrinter::B0 );
387
QPainter p(mPrinter);
388
p.scale ( scale, scale);
390
mComposition->canvas()->drawArea ( QRect(0,0,
391
(int) (mComposition->paperWidth() * mComposition->scale()),
392
(int) (mComposition->paperHeight() * mComposition->scale()) ),
397
std::cout << "mPrinter->outputFormat() = " << mPrinter->outputFormat() << std::endl;
400
//if ( mPrinter->outputFormat() == QPrinter::PostScriptFormat )
404
mPrinter->setPageSize ( psize );
406
QFile f(mPrinter->outputFileName());
408
// Overwrite the bounding box
409
std::cout << "Overwrite the bounding box" << std::endl;
410
if (!f.open( QIODevice::ReadWrite )) {
411
throw QgsIOException(tr("Couldn't open " + f.name() + tr(" for read/write")));
418
while ( !f.atEnd() ) {
419
size = f.readLine ( buf, 100 );
421
if ( s.find ("%%BoundingBox:") == 0 ) {
431
w = (int) ( 72 * mComposition->paperWidth() / 25.4 );
432
h = (int) ( 72 * mComposition->paperHeight() / 25.4 );
433
if ( mPrinter->orientation() == QPrinter::Landscape ) {
434
int tmp = w; w = h; h = tmp;
436
s.sprintf( "%%%%BoundingBox: 0 0 %d %d", w, h );
438
if ( s.length() > size )
440
int shift = s.length() - size;
441
shiftFileContent ( &f, offset + size + 1, shift );
443
if ( ! f.at(offset) ) {
444
QMessageBox::warning(this, tr("Error in Print"), tr("Cannot seek"));
446
/* Write spaces (for case the size > s.length() ) */
448
es.fill(' ', size-1 );
450
if ( f.writeBlock ( es.toLocal8Bit().data(), size-1 ) < size-1 ) {
451
QMessageBox::warning(this, tr("Error in Print"), tr("Cannot overwrite BoundingBox"));
456
if ( f.writeBlock ( s.toLocal8Bit().data(), s.length() ) < s.length()-1 ) {
457
QMessageBox::warning(this, tr("Error in Print"), tr("Cannot overwrite BoundingBox"));
463
QMessageBox::warning(this, tr("Error in Print"), tr("Cannot find BoundingBox"));
467
// Overwrite translate
468
if ( mPrinter->orientation() == QPrinter::Portrait ) {
469
std::cout << "Orientation portraint -> overwrite translate" << std::endl;
470
if (!f.open( QIODevice::ReadWrite )) {
471
throw QgsIOException(tr("Couldn't open ") + f.name() + tr(" for read/write"));
477
//0 4008 translate 1 -1 scale/defM ...
478
//QRegExp rx ( "^0 [^ ]+ translate ([^ ]+ [^ ]+) scale/defM matrix CM d \\} d" );
480
//0 0 translate 0.239999 -0.239999 scale } def
481
QRegExp rx ( "^0 [^ ]+ translate ([^ ]+ [^ ]+) scale \\} def" );
483
while ( !f.atEnd() ) {
484
size = f.readLine ( buf, 100 );
486
if ( rx.search( s ) != -1 ) {
496
trans = (int) ( 72 * mComposition->paperHeight() / 25.4 );
497
std::cout << "trans = " << trans << std::endl;
499
//s.sprintf( "0 %d translate %s scale/defM matrix CM d } d", trans, (const char *)rx.cap(1).toLocal8Bit().data() );
501
s.sprintf( "0 %d translate %s scale } def\n", trans, (const char *)rx.cap(1).toLocal8Bit().data() );
504
std::cout << "s.length() = " << s.length() << " size = " << size << std::endl;
505
if ( s.length() > size ) {
506
//QMessageBox::warning(this, tr("Error in Print"), tr("Cannot format translate"));
507
// Move the content up
508
int shift = s.length() - size;
510
int last = f.size() + shift -1;
511
for ( int i = last; i > offset + size; i-- )
514
QByteArray ba = f.read(1);
519
shiftFileContent ( &f, offset + size + 1, shift );
523
if ( ! f.at(offset) ) {
524
QMessageBox::warning(this, tr("Error in Print"), tr("Cannot seek"));
526
/* Write spaces (for case the size > s.length() ) */
528
es.fill(' ', size-1 );
530
if ( f.writeBlock ( es.toLocal8Bit().data(), size-1 ) < size-1 ) {
531
QMessageBox::warning(this, tr("Error in Print"), tr("Cannot overwrite translate"));
536
if ( f.writeBlock ( s.toLocal8Bit().data(), s.length() ) < s.length()-1 ) {
537
QMessageBox::warning(this, tr("Error in Print"), tr("Cannot overwrite translate"));
542
QMessageBox::warning(this, tr("Error in Print"), tr("Cannot find translate"));
547
} catch (QgsIOException e) {
548
QMessageBox::warning(this, tr("File IO Error"), e.what());
550
} else { // print to printer
554
std::cout << "Paper: " << mPrinter->widthMM() << " x " << mPrinter->heightMM() << std::endl;
555
if ( mComposition->paperWidth() != mPrinter->widthMM() ||
556
mComposition->paperHeight() != mPrinter->heightMM() )
558
int answer = QMessageBox::warning ( 0, tr("Paper does not match"),
559
tr("The selected paper size does not match the composition size"),
560
QMessageBox::Ok, QMessageBox::Abort );
562
if ( answer == QMessageBox::Abort )
568
std::cout << "Printing ... " << std::endl;
569
QPainter p(mPrinter);
570
p.scale ( scale, scale);
571
mComposition->canvas()->drawArea ( QRect(0,0,
572
(int) (mComposition->paperWidth() * mComposition->scale()),
573
(int) (mComposition->paperHeight() * mComposition->scale()) ),
576
std::cout << "... printing finished" << std::endl;
580
mComposition->setPlotStyle ( QgsComposition::Preview );
581
mView->setCanvas(mComposition->canvas());
589
bool QgsComposer::shiftFileContent ( QFile *file, Q_LONG start, int shift )
591
int last = file->size() + shift -1;
592
for ( int i = last; i >= start + shift; i-- )
594
if ( !file->at(i-shift) ) return false;
595
QByteArray ba = file->read(1);
596
if ( ba.isEmpty() ) return false;
597
if ( !file->at(i) ) return false;
598
if ( file->write(ba) != 1 ) return false;
603
void QgsComposer::on_mActionExportAsImage_activated(void)
606
int width = (int) (mComposition->resolution() * mComposition->paperWidth() / 25.4);
607
int height = (int) (mComposition->resolution() * mComposition->paperHeight() / 25.4);
609
int memuse = width * height * 3 / 1000000; // pixmap + image
611
std::cout << "Image " << width << " x " << height << std::endl;
612
std::cout << "memuse = " << memuse << std::endl;
615
if ( memuse > 200 ) { // cca 4500 x 4500
616
int answer = QMessageBox::warning ( 0, tr("Big image"),
617
tr("To create image ") + QString::number(width) + " x "
618
+ QString::number(height)
619
+ tr(" requires circa ")
620
+ QString::number(memuse) + tr(" MB of memory"),
621
QMessageBox::Ok, QMessageBox::Abort );
624
if ( answer == QMessageBox::Abort ) return;
627
// Get file and format (stolen from qgisapp.cpp but modified significantely)
629
//create a map to hold the QImageIO names and the filter names
630
//the QImageIO name must be passed to the mapcanvas saveas image function
631
typedef QMap<QString, QString> FilterMap;
632
FilterMap myFilterMap;
634
//find out the last used filter
635
QSettings myQSettings; // where we keep last used filter in persistant state
636
QString myLastUsedFormat = myQSettings.readEntry("/UI/lastSaveAsImageFormat", "PNG" );
637
QString myLastUsedFile = myQSettings.readEntry("/UI/lastSaveAsImageFile","qgis.png");
638
QFileInfo file(myLastUsedFile);
640
// get a list of supported output image types
643
QString myLastUsedFilter;
644
for ( ; myCounterInt < QImageWriter::supportedImageFormats().count(); myCounterInt++ )
646
QString myFormat=QString(QImageWriter::supportedImageFormats().at( myCounterInt ));
647
QString myFilter = myFormat + " " + tr("format") + " (*." + myFormat.lower() + " *." + myFormat.upper() + ")";
648
if ( myCounterInt > 0 ) myFilters += ";;";
649
myFilters += myFilter;
650
myFilterMap[myFilter] = myFormat;
651
if ( myFormat == myLastUsedFormat )
653
myLastUsedFilter = myFilter;
657
std::cout << "Available Filters Map: " << std::endl;
658
FilterMap::Iterator myIterator;
659
for ( myIterator = myFilterMap.begin(); myIterator != myFilterMap.end(); ++myIterator )
661
std::cout << myIterator.key().toLocal8Bit().data() << " : " << myIterator.data().toLocal8Bit().data() << std::endl;
665
//create a file dialog using the the filter list generated above
666
std::auto_ptr < QFileDialog > myQFileDialog(
669
tr("Choose a filename to save the map image as"),
674
myQFileDialog->selectFile( file.fileName() );
676
// allow for selection of more than one file
677
myQFileDialog->setMode(QFileDialog::AnyFile);
679
// set the filter to the last one used
680
myQFileDialog->selectFilter(myLastUsedFilter);
682
// set the 'Open' button to something that makes more sense
683
myQFileDialog->setAcceptMode(QFileDialog::AcceptSave);
685
//prompt the user for a filename
686
QString myOutputFileNameQString; // = myQFileDialog->getSaveFileName(); //delete this
688
int result = myQFileDialog->exec();
691
if ( result != QDialog::Accepted) return;
693
myOutputFileNameQString = myQFileDialog->selectedFile();
694
QString myFilterString = myQFileDialog->selectedFilter();
696
std::cout << "Selected filter: " << myFilterString.toLocal8Bit().data() << std::endl;
697
std::cout << "Image type: " << myFilterMap[myFilterString].toLocal8Bit().data() << std::endl;
700
myQSettings.writeEntry("/UI/lastSaveAsImageFormat" , myFilterMap[myFilterString] );
701
myQSettings.writeEntry("/UI/lastSaveAsImageFile", myOutputFileNameQString);
703
if ( myOutputFileNameQString == "" ) return;
705
double scale = (double) (mComposition->resolution() / 25.4 / mComposition->scale());
708
mComposition->setPlotStyle ( QgsComposition::Print );
710
QPixmap pixmap ( width, height );
711
pixmap.fill ( QColor(255,255,255) ) ;
713
p.scale ( scale, scale);
714
mComposition->canvas()->drawArea ( QRect(0,0,
715
(int) (mComposition->paperWidth() * mComposition->scale()),
716
(int) (mComposition->paperHeight() * mComposition->scale()) ),
720
mComposition->setPlotStyle ( QgsComposition::Preview );
721
mView->setCanvas(mComposition->canvas());
723
pixmap.save ( myOutputFileNameQString, myFilterMap[myFilterString].toLocal8Bit().data() );
726
void QgsComposer::on_mActionExportAsSVG_activated(void)
728
QSettings myQSettings;
730
bool displaySVGWarning = myQSettings.value("/UI/displaySVGWarning", true).toBool();
732
if (displaySVGWarning)
734
QgsMessageViewer* m = new QgsMessageViewer(this);
735
m->setWindowTitle(tr("SVG warning"));
736
m->setCheckBoxText(tr("Don't show this message again"));
737
m->setCheckBoxState(Qt::Unchecked);
738
m->setCheckBoxVisible(true);
739
m->setMessageAsHtml(tr("<p>The SVG export function in Qgis has several "
740
"problems due to bugs and deficiencies in the "
741
"Qt4 svg code. Of note, text does not "
742
"appear in the SVG file and there are problems "
743
"with the map bounding box clipping other items "
744
"such as the legend or scale bar.</p>"
745
"If you require a vector-based output file from "
746
"Qgis it is suggested that you try printing "
747
"to PostScript if the SVG output is not "
752
if (m->checkBoxState() == Qt::Checked)
753
myQSettings.setValue("/UI/displaySVGWarning", false);
755
myQSettings.setValue("/UI/displaySVGWarning", true);
759
QString myLastUsedFile = myQSettings.readEntry("/UI/lastSaveAsSvgFile","qgis.svg");
760
QFileInfo file(myLastUsedFile);
762
QFileDialog *myQFileDialog = new QFileDialog( this, tr("Choose a filename to save the map as"),
763
file.path(), tr("SVG Format") + " (*.svg *SVG)" );
765
myQFileDialog->selectFile( file.fileName() );
766
myQFileDialog->setMode(QFileDialog::AnyFile);
767
myQFileDialog->setAcceptMode(QFileDialog::AcceptSave);
769
int result = myQFileDialog->exec();
772
if ( result != QDialog::Accepted) return;
773
QString myOutputFileNameQString = myQFileDialog->selectedFile();
775
if ( myOutputFileNameQString == "" ) return;
777
myQSettings.writeEntry("/UI/lastSaveAsSvgFile", myOutputFileNameQString);
780
mComposition->setPlotStyle ( QgsComposition::Print );
784
mComposition->canvas()->drawArea ( QRect(0,0,
785
(int) (mComposition->paperWidth() * mComposition->scale()),
786
(int) (mComposition->paperHeight() * mComposition->scale()) ),
790
mComposition->setPlotStyle ( QgsComposition::Preview );
791
mView->setCanvas(mComposition->canvas());
793
QRect br = pic.boundingRect();
795
pic.save ( myOutputFileNameQString, "svg" );
798
void QgsComposer::setToolActionsOff(void)
800
mActionOpenTemplate->setOn ( false );
801
mActionSaveTemplateAs->setOn ( false );
802
mActionExportAsImage->setOn ( false );
803
mActionExportAsSVG->setOn ( false );
804
mActionPrint->setOn ( false );
805
mActionZoomAll->setOn ( false );
806
mActionZoomIn->setOn ( false );
807
mActionZoomOut->setOn ( false );
808
mActionRefreshView->setOn ( false );
809
mActionAddNewMap->setOn ( false );
810
mActionAddImage->setOn ( false );
811
mActionAddNewLabel->setOn ( false );
812
mActionAddNewVectLegend->setOn ( false );
813
mActionAddNewScalebar->setOn ( false );
814
mActionSelectMoveItem->setOn ( false );
817
void QgsComposer::selectItem(void)
819
mComposition->setTool ( QgsComposition::Select );
821
mActionSelectMoveItem->setOn ( true );
824
void QgsComposer::on_mActionSelectMoveItem_activated(void)
829
void QgsComposer::on_mActionAddNewMap_activated(void)
831
mComposition->setTool ( QgsComposition::AddMap );
833
mActionAddNewMap->setOn ( true );
836
void QgsComposer::on_mActionAddNewVectLegend_activated(void)
838
mComposition->setTool ( QgsComposition::AddVectorLegend );
840
mActionAddNewVectLegend->setOn ( true );
843
void QgsComposer::on_mActionAddNewLabel_activated(void)
845
mComposition->setTool ( QgsComposition::AddLabel );
847
mActionAddNewLabel->setOn ( true );
850
void QgsComposer::on_mActionAddNewScalebar_activated(void)
852
mComposition->setTool ( QgsComposition::AddScalebar );
854
mActionAddNewScalebar->setOn ( true );
857
void QgsComposer::on_mActionAddImage_activated(void)
859
mComposition->setTool ( QgsComposition::AddPicture );
861
mActionAddImage->setOn ( true );
864
void QgsComposer::moveEvent ( QMoveEvent *e ) { saveWindowState(); }
866
void QgsComposer::resizeEvent ( QResizeEvent *e )
868
// Move size grip when window is resized
869
mSizeGrip->move(rect().bottomRight() - mSizeGrip->rect().bottomRight());
874
void QgsComposer::saveWindowState()
877
std::cout << "QgsComposer::saveWindowState" << std::endl;
881
QPoint p = this->pos();
882
QSize s = this->size();
884
settings.writeEntry("/Composer/geometry/x", p.x());
885
settings.writeEntry("/Composer/geometry/y", p.y());
886
settings.writeEntry("/Composer/geometry/w", s.width());
887
settings.writeEntry("/Composer/geometry/h", s.height());
889
Q3ValueList<int> list = mSplitter->sizes();
890
Q3ValueList<int>::Iterator it = list.begin();
891
settings.writeEntry("/Composer/geometry/wiev", (int)(*it) );
893
settings.writeEntry("/Composer/geometry/options", (int)(*it) );
896
void QgsComposer::restoreWindowState()
900
QDesktopWidget *d = QApplication::desktop();
902
int dh = d->height();
903
int w = settings.readNumEntry("/Composer/geometry/w", 600);
904
int h = settings.readNumEntry("/Composer/geometry/h", 400);
905
int x = settings.readNumEntry("/Composer/geometry/x", (dw - 600) / 2);
906
int y = settings.readNumEntry("/Composer/geometry/y", (dh - 400) / 2);
911
Q3ValueList<int> list;
912
w = settings.readNumEntry("/Composer/geometry/view", 300);
914
w = settings.readNumEntry("/Composer/geometry/options", 300);
916
mSplitter->setSizes ( list );
919
void QgsComposer::on_helpPButton_clicked()
921
QgsContextHelp::run(context_id);
924
void QgsComposer::on_closePButton_clicked()
929
void QgsComposer::projectRead(void)
932
std::cout << "QgsComposer::projectRead" << std::endl;
934
if ( mComposition ) delete mComposition;
935
mComposition = new QgsComposition( this, 1 );
937
// Read composition if it is defined in project
938
QStringList l = QgsProject::instance()->subkeyList ( "Compositions", "" );
941
for ( QStringList::iterator it = l.begin(); it != l.end(); ++it ) {
942
std::cout << "key: " << (*it).toLocal8Bit().data() << std::endl;
943
if ( (*it).compare ( "composition_1" ) == 0 ) {
950
mComposition->readSettings ( );
954
mComposition->createDefault();
961
mComposition->setActive ( true );
964
void QgsComposer::newProject(void)
967
std::cout << "QgsComposer::newProject" << std::endl;
969
if ( mComposition ) delete mComposition;
971
mComposition = new QgsComposition( this, 1 );
972
mComposition->setActive ( true );
974
// If composer is visible, create default immediately, otherwise wait for the first open()
976
mComposition->createDefault();
983
bool QgsComposer::writeSettings ( void )
993
bool QgsComposer::readSettings ( void )
1003
bool QgsComposer::writeXML( QDomNode & node, QDomDocument & doc )
1006
std::cout << "QgsComposer::writeXML" << std::endl;
1008
QDomElement compositionsNode = doc.createElement("compositions");
1010
node.appendChild( compositionsNode );
1015
bool QgsComposer::readXML( QDomNode & node )
1018
std::cout << "QgsComposer::readXML" << std::endl;