Skip to content

Commit 6c0e03f

Browse files
author
timlinux
committed
Added option to save histogram and also refactored dialog filetype list for saving images into qgisgui
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@14328 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 9afafee commit 6c0e03f

File tree

6 files changed

+182
-114
lines changed

6 files changed

+182
-114
lines changed

src/app/qgisapp.cpp

Lines changed: 4 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,20 +2593,6 @@ void QgisApp::about()
25932593

25942594

25952595

2596-
/**
2597-
2598-
Convenience function for readily creating file filters.
2599-
2600-
Given a long name for a file filter and a regular expression, return
2601-
a file filter string suitable for use in a QFileDialog::OpenFiles()
2602-
call. The regular express, glob, will have both all lower and upper
2603-
case versions added.
2604-
2605-
*/
2606-
static QString createFileFilter_( QString const &longName, QString const &glob )
2607-
{
2608-
return longName + " (" + glob.toLower() + " " + glob.toUpper() + ")";
2609-
} // createFileFilter_
26102596

26112597

26122598

@@ -3558,94 +3544,16 @@ void QgisApp::showComposerManager()
35583544

35593545
void QgisApp::saveMapAsImage()
35603546
{
3561-
//create a map to hold the QImageIO names and the filter names
3562-
//the QImageIO name must be passed to the mapcanvas saveas image function
3563-
typedef QMap<QString, QString> FilterMap;
3564-
FilterMap myFilterMap;
3565-
3566-
//find out the last used filter
3567-
QSettings myQSettings; // where we keep last used filter in persistent state
3568-
QString myLastUsedFilter = myQSettings.value( "/UI/lastSaveAsImageFilter" ).toString();
3569-
QString myLastUsedDir = myQSettings.value( "/UI/lastSaveAsImageDir", "." ).toString();
3570-
3571-
// get a list of supported output image types
3572-
int myCounterInt = 0;
3573-
QString myFilters;
3574-
QList<QByteArray> formats = QImageWriter::supportedImageFormats();
3575-
3576-
for ( ; myCounterInt < formats.count(); myCounterInt++ )
3577-
{
3578-
QString myFormat = QString( formats.at( myCounterInt ) );
3579-
//svg doesnt work so skip it
3580-
if ( myFormat == "svg" )
3581-
continue;
3582-
3583-
QString myFilter = createFileFilter_( myFormat + " format", "*." + myFormat );
3584-
if ( !myFilters.isEmpty() )
3585-
myFilters += ";;";
3586-
myFilters += myFilter;
3587-
myFilterMap[myFilter] = myFormat;
3588-
}
3589-
#ifdef QGISDEBUG
3590-
QgsDebugMsg( "Available Filters Map: " );
3591-
FilterMap::Iterator myIterator;
3592-
for ( myIterator = myFilterMap.begin(); myIterator != myFilterMap.end(); ++myIterator )
3593-
{
3594-
QgsDebugMsg( myIterator.key() + " : " + myIterator.value() );
3595-
}
3596-
#endif
3597-
3598-
//create a file dialog using the the filter list generated above
3599-
std::auto_ptr < QFileDialog > myQFileDialog( new QFileDialog( this,
3600-
tr( "Choose a file name to save the map image as" ),
3601-
myLastUsedDir, myFilters ) );
3602-
3603-
// allow for selection of more than one file
3604-
myQFileDialog->setFileMode( QFileDialog::AnyFile );
3605-
3606-
myQFileDialog->setAcceptMode( QFileDialog::AcceptSave );
3607-
3608-
myQFileDialog->setConfirmOverwrite( true );
3609-
3610-
3611-
if ( !myLastUsedFilter.isEmpty() ) // set the filter to the last one used
3612-
{
3613-
myQFileDialog->selectFilter( myLastUsedFilter );
3614-
}
3615-
3616-
3617-
//prompt the user for a fileName
3618-
QString myOutputFileNameQString; // = myQFileDialog->getSaveFileName(); //delete this
3619-
if ( myQFileDialog->exec() == QDialog::Accepted )
3547+
QPair< QString,QString> myFileNameAndFilter = QgisGui::getSaveAsImageName( this, tr( "Choose a file name to save the map image as" ) );
3548+
if ( myFileNameAndFilter.first != "" )
36203549
{
3621-
myOutputFileNameQString = myQFileDialog->selectedFiles().first();
3622-
}
3623-
3624-
QString myFilterString = myQFileDialog->selectedFilter();
3625-
QgsDebugMsg( "Selected filter: " + myFilterString );
3626-
QgsDebugMsg( "Image type to be passed to mapcanvas: " + myFilterMap[myFilterString] );
3627-
3628-
// Add the file type suffix to the fileName if required
3629-
if ( !myOutputFileNameQString.endsWith( myFilterMap[myFilterString] ) )
3630-
{
3631-
myOutputFileNameQString += "." + myFilterMap[myFilterString];
3632-
}
3633-
3634-
myQSettings.setValue( "/UI/lastSaveAsImageFilter", myFilterString );
3635-
myQSettings.setValue( "/UI/lastSaveAsImageDir", myQFileDialog->directory().absolutePath() );
3636-
3637-
if ( myOutputFileNameQString != "" )
3638-
{
3639-
36403550
//save the mapview to the selected file
3641-
mMapCanvas->saveAsImage( myOutputFileNameQString, NULL, myFilterMap[myFilterString] );
3642-
statusBar()->showMessage( tr( "Saved map image to %1" ).arg( myOutputFileNameQString ) );
3551+
mMapCanvas->saveAsImage( myFileNameAndFilter.first, NULL, myFileNameAndFilter.second );
3552+
statusBar()->showMessage( tr( "Saved map image to %1" ).arg( myFileNameAndFilter.first ) );
36433553
}
36443554

36453555
} // saveMapAsImage
36463556

3647-
3648-
36493557
//overloaded version of the above function
36503558
void QgisApp::saveMapAsImage( QString theImageFileNameQString, QPixmap * theQPixmap )
36513559
{

src/app/qgsrasterlayerproperties.cpp

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
6666
: QDialog( parent, fl ),
6767
// Constant that signals property not used.
6868
TRSTRING_NOT_SET( tr( "Not Set" ) ),
69-
mRasterLayer( qobject_cast<QgsRasterLayer *>( lyr ) )
69+
mRasterLayer( qobject_cast<QgsRasterLayer *>( lyr ) ),
70+
mpPlot( 0 )
7071
{
7172
ignoreSpinBoxEvent = false; //Short circuit signal loop between min max field and stdDev spin box
7273
mGrayMinimumMaximumEstimated = true;
@@ -204,6 +205,8 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
204205
pbtnExportColorMapToFile->setIcon( QgisApp::getThemeIcon( "/mActionFileSave.png" ) );
205206
pbtnLoadColorMapFromFile->setIcon( QgisApp::getThemeIcon( "/mActionFileOpen.png" ) );
206207

208+
mSaveAsImageButton->setIcon( QgisApp::getThemeIcon( "/mActionFileSave.png" ) );
209+
207210
mMapCanvas = theCanvas;
208211
mPixelSelectorTool = 0;
209212
if ( mMapCanvas )
@@ -1849,29 +1852,31 @@ void QgsRasterLayerProperties::on_tabBar_currentChanged( int theTab )
18491852

18501853
void QgsRasterLayerProperties::refreshHistogram()
18511854
{
1855+
if ( mpPlot != 0 )
1856+
{
1857+
delete mpPlot;
1858+
}
18521859
mHistogramProgress->show();
18531860
connect( mRasterLayer, SIGNAL( progressUpdate( int ) ), mHistogramProgress, SLOT( setValue( int ) ) );
18541861
QApplication::setOverrideCursor( Qt::WaitCursor );
18551862
QgsDebugMsg( "entered." );
1856-
1857-
QwtPlot * mypPlot = new QwtPlot( mChartWidget );
1858-
mypPlot->canvas()->setCursor( Qt::ArrowCursor );
1863+
mpPlot = new QwtPlot( mChartWidget );
18591864
//ensure all children get removed
1860-
mypPlot->setAutoDelete( true );
1865+
mpPlot->setAutoDelete( true );
18611866
QVBoxLayout *mpHistogramLayout = new QVBoxLayout( mChartWidget );
18621867
mpHistogramLayout->setContentsMargins( 0, 0, 0, 0 );
1863-
mpHistogramLayout->addWidget( mypPlot );
1868+
mpHistogramLayout->addWidget( mpPlot );
18641869
mChartWidget->setLayout( mpHistogramLayout );
1865-
mypPlot->setTitle( QObject::tr( "Raster Histogram" ) );
1866-
mypPlot->insertLegend( new QwtLegend(), QwtPlot::BottomLegend );
1870+
mpPlot->setTitle( QObject::tr( "Raster Histogram") );
1871+
mpPlot->insertLegend( new QwtLegend(), QwtPlot::BottomLegend );
18671872
// Set axis titles
1868-
mypPlot->setAxisTitle( QwtPlot::xBottom, QObject::tr( "Pixel Value" ) );
1869-
mypPlot->setAxisTitle( QwtPlot::yLeft, QObject::tr( "Frequency" ) );
1870-
mypPlot->setAxisAutoScale( QwtPlot::xBottom );
1871-
mypPlot->setAxisAutoScale( QwtPlot::yLeft );
1873+
mpPlot->setAxisTitle( QwtPlot::xBottom, QObject::tr("Pixel Value") );
1874+
mpPlot->setAxisTitle( QwtPlot::yLeft, QObject::tr("Frequency") );
1875+
mpPlot->setAxisAutoScale( QwtPlot::xBottom );
1876+
mpPlot->setAxisAutoScale( QwtPlot::yLeft );
18721877
// add a grid
18731878
QwtPlotGrid * myGrid = new QwtPlotGrid();
1874-
myGrid->attach( mypPlot );
1879+
myGrid->attach(mpPlot);
18751880
// Explanation:
18761881
// We use the gdal histogram creation routine is called for each selected
18771882
// layer. Currently the hist is hardcoded
@@ -1917,15 +1922,39 @@ void QgsRasterLayerProperties::refreshHistogram()
19171922
myX2Data.append( double( myBin ) );
19181923
myY2Data.append( double( myBinValue ) );
19191924
}
1920-
mypCurve->setData( myX2Data, myY2Data );
1921-
mypCurve->attach( mypPlot );
1925+
mypCurve->setData(myX2Data,myY2Data);
1926+
mypCurve->attach(mpPlot);
19221927
}
1923-
mypPlot->replot();
1928+
mpPlot->replot();
19241929
disconnect( mRasterLayer, SIGNAL( progressUpdate( int ) ), mHistogramProgress, SLOT( setValue( int ) ) );
19251930
mHistogramProgress->hide();
1931+
mpPlot->canvas()->setCursor(Qt::ArrowCursor);
19261932
QApplication::restoreOverrideCursor();
19271933
}
19281934

1935+
void QgsRasterLayerProperties::on_mSaveAsImageButton_clicked()
1936+
{
1937+
if ( mpPlot == 0 )
1938+
{
1939+
return;
1940+
}
1941+
1942+
QPixmap myPixmap(600, 600);
1943+
myPixmap.fill(Qt::white); // Qt::transparent ?
1944+
1945+
QwtPlotPrintFilter myFilter;
1946+
int myOptions = QwtPlotPrintFilter::PrintAll;
1947+
myOptions &= ~QwtPlotPrintFilter::PrintBackground;
1948+
myOptions |= QwtPlotPrintFilter::PrintFrameWithScales;
1949+
myFilter.setOptions(myOptions);
1950+
1951+
mpPlot->print(myPixmap, myFilter);
1952+
QPair< QString,QString> myFileNameAndFilter = QgisGui::getSaveAsImageName( this, tr( "Choose a file name to save the map image as" ) );
1953+
if ( myFileNameAndFilter.first != "" )
1954+
{
1955+
myPixmap.save( myFileNameAndFilter.first );
1956+
}
1957+
}
19291958
void QgsRasterLayerProperties::on_pbnImportTransparentPixelValues_clicked()
19301959
{
19311960
int myLineCounter = 0;

src/app/qgsrasterlayerproperties.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class QgsMapLayer;
3131
class QgsMapCanvas;
3232
class QgsRasterLayer;
3333
class QgsPixelSelectorTool;
34-
34+
class QwtPlot;
3535

3636
/**Property sheet for a raster map layer
3737
*@author Tim Sutton
@@ -144,6 +144,8 @@ class QgsRasterLayerProperties : public QDialog, private Ui::QgsRasterLayerPrope
144144
void on_pbnSaveStyleAs_clicked();
145145
/** Help button */
146146
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
147+
/** This slot lets you save the histogram as an image to disk */
148+
void on_mSaveAsImageButton_clicked();
147149

148150
signals:
149151

@@ -219,6 +221,7 @@ class QgsRasterLayerProperties : public QDialog, private Ui::QgsRasterLayerPrope
219221

220222
QgsMapCanvas* mMapCanvas;
221223
QgsPixelSelectorTool* mPixelSelectorTool;
224+
QwtPlot * mpPlot;
222225
};
223226

224227
/**

src/gui/qgisgui.cpp

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@
1515
#include "qgisgui.h"
1616

1717
#include <QSettings>
18+
#include <QObject> //for tr
19+
#include <QImageWriter>
1820
#include "qgsencodingfiledialog.h"
1921
#include "qgslogger.h"
22+
#include <memory> //for auto_ptr
23+
2024

2125
namespace QgisGui
2226
{
@@ -34,7 +38,7 @@ namespace QgisGui
3438

3539
haveLastUsedFilter = settings.contains( "/UI/" + filterName );
3640
QString lastUsedFilter = settings.value( "/UI/" + filterName,
37-
QVariant( QString::null ) ).toString();
41+
QVariant( QString::null ) ).toString();
3842

3943
QString lastUsedDir = settings.value( "/UI/" + filterName + "Dir", "." ).toString();
4044

@@ -84,5 +88,91 @@ namespace QgisGui
8488
return false;
8589
}
8690

91+
QPair<QString, QString> GUI_EXPORT getSaveAsImageName( QWidget * theParent, QString theMessage )
92+
{
93+
//create a map to hold the QImageIO names and the filter names
94+
//the QImageIO name must be passed to the mapcanvas saveas image function
95+
typedef QMap<QString, QString> FilterMap;
96+
FilterMap myFilterMap;
97+
98+
//find out the last used filter
99+
QSettings myQSettings; // where we keep last used filter in persistent state
100+
QString myLastUsedFilter = myQSettings.value( "/UI/lastSaveAsImageFilter" ).toString();
101+
QString myLastUsedDir = myQSettings.value( "/UI/lastSaveAsImageDir", "." ).toString();
102+
103+
// get a list of supported output image types
104+
int myCounterInt = 0;
105+
QString myFilters;
106+
QList<QByteArray> formats = QImageWriter::supportedImageFormats();
107+
108+
for ( ; myCounterInt < formats.count(); myCounterInt++ )
109+
{
110+
QString myFormat = QString( formats.at( myCounterInt ) );
111+
//svg doesnt work so skip it
112+
if ( myFormat == "svg" )
113+
continue;
114+
115+
QString myFilter = createFileFilter_( myFormat + " format", "*." + myFormat );
116+
if ( !myFilters.isEmpty() )
117+
myFilters += ";;";
118+
myFilters += myFilter;
119+
myFilterMap[myFilter] = myFormat;
120+
}
121+
#ifdef QGISDEBUG
122+
QgsDebugMsg( "Available Filters Map: " );
123+
FilterMap::Iterator myIterator;
124+
for ( myIterator = myFilterMap.begin(); myIterator != myFilterMap.end(); ++myIterator )
125+
{
126+
QgsDebugMsg( myIterator.key() + " : " + myIterator.value() );
127+
}
128+
#endif
129+
130+
//create a file dialog using the the filter list generated above
131+
std::auto_ptr < QFileDialog > myQFileDialog( new QFileDialog( theParent,
132+
QObject::tr( "Choose a file name to save the map image as" ),
133+
myLastUsedDir, myFilters ) );
134+
135+
// allow for selection of more than one file
136+
myQFileDialog->setFileMode( QFileDialog::AnyFile );
137+
138+
myQFileDialog->setAcceptMode( QFileDialog::AcceptSave );
139+
140+
myQFileDialog->setConfirmOverwrite( true );
141+
142+
143+
if ( !myLastUsedFilter.isEmpty() ) // set the filter to the last one used
144+
{
145+
myQFileDialog->selectFilter( myLastUsedFilter );
146+
}
147+
148+
//prompt the user for a fileName
149+
QString myOutputFileName; // = myQFileDialog->getSaveFileName(); //delete this
150+
if ( myQFileDialog->exec() == QDialog::Accepted )
151+
{
152+
myOutputFileName = myQFileDialog->selectedFiles().first();
153+
}
154+
155+
QString myFilterString = myQFileDialog->selectedFilter();
156+
QgsDebugMsg( "Selected filter: " + myFilterString );
157+
QgsDebugMsg( "Image type: " + myFilterMap[myFilterString] );
158+
159+
// Add the file type suffix to the fileName if required
160+
if ( !myOutputFileName.endsWith( myFilterMap[myFilterString] ) )
161+
{
162+
myOutputFileName += "." + myFilterMap[myFilterString];
163+
}
164+
165+
myQSettings.setValue( "/UI/lastSaveAsImageFilter", myFilterString );
166+
myQSettings.setValue( "/UI/lastSaveAsImageDir", myQFileDialog->directory().absolutePath() );
167+
QPair <QString, QString> myPair;
168+
myPair.first = myOutputFileName;
169+
myPair.second = myFilterMap[myFilterString];
170+
return myPair;
171+
} //
172+
173+
static QString createFileFilter_( QString const &longName, QString const &glob )
174+
{
175+
return longName + " (" + glob.toLower() + " " + glob.toUpper() + ")";
176+
} // createFileFilter_
87177

88178
} // end of QgisGui namespace

0 commit comments

Comments
 (0)