* This is free software; you can redistribute and/or modify it under
* the terms of the GNU General Public Licence. See the COPYING file.
*
- * Maintainer: Paul Ramsey <pramsey@opengeo.org>
+ * Maintainer: Paul Ramsey <pramsey@cleverelephant.ca>
+ * Regina Obe <lr@pcorp.us>
* Mark Leslie <mark.leslie@lisasoft.com>
*
**********************************************************************/
{
va_list ap;
va_start(ap, fmt);
-
+
pgui_seterr_va(fmt, ap);
-
+
va_end(ap);
return;
}
gboolean is_valid;
gchar *filename;
int max_width;
-
+
/* Loop through the list store to find the maximum length of an entry */
max_width = 0;
is_valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(import_file_list_store), &iter);
gtk_tree_model_get(GTK_TREE_MODEL(import_file_list_store), &iter, IMPORT_FILENAME_COLUMN, &filename, -1);
if (strlen(filename) > max_width)
max_width = strlen(filename);
-
+
/* Get next entry */
is_valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(import_file_list_store), &iter);
}
-
+
/* Note the layout manager will handle the minimum size for us; we just need to be concerned with
making sure we don't exceed a maximum limit */
if (max_width > SHAPEFIELDMAXWIDTH)
g_object_set(import_filename_renderer, "width-chars", SHAPEFIELDMAXWIDTH, NULL);
else
g_object_set(import_filename_renderer, "width-chars", -1, NULL);
-
+
return;
}
gboolean dumpformat = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton_loader_options_dumpformat));
gboolean geography = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton_loader_options_geography));
gboolean simplegeoms = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton_loader_options_simplegeoms));
-
+
if (geography)
{
config->geography = 1;
-
+
if (config->geo_col)
free(config->geo_col);
-
+
config->geo_col = strdup(GEOGRAPHY_DEFAULT);
}
else
if (config->geo_col)
free(config->geo_col);
-
+
config->geo_col = strdup(GEOMETRY_DEFAULT);
}
if (dbfonly)
{
config->readshape = 0;
-
+
/* There will be no spatial column so don't create a spatial index */
config->createindex = 0;
}
config->dump_format = 1;
else
config->dump_format = 0;
-
+
/* Simple geometries only */
if (simplegeoms)
config->simple_geometries = 1;
else
- config->simple_geometries = 0;
-
+ config->simple_geometries = 0;
+
return;
}
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_loader_options_dumpformat), global_loader_config->dump_format ? TRUE : FALSE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_loader_options_geography), global_loader_config->geography ? TRUE : FALSE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_loader_options_simplegeoms), global_loader_config->simple_geometries ? TRUE : FALSE);
-
+
return;
}
-
+
/* Set the global config variables controlled by the options dialogue */
static void
pgui_set_loader_configs_from_options_ui()
gboolean is_valid;
gpointer gptr;
SHPLOADERCONFIG *loader_file_config;
-
+
/* First update the global (template) configuration */
update_loader_config_globals_from_options_ui(global_loader_config);
/* Get the SHPLOADERCONFIG for this file entry */
gtk_tree_model_get(GTK_TREE_MODEL(import_file_list_store), &iter, IMPORT_POINTER_COLUMN, &gptr, -1);
loader_file_config = (SHPLOADERCONFIG *)gptr;
-
+
/* Update it */
update_loader_config_globals_from_options_ui(loader_file_config);
-
+
/* Get next entry */
is_valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(import_file_list_store), &iter);
}
-
+
return;
}
GtkListStore *dumper_geocol_combo_list;
char *connection_string, *sql_form, *query, *schema, *table, *geocol_query, *geocol_name=NULL;
int hasgeo, i, j;
-
+
/* Open a connection to the database */
connection_string = ShpDumperGetConnectionStringFromConn(conn);
pg_connection = PQconnectdb(connection_string);
-
+
/* Here we find a list of all tables/views that not in a pg_* schema (or information_schema) and
we return the schema name, table name and whether or not the table/view contains any geo
columns */
- query = "SELECT tableoids.oid, n.nspname, tableoids.relname, COALESCE((SELECT 1 from pg_attribute WHERE attrelid = tableoids.oid AND atttypid IN (SELECT oid FROM pg_type WHERE typname in ('geometry', 'geography')) LIMIT 1), 0) hasgeo FROM (SELECT c.oid, c.relname, c.relnamespace FROM pg_class c WHERE c.relkind IN ('r', 'v') AND c.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname NOT ILIKE 'pg_%' AND nspname <> 'information_schema')) tableoids, pg_namespace n WHERE tableoids.relnamespace = n.oid ORDER BY n.nspname, tableoids.relname";
+ query = "SELECT tableoids.oid, n.nspname, tableoids.relname, COALESCE((SELECT 1 from pg_attribute WHERE attrelid = tableoids.oid AND atttypid IN (SELECT oid FROM pg_type WHERE typname in ('geometry', 'geography')) LIMIT 1), 0) hasgeo FROM (SELECT c.oid, c.relname, c.relnamespace FROM pg_class c WHERE c.relkind IN ('r', 'v', 'm', 'f','p') AND c.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname NOT ILIKE 'pg_%' AND nspname <> 'information_schema')) tableoids, pg_namespace n WHERE tableoids.relnamespace = n.oid ORDER BY n.nspname, tableoids.relname";
result = PQexec(pg_connection, query);
/* Free any existing entries in the model */
gtk_list_store_clear(chooser_table_list_store);
-
+
/* Now insert one row for each query result */
for (i = 0; i < PQntuples(result); i++)
{
dropdown containing the column names */
schema = PQgetvalue(result, i, PQfnumber(result, "nspname"));
table = PQgetvalue(result, i, PQfnumber(result, "relname"));
-
+
sql_form = "SELECT n.nspname, c.relname, a.attname FROM pg_class c, pg_namespace n, pg_attribute a WHERE c.relnamespace = n.oid AND n.nspname = '%s' AND c.relname = '%s' AND a.attrelid = c.oid AND a.atttypid IN (SELECT oid FROM pg_type WHERE typname in ('geometry', 'geography'))";
-
+
geocol_query = malloc(strlen(sql_form) + strlen(schema) + strlen(table) + 1);
sprintf(geocol_query, sql_form, schema, table);
-
+
geocol_result = PQexec(pg_connection, geocol_query);
/* Create a combo list loaded with the column names. Note that while we create the model and load
list here so that we can pass to the export table list store when creating a new entry. This
is to ensure that the export table list model can directly represent a SHPDUMPERCONFIG. */
dumper_geocol_combo_list = gtk_list_store_new(TABLECHOOSER_GEOCOL_COMBO_COLUMNS, G_TYPE_STRING);
-
+
if (PQntuples(geocol_result) > 0)
{
/* Load the columns into the list store */
for (j = 0; j < PQntuples(geocol_result); j++)
{
geocol_name = PQgetvalue(geocol_result, j, PQfnumber(geocol_result, "attname"));
-
+
gtk_list_store_insert_before(dumper_geocol_combo_list, &geocol_iter, (GtkTreeIter *)TABLECHOOSER_GEOCOL_COMBO_TEXT);
gtk_list_store_set(dumper_geocol_combo_list, &geocol_iter,
TABLECHOOSER_GEOCOL_COMBO_TEXT, geocol_name,
{
/* Add a "default" entry */
geocol_name = NULL;
-
+
gtk_list_store_insert_before(dumper_geocol_combo_list, &geocol_iter, (GtkTreeIter *)TABLECHOOSER_GEOCOL_COMBO_TEXT);
gtk_list_store_set(dumper_geocol_combo_list, &geocol_iter,
TABLECHOOSER_GEOCOL_COMBO_TEXT, _("(None)"),
-1);
- }
+ }
/* Free the query result */
PQclear(geocol_result);
/* Free the query string */
free(geocol_query);
-
+
/* Set the list store data */
hasgeo = atoi(PQgetvalue(result, i, PQfnumber(result, "hasgeo")));
gtk_list_store_set(chooser_table_list_store, &iter,
TABLECHOOSER_HASGEO_COLUMN, hasgeo,
-1);
}
-
+
/* Clear up the result set */
PQclear(result);
-
+
/* Close the existing connection */
PQfinish(pg_connection);
pg_connection = NULL;
-
+
return;
}
/* First determine whether the hasgeo tickbox is selected or not */
gboolean geoonly = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton_chooser_geoonly));
int hasgeo;
-
+
/* If unticked then we show all tables */
if (!geoonly)
return TRUE;
else
return FALSE;
}
-
+
return FALSE;
}
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_dumper_options_includegid), global_dumper_config->includegid ? TRUE : FALSE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_dumper_options_keep_fieldname_case), global_dumper_config->keep_fieldname_case ? TRUE : FALSE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_dumper_options_unescapedattrs), global_dumper_config->unescapedattrs ? TRUE : FALSE);
-
+
return;
}
gboolean is_valid;
gpointer gptr;
SHPDUMPERCONFIG *dumper_table_config;
-
+
/* First update the global (template) configuration */
update_dumper_config_globals_from_options_ui(global_dumper_config);
/* Get the SHPDUMPERCONFIG for this file entry */
gtk_tree_model_get(GTK_TREE_MODEL(export_table_list_store), &iter, EXPORT_POINTER_COLUMN, &gptr, -1);
dumper_table_config = (SHPDUMPERCONFIG *)gptr;
-
+
/* Update it */
update_dumper_config_globals_from_options_ui(dumper_table_config);
-
+
/* Get next entry */
is_valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(export_table_list_store), &iter);
}
{
/* Simply update the listview filter */
gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(chooser_filtered_table_list_store));
-
+
return;
}
/* Only update the configuration if the user hit OK */
if (response == GTK_RESPONSE_OK)
pgui_set_dumper_configs_from_options_ui();
-
+
/* Hide the dialog */
gtk_widget_hide(dialog_dumper_options);
-
+
return;
}
SHPLOADERCONFIG *loader_file_config;
char *table_start, *table_end;
int i;
-
+
/* Generate a new configuration by copying the global options first and then
adding in the specific values for this file */
loader_file_config = malloc(sizeof(SHPLOADERCONFIG));
memcpy(loader_file_config, global_loader_config, sizeof(SHPLOADERCONFIG));
-
+
/* Note: we must copy the encoding here since it is the only pass-by-reference
type set in set_loader_config_defaults() and each config needs its own copy
of any referenced items */
loader_file_config->encoding = strdup(global_loader_config->encoding);
-
+
/* Copy the filename (we'll remove the .shp extension in a sec) */
loader_file_config->shp_file = strdup(filename);
-
+
/* Generate the default table name from the filename */
table_start = loader_file_config->shp_file + strlen(loader_file_config->shp_file);
while (*table_start != '/' && *table_start != '\\' && table_start > loader_file_config->shp_file)
table_start--;
-
+
/* Forward one to start of actual characters */
table_start++;
/* Set the default schema to public */
loader_file_config->schema = strdup("public");
-
+
/* Set the default geo column name */
if (global_loader_config->geography)
loader_file_config->geo_col = strdup(GEOGRAPHY_DEFAULT);
else
loader_file_config->geo_col = strdup(GEOMETRY_DEFAULT);
-
+
return loader_file_config;
}
GtkTreeIter iter;
#define MAXLEN 16
char srid[MAXLEN+1];
-
+
/* Convert SRID into string */
if ( MAXLEN+1 <= snprintf(srid, MAXLEN+1, "%d", loader_file_config->sr_id) )
{
pgui_raise_error_dialogue();
srid[MAXLEN] = '\0';
}
-
+
gtk_list_store_insert_before(import_file_list_store, &iter, NULL);
gtk_list_store_set(import_file_list_store, &iter,
IMPORT_POINTER_COLUMN, loader_file_config,
IMPORT_GEOMETRY_COLUMN, loader_file_config->geo_col,
IMPORT_SRID_COLUMN, srid,
IMPORT_MODE_COLUMN, _("Create"),
- -1);
-
+ -1);
+
/* Update the filename field width */
update_filename_field_width();
-
+
return;
}
if (config->schema)
free(config->schema);
-
+
if (config->geo_col)
free(config->geo_col);
-
+
if (config->shp_file)
free(config->shp_file);
if (config->tablespace)
free(config->tablespace);
-
+
if (config->idxtablespace)
free(config->idxtablespace);
-
+
/* Free the config itself */
free(config);
}
SHPDUMPERCONFIG *dumper_table_config;
gchar *schema, *table, *geocol;
gint hasgeo;
-
+
/* Generate a new configuration by copying the global options first and then
adding in the specific values for this table */
dumper_table_config = malloc(sizeof(SHPDUMPERCONFIG));
memcpy(dumper_table_config, global_dumper_config, sizeof(SHPDUMPERCONFIG));
-
+
/* Grab the values from the current iter */
gtk_tree_model_get(GTK_TREE_MODEL(chooser_filtered_table_list_store), iter,
TABLECHOOSER_SCHEMA_COLUMN, &schema,
TABLECHOOSER_TABLE_COLUMN, &table,
TABLECHOOSER_GEO_COLUMN, &geocol,
TABLECHOOSER_HASGEO_COLUMN, &hasgeo,
- -1);
-
+ -1);
+
/* Set up the values in the SHPDUMPERCONFIG */
dumper_table_config->schema = strdup(schema);
dumper_table_config->table = strdup(table);
-
+
/* We also set the filename the same as the table name */
dumper_table_config->shp_file = strdup(table);
-
+
if (hasgeo && geocol)
dumper_table_config->geo_col_name = strdup(geocol);
else
dumper_table_config->geo_col_name = NULL;
-
+
return dumper_table_config;
}
{
GtkTreeIter iter;
GtkListStore *geocol_liststore;
-
+
gtk_list_store_insert_before(export_table_list_store, &iter, NULL);
gtk_list_store_set(export_table_list_store, &iter,
EXPORT_POINTER_COLUMN, dumper_table_config,
EXPORT_GEOMETRY_COLUMN, dumper_table_config->geo_col_name,
EXPORT_FILENAME_COLUMN, dumper_table_config->shp_file,
-1);
-
+
/* If we have supplied the table_chooser store for additional information, use it */
if (chooser_liststore)
{
gtk_tree_model_get(GTK_TREE_MODEL(chooser_liststore), chooser_iter,
TABLECHOOSER_GEO_LISTSTORE_COLUMN, &geocol_liststore,
-1);
-
+
gtk_list_store_set(export_table_list_store, &iter,
EXPORT_GEOMETRY_LISTSTORE_COLUMN, geocol_liststore,
-1);
}
-
+
return;
}
if (config->schema)
free(config->schema);
-
+
if (config->geo_col_name)
free(config->geo_col_name);
-
+
if (config->shp_file)
free(config->shp_file);
-
+
/* Free the config itself */
free(config);
}
if (!strcmp(pg_fieldtype, "varchar"))
return -1;
break;
-
+
case FTDate:
/* Only date */
if (!strcmp(pg_fieldtype, "date"))
return -1;
break;
-
+
case FTInteger:
/* Tentatively allow int2, int4 and numeric */
if (!strcmp(pg_fieldtype, "int2") || !strcmp(pg_fieldtype, "int4") || !strcmp(pg_fieldtype, "numeric"))
return -1;
break;
-
+
case FTDouble:
/* Only float8/numeric */
if (!strcmp(pg_fieldtype, "float8") || !strcmp(pg_fieldtype, "numeric"))
return -1;
break;
-
+
case FTLogical:
/* Only boolean */
if (!strcmp(pg_fieldtype, "boolean"))
return -1;
break;
}
-
+
/* Otherwise we can't guarantee this (but this is just a warning anyway) */
return 0;
}
int ntuples;
char *pg_fieldname, *pg_fieldtype;
int ret, i, j, found, response = SHPLOADEROK;
-
+
/* Check the status of the result set */
status = PQresultStatus(result);
if (status == PGRES_TUPLES_OK)
{
ntuples = PQntuples(result);
-
+
switch (config->opt)
{
case 'c':
{
pgui_seterr(_("ERROR: Create mode selected for existing table: %s.%s"), config->schema, config->table);
response = SHPLOADERERR;
- }
+ }
break;
-
+
case 'p':
/* If we have a row matching the table given in the config, then it already exists */
if (ntuples > 0)
pgui_seterr(_("ERROR: Prepare mode selected for existing table: %s.%s"), config->schema, config->table);
response = SHPLOADERERR;
}
- break;
+ break;
case 'a':
/* If we are trying to append to a table but it doesn't exist, emit a warning */
pgui_logf(_("Warning: Could not load shapefile %s"), config->shp_file);
ShpLoaderDestroy(state);
}
-
+
/* Find each column based upon its name and then validate type separately... */
for (i = 0; i < state->num_fields; i++)
{
{
pg_fieldname = PQgetvalue(result, j, PQfnumber(result, "field"));
pg_fieldtype = PQgetvalue(result, j, PQfnumber(result, "type"));
-
+
if (!strcmp(state->field_names[i], pg_fieldname))
{
found = -1;
-
+
ret = validate_shape_column_against_pg_column(state->types[i], pg_fieldtype);
if (!ret)
{
}
}
}
-
+
/* Flag a warning if we can't find a match */
if (!found)
{
response = SHPLOADERWARN;
}
}
-
+
ShpLoaderDestroy(state);
}
-
+
break;
}
}
pgui_seterr(_("ERROR: unable to process validation response from remote server"));
response = SHPLOADERERR;
}
-
- return response;
+
+ return response;
}
/* Terminate the main loop and exit the application. */
/* Only update the configuration if the user hit OK */
if (response == GTK_RESPONSE_OK)
pgui_set_loader_configs_from_options_ui();
-
+
/* Hide the dialog */
gtk_widget_hide(dialog_loader_options);
-
+
return;
}
/* Make sure we deselect any files from the last time */
gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(dialog_filechooser));
-
+
/* Run the dialog */
if (gtk_dialog_run(GTK_DIALOG(dialog_filechooser)) == GTK_RESPONSE_ACCEPT)
{
/* Create the new file configuration based upon the each filename and add it to the listview */
filename_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog_filechooser));
-
+
filename_item = g_slist_nth(filename_list, 0);
while (filename_item)
{
/* Add the configuration */
filename = g_slist_nth_data(filename_item, 0);
-
+
loader_file_config = create_new_file_config(filename);
add_loader_file_config_to_list(loader_file_config);
-
+
/* Grab the next filename */
filename_item = g_slist_next(filename_item);
}
-
+
/* Free the list */
g_slist_free(filename_list);
}
-
+
gtk_widget_hide(dialog_filechooser);
}
GList *selected_rows_list, *selected_row;
GtkTreeIter iter;
GtkTreePath *tree_path;
-
- /* Make sure we can connect to the database first */
+
+ /* Make sure we can connect to the database first */
if (!connection_test())
{
pgui_seterr(_("Unable to connect to the database - please check your connection settings"));
gtk_widget_show_all(GTK_WIDGET(window_conn));
return;
}
-
+
/* Setup the form */
update_table_chooser_from_database();
gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(chooser_filtered_table_list_store));
/* Get the tree iter */
tree_path = (GtkTreePath *)g_list_nth_data(selected_row, 0);
gtk_tree_model_get_iter(model, &iter, tree_path);
-
+
/* Get the config and add it to the list */
- dumper_table_config = create_new_table_config(&iter);
- add_dumper_table_config_to_list(dumper_table_config, chooser_filtered_table_list_store, &iter);
-
+ dumper_table_config = create_new_table_config(&iter);
+ add_dumper_table_config_to_list(dumper_table_config, chooser_filtered_table_list_store, &iter);
+
/* Get the next row */
selected_row = g_list_next(selected_row);
}
-
+
/* Free the GList */
g_list_foreach(selected_row, (GFunc)gtk_tree_path_free, NULL);
g_list_free(selected_row);
}
-
+
gtk_widget_hide(dialog_tablechooser);
}
GtkTreeIter iter;
SHPDUMPERCONFIG *dumper_table_config;
gpointer gptr;
-
+
/* Grab the SHPDUMPERCONFIG from the EXPORT_POINTER_COLUMN for the list store */
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(export_table_list_store), &iter, path);
gtk_tree_model_get(GTK_TREE_MODEL(export_table_list_store), &iter, EXPORT_POINTER_COLUMN, &gptr, -1);
dumper_table_config = (SHPDUMPERCONFIG *)gptr;
-
+
/* Free the configuration from memory */
free_dumper_config(dumper_table_config);
-
+
/* Remove the row from the list */
gtk_list_store_remove(export_table_list_store, &iter);
}
static void
pgui_action_import(GtkWidget *widget, gpointer data)
-{
+{
SHPLOADERCONFIG *loader_file_config;
SHPLOADERSTATE *state;
gint is_valid;
char *sql_form, *query, *connection_string, *progress_shapefile = NULL;
char progress_text[GUIMSG_LINE_MAXLEN+1];
PGresult *result;
-
+
int ret, i = 0;
char *header, *footer, *record;
-
+
/* Get the first row of the import list */
is_valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(import_file_list_store), &iter);
if (!is_valid)
out earlier in the function */
connection_string = ShpDumperGetConnectionStringFromConn(conn);
pg_connection = PQconnectdb(connection_string);
-
+
/* Setup the table/column type discovery query */
sql_form = "SELECT a.attnum, a.attname AS field, t.typname AS type, a.attlen AS length, a.atttypmod AS precision FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n WHERE c.relname = '%s' AND n.nspname = '%s' AND a.attnum > 0 AND a.attrelid = c.oid AND a.atttypid = t.oid AND c.relnamespace = n.oid ORDER BY a.attnum";
-
+
/* Validation: we loop through each of the files in order to validate them as a separate pass */
while (is_valid)
{
/* Grab the SHPLOADERCONFIG for this row */
gtk_tree_model_get(GTK_TREE_MODEL(import_file_list_store), &iter, IMPORT_POINTER_COLUMN, &gptr, -1);
loader_file_config = (SHPLOADERCONFIG *)gptr;
-
+
/* For each entry, we execute a remote query in order to determine the column names
and types for the remote table if they actually exist */
query = malloc(strlen(sql_form) + strlen(loader_file_config->schema) + strlen(loader_file_config->table) + 1);
sprintf(query, sql_form, loader_file_config->table, loader_file_config->schema);
result = PQexec(pg_connection, query);
-
+
/* Call the validation function with the SHPLOADERCONFIG and the result set */
ret = validate_remote_loader_columns(loader_file_config, result);
if (ret == SHPLOADERERR)
{
pgui_raise_error_dialogue();
-
+
PQclear(result);
free(query);
-
+
return;
- }
-
+ }
+
/* Free the SQL query */
PQclear(result);
free(query);
/* Get next entry */
is_valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(import_file_list_store), &iter);
}
-
+
/* Close our database connection */
- PQfinish(pg_connection);
+ PQfinish(pg_connection);
+
-
/* Once we've done the validation pass, now let's load the shapefile */
is_valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(import_file_list_store), &iter);
while (is_valid)
/* Grab the SHPLOADERCONFIG for this row */
gtk_tree_model_get(GTK_TREE_MODEL(import_file_list_store), &iter, IMPORT_POINTER_COLUMN, &gptr, -1);
loader_file_config = (SHPLOADERCONFIG *)gptr;
-
+
pgui_logf("\n==============================");
pgui_logf("Importing with configuration: %s, %s, %s, %s, mode=%c, dump=%d, simple=%d, geography=%d, index=%d, shape=%d, srid=%d", loader_file_config->table, loader_file_config->schema, loader_file_config->geo_col, loader_file_config->shp_file, loader_file_config->opt, loader_file_config->dump_format, loader_file_config->simple_geometries, loader_file_config->geography, loader_file_config->createindex, loader_file_config->readshape, loader_file_config->sr_id);
-
+
/*
* Loop through the items in the shapefile
*/
is_running = TRUE;
-
+
/* One connection per file, otherwise error handling becomes tricky... */
pg_connection = PQconnectdb(connection_string);
/* Allow GTK events to get a look in */
while (gtk_events_pending())
gtk_main_iteration();
-
+
/* Create the shapefile state object */
state = ShpLoaderCreate(loader_file_config);
progress_shapefile = malloc(strlen(loader_file_config->shp_file));
strcpy(progress_shapefile, &loader_file_config->shp_file[i]);
-
+
/* Display the progress dialog */
snprintf(progress_text, GUIMSG_LINE_MAXLEN, _("Importing shapefile %s (%d records)..."), progress_shapefile, ShpLoaderGetRecordCount(state));
progress_text[GUIMSG_LINE_MAXLEN] = '\0';
if ( records_per_tick < 1 )
records_per_tick = 1;
-
+
/* If we are in COPY (dump format) mode, output the COPY statement and enter COPY mode */
if (state->config->dump_format)
{
if (state->config->createindex)
{
gtk_label_set_text(GTK_LABEL(label_progress), _("Creating spatial index..."));
-
+
/* Allow GTK events to get a look in */
while (gtk_events_pending())
gtk_main_iteration();
if (!ret)
goto import_cleanup;
}
-
+
import_cleanup:
/* Import has definitely stopped running */
is_running = FALSE;
/* Close the existing connection */
PQfinish(pg_connection);
pg_connection = NULL;
-
+
/* If we didn't finish inserting all of the items (and we expected to), an error occurred */
if ((state->config->opt != 'p' && i != ShpLoaderGetRecordCount(state)) || !ret)
pgui_logf(_("Shapefile import failed."));
/* Tidy up */
if (progress_shapefile)
free(progress_shapefile);
-
+
/* Get next entry */
is_valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(import_file_list_store), &iter);
}
-
+
/* Import has definitely finished */
is_running = FALSE;
/* Hide the progress dialog */
gtk_widget_hide(dialog_progress);
-
+
/* Allow GTK events to get a look in */
while (gtk_events_pending())
gtk_main_iteration();
static void
pgui_action_export(GtkWidget *widget, gpointer data)
-{
+{
SHPDUMPERCONFIG *dumper_table_config;
SHPDUMPERSTATE *state;
gint is_valid;
char *output_shapefile, *orig_shapefile;
char progress_text[GUIMSG_LINE_MAXLEN+1];
gchar *folder_path;
-
+
int ret, success = FALSE, i = 0;
-
+
/* Get the first row of the import list */
is_valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(export_table_list_store), &iter);
if (!is_valid)
if (gtk_dialog_run(GTK_DIALOG(dialog_folderchooser)) != GTK_RESPONSE_ACCEPT)
{
gtk_widget_hide(dialog_folderchooser);
-
+
return;
}
-
+
gtk_widget_hide(dialog_folderchooser);
folder_path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog_folderchooser));
-
+
/* Now everything is set up, let's extract the tables */
is_valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(export_table_list_store), &iter);
while (is_valid)
/* Grab the SHPDUMPERCONFIG for this row */
gtk_tree_model_get(GTK_TREE_MODEL(export_table_list_store), &iter, EXPORT_POINTER_COLUMN, &gptr, -1);
dumper_table_config = (SHPDUMPERCONFIG *)gptr;
-
+
pgui_logf("\n==============================");
pgui_logf("Exporting with configuration: %s, %s, %s", dumper_table_config->table, dumper_table_config->schema, dumper_table_config->shp_file);
-
+
/* Export is running */
is_running = TRUE;
success = FALSE;
-
+
/* Disable the button to prevent multiple imports running at the same time */
gtk_widget_set_sensitive(widget, FALSE);
/* Allow GTK events to get a look in */
while (gtk_events_pending())
gtk_main_iteration();
-
+
/* Create the state for each configuration */
state = ShpDumperCreate(dumper_table_config);
state->config->conn = conn;
-
+
/* Save the original shapefile name, then create a temporary version containing the full path */
orig_shapefile = dumper_table_config->shp_file;
output_shapefile = malloc(strlen(folder_path) + strlen(dumper_table_config->shp_file) + 2);
{
pgui_seterr("%s", state->message);
pgui_raise_error_dialogue();
-
+
goto export_cleanup;
}
-
+
/* Display the progress dialog */
gtk_label_set_text(GTK_LABEL(label_progress), _("Initialising..."));
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), 0.0);
gtk_widget_show_all(dialog_progress);
-
+
ret = ShpDumperOpenTable(state);
if (ret != SHPDUMPEROK)
{
if (ret == SHPDUMPERERR)
{
gtk_widget_hide(dialog_progress);
-
+
pgui_seterr("%s", state->message);
pgui_raise_error_dialogue();
-
+
goto export_cleanup;
}
}
pgui_logf(_("Done (postgis major version: %d)"), state->pgis_major_version);
pgui_logf(_("Output shape: %s"), shapetypename(state->outshptype));
-
+
for (i = 0; i < ShpDumperGetRecordCount(state) && is_running == TRUE; i++)
{
ret = ShpLoaderGenerateShapeRow(state);
if (ret != SHPDUMPEROK)
{
pgui_logf("%s", state->message);
-
+
if (ret == SHPDUMPERERR)
{
gtk_widget_hide(dialog_progress);
-
+
pgui_seterr("%s", state->message);
pgui_raise_error_dialogue();
-
+
goto export_cleanup;
}
}
-
+
/* Update the progress bar */
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), (float)i / ShpDumperGetRecordCount(state));
/* Allow GTK events to get a look in */
while (gtk_events_pending())
- gtk_main_iteration();
+ gtk_main_iteration();
}
/* Finish the dump */
if (ret != SHPDUMPEROK)
{
pgui_logf("%s", state->message);
-
+
if (ret == SHPDUMPERERR)
{
gtk_widget_hide(dialog_progress);
-
+
pgui_seterr("%s", state->message);
pgui_raise_error_dialogue();
}
/* Indicate success */
if (is_running)
success = TRUE;
-
+
export_cleanup:
/* Tidy up everything */
/* Reset shapefile back to original form (without full path) */
dumper_table_config->shp_file = orig_shapefile;
-
+
/* Get next entry */
is_valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(export_table_list_store), &iter);
}
-
+
/* Export has definitely finished */
is_running = FALSE;
if (!success)
pgui_logf(_("Table export failed."));
else
pgui_logf(_("Table export completed."));
-
+
/* Enable the button once again */
gtk_widget_set_sensitive(widget, TRUE);
/* Hide the progress dialog */
gtk_widget_hide(dialog_progress);
-
+
/* Allow GTK events to get a look in */
while (gtk_events_pending())
gtk_main_iteration();
-
+
return;
}
/* Create a new row in the listview */
loader_file_config = create_new_file_config(filename);
- add_loader_file_config_to_list(loader_file_config);
+ add_loader_file_config_to_list(loader_file_config);
g_free(filename);
g_free(hostname);
update_loader_file_config_from_listview_iter(GtkTreeIter *iter, SHPLOADERCONFIG *loader_file_config)
{
gchar *schema, *table, *geo_col, *srid;
-
+
/* Grab the main values for this file */
gtk_tree_model_get(GTK_TREE_MODEL(import_file_list_store), iter,
IMPORT_SCHEMA_COLUMN, &schema,
IMPORT_GEOMETRY_COLUMN, &geo_col,
IMPORT_SRID_COLUMN, &srid,
-1);
-
+
/* Update the schema */
if (loader_file_config->schema)
free(loader_file_config->schema);
-
+
loader_file_config->schema = strdup(schema);
/* Update the table */
if (loader_file_config->table)
free(loader_file_config->table);
-
+
loader_file_config->table = strdup(table);
/* Update the geo column */
if (loader_file_config->geo_col)
free(loader_file_config->geo_col);
-
+
loader_file_config->geo_col = strdup(geo_col);
-
+
/* Update the SRID */
loader_file_config->sr_id = atoi(srid);
char opt;
gchar *combo_text;
gpointer gptr;
-
+
/* Grab the SHPLOADERCONFIG from the IMPORT_POINTER_COLUMN for the list store */
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(import_file_list_store), &iter, path_string);
gtk_tree_model_get(GTK_TREE_MODEL(import_file_list_store), &iter, IMPORT_POINTER_COLUMN, &gptr, -1);
/* Now grab the row selected within the combo box */
gtk_tree_model_get(GTK_TREE_MODEL(loader_mode_combo_list), new_iter, LOADER_MODE_COMBO_OPTION_CHAR, &opt, -1);
-
+
/* Update the configuration */
-
+
/* Hack for index creation: we must disable it if we are appending, otherwise we
end up trying to generate the index again */
loader_file_config->createindex = global_loader_config->createindex;
-
+
switch (opt)
{
case 'a':
loader_file_config->opt = 'a';
-
+
/* Other half of index creation hack */
loader_file_config->createindex = 0;
-
+
break;
-
+
case 'd':
loader_file_config->opt = 'd';
break;
-
+
case 'p':
loader_file_config->opt = 'p';
break;
-
+
case 'c':
loader_file_config->opt = 'c';
break;
}
-
+
/* Update the selection in the listview with the text from the combo */
gtk_tree_model_get(GTK_TREE_MODEL(loader_mode_combo_list), new_iter, LOADER_MODE_COMBO_TEXT, &combo_text, -1);
gtk_list_store_set(import_file_list_store, &iter, IMPORT_MODE_COLUMN, combo_text, -1);
-
- return;
+
+ return;
}
-
+
/*
* This method is a signal listener for all text renderers in the file
SHPLOADERCONFIG *loader_file_config;
#define MAXLEN 16
char srid[MAXLEN+1];
-
+
/* Empty doesn't fly */
if (strlen(new_text) == 0)
return;
-
+
/* Update the model with the current edit change */
columnindex = *(gint *)column;
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(import_file_list_store), &iter, path);
gtk_list_store_set(import_file_list_store, &iter, columnindex, new_text, -1);
-
+
/* Grab the SHPLOADERCONFIG from the IMPORT_POINTER_COLUMN for the list store */
gtk_tree_model_get(GTK_TREE_MODEL(import_file_list_store), &iter, IMPORT_POINTER_COLUMN, &gptr, -1);
loader_file_config = (SHPLOADERCONFIG *)gptr;
-
+
/* Update the configuration from the current UI data */
update_loader_file_config_from_listview_iter(&iter, loader_file_config);
-
+
/* Now refresh the listview UI row with the new configuration */
if ( MAXLEN+1 <= snprintf(srid, MAXLEN+1, "%d", loader_file_config->sr_id) )
{
pgui_raise_error_dialogue();
srid[MAXLEN] = '\0';
}
-
+
gtk_list_store_set(import_file_list_store, &iter,
IMPORT_SCHEMA_COLUMN, loader_file_config->schema,
IMPORT_TABLE_COLUMN, loader_file_config->table,
GtkTreeIter iter;
SHPLOADERCONFIG *loader_file_config;
gpointer gptr;
-
+
/* Grab the SHPLOADERCONFIG from the IMPORT_POINTER_COLUMN for the list store */
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(import_file_list_store), &iter, path);
gtk_tree_model_get(GTK_TREE_MODEL(import_file_list_store), &iter, IMPORT_POINTER_COLUMN, &gptr, -1);
loader_file_config = (SHPLOADERCONFIG *)gptr;
-
+
/* Free the configuration from memory */
free_loader_config(loader_file_config);
-
+
/* Remove the row from the list */
gtk_list_store_remove(import_file_list_store, &iter);
update_dumper_table_config_from_listview_iter(GtkTreeIter *iter, SHPDUMPERCONFIG *dumper_table_config)
{
gchar *schema, *table, *geo_col, *filename;
-
+
/* Grab the main values for this file */
gtk_tree_model_get(GTK_TREE_MODEL(export_table_list_store), iter,
EXPORT_SCHEMA_COLUMN, &schema,
EXPORT_GEOMETRY_COLUMN, &geo_col,
EXPORT_FILENAME_COLUMN, &filename,
-1);
-
+
/* Update the schema */
if (dumper_table_config->schema)
free(dumper_table_config->schema);
-
+
dumper_table_config->schema = strdup(schema);
-
+
/* Update the table */
if (dumper_table_config->table)
free(dumper_table_config->table);
-
+
dumper_table_config->table = strdup(table);
-
+
/* Update the geometry column */
if (dumper_table_config->geo_col_name)
free(dumper_table_config->geo_col_name);
-
+
dumper_table_config->geo_col_name = strdup(geo_col);
/* Update the filename column (default to table name) */
if (dumper_table_config->shp_file)
free(dumper_table_config->shp_file);
-
+
dumper_table_config->shp_file = strdup(filename);
return;
GtkTreeIter iter;
GtkListStore *model;
gpointer gptr;
-
- /* Get the existing geo column name */
+
+ /* Get the existing geo column name */
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(export_table_list_store), &iter, path_string);
gtk_tree_model_get(GTK_TREE_MODEL(export_table_list_store), &iter,
EXPORT_POINTER_COLUMN, &gptr,
EXPORT_GEOMETRY_COLUMN, &geocol_name,
EXPORT_GEOMETRY_LISTSTORE_COLUMN, &model,
-1);
-
+
/* If the geocol_name is NULL then there was no geo column so exit */
if (!geocol_name)
return;
-
+
/* Otherwise update the geo column name in the config and the model */
gtk_tree_model_get(GTK_TREE_MODEL(model), new_iter, TABLECHOOSER_GEOCOL_COMBO_TEXT, &geocol_name, -1);
dumper_table_config = (SHPDUMPERCONFIG *)gptr;
-
+
if (dumper_table_config->geo_col_name)
{
free(dumper_table_config->geo_col_name);
-
+
dumper_table_config->geo_col_name = strdup(geocol_name);
}
-
+
gtk_list_store_set(export_table_list_store, &iter,
EXPORT_GEOMETRY_COLUMN, geocol_name,
-1);
-
+
return;
}
gpointer gptr;
gint columnindex;
SHPDUMPERCONFIG *dumper_table_config;
-
+
/* Empty doesn't fly */
if (strlen(new_text) == 0)
return;
-
+
/* Update the model with the current edit change */
columnindex = *(gint *)column;
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(export_table_list_store), &iter, path);
gtk_list_store_set(export_table_list_store, &iter, columnindex, new_text, -1);
-
+
/* Grab the SHPDUMPERCONFIG from the EXPORT_POINTER_COLUMN for the list store */
gtk_tree_model_get(GTK_TREE_MODEL(export_table_list_store), &iter, EXPORT_POINTER_COLUMN, &gptr, -1);
dumper_table_config = (SHPDUMPERCONFIG *)gptr;
-
+
/* Update the configuration from the current UI data */
update_dumper_table_config_from_listview_iter(&iter, dumper_table_config);
-
+
/* Now refresh the listview UI row with the new configuration */
gtk_list_store_set(export_table_list_store, &iter,
EXPORT_SCHEMA_COLUMN, dumper_table_config->schema,
gtk_entry_set_text(GTK_ENTRY(entry_pg_user), conn->username);
else
gtk_entry_set_text(GTK_ENTRY(entry_pg_user), "");
-
+
if (conn->password)
gtk_entry_set_text(GTK_ENTRY(entry_pg_pass), conn->password);
else
gtk_entry_set_text(GTK_ENTRY(entry_pg_pass), "");
-
+
if (conn->host)
gtk_entry_set_text(GTK_ENTRY(entry_pg_host), conn->host);
else
gtk_entry_set_text(GTK_ENTRY(entry_pg_host), "");
-
+
if (conn->port)
gtk_entry_set_text(GTK_ENTRY(entry_pg_port), conn->port);
else
gtk_entry_set_text(GTK_ENTRY(entry_pg_port), "");
-
+
if (conn->database)
gtk_entry_set_text(GTK_ENTRY(entry_pg_db), conn->database);
else
update_conn_config_from_conn_ui(void)
{
const char *text;
-
+
text = gtk_entry_get_text(GTK_ENTRY(entry_pg_user));
if (conn->username)
free(conn->username);
-
+
if (strlen(text))
conn->username = strdup(text);
else
conn->username = NULL;
-
+
text = gtk_entry_get_text(GTK_ENTRY(entry_pg_pass));
if (conn->password)
free(conn->password);
-
+
if (strlen(text))
conn->password = strdup(text);
else
conn->password = NULL;
-
+
text = gtk_entry_get_text(GTK_ENTRY(entry_pg_host));
if (conn->host)
free(conn->host);
-
+
if (strlen(text))
conn->host = strdup(text);
else
text = gtk_entry_get_text(GTK_ENTRY(entry_pg_port));
if (conn->port)
free(conn->port);
-
+
if (strlen(text))
conn->port = strdup(text);
else
text = gtk_entry_get_text(GTK_ENTRY(entry_pg_db));
if (conn->database)
free(conn->database);
-
+
if (strlen(text))
conn->database = strdup(text);
else
{
/* Update the UI with the current options */
update_conn_ui_from_conn_config();
-
+
gtk_widget_show_all(GTK_WIDGET(window_conn));
return;
}
pgui_validate_connection()
{
int i;
-
+
if (conn->port && strlen(conn->port))
{
for (i = 0; i < strlen(conn->port); i++)
}
}
}
-
+
return 1;
}
/* If we find a \, hide both it and the next character */
if ( *ptr == '\\' )
*ptr++ = '*';
-
+
*ptr++ = '*';
}
}
{
/* Update the configuration structure from the form */
update_conn_config_from_conn_ui();
-
+
/* Make sure have a valid connection first */
if (!pgui_validate_connection())
{
pgui_raise_error_dialogue();
return;
}
-
+
if (!connection_test())
{
pgui_logf(_("Connection failed."));
-
+
/* If the connection failed, display a warning before closing */
pgui_seterr(_("Unable to connect to the database - please check your connection settings"));
pgui_raise_error_dialogue();
{
pgui_logf(_("Connection succeeded."));
}
-
-
+
+
/* Hide the window after the test */
gtk_widget_hide(GTK_WIDGET(window_conn));
}
"Mark Leslie <mark.s.leslie@gmail.com>",
NULL
};
-
-
+
+
dialog_about = gtk_about_dialog_new();
gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(dialog_about), _("PostGIS Shapefile Import/Export Manager"));
pgui_create_filechooser_dialog(void)
{
GtkFileFilter *file_filter_shape;
-
+
/* Create the dialog */
dialog_filechooser = gtk_file_chooser_dialog_new( _("Select a Shape File"), GTK_WINDOW (window_main),
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CLOSE, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
/* Allow multiple files to be selected */
g_object_set(dialog_filechooser, "select-multiple", TRUE, NULL);
-
+
return;
}
pgui_create_folderchooser_dialog(void)
{
GtkFileFilter *file_filter_shape;
-
+
/* Create the dialog */
dialog_folderchooser = gtk_file_chooser_dialog_new( _("Select an output folder"), GTK_WINDOW (window_main),
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CLOSE, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
pgui_create_progress_dialog()
{
GtkWidget *vbox_progress, *table_progress;
-
+
dialog_progress = gtk_dialog_new_with_buttons(_("Working..."), GTK_WINDOW(window_main), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
gtk_window_set_modal(GTK_WINDOW(dialog_progress), TRUE);
/* Use a vbox as the base container */
vbox_progress = gtk_dialog_get_content_area(GTK_DIALOG(dialog_progress));
gtk_box_set_spacing(GTK_BOX(vbox_progress), 15);
-
+
/* Create a table within the vbox */
table_progress = gtk_table_new(2, 1, TRUE);
gtk_container_set_border_width (GTK_CONTAINER (table_progress), 12);
gtk_table_set_row_spacings(GTK_TABLE(table_progress), 5);
gtk_table_set_col_spacings(GTK_TABLE(table_progress), 10);
-
+
/* Text for the progress bar */
label_progress = gtk_label_new("");
gtk_table_attach_defaults(GTK_TABLE(table_progress), label_progress, 0, 1, 0, 1);
-
+
/* Progress bar for the import */
progress = gtk_progress_bar_new();
gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(progress), GTK_PROGRESS_LEFT_TO_RIGHT);
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), 0.0);
gtk_table_attach_defaults(GTK_TABLE(table_progress), progress, 0, 1, 1, 2);
-
+
/* Add the table to the vbox */
gtk_box_pack_start(GTK_BOX(vbox_progress), table_progress, FALSE, FALSE, 0);
-
+
/* Add signal for cancel button */
g_signal_connect(dialog_progress, "response", G_CALLBACK(pgui_action_progress_cancel), dialog_progress);
-
+
/* Make sure we catch a delete event too */
gtk_signal_connect(GTK_OBJECT(dialog_progress), "delete_event", GTK_SIGNAL_FUNC(pgui_action_progress_delete), NULL);
-
+
return;
}
align_options_center = gtk_alignment_new( 0.5, 0.5, 0.0, 1.0 );
gtk_table_attach_defaults(GTK_TABLE(table_options), align_options_center, 0, 1, 7, 8 );
gtk_container_add (GTK_CONTAINER (align_options_center), checkbutton_loader_options_simplegeoms);
-
+
/* Catch the response from the dialog */
g_signal_connect(dialog_loader_options, "response", G_CALLBACK(pgui_action_loader_options_close), dialog_loader_options);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_loader_options)->vbox), table_options, FALSE, FALSE, 0);
-
+
/* Hook the delete event so we don't destroy the dialog (just hide) if cancelled */
gtk_signal_connect(GTK_OBJECT(dialog_loader_options), "delete_event", GTK_SIGNAL_FUNC(pgui_event_popup_delete), NULL);
}
align_options_center = gtk_alignment_new( 0.5, 0.5, 0.0, 1.0 );
gtk_table_attach_defaults(GTK_TABLE(table_options), align_options_center, 0, 1, 0, 1 );
gtk_container_add (GTK_CONTAINER (align_options_center), checkbutton_dumper_options_includegid);
-
+
pgui_create_options_dialog_add_label(table_options, _("Preserve case of column names"), 0.0, 1);
checkbutton_dumper_options_keep_fieldname_case = gtk_check_button_new();
align_options_center = gtk_alignment_new( 0.5, 0.5, 0.0, 1.0 );
/* Catch the response from the dialog */
g_signal_connect(dialog_dumper_options, "response", G_CALLBACK(pgui_action_dumper_options_close), dialog_dumper_options);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_dumper_options)->vbox), table_options, FALSE, FALSE, 0);
-
+
/* Hook the delete event so we don't destroy the dialog (just hide) if cancelled */
gtk_signal_connect(GTK_OBJECT(dialog_dumper_options), "delete_event", GTK_SIGNAL_FUNC(pgui_event_popup_delete), NULL);
}
/* Create the main top level window with a 10px border */
dialog_tablechooser = gtk_dialog_new_with_buttons(_("Table selection"), GTK_WINDOW(window_main),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
-
+
gtk_container_set_border_width(GTK_CONTAINER(dialog_tablechooser), 10);
gtk_window_set_position(GTK_WINDOW(dialog_tablechooser), GTK_WIN_POS_CENTER);
-
+
vbox_tree = gtk_dialog_get_content_area(GTK_DIALOG(dialog_tablechooser));
/* Setup a model */
GTK_TYPE_TREE_MODEL,
G_TYPE_STRING,
G_TYPE_INT);
-
+
/* Because we want to do selective filtering on the treeview content, we now implement a GtkTreeModel
filter on top of the original tree model */
chooser_filtered_table_list_store = (GtkListStore *)gtk_tree_model_filter_new(GTK_TREE_MODEL(chooser_table_list_store), NULL);
gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(chooser_filtered_table_list_store),
(GtkTreeModelFilterVisibleFunc)table_chooser_visibility_func, NULL, NULL);
-
+
/* Create the view and such */
chooser_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(chooser_filtered_table_list_store));
chooser_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(chooser_tree));
gtk_tree_selection_set_mode(chooser_selection, GTK_SELECTION_MULTIPLE);
-
+
/* Make the tree view in a scrollable window */
sw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(vbox_tree), sw, FALSE, FALSE, 10);
gtk_container_add(GTK_CONTAINER(sw), chooser_tree);
-
+
/* Schema Field */
chooser_schema_renderer = gtk_cell_renderer_text_new();
g_object_set(chooser_schema_renderer, "editable", TRUE, NULL);
NULL);
g_object_set(chooser_table_column, "resizable", TRUE, "sizing", GTK_TREE_VIEW_COLUMN_AUTOSIZE, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(chooser_tree), chooser_table_column);
-
+
/* Create table to hold the tick-box and text */
table_progress = gtk_table_new(1, 2, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (table_progress), 0);
gtk_table_set_row_spacings(GTK_TABLE(table_progress), 0);
gtk_table_set_col_spacings(GTK_TABLE(table_progress), 0);
-
+
checkbutton_chooser_geoonly = gtk_check_button_new();
gtk_table_attach(GTK_TABLE(table_progress), checkbutton_chooser_geoonly, 0, 1, 0, 1, GTK_SHRINK, GTK_FILL, 0, 0);
label = gtk_label_new(_("Only show tables with geo columns"));
gtk_table_attach(GTK_TABLE(table_progress), label, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 5, 0);
g_signal_connect(G_OBJECT(checkbutton_chooser_geoonly), "toggled", G_CALLBACK(pgui_action_chooser_toggle_show_geocolumn), NULL);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_chooser_geoonly), TRUE);
-
+
/* Attach table to the vbox */
gtk_box_pack_start(GTK_BOX(vbox_tree), table_progress, FALSE, FALSE, 10);
-
+
return;
}
GtkWidget *sw;
GtkTreeIter iter;
gint *column_indexes;
-
+
gtk_container_set_border_width (GTK_CONTAINER (import_list_frame), 0);
vbox_tree = gtk_vbox_new(FALSE, 15);
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_BOOLEAN);
-
+
/* Create the view and such */
import_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(import_file_list_store));
-
+
/* GTK has a slightly brain-dead API in that you can't directly find
the column being used by a GtkCellRenderer when using the same
callback to handle multiple fields; hence we manually store this
information here and pass a pointer to the column index into
the signal handler */
column_indexes = g_malloc(sizeof(gint) * IMPORT_N_COLUMNS);
-
+
/* Make the tree view in a scrollable window */
sw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
gtk_widget_set_size_request(sw, -1, 150);
-
+
gtk_box_pack_start(GTK_BOX(vbox_tree), sw, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER (sw), import_tree);
/* Place the "Add File" button below the list view */
add_file_button = gtk_button_new_with_label(_("Add File"));
gtk_container_add (GTK_CONTAINER (vbox_tree), add_file_button);
-
+
/* Filename Field */
import_filename_renderer = gtk_cell_renderer_text_new();
g_object_set(import_filename_renderer, "editable", FALSE, NULL);
loader_mode_combo_list = gtk_list_store_new(LOADER_MODE_COMBO_COLUMNS,
G_TYPE_STRING,
G_TYPE_CHAR);
-
+
gtk_list_store_insert(loader_mode_combo_list, &iter, CREATE_MODE);
gtk_list_store_set(loader_mode_combo_list, &iter,
LOADER_MODE_COMBO_TEXT, _("Create"),
- LOADER_MODE_COMBO_OPTION_CHAR, 'c',
+ LOADER_MODE_COMBO_OPTION_CHAR, 'c',
-1);
gtk_list_store_insert(loader_mode_combo_list, &iter, APPEND_MODE);
gtk_list_store_set(loader_mode_combo_list, &iter,
gtk_tree_view_append_column(GTK_TREE_VIEW(import_tree), import_mode_column);
gtk_combo_box_set_active(GTK_COMBO_BOX(loader_mode_combo), 1);
g_object_set(import_mode_column, "resizable", TRUE, "expand", TRUE, "sizing", GTK_TREE_VIEW_COLUMN_AUTOSIZE, NULL);
-
+
g_signal_connect (G_OBJECT(import_mode_renderer), "changed", G_CALLBACK(pgui_action_handle_tree_combo), NULL);
/* Remove Field */
{
{ "text/uri-list", 0, 0}
};
-
+
gint n_drop_types = sizeof(drop_types)/sizeof(drop_types[0]);
gtk_drag_dest_set(GTK_WIDGET(import_tree),
GTK_DEST_DEFAULT_ALL,
GtkWidget *vbox_tree;
GtkWidget *sw;
gint *column_indexes;
-
+
gtk_container_set_border_width (GTK_CONTAINER (export_list_frame), 0);
vbox_tree = gtk_vbox_new(FALSE, 15);
GTK_TYPE_TREE_MODEL,
G_TYPE_STRING,
G_TYPE_BOOLEAN);
-
+
/* Create the view and such */
export_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(export_table_list_store));
-
+
/* GTK has a slightly brain-dead API in that you can't directly find
the column being used by a GtkCellRenderer when using the same
callback to handle multiple fields; hence we manually store this
information here and pass a pointer to the column index into
the signal handler */
column_indexes = g_malloc(sizeof(gint) * EXPORT_N_COLUMNS);
-
+
/* Make the tree view in a scrollable window */
sw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
gtk_widget_set_size_request(sw, -1, 150);
-
+
gtk_box_pack_start(GTK_BOX(vbox_tree), sw, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER (sw), export_tree);
NULL);
g_object_set(export_filename_column, "resizable", TRUE, "expand", TRUE, "sizing", GTK_TREE_VIEW_COLUMN_AUTOSIZE, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(export_tree), export_filename_column);
-
+
/* Remove Field */
export_remove_renderer = gtk_cell_renderer_toggle_new();
g_object_set(export_remove_renderer, "activatable", TRUE, NULL);
{
/* Default text width */
static int text_width = 12;
-
+
/* Vbox container */
GtkWidget *vbox;
-
+
/* Reusable label handle */
GtkWidget *label;
/* PgSQL section */
GtkWidget *frame_pg, *table_pg;
-
+
/* OK button */
GtkWidget *button_okay;
gtk_window_set_title(GTK_WINDOW(window_conn), _("PostGIS connection"));
gtk_window_set_position(GTK_WINDOW(window_conn), GTK_WIN_POS_CENTER);
gtk_window_set_modal(GTK_WINDOW(window_conn), TRUE);
-
+
/* Use a vbox as the base container */
vbox = gtk_vbox_new(FALSE, 15);
-
+
/*
** PostGIS info in a table
*/
entry_pg_db = gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(table_pg), label, 0, 1, 3, 4 );
gtk_table_attach_defaults(GTK_TABLE(table_pg), entry_pg_db, 1, 3, 3, 4 );
-
+
/* Add table into containing frame */
gtk_container_add(GTK_CONTAINER(frame_pg), table_pg);
/* Add frame into containing vbox */
gtk_container_add(GTK_CONTAINER(window_conn), vbox);
-
+
/* Add the vbox into the window */
gtk_container_add(GTK_CONTAINER(vbox), frame_pg);
-
+
/* Create a simple "OK" button for the dialog */
button_okay = gtk_button_new_with_label(_("OK"));
gtk_container_add(GTK_CONTAINER(vbox), button_okay);
g_signal_connect(G_OBJECT(button_okay), "clicked", G_CALLBACK(pgui_action_connection_okay), NULL);
-
+
/* Hook the delete event so we don't destroy the dialog (only hide it) if cancelled */
gtk_signal_connect(GTK_OBJECT(window_conn), "delete_event", GTK_SIGNAL_FUNC(pgui_event_popup_delete), NULL);
-
+
return;
-}
+}
static void
pgui_create_main_window(const SHPCONNECTIONCONFIG *conn)
{
/* Main widgets */
GtkWidget *vbox_main, *vbox_loader, *vbox_dumper;
-
+
/* PgSQL section */
GtkWidget *frame_pg, *import_list_frame, *export_list_frame, *frame_log;
GtkWidget *button_pg_conn;
-
+
/* Notebook */
GtkWidget *notebook;
-
+
/* Button section */
GtkWidget *loader_hbox_buttons, *loader_button_options, *loader_button_import, *loader_button_cancel, *loader_button_about;
GtkWidget *dumper_hbox_buttons, *dumper_button_options, *dumper_button_export, *dumper_button_cancel, *dumper_button_about;
-
+
/* Log section */
GtkWidget *scrolledwindow_log;
gtk_window_set_title(GTK_WINDOW(window_main), _("PostGIS Shapefile Import/Export Manager"));
gtk_window_set_position(GTK_WINDOW(window_main), GTK_WIN_POS_CENTER_ALWAYS);
gtk_window_set_resizable(GTK_WINDOW(window_main), FALSE);
-
+
/* Open it a bit wider so that both the label and title show up */
gtk_window_set_default_size(GTK_WINDOW(window_main), 180, 500);
-
+
/* Connect the destroy event of the window with our pgui_quit function
* When the window is about to be destroyed we get a notificaiton and
* stop the main GTK loop
/* Connection row */
frame_pg = gtk_frame_new(_("PostGIS Connection"));
-
+
/* Test button row */
button_pg_conn = gtk_button_new_with_label(_("View connection details..."));
g_signal_connect(G_OBJECT(button_pg_conn), "clicked", G_CALLBACK(pgui_action_connection_details), NULL);
gtk_container_set_border_width(GTK_CONTAINER(button_pg_conn), 10);
gtk_container_add(GTK_CONTAINER(frame_pg), button_pg_conn);
-
+
/*
* GTK Notebook for selecting import/export
*/
notebook = gtk_notebook_new();
-
+
/*
** Shape file selector
*/
dumper_button_export = gtk_button_new_with_label(_("Export"));
dumper_button_cancel = gtk_button_new_with_label(_("Cancel"));
dumper_button_about = gtk_button_new_with_label(_("About"));
-
+
/* Add actions to the buttons */
g_signal_connect (G_OBJECT (dumper_button_export), "clicked", G_CALLBACK (pgui_action_export), NULL);
g_signal_connect (G_OBJECT (dumper_button_options), "clicked", G_CALLBACK (pgui_action_dumper_options_open), NULL);
gtk_box_pack_end(GTK_BOX(dumper_hbox_buttons), dumper_button_cancel, TRUE, TRUE, 0);
gtk_box_pack_end(GTK_BOX(dumper_hbox_buttons), dumper_button_about, TRUE, TRUE, 0);
gtk_box_pack_end(GTK_BOX(dumper_hbox_buttons), dumper_button_export, TRUE, TRUE, 0);
-
+
/*
** Log window
*/
/* Add the loader frames into the notebook page */
vbox_loader = gtk_vbox_new(FALSE, 10);
gtk_container_set_border_width(GTK_CONTAINER(vbox_loader), 10);
-
+
gtk_box_pack_start(GTK_BOX(vbox_loader), import_list_frame, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox_loader), loader_hbox_buttons, FALSE, FALSE, 0);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_loader, gtk_label_new(_("Import")));
-
+
/* Add the dumper frames into the notebook page */
vbox_dumper = gtk_vbox_new(FALSE, 10);
gtk_container_set_border_width(GTK_CONTAINER(vbox_dumper), 10);
-
+
gtk_box_pack_start(GTK_BOX(vbox_dumper), export_list_frame, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox_dumper), dumper_hbox_buttons, FALSE, FALSE, 0);
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_dumper, gtk_label_new(_("Export")));
-
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_dumper, gtk_label_new(_("Export")));
+
/* Add the frames into the main vbox */
gtk_box_pack_start(GTK_BOX(vbox_main), frame_pg, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox_main), notebook, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox_main), frame_log, TRUE, TRUE, 0);
-
+
/* and insert the vbox into the main window */
gtk_container_add(GTK_CONTAINER(window_main), vbox_main);
-
+
/* make sure that everything, window and label, are visible */
gtk_widget_show_all(window_main);
set_loader_config_defaults(global_loader_config);
global_dumper_config = malloc(sizeof(SHPDUMPERCONFIG));
set_dumper_config_defaults(global_dumper_config);
-
+
/* Here we override any defaults for the GUI */
global_loader_config->createindex = 1;
global_loader_config->geo_col = strdup(GEOMETRY_DEFAULT);
global_loader_config->dump_format = 1;
-
+
conn = malloc(sizeof(SHPCONNECTIONCONFIG));
memset(conn, 0, sizeof(SHPCONNECTIONCONFIG));
-
+
/* Here we override any defaults for the connection */
conn->host = strdup("localhost");
conn->port = strdup("5432");
/* initialize the GTK stack */
gtk_init(&argc, &argv);
-
+
/* set up the user interface */
pgui_create_main_window(conn);
pgui_create_connection_window();
pgui_create_progress_dialog();
pgui_create_tablechooser_dialog();
pgui_create_folderchooser_dialog();
-
+
/* start the main loop */
gtk_main();