[FEATURE] add oracle provider

This commit is contained in:
Juergen E. Fischer 2013-01-09 16:46:30 +01:00
parent dda51c62b5
commit 4923c30d73
64 changed files with 15204 additions and 1839 deletions

View File

@ -70,6 +70,11 @@ IF (WITH_SPATIALITE)
ENDIF (WITH_INTERNAL_SPATIALITE)
ENDIF (WITH_SPATIALITE)
SET (WITH_ORACLE FALSE CACHE BOOL "Determines whether Oracle support should be built")
IF(WITH_ORACLE)
SET(HAVE_ORACLE TRUE)
ENDIF(WITH_ORACLE)
# try to configure and build python bindings by default
SET (WITH_BINDINGS TRUE CACHE BOOL "Determines whether python bindings should be built")
IF (WITH_BINDINGS)

View File

@ -38,6 +38,8 @@
#cmakedefine HAVE_MSSQL
#cmakedefine HAVE_ORACLE
#cmakedefine HAVE_PYTHON
#cmakedefine HAVE_TOUCH

232
debian/control.sid-oracle vendored Normal file
View File

@ -0,0 +1,232 @@
Source: qgis
Section: science
Priority: extra
Maintainer: Quantum GIS developers <qgis-developer@lists.osgeo.org>
Build-Depends:
bison,
cmake (>= 2.6),
debhelper (>= 9),
flex,
grass-dev,
libexpat1-dev,
libfcgi-dev,
libgdal1-dev,
libgeos-dev (>= 3.0.0),
libgsl0-dev,
libpq-dev,
libproj-dev,
libqt4-dev (>=4.4.0),
libqt4-opengl-dev,
libqtwebkit-dev,
libqwt-dev,
libspatialite-dev,
libsqlite3-dev,
libspatialindex-dev,
pkg-config,
pyqt4-dev-tools,
python,
python-dev (>= 2.6.6-3~),
python-qt4 (>=4.1.0),
python-qt4-dev (>=4.1.0),
python-sip (>= 4.5.0),
python-sip-dev (>= 4.5.0),
libosgearth-dev,
libopenscenegraph-dev,
git,
doxygen,
graphviz,
txt2tags,
xvfb, xauth, xfonts-base,
oracle-instantclient11.2-devel
Build-Conflicts: libqgis-dev, qgis-dev
Standards-Version: 3.9.3
X-Python-Version: current
Homepage: http://qgis.org/
Package: qgis
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, qgis-providers (= ${binary:Version}), qgis-common (= ${source:Version})
Recommends: qgis-plugin-globe, qgis-plugin-grass, python-qgis
Suggests: gpsbabel
Conflicts: uim-qt3
Description: Geographic Information System (GIS)
A Geographic Information System (GIS) manages, analyzes, and displays
databases of geographic information. Quantum GIS (QGIS) supports shape file
viewing and editing, spatial data storage with PostgreSQL/PostGIS, projection
on-the-fly, map composition, and a number of other features via a plugin
interface. QGIS also supports display of various georeferenced raster and
Digital Elevation Model (DEM) formats including GeoTIFF, Arc/Info ASCII Grid,
and USGS ASCII DEM.
Package: qgis-common
Architecture: all
Depends: ${misc:Depends}
Description: Quantum GIS - architecture-independent data
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This package contains architecture-independent supporting data files for use
with Quantum GIS.
Package: libqgis{QGIS_ABI}
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Replaces: qgis (<=0.9.2rc1), libqgis-core1, libqgis-gui1, libqgis0, libqgis1
Description: Quantum GIS - shared libraries
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This package contains the shared core and gui library that provide an
interface for plugins and stand-alone applications.
Package: libqgis-dev
Architecture: any
Section: libdevel
Depends:
grass-dev,
libexpat1-dev,
libgdal1-dev,
libgeos-dev (>= 3.0.0),
libgsl0-dev,
libpq-dev,
libproj-dev,
libqgis{QGIS_ABI} (= ${binary:Version}),
libqt4-dev (>=4.4.0),
libsqlite3-dev,
python-qt4 (>=4.1.0),
python-qt4-dev (>=4.1.0),
qt4-designer (>=4.4.0),
${misc:Depends}
Provides: qgis-dev
Replaces: qgis-dev, libqgis1-dev, libqgis1.4.0-dev
Description: Quantum GIS - development files
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This package contains the headers and libraries needed to develop plugins for
Quantum GIS.
Package: qgis-plugin-grass
Architecture: any
Depends: qgis (= ${binary:Version}), qgis-plugin-grass-common (= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}, grass{GRASS_ABI}
Description: GRASS plugin for Quantum GIS
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This plugin enables GRASS data access in the Quantum GIS geographic data
viewer.
Package: qgis-plugin-grass-common
Architecture: all
Depends: python, ${misc:Depends}
Replaces: qgis-common (<< 1.5)
Breaks: qgis-common (<< 1.5)
Description: GRASS plugin for Quantum GIS - architecture-independent data
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This package contains architecture-independent supporting data files for use
with the Quantum GIS GRASS plugin.
Package: python-qgis
Section: python
Architecture: any
Depends: python-qt4 (>=4.1.0), python-sip (>= 4.5.0), python-qgis-common (= ${source:Version}), python-pyspatialite, python-psycopg2, python-qscintilla2, ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}
Description: Python bindings to Quantum GIS
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This package contains the files for the Python support.
Package: python-qgis-common
Section: python
Architecture: all
Provides: ${python:Provides}
Depends: gdal-bin, python-gdal, libjs-jquery, libjs-underscore, ${misc:Depends}
Description: Python bindings to Quantum GIS - architecture-independent files
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This package contains architecture-independent files for the Quantum GIS
Python bindings.
Package: qgis-providers
Architecture: any
Depends: qgis-providers-common (= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}
Replaces: qgis (<= 1.6)
Breaks: qgis (<= 1.6)
Description: collection of data providers to Quantum GIS
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This package contains the provider plugins for Quantum GIS.
Package: qgis-providers-common
Architecture: all
Replaces: qgis-common (<= 1.6)
Breaks: qgis-common (<= 1.6)
Depends: ${misc:Depends}
Description: collection of data providers to Quantum GIS - architecture-independent files
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This package contains architecture-independent files for the Quantum GIS
providers.
Package: qgis-mapserver
Architecture: any
Depends: qgis-providers (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
Description: Quantum GIS mapserver
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This package contains the Quantum GIS mapserver.
Package: qgis-sqlanywhere
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Conflicts: qgis-sqlanywhere1.7.0, qgis-sqlanywhere1.7.1, qgis-sqlanywhere1.8.0
Description: Quantum GIS sql anywhere plugin and provider
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This package contains the Quantum GIS sqlanywhere plugin and provider.
Package: qgis-api-doc
Architecture: all
Section: doc
Depends: libjs-jquery
Description: Quantum GIS API documentation
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This package contains the Quantum GIS API documentation.
Package: qgis-plugin-globe
Architecture: any
Depends: qgis (= ${binary:Version}), qgis-plugin-globe-common (= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}
Description: OSG globe plugin for Quantum GIS
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This plugin enables 3D viewing using OSG globe in the Quantum GIS.
Package: qgis-plugin-globe-common
Architecture: all
Description: OSG GLOBE plugin for Quantum GIS - architecture-independent data
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This package contains architecture-independent supporting data files for use
with the Quantum GIS GLOBE plugin.
Package: qgis-oracle-provider
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Section: contrib/databases
Description: Quantum GIS oracle provider
Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
and display databases of geographic information.
.
This package contains the Quantum GIS oracle provider.

View File

@ -0,0 +1,2 @@
usr/lib/qgis/plugins/liboracleprovider.so
usr/lib/{DEB_BUILD_GNU_TYPE}/qt4/plugins/sqldrivers/libqsqlocispatial.so

7
debian/rules vendored
View File

@ -16,7 +16,7 @@ ifeq (,$(DISTRIBUTION))
DISTRIBUTION := $(shell dpkg-parsechangelog --format rfc822 | sed -ne "s/^Distribution: //p")
endif
ifneq ($(DISTRIBUTION),$(findstring $(DISTRIBUTION),"squeeze wheezy lucid maverick natty oneiric precise"))
ifneq ($(DISTRIBUTION),$(findstring $(DISTRIBUTION),"squeeze wheezy lucid maverick natty oneiric precise sid-oracle"))
DISTRIBUTION := sid
endif
@ -71,6 +71,10 @@ else
CMAKE_OPTS += -D WITH_GLOBE=TRUE
endif
ifneq (,$(findstring -oracle,$(DISTRIBUTION)))
CMAKE_OPTS += -D WITH_ORACLE=TRUE
endif
ifneq (,$(findstring $(DISTRIBUTION),"wheezy sid"))
CPPFLAGS := $(shell dpkg-buildflags --get CPPFLAGS)
CFLAGS := $(shell dpkg-buildflags --get CFLAGS) $(CPPFLAGS)
@ -107,6 +111,7 @@ endif
define gentemplate
$(2): $(1)
sed \
-e "s/{DEB_BUILD_GNU_TYPE}/$(DEB_BUILD_GNU_TYPE)/g" \
-e "s/{QGIS_ABI}/$(QGIS_ABI)/g" \
-e "s/{GRASS}/$(GRASS)/g" \
-e "s/{GRASS_ABI}/$(GRASS_ABI)/g" $$^ >$$@

View File

@ -1,46 +1,46 @@
<style>table {font-size:80%;}th {text-align:left; }.bartodo{ background-color:red;width:100px;height:20px;}.bardone{ background-color:green;width:80px;height:20px;font-size:80%;text-align:center;padding-top:4px;height:16px;color:white;}</style><table><tr><th colspan="2" style="width:250px;">Language</th><th>Finished %</th><th>Translators</th></tr>
<tr><td><img src="qrc:/images/flags/de.png"></td><td>German</td><td><div title="finished:8770 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:99px">99.8</div></div></td><td>Jürgen E. Fischer, Stephan Holl, Otto Dassau, Werner Macho</td></tr>
<tr><td><img src="qrc:/images/flags/gl_ES.png"></td><td>Galician (Spain)</td><td><div title="finished:8619 unfinished:28 untranslated:61" class="bartodo"><div class="bardone" style="width:98px">98.2</div></div></td><td>Xan Vieiro</td></tr>
<tr><td><img src="qrc:/images/flags/es.png"></td><td>Spanish</td><td><div title="finished:8438 unfinished:22 untranslated:58" class="bartodo"><div class="bardone" style="width:96px">96.2</div></div></td><td>Carlos Dávila, Javier César Aldariz, Gabriela Awad, Edwin Amado, Mayeul Kauffmann, Diana Galindo</td></tr>
<tr><td><img src="qrc:/images/flags/it.png"></td><td>Italian</td><td><div title="finished:7967 unfinished:28 untranslated:515" class="bartodo"><div class="bardone" style="width:90px">90.8</div></div></td><td>Paolo Cavallini, Flavio Rigolon, Maurizio Napolitano, Roberto Angeletti, Alessandro Fanna, Michele Beneventi, Marco Braida, Luca Casagrande, Luca Delucchi, Anne Gishla</td></tr>
<tr><td><img src="qrc:/images/flags/sv.png"></td><td>Swedish</td><td><div title="finished:7316 unfinished:1131 untranslated:109" class="bartodo"><div class="bardone" style="width:89px">89.7</div></div></td><td>Lars Luthman, Magnus Homann, Victor Axbom</td></tr>
<tr><td><img src="qrc:/images/flags/nl.png"></td><td>Dutch</td><td><div title="finished:7573 unfinished:399 untranslated:543" class="bartodo"><div class="bardone" style="width:88px">88.5</div></div></td><td>Richard Duivenvoorde, Raymond Nijssen, Carlo van Rijswijk</td></tr>
<tr><td><img src="qrc:/images/flags/ja.png"></td><td>Japanese</td><td><div title="finished:7412 unfinished:461 untranslated:630" class="bartodo"><div class="bardone" style="width:86px">87.0</div></div></td><td>BABA Yoshihiko, Yoichi Kayama</td></tr>
<tr><td><img src="qrc:/images/flags/et_EE.png"></td><td>Estonian (Estonia)</td><td><div title="finished:7412 unfinished:452 untranslated:639" class="bartodo"><div class="bardone" style="width:86px">86.9</div></div></td><td>Veiko Viil</td></tr>
<tr><td><img src="qrc:/images/flags/fr.png"></td><td>French</td><td><div title="finished:7407 unfinished:449 untranslated:647" class="bartodo"><div class="bardone" style="width:86px">86.8</div></div></td><td>Eve Rousseau, Marc Monnerat, Lionel Roubeyrie, Jean Roc Morreale, Benjamin Bohard, Jeremy Garniaux, Yves Jacolin, Benjamin Lerre, Stéphane Morel, Marie Silvestre, Tahir Tamba, Xavier M, Mayeul Kauffmann, Mehdi Semchaoui, Robin Cura, Etienne Tourigny, Mathieu Bossaert</td></tr>
<tr><td><img src="qrc:/images/flags/pt_BR.png"></td><td>Portuguese (Brazil)</td><td><div title="finished:7412 unfinished:429 untranslated:662" class="bartodo"><div class="bardone" style="width:86px">86.8</div></div></td><td>Arthur Nanni</td></tr>
<tr><td><img src="qrc:/images/flags/pl_PL.png"></td><td>Polish (Poland)</td><td><div title="finished:7412 unfinished:419 untranslated:672" class="bartodo"><div class="bardone" style="width:86px">86.7</div></div></td><td>Robert Szczepanek, Milena Nowotarska, Borys Jurgiel, Mateusz Loskot, Tomasz Paul, Andrzej Swiader </td></tr>
<tr><td><img src="qrc:/images/flags/ru.png"></td><td>Russian</td><td><div title="finished:7412 unfinished:407 untranslated:684" class="bartodo"><div class="bardone" style="width:86px">86.7</div></div></td><td>Artem Popov</td></tr>
<tr><td><img src="qrc:/images/flags/cs_CZ.png"></td><td>Czech (Czech Republic)</td><td><div title="finished:7337 unfinished:463 untranslated:703" class="bartodo"><div class="bardone" style="width:86px">86.1</div></div></td><td>Martin Landa, Peter Antolik, Martin Dzurov, Jan Helebrant</td></tr>
<tr><td><img src="qrc:/images/flags/hu.png"></td><td>Hungarian</td><td><div title="finished:7249 unfinished:456 untranslated:798" class="bartodo"><div class="bardone" style="width:85px">85.1</div></div></td><td>Zoltan Siki</td></tr>
<tr><td><img src="qrc:/images/flags/ko_KR.png"></td><td>Korean (Korea, Republic of)</td><td><div title="finished:7208 unfinished:440 untranslated:855" class="bartodo"><div class="bardone" style="width:84px">84.5</div></div></td><td>BJ Jang</td></tr>
<tr><td><img src="qrc:/images/flags/sl_SI.png"></td><td>Slovenian (Slovenia)</td><td><div title="finished:6891 unfinished:395 untranslated:1217" class="bartodo"><div class="bardone" style="width:80px">80.7</div></div></td><td>Jože Detečnik, Dejan Gregor</td></tr>
<tr><td><img src="qrc:/images/flags/zh_CN.png"></td><td>Chinese (China)</td><td><div title="finished:6507 unfinished:323 untranslated:1673" class="bartodo"><div class="bardone" style="width:75px">75.9</div></div></td><td>Calvin Ngei, Zhang Jun</td></tr>
<tr><td><img src="qrc:/images/flags/lv.png"></td><td>Latvian</td><td><div title="finished:5906 unfinished:654 untranslated:1943" class="bartodo"><div class="bardone" style="width:70px">70.9</div></div></td><td>Maris Nartiss, Pēteris Brūns</td></tr>
<tr><td><img src="qrc:/images/flags/sr_Latn.png"></td><td>Serbian ()</td><td><div title="finished:5610 unfinished:921 untranslated:1989" class="bartodo"><div class="bardone" style="width:69px">69.1</div></div></td><td>Goran Ivanković</td></tr>
<tr><td><img src="qrc:/images/flags/sr_Cyrl.png"></td><td>Serbian ()</td><td><div title="finished:5646 unfinished:845 untranslated:2029" class="bartodo"><div class="bardone" style="width:69px">69.1</div></div></td><td>Goran Ivanković</td></tr>
<tr><td><img src="qrc:/images/flags/pt_PT.png"></td><td>Portuguese (Portugal)</td><td><div title="finished:3913 unfinished:3151 untranslated:1439" class="bartodo"><div class="bardone" style="width:62px">62.5</div></div></td><td>Giovanni Manghi, Joana Simoes, Duarte Carreira, Alexandre Neto, Pedro Pereira, Pedro Palheiro, Nelson Silva</td></tr>
<tr><td><img src="qrc:/images/flags/id.png"></td><td>Indonesian</td><td><div title="finished:4803 unfinished:936 untranslated:2764" class="bartodo"><div class="bardone" style="width:59px">60.0</div></div></td><td>Januar V. Simarmata, I Made Anombawa</td></tr>
<tr><td><img src="qrc:/images/flags/hr_HR.png"></td><td>Croatian (Croatia)</td><td><div title="finished:4914 unfinished:557 untranslated:3032" class="bartodo"><div class="bardone" style="width:59px">59.1</div></div></td><td>Zoran Jankovic</td></tr>
<tr><td><img src="qrc:/images/flags/th.png"></td><td>Thai</td><td><div title="finished:4139 unfinished:1125 untranslated:3239" class="bartodo"><div class="bardone" style="width:53px">53.5</div></div></td><td>Man Chao</td></tr>
<tr><td><img src="qrc:/images/flags/uk.png"></td><td>Ukrainian</td><td><div title="finished:3754 unfinished:1182 untranslated:3731" class="bartodo"><div class="bardone" style="width:49px">49.4</div></div></td><td>Сергей Якунин</td></tr>
<tr><td><img src="qrc:/images/flags/tr.png"></td><td>Turkish</td><td><div title="finished:3698 unfinished:938 untranslated:3867" class="bartodo"><div class="bardone" style="width:47px">47.4</div></div></td><td>Osman Yilmaz</td></tr>
<tr><td><img src="qrc:/images/flags/zh_TW.png"></td><td>Chinese (Taiwan, Province of China)</td><td><div title="finished:2447 unfinished:2630 untranslated:3426" class="bartodo"><div class="bardone" style="width:42px">42.8</div></div></td><td>Nung-yao Lin</td></tr>
<tr><td><img src="qrc:/images/flags/vi.png"></td><td>Vietnamese</td><td><div title="finished:2795 unfinished:1592 untranslated:4116" class="bartodo"><div class="bardone" style="width:40px">40.9</div></div></td><td>Bùi Hữu Mạnh</td></tr>
<tr><td><img src="qrc:/images/flags/el_GR.png"></td><td>Greek, Modern (1453-) (Greece)</td><td><div title="finished:2989 unfinished:874 untranslated:4640" class="bartodo"><div class="bardone" style="width:38px">39.0</div></div></td><td>Evripidis Argyropoulos, Mike Pegnigiannis, Nikos Ves</td></tr>
<tr><td><img src="qrc:/images/flags/is.png"></td><td>Icelandic</td><td><div title="finished:2853 unfinished:662 untranslated:4988" class="bartodo"><div class="bardone" style="width:36px">36.2</div></div></td><td>Thordur Ivarsson</td></tr>
<tr><td><img src="qrc:/images/flags/mn.png"></td><td>Mongolian</td><td><div title="finished:2488 unfinished:1098 untranslated:4917" class="bartodo"><div class="bardone" style="width:34px">34.6</div></div></td><td>Bayarmaa Enkhtur</td></tr>
<tr><td><img src="qrc:/images/flags/fi.png"></td><td>Finnish</td><td><div title="finished:1547 unfinished:1226 untranslated:5730" class="bartodo"><div class="bardone" style="width:24px">24.6</div></div></td><td>Marko Jarvenpaa</td></tr>
<tr><td><img src="qrc:/images/flags/da_DK.png"></td><td>Danish (Denmark)</td><td><div title="finished:1739 unfinished:788 untranslated:5976" class="bartodo"><div class="bardone" style="width:24px">24.3</div></div></td><td>Preben Lisby</td></tr>
<tr><td><img src="qrc:/images/flags/ka_GE.png"></td><td>Georgian (Georgia)</td><td><div title="finished:1264 unfinished:1542 untranslated:5697" class="bartodo"><div class="bardone" style="width:23px">23.2</div></div></td><td>Shota Murtskhvaladze, George Machitidze</td></tr>
<tr><td><img src="qrc:/images/flags/bg.png"></td><td>Bulgarian</td><td><div title="finished:1064 unfinished:1549 untranslated:5890" class="bartodo"><div class="bardone" style="width:20px">20.9</div></div></td><td>Захари Савов, Jordan Tzvetkov</td></tr>
<tr><td><img src="qrc:/images/flags/sk.png"></td><td>Slovak</td><td><div title="finished:736 unfinished:2014 untranslated:5753" class="bartodo"><div class="bardone" style="width:19px">19.8</div></div></td><td>Lubos Balazovic</td></tr>
<tr><td><img src="qrc:/images/flags/sq_AL.png"></td><td>Albanian (Albania)</td><td><div title="finished:844 unfinished:1396 untranslated:6263" class="bartodo"><div class="bardone" style="width:17px">17.5</div></div></td><td></td></tr>
<tr><td><img src="qrc:/images/flags/lo.png"></td><td>Lao</td><td><div title="finished:422 unfinished:1677 untranslated:6404" class="bartodo"><div class="bardone" style="width:14px">14.3</div></div></td><td>Anousak Souphavanh</td></tr>
<tr><td><img src="qrc:/images/flags/ro.png"></td><td>Romanian</td><td><div title="finished:206 unfinished:1054 untranslated:7243" class="bartodo"><div class="bardone" style="width:8px">8.3</div></div></td><td>Lonut Losifescu-Enescu</td></tr>
<tr><td><img src="qrc:/images/flags/fa.png"></td><td>Persian</td><td><div title="finished:240 unfinished:319 untranslated:7944" class="bartodo"><div class="bardone" style="width:4px">4.5</div></div></td><td>Mola Pahnadayan</td></tr>
<tr><td><img src="qrc:/images/flags/ar.png"></td><td>Arabic</td><td><div title="finished:47 unfinished:255 untranslated:8201" class="bartodo"><div class="bardone" style="width:1px">2.0</div></div></td><td>Assem Kamal, Latif Jalil</td></tr>
<tr><td><img src="qrc:/images/flags/de.png"></td><td>German</td><td><div title="finished:9010 unfinished:0 untranslated:0" class="bartodo"><div class="bardone" style="width:100px">100.0</div></div></td><td>Jürgen E. Fischer, Stephan Holl, Otto Dassau, Werner Macho</td></tr>
<tr><td><img src="qrc:/images/flags/gl_ES.png"></td><td>Galician (Spain)</td><td><div title="finished:8619 unfinished:28 untranslated:61" class="bartodo"><div class="bardone" style="width:95px">95.8</div></div></td><td>Xan Vieiro</td></tr>
<tr><td><img src="qrc:/images/flags/es.png"></td><td>Spanish</td><td><div title="finished:8438 unfinished:22 untranslated:58" class="bartodo"><div class="bardone" style="width:93px">93.8</div></div></td><td>Carlos Dávila, Javier César Aldariz, Gabriela Awad, Edwin Amado, Mayeul Kauffmann, Diana Galindo</td></tr>
<tr><td><img src="qrc:/images/flags/it.png"></td><td>Italian</td><td><div title="finished:7967 unfinished:28 untranslated:515" class="bartodo"><div class="bardone" style="width:88px">88.6</div></div></td><td>Paolo Cavallini, Flavio Rigolon, Maurizio Napolitano, Roberto Angeletti, Alessandro Fanna, Michele Beneventi, Marco Braida, Luca Casagrande, Luca Delucchi, Anne Gishla</td></tr>
<tr><td><img src="qrc:/images/flags/sv.png"></td><td>Swedish</td><td><div title="finished:7316 unfinished:1131 untranslated:109" class="bartodo"><div class="bardone" style="width:87px">87.5</div></div></td><td>Lars Luthman, Magnus Homann, Victor Axbom</td></tr>
<tr><td><img src="qrc:/images/flags/nl.png"></td><td>Dutch</td><td><div title="finished:7573 unfinished:399 untranslated:543" class="bartodo"><div class="bardone" style="width:86px">86.3</div></div></td><td>Richard Duivenvoorde, Raymond Nijssen, Carlo van Rijswijk</td></tr>
<tr><td><img src="qrc:/images/flags/ja.png"></td><td>Japanese</td><td><div title="finished:7412 unfinished:461 untranslated:630" class="bartodo"><div class="bardone" style="width:84px">84.8</div></div></td><td>BABA Yoshihiko, Yoichi Kayama</td></tr>
<tr><td><img src="qrc:/images/flags/et_EE.png"></td><td>Estonian (Estonia)</td><td><div title="finished:7412 unfinished:452 untranslated:639" class="bartodo"><div class="bardone" style="width:84px">84.8</div></div></td><td>Veiko Viil</td></tr>
<tr><td><img src="qrc:/images/flags/fr.png"></td><td>French</td><td><div title="finished:7407 unfinished:449 untranslated:647" class="bartodo"><div class="bardone" style="width:84px">84.7</div></div></td><td>Eve Rousseau, Marc Monnerat, Lionel Roubeyrie, Jean Roc Morreale, Benjamin Bohard, Jeremy Garniaux, Yves Jacolin, Benjamin Lerre, Stéphane Morel, Marie Silvestre, Tahir Tamba, Xavier M, Mayeul Kauffmann, Mehdi Semchaoui, Robin Cura, Etienne Tourigny, Mathieu Bossaert</td></tr>
<tr><td><img src="qrc:/images/flags/pt_BR.png"></td><td>Portuguese (Brazil)</td><td><div title="finished:7412 unfinished:429 untranslated:662" class="bartodo"><div class="bardone" style="width:84px">84.6</div></div></td><td>Arthur Nanni</td></tr>
<tr><td><img src="qrc:/images/flags/pl_PL.png"></td><td>Polish (Poland)</td><td><div title="finished:7412 unfinished:419 untranslated:672" class="bartodo"><div class="bardone" style="width:84px">84.6</div></div></td><td>Robert Szczepanek, Milena Nowotarska, Borys Jurgiel, Mateusz Loskot, Tomasz Paul, Andrzej Swiader </td></tr>
<tr><td><img src="qrc:/images/flags/ru.png"></td><td>Russian</td><td><div title="finished:7412 unfinished:407 untranslated:684" class="bartodo"><div class="bardone" style="width:84px">84.5</div></div></td><td>Artem Popov</td></tr>
<tr><td><img src="qrc:/images/flags/cs_CZ.png"></td><td>Czech (Czech Republic)</td><td><div title="finished:7337 unfinished:463 untranslated:703" class="bartodo"><div class="bardone" style="width:84px">84.0</div></div></td><td>Martin Landa, Peter Antolik, Martin Dzurov, Jan Helebrant</td></tr>
<tr><td><img src="qrc:/images/flags/hu.png"></td><td>Hungarian</td><td><div title="finished:7249 unfinished:456 untranslated:798" class="bartodo"><div class="bardone" style="width:82px">83.0</div></div></td><td>Zoltan Siki</td></tr>
<tr><td><img src="qrc:/images/flags/ko_KR.png"></td><td>Korean (Korea, Republic of)</td><td><div title="finished:7208 unfinished:440 untranslated:855" class="bartodo"><div class="bardone" style="width:82px">82.4</div></div></td><td>BJ Jang</td></tr>
<tr><td><img src="qrc:/images/flags/sl_SI.png"></td><td>Slovenian (Slovenia)</td><td><div title="finished:6891 unfinished:395 untranslated:1217" class="bartodo"><div class="bardone" style="width:78px">78.7</div></div></td><td>Jože Detečnik, Dejan Gregor</td></tr>
<tr><td><img src="qrc:/images/flags/zh_CN.png"></td><td>Chinese (China)</td><td><div title="finished:6507 unfinished:323 untranslated:1673" class="bartodo"><div class="bardone" style="width:74px">74.0</div></div></td><td>Calvin Ngei, Zhang Jun</td></tr>
<tr><td><img src="qrc:/images/flags/lv.png"></td><td>Latvian</td><td><div title="finished:5906 unfinished:654 untranslated:1943" class="bartodo"><div class="bardone" style="width:69px">69.2</div></div></td><td>Maris Nartiss, Pēteris Brūns</td></tr>
<tr><td><img src="qrc:/images/flags/sr_Latn.png"></td><td>Serbian ()</td><td><div title="finished:5610 unfinished:921 untranslated:1989" class="bartodo"><div class="bardone" style="width:67px">67.4</div></div></td><td>Goran Ivanković</td></tr>
<tr><td><img src="qrc:/images/flags/sr_Cyrl.png"></td><td>Serbian ()</td><td><div title="finished:5646 unfinished:845 untranslated:2029" class="bartodo"><div class="bardone" style="width:67px">67.4</div></div></td><td>Goran Ivanković</td></tr>
<tr><td><img src="qrc:/images/flags/pt_PT.png"></td><td>Portuguese (Portugal)</td><td><div title="finished:3913 unfinished:3151 untranslated:1439" class="bartodo"><div class="bardone" style="width:60px">60.9</div></div></td><td>Giovanni Manghi, Joana Simoes, Duarte Carreira, Alexandre Neto, Pedro Pereira, Pedro Palheiro, Nelson Silva</td></tr>
<tr><td><img src="qrc:/images/flags/id.png"></td><td>Indonesian</td><td><div title="finished:4803 unfinished:936 untranslated:2764" class="bartodo"><div class="bardone" style="width:58px">58.5</div></div></td><td>Januar V. Simarmata, I Made Anombawa</td></tr>
<tr><td><img src="qrc:/images/flags/hr_HR.png"></td><td>Croatian (Croatia)</td><td><div title="finished:4914 unfinished:557 untranslated:3032" class="bartodo"><div class="bardone" style="width:57px">57.6</div></div></td><td>Zoran Jankovic</td></tr>
<tr><td><img src="qrc:/images/flags/th.png"></td><td>Thai</td><td><div title="finished:4139 unfinished:1125 untranslated:3239" class="bartodo"><div class="bardone" style="width:52px">52.2</div></div></td><td>Man Chao</td></tr>
<tr><td><img src="qrc:/images/flags/uk.png"></td><td>Ukrainian</td><td><div title="finished:3754 unfinished:1182 untranslated:3731" class="bartodo"><div class="bardone" style="width:48px">48.2</div></div></td><td>Сергей Якунин</td></tr>
<tr><td><img src="qrc:/images/flags/tr.png"></td><td>Turkish</td><td><div title="finished:3698 unfinished:938 untranslated:3867" class="bartodo"><div class="bardone" style="width:46px">46.2</div></div></td><td>Osman Yilmaz</td></tr>
<tr><td><img src="qrc:/images/flags/zh_TW.png"></td><td>Chinese (Taiwan, Province of China)</td><td><div title="finished:2447 unfinished:2630 untranslated:3426" class="bartodo"><div class="bardone" style="width:41px">41.8</div></div></td><td>Nung-yao Lin</td></tr>
<tr><td><img src="qrc:/images/flags/vi.png"></td><td>Vietnamese</td><td><div title="finished:2795 unfinished:1592 untranslated:4116" class="bartodo"><div class="bardone" style="width:39px">39.9</div></div></td><td>Bùi Hữu Mạnh</td></tr>
<tr><td><img src="qrc:/images/flags/el_GR.png"></td><td>Greek, Modern (1453-) (Greece)</td><td><div title="finished:2989 unfinished:874 untranslated:4640" class="bartodo"><div class="bardone" style="width:38px">38.0</div></div></td><td>Evripidis Argyropoulos, Mike Pegnigiannis, Nikos Ves</td></tr>
<tr><td><img src="qrc:/images/flags/is.png"></td><td>Icelandic</td><td><div title="finished:2853 unfinished:662 untranslated:4988" class="bartodo"><div class="bardone" style="width:35px">35.3</div></div></td><td>Thordur Ivarsson</td></tr>
<tr><td><img src="qrc:/images/flags/mn.png"></td><td>Mongolian</td><td><div title="finished:2488 unfinished:1098 untranslated:4917" class="bartodo"><div class="bardone" style="width:33px">33.7</div></div></td><td>Bayarmaa Enkhtur</td></tr>
<tr><td><img src="qrc:/images/flags/fi.png"></td><td>Finnish</td><td><div title="finished:1547 unfinished:1226 untranslated:5730" class="bartodo"><div class="bardone" style="width:23px">24.0</div></div></td><td>Marko Jarvenpaa</td></tr>
<tr><td><img src="qrc:/images/flags/da_DK.png"></td><td>Danish (Denmark)</td><td><div title="finished:1739 unfinished:788 untranslated:5976" class="bartodo"><div class="bardone" style="width:23px">23.7</div></div></td><td>Preben Lisby</td></tr>
<tr><td><img src="qrc:/images/flags/ka_GE.png"></td><td>Georgian (Georgia)</td><td><div title="finished:1264 unfinished:1542 untranslated:5697" class="bartodo"><div class="bardone" style="width:22px">22.6</div></div></td><td>Shota Murtskhvaladze, George Machitidze</td></tr>
<tr><td><img src="qrc:/images/flags/bg.png"></td><td>Bulgarian</td><td><div title="finished:1064 unfinished:1549 untranslated:5890" class="bartodo"><div class="bardone" style="width:20px">20.4</div></div></td><td>Захари Савов, Jordan Tzvetkov</td></tr>
<tr><td><img src="qrc:/images/flags/ro.png"></td><td>Romanian</td><td><div title="finished:1100 unfinished:1443 untranslated:6255" class="bartodo"><div class="bardone" style="width:20px">20.2</div></div></td><td>Lonut Losifescu-Enescu, Bogdan Pacurar</td></tr>
<tr><td><img src="qrc:/images/flags/sk.png"></td><td>Slovak</td><td><div title="finished:736 unfinished:2014 untranslated:5753" class="bartodo"><div class="bardone" style="width:19px">19.3</div></div></td><td>Lubos Balazovic</td></tr>
<tr><td><img src="qrc:/images/flags/sq_AL.png"></td><td>Albanian (Albania)</td><td><div title="finished:844 unfinished:1396 untranslated:6263" class="bartodo"><div class="bardone" style="width:17px">17.1</div></div></td><td></td></tr>
<tr><td><img src="qrc:/images/flags/lo.png"></td><td>Lao</td><td><div title="finished:563 unfinished:1654 untranslated:6598" class="bartodo"><div class="bardone" style="width:15px">15.4</div></div></td><td>Anousak Souphavanh, Soukanh Lathsavong</td></tr>
<tr><td><img src="qrc:/images/flags/fa.png"></td><td>Persian</td><td><div title="finished:240 unfinished:319 untranslated:7944" class="bartodo"><div class="bardone" style="width:4px">4.4</div></div></td><td>Mola Pahnadayan</td></tr>
<tr><td><img src="qrc:/images/flags/ar.png"></td><td>Arabic</td><td><div title="finished:47 unfinished:255 untranslated:8201" class="bartodo"><div class="bardone" style="width:1px">1.9</div></div></td><td>Assem Kamal, Latif Jalil</td></tr>
<tr><td><img src="qrc:/images/flags/af.png"></td><td>Afrikaans</td><td><div title="finished:0 unfinished:341 untranslated:8162" class="bartodo"><div class="bardone" style="width:1px">1.9</div></div></td><td>Hendrik Bosman</td></tr>
<tr><td><img src="qrc:/images/flags/lt.png"></td><td>Lithuanian</td><td><div title="finished:6 unfinished:116 untranslated:8381" class="bartodo"><div class="bardone" style="width:0px">0.7</div></div></td><td>Kestas M</td></tr>
<tr><td><img src="qrc:/images/flags/he.png"></td><td>Hebrew</td><td><div title="finished:0 unfinished:18 untranslated:8485" class="bartodo"><div class="bardone" style="width:0px">0.1</div></div></td><td></td></tr>

File diff suppressed because it is too large Load Diff

View File

@ -196,6 +196,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>
@ -421,10 +422,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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -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 ^
@ -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

View File

@ -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 ^
@ -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" ^
@ -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

View File

@ -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=

12
scripts/licenses Normal file
View File

@ -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\)$

View File

@ -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

View File

@ -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 );

View File

@ -381,9 +381,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() )
{
@ -392,7 +392,8 @@ void QgisApp::validateSrs( QgsCoordinateReferenceSystem* srs )
srs->createFromOgcWmsCrs( mySelector->selectedAuthId() );
}
//QApplication::restoreOverrideCursor();
if ( waiting )
QApplication::restoreOverrideCursor();
delete mySelector;
}
@ -943,6 +944,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() ) );
@ -1030,19 +1032,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
}
@ -1624,6 +1631,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" ) );
@ -2798,11 +2808,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;
@ -2821,8 +2829,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 )
{
@ -2891,11 +2899,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;
@ -2912,15 +2918,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;
@ -2937,9 +2940,30 @@ void QgisApp::addMssqlLayer()
this , SLOT( addDatabaseLayers( QStringList const &, QString const & ) ) );
dbs->exec();
delete dbs;
} // QgisApp::addMssqlLayer()
#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()
{

View File

@ -541,9 +541,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

View File

@ -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

View File

@ -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;
}
}
@ -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.

View File

@ -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 ) );
@ -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;
switch ( wkbType() )
{
case QGis::WKBPoint:
case QGis::WKBPoint25D:
case QGis::WKBMultiPoint:
case QGis::WKBMultiPoint25D:
return QGis::Point;
return QGis::UnknownGeometry;
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()
@ -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;

View File

@ -623,9 +623,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

View File

@ -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

View File

@ -496,7 +496,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();
}

View File

@ -2415,7 +2415,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 )
@ -4297,7 +4297,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 );

View File

@ -24,6 +24,9 @@
#include "qgscoordinatereferencesystem.h"
#include "qgsvectorlayerimport.h"
#include "qgsproviderregistry.h"
#include "qgsdatasourceuri.h"
#include <QProgressDialog>
#define FEATURE_BUFFER_SIZE 200
@ -173,6 +176,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,
@ -360,6 +374,14 @@ QgsVectorLayerImport::importLayer( QgsVectorLayer* layer,
}
int errors = writer->errorCount();
if ( !writer->createSpatialIndex() )
{
if ( writer->hasError() && errorMessage )
{
*errorMessage += "\n" + writer->errorMessage();
}
}
delete writer;
if ( shallTransform )

View File

@ -90,6 +90,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;

View File

@ -352,7 +352,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 ) );
}
}

View File

@ -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 )

View File

@ -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;
}

View File

@ -114,6 +114,9 @@ void QgsManageConnectionsDialog::doExportImport()
case WCS:
doc = saveOWSConnections( items, "WCS" );
break;
case Oracle:
doc = saveOracleConnections( items );
break;
}
QFile file( mFileName );
@ -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();
@ -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();
@ -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();
@ -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();
@ -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;
}
@ -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();

View File

@ -39,7 +39,8 @@ class GUI_EXPORT QgsManageConnectionsDialog : public QDialog, private Ui::QgsMan
PostGIS,
WFS,
MSSQL,
WCS
WCS,
Oracle,
};
// constructor
@ -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;

View File

@ -3617,7 +3617,7 @@ void QgsGrassModuleField::updateFields()
QgsFields 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() ) )
{

View File

@ -13,6 +13,10 @@ ADD_SUBDIRECTORY(gdal)
ADD_SUBDIRECTORY(ows)
ADD_SUBDIRECTORY(wcs)
IF (WITH_ORACLE)
ADD_SUBDIRECTORY(oracle)
ENDIF(WITH_ORACLE)
IF (POSTGRES_FOUND)
ADD_SUBDIRECTORY(postgres)
ENDIF (POSTGRES_FOUND)

View File

@ -33,7 +33,6 @@ class QPushButton;
class QStringList;
class QgsGeomColumnTypeThread;
class QgisApp;
class QgsPgSourceSelect;
class QgsMssqlSourceSelectDelegate : public QItemDelegate
{

View File

@ -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})

View File

@ -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
)

View File

@ -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).

View File

@ -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)

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -0,0 +1,695 @@
/***************************************************************************
qgsoracleconn.cpp - 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. *
* *
***************************************************************************/
#include "qgsoracleconn.h"
#include "qgslogger.h"
#include "qgsdatasourceuri.h"
#include "qgsmessagelog.h"
#include "qgscredentials.h"
#include "qgsfield.h"
#include "qgsoracletablemodel.h"
#include "qgsdatasourceuri.h"
#include <QSettings>
#include <QSqlError>
QMap<QString, QgsOracleConn *> QgsOracleConn::sConnections;
int QgsOracleConn::snConnections = 0;
const int QgsOracleConn::sGeomTypeSelectLimit = 100;
QgsOracleConn *QgsOracleConn::connectDb( QgsDataSourceURI uri )
{
QString conninfo = uri.connectionInfo();
if ( sConnections.contains( conninfo ) )
{
QgsDebugMsg( QString( "Using cached connection for %1" ).arg( conninfo ) );
sConnections[conninfo]->mRef++;
return sConnections[conninfo];
}
QgsOracleConn *conn = new QgsOracleConn( uri );
if ( conn->mRef == 0 )
{
delete conn;
return 0;
}
sConnections.insert( conninfo, conn );
return conn;
}
QgsOracleConn::QgsOracleConn( QgsDataSourceURI uri )
: mRef( 1 )
, mCurrentUser( QString::null )
, mHasSpatial( -1 )
{
QgsDebugMsg( QString( "New Oracle connection for " ) + uri.connectionInfo() );
QString database = databaseName( uri.database(), uri.host(), uri.port() );
QgsDebugMsg( QString( "New Oracle database " ) + database );
mDatabase = QSqlDatabase::addDatabase( "QOCISPATIAL", QString( "oracle%1" ).arg( snConnections++ ) );
mDatabase.setDatabaseName( database );
mDatabase.setUserName( uri.username() );
mDatabase.setPassword( uri.password() );
if ( !mDatabase.open() )
{
QString username = uri.username();
QString password = uri.password();
while ( !mDatabase.open() )
{
bool ok = QgsCredentials::instance()->get( database, username, password, mDatabase.lastError().text() );
if ( !ok )
break;
if ( !username.isEmpty() )
uri.setUsername( username );
if ( !password.isEmpty() )
uri.setPassword( password );
QgsDebugMsg( "Connecting to " + database );
mDatabase.setUserName( username );
mDatabase.setPassword( password );
}
if ( mDatabase.isOpen() )
QgsCredentials::instance()->put( database, username, password );
}
if ( !mDatabase.isOpen() )
{
mDatabase.close();
QgsMessageLog::logMessage( tr( "Connection to database failed" ), tr( "Oracle" ) );
mRef = 0;
return;
}
}
QgsOracleConn::~QgsOracleConn()
{
Q_ASSERT( mRef == 0 );
if ( mDatabase.isOpen() )
mDatabase.close();
}
QString QgsOracleConn::connInfo()
{
return sConnections.key( this, QString::null );
}
void QgsOracleConn::disconnect()
{
if ( --mRef > 0 )
return;
QString key = sConnections.key( this, QString::null );
if ( !key.isNull() )
{
sConnections.remove( key );
}
else
{
QgsDebugMsg( "Connection not found" );
}
deleteLater();
}
bool QgsOracleConn::exec( QSqlQuery &qry, QString sql )
{
QgsDebugMsgLevel( QString( "SQL: %1" ).arg( sql ), 4 );
bool res = qry.exec( sql );
if ( !res )
{
QgsDebugMsg( QString( "SQL: %1\nERROR: %2" )
.arg( qry.lastQuery() )
.arg( qry.lastError().text() ) );
}
return res;
}
QStringList QgsOracleConn::pkCandidates( QString ownerName, QString viewName )
{
QStringList cols;
QSqlQuery qry( mDatabase );
if ( !exec( qry, QString( "SELECT column_name FROM all_tab_columns WHERE owner=%1 AND table_name=%2 AND data_type='NUMBER' AND data_scale=0" )
.arg( quotedValue( ownerName ) ).arg( quotedValue( viewName ) ) ) )
{
QgsMessageLog::logMessage( tr( "SQL:%1\nerror:%2\n" ).arg( qry.lastQuery() ).arg( qry.lastError().text() ), tr( "Oracle" ) );
return cols;
}
while ( qry.next() )
{
cols << qry.value( 0 ).toString();
}
qry.finish();
return cols;
}
bool QgsOracleConn::tableInfo( bool geometryTablesOnly, bool userTablesOnly, bool allowGeometrylessTables )
{
QgsDebugMsg( "Entering." );
mLayersSupported.clear();
QString sql, delim;
sql = QString( "SELECT c.owner,c.table_name,c.column_name,%1,t.table_name AS isview"
" FROM %2 c"
" LEFT OUTER JOIN all_tables t ON c.owner=t.owner AND c.table_name=t.table_name%3" )
.arg( geometryTablesOnly ? "c.srid" : "NULL AS srid" )
.arg( geometryTablesOnly ? "all_sdo_geom_metadata" : "all_tab_columns" )
.arg( geometryTablesOnly ? "" : " WHERE c.data_type='SDO_GEOMETRY' AND c.data_type_owner='MDSYS'" );
if ( allowGeometrylessTables )
{
sql += " UNION SELECT owner,table_name,NULL AS column_name,NULL AS srid,table_name AS isview FROM all_tables"
" UNION SELECT owner,view_name,NULL AS column_name,NULL AS srid,NULL AS isview FROM all_views";
}
sql = "SELECT * FROM (" + sql + ")";
if ( userTablesOnly )
{
sql += " WHERE owner=user";
}
sql += " ORDER BY owner,isview,table_name,column_name";
QSqlQuery qry( mDatabase );
if ( !exec( qry, sql ) )
{
QgsMessageLog::logMessage( tr( "Querying available tables failed.\nSQL:%1\nerror:%2\n" ).arg( qry.lastQuery() ).arg( qry.lastError().text() ), tr( "Oracle" ) );
return false;
}
while ( qry.next() )
{
QgsOracleLayerProperty layerProperty;
layerProperty.ownerName = qry.value( 0 ).toString();
layerProperty.tableName = qry.value( 1 ).toString();
layerProperty.geometryColName = qry.value( 2 ).toString();
layerProperty.srids = QList<int>() << qry.value( 3 ).toInt();
layerProperty.types = QList<QGis::WkbType>() << QGis::WKBUnknown; // detect
layerProperty.isView = qry.value( 4 ).isNull();
layerProperty.pkCols.clear();
mLayersSupported << layerProperty;
}
if ( mLayersSupported.size() == 0 )
{
QgsMessageLog::logMessage( tr( "Database connection was successful, but the accessible tables could not be determined." ), tr( "Oracle" ) );
}
return true;
}
bool QgsOracleConn::supportedLayers( QVector<QgsOracleLayerProperty> &layers, bool geometryTablesOnly, bool userTablesOnly, bool allowGeometrylessTables )
{
// Get the list of supported tables
if ( !tableInfo( geometryTablesOnly, userTablesOnly, allowGeometrylessTables ) )
{
QgsMessageLog::logMessage( tr( "Unable to get list of spatially enabled tables from the database" ), tr( "Oracle" ) );
return false;
}
layers = mLayersSupported;
QgsDebugMsg( "Exiting." );
return true;
}
QString QgsOracleConn::quotedIdentifier( QString ident )
{
ident.replace( '"', "\"\"" );
ident = ident.prepend( "\"" ).append( "\"" );
return ident;
}
QString QgsOracleConn::quotedValue( QVariant value )
{
if ( value.isNull() )
return "NULL";
switch ( value.type() )
{
case QVariant::Int:
case QVariant::LongLong:
case QVariant::Double:
return value.toString();
default:
case QVariant::String:
QString v = value.toString();
v.replace( "'", "''" );
v.replace( "\\\"", "\\\\\"" );
return v.prepend( "'" ).append( "'" );
}
}
QString QgsOracleConn::fieldExpression( const QgsField &fld )
{
#if 0
const QString &type = fld.typeName();
if ( type == "money" )
{
return QString( "cash_out(%1)" ).arg( quotedIdentifier( fld.name() ) );
}
else if ( type.startsWith( "_" ) )
{
return QString( "array_out(%1)" ).arg( quotedIdentifier( fld.name() ) );
}
else if ( type == "bool" )
{
return QString( "boolout(%1)" ).arg( quotedIdentifier( fld.name() ) );
}
else if ( type == "geometry" )
{
return QString( "%1(%2)" )
.arg( majorVersion() < 2 ? "asewkt" : "st_asewkt" )
.arg( quotedIdentifier( fld.name() ) );
}
else if ( type == "geography" )
{
return QString( "st_astext(%1)" ).arg( quotedIdentifier( fld.name() ) );
}
else
{
return quotedIdentifier( fld.name() ) + "::text";
}
#else
return quotedIdentifier( fld.name() );
#endif
}
void QgsOracleConn::retrieveLayerTypes( QgsOracleLayerProperty &layerProperty, bool useEstimatedMetadata )
{
QgsDebugMsg( "entering: " + layerProperty.toString() );
QString table;
QString where;
if ( useEstimatedMetadata )
{
table = QString( "(SELECT %1 FROM %2.%3 WHERE %1 IS NOT NULL%4 AND rownum<=%5)" )
.arg( quotedIdentifier( layerProperty.geometryColName ) )
.arg( quotedIdentifier( layerProperty.ownerName ) )
.arg( quotedIdentifier( layerProperty.tableName ) )
.arg( layerProperty.sql.isEmpty() ? "" : QString( " AND (%1)" ).arg( layerProperty.sql ) )
.arg( sGeomTypeSelectLimit );
}
else if ( !layerProperty.ownerName.isEmpty() )
{
table = QString( "%1.%2" )
.arg( quotedIdentifier( layerProperty.ownerName ) )
.arg( quotedIdentifier( layerProperty.tableName ) );
where = layerProperty.sql;
}
else
{
table = quotedIdentifier( layerProperty.tableName );
where = layerProperty.sql;
}
QSqlQuery qry( mDatabase );
QString sql = QString( "SELECT DISTINCT t.%1.SDO_GTYPE,t.%1.SDO_SRID FROM %2 t WHERE NOT t.%1 IS NULL%3" )
.arg( quotedIdentifier( layerProperty.geometryColName ) )
.arg( table )
.arg( where.isEmpty() ? "" : QString( " AND (%1)" ).arg( where ) );
if ( !exec( qry, sql ) )
{
QgsMessageLog::logMessage( tr( "SQL:%1\nerror:%2\n" )
.arg( qry.lastQuery() )
.arg( qry.lastError().text() ),
tr( "Oracle" ) );
return;
}
layerProperty.types.clear();
layerProperty.srids.clear();
QSet<int> srids;
while ( qry.next() )
{
QGis::WkbType type = wkbTypeFromDatabase( qry.value( 0 ).toInt() );
if ( type == QGis::WKBUnknown )
{
QgsMessageLog::logMessage( tr( "Unsupported geometry type %1 in %2.%3.%4 ignored" )
.arg( qry.value( 0 ).toInt() )
.arg( layerProperty.ownerName ).arg( layerProperty.tableName ).arg( layerProperty.geometryColName ),
tr( "Oracle" ) );
continue;
}
QgsDebugMsg( QString( "add type %1" ).arg( type ) );
layerProperty.types << type;
layerProperty.srids << ( qry.value( 1 ).isNull() ? 0 : qry.value( 1 ).toInt() );
srids << ( qry.value( 1 ).isNull() ? 0 : qry.value( 1 ).toInt() );
}
qry.finish();
if ( srids.size() == 1 )
{
layerProperty.types << QGis::WKBUnknown;
layerProperty.srids << *srids.constBegin();
}
if ( layerProperty.isView )
{
layerProperty.pkCols = pkCandidates( layerProperty.ownerName, layerProperty.tableName );
if ( layerProperty.pkCols.isEmpty() )
{
QgsMessageLog::logMessage( tr( "View %1.%2 doesn't have integer columns for use as keys." )
.arg( layerProperty.ownerName ).arg( layerProperty.tableName ),
tr( "Oracle" ) );
}
}
QgsDebugMsg( "leaving." );
}
QString QgsOracleConn::databaseTypeFilter( QString alias, QString geomCol, QGis::WkbType geomType )
{
geomCol = quotedIdentifier( alias ) + "." + quotedIdentifier( geomCol );
switch ( geomType )
{
case QGis::WKBPoint:
case QGis::WKBPoint25D:
case QGis::WKBMultiPoint:
case QGis::WKBMultiPoint25D:
return QString( "mod(%1.sdo_gtype,100) IN (1,5)" ).arg( geomCol );
case QGis::WKBLineString:
case QGis::WKBLineString25D:
case QGis::WKBMultiLineString:
case QGis::WKBMultiLineString25D:
return QString( "mod(%1.sdo_gtype,100) IN (2,6)" ).arg( geomCol );
case QGis::WKBPolygon:
case QGis::WKBPolygon25D:
case QGis::WKBMultiPolygon:
case QGis::WKBMultiPolygon25D:
return QString( "mod(%1.sdo_gtype,100) IN (3,7)" ).arg( geomCol );
case QGis::WKBNoGeometry:
return QString( "%1 IS NULL" ).arg( geomCol );
case QGis::WKBUnknown:
Q_ASSERT( !"unknown geometry unexpected" );
return QString::null;
}
Q_ASSERT( !"unexpected geomType" );
return QString::null;
}
QGis::WkbType QgsOracleConn::wkbTypeFromDatabase( int gtype )
{
QgsDebugMsg( QString( "entering %1" ).arg( gtype ) );
int t = gtype % 100;
if ( t == 0 )
return QGis::WKBUnknown;
int d = gtype / 1000;
if ( d == 2 )
{
switch ( t )
{
case 1:
return QGis::WKBPoint;
case 2:
return QGis::WKBLineString;
case 3:
return QGis::WKBPolygon;
case 4:
QgsDebugMsg( QString( "geometry collection type %1 unsupported" ).arg( gtype ) );
return QGis::WKBUnknown;
case 5:
return QGis::WKBMultiPoint;
case 6:
return QGis::WKBMultiLineString;
case 7:
return QGis::WKBMultiPolygon;
default:
QgsDebugMsg( QString( "gtype %1 unsupported" ).arg( gtype ) );
return QGis::WKBUnknown;
}
}
else if ( d == 3 )
{
switch ( t )
{
case 1:
return QGis::WKBPoint25D;
case 2:
return QGis::WKBLineString25D;
case 3:
return QGis::WKBPolygon25D;
case 4:
QgsDebugMsg( QString( "geometry collection type %1 unsupported" ).arg( gtype ) );
return QGis::WKBUnknown;
case 5:
return QGis::WKBMultiPoint25D;
case 6:
return QGis::WKBMultiLineString25D;
case 7:
return QGis::WKBMultiPolygon25D;
default:
QgsDebugMsg( QString( "gtype %1 unsupported" ).arg( gtype ) );
return QGis::WKBUnknown;
}
}
else
{
QgsDebugMsg( QString( "dimension of gtype %1 unsupported" ).arg( gtype ) );
return QGis::WKBUnknown;
}
}
QString QgsOracleConn::displayStringForWkbType( QGis::WkbType type )
{
switch ( type )
{
case QGis::WKBPoint:
case QGis::WKBPoint25D:
return tr( "Point" );
case QGis::WKBMultiPoint:
case QGis::WKBMultiPoint25D:
return tr( "Multipoint" );
case QGis::WKBLineString:
case QGis::WKBLineString25D:
return tr( "Line" );
case QGis::WKBMultiLineString:
case QGis::WKBMultiLineString25D:
return tr( "Multiline" );
case QGis::WKBPolygon:
case QGis::WKBPolygon25D:
return tr( "Polygon" );
case QGis::WKBMultiPolygon:
case QGis::WKBMultiPolygon25D:
return tr( "Multipolygon" );
case QGis::WKBNoGeometry:
return tr( "No Geometry" );
case QGis::WKBUnknown:
return tr( "Unknown Geometry" );
}
Q_ASSERT( !"unexpected wkbType" );
return QString::null;
}
QGis::WkbType QgsOracleConn::wkbTypeFromGeomType( QGis::GeometryType geomType )
{
switch ( geomType )
{
case QGis::Point:
return QGis::WKBPoint;
case QGis::Line:
return QGis::WKBLineString;
case QGis::Polygon:
return QGis::WKBPolygon;
case QGis::NoGeometry:
return QGis::WKBNoGeometry;
case QGis::UnknownGeometry:
return QGis::WKBUnknown;
}
Q_ASSERT( !"unexpected geomType" );
return QGis::WKBUnknown;
}
QStringList QgsOracleConn::connectionList()
{
QSettings settings;
settings.beginGroup( "/Oracle/connections" );
return settings.childGroups();
}
void QgsOracleConn::deleteConnection( QString theConnName )
{
QSettings settings;
QString key = "/Oracle/connections/" + theConnName;
settings.remove( key + "/host" );
settings.remove( key + "/port" );
settings.remove( key + "/database" );
settings.remove( key + "/username" );
settings.remove( key + "/password" );
settings.remove( key + "/publicOnly" );
settings.remove( key + "/geometryColumnsOnly" );
settings.remove( key + "/allowGeometrylessTables" );
settings.remove( key + "/estimatedMetadata" );
settings.remove( key + "/saveUsername" );
settings.remove( key + "/savePassword" );
settings.remove( key + "/save" );
settings.remove( key );
}
QString QgsOracleConn::selectedConnection()
{
QSettings settings;
return settings.value( "/Oracle/connections/selected" ).toString();
}
void QgsOracleConn::setSelectedConnection( QString name )
{
QSettings settings;
return settings.setValue( "/Oracle/connections/selected", name );
}
QgsDataSourceURI QgsOracleConn::connUri( QString theConnName )
{
QgsDebugMsg( "theConnName = " + theConnName );
QSettings settings;
QString key = "/Oracle/connections/" + theConnName;
QString service = settings.value( key + "/service" ).toString();
QString host = settings.value( key + "/host" ).toString();
QString port = settings.value( key + "/port" ).toString();
if ( port.length() == 0 )
{
port = "1521";
}
bool useEstimatedMetadata = settings.value( key + "/estimatedMetadata", false ).toBool();
QString username;
QString password;
if ( settings.value( key + "/saveUsername" ).toString() == "true" )
{
username = settings.value( key + "/username" ).toString();
}
if ( settings.value( key + "/savePassword" ).toString() == "true" )
{
password = settings.value( key + "/password" ).toString();
}
QgsDataSourceURI uri;
uri.setConnection( host, port, QString::null, username, password );
uri.setUseEstimatedMetadata( useEstimatedMetadata );
return uri;
}
bool QgsOracleConn::userTablesOnly( QString theConnName )
{
QSettings settings;
return settings.value( "/Oracle/connections/" + theConnName + "/userTablesOnly", false ).toBool();
}
bool QgsOracleConn::allowGeometrylessTables( QString theConnName )
{
QSettings settings;
return settings.value( "/Oracle/connections/" + theConnName + "/allowGeometrylessTables", false ).toBool();
}
QString QgsOracleConn::databaseName( QString serviceName, QString host, QString port )
{
QString db;
if ( !host.isEmpty() )
{
db += host;
if ( !port.isEmpty() && port != "1521" )
{
db += QString( ":%1" ).arg( port );
}
if ( !serviceName.isEmpty() )
{
db += "/" + serviceName;
}
}
else if ( !serviceName.isEmpty() )
{
db = serviceName;
}
return db;
}
bool QgsOracleConn::hasSpatial()
{
if ( mHasSpatial == -1 )
{
QSqlQuery qry( mDatabase );
mHasSpatial = exec( qry, "SELECT 1 FROM v$option WHERE parameter='Spatial' AND value='TRUE'" ) && qry.next();
}
return mHasSpatial;
}
QString QgsOracleConn::currentUser()
{
if ( mCurrentUser.isNull() )
{
QSqlQuery qry( mDatabase );
if ( exec( qry, "SELECT user FROM dual" ) && qry.next() )
{
mCurrentUser = qry.value( 0 ).toString();
}
}
return mCurrentUser;
}
// vim: sw=2 :

View File

@ -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

View File

@ -0,0 +1,473 @@
/***************************************************************************
qgsoracledataitems.cpp
---------------------
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 "qgsoracledataitems.h"
#include "qgsoracletablemodel.h"
#include "qgsoraclenewconnection.h"
#include "qgsoraclecolumntypethread.h"
#include "qgslogger.h"
#include "qgsdatasourceuri.h"
#include "qgsapplication.h"
#include <QMessageBox>
#include <QProgressDialog>
QGISEXTERN bool deleteLayer( const QString& uri, QString& errCause );
// ---------------------------------------------------------------------------
QgsOracleConnectionItem::QgsOracleConnectionItem( QgsDataItem* parent, QString name, QString path )
: QgsDataCollectionItem( parent, name, path )
, mColumnTypeThread( 0 )
{
mIcon = QgsApplication::getThemeIcon( "mIconConnect.png" );
}
QgsOracleConnectionItem::~QgsOracleConnectionItem()
{
stop();
}
void QgsOracleConnectionItem::stop()
{
if ( mColumnTypeThread )
{
mColumnTypeThread->stop();
mColumnTypeThread->wait();
delete mColumnTypeThread;
mColumnTypeThread = 0;
}
}
void QgsOracleConnectionItem::refresh()
{
QgsDebugMsg( "Entering." );
QApplication::setOverrideCursor( Qt::WaitCursor );
stop();
foreach ( QgsDataItem *child, mChildren )
{
QgsDebugMsg( QString( "Deleting child: %1" ).arg( child->name() ) );
deleteChildItem( child );
}
foreach ( QgsDataItem *item, createChildren() )
{
QgsDebugMsg( QString( "Adding child %1" ).arg( item->name() ) );
addChildItem( item, true );
}
QApplication::restoreOverrideCursor();
QgsDebugMsg( "Leaving." );
}
QVector<QgsDataItem*> QgsOracleConnectionItem::createChildren()
{
QgsDebugMsg( "Entered" );
QVector<QgsDataItem*> children;
QgsDataSourceURI uri = QgsOracleConn::connUri( mName );
mOwnerMap.clear();
mConn = QgsOracleConn::connectDb( uri.connectionInfo() );
if ( !mConn )
return children;
QVector<QgsOracleLayerProperty> layerProperties;
if ( !mConn->supportedLayers( layerProperties,
QgsOracleConn::userTablesOnly( mName ),
QgsOracleConn::allowGeometrylessTables( mName ) ) )
{
children.append( new QgsErrorItem( this, tr( "Failed to retrieve layers" ), mPath + "/error" ) );
return children;
}
if ( layerProperties.isEmpty() )
{
children.append( new QgsErrorItem( this, tr( "No layers found." ), mPath + "/error" ) );
return children;
}
stop();
foreach ( QgsOracleLayerProperty layerProperty, layerProperties )
{
QgsOracleOwnerItem *ownerItem = mOwnerMap.value( layerProperty.ownerName, 0 );
if ( !ownerItem )
{
ownerItem = new QgsOracleOwnerItem( this, layerProperty.ownerName, mPath + "/" + layerProperty.ownerName );
children.append( ownerItem );
mOwnerMap[ layerProperty.ownerName ] = ownerItem;
}
if ( !layerProperty.geometryColName.isNull() )
{
if ( layerProperty.types.contains( QGis::WKBUnknown ) || layerProperty.srids.isEmpty() )
{
if ( !mColumnTypeThread )
{
QgsOracleConn *conn = QgsOracleConn::connectDb( uri.connectionInfo() );
if ( conn )
{
mColumnTypeThread = new QgsOracleColumnTypeThread( conn, true /* use estimated metadata */ );
connect( mColumnTypeThread, SIGNAL( setLayerType( QgsOracleLayerProperty ) ),
this, SLOT( setLayerType( QgsOracleLayerProperty ) ) );
connect( this, SIGNAL( addGeometryColumn( QgsOracleLayerProperty ) ),
mColumnTypeThread, SLOT( addGeometryColumn( QgsOracleLayerProperty ) ) );
}
}
emit addGeometryColumn( layerProperty );
}
}
else
{
ownerItem->addLayer( layerProperty );
}
}
if ( mColumnTypeThread )
mColumnTypeThread->start();
return children;
}
void QgsOracleConnectionItem::setLayerType( QgsOracleLayerProperty layerProperty )
{
QgsDebugMsg( layerProperty.toString() );
QgsOracleOwnerItem *ownerItem = mOwnerMap.value( layerProperty.ownerName, 0 );
if ( !ownerItem )
{
QgsDebugMsg( QString( "owner item for %1 not found." ).arg( layerProperty.ownerName ) );
return;
}
for ( int i = 0 ; i < layerProperty.size(); i++ )
{
QGis::WkbType wkbType = layerProperty.types.at( i );
if ( wkbType == QGis::WKBUnknown )
{
// skip any geometry entry
continue;
}
ownerItem->addLayer( layerProperty.at( i ) );
}
}
bool QgsOracleConnectionItem::equal( const QgsDataItem *other )
{
if ( type() != other->type() )
{
return false;
}
const QgsOracleConnectionItem *o = qobject_cast<const QgsOracleConnectionItem *>( other );
return ( mPath == o->mPath && mName == o->mName && o->connection() == connection() );
}
QList<QAction*> QgsOracleConnectionItem::actions()
{
QList<QAction*> lst;
QAction* actionEdit = new QAction( tr( "Edit..." ), this );
connect( actionEdit, SIGNAL( triggered() ), this, SLOT( editConnection() ) );
lst.append( actionEdit );
QAction* actionDelete = new QAction( tr( "Delete" ), this );
connect( actionDelete, SIGNAL( triggered() ), this, SLOT( deleteConnection() ) );
lst.append( actionDelete );
return lst;
}
void QgsOracleConnectionItem::editConnection()
{
QgsOracleNewConnection nc( NULL, mName );
if ( nc.exec() )
{
// the parent should be updated
mParent->refresh();
}
}
void QgsOracleConnectionItem::deleteConnection()
{
QgsOracleConn::deleteConnection( mName );
// the parent should be updated
mParent->refresh();
}
bool QgsOracleConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction )
{
if ( !QgsMimeDataUtils::isUriList( data ) )
return false;
// TODO: probably should show a GUI with settings etc
QgsDataSourceURI uri = QgsOracleConn::connUri( mName );
qApp->setOverrideCursor( Qt::WaitCursor );
QProgressDialog *progress = new QProgressDialog( tr( "Copying features..." ), tr( "Abort" ), 0, 0, 0 );
progress->setWindowTitle( tr( "Import layer" ) );
progress->setWindowModality( Qt::WindowModal );
progress->show();
QStringList importResults;
bool hasError = false;
QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data );
foreach ( const QgsMimeDataUtils::Uri& u, lst )
{
if ( u.layerType != "vector" )
{
importResults.append( tr( "%1: Not a vector layer!" ).arg( u.name ) );
hasError = true; // only vectors can be imported
continue;
}
// open the source layer
QgsVectorLayer* srcLayer = new QgsVectorLayer( u.uri, u.name, u.providerKey );
if ( srcLayer->isValid() )
{
uri.setDataSource( QString(), u.name.left( 30 ).toUpper(), "QGS_GEOMETRY" );
uri.setWkbType( srcLayer->wkbType() );
QString authid = srcLayer->crs().authid();
if( authid.startsWith( "EPSG:", Qt::CaseInsensitive ) )
{
uri.setSrid( authid.mid( 5 ) );
}
QgsDebugMsg( "URI " + uri.uri() );
QgsVectorLayerImport::ImportError err;
QString importError;
err = QgsVectorLayerImport::importLayer( srcLayer, uri.uri(), "oracle", &srcLayer->crs(), false, &importError, false, 0, progress );
if ( err == QgsVectorLayerImport::NoError )
importResults.append( tr( "%1: OK!" ).arg( u.name ) );
else
{
importResults.append( QString( "%1: %2" ).arg( u.name ).arg( importError ) );
hasError = true;
}
}
else
{
importResults.append( tr( "%1: OK!" ).arg( u.name ) );
hasError = true;
}
delete srcLayer;
}
delete progress;
qApp->restoreOverrideCursor();
if ( hasError )
{
QMessageBox::warning( 0, tr( "Import to Oracle database" ), tr( "Failed to import some layers!\n\n" ) + importResults.join( "\n" ) );
}
else
{
QMessageBox::information( 0, tr( "Import to Oracle database" ), tr( "Import was successful." ) );
}
refresh();
return true;
}
// ---------------------------------------------------------------------------
QgsOracleLayerItem::QgsOracleLayerItem( QgsDataItem* parent, QString name, QString path, QgsLayerItem::LayerType layerType, QgsOracleLayerProperty layerProperty )
: QgsLayerItem( parent, name, path, QString(), layerType, "oracle" )
, mLayerProperty( layerProperty )
{
mUri = createUri();
mPopulated = true;
}
QgsOracleLayerItem::~QgsOracleLayerItem()
{
}
QList<QAction*> QgsOracleLayerItem::actions()
{
QList<QAction*> lst;
QAction* actionDeleteLayer = new QAction( tr( "Delete layer" ), this );
connect( actionDeleteLayer, SIGNAL( triggered() ), this, SLOT( deleteLayer() ) );
lst.append( actionDeleteLayer );
return lst;
}
void QgsOracleLayerItem::deleteLayer()
{
QString errCause;
bool res = ::deleteLayer( mUri, errCause );
if ( !res )
{
QMessageBox::warning( 0, tr( "Delete layer" ), errCause );
}
else
{
QMessageBox::information( 0, tr( "Delete layer" ), tr( "Layer deleted successfully." ) );
mParent->refresh();
}
}
QString QgsOracleLayerItem::createUri()
{
QString pkColName = mLayerProperty.pkCols.size() > 0 ? mLayerProperty.pkCols.at( 0 ) : QString::null;
QgsOracleConnectionItem *connItem = qobject_cast<QgsOracleConnectionItem *>( parent() ? parent()->parent() : 0 );
if ( !connItem )
{
QgsDebugMsg( "connection item not found." );
return QString::null;
}
QgsDebugMsg( QString( "connInfo: %1" ).arg( connItem->connection()->connInfo() ) );
QgsDataSourceURI uri( connItem->connection()->connInfo() );
uri.setDataSource( mLayerProperty.ownerName, mLayerProperty.tableName, mLayerProperty.geometryColName, mLayerProperty.sql, QString::null );
Q_ASSERT( mLayerProperty.size() == 1 );
uri.setSrid( QString::number( mLayerProperty.srids.at( 0 ) ) );
uri.setWkbType( mLayerProperty.types.at( 0 ) );
QgsDebugMsg( QString( "layer uri: %1" ).arg( uri.uri() ) );
return uri.uri();
}
// ---------------------------------------------------------------------------
QgsOracleOwnerItem::QgsOracleOwnerItem( QgsDataItem* parent, QString name, QString path )
: QgsDataCollectionItem( parent, name, path )
{
mIcon = QgsApplication::getThemeIcon( "mIconDbOwner.png" );
}
QVector<QgsDataItem*> QgsOracleOwnerItem::createChildren()
{
QgsDebugMsg( "Entering." );
return QVector<QgsDataItem*>();
}
QgsOracleOwnerItem::~QgsOracleOwnerItem()
{
}
void QgsOracleOwnerItem::addLayer( QgsOracleLayerProperty layerProperty )
{
QgsDebugMsg( layerProperty.toString() );
Q_ASSERT( layerProperty.size() == 1 );
QGis::WkbType wkbType = layerProperty.types.at( 0 );
QString tip = tr( "%1 as %2 in %3" ).arg( layerProperty.geometryColName ).arg( QgsOracleConn::displayStringForWkbType( wkbType ) ).arg( layerProperty.srids.at( 0 ) );
QgsLayerItem::LayerType layerType;
switch ( wkbType )
{
case QGis::WKBPoint:
case QGis::WKBPoint25D:
case QGis::WKBMultiPoint:
case QGis::WKBMultiPoint25D:
layerType = QgsLayerItem::Point;
break;
case QGis::WKBLineString:
case QGis::WKBLineString25D:
case QGis::WKBMultiLineString:
case QGis::WKBMultiLineString25D:
layerType = QgsLayerItem::Line;
break;
case QGis::WKBPolygon:
case QGis::WKBPolygon25D:
case QGis::WKBMultiPolygon:
case QGis::WKBMultiPolygon25D:
layerType = QgsLayerItem::Polygon;
break;
default:
if ( wkbType == QGis::WKBNoGeometry && layerProperty.geometryColName.isEmpty() )
{
layerType = QgsLayerItem::TableLayer;
tip = tr( "as geometryless table" );
}
else
{
return;
}
}
QgsOracleLayerItem *layerItem = new QgsOracleLayerItem( this, layerProperty.tableName, mPath + "/" + layerProperty.tableName, layerType, layerProperty );
layerItem->setToolTip( tip );
addChild( layerItem );
}
// ---------------------------------------------------------------------------
QgsOracleRootItem::QgsOracleRootItem( QgsDataItem* parent, QString name, QString path )
: QgsDataCollectionItem( parent, name, path )
{
mIcon = QgsApplication::getThemeIcon( "mIconOracle.png" );
populate();
}
QgsOracleRootItem::~QgsOracleRootItem()
{
}
QVector<QgsDataItem*> QgsOracleRootItem::createChildren()
{
QVector<QgsDataItem*> connections;
foreach ( QString connName, QgsOracleConn::connectionList() )
{
connections << new QgsOracleConnectionItem( this, connName, mPath + "/" + connName );
}
return connections;
}
QList<QAction*> QgsOracleRootItem::actions()
{
QList<QAction*> lst;
QAction* actionNew = new QAction( tr( "New Connection..." ), this );
connect( actionNew, SIGNAL( triggered() ), this, SLOT( newConnection() ) );
lst.append( actionNew );
return lst;
}
QWidget *QgsOracleRootItem::paramWidget()
{
QgsOracleSourceSelect *select = new QgsOracleSourceSelect( 0, 0, true, true );
connect( select, SIGNAL( connectionsChanged() ), this, SLOT( connectionsChanged() ) );
return select;
}
void QgsOracleRootItem::connectionsChanged()
{
refresh();
}
void QgsOracleRootItem::newConnection()
{
QgsOracleNewConnection nc( NULL );
if ( nc.exec() )
{
refresh();
}
}

View File

@ -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

View File

@ -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()
{
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,427 @@
/***************************************************************************
qgsoracleprovider.h - Data provider for oracle layers
-------------------
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 QGSORACLEPROVIDER_H
#define QGSORACLEPROVIDER_H
#include "qgsvectordataprovider.h"
#include "qgsrectangle.h"
#include "qgsvectorlayerimport.h"
#include "qgsoracletablemodel.h"
#include "qgsdatasourceuri.h"
#include <QVector>
#include <QQueue>
#include <QSqlQuery>
#include <QSqlError>
class QgsFeature;
class QgsField;
class QgsGeometry;
#include "qgsdatasourceuri.h"
#include "ocispatial/wkbptr.h"
/**
\class QgsOracleProvider
\brief Data provider for oracle layers.
This provider implements the
interface defined in the QgsDataProvider class to provide access to spatial
data residing in a oracle enabled database.
*/
class QgsOracleProvider : public QgsVectorDataProvider
{
Q_OBJECT
public:
/** Import a vector layer into the database */
static QgsVectorLayerImport::ImportError createEmptyLayer(
const QString& uri,
const QgsFieldMap &fields,
QGis::WkbType wkbType,
const QgsCoordinateReferenceSystem *srs,
bool overwrite,
QMap<int, int> *oldToNewAttrIdxMap,
QString *errorMessage = 0,
const QMap<QString, QVariant> *options = 0
);
/**
* Constructor for the provider. The uri must be in the following format:
* host=localhost user=gsherman dbname=test password=xxx table=test.alaska (the_geom)
* @param uri String containing the required parameters to connect to the database
* and query the table.
*/
QgsOracleProvider( QString const &uri = "" );
//! Destructor
virtual ~QgsOracleProvider();
/**
* Returns the permanent storage type for this layer as a friendly name.
*/
virtual QString storageType() const;
/*! Get the QgsCoordinateReferenceSystem for this layer
* @note Must be reimplemented by each provider.
* If the provider isn't capable of returning
* its projection an empty srs will be returned
*/
virtual QgsCoordinateReferenceSystem crs();
/** Select features based on a bounding rectangle. Features can be retrieved with calls to nextFeature.
* @param fetchAttributes list of attributes which should be fetched
* @param rect spatial filter
* @param fetchGeometry true if the feature geometry should be fetched
* @param useIntersect true if an accurate intersection test should be used,
* false if a test based on bounding box is sufficient
*/
virtual void select( QgsAttributeList fetchAttributes = QgsAttributeList(),
QgsRectangle rect = QgsRectangle(),
bool fetchGeometry = true,
bool useIntersect = false );
/**
* Get the next feature resulting from a select operation.
* @param feature feature which will receive data from the provider
* @return true when there was a feature to fetch, false when end was hit
*/
virtual bool nextFeature( QgsFeature& feature );
/**
* Gets the feature at the given feature ID.
* @param featureId id of the feature
* @param feature feature which will receive the data
* @param fetchGeoemtry if true, geometry will be fetched from the provider
* @param fetchAttributes a list containing the indexes of the attribute fields to copy
* @return True when feature was found, otherwise false
*/
virtual bool featureAtId( QgsFeatureId featureId,
QgsFeature& feature,
bool fetchGeometry = true,
QgsAttributeList fetchAttributes = QgsAttributeList() );
/** Get the feature type. This corresponds to
* WKBPoint,
* WKBLineString,
* WKBPolygon,
* WKBMultiPoint,
* WKBMultiLineString or
* WKBMultiPolygon
* as defined in qgis.h
*/
QGis::WkbType geometryType() const;
/** return the number of layers for the current data source
* @note Should this be subLayerCount() instead?
*/
size_t layerCount() const;
/**
* Get the number of features in the layer
*/
long featureCount() const;
/**
* Get the number of fields in the layer
*/
uint fieldCount() const;
/**
* Return a string representation of the endian-ness for the layer
*/
QString endianString();
/**
* Changes the stored extent for this layer to the supplied extent.
* For example, this is called when the extent worker thread has a result.
*/
void setExtent( QgsRectangle& newExtent );
/** Return the extent for this data layer
*/
virtual QgsRectangle extent();
/** Update the extent
*/
virtual void updateExtents();
/** Determine the fields making up the primary key
*/
bool determinePrimaryKey();
/**
* Get the field information for the layer
* @return vector of QgsField objects
*/
const QgsFieldMap &fields() const;
/**
* Return a short comment for the data that this provider is
* providing access to (e.g. the comment for oracle table).
*/
QString dataComment() const;
/** Reset the layer
*/
void rewind();
/** Returns the minimum value of an attribute
* @param index the index of the attribute */
QVariant minimumValue( int index );
/** Returns the maximum value of an attribute
* @param index the index of the attribute */
QVariant maximumValue( int index );
/** Return the unique values of an attribute
* @param index the index of the attribute
* @param values reference to the list of unique values */
virtual void uniqueValues( int index, QList<QVariant> &uniqueValues, int limit = -1 );
/**Returns true if layer is valid
*/
bool isValid();
QgsAttributeList attributeIndexes();
QgsAttributeList pkAttributeIndexes() { return mPrimaryKeyAttrs; }
/**Returns the default value for field specified by @c fieldName */
QVariant defaultValue( QString fieldName, QString tableName = QString::null, QString schemaName = QString::null );
/**Returns the default value for field specified by @c fieldId */
QVariant defaultValue( int fieldId );
/**Adds a list of features
@return true in case of success and false in case of failure*/
bool addFeatures( QgsFeatureList & flist );
/**Deletes a list of features
@param id list of feature ids
@return true in case of success and false in case of failure*/
bool deleteFeatures( const QgsFeatureIds & id );
/**Adds new attributes
@param name map with attribute name as key and type as value
@return true in case of success and false in case of failure*/
bool addAttributes( const QList<QgsField> &attributes );
/**Deletes existing attributes
@param names of the attributes to delete
@return true in case of success and false in case of failure*/
bool deleteAttributes( const QgsAttributeIds & name );
/**Changes attribute values of existing features
@param attr_map a map containing the new attributes. The integer is the feature id,
the first QString is the attribute name and the second one is the new attribute value
@return true in case of success and false in case of failure*/
bool changeAttributeValues( const QgsChangedAttributesMap & attr_map );
/**
Changes geometries of existing features
@param geometry_map A QMap containing the feature IDs to change the geometries of.
the second map parameter being the new geometries themselves
@return true in case of success and false in case of failure
*/
bool changeGeometryValues( QgsGeometryMap & geometry_map );
/**Tries to create an spatial index file for faster access if only a subset of the features is required
@return true in case of success*/
bool createSpatialIndex();
//! Get the table name associated with this provider instance
QString getTableName();
/** Accessor for sql where clause used to limit dataset */
QString subsetString();
/** mutator for sql where clause used to limit dataset size */
bool setSubsetString( QString theSQL, bool updateFeatureCount = true );
virtual bool supportsSubsetString() { return true; }
/**Returns a bitmask containing the supported capabilities*/
int capabilities() const;
/** return a provider name
Essentially just returns the provider key. Should be used to build file
dialogs so that providers can be shown with their supported types. Thus
if more than one provider supports a given format, the user is able to
select a specific provider to open that file.
@note
Instead of being pure virtual, might be better to generalize this
behavior and presume that none of the sub-classes are going to do
anything strange with regards to their name or description?
*/
QString name() const;
/** return description
Return a terse string describing what the provider is.
@note
Instead of being pure virtual, might be better to generalize this
behavior and presume that none of the sub-classes are going to do
anything strange with regards to their name or description?
*/
QString description() const;
static bool exec( QSqlQuery &qry, QString sql );
private:
bool openQuery( QString alias,
const QgsAttributeList &fetchAttributes,
bool fetchGeometry,
QString whereClause );
bool getFeature( bool fetchGeometry,
QgsFeature &feature,
const QgsAttributeList &fetchAttributes );
QString whereClause( QgsFeatureId featureId ) const;
QString pkParamWhereClause() const;
QString paramValue( QString fieldvalue, const QString &defaultValue ) const;
void appendGeomParam( QgsGeometry *geom, QSqlQuery &qry ) const;
void appendPkParams( QgsFeatureId fid, QSqlQuery &qry ) const;
bool hasSufficientPermsAndCapabilities();
const QgsField &field( int index ) const;
/** Load the field list
*/
bool loadFields();
/** convert a QgsField to work with Oracle */
static bool convertField( QgsField &field );
QgsFieldMap mAttributeFields;
QMap<int, QVariant> mDefaultValues;
QString mDataComment;
//! Data source URI struct for this layer
QgsDataSourceURI mUri;
/**
* Flag indicating if the layer data source is a valid oracle layer
*/
bool mValid;
/**
* provider references query (instead of a table)
*/
bool mIsQuery;
/**
* Name of the table with no schema
*/
QString mTableName;
/**
* Name of the table or subquery
*/
QString mQuery;
/**
* Owner of the table
*/
QString mOwnerName;
/**
* SQL statement used to limit the features retrieved
*/
QString mSqlWhereClause;
/**
* Data type for the primary key
*/
enum { pktUnknown, pktInt, pktRowId, pktFidMap } mPrimaryKeyType;
/**
* List of primary key attributes for fetching features.
*/
QList<int> mPrimaryKeyAttrs;
QString mPrimaryKeyDefault;
QString mGeometryColumn; //! name of the geometry column
QgsRectangle mLayerExtent; //! Rectangle that contains the extent (bounding box) of the layer
mutable long mFeaturesCounted; //! Number of features in the layer
int mSrid; //! srid of column
int mEnabledCapabilities; //! capabilities of layer
QGis::WkbType mDetectedGeomType; //! geometry type detected in the database
QGis::WkbType mRequestedGeomType; //! geometry type requested in the uri
bool getGeometryDetails();
/* Use estimated metadata. Uses fast table counts, geometry type and extent determination */
bool mUseEstimatedMetadata;
struct OracleFieldNotFound {}; //! Exception to throw
struct OracleException
{
OracleException( const QSqlQuery &q )
: mWhat( tr( "Oracle-Error: %1\nSQL: %2\n" ).arg( q.lastError().text() ).arg( q.lastQuery() ) )
{}
OracleException( const OracleException &e )
: mWhat( e.errorMessage() )
{}
~OracleException()
{}
QString errorMessage() const
{
return mWhat;
}
private:
QString mWhat;
};
// A function that determines if the given schema.table.column
// contains unqiue entries
bool uniqueData( QString query, QString colName );
void disconnectDb();
static QString quotedIdentifier( QString ident ) { return QgsOracleConn::quotedIdentifier( ident ); }
static QString quotedValue( QVariant value ) { return QgsOracleConn::quotedValue( value ); }
QgsFeatureId lookupFid( const QVariant &v ); //! lookup existing mapping or add a new one
QMap<QVariant, QgsFeatureId> mKeyToFid; //! map key values to feature id
QMap<QgsFeatureId, QVariant> mFidToKey; //! map feature back to fea
QgsFeatureId mFidCounter; //! next feature id if map is used
QgsOracleConn *mConnection;
QSqlQuery mQry;
bool mFetchGeomRequested; //! geometry was requested
bool mIntersectResult; //! need to intersect the results (Oracle Locator only)
bool mHasSpatial; //! Oracle Spatial is installed
QString mSpatialIndex; //! name of spatial index of geometry column
QgsRectangle mIntersectRect; //! rectangle to intersect with (if any)
};
#endif

View File

@ -0,0 +1,655 @@
/***************************************************************************
qgsoraclesourceselect.cpp
Dialog to select Oracle layer(s) and add it to the map canvas
-------------------
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 "qgsoraclesourceselect.h"
#include "qgsoraclecolumntypethread.h"
#include "qgslogger.h"
#include "qgsapplication.h"
#include "qgscontexthelp.h"
#include "qgsoracleprovider.h"
#include "qgsoraclenewconnection.h"
#include "qgsmanageconnectionsdialog.h"
#include "qgsquerybuilder.h"
#include "qgsdatasourceuri.h"
#include "qgsvectorlayer.h"
#include <QFileDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QSettings>
#include <QTextStream>
#include <QHeaderView>
#include <QStringList>
/** Used to create an editor for when the user tries to change the contents of a cell */
QWidget *QgsOracleSourceSelectDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
Q_UNUSED( option );
if ( index.column() == QgsOracleTableModel::dbtmSql )
{
QLineEdit *le = new QLineEdit( parent );
le->setText( index.data( Qt::DisplayRole ).toString() );
return le;
}
if ( index.column() == QgsOracleTableModel::dbtmType && index.data( Qt::UserRole + 1 ).toBool() )
{
QComboBox *cb = new QComboBox( parent );
foreach ( QGis::WkbType type,
QList<QGis::WkbType>()
<< QGis::WKBPoint
<< QGis::WKBLineString
<< QGis::WKBPolygon
<< QGis::WKBMultiPoint
<< QGis::WKBMultiLineString
<< QGis::WKBMultiPolygon
<< QGis::WKBNoGeometry )
{
cb->addItem( QgsOracleTableModel::iconForWkbType( type ), QgsOracleConn::displayStringForWkbType( type ), type );
}
cb->setCurrentIndex( cb->findData( index.data( Qt::UserRole + 2 ).toInt() ) );
return cb;
}
if ( index.column() == QgsOracleTableModel::dbtmPkCol )
{
bool isView = index.data( Qt::UserRole + 1 ).toBool();
if ( !isView )
return 0;
QStringList values = index.data( Qt::UserRole + 2 ).toStringList();
if ( values.size() == 0 )
{
QString tableName = index.sibling( index.row(), QgsOracleTableModel::dbtmTable ).data( Qt::DisplayRole ).toString();
QString ownerName = index.sibling( index.row(), QgsOracleTableModel::dbtmOwner ).data( Qt::DisplayRole ).toString();
values = mConn->pkCandidates( ownerName, tableName );
}
if ( values.size() == 0 )
return 0;
if ( values.size() > 0 )
{
QComboBox *cb = new QComboBox( parent );
cb->addItems( values );
cb->setCurrentIndex( cb->findText( index.data( Qt::DisplayRole ).toString() ) );
return cb;
}
}
if ( index.column() == QgsOracleTableModel::dbtmSrid )
{
QLineEdit *le = new QLineEdit( parent );
le->setValidator( new QIntValidator( -1, 999999, parent ) );
le->insert( index.data( Qt::DisplayRole ).toString() );
return le;
}
return 0;
}
void QgsOracleSourceSelectDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
{
QComboBox *cb = qobject_cast<QComboBox *>( editor );
if ( cb )
{
if ( index.column() == QgsOracleTableModel::dbtmType )
{
QGis::WkbType type = ( QGis::WkbType ) cb->itemData( cb->currentIndex() ).toInt();
model->setData( index, QgsOracleTableModel::iconForWkbType( type ), Qt::DecorationRole );
model->setData( index, type != QGis::WKBUnknown ? QgsOracleConn::displayStringForWkbType( type ) : tr( "Select..." ) );
model->setData( index, type, Qt::UserRole + 2 );
}
else if ( index.column() == QgsOracleTableModel::dbtmPkCol )
{
model->setData( index, cb->currentText() );
model->setData( index, cb->currentText(), Qt::UserRole + 2 );
}
}
QLineEdit *le = qobject_cast<QLineEdit *>( editor );
if ( le )
model->setData( index, le->text() );
}
QgsOracleSourceSelect::QgsOracleSourceSelect( QWidget *parent, Qt::WFlags fl, bool managerMode, bool embeddedMode )
: QDialog( parent, fl )
, mManagerMode( managerMode )
, mEmbeddedMode( embeddedMode )
, mColumnTypeThread( 0 )
, mIsConnected( false )
{
setupUi( this );
if ( mEmbeddedMode )
{
buttonBox->button( QDialogButtonBox::Close )->hide();
}
else
{
setWindowTitle( tr( "Add Oracle Table(s)" ) );
}
mAddButton = new QPushButton( tr( "&Add" ) );
mAddButton->setEnabled( false );
mBuildQueryButton = new QPushButton( tr( "&Build query" ) );
mBuildQueryButton->setToolTip( tr( "Build query" ) );
mBuildQueryButton->setDisabled( true );
if ( !mManagerMode )
{
buttonBox->addButton( mAddButton, QDialogButtonBox::ActionRole );
connect( mAddButton, SIGNAL( clicked() ), this, SLOT( addTables() ) );
buttonBox->addButton( mBuildQueryButton, QDialogButtonBox::ActionRole );
connect( mBuildQueryButton, SIGNAL( clicked() ), this, SLOT( buildQuery() ) );
}
populateConnectionList();
mSearchModeComboBox->addItem( tr( "Wildcard" ) );
mSearchModeComboBox->addItem( tr( "RegExp" ) );
mSearchColumnComboBox->addItem( tr( "All" ) );
mSearchColumnComboBox->addItem( tr( "Owner" ) );
mSearchColumnComboBox->addItem( tr( "Table" ) );
mSearchColumnComboBox->addItem( tr( "Type" ) );
mSearchColumnComboBox->addItem( tr( "Geometry column" ) );
mSearchColumnComboBox->addItem( tr( "Primary key column" ) );
mSearchColumnComboBox->addItem( tr( "SRID" ) );
mSearchColumnComboBox->addItem( tr( "Sql" ) );
mProxyModel.setParent( this );
mProxyModel.setFilterKeyColumn( -1 );
mProxyModel.setFilterCaseSensitivity( Qt::CaseInsensitive );
mProxyModel.setSourceModel( &mTableModel );
mTablesTreeDelegate = new QgsOracleSourceSelectDelegate( this );
mTablesTreeView->setModel( &mProxyModel );
mTablesTreeView->setSortingEnabled( true );
mTablesTreeView->setEditTriggers( QAbstractItemView::CurrentChanged );
mTablesTreeView->setItemDelegate( mTablesTreeDelegate );
QSettings settings;
mTablesTreeView->setSelectionMode( settings.value( "/qgis/addOracleDC", false ).toBool() ?
QAbstractItemView::ExtendedSelection :
QAbstractItemView::MultiSelection );
//for Qt < 4.3.2, passing -1 to include all model columns
//in search does not seem to work
mSearchColumnComboBox->setCurrentIndex( 2 );
restoreGeometry( settings.value( "/Windows/PgSourceSelect/geometry" ).toByteArray() );
for ( int i = 0; i < mTableModel.columnCount(); i++ )
{
mTablesTreeView->setColumnWidth( i, settings.value( QString( "/Windows/PgSourceSelect/columnWidths/%1" ).arg( i ), mTablesTreeView->columnWidth( i ) ).toInt() );
}
//hide the search options by default
//they will be shown when the user ticks
//the search options group box
mSearchLabel->setVisible( false );
mSearchColumnComboBox->setVisible( false );
mSearchColumnsLabel->setVisible( false );
mSearchModeComboBox->setVisible( false );
mSearchModeLabel->setVisible( false );
mSearchTableEdit->setVisible( false );
}
/** Autoconnected SLOTS **/
// Slot for adding a new connection
void QgsOracleSourceSelect::on_btnNew_clicked()
{
QgsOracleNewConnection *nc = new QgsOracleNewConnection( this );
if ( nc->exec() )
{
populateConnectionList();
emit connectionsChanged();
}
delete nc;
}
// Slot for deleting an existing connection
void QgsOracleSourceSelect::on_btnDelete_clicked()
{
QString msg = tr( "Are you sure you want to remove the %1 connection and all associated settings?" )
.arg( cmbConnections->currentText() );
if ( QMessageBox::Ok != QMessageBox::information( this, tr( "Confirm Delete" ), msg, QMessageBox::Ok | QMessageBox::Cancel ) )
return;
QgsOracleConn::deleteConnection( cmbConnections->currentText() );
populateConnectionList();
emit connectionsChanged();
}
void QgsOracleSourceSelect::on_btnSave_clicked()
{
QgsManageConnectionsDialog dlg( this, QgsManageConnectionsDialog::Export, QgsManageConnectionsDialog::Oracle );
dlg.exec();
}
void QgsOracleSourceSelect::on_btnLoad_clicked()
{
QString fileName = QFileDialog::getOpenFileName( this, tr( "Load connections" ), ".",
tr( "XML files (*.xml *XML)" ) );
if ( fileName.isEmpty() )
{
return;
}
QgsManageConnectionsDialog dlg( this, QgsManageConnectionsDialog::Import, QgsManageConnectionsDialog::Oracle, fileName );
dlg.exec();
populateConnectionList();
}
// Slot for editing a connection
void QgsOracleSourceSelect::on_btnEdit_clicked()
{
QgsOracleNewConnection *nc = new QgsOracleNewConnection( this, cmbConnections->currentText() );
if ( nc->exec() )
{
populateConnectionList();
emit connectionsChanged();
}
delete nc;
}
/** End Autoconnected SLOTS **/
// Remember which database is selected
void QgsOracleSourceSelect::on_cmbConnections_currentIndexChanged( const QString & text )
{
// Remember which database was selected.
QgsOracleConn::setSelectedConnection( text );
cbxAllowGeometrylessTables->blockSignals( true );
cbxAllowGeometrylessTables->setChecked( QgsOracleConn::allowGeometrylessTables( text ) );
cbxAllowGeometrylessTables->blockSignals( false );
}
void QgsOracleSourceSelect::on_cbxAllowGeometrylessTables_stateChanged( int )
{
if ( mIsConnected )
on_btnConnect_clicked();
}
void QgsOracleSourceSelect::buildQuery()
{
setSql( mTablesTreeView->currentIndex() );
}
void QgsOracleSourceSelect::on_mTablesTreeView_clicked( const QModelIndex &index )
{
mBuildQueryButton->setEnabled( index.parent().isValid() );
}
void QgsOracleSourceSelect::on_mTablesTreeView_doubleClicked( const QModelIndex &index )
{
QSettings settings;
if ( settings.value( "/qgis/addOracleDC", false ).toBool() )
{
addTables();
}
else
{
setSql( index );
}
}
void QgsOracleSourceSelect::on_mSearchTableEdit_textChanged( const QString & text )
{
if ( mSearchModeComboBox->currentText() == tr( "Wildcard" ) )
{
mProxyModel._setFilterWildcard( text );
}
else if ( mSearchModeComboBox->currentText() == tr( "RegExp" ) )
{
mProxyModel._setFilterRegExp( text );
}
}
void QgsOracleSourceSelect::on_mSearchColumnComboBox_currentIndexChanged( const QString & text )
{
if ( text == tr( "All" ) )
{
mProxyModel.setFilterKeyColumn( -1 );
}
else if ( text == tr( "Owner" ) )
{
mProxyModel.setFilterKeyColumn( QgsOracleTableModel::dbtmOwner );
}
else if ( text == tr( "Table" ) )
{
mProxyModel.setFilterKeyColumn( QgsOracleTableModel::dbtmTable );
}
else if ( text == tr( "Type" ) )
{
mProxyModel.setFilterKeyColumn( QgsOracleTableModel::dbtmType );
}
else if ( text == tr( "Geometry column" ) )
{
mProxyModel.setFilterKeyColumn( QgsOracleTableModel::dbtmGeomCol );
}
else if ( text == tr( "Primary key column" ) )
{
mProxyModel.setFilterKeyColumn( QgsOracleTableModel::dbtmPkCol );
}
else if ( text == tr( "SRID" ) )
{
mProxyModel.setFilterKeyColumn( QgsOracleTableModel::dbtmSrid );
}
else if ( text == tr( "Sql" ) )
{
mProxyModel.setFilterKeyColumn( QgsOracleTableModel::dbtmSql );
}
}
void QgsOracleSourceSelect::on_mSearchModeComboBox_currentIndexChanged( const QString & text )
{
Q_UNUSED( text );
on_mSearchTableEdit_textChanged( mSearchTableEdit->text() );
}
void QgsOracleSourceSelect::setLayerType( QgsOracleLayerProperty layerProperty )
{
QgsDebugMsg( "entering." );
mTableModel.addTableEntry( layerProperty );
}
QgsOracleSourceSelect::~QgsOracleSourceSelect()
{
if ( mColumnTypeThread )
{
mColumnTypeThread->stop();
mColumnTypeThread->wait();
finishList();
}
QSettings settings;
settings.setValue( "/Windows/OracleSourceSelect/geometry", saveGeometry() );
for ( int i = 0; i < mTableModel.columnCount(); i++ )
{
settings.setValue( QString( "/Windows/OracleSourceSelect/columnWidths/%1" ).arg( i ), mTablesTreeView->columnWidth( i ) );
}
}
void QgsOracleSourceSelect::populateConnectionList()
{
cmbConnections->blockSignals( true );
cmbConnections->clear();
cmbConnections->addItems( QgsOracleConn::connectionList() );
cmbConnections->blockSignals( false );
setConnectionListPosition();
btnEdit->setDisabled( cmbConnections->count() == 0 );
btnDelete->setDisabled( cmbConnections->count() == 0 );
btnConnect->setDisabled( cmbConnections->count() == 0 );
cmbConnections->setDisabled( cmbConnections->count() == 0 );
}
// Slot for performing action when the Add button is clicked
void QgsOracleSourceSelect::addTables()
{
mSelectedTables.clear();
foreach ( QModelIndex idx, mTablesTreeView->selectionModel()->selection().indexes() )
{
if ( idx.column() != QgsOracleTableModel::dbtmTable )
continue;
QString uri = mTableModel.layerURI( mProxyModel.mapToSource( idx ), mConnInfo, mUseEstimatedMetadata );
if ( uri.isNull() )
continue;
mSelectedTables << uri;
}
if ( mSelectedTables.empty() )
{
QMessageBox::information( this, tr( "Select Table" ), tr( "You must select a table in order to add a layer." ) );
}
else
{
emit addDatabaseLayers( mSelectedTables, "oracle" );
accept();
}
}
void QgsOracleSourceSelect::on_btnConnect_clicked()
{
cbxAllowGeometrylessTables->setEnabled( true );
if ( mColumnTypeThread )
{
mColumnTypeThread->stop();
return;
}
QModelIndex rootItemIndex = mTableModel.indexFromItem( mTableModel.invisibleRootItem() );
mTableModel.removeRows( 0, mTableModel.rowCount( rootItemIndex ), rootItemIndex );
// populate the table list
QgsDataSourceURI uri = QgsOracleConn::connUri( cmbConnections->currentText() );
QgsDebugMsg( "Connection info: " + uri.connectionInfo() );
mConnInfo = uri.connectionInfo();
mUseEstimatedMetadata = uri.useEstimatedMetadata();
QgsOracleConn *conn = QgsOracleConn::connectDb( uri.connectionInfo() );
if ( conn )
{
QApplication::setOverrideCursor( Qt::WaitCursor );
mIsConnected = true;
mTablesTreeDelegate->setConn( QgsOracleConn::connectDb( uri.connectionInfo() ) );
bool userTablesOnly = QgsOracleConn::userTablesOnly( cmbConnections->currentText() );
bool allowGeometrylessTables = cbxAllowGeometrylessTables->isChecked();
QVector<QgsOracleLayerProperty> layers;
if ( conn->supportedLayers( layers, userTablesOnly, allowGeometrylessTables ) )
{
// Add the supported layers to the table
foreach ( QgsOracleLayerProperty layer, layers )
{
if ( !layer.geometryColName.isNull() )
{
if ( layer.types.contains( QGis::WKBUnknown ) || layer.srids.isEmpty() )
{
addSearchGeometryColumn( layer );
}
}
else
{
QgsDebugMsg( QString( "adding table %1.%2" ).arg( layer.ownerName ).arg( layer.tableName ) );
layer.types.clear();
layer.srids.clear();
mTableModel.addTableEntry( layer );
}
}
if ( mColumnTypeThread )
{
btnConnect->setText( tr( "Stop" ) );
mColumnTypeThread->start();
}
}
//if we have only one owner item, expand it by default
int numTopLevelItems = mTableModel.invisibleRootItem()->rowCount();
if ( numTopLevelItems < 2 || mTableModel.tableCount() < 20 )
{
//expand all the toplevel items
for ( int i = 0; i < numTopLevelItems; ++i )
{
mTablesTreeView->expand( mProxyModel.mapFromSource( mTableModel.indexFromItem( mTableModel.invisibleRootItem()->child( i ) ) ) );
}
}
conn->disconnect();
if ( !mColumnTypeThread )
{
finishList();
}
}
else
{
// Let user know we couldn't initialise the Oracle provider
QMessageBox::warning( this,
tr( "Oracle Locator Provider" ),
tr( "Could not open the Oracle Locator Provider" ) );
}
}
void QgsOracleSourceSelect::finishList()
{
QApplication::restoreOverrideCursor();
if ( cmbConnections->count() > 0 )
mAddButton->setEnabled( true );
#if 0
for ( int i = 0; i < QgsOracleTableModel::dbtmColumns; i++ )
mTablesTreeView->resizeColumnToContents( i );
#endif
mTablesTreeView->sortByColumn( QgsOracleTableModel::dbtmTable, Qt::AscendingOrder );
mTablesTreeView->sortByColumn( QgsOracleTableModel::dbtmOwner, Qt::AscendingOrder );
}
void QgsOracleSourceSelect::columnThreadFinished()
{
delete mColumnTypeThread;
mColumnTypeThread = 0;
btnConnect->setText( tr( "Connect" ) );
finishList();
}
QStringList QgsOracleSourceSelect::selectedTables()
{
return mSelectedTables;
}
QString QgsOracleSourceSelect::connectionInfo()
{
return mConnInfo;
}
void QgsOracleSourceSelect::setSql( const QModelIndex &index )
{
if ( !index.parent().isValid() )
{
QgsDebugMsg( "no owner item found" );
return;
}
QModelIndex idx = mProxyModel.mapToSource( index );
QString tableName = mTableModel.itemFromIndex( idx.sibling( idx.row(), QgsOracleTableModel::dbtmTable ) )->text();
QString uri = mTableModel.layerURI( idx, mConnInfo, mUseEstimatedMetadata );
if ( uri.isNull() )
{
QgsDebugMsg( "no uri" );
return;
}
QgsVectorLayer *vlayer = new QgsVectorLayer( uri, tableName, "oracle" );
if ( !vlayer->isValid() )
{
delete vlayer;
return;
}
// create a query builder object
QgsQueryBuilder *gb = new QgsQueryBuilder( vlayer, this );
if ( gb->exec() )
{
mTableModel.setSql( mProxyModel.mapToSource( index ), gb->sql() );
}
delete gb;
delete vlayer;
}
void QgsOracleSourceSelect::addSearchGeometryColumn( QgsOracleLayerProperty layerProperty )
{
// store the column details and do the query in a thread
if ( !mColumnTypeThread )
{
QgsOracleConn *conn = QgsOracleConn::connectDb( mConnInfo );
if ( conn )
{
mColumnTypeThread = new QgsOracleColumnTypeThread( conn, mUseEstimatedMetadata );
connect( mColumnTypeThread, SIGNAL( setLayerType( QgsOracleLayerProperty ) ),
this, SLOT( setLayerType( QgsOracleLayerProperty ) ) );
connect( this, SIGNAL( addGeometryColumn( QgsOracleLayerProperty ) ),
mColumnTypeThread, SLOT( addGeometryColumn( QgsOracleLayerProperty ) ) );
connect( mColumnTypeThread, SIGNAL( finished() ),
this, SLOT( columnThreadFinished() ) );
}
}
emit addGeometryColumn( layerProperty );
}
QString QgsOracleSourceSelect::fullDescription( QString owner, QString table, QString column, QString type )
{
QString full_desc = "";
if ( !owner.isEmpty() )
full_desc = QgsOracleConn::quotedIdentifier( owner ) + ".";
full_desc += QgsOracleConn::quotedIdentifier( table ) + " (" + column + ") " + type;
return full_desc;
}
void QgsOracleSourceSelect::setConnectionListPosition()
{
// If possible, set the item currently displayed database
QString toSelect = QgsOracleConn::selectedConnection();
cmbConnections->setCurrentIndex( cmbConnections->findText( toSelect ) );
if ( cmbConnections->currentIndex() < 0 )
{
if ( toSelect.isNull() )
cmbConnections->setCurrentIndex( 0 );
else
cmbConnections->setCurrentIndex( cmbConnections->count() - 1 );
}
}
void QgsOracleSourceSelect::setSearchExpression( const QString& regexp )
{
Q_UNUSED( regexp );
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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();

View File

@ -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" )
@ -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 )

View File

@ -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"/>
@ -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">

View File

@ -0,0 +1,265 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsOracleNewConnectionBase</class>
<widget class="QDialog" name="QgsOracleNewConnectionBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>459</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Create a New Oracle connection</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QGridLayout">
<property name="margin">
<number>9</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="GroupBox1">
<property name="title">
<string>Connection Information</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="1" colspan="2">
<widget class="QLineEdit" name="txtUsername"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="TextLabel3_2">
<property name="text">
<string>Password</string>
</property>
<property name="buddy">
<cstring>txtPassword</cstring>
</property>
</widget>
</item>
<item row="5" column="1" colspan="2">
<widget class="QLineEdit" name="txtPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QCheckBox" name="chkStoreUsername">
<property name="text">
<string>Save Username</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="TextLabel3">
<property name="text">
<string>Username</string>
</property>
<property name="buddy">
<cstring>txtUsername</cstring>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="txtName">
<property name="toolTip">
<string>Name of the new connection</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Database</string>
</property>
<property name="buddy">
<cstring>txtDatabase</cstring>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="TextLabel1_2">
<property name="text">
<string>Name</string>
</property>
<property name="buddy">
<cstring>txtName</cstring>
</property>
</widget>
</item>
<item row="8" column="0" colspan="3">
<widget class="QCheckBox" name="cb_geometryColumnsOnly">
<property name="toolTip">
<string>Restrict the displayed tables to those that are in the geometry_columns table</string>
</property>
<property name="whatsThis">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Restricts the displayed tables to those that are in the all_sdo_geom_metadata view. This can speed up the initial display of spatial tables.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Only look in meta data table</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="3">
<widget class="QCheckBox" name="cb_userTablesOnly">
<property name="toolTip">
<string>Restrict the search to the public schema for spatial tables not in the geometry_columns table</string>
</property>
<property name="whatsThis">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When searching for spatial tables restrict the search to tables that are owner by the user.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Only look for user's tables</string>
</property>
</widget>
</item>
<item row="10" column="0" colspan="3">
<widget class="QCheckBox" name="cb_allowGeometrylessTables">
<property name="text">
<string>Also list tables with no geometry</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="TextLabel2_2">
<property name="text">
<string>Port</string>
</property>
<property name="buddy">
<cstring>txtPort</cstring>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="txtPort">
<property name="text">
<string>1521</string>
</property>
</widget>
</item>
<item row="6" column="2" rowspan="2">
<widget class="QPushButton" name="btnConnect">
<property name="text">
<string>&amp;Test Connect</string>
</property>
</widget>
</item>
<item row="7" column="0" colspan="2">
<widget class="QCheckBox" name="chkStorePassword">
<property name="text">
<string>Save Password</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QLineEdit" name="txtDatabase"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="TextLabel1">
<property name="text">
<string>Host</string>
</property>
<property name="buddy">
<cstring>txtHost</cstring>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLineEdit" name="txtHost"/>
</item>
<item row="11" column="0" colspan="3">
<widget class="QCheckBox" name="cb_useEstimatedMetadata">
<property name="toolTip">
<string>Use estimated table statistics for the layer metadata.</string>
</property>
<property name="whatsThis">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When the layer is setup various metadata is required for the Oracle table. This includes information such as the table row count, geometry type and spatial extents of the data in the geometry column. If the table contains a large number of rows determining this metadata is time consuming.&lt;/p&gt;&lt;p&gt;By activating this option the following fast table metadata operations are done:&lt;/p&gt;&lt;p&gt;1) Row count is determined from all_tables.num_rows.&lt;/p&gt;&lt;p&gt;2) Table extents are always determined with the SDO_TUNE.EXTENTS_OF function even if a layer filter is applied.&lt;/p&gt;&lt;p&gt;3) The table geometry is determined from the first 100 non-null geometry rows in the table.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Use estimated table metadata</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<tabstops>
<tabstop>txtName</tabstop>
<tabstop>txtDatabase</tabstop>
<tabstop>txtHost</tabstop>
<tabstop>txtPort</tabstop>
<tabstop>txtUsername</tabstop>
<tabstop>txtPassword</tabstop>
<tabstop>chkStoreUsername</tabstop>
<tabstop>chkStorePassword</tabstop>
<tabstop>btnConnect</tabstop>
<tabstop>cb_geometryColumnsOnly</tabstop>
<tabstop>cb_userTablesOnly</tabstop>
<tabstop>cb_allowGeometrylessTables</tabstop>
<tabstop>cb_useEstimatedMetadata</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsOracleNewConnectionBase</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>313</x>
<y>501</y>
</hint>
<hint type="destinationlabel">
<x>451</x>
<y>312</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QgsOracleNewConnectionBase</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>395</x>
<y>501</y>
</hint>
<hint type="destinationlabel">
<x>450</x>
<y>287</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -58,8 +58,6 @@ class TestQgsGeometry: public QObject
private:
/** A helper method to do a render check to see if the geometry op is as expected */
bool renderCheck( QString theTestName, QString theComment = "" );
/** A helper method to return wkb geometry type as a string */
QString wkbTypeAsString( QGis::WkbType theType );
/** A helper method to dump to qdebug the geometry of a multipolygon */
void dumpMultiPolygon( QgsMultiPolygon &theMultiPolygon );
/** A helper method to dump to qdebug the geometry of a polygon */
@ -217,7 +215,7 @@ void TestQgsGeometry::simplifyCheck1()
QVERIFY( mpPolylineGeometryD->simplify( 0.5 ) );
// should be a single polygon as A intersect B
QgsGeometry * mypSimplifyGeometry = mpPolylineGeometryD->simplify( 0.5 );
qDebug( "Geometry Type: %s", wkbTypeAsString( mypSimplifyGeometry->wkbType() ).toLocal8Bit().constData() );
qDebug( "Geometry Type: %s", QGis::featureType( mypSimplifyGeometry->wkbType() ) );
QVERIFY( mypSimplifyGeometry->wkbType() == QGis::WKBLineString );
QgsPolyline myLine = mypSimplifyGeometry->asPolyline();
QVERIFY( myLine.size() > 0 ); //check that the union created a feature
@ -230,7 +228,7 @@ void TestQgsGeometry::intersectionCheck1()
QVERIFY( mpPolygonGeometryA->intersects( mpPolygonGeometryB ) );
// should be a single polygon as A intersect B
QgsGeometry * mypIntersectionGeometry = mpPolygonGeometryA->intersection( mpPolygonGeometryB );
qDebug( "Geometry Type: %s", wkbTypeAsString( mypIntersectionGeometry->wkbType() ).toLocal8Bit().constData() );
qDebug( "Geometry Type: %s", QGis::featureType( mypIntersectionGeometry->wkbType() ) );
QVERIFY( mypIntersectionGeometry->wkbType() == QGis::WKBPolygon );
QgsPolygon myPolygon = mypIntersectionGeometry->asPolygon();
QVERIFY( myPolygon.size() > 0 ); //check that the union created a feature
@ -247,7 +245,7 @@ void TestQgsGeometry::unionCheck1()
{
// should be a multipolygon with 2 parts as A does not intersect C
QgsGeometry * mypUnionGeometry = mpPolygonGeometryA->combine( mpPolygonGeometryC );
qDebug( "Geometry Type: %s", wkbTypeAsString( mypUnionGeometry->wkbType() ).toLocal8Bit().constData() );
qDebug( "Geometry Type: %s", QGis::featureType( mypUnionGeometry->wkbType() ) );
QVERIFY( mypUnionGeometry->wkbType() == QGis::WKBMultiPolygon );
QgsMultiPolygon myMultiPolygon = mypUnionGeometry->asMultiPolygon();
QVERIFY( myMultiPolygon.size() > 0 ); //check that the union did not fail
@ -260,7 +258,7 @@ void TestQgsGeometry::unionCheck2()
{
// should be a single polygon as A intersect B
QgsGeometry * mypUnionGeometry = mpPolygonGeometryA->combine( mpPolygonGeometryB );
qDebug( "Geometry Type: %s", wkbTypeAsString( mypUnionGeometry->wkbType() ).toLocal8Bit().constData() );
qDebug( "Geometry Type: %s", QGis::featureType( mypUnionGeometry->wkbType() ) );
QVERIFY( mypUnionGeometry->wkbType() == QGis::WKBPolygon );
QgsPolygon myPolygon = mypUnionGeometry->asPolygon();
QVERIFY( myPolygon.size() > 0 ); //check that the union created a feature
@ -273,7 +271,7 @@ void TestQgsGeometry::differenceCheck1()
{
// should be same as A since A does not intersect C so diff is 100% of A
QgsGeometry * mypDifferenceGeometry = mpPolygonGeometryA->difference( mpPolygonGeometryC );
qDebug( "Geometry Type: %s", wkbTypeAsString( mypDifferenceGeometry->wkbType() ).toLocal8Bit().constData() );
qDebug( "Geometry Type: %s", QGis::featureType( mypDifferenceGeometry->wkbType() ) );
QVERIFY( mypDifferenceGeometry->wkbType() == QGis::WKBPolygon );
QgsPolygon myPolygon = mypDifferenceGeometry->asPolygon();
QVERIFY( myPolygon.size() > 0 ); //check that the union did not fail
@ -286,7 +284,7 @@ void TestQgsGeometry::differenceCheck2()
{
// should be a single polygon as (A - B) = subset of A
QgsGeometry * mypDifferenceGeometry = mpPolygonGeometryA->difference( mpPolygonGeometryB );
qDebug( "Geometry Type: %s", wkbTypeAsString( mypDifferenceGeometry->wkbType() ).toLocal8Bit().constData() );
qDebug( "Geometry Type: %s", QGis::featureType( mypDifferenceGeometry->wkbType() ) );
QVERIFY( mypDifferenceGeometry->wkbType() == QGis::WKBPolygon );
QgsPolygon myPolygon = mypDifferenceGeometry->asPolygon();
QVERIFY( myPolygon.size() > 0 ); //check that the union created a feature
@ -298,7 +296,7 @@ void TestQgsGeometry::bufferCheck()
{
// should be a single polygon
QgsGeometry * mypBufferGeometry = mpPolygonGeometryB->buffer( 10, 10 );
qDebug( "Geometry Type: %s", wkbTypeAsString( mypBufferGeometry->wkbType() ).toLocal8Bit().constData() );
qDebug( "Geometry Type: %s", QGis::featureType( mypBufferGeometry->wkbType() ) );
QVERIFY( mypBufferGeometry->wkbType() == QGis::WKBPolygon );
QgsPolygon myPolygon = mypBufferGeometry->asPolygon();
QVERIFY( myPolygon.size() > 0 ); //check that the buffer created a feature
@ -371,41 +369,6 @@ void TestQgsGeometry::dumpPolyline( QgsPolyline &thePolyline )
mpPainter->drawPolyline( myPoints );
}
QString TestQgsGeometry::wkbTypeAsString( QGis::WkbType theType )
{
switch ( theType )
{
case QGis::WKBPoint:
return "WKBPoint";
case QGis::WKBLineString:
return "WKBLineString";
case QGis::WKBPolygon:
return "WKBPolygon";
case QGis::WKBMultiPoint:
return "WKBMultiPoint";
case QGis::WKBMultiLineString:
return "WKBMultiLineString";
case QGis::WKBMultiPolygon:
return "WKBMultiPolygon";
case QGis::WKBUnknown:
return "WKBUnknown";
case QGis::WKBPoint25D:
return "WKBPoint25D";
case QGis::WKBLineString25D:
return "WKBLineString25D";
case QGis::WKBPolygon25D:
return "WKBPolygon25D";
case QGis::WKBMultiPoint25D:
return "WKBMultiPoint25D";
case QGis::WKBMultiLineString25D:
return "WKBMultiLineString25D";
case QGis::WKBMultiPolygon25D:
return "WKBMultiPolygon25D";
default:
return "Unknown type";
}
}
QTEST_MAIN( TestQgsGeometry )
#include "moc_testqgsgeometry.cxx"