82 changes: 41 additions & 41 deletions doc/TRANSLATORS

Large diffs are not rendered by default.

2,869 changes: 2,302 additions & 567 deletions i18n/qgis_de.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions images/images.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@
<file>themes/default/mIconLock.png</file>
<file>themes/default/mIconNew.png</file>
<file>themes/default/mIconMssql.png</file>
<file>themes/default/mIconOracle.png</file>
<file>themes/default/mIconNext.png</file>
<file>themes/default/mIconNoPyramid.png</file>
<file>themes/default/mIconOws.png</file>
Expand Down Expand Up @@ -433,10 +434,12 @@
<file>themes/gis/mIconRaster.png</file>
<file>themes/gis/mIconPostgis.png</file>
<file>themes/gis/mIconMssql.png</file>
<file>themes/gis/mIconOracle.png</file>
<file>themes/gis/mIconConnect.png</file>
<file>themes/gis/mIconDbSchema.png</file>
<file>themes/gis/mActionTouch.png</file>
<file>themes/default/mActionAddMssqlLayer.png</file>
<file>themes/default/mActionAddOracleLayer.png</file>
<file>themes/default/mActionTouch.png</file>
<file>themes/default/mActionTouch2.png</file>
<file>themes/classic/mActionTouch.png</file>
Expand Down
Binary file added images/themes/default/mActionAddOracleLayer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/themes/default/mIconOracle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/themes/gis/mIconOracle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions ms-windows/osgeo4w/package-nightly.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ cmake -G "Visual Studio 9 2008" ^
-D WITH_ASTYLE=TRUE ^
-D WITH_GLOBE=TRUE ^
-D WITH_TOUCH=TRUE ^
-D WITH_ORACLE=TRUE ^
-D CMAKE_CONFIGURATION_TYPES=%BUILDCONF% ^
-D GEOS_LIBRARY=%O4W_ROOT%/lib/geos_c_i.lib ^
-D SQLITE3_LIBRARY=%O4W_ROOT%/lib/sqlite3_i.lib ^
Expand Down Expand Up @@ -183,6 +184,7 @@ tar -C %OSGEO4W_ROOT% -cjf %PACKAGENAME%-%VERSION%-%PACKAGE%.tar.bz2 ^
bin/%PACKAGENAME%-browser.exe ^
bin/%PACKAGENAME%.bat.tmpl ^
bin/%PACKAGENAME%-browser.bat.tmpl ^
apps/qt4/plugins/sqldrivers/qsqlocispatial.dll ^
etc/postinstall/%PACKAGENAME%.bat ^
etc/preremove/%PACKAGENAME%.bat ^
>>%LOG% 2>&1
Expand Down
8 changes: 8 additions & 0 deletions ms-windows/osgeo4w/package.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ cmake -G "Visual Studio 9 2008" ^
-D WITH_MAPSERVER=TRUE ^
-D WITH_GLOBE=TRUE ^
-D WITH_TOUCH=TRUE ^
-D WITH_ORACLE=TRUE ^
-D CMAKE_BUILD_TYPE=%BUILDCONF% ^
-D CMAKE_CONFIGURATION_TYPES=%BUILDCONF% ^
-D GEOS_LIBRARY=%O4W_ROOT%/lib/geos_c_i.lib ^
Expand Down Expand Up @@ -281,6 +282,12 @@ tar -C %OSGEO4W_ROOT% -cjf %PACKAGENAME%-globe-plugin-%VERSION%-%PACKAGE%.tar.bz
>>%LOG% 2>&1
if errorlevel 1 goto error

tar -C %OSGEO4W_ROOT% -cjf %PACKAGENAME%-oracle-provider-%VERSION%-%PACKAGE%.tar.bz2 ^
"apps/%PACKAGENAME%/plugins/oracleprovider.dll" ^
apps/qt4/plugins/sqldrivers/qsqlocispatial.dll ^
>>%LOG% 2>&1
if errorlevel 1 goto error

tar -C %OSGEO4W_ROOT% -cjf %PACKAGENAME%-devel-%VERSION%-%PACKAGE%.tar.bz2 ^
--exclude-from exclude ^
--exclude "*.pyc" ^
Expand All @@ -301,6 +308,7 @@ if exist %PACKAGENAME%-server-%VERSION%-%PACKAGE%.tar.bz2 del %PACKAGENAME%-serv
if exist %PACKAGENAME%-devel-%VERSION%-%PACKAGE%.tar.bz2 del %PACKAGENAME%-devel-%VERSION%-%PACKAGE%.tar.bz2
if exist %PACKAGENAME%-grass-plugin-%VERSION%-%PACKAGE%.tar.bz2 del %PACKAGENAME%-grass-plugin-%VERSION%-%PACKAGE%.tar.bz2
if exist %PACKAGENAME%-globe-plugin-%VERSION%-%PACKAGE%.tar.bz2 del %PACKAGENAME%-globe-plugin-%VERSION%-%PACKAGE%.tar.bz2
if exist %PACKAGENAME%-oracle-provider-%VERSION%-%PACKAGE%.tar.bz2 del %PACKAGENAME%-oracle-provider-%VERSION%-%PACKAGE%.tar.bz2

:end
echo FINISHED: %DATE% %TIME% >>%LOG% 2>&1
11 changes: 10 additions & 1 deletion scripts/addcopyright.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,16 @@

set -e

for i in $(<files); do
if [ $# -gt 0 ]; then
FILES="$@"
elif [ -f files ]; then
FILES=$(<files)
else
echo no files
exit 1
fi

for i in $FILES; do
echo $i >&2
author=
authordate=
Expand Down
12 changes: 12 additions & 0 deletions scripts/licenses
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
: GPL \(v[23] or later\)$
: GPL \(v2 or later\) GENERATED FILE$
: \*No copyright\* LGPL \(v2\.1 or later\)$
: GPL LGPL$
: LGPL$
: Apache \(v2\.0\)$
: GPL \(v2\)$
: LGPL \(v2 or later\)$
: Apache \(v2.0\) GPL \(v2 or later\)$
: MIT\/X11 \(BSD like\)$
: MPL \(v1\.1\) GPL \(unversioned\/unknown version\)$
: LGPL \(v2\.1\)$
5 changes: 5 additions & 0 deletions scripts/prepare-commit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ if ! type -p colordiff >/dev/null; then
}
fi

if [ "$1" = "-c" ]; then
echo "Cleaning..."
find . \( -name "*.prepare" -o -name "*.astyle" -o -name "astyle.*.diff" -o -name "sha-*.diff" \) -print -delete
fi

set -e

# determine changed files
Expand Down
4 changes: 2 additions & 2 deletions src/app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ void myMessageOutput( QtMsgType type, const char *msg )
case QtFatalMsg:
{
fprintf( stderr, "Fatal: %s\n", msg );
#if defined(linux) && ! defined(ANDROID)
fprintf( stderr, "Stacktrace (run through c++filt):\n" );
#if defined(linux) && !defined(ANDROID)
write( STDERR_FILENO, "Stacktrace (run through c++filt):\n", 34 );
void *buffer[256];
int nptrs = backtrace( buffer, sizeof( buffer ) / sizeof( *buffer ) );
backtrace_symbols_fd( buffer, nptrs, STDERR_FILENO );
Expand Down
68 changes: 47 additions & 21 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,9 @@ void QgisApp::validateSrs( QgsCoordinateReferenceSystem &srs )
mySelector->setSelectedCrsId( defaultCrs.srsid() );
}

// why is this: it overrides the default cursor in the splitter in the dialog
// commenting it now till somebody tells us why it is necessary :-)
//QApplication::setOverrideCursor( Qt::ArrowCursor );
bool waiting = QApplication::overrideCursor()->shape() == Qt::WaitCursor;
if ( waiting )
QApplication::setOverrideCursor( Qt::ArrowCursor );

if ( mySelector->exec() )
{
Expand All @@ -393,7 +393,8 @@ void QgisApp::validateSrs( QgsCoordinateReferenceSystem &srs )
srs.createFromOgcWmsCrs( mySelector->selectedAuthId() );
}

//QApplication::restoreOverrideCursor();
if ( waiting )
QApplication::restoreOverrideCursor();

delete mySelector;
}
Expand Down Expand Up @@ -944,6 +945,7 @@ void QgisApp::createActions()
connect( mActionAddPgLayer, SIGNAL( triggered() ), this, SLOT( addDatabaseLayer() ) );
connect( mActionAddSpatiaLiteLayer, SIGNAL( triggered() ), this, SLOT( addSpatiaLiteLayer() ) );
connect( mActionAddMssqlLayer, SIGNAL( triggered() ), this, SLOT( addMssqlLayer() ) );
connect( mActionAddOracleLayer, SIGNAL( triggered() ), this, SLOT( addOracleLayer() ) );
connect( mActionAddWmsLayer, SIGNAL( triggered() ), this, SLOT( addWmsLayer() ) );
connect( mActionAddWcsLayer, SIGNAL( triggered() ), this, SLOT( addWcsLayer() ) );
connect( mActionAddWfsLayer, SIGNAL( triggered() ), this, SLOT( addWfsLayer() ) );
Expand Down Expand Up @@ -1047,19 +1049,24 @@ void QgisApp::createActions()

#ifndef HAVE_SPATIALITE
delete mActionNewSpatialiteLayer;
mActionNewSpatialiteLayer = NULL;
mActionNewSpatialiteLayer = 0;
delete mActionAddSpatiaLiteLayer;
mActionAddSpatiaLiteLayer = NULL;
mActionAddSpatiaLiteLayer = 0;
#endif

#ifndef HAVE_POSTGRESQL
delete mActionAddPgLayer;
mActionAddPgLayer = NULL;
mActionAddPgLayer = 0;
#endif

#ifndef HAVE_MSSQL
delete mActionAddMssqlLayer;
mActionAddMssqlLayer = NULL;
mActionAddMssqlLayer = 0;
#endif

#ifndef HAVE_ORACLE
delete mActionAddOracleLayer;
mActionAddOracleLayer = 0;
#endif

}
Expand Down Expand Up @@ -1645,6 +1652,9 @@ void QgisApp::setTheme( QString theThemeName )
#endif
#ifdef HAVE_MSSQL
mActionAddMssqlLayer->setIcon( QgsApplication::getThemeIcon( "/mActionAddMssqlLayer.png" ) );
#endif
#ifdef HAVE_ORACLE
mActionAddOracleLayer->setIcon( QgsApplication::getThemeIcon( "/mActionAddOracleLayer.png" ) );
#endif
mActionRemoveLayer->setIcon( QgsApplication::getThemeIcon( "/mActionRemoveLayer.png" ) );
mActionDuplicateLayer->setIcon( QgsApplication::getThemeIcon( "/mActionAddMap.png" ) );
Expand Down Expand Up @@ -2826,11 +2836,9 @@ void QgisApp::loadOGRSublayers( QString layertype, QString uri, QStringList list
}
}

#ifndef HAVE_POSTGRESQL
void QgisApp::addDatabaseLayer() {}
#else
void QgisApp::addDatabaseLayer()
{
#ifdef HAVE_POSTGRESQL
if ( mMapCanvas && mMapCanvas->isDrawing() )
{
return;
Expand All @@ -2849,8 +2857,8 @@ void QgisApp::addDatabaseLayer()
this , SLOT( addDatabaseLayers( QStringList const &, QString const & ) ) );
pgs->exec();
delete pgs;
} // QgisApp::addDatabaseLayer()
#endif
} // QgisApp::addDatabaseLayer()

void QgisApp::addDatabaseLayers( QStringList const & layerPathList, QString const & providerKey )
{
Expand Down Expand Up @@ -2919,11 +2927,9 @@ void QgisApp::addDatabaseLayers( QStringList const & layerPathList, QString cons
}


#ifndef HAVE_SPATIALITE
void QgisApp::addSpatiaLiteLayer() {}
#else
void QgisApp::addSpatiaLiteLayer()
{
#ifdef HAVE_SPATIALITE
if ( mMapCanvas && mMapCanvas->isDrawing() )
{
return;
Expand All @@ -2940,15 +2946,12 @@ void QgisApp::addSpatiaLiteLayer()
this , SLOT( addDatabaseLayers( QStringList const &, QString const & ) ) );
dbs->exec();
delete dbs;

} // QgisApp::addSpatiaLiteLayer()
#endif
} // QgisApp::addSpatiaLiteLayer()

#ifndef HAVE_MSSQL
void QgisApp::addMssqlLayer() {}
#else
void QgisApp::addMssqlLayer()
{
#ifdef HAVE_MSSQL
if ( mMapCanvas && mMapCanvas->isDrawing() )
{
return;
Expand All @@ -2965,9 +2968,30 @@ void QgisApp::addMssqlLayer()
this , SLOT( addDatabaseLayers( QStringList const &, QString const & ) ) );
dbs->exec();
delete dbs;

#endif
} // QgisApp::addMssqlLayer()

void QgisApp::addOracleLayer()
{
#ifdef HAVE_ORACLE
if ( mMapCanvas && mMapCanvas->isDrawing() )
{
return;
}

// show the Oracle dialog
QDialog *dbs = dynamic_cast<QDialog*>( QgsProviderRegistry::instance()->selectWidget( QString( "oracle" ), this ) );
if ( !dbs )
{
QMessageBox::warning( this, tr( "Oracle" ), tr( "Cannot get Oracle select dialog from provider." ) );
return;
}
connect( dbs , SIGNAL( addDatabaseLayers( QStringList const &, QString const & ) ),
this , SLOT( addDatabaseLayers( QStringList const &, QString const & ) ) );
dbs->exec();
delete dbs;
#endif
} // QgisApp::addOracleLayer()

void QgisApp::addWmsLayer()
{
Expand Down Expand Up @@ -7062,7 +7086,9 @@ void QgisApp::layersWereAdded( QList<QgsMapLayer *> theLayers )
QgsVectorDataProvider* vProvider = vlayer->dataProvider();
if ( vProvider && vProvider->capabilities() & QgsVectorDataProvider::EditingCapabilities )
{
#if 0
connect( vlayer, SIGNAL( layerModified( bool ) ), this, SLOT( updateLayerModifiedActions() ) );
#endif

This comment has been minimized.

Copy link
@dakcarto

dakcarto Jan 10, 2013

Member

Hi Juergen,

Negating the above connection keeps all of the new actions, for saving edits for the active layer and multiple layers, from being enabled/disabled. Right now, can not save any edits except on toggling off editing. Can you explain why negating it is necessary? Or, how we might be able to work around it for the Oracle provider? Thanks.

connect( vlayer, SIGNAL( editingStarted() ), this, SLOT( layerEditStateChanged() ) );
connect( vlayer, SIGNAL( editingStopped() ), this, SLOT( layerEditStateChanged() ) );
}
Expand Down
6 changes: 5 additions & 1 deletion src/app/qgisapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -594,9 +594,13 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
void addSpatiaLiteLayer();
//#endif
//#ifdef HAVE_MSSQL
//! Add a SpatiaLite layer to the map
//! Add a MSSQL layer to the map
void addMssqlLayer();
//#endif
//#ifdef HAVE_ORACLE
//! Add a Oracle layer to the map
void addOracleLayer();
//#endif
/** toggles whether the current selected layer is in overview or not */
void isInOverview();
//! Slot to show the map coordinate position of the mouse cursor
Expand Down
22 changes: 0 additions & 22 deletions src/core/qgis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,6 @@ const QString GEOPROJ4 = "+proj=longlat +datum=WGS84 +no_defs";
const QString GEOPROJ4 = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs";
#endif

const char* QGis::qgisVectorGeometryType[] =
{
"Point",
"Line",
"Polygon",
"Unknown geometry",
"No geometry",
};

// description strings for feature types
const char* QGis::qgisFeatureTypes[] =
{
"Null",
"WKBPoint",
"WKBLineString",
"WKBPolygon",
"WKBMultiPoint",
"WKBMultiLineString",
"WKBMultiPolygon"
};


const double QGis::DEFAULT_IDENTIFY_RADIUS = 0.5;

// description strings for units
Expand Down
89 changes: 70 additions & 19 deletions src/core/qgis.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,24 +67,47 @@ class CORE_EXPORT QGis
WKBMultiPolygon25D,
};

static WkbType singleType( WkbType type )
{
switch ( type )
{
case WKBMultiPoint: return WKBPoint;
case WKBMultiLineString: return WKBLineString;
case WKBMultiPolygon: return WKBPolygon;
case WKBMultiPoint25D: return WKBPoint25D;
case WKBMultiLineString25D: return WKBLineString25D;
case WKBMultiPolygon25D: return WKBPolygon25D;
default: return type;
}
}

static WkbType flatType( WkbType type )
{
switch ( type )
{
case WKBMultiPoint:
return WKBPoint;
case WKBMultiLineString:
return WKBLineString;
case WKBMultiPolygon:
return WKBPolygon;
case WKBMultiPoint25D:
return WKBPoint25D;
case WKBMultiLineString25D:
return WKBLineString25D;
case WKBMultiPolygon25D:
return WKBPolygon25D;
default:
return type;
case WKBPoint25D: return WKBPoint;
case WKBLineString25D: return WKBLineString;
case WKBPolygon25D: return WKBPolygon;
case WKBMultiPoint25D: return WKBMultiPoint;
case WKBMultiLineString25D: return WKBMultiLineString;
case WKBMultiPolygon25D: return WKBMultiPolygon;
default: return type;
}
}

static int wkbDimensions( WkbType type )
{
switch ( type )
{
case WKBUnknown: return 0;
case WKBNoGeometry: return 0;
case WKBPoint25D: return 3;
case WKBLineString25D: return 3;
case WKBPolygon25D: return 3;
case WKBMultiPoint25D: return 3;
case WKBMultiLineString25D: return 3;
case WKBMultiPolygon25D: return 3;
default: return 2;
}
}

Expand All @@ -97,13 +120,41 @@ class CORE_EXPORT QGis
NoGeometry
};

// String representation of geometry types (set in qgis.cpp)
//! @note not available in python bindings
static const char *qgisVectorGeometryType[];
//! description strings for geometry types
static const char *vectorGeometryType( GeometryType type )
{
switch ( type )
{
case Point: return "Point";
case Line: return "Line";
case Polygon: return "Polygon";
case UnknownGeometry: return "Unknown geometry";
case NoGeometry: return "No geometry";
default: return "Invalid type";
}
}

//! description strings for feature types
//! @note not available in python bindings
static const char *qgisFeatureTypes[];
static const char *featureType( WkbType type )
{
switch ( type )
{
case WKBUnknown: return "WKBUnknown";
case WKBPoint: return "WKBPoint";
case WKBLineString: return "WKBLineString";
case WKBPolygon: return "WKBPolygon";
case WKBMultiPoint: return "WKBMultiLineString";
case WKBMultiPolygon: return "WKBMultiPolygon";
case WKBNoGeometry: return "WKBNoGeometry";
case WKBPoint25D: return "WKBPoint25D";
case WKBLineString25D: return "WKBLineString25D";
case WKBPolygon25D: return "WKBPolygon25D";
case WKBMultiPoint25D: return "WKBMultiPoint25D";
case WKBMultiLineString25D: return "WKBMultiLineString25D";
case WKBMultiPolygon25D: return "WKBMultiPolygon25D";
default: return "invalid wkbtype";
}
}

/** Raster data types.
* This is modified and extended copy of GDALDataType.
Expand Down
39 changes: 25 additions & 14 deletions src/core/qgsgeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,7 @@ GEOSGeometry* QgsGeometry::asGeos()
QGis::WkbType QgsGeometry::wkbType()
{
unsigned char *geom = asWkb(); // ensure that wkb representation exists
if ( geom )
if ( geom && wkbSize() >= 5 )
{
unsigned int wkbType;
memcpy( &wkbType, ( geom + 1 ), sizeof( wkbType ) );
Expand All @@ -1250,18 +1250,29 @@ QGis::GeometryType QgsGeometry::type()
exportGeosToWkb();
}

QGis::WkbType type = wkbType();
if ( type == QGis::WKBPoint || type == QGis::WKBPoint25D ||
type == QGis::WKBMultiPoint || type == QGis::WKBMultiPoint25D )
return QGis::Point;
if ( type == QGis::WKBLineString || type == QGis::WKBLineString25D ||
type == QGis::WKBMultiLineString || type == QGis::WKBMultiLineString25D )
return QGis::Line;
if ( type == QGis::WKBPolygon || type == QGis::WKBPolygon25D ||
type == QGis::WKBMultiPolygon || type == QGis::WKBMultiPolygon25D )
return QGis::Polygon;

return QGis::UnknownGeometry;
switch ( wkbType() )
{
case QGis::WKBPoint:
case QGis::WKBPoint25D:
case QGis::WKBMultiPoint:
case QGis::WKBMultiPoint25D:
return QGis::Point;

case QGis::WKBLineString:
case QGis::WKBLineString25D:
case QGis::WKBMultiLineString:
case QGis::WKBMultiLineString25D:
return QGis::Line;

case QGis::WKBPolygon:
case QGis::WKBPolygon25D:
case QGis::WKBMultiPolygon:
case QGis::WKBMultiPolygon25D:
return QGis::Polygon;

default:
return QGis::UnknownGeometry;
}
}

bool QgsGeometry::isMultipart()
Expand Down Expand Up @@ -4426,7 +4437,7 @@ QgsRectangle QgsGeometry::boundingBox()
}

default:
QgsDebugMsg( "Unknown WkbType ENCOUNTERED" );
QgsDebugMsg( QString( "Unknown WkbType %1 ENCOUNTERED" ).arg( wkbType ) );
return QgsRectangle( 0, 0, 0, 0 );
break;

Expand Down
3 changes: 0 additions & 3 deletions src/core/qgsgeometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -622,9 +622,6 @@ class CORE_EXPORT QgsGeometry

/**Returns < 0 if point(x/y) is left of the line x1,y1 -> x1,y2*/
double leftOf( double x, double y, double& x1, double& y1, double& x2, double& y2 );


static int refcount;
}; // class QgsGeometry

#endif
6 changes: 3 additions & 3 deletions src/core/qgsproviderregistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,10 +526,10 @@ const QgsProviderMetadata* QgsProviderRegistry::providerMetadata( const QString&
}


/*
#if 0
QgsDataProvider *
QgsProviderRegistry::openVector( QString const & dataSource, QString const & providerKey )
{
return getProvider( providerKey, dataSource );
return getProvider( providerKey, dataSource );
} // QgsProviderRegistry::openVector
*/
#endif
2 changes: 1 addition & 1 deletion src/core/qgsvectorfilewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ bool QgsVectorFileWriter::addFeature( QgsFeature& feature )
QgsGeometry *geom = feature.geometry();

// turn single geoemetry to multi geometry if needed
if ( geom && geom->wkbType() != mWkbType && geom->wkbType() == QGis::flatType( mWkbType ) )
if ( geom && geom->wkbType() != mWkbType && geom->wkbType() == QGis::singleType( mWkbType ) )
{
geom->convertToMultiType();
}
Expand Down
4 changes: 2 additions & 2 deletions src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3015,7 +3015,7 @@ bool QgsVectorLayer::writeXml( QDomNode & layer_node,
mapLayerNode.setAttribute( "type", "vector" );

// set the geometry type
mapLayerNode.setAttribute( "geometry", QGis::qgisVectorGeometryType[geometryType()] );
mapLayerNode.setAttribute( "geometry", QGis::vectorGeometryType( geometryType() ) );

// add provider node
if ( mDataProvider )
Expand Down Expand Up @@ -5799,7 +5799,7 @@ QString QgsVectorLayer::metadata()
}
else
{
QString typeString( QGis::qgisVectorGeometryType[geometryType()] );
QString typeString( QGis::vectorGeometryType( geometryType() ) );

myMetadata += "<tr><td>";
myMetadata += tr( "Geometry type of the features in this layer: %1" ).arg( typeString );
Expand Down
22 changes: 22 additions & 0 deletions src/core/qgsvectorlayerimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
#include "qgscoordinatereferencesystem.h"
#include "qgsvectorlayerimport.h"
#include "qgsproviderregistry.h"
#include "qgsdatasourceuri.h"

#include <QProgressDialog>

#include <QProgressDialog>

Expand Down Expand Up @@ -176,6 +179,17 @@ bool QgsVectorLayerImport::flushBuffer()
return true;
}

bool QgsVectorLayerImport::createSpatialIndex()
{
if ( mProvider && ( mProvider->capabilities() & QgsVectorDataProvider::CreateSpatialIndex ) != 0 )
{
return mProvider->createSpatialIndex();
}
else
{
return true;
}
}

QgsVectorLayerImport::ImportError
QgsVectorLayerImport::importLayer( QgsVectorLayer* layer,
Expand Down Expand Up @@ -384,6 +398,14 @@ QgsVectorLayerImport::importLayer( QgsVectorLayer* layer,
}
int errors = writer->errorCount();

if ( !writer->createSpatialIndex() )
{
if ( writer->hasError() && errorMessage )
{
*errorMessage += "\n" + writer->errorMessage();
}
}

delete writer;

if ( shallTransform )
Expand Down
3 changes: 3 additions & 0 deletions src/core/qgsvectorlayerimport.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ class CORE_EXPORT QgsVectorLayerImport
/** flush the buffer writing the features to the new layer */
bool flushBuffer();

/** create index */
bool createSpatialIndex();

/** contains error value */
ImportError mError;
QString mErrorMessage;
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgsrendererv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ void QgsFeatureRendererV2::renderFeatureWithSymbol( QgsFeature& feature, QgsSymb
break;

default:
QgsDebugMsg( "unsupported wkb type for rendering" );
QgsDebugMsg( QString( "unsupported wkb type 0x%1 for rendering" ).arg( geom->wkbType(), 0, 16 ) );
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/gui/attributetable/qgsattributetablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ bool QgsAttributeTableModel::removeRows( int row, int count, const QModelIndex &

void QgsAttributeTableModel::featureAdded( QgsFeatureId fid, bool newOperation )
{
QgsDebugMsgLevel( QString( "feature %1 added (%2, rows %3, ids %4)" ).arg( fid ).arg( newOperation ).arg( mRowIdMap.size() ).arg( mIdRowMap.size() ), 3 );
QgsDebugMsgLevel( QString( "feature %1 added (%2, rows %3, ids %4)" ).arg( fid ).arg( newOperation ).arg( mRowIdMap.size() ).arg( mIdRowMap.size() ), 4 );

int n = mRowIdMap.size();
if ( newOperation )
Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgsfieldvalidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ QValidator::State QgsFieldValidator::validate( QString &s, int &i ) const
}
else
{
QgsDebugMsg( "unsupported type for validation" );
QgsDebugMsg( QString( "unsupported type %1 for validation" ).arg( mField.type() ) );
return Invalid;
}

Expand Down
141 changes: 140 additions & 1 deletion src/gui/qgsmanageconnectionsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ void QgsManageConnectionsDialog::doExportImport()
case WCS:
doc = saveOWSConnections( items, "WCS" );
break;
case Oracle:
doc = saveOracleConnections( items );
break;
}

QFile file( mFileName );
Expand Down Expand Up @@ -173,6 +176,9 @@ void QgsManageConnectionsDialog::doExportImport()
case WCS:
loadOWSConnections( doc, items, "WCS" );
break;
case Oracle:
loadOracleConnections( doc, items );
break;
}
// clear connections list and close window
listConnections->clear();
Expand Down Expand Up @@ -205,6 +211,9 @@ bool QgsManageConnectionsDialog::populateConnections()
case MSSQL:
settings.beginGroup( "/MSSQL/connections" );
break;
case Oracle:
settings.beginGroup( "/Oracle/connections" );
break;
}
QStringList keys = settings.childGroups();
QStringList::Iterator it = keys.begin();
Expand Down Expand Up @@ -292,6 +301,14 @@ bool QgsManageConnectionsDialog::populateConnections()
return false;
}
break;
case Oracle:
if ( root.tagName() != "qgsOracleConnections" )
{
QMessageBox::information( this, tr( "Loading connections" ),
tr( "The file is not an Oracle connections exchange file." ) );
return false;
}
break;
}

QDomElement child = root.firstChildElement();
Expand Down Expand Up @@ -446,6 +463,46 @@ QDomDocument QgsManageConnectionsDialog::saveMssqlConnections( const QStringList
return doc;
}

QDomDocument QgsManageConnectionsDialog::saveOracleConnections( const QStringList &connections )
{
QDomDocument doc( "connections" );
QDomElement root = doc.createElement( "qgsOracleConnections" );
root.setAttribute( "version", "1.0" );
doc.appendChild( root );

QSettings settings;
QString path;
for ( int i = 0; i < connections.count(); ++i )
{
path = "/Oracle/connections/" + connections[ i ];
QDomElement el = doc.createElement( "oracle" );
el.setAttribute( "name", connections[ i ] );
el.setAttribute( "host", settings.value( path + "/host", "" ).toString() );
el.setAttribute( "port", settings.value( path + "/port", "" ).toString() );
el.setAttribute( "database", settings.value( path + "/database", "" ).toString() );
el.setAttribute( "sslmode", settings.value( path + "/sslmode", "1" ).toString() );
el.setAttribute( "estimatedMetadata", settings.value( path + "/estimatedMetadata", "0" ).toString() );

el.setAttribute( "saveUsername", settings.value( path + "/saveUsername", "false" ).toString() );

if ( settings.value( path + "/saveUsername", "false" ).toString() == "true" )
{
el.setAttribute( "username", settings.value( path + "/username", "" ).toString() );
}

el.setAttribute( "savePassword", settings.value( path + "/savePassword", "false" ).toString() );

if ( settings.value( path + "/savePassword", "false" ).toString() == "true" )
{
el.setAttribute( "password", settings.value( path + "/password", "" ).toString() );
}

root.appendChild( el );
}

return doc;
}

void QgsManageConnectionsDialog::loadOWSConnections( const QDomDocument &doc, const QStringList &items, const QString &service )
{
QDomElement root = doc.documentElement();
Expand Down Expand Up @@ -708,7 +765,7 @@ void QgsManageConnectionsDialog::loadMssqlConnections( const QDomDocument &doc,
{
QMessageBox::information( this,
tr( "Loading connections" ),
tr( "The file is not an PostGIS connections exchange file." ) );
tr( "The file is not an MSSQL connections exchange file." ) );
return;
}

Expand Down Expand Up @@ -791,6 +848,88 @@ void QgsManageConnectionsDialog::loadMssqlConnections( const QDomDocument &doc,
}
}

void QgsManageConnectionsDialog::loadOracleConnections( const QDomDocument &doc, const QStringList &items )
{
QDomElement root = doc.documentElement();
if ( root.tagName() != "qgsOracleConnections" )
{
QMessageBox::information( this,
tr( "Loading connections" ),
tr( "The file is not an Oracle connections exchange file." ) );
return;
}

QString connectionName;
QSettings settings;
settings.beginGroup( "/Oracle/connections" );
QStringList keys = settings.childGroups();
settings.endGroup();
QDomElement child = root.firstChildElement();
bool prompt = true;
bool overwrite = true;

while ( !child.isNull() )
{
connectionName = child.attribute( "name" );
if ( !items.contains( connectionName ) )
{
child = child.nextSiblingElement();
continue;
}

// check for duplicates
if ( keys.contains( connectionName ) && prompt )
{
int res = QMessageBox::warning( this,
tr( "Loading connections" ),
tr( "Connection with name '%1' already exists. Overwrite?" )
.arg( connectionName ),
QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
switch ( res )
{
case QMessageBox::Cancel:
return;
case QMessageBox::No:
child = child.nextSiblingElement();
continue;
case QMessageBox::Yes:
overwrite = true;
break;
case QMessageBox::YesToAll:
prompt = false;
overwrite = true;
break;
case QMessageBox::NoToAll:
prompt = false;
overwrite = false;
break;
}
}

if ( keys.contains( connectionName ) && !overwrite )
{
child = child.nextSiblingElement();
continue;
}

//no dups detected or overwrite is allowed
settings.beginGroup( "/Oracle/connections/" + connectionName );

settings.setValue( "/host", child.attribute( "host" ) );
settings.setValue( "/port", child.attribute( "port" ) );
settings.setValue( "/database", child.attribute( "database" ) );
settings.setValue( "/sslmode", child.attribute( "sslmode" ) );
settings.setValue( "/estimatedMetadata", child.attribute( "estimatedMetadata" ) );
settings.setValue( "/saveUsername", child.attribute( "saveUsername" ) );
settings.setValue( "/username", child.attribute( "username" ) );
settings.setValue( "/savePassword", child.attribute( "savePassword" ) );
settings.setValue( "/password", child.attribute( "password" ) );
settings.endGroup();

child = child.nextSiblingElement();
}
}

void QgsManageConnectionsDialog::selectAll()
{
listConnections->selectAll();
Expand Down
7 changes: 6 additions & 1 deletion src/gui/qgsmanageconnectionsdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class GUI_EXPORT QgsManageConnectionsDialog : public QDialog, private Ui::QgsMan
PostGIS,
WFS,
MSSQL,
WCS
WCS,
Oracle,
};

// constructor
Expand All @@ -54,14 +55,18 @@ class GUI_EXPORT QgsManageConnectionsDialog : public QDialog, private Ui::QgsMan

private:
bool populateConnections();

QDomDocument saveOWSConnections( const QStringList &connections, const QString &service );
QDomDocument saveWFSConnections( const QStringList &connections );
QDomDocument savePgConnections( const QStringList & connections );
QDomDocument saveMssqlConnections( const QStringList & connections );
QDomDocument saveOracleConnections( const QStringList & connections );

void loadOWSConnections( const QDomDocument &doc, const QStringList &items, const QString &service );
void loadWFSConnections( const QDomDocument &doc, const QStringList &items );
void loadPgConnections( const QDomDocument &doc, const QStringList &items );
void loadMssqlConnections( const QDomDocument &doc, const QStringList &items );
void loadOracleConnections( const QDomDocument &doc, const QStringList &items );

QString mFileName;
Mode mDialogMode;
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/grass/qgsgrassmodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3621,7 +3621,7 @@ void QgsGrassModuleField::updateFields()

std::vector<QgsField> fields = mLayerInput->currentFields();

for ( unsigned int i = 0; i < fields.size(); i++ )
for ( int i = 0; i < fields.size(); i++ )
{
if ( mType.contains( fields[i].typeName() ) )
{
Expand Down
4 changes: 4 additions & 0 deletions src/providers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ ADD_SUBDIRECTORY(wcs)
ADD_SUBDIRECTORY(gpx)
ADD_SUBDIRECTORY(wfs)

IF (WITH_ORACLE)
ADD_SUBDIRECTORY(oracle)
ENDIF(WITH_ORACLE)

IF (POSTGRES_FOUND)
ADD_SUBDIRECTORY(postgres)
ENDIF (POSTGRES_FOUND)
Expand Down
1 change: 0 additions & 1 deletion src/providers/mssql/qgsmssqlsourceselect.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ class QPushButton;
class QStringList;
class QgsGeomColumnTypeThread;
class QgisApp;
class QgsPgSourceSelect;

class QgsMssqlSourceSelectDelegate : public QItemDelegate
{
Expand Down
54 changes: 54 additions & 0 deletions src/providers/oracle/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
########################################################
# Files

ADD_SUBDIRECTORY(ocispatial)

SET(ORACLE_SRCS
qgsoracleprovider.cpp
qgsoracleconn.cpp
qgsoracledataitems.cpp
qgsoraclesourceselect.cpp
qgsoraclenewconnection.cpp
qgsoracletablemodel.cpp
qgsoraclecolumntypethread.cpp
)

SET(ORACLE_MOC_HDRS
qgsoracleprovider.h
qgsoracleconn.h
qgsoracledataitems.h
qgsoraclesourceselect.h
qgsoraclenewconnection.h
qgsoracletablemodel.h
qgsoraclecolumntypethread.h
)


########################################################
# Build

QT4_WRAP_CPP(ORACLE_MOC_SRCS ${ORACLE_MOC_HDRS})

INCLUDE_DIRECTORIES(
../../core
../../gui
${GEOS_INCLUDE_DIR}
${CMAKE_CURRENT_BINARY_DIR}/../../ui
${QT_QTSQL_INCLUDEDIR}
)

ADD_LIBRARY (oracleprovider MODULE ${ORACLE_SRCS} ${ORACLE_MOC_SRCS})

TARGET_LINK_LIBRARIES (oracleprovider
qgis_core
qgis_gui
${QT_QTSQL_LIBRARY}
)


########################################################
# Install

INSTALL(TARGETS oracleprovider
RUNTIME DESTINATION ${QGIS_PLUGIN_DIR}
LIBRARY DESTINATION ${QGIS_PLUGIN_DIR})
32 changes: 32 additions & 0 deletions src/providers/oracle/ocispatial/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/${QGIS_PLUGIN_SUBDIR}/sqldrivers)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/${QGIS_PLUGIN_SUBDIR}/sqldrivers)

FIND_PACKAGE(OCI)

ADD_DEFINITIONS(${QT_DEFINITIONS})
ADD_DEFINITIONS(-DQT_PLUGIN)
ADD_DEFINITIONS(-DQT_NO_DEBUG)
ADD_DEFINITIONS(-DQT_SHARED)

INCLUDE_DIRECTORIES(${OCI_INCLUDE_DIR})

SET(QSQLOCISPATIAL_SRC qsql_ocispatial.cpp main.cpp)
QT4_WRAP_CPP(QSQLOCISPATIAL_SRC qsql_ocispatial.h)

ADD_LIBRARY(qsqlocispatial SHARED ${QSQLOCISPATIAL_SRC})

TARGET_LINK_LIBRARIES(qsqlocispatial
${QT_QTCORE_LIBRARY}
${QT_QTSQL_LIBRARY}
${OCI_LIBRARY}
)

IF(MSVC)
TARGET_LINK_LIBRARIES(qsqlocispatial wsock32)
ENDIF(MSVC)

INSTALL(TARGETS qsqlocispatial
RUNTIME DESTINATION ${QT_PLUGINS_DIR}/sqldrivers
LIBRARY DESTINATION ${QT_PLUGINS_DIR}/sqldrivers
)
7 changes: 7 additions & 0 deletions src/providers/oracle/ocispatial/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
QOCISPATIAL driver derived from QOCI driver.

You will need the Oracle development headers and libraries installed
before compiling this plugin.

See the Qt SQL documentation for more information on compiling Qt SQL
driver plugins (sql-driver.html).
45 changes: 45 additions & 0 deletions src/providers/oracle/ocispatial/cmake/FindOCI.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# ~~~~~~~~~~
# Copyright (c) 2012, Juergen E. Fischer <jef at norbit dot de>
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
# CMake module to search for OCI library
#
# If it's found it sets OCI_FOUND to TRUE
# and following variables are set:
# OCI_INCLUDE_DIR
# OCI_LIBRARY

FIND_PATH(OCI_INCLUDE_DIR oci.h
PATHS
/usr/include/oracle/11.2/client64
$ENV{OSGEO4W_ROOT}/include
$ENV{ORACLE_HOME}/rdbms/public
)

FIND_LIBRARY(OCI_LIBRARY clntsh oci
PATHS
/usr/lib/oracle/11.2/client64/lib/
$ENV{OSGEO4W_ROOT}/lib
$ENV{ORACLE_HOME}/lib
)

IF (OCI_INCLUDE_DIR)
SET(OCI_FOUND TRUE)
ELSE (OCI_INCLUDE_DIR)
SET(OCI_FOUND FALSE)
ENDIF(OCI_INCLUDE_DIR)

IF (OCI_FOUND)
IF (NOT OCI_FIND_QUIETLY)
MESSAGE(STATUS "Found OCI: ${OCI_LIBRARY}")
ENDIF (NOT OCI_FIND_QUIETLY)
ELSE (OCI_FOUND)
IF (OCI_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find OCI")
ELSE (OCI_FIND_REQUIRED)
IF (NOT OCI_FIND_QUIETLY)
MESSAGE(STATUS "Could not find OCI")
ENDIF (NOT OCI_FIND_QUIETLY)
ENDIF (OCI_FIND_REQUIRED)
ENDIF (OCI_FOUND)
85 changes: 85 additions & 0 deletions src/providers/oracle/ocispatial/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
** Oracle Spatial Support: (C) 2012-2013 Juergen E. Fischer < jef at norbit dot de >, norBIT GmbH
**
****************************************************************************/

#include <qsqldriverplugin.h>
#include <qstringlist.h>
#include "qsql_ocispatial.h"

QT_BEGIN_NAMESPACE

class QOCISpatialDriverPlugin : public QSqlDriverPlugin
{
public:
QOCISpatialDriverPlugin();

QSqlDriver* create( const QString & );
QStringList keys() const;
};

QOCISpatialDriverPlugin::QOCISpatialDriverPlugin()
: QSqlDriverPlugin()
{
}

QSqlDriver* QOCISpatialDriverPlugin::create( const QString &name )
{
if ( name == QLatin1String( "QOCISPATIAL" ) || name == QLatin1String( "QOCISPATIAL8" ) )
{
QOCISpatialDriver* driver = new QOCISpatialDriver();
return driver;
}
return 0;
}

QStringList QOCISpatialDriverPlugin::keys() const
{
QStringList l;
l.append( QLatin1String( "QOCISPATIAL8" ) );
l.append( QLatin1String( "QOCISPATIAL" ) );
return l;
}

Q_EXPORT_STATIC_PLUGIN( QOCISpatialDriverPlugin )
Q_EXPORT_PLUGIN2( qsqloci, QOCISpatialDriverPlugin )

QT_END_NAMESPACE
3,983 changes: 3,983 additions & 0 deletions src/providers/oracle/ocispatial/qsql_ocispatial.cpp

Large diffs are not rendered by default.

130 changes: 130 additions & 0 deletions src/providers/oracle/ocispatial/qsql_ocispatial.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSql module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef QSQL_OCISPATIAL_H
#define QSQL_OCISPATIAL_H

#include <QtSql/qsqlresult.h>
#include <QtSql/qsqldriver.h>
#include "qsqlcachedresult_p.h"

#ifdef QT_PLUGIN
#define Q_EXPORT_SQLDRIVER_OCISPATIAL
#else
#define Q_EXPORT_SQLDRIVER_OCISPATIAL Q_SQL_EXPORT
#endif

QT_BEGIN_HEADER

typedef struct OCIEnv OCIEnv;
typedef struct OCISvcCtx OCISvcCtx;

QT_BEGIN_NAMESPACE

class QOCISpatialDriver;
class QOCISpatialCols;
struct QOCISpatialDriverPrivate;
struct QOCISpatialResultPrivate;

class Q_EXPORT_SQLDRIVER_OCISPATIAL QOCISpatialResult : public QSqlCachedResult
{
friend class QOCISpatialDriver;
friend struct QOCISpatialResultPrivate;
friend class QOCISpatialCols;
public:
QOCISpatialResult( const QOCISpatialDriver * db, const QOCISpatialDriverPrivate* p );
~QOCISpatialResult();
bool prepare( const QString& query );
bool exec();
QVariant handle() const;

protected:
bool gotoNext( ValueCache &values, int index );
bool reset( const QString& query );
int size();
int numRowsAffected();
QSqlRecord record() const;
QVariant lastInsertId() const;
void virtual_hook( int id, void *data );

private:
QOCISpatialResultPrivate *d;
};

class Q_EXPORT_SQLDRIVER_OCISPATIAL QOCISpatialDriver : public QSqlDriver
{
Q_OBJECT
friend struct QOCISpatialResultPrivate;
friend class QOCISpatialPrivate;
public:
explicit QOCISpatialDriver( QObject* parent = 0 );
QOCISpatialDriver( OCIEnv* env, OCISvcCtx* ctx, QObject* parent = 0 );
~QOCISpatialDriver();
bool hasFeature( DriverFeature f ) const;
bool open( const QString & db,
const QString & user,
const QString & password,
const QString & host,
int port,
const QString& connOpts );
void close();
QSqlResult *createResult() const;
QStringList tables( QSql::TableType ) const;
QSqlRecord record( const QString& tablename ) const;
QSqlIndex primaryIndex( const QString& tablename ) const;
QString formatValue( const QSqlField &field,
bool trimStrings ) const;
QVariant handle() const;
QString escapeIdentifier( const QString &identifier, IdentifierType ) const;

protected:
bool beginTransaction();
bool commitTransaction();
bool rollbackTransaction();
private:
QOCISpatialDriverPrivate *d;
};

QT_END_NAMESPACE

QT_END_HEADER

#endif // QSQL_OCISPATIAL_H
100 changes: 100 additions & 0 deletions src/providers/oracle/ocispatial/qsqlcachedresult_p.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSql module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef QSQLCACHEDRESULT_P_H
#define QSQLCACHEDRESULT_P_H

//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of other Qt classes. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include "QtSql/qsqlresult.h"

QT_BEGIN_NAMESPACE

class QVariant;
template <typename T> class QVector;

class QSqlCachedResultPrivate;

class Q_SQL_EXPORT QSqlCachedResult: public QSqlResult
{
public:
virtual ~QSqlCachedResult();

typedef QVector<QVariant> ValueCache;

protected:
QSqlCachedResult( const QSqlDriver * db );

void init( int colCount );
void cleanup();
void clearValues();

virtual bool gotoNext( ValueCache &values, int index ) = 0;

QVariant data( int i );
bool isNull( int i );
bool fetch( int i );
bool fetchNext();
bool fetchPrevious();
bool fetchFirst();
bool fetchLast();

int colCount() const;
ValueCache &cache();

void virtual_hook( int id, void *data );
private:
bool cacheNext();
QSqlCachedResultPrivate *d;
};

QT_END_NAMESPACE

#endif // QSQLCACHEDRESULT_P_H
66 changes: 66 additions & 0 deletions src/providers/oracle/ocispatial/wkbptr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/***************************************************************************
wkbptr.h
---------------------
begin : Dezember 2012
copyright : (C) 2012 by Juergen E. Fischer
email : jef at norbit dot de
***************************************************************************
* *
* This file may be used under the terms of the GNU Lesser *
* General Public License version 2.1 as published by the Free Software *
* Foundation and appearing in the file LICENSE.LGPL included in the *
* packaging of this file. Please review the following information to *
* ensure the GNU Lesser General Public License version 2.1 requirements *
* will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. *
* *
***************************************************************************/
#ifndef WKBPTR_H
#define WKBPTR_H

#include <QSharedData>

union wkbPtr
{
void *vPtr;
double *dPtr;
int *iPtr;
unsigned char *ucPtr;
char *cPtr;

};

const int SDO_ARRAY_SIZE = 1024;

#define SDO_GTYPE_D(g) (g/1000%10)
#define SDO_GTYPE_L(g) (g/100%10)
#define SDO_GTYPE_TT(g) (g%100)
#define SDO_GTYPE(g,tt) (g*1000+tt)

enum SDO_GTYPE_TT
{
gtUnknown = 0,
gtPoint = 1,
gtLine = 2,
gtPolygon = 3,
gtCollection = 4,
gtMultiPoint = 5,
gtMultiLine = 6,
gtMultiPolygon = 7,
};


class QOCISpatialGeometry : public QSharedData
{
public:
bool isNull;
int gtype;
int srid;
double x, y, z;

QVector<int> eleminfo;
QVector<double> ordinates;
};

Q_DECLARE_METATYPE( QOCISpatialGeometry );

#endif // WKBPTR_H
66 changes: 66 additions & 0 deletions src/providers/oracle/qgsoraclecolumntypethread.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/***************************************************************************
qgscolumntypethread.cpp - lookup oracle geometry type and srid in a thread
-------------------
begin : 3.1.2012
copyright : (C) 2012 by Juergen E. Fischer
email : jef at norbit dot de
***************************************************************************/

/***************************************************************************
* *
* 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 "qgsoraclecolumntypethread.h"

#include <QMetaType>

QgsOracleColumnTypeThread::QgsOracleColumnTypeThread( QgsOracleConn *conn, bool useEstimatedMetaData )
: QThread()
, mConn( conn )
, mUseEstimatedMetadata( useEstimatedMetaData )
{
qRegisterMetaType<QgsOracleLayerProperty>( "QgsOracleLayerProperty" );
}

void QgsOracleColumnTypeThread::addGeometryColumn( QgsOracleLayerProperty layerProperty )
{
layerProperties << layerProperty;
}

void QgsOracleColumnTypeThread::stop()
{
mStopped = true;
}

void QgsOracleColumnTypeThread::run()
{
if ( !mConn )
return;

mStopped = false;

foreach ( QgsOracleLayerProperty layerProperty, layerProperties )
{
if ( !mStopped )
{
mConn->retrieveLayerTypes( layerProperty, mUseEstimatedMetadata );
}

if ( mStopped )
{
layerProperty.types.clear();
layerProperty.srids.clear();
}

// Now tell the layer list dialog box...
emit setLayerType( layerProperty );
}

mConn->disconnect();
mConn = 0;
}
53 changes: 53 additions & 0 deletions src/providers/oracle/qgsoraclecolumntypethread.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/***************************************************************************
qgsoraclecolumntypethread.cpp - lookup oracle geometry type and srid in a thread
-------------------
begin : 12.12.2012
copyright : (C) 2012 by Juergen E. Fischer
email : jef at norbit dot de
***************************************************************************/

/***************************************************************************
* *
* 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 QGSORACLECOLUMNTYPETHREAD_H
#define QGSORACLECOLUMNTYPETHREAD_H

#include <QThread>
#include "qgsoracleconn.h"

// A class that determines the geometry type of a given database
// schema.table.column, with the option of doing so in a separate
// thread.

class QgsOracleColumnTypeThread : public QThread
{
Q_OBJECT
public:
QgsOracleColumnTypeThread( QgsOracleConn *conn, bool useEstimatedMetaData );

// These functions get the layer types and pass that information out
// by emitting the setLayerType() signal.
virtual void run();

signals:
void setLayerType( QgsOracleLayerProperty layerProperty );

public slots:
void addGeometryColumn( QgsOracleLayerProperty layerProperty );
void stop();

private:
QgsOracleColumnTypeThread() {}

QgsOracleConn *mConn;
bool mUseEstimatedMetadata;
bool mStopped;
QList<QgsOracleLayerProperty> layerProperties;
};

#endif // QGSORACLECOLUMNTYPETHREAD_H
695 changes: 695 additions & 0 deletions src/providers/oracle/qgsoracleconn.cpp

Large diffs are not rendered by default.

180 changes: 180 additions & 0 deletions src/providers/oracle/qgsoracleconn.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/***************************************************************************
qgsoracleconn.h - connection class to Oracle
-------------------
begin : August 2012
copyright : (C) 2012 by Juergen E. Fischer
email : jef at norbit dot de
***************************************************************************/

/***************************************************************************
* *
* 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 QGSORACLECONN_H
#define QGSORACLECONN_H

#include <QString>
#include <QStringList>
#include <QVector>
#include <QMap>
#include <QSet>
#include <QThread>

#include "qgis.h"
#include "qgsdatasourceuri.h"

#include <QSqlDatabase>
#include <QSqlQuery>

class QgsField;

// Oracle layer properties
struct QgsOracleLayerProperty
{
QList<QGis::WkbType> types;
QList<int> srids;
QString ownerName;
QString tableName;
QString geometryColName;
bool isView;
QStringList pkCols;
QString sql;

int size() { Q_ASSERT( types.size() == srids.size() ); return types.size(); }

QgsOracleLayerProperty at( int i )
{
QgsOracleLayerProperty property;

Q_ASSERT( i >= 0 && i < size() );

property.types << types.at( i );
property.srids << srids.at( i );
property.ownerName = ownerName;
property.tableName = tableName;
property.geometryColName = geometryColName;
property.isView = isView;
property.pkCols = pkCols;
property.sql = sql;

return property;
}

#if QGISDEBUG
QString toString()
{
QString typeString;
foreach ( QGis::WkbType type, types )
{
if ( !typeString.isEmpty() )
typeString += "|";
typeString += QString::number( type );
}
QString sridString;
foreach ( int srid, srids )
{
if ( !sridString.isEmpty() )
sridString += "|";
sridString += QString::number( srid );
}

return QString( "%1.%2.%3 type=%4 srid=%5 view=%6 sql=%7" )
.arg( ownerName )
.arg( tableName )
.arg( geometryColName )
.arg( typeString )
.arg( sridString )
.arg( isView ? "yes" : "no" )
.arg( sql );
}
#endif
};

class QgsOracleConn : public QThread
{
Q_OBJECT;

public:
static QgsOracleConn *connectDb( QgsDataSourceURI uri );
void disconnect();

/** Double quote a Oracle identifier for placement in a SQL string.
*/
static QString quotedIdentifier( QString ident );

/** Quote a value for placement in a SQL string.
*/
static QString quotedValue( QVariant value );

//! Get the list of usable to check
bool supportedLayers( QVector<QgsOracleLayerProperty> &layers,
bool geometryTablesOnly,
bool userTablesOnly = true,
bool allowGeometrylessTables = false );

void retrieveLayerTypes( QgsOracleLayerProperty &layerProperty, bool useEstimatedMetadata );

/** Gets information about the spatial tables */
bool tableInfo( bool geometryTablesOnly, bool userTablesOnly, bool allowGeometrylessTables );

/** get primary key candidates (all int4 columns) */
QStringList pkCandidates( QString ownerName, QString viewName );

QString fieldExpression( const QgsField &fld );

QString connInfo();

QString currentUser();

bool hasSpatial();

static const int sGeomTypeSelectLimit;

static QString displayStringForWkbType( QGis::WkbType wkbType );
static QGis::WkbType wkbTypeFromDatabase( int gtype );

static QString databaseTypeFilter( QString alias, QString geomCol, QGis::WkbType wkbType );

static QGis::WkbType wkbTypeFromGeomType( QGis::GeometryType geomType );

static QStringList connectionList();
static QString selectedConnection();
static void setSelectedConnection( QString theConnName );
static QgsDataSourceURI connUri( QString theConnName );
static bool userTablesOnly( QString theConnName );
static bool allowGeometrylessTables( QString theConnName );
static void deleteConnection( QString theConnName );
static QString databaseName( QString serviceName, QString host, QString port );

operator QSqlDatabase() { return mDatabase; }

private:
QgsOracleConn( QgsDataSourceURI uri );
~QgsOracleConn();

bool exec( QSqlQuery &qry, QString sql );

//! reference count
int mRef;

QString mCurrentUser;

//! has spatial
int mHasSpatial;

QSqlDatabase mDatabase;
QSqlQuery mQuery;

//! List of the supported layers
QVector<QgsOracleLayerProperty> mLayersSupported;

static QMap<QString, QgsOracleConn *> sConnections;
static int snConnections;
};

#endif
473 changes: 473 additions & 0 deletions src/providers/oracle/qgsoracledataitems.cpp

Large diffs are not rendered by default.

117 changes: 117 additions & 0 deletions src/providers/oracle/qgsoracledataitems.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/***************************************************************************
qgsoracledataitems.h
---------------------
begin : August 2012
copyright : (C) 2012 by Juergen E. Fischer
email : jef at norbit dot de
***************************************************************************
* *
* 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 QGSORACLEDATAITEMS_H
#define QGSORACLEDATAITEMS_H

#include <QSqlDatabase>

#include "qgsdataitem.h"

#include "qgsoracletablemodel.h"
#include "qgsoraclesourceselect.h"
#include "qgsmimedatautils.h"
#include "qgsvectorlayerimport.h"

class QSqlDatabase;

class QgsOracleRootItem;
class QgsOracleConnectionItem;
class QgsOracleOwnerItem;
class QgsOracleLayerItem;

class QgsOracleRootItem : public QgsDataCollectionItem
{
Q_OBJECT
public:
QgsOracleRootItem( QgsDataItem* parent, QString name, QString path );
~QgsOracleRootItem();

QVector<QgsDataItem*> createChildren();

virtual QWidget * paramWidget();

virtual QList<QAction*> actions();

public slots:
void connectionsChanged();
void newConnection();
};

class QgsOracleConnectionItem : public QgsDataCollectionItem
{
Q_OBJECT
public:
QgsOracleConnectionItem( QgsDataItem* parent, QString name, QString path );
~QgsOracleConnectionItem();

QVector<QgsDataItem*> createChildren();
virtual bool equal( const QgsDataItem *other );
virtual QList<QAction*> actions();

virtual bool acceptDrop() { return true; }
virtual bool handleDrop( const QMimeData * data, Qt::DropAction action );

QgsOracleConn *connection() const { return mConn; }

void refresh();

signals:
void addGeometryColumn( QgsOracleLayerProperty );

public slots:
void editConnection();
void deleteConnection();

void setLayerType( QgsOracleLayerProperty layerProperty );

private:
void stop();
QgsOracleConn *mConn;
QMap<QString, QgsOracleOwnerItem * > mOwnerMap;
QgsOracleColumnTypeThread *mColumnTypeThread;
};

class QgsOracleOwnerItem : public QgsDataCollectionItem
{
Q_OBJECT
public:
QgsOracleOwnerItem( QgsDataItem* parent, QString name, QString path );
~QgsOracleOwnerItem();

QVector<QgsDataItem*> createChildren();

void addLayer( QgsOracleLayerProperty layerProperty );
};

class QgsOracleLayerItem : public QgsLayerItem
{
Q_OBJECT

public:
QgsOracleLayerItem( QgsDataItem* parent, QString name, QString path, QgsLayerItem::LayerType layerType, QgsOracleLayerProperty layerProperties );
~QgsOracleLayerItem();

QString createUri();

virtual QList<QAction*> actions();

public slots:
void deleteLayer();

private:
QgsOracleLayerProperty mLayerProperty;
};

#endif // QGSORACLEDATAITEMS_H
160 changes: 160 additions & 0 deletions src/providers/oracle/qgsoraclenewconnection.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/***************************************************************************
qgsoraclenewconnection.cpp - description
-------------------
begin : August 2012
copyright : (C) 2012 by Juergen E. Fischer
email : jef at norbit dot de
***************************************************************************/

/***************************************************************************
* *
* 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 <QSettings>
#include <QMessageBox>
#include <QInputDialog>

#include "qgsoraclenewconnection.h"
#include "qgscontexthelp.h"
#include "qgsdatasourceuri.h"
#include "qgsoracletablemodel.h"

QgsOracleNewConnection::QgsOracleNewConnection( QWidget *parent, const QString& connName, Qt::WFlags fl )
: QDialog( parent, fl ), mOriginalConnName( connName )
{
setupUi( this );

if ( !connName.isEmpty() )
{
// populate the dialog with the information stored for the connection
// populate the fields with the stored setting parameters
QSettings settings;

QString key = "/Oracle/connections/" + connName;
txtDatabase->setText( settings.value( key + "/database" ).toString() );
txtHost->setText( settings.value( key + "/host" ).toString() );
QString port = settings.value( key + "/port" ).toString();
if ( port.length() == 0 )
{
port = "1521";
}
txtPort->setText( port );
cb_userTablesOnly->setChecked( settings.value( key + "/userTablesOnly", false ).toBool() );
cb_allowGeometrylessTables->setChecked( settings.value( key + "/allowGeometrylessTables", false ).toBool() );
cb_useEstimatedMetadata->setChecked( settings.value( key + "/estimatedMetadata", false ).toBool() );

if ( settings.value( key + "/saveUsername" ).toString() == "true" )
{
txtUsername->setText( settings.value( key + "/username" ).toString() );
chkStoreUsername->setChecked( true );
}

if ( settings.value( key + "/savePassword" ).toString() == "true" )
{
txtPassword->setText( settings.value( key + "/password" ).toString() );
chkStorePassword->setChecked( true );
}

// Old save setting
if ( settings.contains( key + "/save" ) )
{
txtUsername->setText( settings.value( key + "/username" ).toString() );
chkStoreUsername->setChecked( !txtUsername->text().isEmpty() );

if ( settings.value( key + "/save" ).toString() == "true" )
txtPassword->setText( settings.value( key + "/password" ).toString() );

chkStorePassword->setChecked( true );
}

txtName->setText( connName );
}
}
/** Autoconnected SLOTS **/
void QgsOracleNewConnection::accept()
{
QSettings settings;
QString baseKey = "/Oracle/connections/";
settings.setValue( baseKey + "selected", txtName->text() );

if ( chkStorePassword->isChecked() &&
QMessageBox::question( this,
tr( "Saving passwords" ),
tr( "WARNING: You have opted to save your password. It will be stored in plain text in your project files and in your home directory on Unix-like systems, or in your user profile on Windows. If you do not want this to happen, please press the Cancel button.\n" ),
QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
{
return;
}

// warn if entry was renamed to an existing connection
if (( mOriginalConnName.isNull() || mOriginalConnName != txtName->text() ) &&
( settings.contains( baseKey + txtName->text() + "/service" ) ||
settings.contains( baseKey + txtName->text() + "/host" ) ) &&
QMessageBox::question( this,
tr( "Save connection" ),
tr( "Should the existing connection %1 be overwritten?" ).arg( txtName->text() ),
QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
{
return;
}

// on rename delete the original entry first
if ( !mOriginalConnName.isNull() && mOriginalConnName != txtName->text() )
{

settings.remove( baseKey + mOriginalConnName );
}

baseKey += txtName->text();
settings.setValue( baseKey + "/database", txtDatabase->text() );
settings.setValue( baseKey + "/host", txtHost->text() );
settings.setValue( baseKey + "/port", txtPort->text() );
settings.setValue( baseKey + "/username", chkStoreUsername->isChecked() ? txtUsername->text() : "" );
settings.setValue( baseKey + "/password", chkStorePassword->isChecked() ? txtPassword->text() : "" );
settings.setValue( baseKey + "/userTablesOnly", cb_userTablesOnly->isChecked() );
settings.setValue( baseKey + "/allowGeometrylessTables", cb_allowGeometrylessTables->isChecked() );
settings.setValue( baseKey + "/saveUsername", chkStoreUsername->isChecked() ? "true" : "false" );
settings.setValue( baseKey + "/savePassword", chkStorePassword->isChecked() ? "true" : "false" );
settings.setValue( baseKey + "/estimatedMetadata", cb_useEstimatedMetadata->isChecked() ? "true" : "false" );

// remove old save setting
settings.remove( baseKey + "/save" );

QDialog::accept();
}

void QgsOracleNewConnection::on_btnConnect_clicked()
{
QgsDataSourceURI uri;
uri.setConnection( txtHost->text(), txtPort->text(), txtDatabase->text(), txtUsername->text(), txtPassword->text() );

QgsOracleConn *conn = QgsOracleConn::connectDb( uri );

if ( conn )
{
// Database successfully opened; we can now issue SQL commands.
QMessageBox::information( this,
tr( "Test connection" ),
tr( "Connection to %1 was successful" ).arg( txtDatabase->text() ) );

// free connection resources
conn->disconnect();
}
else
{
QMessageBox::information( this,
tr( "Test connection" ),
tr( "Connection failed - Check settings and try again.\n\n" ) );
}
}

/** end Autoconnected SLOTS **/

QgsOracleNewConnection::~QgsOracleNewConnection()
{
}
43 changes: 43 additions & 0 deletions src/providers/oracle/qgsoraclenewconnection.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/***************************************************************************
qgsoraclenewconnection.h - description
-------------------
begin : August 2012
copyright : (C) 2012 by Juergen E. Fischer
email : jef at norbit dot de
***************************************************************************/

/***************************************************************************
* *
* 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 QGSORACLENEWCONNECTION_H
#define QGSORACLENEWCONNECTION_H
#include "ui_qgsoraclenewconnectionbase.h"
#include "qgisgui.h"
#include "qgscontexthelp.h"

/*! \class QgsOracleNewConnection
* \brief Dialog to allow the user to configure and save connection
* information for a Oracle database
*/
class QgsOracleNewConnection : public QDialog, private Ui::QgsOracleNewConnectionBase
{
Q_OBJECT
public:
//! Constructor
QgsOracleNewConnection( QWidget *parent = 0, const QString& connName = QString::null, Qt::WFlags fl = QgisGui::ModalDialogFlags );
//! Destructor
~QgsOracleNewConnection();
public slots:
void accept();
void on_btnConnect_clicked();
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
private:
QString mOriginalConnName; //store initial name to delete entry in case of rename
};

#endif // QGSORACLENEWCONNECTIONBASE_H
3,156 changes: 3,156 additions & 0 deletions src/providers/oracle/qgsoracleprovider.cpp

Large diffs are not rendered by default.

427 changes: 427 additions & 0 deletions src/providers/oracle/qgsoracleprovider.h

Large diffs are not rendered by default.

655 changes: 655 additions & 0 deletions src/providers/oracle/qgsoraclesourceselect.cpp

Large diffs are not rendered by default.

167 changes: 167 additions & 0 deletions src/providers/oracle/qgsoraclesourceselect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/***************************************************************************
qgoraclesourceselect.h - description
-------------------
begin : August 2012
copyright : (C) 2012 by Juergen E. Fischer
email : jef at norbit dot de
***************************************************************************/

/***************************************************************************
* *
* 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 QGSORACLESOURCESELECT_H
#define QGSORACLESOURCESELECT_H

#include "ui_qgsdbsourceselectbase.h"
#include "qgisgui.h"
#include "qgsdbfilterproxymodel.h"
#include "qgscontexthelp.h"

#include "qgsoracletablemodel.h"

#include <QMap>
#include <QPair>
#include <QIcon>
#include <QItemDelegate>

class QPushButton;
class QStringList;
class QgisApp;
class QgsOracleColumnTypeThread;
class QgsOracleSourceSelect;

class QgsOracleSourceSelectDelegate : public QItemDelegate
{
Q_OBJECT;

public:
QgsOracleSourceSelectDelegate( QObject *parent = NULL )
: QItemDelegate( parent )
, mConn( 0 )
{}

~QgsOracleSourceSelectDelegate()
{
setConn( 0 );
}

QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const;

void setConn( QgsOracleConn *conn ) { if ( mConn ) mConn->disconnect(); mConn = conn; }
private:
QgsOracleConn *mConn;
};


/*! \class QgsOracleSourceSelect
* \brief Dialog to create connections and add tables from Oracle.
*
* This dialog allows the user to define and save connection information
* for Oracle databases. The user can then connect and add
* tables from the database to the map canvas.
*/
class QgsOracleSourceSelect : public QDialog, private Ui::QgsDbSourceSelectBase
{
Q_OBJECT

public:
//! Constructor
QgsOracleSourceSelect( QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags, bool managerMode = false, bool embeddedMode = false );
//! Destructor
~QgsOracleSourceSelect();
//! Populate the connection list combo box
void populateConnectionList();
//! String list containing the selected tables
QStringList selectedTables();
//! Connection info (database, host, user, password)
QString connectionInfo();

signals:
void addDatabaseLayers( QStringList const & layerPathList, QString const & providerKey );
void connectionsChanged();
void addGeometryColumn( QgsOracleLayerProperty );

public slots:
//! Determines the tables the user selected and closes the dialog
void addTables();
void buildQuery();

/*! Connects to the database using the stored connection parameters.
* Once connected, available layers are displayed.
*/
void on_btnConnect_clicked();
void on_cbxAllowGeometrylessTables_stateChanged( int );
//! Opens the create connection dialog to build a new connection
void on_btnNew_clicked();
//! Opens a dialog to edit an existing connection
void on_btnEdit_clicked();
//! Deletes the selected connection
void on_btnDelete_clicked();
//! Saves the selected connections to file
void on_btnSave_clicked();
//! Loads the selected connections from file
void on_btnLoad_clicked();
void on_mSearchTableEdit_textChanged( const QString & text );
void on_mSearchColumnComboBox_currentIndexChanged( const QString & text );
void on_mSearchModeComboBox_currentIndexChanged( const QString & text );
void on_cmbConnections_currentIndexChanged( const QString &text );
void setSql( const QModelIndex& index );
//! Store the selected database
void setLayerType( QgsOracleLayerProperty layerProperty );
void on_mTablesTreeView_clicked( const QModelIndex &index );
void on_mTablesTreeView_doubleClicked( const QModelIndex &index );
//!Sets a new regular expression to the model
void setSearchExpression( const QString& regexp );

void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }

void columnThreadFinished();

private:
typedef QPair<QString, QString> geomPair;
typedef QList<geomPair> geomCol;

//! Connections manager mode
bool mManagerMode;

//! Embedded mode, without 'Close'
bool mEmbeddedMode;

// queue another query for the thread
void addSearchGeometryColumn( QgsOracleLayerProperty layerProperty );

// Set the position of the database connection list to the last
// used one.
void setConnectionListPosition();
// Combine the schema, table and column data into a single string
// useful for display to the user
QString fullDescription( QString schema, QString table, QString column, QString type );
// The column labels
QStringList mColumnLabels;
// Our thread for doing long running queries
QgsOracleColumnTypeThread *mColumnTypeThread;
QString mConnInfo;
QStringList mSelectedTables;
bool mUseEstimatedMetadata;
// Storage for the range of layer type icons
QMap<QString, QPair<QString, QIcon> > mLayerIcons;

//! Model that acts as datasource for mTableTreeWidget
QgsOracleTableModel mTableModel;
QgsDbFilterProxyModel mProxyModel;
QgsOracleSourceSelectDelegate *mTablesTreeDelegate;

QPushButton *mBuildQueryButton;
QPushButton *mAddButton;

void finishList();
bool mIsConnected;
};

#endif // QGSORACLESOURCESELECT_H
339 changes: 339 additions & 0 deletions src/providers/oracle/qgsoracletablemodel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,339 @@
/***************************************************************************
qgsoracletablemodel.cpp - description
-------------------
begin : August 2012
copyright : (C) 2012 by Juergen E. Fischer
email : jef at norbit dot de
***************************************************************************/

/***************************************************************************
* *
* 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 "qgsoracletablemodel.h"
#include "qgsdataitem.h"
#include "qgslogger.h"

QgsOracleTableModel::QgsOracleTableModel()
: QStandardItemModel()
, mTableCount( 0 )
{
QStringList headerLabels;
headerLabels << tr( "Owner" );
headerLabels << tr( "Table" );
headerLabels << tr( "Type" );
headerLabels << tr( "Geometry column" );
headerLabels << tr( "SRID" );
headerLabels << tr( "Primary key column" );
headerLabels << tr( "Select at id" );
headerLabels << tr( "Sql" );
setHorizontalHeaderLabels( headerLabels );
}

QgsOracleTableModel::~QgsOracleTableModel()
{
}

void QgsOracleTableModel::addTableEntry( QgsOracleLayerProperty layerProperty )
{
#ifdef QGISDEBUG
QString typeString;
foreach ( QGis::WkbType type, layerProperty.types )
{
if ( !typeString.isEmpty() )
typeString += "|";
typeString += QString::number( type );
}
QString sridString;
foreach ( int srid, layerProperty.srids )
{
if ( !sridString.isEmpty() )
sridString += "|";
sridString += QString::number( srid );
}
QgsDebugMsg( layerProperty.toString() );
#endif

if ( !layerProperty.types.contains( QGis::WKBUnknown ) )
{
layerProperty.types << ( layerProperty.geometryColName.isEmpty() ? QGis::WKBNoGeometry : QGis::WKBUnknown );
layerProperty.srids << 0;
}

// is there already a root item with the given scheme Name?
QStandardItem *ownerItem = 0;

for ( int i = 0; i < layerProperty.size(); i++ )
{
QGis::WkbType wkbType = layerProperty.at( i ).types[0];
int srid = layerProperty.at( i ).srids[0];

QStandardItem *ownerNameItem = new QStandardItem( layerProperty.ownerName );

bool selectable = wkbType != QGis::WKBUnknown && srid != 0;

QStandardItem *typeItem = new QStandardItem( iconForWkbType( wkbType ), wkbType == QGis::WKBUnknown ? tr( "Select..." ) : QgsOracleConn::displayStringForWkbType( wkbType ) );
typeItem->setData( wkbType == QGis::WKBUnknown, Qt::UserRole + 1 );
typeItem->setData( wkbType, Qt::UserRole + 2 );
if ( wkbType == QGis::WKBUnknown )
typeItem->setFlags( typeItem->flags() | Qt::ItemIsEditable );

QStandardItem *tableItem = new QStandardItem( layerProperty.tableName );
QStandardItem *geomItem = new QStandardItem( layerProperty.geometryColName );
QStandardItem *sridItem = new QStandardItem( QString::number( srid ) );
sridItem->setEditable( srid == 0 );
if ( srid == 0 )
{
sridItem->setText( tr( "Enter..." ) );
sridItem->setFlags( sridItem->flags() | Qt::ItemIsEditable );
}

QStandardItem *pkItem = new QStandardItem( layerProperty.isView ? tr( "Select..." ) : "" );
if ( layerProperty.isView )
pkItem->setFlags( pkItem->flags() | Qt::ItemIsEditable );
else
pkItem->setFlags( pkItem->flags() & ~Qt::ItemIsEditable );

pkItem->setData( layerProperty.isView, Qt::UserRole + 1 );
pkItem->setData( false, Qt::UserRole + 2 ); // not selected

QStandardItem *selItem = new QStandardItem( "" );
selItem->setFlags( selItem->flags() | Qt::ItemIsUserCheckable );
selItem->setCheckState( Qt::Checked );
selItem->setToolTip( tr( "Disable 'Fast Access to Features at ID' capability to force keeping the attribute table in memory (e.g. in case of expensive views)." ) );

QStandardItem* sqlItem = new QStandardItem( layerProperty.sql );

QList<QStandardItem*> childItemList;
childItemList << ownerNameItem;
childItemList << tableItem;
childItemList << typeItem;
childItemList << geomItem;
childItemList << sridItem;
childItemList << pkItem;
childItemList << selItem;
childItemList << sqlItem;

foreach ( QStandardItem *item, childItemList )
{
if ( selectable )
{
item->setFlags( item->flags() | Qt::ItemIsSelectable );
}
else
{
item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
}
}

if ( !ownerItem )
{
QList<QStandardItem*> ownerItems = findItems( layerProperty.ownerName, Qt::MatchExactly, dbtmOwner );

// there is already an item for this schema
if ( ownerItems.size() > 0 )
{
ownerItem = ownerItems.at( dbtmOwner );
}
else
{
// create a new toplevel item for this schema
ownerItem = new QStandardItem( layerProperty.ownerName );
ownerItem->setFlags( Qt::ItemIsEnabled );
invisibleRootItem()->setChild( invisibleRootItem()->rowCount(), ownerItem );
}
}

ownerItem->appendRow( childItemList );

++mTableCount;
}
}

void QgsOracleTableModel::setSql( const QModelIndex &index, const QString &sql )
{
if ( !index.isValid() || !index.parent().isValid() )
{
return;
}

//find out schema name and table name
QModelIndex ownerSibling = index.sibling( index.row(), dbtmOwner );
QModelIndex tableSibling = index.sibling( index.row(), dbtmTable );
QModelIndex geomSibling = index.sibling( index.row(), dbtmGeomCol );

if ( !ownerSibling.isValid() || !tableSibling.isValid() || !geomSibling.isValid() )
{
return;
}

QString ownerName = itemFromIndex( ownerSibling )->text();
QString tableName = itemFromIndex( tableSibling )->text();
QString geomName = itemFromIndex( geomSibling )->text();

QList<QStandardItem*> ownerItems = findItems( ownerName, Qt::MatchExactly, dbtmOwner );
if ( ownerItems.size() < 1 )
{
return;
}

QStandardItem* ownerItem = ownerItems.at( dbtmOwner );

int n = ownerItem->rowCount();
for ( int i = 0; i < n; i++ )
{
QModelIndex currentChildIndex = indexFromItem( ownerItem->child( i, dbtmOwner ) );
if ( !currentChildIndex.isValid() )
{
continue;
}

QModelIndex currentTableIndex = currentChildIndex.sibling( i, dbtmTable );
if ( !currentTableIndex.isValid() )
{
continue;
}

QModelIndex currentGeomIndex = currentChildIndex.sibling( i, dbtmGeomCol );
if ( !currentGeomIndex.isValid() )
{
continue;
}

if ( itemFromIndex( currentTableIndex )->text() == tableName && itemFromIndex( currentGeomIndex )->text() == geomName )
{
QModelIndex sqlIndex = currentChildIndex.sibling( i, dbtmSql );
if ( sqlIndex.isValid() )
{
itemFromIndex( sqlIndex )->setText( sql );
break;
}
}
}
}

QIcon QgsOracleTableModel::iconForWkbType( QGis::WkbType type )
{
switch ( type )
{
case QGis::WKBPoint:
case QGis::WKBPoint25D:
case QGis::WKBMultiPoint:
case QGis::WKBMultiPoint25D:
return QgsApplication::getThemeIcon( "/mIconPointLayer.png" );
case QGis::WKBLineString:
case QGis::WKBLineString25D:
case QGis::WKBMultiLineString:
case QGis::WKBMultiLineString25D:
return QgsApplication::getThemeIcon( "/mIconLineLayer.png" );
case QGis::WKBPolygon:
case QGis::WKBPolygon25D:
case QGis::WKBMultiPolygon:
case QGis::WKBMultiPolygon25D:
return QgsApplication::getThemeIcon( "/mIconPolygonLayer.png" );
case QGis::WKBNoGeometry:
return QgsApplication::getThemeIcon( "/mIconTableLayer.png" );
case QGis::WKBUnknown:
break;
}
return QgsApplication::getThemeIcon( "/mIconLayer.png" );
}

bool QgsOracleTableModel::setData( const QModelIndex &idx, const QVariant &value, int role )
{
if ( !QStandardItemModel::setData( idx, value, role ) )
return false;

if ( idx.column() == dbtmType || idx.column() == dbtmSrid || idx.column() == dbtmPkCol )
{
QGis::WkbType geomType = ( QGis::WkbType ) idx.sibling( idx.row(), dbtmType ).data( Qt::UserRole + 2 ).toInt();

bool ok = geomType != QGis::WKBUnknown;

if ( ok && geomType != QGis::WKBNoGeometry )
idx.sibling( idx.row(), dbtmSrid ).data().toInt( &ok );

int srid = idx.sibling( idx.row(), dbtmSrid ).data().toInt();
ok &= srid != 0;

ok &= !idx.sibling( idx.row(), dbtmPkCol ).data( Qt::UserRole + 1 ).toBool() ||
idx.sibling( idx.row(), dbtmPkCol ).data( Qt::UserRole + 2 ).toBool();

for ( int i = 0; i < dbtmColumns; i++ )
{
QStandardItem *item = itemFromIndex( idx.sibling( idx.row(), i ) );
if ( ok )
item->setFlags( item->flags() | Qt::ItemIsSelectable );
else
item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
}
}

return true;
}

QString QgsOracleTableModel::layerURI( const QModelIndex &index, QString connInfo, bool useEstimatedMetadata )
{
if ( !index.isValid() )
{
QgsDebugMsg( "invalid index" );
return QString::null;
}

QGis::WkbType wkbType = ( QGis::WkbType ) itemFromIndex( index.sibling( index.row(), dbtmType ) )->data( Qt::UserRole + 2 ).toInt();
if ( wkbType == QGis::WKBUnknown )
{
QgsDebugMsg( "unknown geometry type" );
// no geometry type selected
return QString::null;
}

QStandardItem *pkItem = itemFromIndex( index.sibling( index.row(), dbtmPkCol ) );
QString pkColumnName = pkItem->data( Qt::DisplayRole ).toString();
bool isView = pkItem->data( Qt::UserRole + 1 ).toBool();
bool isSet = pkItem->data( Qt::UserRole + 2 ).toBool();

if ( isView && !isSet )
{
// no valid primary candidate selected
QgsDebugMsg( "no pk candidate selected" );
return QString::null;
}

QString ownerName = index.sibling( index.row(), dbtmOwner ).data( Qt::DisplayRole ).toString();
QString tableName = index.sibling( index.row(), dbtmTable ).data( Qt::DisplayRole ).toString();

QString geomColumnName;
QString srid;
if ( wkbType != QGis::WKBNoGeometry )
{
geomColumnName = index.sibling( index.row(), dbtmGeomCol ).data( Qt::DisplayRole ).toString();

srid = index.sibling( index.row(), dbtmSrid ).data( Qt::DisplayRole ).toString();
bool ok;
srid.toInt( &ok );
if ( !ok )
{
QgsDebugMsg( "srid not numeric" );
return QString::null;
}
}

bool selectAtId = itemFromIndex( index.sibling( index.row(), dbtmSelectAtId ) )->checkState() == Qt::Checked;
QString sql = index.sibling( index.row(), dbtmSql ).data( Qt::DisplayRole ).toString();

QgsDataSourceURI uri( connInfo );
uri.setDataSource( ownerName, tableName, geomColumnName, sql, pkColumnName );
uri.setUseEstimatedMetadata( useEstimatedMetadata );
uri.setWkbType( wkbType );
uri.setSrid( srid );
uri.disableSelectAtId( !selectAtId );

QgsDebugMsg( QString( "returning uri %1" ).arg( uri.uri() ) );
return uri.uri();
}
69 changes: 69 additions & 0 deletions src/providers/oracle/qgsoracletablemodel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/***************************************************************************
qgsoracletablemodel.h - description
-------------------
begin : August 2012
copyright : (C) 2012 by Juergen E. Fischer
email : jef at norbit dot de
***************************************************************************/

/***************************************************************************
* *
* 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 QGSORACLETABLEMODEL_H
#define QGSORACLETABLEMODEL_H
#include <QStandardItemModel>

#include "qgis.h"
#include "qgsoracleconn.h"

class QIcon;

/**A model that holds the tables of a database in a hierarchy where the
schemas are the root elements that contain the individual tables as children.
The tables have the following columns: Type, Owner, Tablename, Geometry Column, Sql*/
class QgsOracleTableModel : public QStandardItemModel
{
Q_OBJECT
public:
QgsOracleTableModel();
~QgsOracleTableModel();

/**Adds entry for one database table to the model*/
void addTableEntry( QgsOracleLayerProperty property );

/**Sets an sql statement that belongs to a cell specified by a model index*/
void setSql( const QModelIndex& index, const QString& sql );

/**Returns the number of tables in the model*/
int tableCount() const { return mTableCount; }

enum columns
{
dbtmOwner = 0,
dbtmTable,
dbtmType,
dbtmGeomCol,
dbtmSrid,
dbtmPkCol,
dbtmSelectAtId,
dbtmSql,
dbtmColumns
};

bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole );

QString layerURI( const QModelIndex &index, QString connInfo, bool useEstimatedMetadata );

static QIcon iconForWkbType( QGis::WkbType type );

private:
/**Number of tables in the model*/
int mTableCount;
};

#endif // QGSORACLETABLEMODEL_H
2 changes: 1 addition & 1 deletion src/providers/postgres/qgspgnewconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ QgsPgNewConnection::QgsPgNewConnection( QWidget *parent, const QString& connName
txtPort->setText( port );
txtDatabase->setText( settings.value( key + "/database" ).toString() );
cb_publicSchemaOnly->setChecked( settings.value( key + "/publicOnly", false ).toBool() );
cb_geometryColumnsOnly->setChecked( settings.value( key + "/geometrycolumnsOnly", true ).toBool() );
cb_geometryColumnsOnly->setChecked( settings.value( key + "/geometryColumnsOnly", true ).toBool() );
cb_allowGeometrylessTables->setChecked( settings.value( key + "/allowGeometrylessTables", false ).toBool() );
// Ensure that cb_publicSchemaOnly is set correctly
on_cb_geometryColumnsOnly_clicked();
Expand Down
4 changes: 2 additions & 2 deletions src/providers/postgres/qgspostgresconn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1091,7 +1091,7 @@ void QgsPostgresConn::retrieveLayerTypes( QgsPostgresLayerProperty &layerPropert
}


// it is possible that the where clause restricts the feature type or srid
// our estimatation ignores that a where clause might restrict the feature type or srid
if ( useEstimatedMetadata )
{
table = QString( "(SELECT %1 FROM %2 WHERE %1 IS NOT NULL%3 LIMIT %4) AS t" )
Expand Down Expand Up @@ -1476,7 +1476,7 @@ bool QgsPostgresConn::geometryColumnsOnly( QString theConnName )
{
QSettings settings;

return settings.value( "/PostgreSQL/connections/" + theConnName + "/geometrycolumnsOnly", false ).toBool();
return settings.value( "/PostgreSQL/connections/" + theConnName + "/geometryColumnsOnly", false ).toBool();
}

bool QgsPostgresConn::allowGeometrylessTables( QString theConnName )
Expand Down
13 changes: 6 additions & 7 deletions src/providers/postgres/qgspostgresprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,6 @@ bool QgsPostgresProvider::getFeature( QgsPostgresResult &queryResult, int row, b
else
{
feature.setGeometryAndOwnership( 0, 0 );
QgsMessageLog::logMessage( tr( "Couldn't get the feature geometry in binary form" ), tr( "PostGIS" ) );
}

col++;
Expand Down Expand Up @@ -1861,12 +1860,12 @@ bool QgsPostgresProvider::getTopoLayerInfo( )
void QgsPostgresProvider::dropOrphanedTopoGeoms( )
{
QString sql = QString( "DELETE FROM %1.relation WHERE layer_id = %2 AND "
"topogeo_id NOT IN ( SELECT id(%3) FROM %4.%5 )" )
.arg( quotedIdentifier(mTopoLayerInfo.topologyName) )
"topogeo_id NOT IN ( SELECT id(%3) FROM %4.%5 )" )
.arg( quotedIdentifier( mTopoLayerInfo.topologyName ) )
.arg( mTopoLayerInfo.layerId )
.arg( quotedIdentifier(mGeometryColumn) )
.arg( quotedIdentifier(mSchemaName) )
.arg( quotedIdentifier(mTableName) )
.arg( quotedIdentifier( mGeometryColumn ) )
.arg( quotedIdentifier( mSchemaName ) )
.arg( quotedIdentifier( mTableName ) )
;

QgsDebugMsg( "TopoGeom orphans cleanup query: " + sql );
Expand Down Expand Up @@ -3163,7 +3162,7 @@ bool QgsPostgresProvider::getGeometryDetails()
mEnabledCapabilities &= ~( QgsVectorDataProvider::ChangeGeometries | QgsVectorDataProvider::AddFeatures );
}

QgsDebugMsg( QString( "Feature type name is %1" ).arg( QGis::qgisFeatureTypes[ geometryType()] ) );
QgsDebugMsg( QString( "Feature type name is %1" ).arg( QGis::featureType( geometryType() ) ) );
QgsDebugMsg( QString( "Spatial column type is %1" ).arg( QgsPostgresConn::displayStringForGeomType( mSpatialColType ) ) );

return mValid;
Expand Down
13 changes: 13 additions & 0 deletions src/ui/qgisapp.ui
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@
<addaction name="mActionAddPgLayer"/>
<addaction name="mActionAddSpatiaLiteLayer"/>
<addaction name="mActionAddMssqlLayer"/>
<addaction name="mActionAddOracleLayer"/>
<addaction name="mActionAddWmsLayer"/>
<addaction name="mActionAddWcsLayer"/>
<addaction name="mActionAddWfsLayer"/>
Expand Down Expand Up @@ -1188,6 +1189,18 @@
<string>Ctrl+Shift+M</string>
</property>
</action>
<action name="mActionAddOracleLayer">
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionAddOracleLayer.png</normaloff>:/images/themes/default/mActionAddOracleLayer.png</iconset>
</property>
<property name="text">
<string>Add Oracle Spatial Layer...</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+O</string>
</property>
</action>
<action name="mActionAddWmsLayer">
<property name="icon">
<iconset resource="../../images/images.qrc">
Expand Down
Loading