mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-18 00:03:05 -04:00
[DBManager] Integrate QSpatialite's query builder
This commit is contained in:
parent
d684c8c749
commit
4876e7a2be
@ -1894,6 +1894,69 @@ Colonnes</translation>
|
||||
<translation>Éviter la sélection par l'id de l’entité</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DbManagerQueryBuilderDlg</name>
|
||||
<message>
|
||||
<source>SQL query builder</source>
|
||||
<translation>Constructeur de requête SQL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Data</source>
|
||||
<translation>Données</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Columns' values</source>
|
||||
<translation>Valeurs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Spatial index</source>
|
||||
<translation>Index spatial</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Columns</source>
|
||||
<translation>Colonnes</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Aggregates</source>
|
||||
<translation>Agrégats</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Functions</source>
|
||||
<translation>Fonctions</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>String functions</source>
|
||||
<translation>Fonctions sur les chaînes</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Operators</source>
|
||||
<translation>Opérateurs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Only 10 first values</source>
|
||||
<translation>Seulement les 10 premières</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Reset</source>
|
||||
<translation>Effacer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Table (with spatial index)</source>
|
||||
<translation>Table (avec index spatial)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Table (Target)</source>
|
||||
<translation>Table (cible)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use spatial index</source>
|
||||
<translation>Utiliser index spatial</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show system tables</source>
|
||||
<translation>Montrer les tables système</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DbManagerDlgTableProperties</name>
|
||||
<message>
|
||||
|
@ -223,3 +223,7 @@ class DBConnector:
|
||||
return getSqlDictionary()
|
||||
except ImportError:
|
||||
return []
|
||||
|
||||
def getQueryBuilderDictionary(self):
|
||||
return {}
|
||||
|
||||
|
@ -208,6 +208,12 @@ class Database(DbItemObject):
|
||||
|
||||
return SqlResultModel(self, sql, parent)
|
||||
|
||||
def columnUniqueValuesModel( self, col, table, limit = 10 ):
|
||||
l = ""
|
||||
if limit is not None:
|
||||
l = "LIMIT %d" % limit
|
||||
return self.sqlResultModel( "SELECT DISTINCT %s FROM %s %s" % (col, table, l), self)
|
||||
|
||||
def uniqueIdFunction(self):
|
||||
"""Return a SQL function used to generate a unique id for rows of a query"""
|
||||
# may be overloaded by derived classes
|
||||
@ -456,8 +462,8 @@ class Database(DbItemObject):
|
||||
def rasterTablesFactory(self, row, db, schema=None):
|
||||
return None
|
||||
|
||||
def tables(self, schema=None):
|
||||
tables = self.connector.getTables(schema.name if schema else None)
|
||||
def tables(self, schema=None, sys_tables=False):
|
||||
tables = self.connector.getTables(schema.name if schema else None, sys_tables)
|
||||
if tables is not None:
|
||||
tables = map(lambda x: self.tablesFactory(x, self, schema), tables)
|
||||
return tables
|
||||
@ -494,6 +500,12 @@ class Database(DbItemObject):
|
||||
self.refresh()
|
||||
return True
|
||||
|
||||
def explicitSpatialIndex( self ):
|
||||
return False
|
||||
|
||||
def spatialIndexClause( self, src_table, src_column, dest_table, dest_table_column ):
|
||||
return None
|
||||
|
||||
|
||||
class Schema(DbItemObject):
|
||||
def __init__(self, db):
|
||||
@ -554,6 +566,9 @@ class Table(DbItemObject):
|
||||
def __del__(self):
|
||||
pass # print "Table.__del__", self
|
||||
|
||||
def canBeAddedToCanvas( self ):
|
||||
return True
|
||||
|
||||
def database(self):
|
||||
return self.parent()
|
||||
|
||||
|
@ -231,7 +231,7 @@ class PostGisDBConnector(DBConnector):
|
||||
self._close_cursor(c)
|
||||
return res
|
||||
|
||||
def getTables(self, schema=None):
|
||||
def getTables(self, schema=None, add_sys_tables=False):
|
||||
""" get list of tables """
|
||||
tablenames = []
|
||||
items = []
|
||||
@ -242,7 +242,7 @@ class PostGisDBConnector(DBConnector):
|
||||
try:
|
||||
vectors = self.getVectorTables(schema)
|
||||
for tbl in vectors:
|
||||
if tbl[1] in sys_tables and tbl[2] in ['', 'public']:
|
||||
if not add_sys_tables and tbl[1] in sys_tables and tbl[2] in ['', 'public']:
|
||||
continue
|
||||
tablenames.append((tbl[2], tbl[1]))
|
||||
items.append(tbl)
|
||||
@ -252,7 +252,7 @@ class PostGisDBConnector(DBConnector):
|
||||
try:
|
||||
rasters = self.getRasterTables(schema)
|
||||
for tbl in rasters:
|
||||
if tbl[1] in sys_tables and tbl[2] in ['', 'public']:
|
||||
if not add_sys_tables and tbl[1] in sys_tables and tbl[2] in ['', 'public']:
|
||||
continue
|
||||
tablenames.append((tbl[2], tbl[1]))
|
||||
items.append(tbl)
|
||||
@ -988,3 +988,9 @@ UNION SELECT attname FROM pg_attribute WHERE attnum > 0"""
|
||||
|
||||
sql_dict["identifier"] = items
|
||||
return sql_dict
|
||||
|
||||
def getQueryBuilderDictionary(self):
|
||||
from .sql_dictionary import getQueryBuilderDictionary
|
||||
|
||||
return getQueryBuilderDictionary()
|
||||
|
||||
|
@ -93,75 +93,88 @@ postgis_keywords = []
|
||||
|
||||
# functions
|
||||
functions = [
|
||||
# TODO get them from a reference page
|
||||
"abs", "changes", "coalesce", "glob", "ifnull", "hex", "last_insert_rowid",
|
||||
"length", "like", "lower", "ltrim", "max", "min", "nullif", "quote", "random",
|
||||
"randomblob", "replace", "round", "rtrim", "soundex", "total_change", "trim",
|
||||
"typeof", "upper", "zeroblob", "date", "datetime", "julianday", "strftime",
|
||||
"avg", "count", "group_concat", "sum", "total"
|
||||
"coalesce",
|
||||
"nullif", "quote", "random",
|
||||
"replace", "soundex"
|
||||
]
|
||||
operators=[
|
||||
' AND ',' OR ','||',' < ',' <= ',' > ',' >= ',' = ',' <> ',' IS ',' IS NOT ',' IN ',' LIKE ',' GLOB ',' MATCH ',' REGEXP '
|
||||
]
|
||||
|
||||
math_functions = [
|
||||
# SQL math functions
|
||||
"Abs", "ACos", "ASin", "ATan", "Cos", "Cot", "Degrees", "Exp", "Floor", "Log", "Log2",
|
||||
"Log10", "Pi", "Radians", "Round", "Sign", "Sin", "Sqrt", "StdDev_Pop", "StdDev_Samp", "Tan",
|
||||
"Var_Pop", "Var_Samp" ]
|
||||
|
||||
string_functions=["Length", "Lower", "Upper", "Like", "Trim", "LTrim", "RTrim", "Replace", "Substr"]
|
||||
|
||||
aggregate_functions=[
|
||||
"Max","Min","Avg","Count","Sum","Group_Concat","Total","Var_Pop","Var_Samp","StdDev_Pop","StdDev_Samp"
|
||||
]
|
||||
|
||||
postgis_functions = [ # from http://www.postgis.org/docs/reference.html
|
||||
# 7.1. PostgreSQL PostGIS Types
|
||||
"box2d", "box3d", "box3d_extent", "geometry", "geometry_dump", "geography",
|
||||
"*box2d", "*box3d", "*box3d_extent", "*geometry", "*geometry_dump", "*geography",
|
||||
# 7.2. Management Functions
|
||||
"addgeometrycolumn", "dropgeometrycolumn", "dropgeometrytable", "postgis_full_version",
|
||||
"postgis_geos_version", "postgis_libxml_version", "postgis_lib_build_date",
|
||||
"postgis_lib_version", "postgis_proj_version", "postgis_scripts_build_date",
|
||||
"postgis_scripts_installed", "postgis_scripts_released", "postgis_uses_stats", "postgis_version",
|
||||
"populate_geometry_columns", "probe_geometry_columns", "updategeometrysrid",
|
||||
"*addgeometrycolumn", "*dropgeometrycolumn", "*dropgeometrytable", "*postgis_full_version",
|
||||
"*postgis_geos_version", "*postgis_libxml_version", "*postgis_lib_build_date",
|
||||
"*postgis_lib_version", "*postgis_proj_version", "*postgis_scripts_build_date",
|
||||
"*postgis_scripts_installed", "*postgis_scripts_released", "*postgis_uses_stats", "*postgis_version",
|
||||
"*populate_geometry_columns", "*probe_geometry_columns", "*updategeometrysrid",
|
||||
# 7.3. Geometry Constructors
|
||||
"st_bdpolyfromtext", "st_bdmpolyfromtext", "st_geogfromtext", "st_geographyfromtext",
|
||||
"st_geogfromwkb", "st_geomcollfromtext", "st_geomfromewkb", "st_geomfromewkt",
|
||||
"st_geometryfromtext", "st_geomfromgml", "st_geomfromkml", "st_gmltosql", "st_geomfromtext",
|
||||
"st_geomfromwkb", "st_linefrommultipoint", "st_linefromtext", "st_linefromwkb",
|
||||
"st_linestringfromwkb", "st_makebox2d", "st_makebox3d", "st_makeline", "st_makeenvelope",
|
||||
"st_makepolygon", "st_makepoint", "st_makepointm", "st_mlinefromtext", "st_mpointfromtext",
|
||||
"st_mpolyfromtext", "st_point", "st_pointfromtext", "st_pointfromwkb", "st_polygon",
|
||||
"st_polygonfromtext", "st_wkbtosql", "st_wkttosql",
|
||||
"*ST_bdpolyfromtext", "*ST_bdmpolyfromtext", "*ST_geogfromtext", "*ST_geographyfromtext",
|
||||
"*ST_geogfromwkb", "*ST_geomcollfromtext", "*ST_geomfromewkb", "*ST_geomfromewkt",
|
||||
"*ST_geometryfromtext", "*ST_geomfromgml", "*ST_geomfromkml", "*ST_gmltosql", "*ST_geomfromtext",
|
||||
"*ST_geomfromwkb", "*ST_linefrommultipoint", "*ST_linefromtext", "*ST_linefromwkb",
|
||||
"*ST_linestringfromwkb", "*ST_makebox2d", "*ST_makebox3d", "ST_MakeLine", "*ST_makeenvelope",
|
||||
"ST_MakePolygon", "ST_MakePoint", "ST_MakePointM", "*ST_MLinefromtext", "*ST_mpointfromtext",
|
||||
"*ST_mpolyfromtext", "ST_Point", "*ST_pointfromtext", "*ST_pointfromwkb", "ST_Polygon",
|
||||
"*ST_polygonfromtext", "*ST_wkbtosql", "*ST_wkttosql",
|
||||
# 7.4. Geometry Accessors
|
||||
"geometrytype", "st_boundary", "st_coorddim", "st_dimension", "st_endpoint", "st_envelope",
|
||||
"st_exteriorring", "st_geometryn", "st_geometrytype", "st_interiorringn", "st_isclosed",
|
||||
"st_isempty", "st_isring", "st_issimple", "st_isvalid", "st_isvalidreason", "st_m", "st_ndims",
|
||||
"st_npoints", "st_nrings", "st_numgeometries", "st_numinteriorrings", "st_numinteriorring",
|
||||
"st_numpoints", "st_pointn", "st_srid", "st_startpoint", "st_summary", "st_x", "st_y", "st_z",
|
||||
"st_zmflag",
|
||||
"GeometryType", "ST_Boundary", "*ST_coorddim", "ST_Dimension", "ST_EndPoint", "ST_Envelope",
|
||||
"ST_ExteriorRing", "ST_GeometryN", "ST_GeometryType", "ST_InteriorRingN", "ST_isClosed",
|
||||
"ST_isEmpty", "ST_isRing", "ST_isSimple", "ST_isValid", "ST_isValidReason", "ST_M", "ST_NDims",
|
||||
"ST_NPoints", "ST_NRings", "ST_NumGeometries", "ST_NumInteriorrings", "ST_NumInteriorring",
|
||||
"ST_NumPoints", "ST_PointN", "ST_Srid", "ST_StartPoint", "ST_Summary", "ST_X", "ST_Y", "ST_Z",
|
||||
"*ST_zmflag",
|
||||
# 7.5. Geometry Editors
|
||||
"st_addpoint", "st_affine", "st_force_2d", "st_force_3d", "st_force_3dz", "st_force_3dm",
|
||||
"st_force_4d", "st_force_collection", "st_forcerhr", "st_linemerge", "st_collectionextract",
|
||||
"st_multi", "st_removepoint", "st_reverse", "st_rotate", "st_rotatex", "st_rotatey",
|
||||
"st_rotatez", "st_scale", "st_segmentize", "st_setpoint", "st_setsrid", "st_snaptogrid",
|
||||
"st_transform", "st_translate", "st_transscale",
|
||||
"ST_AddPoint", "ST_Affine", "ST_Force2D", "*ST_Force3D", "*ST_Force3dZ", "*ST_Force3DM",
|
||||
"*ST_Force_4d", "*ST_force_collection", "*ST_forcerhr", "*ST_linemerge", "*ST_collectionextract",
|
||||
"ST_Multi", "*ST_removepoint", "*ST_reverse", "*ST_rotate", "*ST_rotatex", "*ST_rotatey",
|
||||
"*ST_rotatez", "*ST_scale", "*ST_segmentize", "*ST_setpoint", "ST_SetSrid", "ST_SnapToGrid",
|
||||
"ST_Transform", "ST_Translate", "*ST_transscale",
|
||||
# 7.6. Geometry Outputs
|
||||
"st_asbinary", "st_asewkb", "st_asewkt", "st_asgeojson", "st_asgml", "st_ashexewkb", "st_askml",
|
||||
"st_assvg", "st_geohash", "st_astext",
|
||||
"*ST_asbinary", "*ST_asewkb", "*ST_asewkt", "*ST_asgeojson", "*ST_asgml", "*ST_ashexewkb", "*ST_askml",
|
||||
"*ST_assvg", "*ST_geohash", "ST_Astext",
|
||||
# 7.7. Operators
|
||||
# 7.8. Spatial Relationships and Measurements
|
||||
"st_area", "st_azimuth", "st_centroid", "st_closestpoint", "st_contains", "st_containsproperly",
|
||||
"st_covers", "st_coveredby", "st_crosses", "st_linecrossingdirection", "st_disjoint",
|
||||
"st_distance", "st_hausdorffdistance", "st_maxdistance", "st_distance_sphere",
|
||||
"st_distance_spheroid", "st_dfullywithin", "st_dwithin", "st_equals", "st_hasarc",
|
||||
"st_intersects", "st_length", "st_length2d", "st_length3d", "st_length_spheroid",
|
||||
"st_length2d_spheroid", "st_length3d_spheroid", "st_longestline", "st_orderingequals",
|
||||
"st_overlaps", "st_perimeter", "st_perimeter2d", "st_perimeter3d", "st_pointonsurface",
|
||||
"st_relate", "st_shortestline", "st_touches", "st_within",
|
||||
"ST_Area", "ST_Azimuth", "ST_Centroid", "ST_ClosestPoint", "ST_Contains", "ST_ContainsProperly",
|
||||
"ST_Covers", "ST_CoveredBy", "ST_Crosses", "*ST_linecrossingdirection", "ST_Cisjoint",
|
||||
"ST_Distance", "*ST_hausdorffdistance", "*ST_maxdistance", "ST_Distance_Sphere",
|
||||
"ST_Distance_Spheroid", "*ST_DFullyWithin", "ST_DWithin", "ST_Equals", "*ST_hasarc",
|
||||
"ST_Intersects", "ST_Length", "*ST_Length2d", "*ST_length3d", "ST_Length_Spheroid",
|
||||
"*ST_length2d_spheroid", "*ST_length3d_spheroid", "*ST_longestline", "*ST_orderingequals",
|
||||
"ST_Overlaps", "*ST_perimeter", "*ST_perimeter2d", "*ST_perimeter3d", "ST_PointOnSurface",
|
||||
"ST_Relate", "ST_ShortestLine", "ST_Touches", "ST_Within",
|
||||
# 7.9. Geometry Processing Functions
|
||||
"st_buffer", "st_buildarea", "st_collect", "st_convexhull", "st_curvetoline", "st_difference",
|
||||
"st_dump", "st_dumppoints", "st_dumprings", "st_intersection", "st_linetocurve", "st_memunion",
|
||||
"st_minimumboundingcircle", "st_polygonize", "st_shift_longitude", "st_simplify",
|
||||
"st_simplifypreservetopology", "st_symdifference", "st_union",
|
||||
"ST_Buffer", "ST_BuildArea", "ST_Collect", "ST_ConvexHull", "*ST_curvetoline", "ST_Difference",
|
||||
"ST_Dump", "*ST_dumppoints", "*ST_dumprings", "ST_Intersection", "*ST_linetocurve", "*ST_memunion",
|
||||
"*ST_minimumboundingcircle", "*ST_polygonize", "*ST_shift_longitude", "ST_Simplify",
|
||||
"ST_SimplifyPreserveTopology", "ST_SymDifference", "ST_Union",
|
||||
# 7.10. Linear Referencing
|
||||
"st_line_interpolate_point", "st_line_locate_point", "st_line_substring",
|
||||
"st_locate_along_measure", "st_locate_between_measures", "st_locatebetweenelevations",
|
||||
"st_addmeasure",
|
||||
"ST_Line_Interpolate_Point", "ST_Line_Locate_Point", "ST_Line_Substring",
|
||||
"*ST_locate_along_measure", "*ST_locate_between_measures", "*ST_locatebetweenelevations",
|
||||
"*ST_addmeasure",
|
||||
# 7.11. Long Transactions Support
|
||||
"addauth", "checkauth", "disablelongtransactions", "enablelongtransactions", "lockrow",
|
||||
"unlockrows",
|
||||
"*addauth", "*checkauth", "*disablelongtransactions", "*enablelongtransactions", "*lockrow",
|
||||
"*unlockrows",
|
||||
# 7.12. Miscellaneous Functions
|
||||
"st_accum", "box2d", "box3d", "st_estimated_extent", "st_expand", "st_extent", "st_extent3d",
|
||||
"find_srid", "st_mem_size", "st_point_inside_circle", "st_xmax", "st_xmin", "st_ymax", "st_ymin",
|
||||
"st_zmax", "st_zmin",
|
||||
"*ST_accum", "*box2d", "*box3d", "*ST_estimated_extent", "*ST_expand", "ST_Extent", "*ST_extent3d",
|
||||
"*find_srid", "*ST_mem_size", "*ST_point_inside_circle", "ST_XMax", "ST_XMin", "ST_YMax", "ST_YMin",
|
||||
"ST_ZMax", "ST_ZMin",
|
||||
# 7.13. Exceptional Functions
|
||||
"postgis_addbbox", "postgis_dropbbox", "postgis_hasbbox"
|
||||
"*postgis_addbbox", "*postgis_dropbbox", "*postgis_hasbbox"
|
||||
]
|
||||
|
||||
# constants
|
||||
@ -170,6 +183,12 @@ postgis_constants = []
|
||||
|
||||
|
||||
def getSqlDictionary(spatial=True):
|
||||
def strip_star(s):
|
||||
if s[0] == '*':
|
||||
return s.lower()[1:]
|
||||
else:
|
||||
return s.lower()
|
||||
|
||||
k, c, f = list(keywords), list(constants), list(functions)
|
||||
|
||||
if spatial:
|
||||
@ -177,4 +196,17 @@ def getSqlDictionary(spatial=True):
|
||||
f += postgis_functions
|
||||
c += postgis_constants
|
||||
|
||||
return {'keyword': k, 'constant': c, 'function': f}
|
||||
return {'keyword': map(strip_star,k), 'constant': map(strip_star,c), 'function': map(strip_star,f)}
|
||||
|
||||
def getQueryBuilderDictionary():
|
||||
# concat functions
|
||||
def ff( l ):
|
||||
return filter( lambda s:s[0] != '*', l )
|
||||
def add_paren( l ):
|
||||
return map( lambda s:s+"(", l )
|
||||
foo = sorted(add_paren(ff( list(set.union(set(functions), set(postgis_functions))) )))
|
||||
m = sorted(add_paren(ff( math_functions )))
|
||||
agg = sorted(add_paren(ff(aggregate_functions)))
|
||||
op = ff(operators)
|
||||
s = sorted(add_paren(ff(string_functions)))
|
||||
return {'function': foo, 'math' : m, 'aggregate': agg, 'operator': op, 'string': s }
|
||||
|
@ -135,22 +135,28 @@ class SpatiaLiteDBConnector(DBConnector):
|
||||
def getSchemas(self):
|
||||
return None
|
||||
|
||||
def getTables(self, schema=None):
|
||||
def getTables(self, schema=None, add_sys_tables=False):
|
||||
""" get list of tables """
|
||||
tablenames = []
|
||||
items = []
|
||||
|
||||
sys_tables = ["geom_cols_ref_sys", "geometry_columns", "geometry_columns_auth",
|
||||
sys_tables = ["SpatialIndex", "geom_cols_ref_sys", "geometry_columns", "geometry_columns_auth",
|
||||
"views_geometry_columns", "virts_geometry_columns", "spatial_ref_sys",
|
||||
"sqlite_sequence", # "tableprefix_metadata", "tableprefix_rasters",
|
||||
"layer_params", "layer_statistics", "layer_sub_classes", "layer_table_layout",
|
||||
"pattern_bitmaps", "symbol_bitmaps", "project_defs", "raster_pyramids",
|
||||
"sqlite_stat1", "sqlite_stat2", "spatialite_history"]
|
||||
"sqlite_stat1", "sqlite_stat2", "spatialite_history",
|
||||
"geometry_columns_field_infos",
|
||||
"geometry_columns_statistics", "geometry_columns_time",
|
||||
"sql_statements_log","vector_layers", "vector_layers_auth", "vector_layers_field_infos", "vector_layers_statistics",
|
||||
"views_geometry_columns_auth", "views_geometry_columns_field_infos", "views_geometry_columns_statistics",
|
||||
"virts_geometry_columns_auth", "virts_geometry_columns_field_infos", "virts_geometry_columns_statistics"
|
||||
]
|
||||
|
||||
try:
|
||||
vectors = self.getVectorTables(schema)
|
||||
for tbl in vectors:
|
||||
if tbl[1] in sys_tables:
|
||||
if not add_sys_tables and tbl[1] in sys_tables:
|
||||
continue
|
||||
tablenames.append(tbl[1])
|
||||
items.append(tbl)
|
||||
@ -160,7 +166,7 @@ class SpatiaLiteDBConnector(DBConnector):
|
||||
try:
|
||||
rasters = self.getRasterTables(schema)
|
||||
for tbl in rasters:
|
||||
if tbl[1] in sys_tables:
|
||||
if not add_sys_tables and tbl[1] in sys_tables:
|
||||
continue
|
||||
tablenames.append(tbl[1])
|
||||
items.append(tbl)
|
||||
@ -183,7 +189,9 @@ class SpatiaLiteDBConnector(DBConnector):
|
||||
self._execute(c, sql)
|
||||
|
||||
for tbl in c.fetchall():
|
||||
if tablenames.count(tbl[0]) <= 0 and not (tbl[0].startswith('idx_') and tbl[0] in sys_tables):
|
||||
if tablenames.count(tbl[0]) <= 0 and not tbl[0].startswith('idx_'):
|
||||
if not add_sys_tables and tbl[0] in sys_tables:
|
||||
continue
|
||||
item = list(tbl)
|
||||
item.insert(0, Table.TableType)
|
||||
items.append(item)
|
||||
@ -638,3 +646,8 @@ class SpatiaLiteDBConnector(DBConnector):
|
||||
|
||||
sql_dict["identifier"] = items
|
||||
return sql_dict
|
||||
|
||||
def getQueryBuilderDictionary(self):
|
||||
from .sql_dictionary import getQueryBuilderDictionary
|
||||
|
||||
return getQueryBuilderDictionary()
|
||||
|
@ -109,7 +109,6 @@ class SLDatabase(Database):
|
||||
|
||||
return SLSqlResultModel(self, sql, parent)
|
||||
|
||||
|
||||
def registerDatabaseActions(self, mainWindow):
|
||||
action = QAction(self.tr("Run &Vacuum"), self)
|
||||
mainWindow.registerAction(action, self.tr("&Database"), self.runVacuumActionSlot)
|
||||
@ -147,6 +146,12 @@ class SLDatabase(Database):
|
||||
def uniqueIdFunction(self):
|
||||
return None
|
||||
|
||||
def explicitSpatialIndex( self ):
|
||||
return True
|
||||
|
||||
def spatialIndexClause( self, src_table, src_column, dest_table, dest_column ):
|
||||
return """"%s".ROWID IN (\nSELECT ROWID FROM SpatialIndex WHERE f_table_name='%s' AND search_frame="%s"."%s") """ % (src_table,src_table,dest_table, dest_column)
|
||||
|
||||
class SLTable(Table):
|
||||
def __init__(self, row, db, schema=None):
|
||||
Table.__init__(self, db, None)
|
||||
|
@ -50,73 +50,89 @@ spatialite_keywords = []
|
||||
# functions
|
||||
functions = [
|
||||
# TODO get them from a reference page
|
||||
"abs", "changes", "coalesce", "glob", "ifnull", "hex", "last_insert_rowid",
|
||||
"length", "like", "lower", "ltrim", "max", "min", "nullif", "quote", "random",
|
||||
"randomblob", "replace", "round", "rtrim", "soundex", "total_change", "trim",
|
||||
"typeof", "upper", "zeroblob", "date", "datetime", "julianday", "strftime",
|
||||
"avg", "count", "group_concat", "sum", "total"
|
||||
"changes", "coalesce", "glob", "ifnull", "hex", "last_insert_rowid",
|
||||
"nullif", "quote", "random",
|
||||
"randomblob", "replace", "round", "soundex", "total_change",
|
||||
"typeof", "zeroblob", "date", "datetime", "julianday", "strftime"
|
||||
]
|
||||
operators=[
|
||||
' AND ',' OR ','||',' < ',' <= ',' > ',' >= ',' = ',' <> ',' IS ',' IS NOT ',' IN ',' LIKE ',' GLOB ',' MATCH ',' REGEXP '
|
||||
]
|
||||
|
||||
math_functions = [
|
||||
# SQL math functions
|
||||
"Abs", "ACos", "ASin", "ATan", "Cos", "Cot", "Degrees", "Exp", "Floor", "Log", "Log2",
|
||||
"Log10", "Pi", "Radians", "Round", "Sign", "Sin", "Sqrt", "StdDev_Pop", "StdDev_Samp", "Tan",
|
||||
"Var_Pop", "Var_Samp" ]
|
||||
|
||||
string_functions=["Length", "Lower", "Upper", "Like", "Trim", "LTrim", "RTrim", "Replace", "Substr"]
|
||||
|
||||
aggregate_functions=[
|
||||
"Max","Min","Avg","Count","Sum","Group_Concat","Total","Var_Pop","Var_Samp","StdDev_Pop","StdDev_Samp"
|
||||
]
|
||||
|
||||
spatialite_functions = [ # from www.gaia-gis.it/spatialite-2.3.0/spatialite-sql-2.3.0.html
|
||||
# SQL math functions
|
||||
"abs", "acos", "asin", "atan", "cos", "cot", "degrees", "exp", "floor", "log", "log2",
|
||||
"log10", "pi", "radians", "round", "sign", "sin", "sqrt", "stddev_pop", "stddev_samp", "tan",
|
||||
"var_pop", "var_samp",
|
||||
# SQL utility functions for BLOB objects
|
||||
"iszipblob", "ispdfblob", "isgifblob", "ispngblob", "isjpegblob", "isexifblob",
|
||||
"isexifgpsblob", "geomfromexifgpsblob", "makepoint", "buildmbr", "buildcirclembr", "mbrminx",
|
||||
"mbrminy", "mbrmaxx", "mbrmaxy",
|
||||
"*iszipblob", "*ispdfblob", "*isgifblob", "*ispngblob", "*isjpegblob", "*isexifblob",
|
||||
"*isexifgpsblob", "*geomfromexifgpsblob", "MakePoint", "BuildMbr", "*buildcirclembr", "ST_MinX",
|
||||
"ST_MinY", "ST_MaxX", "ST_MaxY",
|
||||
# SQL functions for constructing a geometric object given its Well-known Text Representation
|
||||
"geomfromtext", "pointfromtext",
|
||||
"ST_GeomFromText", "*pointfromtext",
|
||||
# SQL functions for constructing a geometric object given its Well-known Binary Representation
|
||||
"geomfromwkb", "pointfromwkb",
|
||||
"*geomfromwkb", "*pointfromwkb",
|
||||
# SQL functions for obtaining the Well-known Text / Well-known Binary Representation of a geometric object
|
||||
"astext", "asbinary",
|
||||
"ST_AsText", "ST_AsBinary",
|
||||
# SQL functions supporting exotic geometric formats
|
||||
"assvg", "asfgf", "geomfromfgf",
|
||||
"*assvg", "*asfgf", "*geomfromfgf",
|
||||
# SQL functions on type Geometry
|
||||
"dimension", "geometrytype", "srid", "setsrid", "isempty", "issimple", "isvalid", "boundary",
|
||||
"envelope",
|
||||
"ST_Dimension", "ST_GeometryType", "ST_Srid", "ST_SetSrid", "ST_isEmpty", "ST_isSimple", "ST_isValid", "ST_Boundary",
|
||||
"ST_Envelope",
|
||||
# SQL functions on type Point
|
||||
"x", "y",
|
||||
"ST_X", "ST_Y",
|
||||
# SQL functions on type Curve [Linestring or Ring]
|
||||
"startpoint", "endpoint", "glength", "isclosed", "isring", "simplify",
|
||||
"simplifypreservetopology",
|
||||
"ST_StartPoint", "ST_EndPoint", "ST_Length", "ST_isClosed", "ST_isRing", "ST_Simplify",
|
||||
"*simplifypreservetopology",
|
||||
# SQL functions on type LineString
|
||||
"numpoints", "pointn",
|
||||
"ST_NumPoints", "ST_PointN",
|
||||
# SQL functions on type Surface [Polygon or Ring]
|
||||
"centroid", "pointonsurface", "area",
|
||||
"ST_Centroid", "ST_PointOnSurface", "ST_Area",
|
||||
# SQL functions on type Polygon
|
||||
"exteriorring", "interiorringn",
|
||||
"ST_ExteriorRing", "ST_InteriorRingN",
|
||||
# SQL functions on type GeomCollection
|
||||
"numgeometries", "geometryn",
|
||||
"ST_NumGeometries", "ST_GeometryN",
|
||||
# SQL functions that test approximative spatial relationships via MBRs
|
||||
"mbrequal", "mbrdisjoint", "mbrtouches", "mbrwithin", "mbroverlaps", "mbrintersects",
|
||||
"mbrcontains",
|
||||
"MbrEqual", "MbrDisjoint", "MbrTouches", "MbrWithin", "MbrOverlaps", "MbrIntersects",
|
||||
"MbrContains",
|
||||
# SQL functions that test spatial relationships
|
||||
"equals", "disjoint", "touches", "within", "overlaps", "crosses", "intersects", "contains",
|
||||
"relate",
|
||||
"ST_Equals", "ST_Disjoint", "ST_Touches", "ST_Within", "ST_Overlaps", "ST_Crosses", "ST_Intersects", "ST_Contains",
|
||||
"ST_Relate",
|
||||
# SQL functions for distance relationships
|
||||
"distance",
|
||||
"ST_Distance",
|
||||
# SQL functions that implement spatial operators
|
||||
"intersection", "difference", "gunion", "gunion", "symdifference", "buffer", "convexhull",
|
||||
"ST_Intersection", "ST_Difference", "ST_Union", "ST_SymDifference", "ST_Buffer", "ST_ConvexHull",
|
||||
# SQL functions for coordinate transformations
|
||||
"transform",
|
||||
"ST_Transform",
|
||||
# SQL functions for Spatial-MetaData and Spatial-Index handling
|
||||
"initspatialmetadata", "addgeometrycolumn", "recovergeometrycolumn", "discardgeometrycolumn",
|
||||
"createspatialindex", "creatembrcache", "disablespatialindex",
|
||||
"*initspatialmetadata", "*addgeometrycolumn", "*recovergeometrycolumn", "*discardgeometrycolumn",
|
||||
"*createspatialindex", "*creatembrcache", "*disablespatialindex",
|
||||
# SQL functions implementing FDO/OGR compatibily
|
||||
"checkspatialmetadata", "autofdostart", "autofdostop", "initfdospatialmetadata",
|
||||
"addfdogeometrycolumn", "recoverfdogeometrycolumn", "discardfdogeometrycolumn",
|
||||
"*checkspatialmetadata", "*autofdostart", "*autofdostop", "*initfdospatialmetadata",
|
||||
"*addfdogeometrycolumn", "*recoverfdogeometrycolumn", "*discardfdogeometrycolumn",
|
||||
# SQL functions for MbrCache-based queries
|
||||
"filtermbrwithin", "filtermbrcontains", "filtermbrintersects", "buildmbrfilter"
|
||||
"*filtermbrwithin", "*filtermbrcontains", "*filtermbrintersects", "*buildmbrfilter"
|
||||
]
|
||||
|
||||
# constants
|
||||
constants = ["null", "false", "true"]
|
||||
spatialite_constants = []
|
||||
|
||||
|
||||
def getSqlDictionary(spatial=True):
|
||||
def strip_star(s):
|
||||
if s[0] == '*':
|
||||
return s.lower()[1:]
|
||||
else:
|
||||
return s.lower()
|
||||
|
||||
k, c, f = list(keywords), list(constants), list(functions)
|
||||
|
||||
if spatial:
|
||||
@ -124,4 +140,17 @@ def getSqlDictionary(spatial=True):
|
||||
f += spatialite_functions
|
||||
c += spatialite_constants
|
||||
|
||||
return {'keyword': k, 'constant': c, 'function': f}
|
||||
return {'keyword': map(strip_star,k), 'constant': map(strip_star,c), 'function': map(strip_star,f)}
|
||||
|
||||
def getQueryBuilderDictionary():
|
||||
# concat functions
|
||||
def ff( l ):
|
||||
return filter( lambda s:s[0] != '*', l )
|
||||
def add_paren( l ):
|
||||
return map( lambda s:s+"(", l )
|
||||
foo = sorted(add_paren(ff( list(set.union(set(functions), set(spatialite_functions))) )))
|
||||
m = sorted(add_paren(ff( math_functions )))
|
||||
agg = sorted(add_paren(ff(aggregate_functions)))
|
||||
op = ff(operators)
|
||||
s = sorted(add_paren(ff(string_functions)))
|
||||
return {'function': foo, 'math' : m, 'aggregate': agg, 'operator': op, 'string': s }
|
||||
|
@ -117,7 +117,7 @@ class DBTree(QTreeView):
|
||||
menu.addAction(self.tr("Rename"), self.rename)
|
||||
menu.addAction(self.tr("Delete"), self.delete)
|
||||
|
||||
if isinstance(item, Table):
|
||||
if isinstance(item, Table) and item.canBeAddedToCanvas():
|
||||
menu.addSeparator()
|
||||
menu.addAction(self.tr("Add to canvas"), self.addLayer)
|
||||
|
||||
|
381
python/plugins/db_manager/dlg_query_builder.py
Normal file
381
python/plugins/db_manager/dlg_query_builder.py
Normal file
@ -0,0 +1,381 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
/***************************************************************************
|
||||
Name : DB Manager
|
||||
Description : Database manager plugin for QGIS
|
||||
Date : March 2015
|
||||
copyright : (C) 2015 Hugo Mercier / Oslandia
|
||||
email : hugo dot mercier at oslandia dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
Query builder dialog, based on the QSpatialite plugin (GPLv2+) by Romain Riviere
|
||||
"""
|
||||
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
|
||||
from .ui.ui_DlgQueryBuilder import Ui_DbManagerQueryBuilderDlg as Ui_Dialog
|
||||
from .db_plugins.plugin import VectorTable
|
||||
|
||||
class FocusEventFilter(QObject):
|
||||
def __init__( self, parent ):
|
||||
QObject.__init__( self, parent)
|
||||
self.focus = ''
|
||||
|
||||
def eventFilter( self, obj, event ):
|
||||
if event.type() == QEvent.FocusIn:
|
||||
self.focus = obj.objectName()
|
||||
return QObject.eventFilter( self, obj, event )
|
||||
|
||||
|
||||
def insertWithSelection( widget, text ):
|
||||
if widget.textCursor().hasSelection(): #user has selectedsomething...
|
||||
selection=widget.textCursor().selectedText()
|
||||
widget.insertPlainText(text+selection+")")
|
||||
else:
|
||||
widget.insertPlainText(text)
|
||||
|
||||
def insertWithSelectionOn( parent, objectname, text ):
|
||||
"""Insert the text in a QTextEdit given by its objectname"""
|
||||
w = parent.findChild( QTextEdit, objectname )
|
||||
insertWithSelection( w, text )
|
||||
|
||||
class QueryBuilderDlg(QDialog):
|
||||
|
||||
# object used to store parameters between invocations
|
||||
saveParameter = None
|
||||
|
||||
def __init__(self, iface, db, parent=None, reset = False):
|
||||
QDialog.__init__(self, parent)
|
||||
self.iface = iface
|
||||
self.db = db
|
||||
self.query = ''
|
||||
self.ui = Ui_Dialog()
|
||||
self.ui.setupUi(self)
|
||||
self.ui.group.setMaximumHeight(self.ui.tab.sizeHint().height())
|
||||
self.ui.order.setMaximumHeight(self.ui.tab.sizeHint().height())
|
||||
|
||||
self.evt = FocusEventFilter( self )
|
||||
self.ui.col.installEventFilter( self.evt )
|
||||
self.ui.where.installEventFilter( self.evt )
|
||||
self.ui.group.installEventFilter( self.evt )
|
||||
self.ui.order.installEventFilter( self.evt )
|
||||
|
||||
d = self.db.connector.getQueryBuilderDictionary()
|
||||
#Application default parameters
|
||||
self.table=None
|
||||
self.col_col=[]
|
||||
self.col_where=[]
|
||||
self.coltables=[]
|
||||
self.ui.extract.setChecked(True)
|
||||
#ComboBox default values
|
||||
self.ui.functions.insertItems(1,d['function'])
|
||||
self.ui.math.insertItems(1,d['math'])
|
||||
self.ui.aggregates.insertItems(1,d['aggregate'])
|
||||
self.ui.operators.insertItems(1,d['operator'])
|
||||
self.ui.stringfct.insertItems(1,d['string'])
|
||||
#self.ui.Rtree.insertItems(1,rtreecommand)
|
||||
|
||||
# restore last query if needed
|
||||
if reset:
|
||||
QueryBuilderDlg.saveParameter = None
|
||||
if QueryBuilderDlg.saveParameter is not None:
|
||||
self.restoreLastQuery()
|
||||
|
||||
#Show Tables
|
||||
self.show_tables()
|
||||
|
||||
#Signal/slot
|
||||
QObject.connect(self.ui.aggregates,SIGNAL("currentIndexChanged(const QString&)"),self.add_aggregate)
|
||||
QObject.connect(self.ui.stringfct,SIGNAL("currentIndexChanged(const QString&)"),self.add_stringfct)
|
||||
QObject.connect(self.ui.operators,SIGNAL("currentIndexChanged(const QString&)"),self.add_operators)
|
||||
QObject.connect(self.ui.functions,SIGNAL("currentIndexChanged(const QString&)"),self.add_functions)
|
||||
QObject.connect(self.ui.math,SIGNAL("currentIndexChanged(const QString&)"),self.add_math)
|
||||
QObject.connect(self.ui.tables,SIGNAL("currentIndexChanged(const QString&)"),self.add_tables)
|
||||
QObject.connect(self.ui.tables,SIGNAL("currentIndexChanged(const QString&)"),self.list_cols)
|
||||
QObject.connect(self.ui.columns,SIGNAL("currentIndexChanged(const QString&)"),self.add_columns)
|
||||
QObject.connect(self.ui.columns_2,SIGNAL("currentIndexChanged(const QString&)"),self.list_values)
|
||||
QObject.connect(self.ui.reset,SIGNAL("clicked(bool)"),self.reset)
|
||||
QObject.connect(self.ui.extract,SIGNAL("stateChanged(int)"),self.list_values)
|
||||
QObject.connect(self.ui.values,SIGNAL("doubleClicked(const QModelIndex &)"),self.query_item)
|
||||
QObject.connect(self.ui.buttonBox,SIGNAL("accepted()"),self.validate)
|
||||
QObject.connect(self.ui.checkBox,SIGNAL("stateChanged(int)"),self.show_tables)
|
||||
|
||||
if self.db.explicitSpatialIndex():
|
||||
self.tablesGeo=[table for table in self.tables if isinstance(table,VectorTable)]
|
||||
tablesGeo=[ '"%s"."%s"'%(table.name,table.geomColumn) for table in self.tablesGeo]
|
||||
self.ui.table_target.insertItems(1,tablesGeo)
|
||||
self.idxTables=[table for table in self.tablesGeo if table.hasSpatialIndex()]
|
||||
idxTables=['"%s"."%s"'%(table.name,table.geomColumn) for table in self.idxTables]
|
||||
self.ui.table_idx.insertItems(1,idxTables)
|
||||
|
||||
QObject.connect(self.ui.usertree,SIGNAL("clicked(bool)"),self.use_rtree)
|
||||
else:
|
||||
self.ui.toolBox.setItemEnabled(2, False )
|
||||
|
||||
|
||||
def update_table_list( self ):
|
||||
self.tables = []
|
||||
add_sys_tables = self.ui.checkBox.isChecked()
|
||||
schemas = self.db.schemas()
|
||||
if schemas is None:
|
||||
self.tables = self.db.tables( None, add_sys_tables )
|
||||
else:
|
||||
for schema in schemas:
|
||||
self.tables += self.db.tables(schema, add_sys_tables)
|
||||
|
||||
def show_tables(self):
|
||||
self.update_table_list()
|
||||
self.ui.tables.clear()
|
||||
self.ui.tables.insertItems(0,["Tables"])
|
||||
self.ui.tables.insertItems(1,[t.name for t in self.tables])
|
||||
|
||||
def add_aggregate(self):
|
||||
if self.ui.aggregates.currentIndex() <= 0:
|
||||
return
|
||||
ag=self.ui.aggregates.currentText()
|
||||
|
||||
insertWithSelection( self.ui.col, ag )
|
||||
|
||||
self.ui.aggregates.setCurrentIndex(0)
|
||||
|
||||
def add_functions(self):
|
||||
if self.ui.functions.currentIndex() <= 0:
|
||||
return
|
||||
ag=self.ui.functions.currentText()
|
||||
|
||||
insertWithSelectionOn( self, self.evt.focus, ag )
|
||||
|
||||
self.ui.functions.setCurrentIndex(0)
|
||||
|
||||
|
||||
|
||||
def add_stringfct(self):
|
||||
if self.ui.stringFct.currentIndex() <= 0:
|
||||
return
|
||||
ag=self.ui.stringfct.currentText()
|
||||
|
||||
insertWithSelectionOn( self, self.evt.focus, ag )
|
||||
|
||||
self.ui.stringfct.setCurrentIndex(0)
|
||||
|
||||
def add_math(self):
|
||||
if self.ui.math.currentIndex() <= 0:
|
||||
return
|
||||
ag=self.ui.math.currentText()
|
||||
|
||||
insertWithSelectionOn( self, self.evt.focus, ag )
|
||||
|
||||
self.ui.math.setCurrentIndex(0)
|
||||
|
||||
def add_operators(self):
|
||||
if self.ui.operators.currentIndex() <= 0:
|
||||
return
|
||||
ag=self.ui.operators.currentText()
|
||||
|
||||
if self.evt.focus == "where": # in where section
|
||||
self.ui.where.insertPlainText(ag)
|
||||
else:
|
||||
self.ui.col.insertPlainText(ag)
|
||||
self.ui.operators.setCurrentIndex(0)
|
||||
|
||||
def add_tables(self):
|
||||
if self.ui.tables.currentIndex() <= 0:
|
||||
return
|
||||
ag=self.ui.tables.currentText()
|
||||
#Retrieve Table Object from txt
|
||||
tableObj=[table for table in self.tables if table.name.upper()==ag.upper()]
|
||||
if len(tableObj)!=1:
|
||||
return #No object with this name
|
||||
self.table=tableObj[0]
|
||||
if (ag in self.coltables): #table already use
|
||||
reponse=QMessageBox.question(self, "Table already used","Do you want to add table %s again ?"%ag, QMessageBox.Yes | QMessageBox.No)
|
||||
if reponse==QMessageBox.No:
|
||||
return
|
||||
ag = self.table.quotedName()
|
||||
txt=self.ui.tab.text()
|
||||
if (txt is None) or (txt in (""," ")):
|
||||
self.ui.tab.setText('%s'%ag)
|
||||
else:
|
||||
self.ui.tab.setText('%s, %s'%(txt,ag))
|
||||
self.ui.tables.setCurrentIndex(0)
|
||||
|
||||
def add_columns(self):
|
||||
if self.ui.columns.currentIndex() <= 0:
|
||||
return
|
||||
ag=self.ui.columns.currentText()
|
||||
if self.evt.focus == "where": # in where section
|
||||
if ag in self.col_where: # column already called in where section
|
||||
reponse=QMessageBox.question(self, "Column already used in WHERE clause","Do you want to add column %s again ?"%ag, QMessageBox.Yes | QMessageBox.No)
|
||||
if reponse==QMessageBox.No:
|
||||
self.ui.columns.setCurrentIndex(0)
|
||||
return
|
||||
self.ui.where.insertPlainText(ag)
|
||||
self.col_where.append(ag)
|
||||
elif self.evt.focus == "col" :
|
||||
if ag in self.col_col: # column already called in col section
|
||||
reponse=QMessageBox.question(self, "Column already used in COLUMNS section","Do you want to add column %s again ?"%ag, QMessageBox.Yes | QMessageBox.No)
|
||||
if reponse==QMessageBox.No:
|
||||
self.ui.columns.setCurrentIndex(0)
|
||||
return
|
||||
if len(self.ui.col.toPlainText().strip()) > 0:
|
||||
self.ui.col.insertPlainText(",\n" + ag)
|
||||
else:
|
||||
self.ui.col.insertPlainText(ag)
|
||||
self.col_col.append(ag)
|
||||
elif self.evt.focus == "group":
|
||||
if len(self.ui.group.toPlainText().strip()) > 0:
|
||||
self.ui.group.insertPlainText( ", " + ag )
|
||||
else:
|
||||
self.ui.group.insertPlainText( ag )
|
||||
elif self.evt.focus == "order":
|
||||
if len(self.ui.order.toPlainText().strip()) > 0:
|
||||
self.ui.order.insertPlainText( ", " + ag )
|
||||
else:
|
||||
self.ui.order.insertPlainText( ag )
|
||||
|
||||
self.ui.columns.setCurrentIndex(0)
|
||||
|
||||
def list_cols(self):
|
||||
table=self.table
|
||||
if (table is None):
|
||||
return
|
||||
if (table.name in self.coltables):
|
||||
return
|
||||
|
||||
columns=['"%s"."%s"'%(table.name,col.name) for col in table.fields()]
|
||||
#add special '*' column:
|
||||
columns=['"%s".*'%table.name]+columns
|
||||
self.coltables.append(table.name) #table columns have been listed
|
||||
# first and second col combobox
|
||||
end=self.ui.columns.count()
|
||||
self.ui.columns.insertItems(end,columns)
|
||||
self.ui.columns_2.insertItems(end,columns)
|
||||
end=self.ui.columns.count()
|
||||
self.ui.columns.insertSeparator(end)
|
||||
self.ui.columns_2.insertSeparator(end)
|
||||
|
||||
def list_values(self):
|
||||
if self.ui.columns_2.currentIndex() <= 0:
|
||||
return
|
||||
item=self.ui.columns_2.currentText()
|
||||
#recover column and table:
|
||||
column=item.split(".") # "table".'column'
|
||||
table=column[0]
|
||||
if column[1]=='*':
|
||||
return
|
||||
table = table[1:-1]
|
||||
|
||||
qtable = [t for t in self.tables if t.name.lower() == table.lower()][0].quotedName()
|
||||
|
||||
if self.ui.extract.isChecked():
|
||||
limit = 10
|
||||
else:
|
||||
limit = None
|
||||
model = self.db.columnUniqueValuesModel( item, qtable, limit )
|
||||
self.ui.values.setModel(model)
|
||||
|
||||
def query_item(self, index):
|
||||
queryWord = index.data()
|
||||
queryWord=' "%s"' %queryWord
|
||||
if queryWord != '':
|
||||
self.ui.where.insertPlainText(queryWord)
|
||||
self.ui.where.setFocus()
|
||||
|
||||
def use_rtree(self):
|
||||
idx=self.ui.table_idx.currentText()
|
||||
if idx in (None,""," ","Table (with Spatial Index)"):
|
||||
return
|
||||
try:
|
||||
tab_idx=idx.split(".")[0][1:-1] #remove "
|
||||
col_idx=idx.split(".")[1][1:-1] #remove '
|
||||
except:
|
||||
pop_up_error("All fields are necessary",self)
|
||||
tgt=self.ui.table_target.currentText()
|
||||
if tgt in (None,""," ","Table (Target)"):
|
||||
return
|
||||
tgt_tab = tgt.split('.')[0][1:-1]
|
||||
tgt_col = tgt.split('.')[1][1:-1]
|
||||
sql=""
|
||||
if self.ui.where.toPlainText() not in (None,""," "):
|
||||
sql+="\nAND"
|
||||
sql+=self.db.spatialIndexClause( tab_idx, col_idx, tgt_tab, tgt_col )
|
||||
self.ui.where.insertPlainText(sql)
|
||||
|
||||
def reset(self):
|
||||
#reset lists:
|
||||
self.ui.values.setModel(None)
|
||||
self.ui.columns_2.clear()
|
||||
self.ui.columns.insertItems(0,["Columns"])
|
||||
self.ui.columns_2.insertItems(0,["Columns"])
|
||||
self.coltables=[]
|
||||
self.col_col=[]
|
||||
self.col_where=[]
|
||||
|
||||
def validate(self):
|
||||
query_col=unicode(self.ui.col.toPlainText())
|
||||
query_table=unicode(self.ui.tab.text())
|
||||
query_where=unicode(self.ui.where.toPlainText())
|
||||
query_group=unicode(self.ui.group.toPlainText())
|
||||
query_order=unicode(self.ui.order.toPlainText())
|
||||
query=""
|
||||
if query_col.strip()!='':
|
||||
query+="SELECT %s \nFROM %s"%(query_col,query_table)
|
||||
if query_where.strip()!='':
|
||||
query+="\nWHERE %s"%query_where
|
||||
if query_group.strip()!='':
|
||||
query+="\nGROUP BY %s"%query_group
|
||||
if query_order.strip()!='':
|
||||
query+="\nORDER BY %s"%query_order
|
||||
if query == '':
|
||||
return
|
||||
self.query = query
|
||||
|
||||
saveParameter = {}
|
||||
saveParameter["coltables"]=self.coltables
|
||||
saveParameter["col_col"]=self.col_col
|
||||
saveParameter["col_where"]=self.col_where
|
||||
saveParameter["col"]=query_col
|
||||
saveParameter["tab"]=query_table
|
||||
saveParameter["where"]=query_where
|
||||
saveParameter["group"]=query_group
|
||||
saveParameter["order"]=query_order
|
||||
QueryBuilderDlg.saveParameter = saveParameter
|
||||
|
||||
def restoreLastQuery(self):
|
||||
self.update_table_list()
|
||||
|
||||
saveParameter = QueryBuilderDlg.saveParameter
|
||||
self.coltables=saveParameter["coltables"]
|
||||
self.col_col=saveParameter["col_col"]
|
||||
self.col_where=saveParameter["col_where"]
|
||||
self.ui.col.insertPlainText(saveParameter["col"])
|
||||
self.ui.tab.setText(saveParameter["tab"])
|
||||
self.ui.where.insertPlainText(saveParameter["where"])
|
||||
self.ui.order.setPlainText(saveParameter["order"])
|
||||
self.ui.group.setPlainText(saveParameter["group"])
|
||||
#list previous colist:
|
||||
for tablename in self.coltables:
|
||||
#Retrieve table object from table name:
|
||||
table=[table for table in self.tables if table.name.upper()==tablename.upper()]
|
||||
if len(table)!=1:
|
||||
break
|
||||
table=table[0]
|
||||
columns=['"%s"."%s"'%(table.name,col.name) for col in table.fields()]
|
||||
# first and second col combobox
|
||||
end=self.ui.columns.count()
|
||||
self.ui.columns.insertItems(end,columns)
|
||||
self.ui.columns_2.insertItems(end,columns)
|
||||
end=self.ui.columns.count()
|
||||
self.ui.columns.insertSeparator(end)
|
||||
self.ui.columns_2.insertSeparator(end)
|
@ -30,6 +30,7 @@ from qgis.core import QgsProject
|
||||
|
||||
from .db_plugins.plugin import BaseError
|
||||
from .dlg_db_error import DlgDbError
|
||||
from .dlg_query_builder import QueryBuilderDlg
|
||||
|
||||
try:
|
||||
from qgis.gui import QgsCodeEditorSQL
|
||||
@ -88,6 +89,9 @@ class DlgSqlWindow(QDialog, Ui_Dialog):
|
||||
self.connect(self.loadAsLayerGroup, SIGNAL("toggled(bool)"), self.loadAsLayerToggled)
|
||||
self.loadAsLayerToggled(False)
|
||||
|
||||
self.queryBuilderFirst = True
|
||||
self.connect( self.queryBuilderBtn, SIGNAL("clicked()"), self.displayQueryBuilder )
|
||||
|
||||
def updatePresetsCombobox(self):
|
||||
self.presetCombo.clear()
|
||||
|
||||
@ -326,3 +330,11 @@ class DlgSqlWindow(QDialog, Ui_Dialog):
|
||||
|
||||
api.prepare()
|
||||
self.editSql.lexer().setAPIs(api)
|
||||
|
||||
def displayQueryBuilder( self ):
|
||||
dlg = QueryBuilderDlg( self.iface, self.db, self, reset = self.queryBuilderFirst )
|
||||
self.queryBuilderFirst = False
|
||||
r = dlg.exec_()
|
||||
if r == QDialog.Accepted:
|
||||
self.editSql.setText( dlg.query )
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
FILE(GLOB ICON_FILES *.png *.xpm toolbar/*.png)
|
||||
FILE(GLOB ICON_FILES *.gif *.png *.xpm toolbar/*.png)
|
||||
|
||||
PLUGIN_INSTALL(db_manager icons ${ICON_FILES})
|
||||
|
BIN
python/plugins/db_manager/icons/sql.gif
Normal file
BIN
python/plugins/db_manager/icons/sql.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 175 B |
@ -1,30 +1,31 @@
|
||||
<RCC>
|
||||
<qresource prefix="/db_manager">
|
||||
<file>icons/layer_line.png</file>
|
||||
<file>icons/layer_point.png</file>
|
||||
<file>icons/layer_polygon.png</file>
|
||||
<file>icons/layer_raster.png</file>
|
||||
<file>icons/layer_unknown.png</file>
|
||||
<file>icons/namespace.png</file>
|
||||
<file>icons/namespaces.xpm</file>
|
||||
<file>icons/table.png</file>
|
||||
<file>icons/tables.xpm</file>
|
||||
<file>icons/user.xpm</file>
|
||||
<file>icons/users.xpm</file>
|
||||
<file>icons/view.png</file>
|
||||
<file alias="warning">icons/warning-20px.png</file>
|
||||
<file>icons/plugged.png</file>
|
||||
<file>icons/unplugged.png</file>
|
||||
<file alias="icon">icons/dbmanager.png</file>
|
||||
<file>icons/about.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/db_manager/actions">
|
||||
<file alias="del_table">icons/toolbar/action_del_table.png</file>
|
||||
<file alias="edit_table">icons/toolbar/action_edit_table.png</file>
|
||||
<file alias="export">icons/toolbar/action_export.png</file>
|
||||
<file alias="import">icons/toolbar/action_import.png</file>
|
||||
<file alias="create_table">icons/toolbar/action_new_table.png</file>
|
||||
<file alias="refresh">icons/toolbar/action_refresh.png</file>
|
||||
<file alias="sql_window">icons/toolbar/action_sql_window.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/db_manager">
|
||||
<file>icons/layer_line.png</file>
|
||||
<file>icons/sql.gif</file>
|
||||
<file>icons/layer_point.png</file>
|
||||
<file>icons/layer_polygon.png</file>
|
||||
<file>icons/layer_raster.png</file>
|
||||
<file>icons/layer_unknown.png</file>
|
||||
<file>icons/namespace.png</file>
|
||||
<file>icons/namespaces.xpm</file>
|
||||
<file>icons/table.png</file>
|
||||
<file>icons/tables.xpm</file>
|
||||
<file>icons/user.xpm</file>
|
||||
<file>icons/users.xpm</file>
|
||||
<file>icons/view.png</file>
|
||||
<file alias="warning">icons/warning-20px.png</file>
|
||||
<file>icons/plugged.png</file>
|
||||
<file>icons/unplugged.png</file>
|
||||
<file alias="icon">icons/dbmanager.png</file>
|
||||
<file>icons/about.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/db_manager/actions">
|
||||
<file alias="del_table">icons/toolbar/action_del_table.png</file>
|
||||
<file alias="edit_table">icons/toolbar/action_edit_table.png</file>
|
||||
<file alias="export">icons/toolbar/action_export.png</file>
|
||||
<file alias="import">icons/toolbar/action_import.png</file>
|
||||
<file alias="create_table">icons/toolbar/action_new_table.png</file>
|
||||
<file alias="refresh">icons/toolbar/action_refresh.png</file>
|
||||
<file alias="sql_window">icons/toolbar/action_sql_window.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
520
python/plugins/db_manager/ui/DlgQueryBuilder.ui
Normal file
520
python/plugins/db_manager/ui/DlgQueryBuilder.ui
Normal file
@ -0,0 +1,520 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DbManagerQueryBuilderDlg</class>
|
||||
<widget class="QDialog" name="DbManagerQueryBuilderDlg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>797</width>
|
||||
<height>463</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>SQL query builder</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6" stretch="0,0">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Columns</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QTextEdit" name="col">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Tables </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="tab">
|
||||
<property name="frame">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QTextEdit" name="where"/>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QTextEdit" name="group">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QTextEdit" name="order">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Where </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Group by</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Order by</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QToolBox" name="toolBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>250</width>
|
||||
<height>313</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Data</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
<kerning>true</kerning>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show system tables</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="tables">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Tables</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="columns">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Columns</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="aggregates">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Aggregates</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="functions">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Functions</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="math">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Math</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="stringfct">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Strings functions</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="operators">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Operators</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>250</width>
|
||||
<height>313</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Columns' values</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QComboBox" name="columns_2">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Columns</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="extract">
|
||||
<property name="text">
|
||||
<string>Only 10 first values</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListView" name="values">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::NoDragDrop</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>250</width>
|
||||
<height>313</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Spatial index</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
<item>
|
||||
<widget class="QComboBox" name="table_idx">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Table (with spatial index)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="table_target">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Table (Target)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="usertree">
|
||||
<property name="text">
|
||||
<string>Use spatial index</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QPushButton" name="reset">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Reset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>DbManagerQueryBuilderDlg</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>633</x>
|
||||
<y>440</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>DbManagerQueryBuilderDlg</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>516</x>
|
||||
<y>433</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>306</x>
|
||||
<y>423</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>reset</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>where</receiver>
|
||||
<slot>clear()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>21</x>
|
||||
<y>426</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>118</x>
|
||||
<y>249</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>reset</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>tab</receiver>
|
||||
<slot>clear()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>24</x>
|
||||
<y>434</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>147</x>
|
||||
<y>165</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>reset</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>col</receiver>
|
||||
<slot>clear()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>24</x>
|
||||
<y>428</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>208</x>
|
||||
<y>98</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>reset</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>columns</receiver>
|
||||
<slot>clear()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>57</x>
|
||||
<y>437</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>513</x>
|
||||
<y>67</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<width>801</width>
|
||||
<height>525</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -43,6 +43,17 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="queryBuilderBtn">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/db_manager/icons/sql.gif</normaloff>:/db_manager/icons/sql.gif</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="presetName">
|
||||
<property name="text">
|
||||
@ -372,7 +383,9 @@ columns</string>
|
||||
<tabstop>btnClear</tabstop>
|
||||
<tabstop>viewResult</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>loadAsLayerGroup</sender>
|
||||
|
Loading…
x
Reference in New Issue
Block a user