Skip to content

Commit e210a57

Browse files
committed
QgsError for better error propagation to user, started using for rasters
1 parent b78456f commit e210a57

27 files changed

+732
-254
lines changed

CMakeLists.txt

+17
Original file line numberDiff line numberDiff line change
@@ -559,9 +559,26 @@ IF (GIT_MARKER)
559559
COMMAND ${GITCOMMAND} log -n1 --pretty=%h OUTPUT_VARIABLE REVISION
560560
)
561561
STRING(STRIP "${REVISION}" REVISION)
562+
# Get GIT remote and branch
563+
EXECUTE_PROCESS(
564+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
565+
COMMAND ${GITCOMMAND} name-rev --name-only HEAD OUTPUT_VARIABLE GIT_LOCAL_BRANCH
566+
)
567+
STRING(STRIP "${GIT_LOCAL_BRANCH}" GIT_LOCAL_BRANCH)
568+
EXECUTE_PROCESS(
569+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
570+
COMMAND ${GITCOMMAND} config branch.${GIT_LOCAL_BRANCH}.remote OUTPUT_VARIABLE GIT_REMOTE
571+
)
572+
STRING(STRIP "${GIT_REMOTE}" GIT_REMOTE)
573+
EXECUTE_PROCESS(
574+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
575+
COMMAND ${GITCOMMAND} config remote.${GIT_REMOTE}.url OUTPUT_VARIABLE GIT_REMOTE_URL
576+
)
577+
STRING(STRIP "${GIT_REMOTE_URL}" GIT_REMOTE_URL)
562578
ADD_CUSTOM_COMMAND(
563579
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/qgsversion.h
564580
COMMAND echo \\\#define QGSVERSION \\\"${REVISION}\\\" >${CMAKE_CURRENT_BINARY_DIR}/qgsversion.h
581+
COMMAND echo \\\#define QGS_GIT_REMOTE_URL \\\"${GIT_REMOTE_URL}\\\" >>${CMAKE_CURRENT_BINARY_DIR}/qgsversion.h
565582
MAIN_DEPENDENCY ${GIT_MARKER}
566583
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
567584
)

python/core/raster/qgsrasterdataprovider.sip

-25
Original file line numberDiff line numberDiff line change
@@ -99,31 +99,6 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
9999
/* It makes no sense to set input on provider */
100100
bool setInput( QgsRasterInterface* input );
101101

102-
/**
103-
* Add the list of WMS layer names to be rendered by this server
104-
*/
105-
virtual void addLayers( const QStringList & layers,
106-
const QStringList & styles = QStringList() ) = 0;
107-
108-
//! get raster image encodings supported by (e.g.) the WMS Server, expressed as MIME types
109-
virtual QStringList supportedImageEncodings() = 0;
110-
111-
/**
112-
* Get the image encoding (as a MIME type) used in the transfer from (e.g.) the WMS server
113-
*/
114-
virtual QString imageEncoding() const = 0;
115-
116-
/**
117-
* Set the image encoding (as a MIME type) used in the transfer from (e.g.) the WMS server
118-
*/
119-
virtual void setImageEncoding( const QString & mimeType ) = 0;
120-
121-
/**
122-
* Set the image projection (in WMS CRS format) used in the transfer from (e.g.) the WMS server
123-
*/
124-
virtual void setImageCrs( const QString & crs ) = 0;
125-
126-
127102
// TODO: Document this better.
128103
/** \brief Renders the layer as an image
129104
*/

python/core/raster/qgsrasterlayer.sip

-4
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,6 @@ class QgsRasterLayer : QgsMapLayer
147147
/** [ data provider interface ] Set the data provider */
148148
void setDataProvider( const QString & provider );
149149

150-
static QLibrary* loadProviderLibrary( QString theProviderKey );
151-
static QgsRasterDataProvider* loadProvider( QString theProviderKey, QString theDataSource = 0 );
152-
153-
154150
/** \brief Accessor for blue band name mapping */
155151
QString blueBandName() const;
156152

src/app/qgisapp.cpp

+37-16
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@
120120
#include "qgsdecorationscalebar.h"
121121
#include "qgsdecorationgrid.h"
122122
#include "qgsencodingfiledialog.h"
123+
#include "qgserror.h"
124+
#include "qgserrordialog.h"
123125
#include "qgsexception.h"
124126
#include "qgsfeature.h"
125127
#include "qgsformannotationitem.h"
@@ -7294,6 +7296,14 @@ QgsRasterLayer* QgisApp::addRasterLayer( QString const & rasterFile, QString con
72947296
QgsRasterLayer *layer =
72957297
new QgsRasterLayer( rasterFile, baseName ); // fi.completeBaseName());
72967298

7299+
if ( !layer->isValid() )
7300+
{
7301+
//QMessageBox::critical( this, tr( "Invalid Layer" ), layer->error().message() );
7302+
QgsErrorDialog::show( layer->error(), tr( "Invalid Layer" ) );
7303+
delete layer;
7304+
return NULL;
7305+
}
7306+
72977307
bool ok = false;
72987308

72997309
if ( shouldAskUserForGDALSublayers( layer ) )
@@ -7377,16 +7387,15 @@ QgsRasterLayer* QgisApp::addRasterLayer(
73777387

73787388
QgsDebugMsg( "Constructed new layer." );
73797389

7380-
if ( layer && layer->isValid() )
7390+
if ( layer->isValid() )
73817391
{
73827392
addRasterLayer( layer );
73837393

73847394
statusBar()->showMessage( mMapCanvas->extent().toString( 2 ) );
73857395
}
73867396
else
73877397
{
7388-
QMessageBox::critical( this, tr( "Layer is not valid" ),
7389-
tr( "The layer is not a valid layer and can not be added to the map" ) );
7398+
QgsErrorDialog::show( layer->error(), tr( "Invalid Layer" ) );
73907399
}
73917400

73927401
// update UI
@@ -7454,25 +7463,37 @@ bool QgisApp::addRasterLayers( QStringList const &theFileNameQStringList, bool g
74547463
// create the layer
74557464
QgsRasterLayer *layer = new QgsRasterLayer( *myIterator, myBaseNameQString );
74567465

7457-
if ( shouldAskUserForGDALSublayers( layer ) )
7466+
if ( !layer->isValid() )
74587467
{
7459-
askUserForGDALSublayers( layer );
7460-
7461-
// The first layer loaded is not useful in that case. The user can select it in
7462-
// the list if he wants to load it.
7463-
delete layer;
7468+
returnValue = false;
7469+
if ( guiWarning )
7470+
{
7471+
QgsErrorDialog::show( layer->error(), tr( "Invalid Layer" ) );
7472+
delete layer;
7473+
}
74647474
}
74657475
else
74667476
{
7467-
addRasterLayer( layer );
7468-
7469-
//only allow one copy of a ai grid file to be loaded at a
7470-
//time to prevent the user selecting all adfs in 1 dir which
7471-
//actually represent 1 coverate,
7477+
if ( shouldAskUserForGDALSublayers( layer ) )
7478+
{
7479+
askUserForGDALSublayers( layer );
74727480

7473-
if ( myBaseNameQString.toLower().endsWith( ".adf" ) )
7481+
// The first layer loaded is not useful in that case. The user can select it in
7482+
// the list if he wants to load it.
7483+
delete layer;
7484+
}
7485+
else
74747486
{
7475-
break;
7487+
addRasterLayer( layer );
7488+
7489+
//only allow one copy of a ai grid file to be loaded at a
7490+
//time to prevent the user selecting all adfs in 1 dir which
7491+
//actually represent 1 coverate,
7492+
7493+
if ( myBaseNameQString.toLower().endsWith( ".adf" ) )
7494+
{
7495+
break;
7496+
}
74767497
}
74777498
}
74787499
} // valid raster filename

src/core/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ SET(QGIS_CORE_SRCS
6363
qgsdbfilterproxymodel.cpp
6464
qgsdiagramrendererv2.cpp
6565
qgsdistancearea.cpp
66+
qgserror.cpp
6667
qgsexpression.cpp
6768
qgsfeature.cpp
6869
qgsfield.cpp
@@ -350,6 +351,7 @@ SET(QGIS_CORE_HDRS
350351
qgsdataitem.h
351352
qgsdistancearea.h
352353
qgscsexception.h
354+
qgserror.h
353355
qgsexception.h
354356
qgsexpression.h
355357
qgsfeature.h

src/core/qgsdataprovider.h

+17
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <QStringList>
2323

2424
//#include "qgsdataitem.h"
25+
#include "qgserror.h"
2526

2627
class QgsRectangle;
2728
class QgsCoordinateReferenceSystem;
@@ -290,6 +291,12 @@ class CORE_EXPORT QgsDataProvider : public QObject
290291
/** Current time stamp of data source */
291292
virtual QDateTime dataTimestamp() const { return QDateTime(); }
292293

294+
/** Get current status error. This error describes some principal problem
295+
* for which provider cannot work and thus is not valid. It is not last error
296+
* after accessing data by block(), identify() etc.
297+
*/
298+
virtual QgsError error() const { return mError; }
299+
293300
signals:
294301

295302
/**
@@ -318,6 +325,16 @@ class CORE_EXPORT QgsDataProvider : public QObject
318325
* Timestamp of data in the moment when the data were loaded by provider.
319326
*/
320327
QDateTime mTimestamp;
328+
329+
/** \brief Error */
330+
QgsError mError;
331+
332+
/** Add error message */
333+
void appendError( const QgsErrorMessage & theMessage ) { mError.append( theMessage );}
334+
335+
/** Set error message */
336+
void setError( const QgsError & theError ) { mError = theError;}
337+
321338
private:
322339

323340
/**

src/core/qgserror.cpp

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/***************************************************************************
2+
qgserror.cpp - Error container
3+
-------------------
4+
begin : October 2012
5+
copyright : (C) 2012 Radim Blazek
6+
email : radim dot blazek at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
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. *
15+
* *
16+
***************************************************************************/
17+
#include "qgis.h"
18+
#include "qgsversion.h"
19+
#include "qgsconfig.h"
20+
#include "qgserror.h"
21+
#include "qgslogger.h"
22+
23+
#include <QRegExp>
24+
25+
QgsErrorMessage::QgsErrorMessage ( const QString & theMessage, const QString & theTag, const QString & theFile, const QString & theFunction, int theLine )
26+
: mMessage(theMessage)
27+
, mTag(theTag)
28+
, mFile(theFile)
29+
, mFunction(theFunction)
30+
, mLine(theLine)
31+
, mFormat(Text)
32+
{
33+
}
34+
35+
QgsError::QgsError ( const QString & theMessage, const QString & theTag )
36+
{
37+
append ( theMessage, theTag );
38+
}
39+
40+
void QgsError::append ( const QString & theMessage, const QString & theTag )
41+
{
42+
mMessageList.append ( QgsErrorMessage ( theMessage, theTag ) );
43+
}
44+
45+
void QgsError::append ( const QgsErrorMessage & theMessage )
46+
{
47+
mMessageList.append ( theMessage );
48+
}
49+
50+
QString QgsError::message ( QgsErrorMessage::Format theFormat ) const
51+
{
52+
QString str;
53+
int sPrefixLength = strlen( CMAKE_SOURCE_DIR ) + 1;
54+
55+
QString srcUrl;
56+
#if defined(QGISDEBUG) && defined(QGS_GIT_REMOTE_URL)
57+
// TODO: verify if we are not ahead to origin (remote hash does not exist)
58+
// and there are no local not commited changes
59+
QString hash = QString(QGis::QGIS_DEV_VERSION);
60+
QString remote = QString(QGS_GIT_REMOTE_URL);
61+
QgsDebugMsg ("remote = " + remote );
62+
if ( !hash.isEmpty () && !remote.isEmpty() && remote.contains ( "github.com" ) )
63+
{
64+
QString path = remote.remove( QRegExp(".*github.com[:/]" )).remove(".git");
65+
srcUrl = "https://github.com/" + path + "/blob/" + hash;
66+
}
67+
#endif
68+
69+
foreach ( QgsErrorMessage m, mMessageList )
70+
{
71+
#ifdef QGISDEBUG
72+
QString file;
73+
#ifndef _MSC_VER
74+
file = m.file().mid(sPrefixLength);
75+
#else
76+
file = m.file();
77+
#endif
78+
#endif
79+
80+
if ( theFormat == QgsErrorMessage::Text )
81+
{
82+
str += m.tag() + " " + m.message();
83+
#ifdef QGISDEBUG
84+
str += QString( "\nat %1 : %2 : %3" ).arg( file ).arg( m.line() ).arg( m.function() );
85+
#endif
86+
}
87+
else // QgsErrorMessage::Html
88+
{
89+
str += "<p><b>" + m.tag() + ":</b> " + m.message();
90+
#ifdef QGISDEBUG
91+
QString location = QString( "%1 : %2 : %3" ).arg( file ).arg( m.line() ).arg( m.function() );
92+
if ( !srcUrl.isEmpty() )
93+
{
94+
QString url = QString("%1/%2#L%3").arg(srcUrl).arg(file).arg( m.line() );
95+
str += QString( "<br>(<a href='%1'>%2</a>)" ).arg(url).arg( location );
96+
}
97+
else
98+
{
99+
str += QString( "<br>(%1)" ).arg( location );
100+
}
101+
#endif
102+
}
103+
}
104+
return str;
105+
}
106+
107+
QString QgsError::summary ( ) const
108+
{
109+
// The first message in chain is usually the real error given by backend/server
110+
return mMessageList.first().message();
111+
}

0 commit comments

Comments
 (0)