QgsError for better error propagation to user, started using for rasters

This commit is contained in:
Radim Blazek 2012-10-24 13:58:49 +02:00
parent b78456f70d
commit e210a57101
27 changed files with 734 additions and 256 deletions

View File

@ -559,9 +559,26 @@ IF (GIT_MARKER)
COMMAND ${GITCOMMAND} log -n1 --pretty=%h OUTPUT_VARIABLE REVISION
)
STRING(STRIP "${REVISION}" REVISION)
# Get GIT remote and branch
EXECUTE_PROCESS(
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND ${GITCOMMAND} name-rev --name-only HEAD OUTPUT_VARIABLE GIT_LOCAL_BRANCH
)
STRING(STRIP "${GIT_LOCAL_BRANCH}" GIT_LOCAL_BRANCH)
EXECUTE_PROCESS(
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND ${GITCOMMAND} config branch.${GIT_LOCAL_BRANCH}.remote OUTPUT_VARIABLE GIT_REMOTE
)
STRING(STRIP "${GIT_REMOTE}" GIT_REMOTE)
EXECUTE_PROCESS(
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND ${GITCOMMAND} config remote.${GIT_REMOTE}.url OUTPUT_VARIABLE GIT_REMOTE_URL
)
STRING(STRIP "${GIT_REMOTE_URL}" GIT_REMOTE_URL)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/qgsversion.h
COMMAND echo \\\#define QGSVERSION \\\"${REVISION}\\\" >${CMAKE_CURRENT_BINARY_DIR}/qgsversion.h
COMMAND echo \\\#define QGS_GIT_REMOTE_URL \\\"${GIT_REMOTE_URL}\\\" >>${CMAKE_CURRENT_BINARY_DIR}/qgsversion.h
MAIN_DEPENDENCY ${GIT_MARKER}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)

View File

@ -99,31 +99,6 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
/* It makes no sense to set input on provider */
bool setInput( QgsRasterInterface* input );
/**
* Add the list of WMS layer names to be rendered by this server
*/
virtual void addLayers( const QStringList & layers,
const QStringList & styles = QStringList() ) = 0;
//! get raster image encodings supported by (e.g.) the WMS Server, expressed as MIME types
virtual QStringList supportedImageEncodings() = 0;
/**
* Get the image encoding (as a MIME type) used in the transfer from (e.g.) the WMS server
*/
virtual QString imageEncoding() const = 0;
/**
* Set the image encoding (as a MIME type) used in the transfer from (e.g.) the WMS server
*/
virtual void setImageEncoding( const QString & mimeType ) = 0;
/**
* Set the image projection (in WMS CRS format) used in the transfer from (e.g.) the WMS server
*/
virtual void setImageCrs( const QString & crs ) = 0;
// TODO: Document this better.
/** \brief Renders the layer as an image
*/

View File

@ -147,10 +147,6 @@ class QgsRasterLayer : QgsMapLayer
/** [ data provider interface ] Set the data provider */
void setDataProvider( const QString & provider );
static QLibrary* loadProviderLibrary( QString theProviderKey );
static QgsRasterDataProvider* loadProvider( QString theProviderKey, QString theDataSource = 0 );
/** \brief Accessor for blue band name mapping */
QString blueBandName() const;

View File

@ -120,6 +120,8 @@
#include "qgsdecorationscalebar.h"
#include "qgsdecorationgrid.h"
#include "qgsencodingfiledialog.h"
#include "qgserror.h"
#include "qgserrordialog.h"
#include "qgsexception.h"
#include "qgsfeature.h"
#include "qgsformannotationitem.h"
@ -7294,6 +7296,14 @@ QgsRasterLayer* QgisApp::addRasterLayer( QString const & rasterFile, QString con
QgsRasterLayer *layer =
new QgsRasterLayer( rasterFile, baseName ); // fi.completeBaseName());
if ( !layer->isValid() )
{
//QMessageBox::critical( this, tr( "Invalid Layer" ), layer->error().message() );
QgsErrorDialog::show( layer->error(), tr( "Invalid Layer" ) );
delete layer;
return NULL;
}
bool ok = false;
if ( shouldAskUserForGDALSublayers( layer ) )
@ -7377,7 +7387,7 @@ QgsRasterLayer* QgisApp::addRasterLayer(
QgsDebugMsg( "Constructed new layer." );
if ( layer && layer->isValid() )
if ( layer->isValid() )
{
addRasterLayer( layer );
@ -7385,8 +7395,7 @@ QgsRasterLayer* QgisApp::addRasterLayer(
}
else
{
QMessageBox::critical( this, tr( "Layer is not valid" ),
tr( "The layer is not a valid layer and can not be added to the map" ) );
QgsErrorDialog::show( layer->error(), tr( "Invalid Layer" ) );
}
// update UI
@ -7454,25 +7463,37 @@ bool QgisApp::addRasterLayers( QStringList const &theFileNameQStringList, bool g
// create the layer
QgsRasterLayer *layer = new QgsRasterLayer( *myIterator, myBaseNameQString );
if ( shouldAskUserForGDALSublayers( layer ) )
if ( !layer->isValid() )
{
askUserForGDALSublayers( layer );
// The first layer loaded is not useful in that case. The user can select it in
// the list if he wants to load it.
delete layer;
returnValue = false;
if ( guiWarning )
{
QgsErrorDialog::show( layer->error(), tr( "Invalid Layer" ) );
delete layer;
}
}
else
{
addRasterLayer( layer );
//only allow one copy of a ai grid file to be loaded at a
//time to prevent the user selecting all adfs in 1 dir which
//actually represent 1 coverate,
if ( myBaseNameQString.toLower().endsWith( ".adf" ) )
if ( shouldAskUserForGDALSublayers( layer ) )
{
break;
askUserForGDALSublayers( layer );
// The first layer loaded is not useful in that case. The user can select it in
// the list if he wants to load it.
delete layer;
}
else
{
addRasterLayer( layer );
//only allow one copy of a ai grid file to be loaded at a
//time to prevent the user selecting all adfs in 1 dir which
//actually represent 1 coverate,
if ( myBaseNameQString.toLower().endsWith( ".adf" ) )
{
break;
}
}
}
} // valid raster filename

View File

@ -63,6 +63,7 @@ SET(QGIS_CORE_SRCS
qgsdbfilterproxymodel.cpp
qgsdiagramrendererv2.cpp
qgsdistancearea.cpp
qgserror.cpp
qgsexpression.cpp
qgsfeature.cpp
qgsfield.cpp
@ -350,6 +351,7 @@ SET(QGIS_CORE_HDRS
qgsdataitem.h
qgsdistancearea.h
qgscsexception.h
qgserror.h
qgsexception.h
qgsexpression.h
qgsfeature.h

View File

@ -22,6 +22,7 @@
#include <QStringList>
//#include "qgsdataitem.h"
#include "qgserror.h"
class QgsRectangle;
class QgsCoordinateReferenceSystem;
@ -290,6 +291,12 @@ class CORE_EXPORT QgsDataProvider : public QObject
/** Current time stamp of data source */
virtual QDateTime dataTimestamp() const { return QDateTime(); }
/** Get current status error. This error describes some principal problem
* for which provider cannot work and thus is not valid. It is not last error
* after accessing data by block(), identify() etc.
*/
virtual QgsError error() const { return mError; }
signals:
/**
@ -318,6 +325,16 @@ class CORE_EXPORT QgsDataProvider : public QObject
* Timestamp of data in the moment when the data were loaded by provider.
*/
QDateTime mTimestamp;
/** \brief Error */
QgsError mError;
/** Add error message */
void appendError( const QgsErrorMessage & theMessage ) { mError.append( theMessage );}
/** Set error message */
void setError( const QgsError & theError ) { mError = theError;}
private:
/**

111
src/core/qgserror.cpp Normal file
View File

@ -0,0 +1,111 @@
/***************************************************************************
qgserror.cpp - Error container
-------------------
begin : October 2012
copyright : (C) 2012 Radim Blazek
email : radim dot blazek at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgis.h"
#include "qgsversion.h"
#include "qgsconfig.h"
#include "qgserror.h"
#include "qgslogger.h"
#include <QRegExp>
QgsErrorMessage::QgsErrorMessage ( const QString & theMessage, const QString & theTag, const QString & theFile, const QString & theFunction, int theLine )
: mMessage(theMessage)
, mTag(theTag)
, mFile(theFile)
, mFunction(theFunction)
, mLine(theLine)
, mFormat(Text)
{
}
QgsError::QgsError ( const QString & theMessage, const QString & theTag )
{
append ( theMessage, theTag );
}
void QgsError::append ( const QString & theMessage, const QString & theTag )
{
mMessageList.append ( QgsErrorMessage ( theMessage, theTag ) );
}
void QgsError::append ( const QgsErrorMessage & theMessage )
{
mMessageList.append ( theMessage );
}
QString QgsError::message ( QgsErrorMessage::Format theFormat ) const
{
QString str;
int sPrefixLength = strlen( CMAKE_SOURCE_DIR ) + 1;
QString srcUrl;
#if defined(QGISDEBUG) && defined(QGS_GIT_REMOTE_URL)
// TODO: verify if we are not ahead to origin (remote hash does not exist)
// and there are no local not commited changes
QString hash = QString(QGis::QGIS_DEV_VERSION);
QString remote = QString(QGS_GIT_REMOTE_URL);
QgsDebugMsg ("remote = " + remote );
if ( !hash.isEmpty () && !remote.isEmpty() && remote.contains ( "github.com" ) )
{
QString path = remote.remove( QRegExp(".*github.com[:/]" )).remove(".git");
srcUrl = "https://github.com/" + path + "/blob/" + hash;
}
#endif
foreach ( QgsErrorMessage m, mMessageList )
{
#ifdef QGISDEBUG
QString file;
#ifndef _MSC_VER
file = m.file().mid(sPrefixLength);
#else
file = m.file();
#endif
#endif
if ( theFormat == QgsErrorMessage::Text )
{
str += m.tag() + " " + m.message();
#ifdef QGISDEBUG
str += QString( "\nat %1 : %2 : %3" ).arg( file ).arg( m.line() ).arg( m.function() );
#endif
}
else // QgsErrorMessage::Html
{
str += "<p><b>" + m.tag() + ":</b> " + m.message();
#ifdef QGISDEBUG
QString location = QString( "%1 : %2 : %3" ).arg( file ).arg( m.line() ).arg( m.function() );
if ( !srcUrl.isEmpty() )
{
QString url = QString("%1/%2#L%3").arg(srcUrl).arg(file).arg( m.line() );
str += QString( "<br>(<a href='%1'>%2</a>)" ).arg(url).arg( location );
}
else
{
str += QString( "<br>(%1)" ).arg( location );
}
#endif
}
}
return str;
}
QString QgsError::summary ( ) const
{
// The first message in chain is usually the real error given by backend/server
return mMessageList.first().message();
}

124
src/core/qgserror.h Normal file
View File

@ -0,0 +1,124 @@
/***************************************************************************
qgserror.h - Error container
-------------------
begin : October 2012
copyright : (C) 2012 Radim Blazek
email : radim dot blazek at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSERROR_H
#define QGSERROR_H
#include <QString>
#include <QList>
// Macro to create Error message including info about where it was created.
#define QGS_ERROR_MESSAGE(message, tag) QgsErrorMessage(QString(message),QString(tag), QString(__FILE__), QString(__FUNCTION__), __LINE__)
/** \ingroup core
* QgsErrorMessage represents single error message.
*/
class CORE_EXPORT QgsErrorMessage
{
public:
/** Format */
enum Format
{
Text, // Plain text
Html
};
QgsErrorMessage() {}
/** Constructor.
* @param theMessage error message string
* @param theTag error label, for example GDAL, GDAL Provider, Raster layer
* @param theFile the file where error was created
* @param theFunction the function where error was created
* @param theLine the line where error was created
*/
QgsErrorMessage ( const QString & theMessage, const QString & theTag = QString::null, const QString & theFile = QString::null, const QString & theFunction = QString::null, int theLine = 0 );
QString message() const { return mMessage; }
QString tag() const { return mTag; }
QString file() const { return mFile; }
QString function() const { return mFunction; }
int line() const { return mLine; }
private:
/** Error messages */
QString mMessage;
/** Short description */
QString mTag;
/** Detailed debug info */
QString mFile;
QString mFunction;
int mLine;
/* Message format */
Format mFormat;
};
/** \ingroup core
* QgsError is container for error messages (report). It may contain chain
* (sort of traceback) of error messages (e.g. GDAL - provider - layer).
* Higher level messages are appended at the end.
*/
class CORE_EXPORT QgsError
{
public:
QgsError() {}
/** Constructor with single message.
* @param theMessage error message
* @param theTag short description, e.g. GDAL, Provider, Layer
*/
QgsError ( const QString & theMessage, const QString & theTag );
/** Append new error message.
* @param theMessage error message string
* @param theTag error label, for example GDAL, GDAL Provider, Raster layer
*/
void append ( const QString & theMessage, const QString & theTag );
/** Append new error message.
* @param theMessage error message
*/
void append ( const QgsErrorMessage & theMessage );
/** Test if any error is set.
* @return true if contains error
*/
bool isEmpty() const { return mMessageList.isEmpty(); }
/** Full error messages description
* @param theFormat output format
* @return error report
*/
QString message( QgsErrorMessage::Format theFormat = QgsErrorMessage::Html ) const;
/** Short error descriprion, usually the first error in chain, the real error.
* @return error description
*/
QString summary() const;
/** Clear error messages */
void clear() { mMessageList.clear(); }
private:
/** List of messages */
QList<QgsErrorMessage> mMessageList;
};
#endif

View File

@ -26,6 +26,7 @@
#include <QDomNode>
#include "qgis.h"
#include "qgserror.h"
#include "qgsrectangle.h"
class QgsRenderContext;
@ -218,6 +219,12 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/
virtual QString lastError();
/** Get current status error. This error describes some principal problem
* for which layer cannot work and thus is not valid. It is not last error
* after accessing data by draw() etc.
*/
virtual QgsError error() const { return mError; }
/** Returns layer's spatial reference system
@note This was introduced in QGIS 1.4
*/
@ -419,6 +426,11 @@ class CORE_EXPORT QgsMapLayer : public QObject
/** debugging member - invoked when a connect() is made to this object */
void connectNotify( const char * signal );
/** Add error message */
void appendError( const QgsErrorMessage & theMessage ) { mError.append( theMessage );}
/** Set error message */
void setError( const QgsError & theError ) { mError = theError;}
/** Transparency level for this layer should be 0-255 (255 being opaque) */
unsigned int mTransparencyLevel;
@ -439,6 +451,9 @@ class CORE_EXPORT QgsMapLayer : public QObject
/**Description of the layer*/
QString mAbstract;
/** \brief Error */
QgsError mError;
private:
/** layer's spatial reference system.
private to make sure setCrs must be used and layerCrsChanged() is emitted */

View File

@ -449,6 +449,7 @@ void * QgsProviderRegistry::function( QString const & providerKey,
delete myLib;
return ptr;
}
QgsDebugMsg( "Cannot load library: " + myLib->errorString() );
delete myLib;
return 0;
}
@ -467,6 +468,7 @@ QLibrary *QgsProviderRegistry::providerLibrary( QString const & providerKey ) co
{
return myLib;
}
QgsDebugMsg( "Cannot load library: " + myLib->errorString() );
delete myLib;
return 0;
}

View File

@ -13,6 +13,7 @@
* *
***************************************************************************/
#include "qgsproviderregistry.h"
#include "qgsrasterchecker.h"
#include "qgsrasterdataprovider.h"
#include "qgsrasterlayer.h"
@ -43,14 +44,16 @@ bool QgsRasterChecker::runTest( QString theVerifiedKey, QString theVerifiedUri,
bool ok = true;
mReport += "\n\n";
QgsRasterDataProvider* verifiedProvider = QgsRasterLayer::loadProvider( theVerifiedKey, theVerifiedUri );
//QgsRasterDataProvider* verifiedProvider = QgsRasterLayer::loadProvider( theVerifiedKey, theVerifiedUri );
QgsRasterDataProvider* verifiedProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( theVerifiedKey, theVerifiedUri );
if ( !verifiedProvider || !verifiedProvider->isValid() )
{
error( QString( "Cannot load provider %1 with URI: %2" ).arg( theVerifiedKey ).arg( theVerifiedUri ), mReport );
ok = false;
}
QgsRasterDataProvider* expectedProvider = QgsRasterLayer::loadProvider( theExpectedKey, theExpectedUri );
//QgsRasterDataProvider* expectedProvider = QgsRasterLayer::loadProvider( theExpectedKey, theExpectedUri );
QgsRasterDataProvider* expectedProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( theExpectedKey, theExpectedUri );
if ( !expectedProvider || !expectedProvider->isValid() )
{
error( QString( "Cannot load provider %1 with URI: %2" ).arg( theExpectedKey ).arg( theExpectedUri ), mReport );

View File

@ -25,6 +25,7 @@
#include "qgslogger.h"
#include "qgsrectangle.h"
#include "qgsdataprovider.h"
#include "qgserror.h"
#include "qgsrasterinterface.h"
#include "qgscolorrampshader.h"
#include "qgsrasterpyramid.h"
@ -144,31 +145,6 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
/* It makes no sense to set input on provider */
bool setInput( QgsRasterInterface* input ) { Q_UNUSED( input ); return false; }
/**
* Add the list of WMS layer names to be rendered by this server
*/
virtual void addLayers( const QStringList & layers,
const QStringList & styles = QStringList() ) = 0;
//! get raster image encodings supported by (e.g.) the WMS Server, expressed as MIME types
virtual QStringList supportedImageEncodings() = 0;
/**
* Get the image encoding (as a MIME type) used in the transfer from (e.g.) the WMS server
*/
virtual QString imageEncoding() const = 0;
/**
* Set the image encoding (as a MIME type) used in the transfer from (e.g.) the WMS server
*/
virtual void setImageEncoding( const QString & mimeType ) = 0;
/**
* Set the image projection (in WMS CRS format) used in the transfer from (e.g.) the WMS server
*/
virtual void setImageCrs( const QString & crs ) = 0;
// TODO: Document this better.
/** \brief Renders the layer as an image
*/

View File

@ -668,7 +668,8 @@ void QgsRasterFileWriter::buildPyramids( const QString& filename )
void QgsRasterFileWriter::buildPyramids( const QString& filename )
{
// open new dataProvider so we can build pyramids with it
QgsRasterDataProvider* destProvider = QgsRasterLayer::loadProvider( mOutputProviderKey, filename );
//QgsRasterDataProvider* destProvider = QgsRasterLayer::loadProvider( mOutputProviderKey, filename );
QgsRasterDataProvider* destProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( mOutputProviderKey, filename );
if ( !destProvider )
{
return;
@ -834,7 +835,8 @@ QgsRasterDataProvider* QgsRasterFileWriter::createPartProvider( const QgsRectang
QgsRectangle mapRect( mapLeft, mapBottom, mapRight, mapTop );
QString outputFile = outputUrl + "/" + QString::number( fileIndex );
QgsRasterDataProvider* destProvider = QgsRasterLayer::loadProvider( mOutputProviderKey, outputFile );
//QgsRasterDataProvider* destProvider = QgsRasterLayer::loadProvider( mOutputProviderKey, outputFile );
QgsRasterDataProvider* destProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( mOutputProviderKey, outputFile );
if ( !destProvider )
{
return 0;
@ -869,7 +871,8 @@ QgsRasterDataProvider* QgsRasterFileWriter::initOutput( int nCols, int nRows, co
}
else
{
QgsRasterDataProvider* destProvider = QgsRasterLayer::loadProvider( mOutputProviderKey, mOutputUrl );
//QgsRasterDataProvider* destProvider = QgsRasterLayer::loadProvider( mOutputProviderKey, mOutputUrl );
QgsRasterDataProvider* destProvider = ( QgsRasterDataProvider* ) QgsProviderRegistry::instance()->provider( mOutputProviderKey, mOutputUrl );
if ( !destProvider )
{
return 0;

View File

@ -86,6 +86,8 @@ typedef bool isvalidrasterfilename_t( QString const & theFileNameQString, QStrin
// doubles can take for the current system. (Yes, 20 was arbitrary.)
#define TINY_VALUE std::numeric_limits<double>::epsilon() * 20
#define ERR(message) QGS_ERROR_MESSAGE(message,"Raster layer")
const double QgsRasterLayer::CUMULATIVE_CUT_LOWER = 0.02;
const double QgsRasterLayer::CUMULATIVE_CUT_UPPER = 0.98;
const double QgsRasterLayer::SAMPLE_SIZE = 250000;
@ -121,6 +123,7 @@ QgsRasterLayer::QgsRasterLayer(
// TODO, call constructor with provider key
init();
setDataProvider( "gdal" );
if ( !mValid ) return;
bool defaultLoadedFlag = false;
if ( mValid && loadDefaultStyleFlag )
@ -157,6 +160,7 @@ QgsRasterLayer::QgsRasterLayer( const QString & uri,
QgsDebugMsg( "Entered" );
init();
setDataProvider( providerKey );
if ( !mValid ) return;
// load default style
bool defaultLoadedFlag = false;
@ -189,6 +193,7 @@ QgsRasterLayer::QgsRasterLayer( const QString & uri,
QgsRasterLayer::~QgsRasterLayer()
{
mValid = false;
//delete mDataProvider; // deleted by pipe
}
//////////////////////////////////////////////////////////
@ -207,21 +212,14 @@ QgsRasterLayer::~QgsRasterLayer()
void QgsRasterLayer::buildSupportedRasterFileFilter( QString & theFileFiltersString )
{
QgsDebugMsg( "Entered" );
QLibrary* myLib = QgsRasterLayer::loadProviderLibrary( "gdal" );
if ( !myLib )
{
QgsDebugMsg( "Could not load gdal provider library" );
return;
}
buildsupportedrasterfilefilter_t *pBuild = ( buildsupportedrasterfilefilter_t * ) cast_to_fptr( myLib->resolve( "buildSupportedRasterFileFilter" ) );
buildsupportedrasterfilefilter_t *pBuild = ( buildsupportedrasterfilefilter_t * ) cast_to_fptr( QgsProviderRegistry::instance()->function( "gdal", "buildSupportedRasterFileFilter" ) );
if ( ! pBuild )
{
QgsDebugMsg( "Could not resolve buildSupportedRasterFileFilter in gdal provider library" );
QgsDebugMsg( "Could get buildSupportedRasterFileFilter in gdal provider library" );
return;
}
pBuild( theFileFiltersString );
delete myLib;
}
/**
@ -229,14 +227,7 @@ void QgsRasterLayer::buildSupportedRasterFileFilter( QString & theFileFiltersStr
*/
bool QgsRasterLayer::isValidRasterFileName( QString const & theFileNameQString, QString & retErrMsg )
{
QLibrary* myLib = QgsRasterLayer::loadProviderLibrary( "gdal" );
if ( !myLib )
{
QgsDebugMsg( "Could not load gdal provider library" );
return false;
}
isvalidrasterfilename_t *pValid = ( isvalidrasterfilename_t * ) cast_to_fptr( myLib->resolve( "isValidRasterFileName" ) );
isvalidrasterfilename_t *pValid = ( isvalidrasterfilename_t * ) cast_to_fptr( QgsProviderRegistry::instance()->function( "gdal", "isValidRasterFileName" ) );
if ( ! pValid )
{
QgsDebugMsg( "Could not resolve isValidRasterFileName in gdal provider library" );
@ -244,7 +235,6 @@ bool QgsRasterLayer::isValidRasterFileName( QString const & theFileNameQString,
}
bool myIsValid = pValid( theFileNameQString, retErrMsg );
delete myLib;
return myIsValid;
}
@ -1587,96 +1577,18 @@ void QgsRasterLayer::init()
mLastViewPort.drawableAreaYDim = 0;
}
QLibrary* QgsRasterLayer::loadProviderLibrary( QString theProviderKey )
{
QgsDebugMsg( "theProviderKey = " + theProviderKey );
// load the plugin
QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
QString myLibPath = pReg->library( theProviderKey );
QgsDebugMsg( "myLibPath = " + myLibPath );
#ifdef TESTPROVIDERLIB
const char *cOgrLib = ( const char * ) myLibPath;
// test code to help debug provider loading problems
// void *handle = dlopen(cOgrLib, RTLD_LAZY);
void *handle = dlopen( cOgrLib, RTLD_LAZY | RTLD_GLOBAL );
if ( !handle )
{
QgsLogger::warning( "Error in dlopen: " );
}
else
{
QgsDebugMsg( "dlopen suceeded" );
dlclose( handle );
}
#endif
// load the data provider
QLibrary* myLib = new QLibrary( myLibPath );
QgsDebugMsg( "Library name is " + myLib->fileName() );
bool loaded = myLib->load();
if ( !loaded )
{
QgsMessageLog::logMessage( tr( "Failed to load provider %1 (Reason: %2)" ).arg( myLib->fileName() ).arg( myLib->errorString() ), tr( "Raster" ) );
return NULL;
}
QgsDebugMsg( "Loaded data provider library" );
return myLib;
}
// This code should be shared also by vector layer -> move it to QgsMapLayer
QgsRasterDataProvider* QgsRasterLayer::loadProvider( QString theProviderKey, QString theDataSource )
{
QgsDebugMsg( "Entered" );
QLibrary* myLib = QgsRasterLayer::loadProviderLibrary( theProviderKey );
QgsDebugMsg( "Library loaded" );
if ( !myLib )
{
QgsDebugMsg( "myLib is NULL" );
return NULL;
}
QgsDebugMsg( "Attempting to resolve the classFactory function" );
classFactoryFunction_t * classFactory = ( classFactoryFunction_t * ) cast_to_fptr( myLib->resolve( "classFactory" ) );
if ( !classFactory )
{
QgsMessageLog::logMessage( tr( "Cannot resolve the classFactory function" ), tr( "Raster" ) );
return NULL;
}
QgsDebugMsg( "Getting pointer to a mDataProvider object from the library" );
//XXX - This was a dynamic cast but that kills the Windows
// version big-time with an abnormal termination error
// mDataProvider = (QgsRasterDataProvider*)(classFactory((const
// char*)(dataSource.utf8())));
// Copied from qgsproviderregistry in preference to the above.
QgsRasterDataProvider* myDataProvider = ( QgsRasterDataProvider* )( *classFactory )( &theDataSource );
if ( !myDataProvider )
{
QgsMessageLog::logMessage( tr( "Cannot instantiate the data provider" ), tr( "Raster" ) );
return NULL;
}
QgsDebugMsg( "Data driver created" );
return myDataProvider;
}
/** Copied from QgsVectorLayer::setDataProvider
* TODO: Make it work in the raster environment
*/
void QgsRasterLayer::setDataProvider( QString const & provider )
{
QgsDebugMsg( "Entered" );
mValid = false; // assume the layer is invalid until we determine otherwise
mPipe.remove( mDataProvider ); // deletes if exists
mDataProvider = 0;
// XXX should I check for and possibly delete any pre-existing providers?
// XXX How often will that scenario occur?
mProviderKey = provider;
mValid = false; // assume the layer is invalid until we determine otherwise
// set the layer name (uppercase first character)
if ( ! mLayerName.isEmpty() ) // XXX shouldn't this happen in parent?
{
@ -1685,13 +1597,19 @@ void QgsRasterLayer::setDataProvider( QString const & provider )
mBandCount = 0;
mDataProvider = QgsRasterLayer::loadProvider( mProviderKey, mDataSource );
mDataProvider = ( QgsRasterDataProvider* )QgsProviderRegistry::instance()->provider( mProviderKey, mDataSource );
if ( !mDataProvider )
{
//QgsMessageLog::logMessage( tr( "Cannot instantiate the data provider" ), tr( "Raster" ) );
appendError( ERR( tr( "Cannot instantiate the '%1' data provider" ).arg( mProviderKey ) ) );
return;
}
QgsDebugMsg( "Data provider created" );
if ( !mDataProvider->isValid() )
{
setError( mDataProvider->error() );
appendError( ERR( tr( "Provider is not valid (provider: %1, URI: %2" ).arg( mProviderKey ).arg( mDataSource ) ) );
return;
}
mPipe.set( mDataProvider );
@ -2619,7 +2537,7 @@ bool QgsRasterLayer::readXml( const QDomNode& layer_node )
}
setDataProvider( mProviderKey );
if ( !mValid ) return false;
QString theError;
bool res = readSymbology( layer_node, theError );
@ -2644,6 +2562,7 @@ bool QgsRasterLayer::readXml( const QDomNode& layer_node )
closeDataProvider();
init();
setDataProvider( mProviderKey );
if ( !mValid ) return false;
}
}

View File

@ -309,10 +309,6 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
/** [ data provider interface ] Set the data provider */
void setDataProvider( const QString & provider );
static QLibrary* loadProviderLibrary( QString theProviderKey );
static QgsRasterDataProvider* loadProvider( QString theProviderKey, QString theDataSource = 0 );
/** \brief Accessor for blue band name mapping */
QString blueBandName() const { return mBlueBandName; }

View File

@ -56,6 +56,7 @@ qgsdetaileditemwidget.cpp
qgsdetaileditemdata.cpp
qgsdialog.cpp
qgsencodingfiledialog.cpp
qgserrordialog.cpp
qgsfiledropedit.cpp
qgsfieldvalidator.cpp
qgsformannotationitem.cpp
@ -155,6 +156,7 @@ qgsdialog.h
qgslegendinterface.h
qgisinterface.h
qgsencodingfiledialog.h
qgserrordialog.h
qgsfieldvalidator.h
qgsformannotationitem.h
qgshtmlannotationitem.h

View File

@ -0,0 +1,79 @@
/***************************************************************************
qgserrordialog.cpp - error description
-------------------
begin : October 2012
copyright : (C) October 2012 Radim Blazek
email : radim dot blazek at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgserrordialog.h"
#include <QMessageBox>
#include <QSettings>
QgsErrorDialog::QgsErrorDialog( const QgsError & theError, const QString & theTitle, QWidget *parent, Qt::WFlags fl )
: QDialog( parent, fl )
, mError( theError )
{
setupUi( this );
QString title = theTitle;
if ( title.isEmpty() ) title = tr("Error");
setWindowTitle( title );
// QMessageBox has static standardIcon( Icon icon ), but it is marked as obsolete
QMessageBox messageBox( QMessageBox::Critical, "", "" );
mIconLabel->setPixmap( messageBox.iconPixmap() );
mSummaryTextBrowser->setOpenExternalLinks ( true );
mDetailTextBrowser->setOpenExternalLinks ( true );
mDetailTextBrowser->hide();
QPalette p = palette();
p.setColor(QPalette::Base, Qt::transparent);
mSummaryTextBrowser->setPalette(p);
mDetailCheckBox->hide();
mSummaryTextBrowser->setText ( mError.summary() );
mDetailTextBrowser->setText( mError.message( QgsErrorMessage::Html ) );
resize( width(), 150);
QSettings settings;
Qt::CheckState state = (Qt::CheckState) settings.value( "/Error/dialog/detail", 0 ).toInt();
mDetailCheckBox->setCheckState( state );
if ( state == Qt::Checked ) on_mDetailPushButton_clicked();
}
QgsErrorDialog::~QgsErrorDialog()
{
}
void QgsErrorDialog::show ( const QgsError & theError, const QString & theTitle, QWidget *parent, Qt::WFlags fl )
{
QgsErrorDialog d( theError, theTitle, parent, fl );
d.exec();
}
void QgsErrorDialog::on_mDetailPushButton_clicked()
{
mSummaryTextBrowser->hide();
mDetailTextBrowser->show();
mDetailCheckBox->show();
mDetailPushButton->hide();
resize( width(), 400);
}
void QgsErrorDialog::on_mDetailCheckBox_stateChanged ( int state )
{
QSettings settings;
settings.setValue( "/Error/dialog/detail", state );
}

46
src/gui/qgserrordialog.h Normal file
View File

@ -0,0 +1,46 @@
/***************************************************************************
qgserrordialog.h - error dialog
-------------------
begin : October 2012
copyright : (C) October 2012 Radim Blazek
email : radim dot blazek at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSERRORDIALOG_H
#define QGSERRORDIALOG_H
#include <QDialog>
#include "ui_qgserrordialogbase.h"
#include "qgisgui.h"
#include "qgserror.h"
class GUI_EXPORT QgsErrorDialog: public QDialog, private Ui::QgsErrorDialogBase
{
Q_OBJECT
public:
QgsErrorDialog( const QgsError & theError, const QString & theTitle, QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags );
~QgsErrorDialog();
/** Show dialog with error
* @param theError error
*/
static void show ( const QgsError & theError, const QString & theTitle, QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags );
public slots:
void on_mDetailPushButton_clicked();
void on_mDetailCheckBox_stateChanged ( int state );
private:
QgsError mError;
};
#endif

View File

@ -52,6 +52,7 @@
#include "cpl_conv.h"
#include "cpl_string.h"
#define ERR(message) QGS_ERROR_MESSAGE(message,"GDAL provider")
static QString PROVIDER_KEY = "gdal";
static QString PROVIDER_DESCRIPTION = "GDAL provider";
@ -134,8 +135,7 @@ QgsGdalProvider::QgsGdalProvider( QString const & uri )
if ( !mGdalBaseDataset )
{
QString msg = QString( "Cannot open GDAL dataset %1:\n%2" ).arg( dataSourceUri() ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
QgsDebugMsg( msg );
QgsMessageLog::logMessage( msg );
appendError( ERR( msg ) );
return;
}
@ -538,7 +538,6 @@ void QgsGdalProvider::readBlock( int theBandNo, QgsRectangle const & theExtent,
if ( err != CPLE_None )
{
QgsLogger::warning( "RasterIO error: " + QString::fromUtf8( CPLGetLastErrorMsg() ) );
QgsDebugMsg( "RasterIO error: " + QString::fromUtf8( CPLGetLastErrorMsg() ) );
QgsFree( tmpBlock );
return;
}
@ -2223,8 +2222,7 @@ void QgsGdalProvider::initBaseDataset()
// if there are no subdatasets, then close the dataset
if ( mSubLayers.size() == 0 )
{
QMessageBox::warning( 0, QObject::tr( "Warning" ),
QObject::tr( "Cannot get GDAL raster band: %1" ).arg( msg ) );
appendError( ERR( tr( "Cannot get GDAL raster band: %1" ).arg( msg ) ) );
GDALDereferenceDataset( mGdalBaseDataset );
mGdalBaseDataset = NULL;

View File

@ -186,16 +186,6 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase
*/
QString metadata();
// Following methods specific for WMS are not used at all in this provider and should be removed IMO from qgsdataprovider.h
void addLayers( QStringList const &layers, QStringList const &styles = QStringList() )
{ Q_UNUSED( layers ); Q_UNUSED( styles ); }
QStringList supportedImageEncodings() { return QStringList(); }
QString imageEncoding() const { return QString(); }
void setImageEncoding( QString const &mimeType )
{ Q_UNUSED( mimeType ); }
void setImageCrs( QString const &crs )
{ Q_UNUSED( crs ); }
/** \brief Returns the sublayers of this layer - Useful for providers that manage their own layers, such as WMS */
QStringList subLayers() const;
static QStringList subLayers( GDALDatasetH dataset );

View File

@ -38,27 +38,32 @@
#include <QFile>
#include <QHash>
#define ERR(message) QGS_ERROR_MESSAGE(message,"GRASS provider")
static QString PROVIDER_KEY = "grassraster";
static QString PROVIDER_DESCRIPTION = "GRASS raster provider";
QgsGrassRasterProvider::QgsGrassRasterProvider( QString const & uri )
: QgsRasterDataProvider( uri ), mValid( true )
: QgsRasterDataProvider( uri ), mValid( false )
{
QgsDebugMsg( "QgsGrassRasterProvider: constructing with uri '" + uri + "'." );
mValid = false;
// Parse URI, it is the same like using GDAL, i.e. path to raster cellhd, i.e.
// /path/to/gisdbase/location/mapset/cellhd/map
QFileInfo fileInfo( uri );
mValid = fileInfo.exists(); // then we keep it valid forever
if ( !fileInfo.exists() ) // then we keep it valid forever
{
appendError( ERR( tr( "cellhd file %1 does not exist" ).arg( uri ) ) );
return;
}
mMapName = fileInfo.fileName();
QDir dir = fileInfo.dir();
QString element = dir.dirName();
if ( element != "cellhd" )
{
QMessageBox::warning( 0, QObject::tr( "Warning" ),
QObject::tr( "Groups not yet supported" ) + " (GRASS " + uri + ")" );
mValid = false;
appendError( ERR( tr( "Groups not yet supported" ) ) );
return;
}
dir.cdUp(); // skip cellhd
@ -133,6 +138,7 @@ QgsGrassRasterProvider::QgsGrassRasterProvider( QString const & uri )
{
mYBlockSize = mRows;
}
mValid = true;
QgsDebugMsg( "mYBlockSize = " + QString::number( mYBlockSize ) );
}
@ -398,10 +404,13 @@ QgsCoordinateReferenceSystem QgsGrassRasterProvider::crs()
QgsRectangle QgsGrassRasterProvider::extent()
{
QgsDebugMsg( "Entered" );
// The extend can change of course so we get always fresh, to avoid running always the module
// we should save mExtent and mLastModified and check if the map was modified
mExtent = QgsGrass::extent( mGisdbase, mLocation, mMapset, mMapName, QgsGrass::Raster );
QgsDebugMsg( "Extent got" );
return mExtent;
}

View File

@ -207,16 +207,6 @@ class QgsGrassRasterProvider : public QgsRasterDataProvider
*/
QString metadata();
// Following methods specific for are not used at all in this provider and should be removed IMO from qgsdataprovider.h
void addLayers( QStringList const &layers, QStringList const &styles = QStringList() )
{ Q_UNUSED( layers ); Q_UNUSED( styles ); }
QStringList supportedImageEncodings() { return QStringList();}
QString imageEncoding() const { return QString(); }
void setImageEncoding( QString const &mimeType )
{ Q_UNUSED( mimeType ); }
void setImageCrs( QString const &crs )
{ Q_UNUSED( crs ); }
virtual QDateTime dataTimestamp() const;
private:

View File

@ -60,6 +60,9 @@
#include "cpl_conv.h"
#include "cpl_string.h"
#define ERR(message) QGS_ERROR_MESSAGE(message,"WCS provider")
#define SRVERR(message) QGS_ERROR_MESSAGE(message,"WCS server")
static QString WCS_KEY = "wcs";
static QString WCS_DESCRIPTION = "OGC Web Coverage Service version 1.0/1.1 data provider";
@ -117,7 +120,7 @@ QgsWcsProvider::QgsWcsProvider( QString const &uri )
// 1.0 get additional coverage info
if ( !mCapabilities.describeCoverage( mIdentifier ) )
{
QgsMessageLog::logMessage( tr( "Cannot describe coverage" ), tr( "WCS" ) );
appendError( ERR( tr( "Cannot describe coverage" ) ) );
return;
}
@ -125,7 +128,7 @@ QgsWcsProvider::QgsWcsProvider( QString const &uri )
if ( !mCoverageSummary.valid )
{
// Should not happen if describeCoverage() did not fail
QgsMessageLog::logMessage( tr( "Coverage not found" ), tr( "WCS" ) );
appendError( ERR( tr( "Coverage not found" ) ) );
return;
}
@ -182,7 +185,7 @@ QgsWcsProvider::QgsWcsProvider( QString const &uri )
if ( !calculateExtent() )
{
QgsMessageLog::logMessage( tr( "Cannot calculate extent" ), tr( "WCS" ) );
appendError( ERR( tr( "Cannot calculate extent" ) ) );
return;
}
@ -239,7 +242,8 @@ QgsWcsProvider::QgsWcsProvider( QString const &uri )
if ( !mCachedGdalDataset )
{
QgsMessageLog::logMessage( tr( "Cannot get test dataset." ), tr( "WCS" ) );
setError( mCachedError );
appendError( ERR( tr( "Cannot get test dataset." ) ) );
return;
}
@ -871,9 +875,9 @@ void QgsWcsProvider::cacheReplyFinished()
contentType.startsWith( "application/vnd.ogc.se_xml", Qt::CaseInsensitive ) )
&& parseServiceExceptionReportDom( text ) )
{
QgsMessageLog::logMessage( tr( "Map request error (Title:%1; Error:%2; URL: %3)" )
.arg( mErrorCaption ).arg( mError )
.arg( mCacheReply->url().toString() ), tr( "WCS" ) );
mCachedError.append( SRVERR( tr( "Map request error:<br>Title: %1<br>Error: %2<br>URL: <a href='%3'>%3</a>)" )
.arg( mErrorCaption ).arg( mError )
.arg( mCacheReply->url().toString() ) ) );
}
else
{
@ -1186,6 +1190,7 @@ void QgsWcsProvider::clearCache()
}
QgsDebugMsg( "Clear mCachedData" );
mCachedData.clear();
mCachedError.clear();
QgsDebugMsg( "Cleared" );
}
@ -1456,6 +1461,7 @@ bool QgsWcsProvider::calculateExtent()
else
{
QgsDebugMsg( "Cannot get cache to verify extent" );
setError( mCachedError );
return false;
}

View File

@ -22,6 +22,7 @@
#ifndef QGSWCSPROVIDER_H
#define QGSWCSPROVIDER_H
#include "qgserror.h"
#include "qgswcscapabilities.h"
#include "qgsrasterdataprovider.h"
#include "qgsgdalproviderbase.h"
@ -162,13 +163,6 @@ class QgsWcsProvider : public QgsRasterDataProvider, QgsGdalProviderBase
void reloadData();
QList<QgsColorRampShader::ColorRampItem> colorTable( int bandNo )const;
// WMS specific, maybe to be removed from QgsRasterDataProvider
void addLayers( QStringList const &layers, QStringList const &styles = QStringList() ) { Q_UNUSED( layers ); Q_UNUSED( styles ); }
QStringList supportedImageEncodings() { return QStringList(); }
QString imageEncoding() const { return QString(); }
void setImageEncoding( QString const &mimeType ) { Q_UNUSED( mimeType ); }
void setImageCrs( QString const &crs ) { Q_UNUSED( crs ); }
static QMap<QString, QString> supportedMimes();
signals:
@ -348,16 +342,8 @@ class QgsWcsProvider : public QgsRasterDataProvider, QgsGdalProviderBase
/** Pointer to cached GDAL dataset */
GDALDatasetH mCachedGdalDataset;
/** \brief Values for mapping pixel to world coordinates. Contents of this array are the same as the GDAL adfGeoTransform */
//double mGeoTransform[6];
/**
* The previously retrieved image from the WCS server.
* This can be reused if draw() is called consecutively
* with the same parameters.
*/
//QImage *mCachedImage;
/** Current cache error last getCache() error. */
QgsError mCachedError;
/** The previous parameters to draw(). */
QgsRectangle mCachedViewExtent;

View File

@ -61,6 +61,9 @@
#include <QDir>
#endif
#define ERR(message) QGS_ERROR_MESSAGE(message,"WMS provider")
#define SRVERR(message) QGS_ERROR_MESSAGE(message,"WMS server")
static QString WMS_KEY = "wms";
static QString WMS_DESCRIPTION = "OGC Web Map Service version 1.3 data provider";
@ -93,13 +96,22 @@ QgsWmsProvider::QgsWmsProvider( QString const &uri )
{
QgsDebugMsg( "constructing with uri '" + mHttpUri + "'." );
// assume this is a valid layer until we determine otherwise
mValid = true;
mValid = false;
// URL may contain username/password information for a WMS
// requiring authentication. In this case the URL is prefixed
// with username=user,password=pass,url=http://xxx.xxx.xx/yyy...
parseUri( uri );
if ( !parseUri( uri ) )
{
appendError( ERR( tr( "Cannot parse URI" ) ) );
return;
}
if ( !calculateExtent() || mLayerExtent.isEmpty() )
{
appendError( ERR( tr( "Cannot calculate extent" ) ) );
return;
}
// URL can be in 3 forms:
// 1) http://xxx.xxx.xx/yyy/yyy
@ -109,12 +121,12 @@ QgsWmsProvider::QgsWmsProvider( QString const &uri )
mSupportedGetFeatureFormats = QStringList() << "text/html" << "text/plain" << "text/xml";
mValid = true;
QgsDebugMsg( "exiting constructor." );
}
void QgsWmsProvider::parseUri( QString uriString )
bool QgsWmsProvider::parseUri( QString uriString )
{
QgsDebugMsg( "uriString = " + uriString );
QgsDataSourceURI uri;
uri.setEncodedUri( uriString );
@ -181,11 +193,16 @@ void QgsWmsProvider::parseUri( QString uriString )
}
// setImageCrs is using mTiled !!!
setImageCrs( uri.param( "crs" ) );
if ( !setImageCrs( uri.param( "crs" ) ) )
{
appendError( ERR( tr( "Cannot set CRS" ) ) );
return false;
}
mCrs.createFromOgcWmsCrs( uri.param( "crs" ) );
mFeatureCount = uri.param( "featureCount" ).toInt(); // default to 0
return true;
}
QString QgsWmsProvider::prepareUri( QString uri ) const
@ -398,7 +415,7 @@ void QgsWmsProvider::setImageEncoding( QString const & mimeType )
}
void QgsWmsProvider::setImageCrs( QString const & crs )
bool QgsWmsProvider::setImageCrs( QString const & crs )
{
QgsDebugMsg( "Setting image CRS to " + crs + "." );
@ -420,17 +437,20 @@ void QgsWmsProvider::setImageCrs( QString const & crs )
{
if ( mActiveSubLayers.size() != 1 )
{
QgsDebugMsg( "Number of tile layers must be one" );
mValid = false;
return;
appendError( ERR( tr( "Number of tile layers must be one" ) ) );
return false;
}
mValid = retrieveServerCapabilities();
QgsDebugMsg( QString( "mValid = %1 mTileLayersSupported.size() = %2" ).arg( mValid ).arg( mTileLayersSupported.size() ) );
if ( !mValid || mTileLayersSupported.size() == 0 )
if ( !retrieveServerCapabilities() )
{
QgsDebugMsg( "Tile layer not found" );
return;
// Error set in retrieveServerCapabilities()
return false;
}
QgsDebugMsg( QString( "mTileLayersSupported.size() = %1" ).arg( mTileLayersSupported.size() ) );
if ( mTileLayersSupported.size() == 0 )
{
appendError( ERR( tr( "Tile layer not found" ) ) );
return false;
}
for ( int i = 0; i < mTileLayersSupported.size(); i++ )
@ -483,8 +503,13 @@ void QgsWmsProvider::setImageCrs( QString const & crs )
setProperty( "resolutions", resolutions );
mValid = mTileLayer != 0 && mTileMatrixSet != 0;
if ( mTileLayer == 0 && mTileMatrixSet == 0 )
{
appendError( ERR( tr( "Tile layer or tile matrix set not found" ) ) );
return false;
}
}
return true;
}
void QgsWmsProvider::setQueryItem( QUrl &url, QString item, QString value )
@ -3120,6 +3145,13 @@ bool QgsWmsProvider::calculateExtent()
{
QgsDebugMsg( "Sublayer Iterator: " + *it );
// This is the extent for the layer name in *it
if ( !mExtentForLayer.contains( *it ) )
{
mLayerExtent = QgsRectangle();
appendError( ERR( tr( "Extent for layer %1 not found in capabilities" ).arg( *it ) ) );
return false;
}
QgsRectangle extent = mExtentForLayer.find( *it ).value();
// Convert to the user's CRS as required
@ -3159,6 +3191,7 @@ bool QgsWmsProvider::calculateExtent()
QgsDebugMsg( "exiting with '" + mLayerExtent.toString() + "'." );
return true;
}
return false; // should not be reached
}

View File

@ -542,7 +542,7 @@ class QgsWmsProvider : public QgsRasterDataProvider
*
* \note an empty crs value will result in the previous CRS being retained.
*/
void setImageCrs( QString const & crs );
bool setImageCrs( QString const & crs );
/**
* Set the name of the connection for use in authentication where required
@ -846,7 +846,7 @@ class QgsWmsProvider : public QgsRasterDataProvider
* \note added in 1.1
*/
void parseUri( QString uri );
bool parseUri( QString uri );
/**
* \brief Prepare the URI so that we can later simply append param=value

View File

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsErrorDialogBase</class>
<widget class="QDialog" name="QgsErrorDialogBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>580</width>
<height>208</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="mIconLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>../../images/themes/default/mIconWarn.png</pixmap>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTextBrowser" name="mSummaryTextBrowser">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Summary&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QTextBrowser" name="mDetailTextBrowser">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Detailed report.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="mDetailCheckBox">
<property name="text">
<string>Always show details</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="mDetailPushButton">
<property name="text">
<string>Details &gt;&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QgsErrorDialogBase</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsErrorDialogBase</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>