2009-01-19 21:33:14 +00:00
/**********************************************************************
*
* PostGIS - Spatial Types for PostgreSQL
2014-01-29 17:49:35 +00:00
* http : //postgis.net
2009-01-19 21:33:14 +00:00
* Copyright 2008 OpenGeo . org
2010-08-11 09:50:38 +00:00
* Copyright 2010 LISAsoft
2009-01-19 21:33:14 +00:00
*
* 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 >
2010-08-11 09:50:38 +00:00
* Mark Leslie < mark . leslie @ lisasoft . com >
2009-01-19 21:33:14 +00:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-01-14 00:49:14 +00:00
# include "../postgis_config.h"
2009-01-19 21:33:14 +00:00
# include <stdarg.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <gtk/gtk.h>
2010-08-11 09:50:38 +00:00
# include <gdk/gdk.h>
# include <sys/stat.h>
2009-01-19 21:33:14 +00:00
# include "libpq-fe.h"
# include "shp2pgsql-core.h"
2012-01-08 23:32:05 +00:00
# include "pgsql2shp-core.h"
2009-01-19 21:33:14 +00:00
2010-01-04 00:34:19 +00:00
# define GUI_RCSID "shp2pgsql-gui $Revision$"
2010-08-11 09:50:38 +00:00
# define SHAPEFIELDMAXWIDTH 60
2012-01-08 23:32:05 +00:00
static void pgui_log_va ( const char * fmt , va_list ap ) ;
static void pgui_seterr_va ( const char * fmt , va_list ap ) ;
2010-01-04 00:32:15 +00:00
2012-01-10 12:28:46 +00:00
static void update_conn_ui_from_conn_config ( void ) ;
2012-03-30 14:17:34 +00:00
/* If GTK+ version is < 2.14.0, define gtk_dialog_get_content_area() */
# if !GTK_CHECK_VERSION(2, 14, 0)
# if !defined(gtk_dialog_get_content_area)
# define gtk_dialog_get_content_area(dialog) GTK_DIALOG(dialog)->vbox
# endif
# endif
2009-01-19 21:33:14 +00:00
/*
* * Global variables for GUI only
*/
/* Main window */
2009-12-29 20:16:48 +00:00
static GtkWidget * window_main = NULL ;
2012-01-08 23:32:05 +00:00
2009-12-29 20:16:48 +00:00
static GtkWidget * textview_log = NULL ;
static GtkTextBuffer * textbuffer_log = NULL ;
2010-08-11 09:50:38 +00:00
2012-02-04 00:39:24 +00:00
/* Main import window (listview) */
GtkListStore * import_file_list_store ;
GtkWidget * import_tree ;
GtkCellRenderer * import_filename_renderer ;
GtkCellRenderer * import_schema_renderer ;
GtkCellRenderer * import_table_renderer ;
GtkCellRenderer * import_geom_column_renderer ;
GtkCellRenderer * import_srid_renderer ;
GtkCellRenderer * import_mode_renderer ;
GtkCellRenderer * import_remove_renderer ;
GtkTreeViewColumn * import_filename_column ;
GtkTreeViewColumn * import_schema_column ;
GtkTreeViewColumn * import_table_column ;
GtkTreeViewColumn * import_geom_column ;
GtkTreeViewColumn * import_srid_column ;
GtkTreeViewColumn * import_mode_column ;
GtkTreeViewColumn * import_remove_column ;
static GtkWidget * add_file_button = NULL ;
GtkWidget * loader_mode_combo = NULL ;
GtkListStore * loader_mode_combo_list ;
/* Main export window (listview) */
GtkListStore * export_table_list_store ;
GtkWidget * export_tree ;
GtkWidget * export_geom_column_combo ;
GtkCellRenderer * export_schema_renderer ;
GtkCellRenderer * export_table_renderer ;
GtkCellRenderer * export_geom_column_renderer ;
GtkCellRenderer * export_filename_renderer ;
GtkCellRenderer * export_remove_renderer ;
GtkTreeViewColumn * export_schema_column ;
GtkTreeViewColumn * export_table_column ;
GtkTreeViewColumn * export_geom_column ;
GtkTreeViewColumn * export_filename_column ;
GtkTreeViewColumn * export_remove_column ;
static GtkWidget * add_table_button = NULL ;
2009-01-19 21:33:14 +00:00
2012-01-08 23:32:05 +00:00
/* PostgreSQL database connection window */
static GtkWidget * window_conn = NULL ;
static GtkWidget * entry_pg_user = NULL ;
static GtkWidget * entry_pg_pass = NULL ;
static GtkWidget * entry_pg_host = NULL ;
static GtkWidget * entry_pg_port = NULL ;
static GtkWidget * entry_pg_db = NULL ;
2012-02-04 00:39:24 +00:00
/* Loader options window */
static GtkWidget * dialog_loader_options = NULL ;
2010-08-15 08:30:08 +00:00
static GtkWidget * entry_options_encoding = NULL ;
2012-02-04 00:39:24 +00:00
static GtkWidget * checkbutton_loader_options_preservecase = NULL ;
static GtkWidget * checkbutton_loader_options_forceint = NULL ;
static GtkWidget * checkbutton_loader_options_autoindex = NULL ;
static GtkWidget * checkbutton_loader_options_dbfonly = NULL ;
static GtkWidget * checkbutton_loader_options_dumpformat = NULL ;
static GtkWidget * checkbutton_loader_options_geography = NULL ;
2012-02-04 00:39:38 +00:00
static GtkWidget * checkbutton_loader_options_simplegeoms = NULL ;
2012-02-04 00:39:24 +00:00
/* Dumper options window */
static GtkWidget * dialog_dumper_options = NULL ;
static GtkWidget * checkbutton_dumper_options_includegid = NULL ;
static GtkWidget * checkbutton_dumper_options_keep_fieldname_case = NULL ;
static GtkWidget * checkbutton_dumper_options_unescapedattrs = NULL ;
2009-01-19 21:33:14 +00:00
2012-01-08 23:32:05 +00:00
/* About dialog */
static GtkWidget * dialog_about = NULL ;
/* File chooser */
static GtkWidget * dialog_filechooser = NULL ;
2012-02-04 00:39:24 +00:00
static GtkWidget * dialog_folderchooser = NULL ;
2012-01-08 23:32:05 +00:00
/* Progress dialog */
static GtkWidget * dialog_progress = NULL ;
static GtkWidget * progress = NULL ;
static GtkWidget * label_progress = NULL ;
2012-02-04 00:39:24 +00:00
/* Table chooser dialog */
static GtkWidget * dialog_tablechooser = NULL ;
GtkListStore * chooser_filtered_table_list_store ;
GtkListStore * chooser_table_list_store ;
GtkWidget * chooser_tree ;
GtkCellRenderer * chooser_schema_renderer ;
GtkCellRenderer * chooser_table_renderer ;
GtkTreeViewColumn * chooser_schema_column ;
GtkTreeViewColumn * chooser_table_column ;
static GtkWidget * checkbutton_chooser_geoonly = NULL ;
2012-01-08 23:32:05 +00:00
/* Other items */
static int valid_connection = 0 ;
/* Constants for the list view etc. */
enum
{
2012-02-04 00:39:24 +00:00
IMPORT_POINTER_COLUMN ,
IMPORT_FILENAME_COLUMN ,
IMPORT_SCHEMA_COLUMN ,
IMPORT_TABLE_COLUMN ,
IMPORT_GEOMETRY_COLUMN ,
IMPORT_SRID_COLUMN ,
IMPORT_MODE_COLUMN ,
IMPORT_REMOVE_COLUMN ,
IMPORT_N_COLUMNS
2012-01-08 23:32:05 +00:00
} ;
enum
{
2012-02-04 00:39:24 +00:00
LOADER_MODE_COMBO_TEXT ,
LOADER_MODE_COMBO_OPTION_CHAR ,
LOADER_MODE_COMBO_COLUMNS
2012-01-08 23:32:05 +00:00
} ;
enum
{
CREATE_MODE ,
APPEND_MODE ,
DELETE_MODE ,
PREPARE_MODE
} ;
2012-02-04 00:39:24 +00:00
enum
{
EXPORT_POINTER_COLUMN ,
EXPORT_SCHEMA_COLUMN ,
EXPORT_TABLE_COLUMN ,
EXPORT_GEOMETRY_COLUMN ,
EXPORT_GEOMETRY_LISTSTORE_COLUMN ,
EXPORT_FILENAME_COLUMN ,
EXPORT_REMOVE_COLUMN ,
EXPORT_N_COLUMNS
} ;
enum
{
TABLECHOOSER_SCHEMA_COLUMN ,
TABLECHOOSER_TABLE_COLUMN ,
TABLECHOOSER_GEO_LISTSTORE_COLUMN ,
TABLECHOOSER_GEO_COLUMN ,
TABLECHOOSER_HASGEO_COLUMN ,
TABLECHOOSER_N_COLUMNS
} ;
enum
{
TABLECHOOSER_GEOCOL_COMBO_TEXT ,
TABLECHOOSER_GEOCOL_COMBO_COLUMNS
} ;
2009-01-19 21:33:14 +00:00
/* Other */
2015-02-17 10:23:18 +00:00
# define GUIMSG_LINE_MAXLEN 256
2015-02-17 10:42:51 +00:00
static char pgui_errmsg [ GUIMSG_LINE_MAXLEN + 1 ] ;
2009-12-29 20:16:48 +00:00
static PGconn * pg_connection = NULL ;
static SHPCONNECTIONCONFIG * conn = NULL ;
2012-01-08 23:32:05 +00:00
static SHPLOADERCONFIG * global_loader_config = NULL ;
2012-02-04 00:39:24 +00:00
static SHPDUMPERCONFIG * global_dumper_config = NULL ;
2009-01-19 21:33:14 +00:00
2012-02-04 00:39:24 +00:00
static volatile int is_running = FALSE ;
2009-12-22 12:28:35 +00:00
2009-12-29 20:16:48 +00:00
/* Local prototypes */
2010-08-11 09:50:38 +00:00
static void pgui_sanitize_connection_string ( char * connection_string ) ;
2012-01-08 23:32:05 +00:00
2009-01-19 21:33:14 +00:00
/*
* * Write a message to the Import Log text area .
*/
2010-08-11 09:50:38 +00:00
void
2009-12-13 20:31:54 +00:00
pgui_log_va ( const char * fmt , va_list ap )
2009-01-19 21:33:14 +00:00
{
2015-02-17 10:29:26 +00:00
char msg [ GUIMSG_LINE_MAXLEN + 1 ] ;
2010-08-11 09:50:38 +00:00
GtkTextIter iter ;
2009-01-19 21:33:14 +00:00
2015-02-17 10:23:18 +00:00
if ( - 1 = = vsnprintf ( msg , GUIMSG_LINE_MAXLEN , fmt , ap ) ) return ;
msg [ GUIMSG_LINE_MAXLEN ] = ' \0 ' ;
2009-01-19 21:33:14 +00:00
2010-09-18 15:22:54 +00:00
/* Append text to the end of the text area, scrolling if required to make it visible */
2010-08-11 09:50:38 +00:00
gtk_text_buffer_get_end_iter ( textbuffer_log , & iter ) ;
gtk_text_buffer_insert ( textbuffer_log , & iter , msg , - 1 ) ;
gtk_text_buffer_insert ( textbuffer_log , & iter , " \n " , - 1 ) ;
2010-09-18 15:22:54 +00:00
gtk_text_view_scroll_to_iter ( GTK_TEXT_VIEW ( textview_log ) , & iter , 0.0 , TRUE , 0.0 , 1.0 ) ;
2009-12-13 20:31:54 +00:00
/* Allow GTK to process events */
while ( gtk_events_pending ( ) )
gtk_main_iteration ( ) ;
2009-01-19 21:33:14 +00:00
}
/*
* * Write a message to the Import Log text area .
*/
2009-12-13 20:31:54 +00:00
static void
pgui_logf ( const char * fmt , . . . )
2009-01-19 21:33:14 +00:00
{
2009-12-13 20:31:54 +00:00
va_list ap ;
va_start ( ap , fmt ) ;
2009-01-19 21:33:14 +00:00
2009-12-13 20:31:54 +00:00
pgui_log_va ( fmt , ap ) ;
2009-01-19 21:33:14 +00:00
2009-12-13 20:31:54 +00:00
va_end ( ap ) ;
2009-01-19 21:33:14 +00:00
return ;
}
2012-01-08 23:32:05 +00:00
/* Write an error message */
void
pgui_seterr_va ( const char * fmt , va_list ap )
2009-01-19 21:33:14 +00:00
{
2015-02-17 10:23:18 +00:00
if ( - 1 = = vsnprintf ( pgui_errmsg , GUIMSG_LINE_MAXLEN , fmt , ap ) ) return ;
pgui_errmsg [ GUIMSG_LINE_MAXLEN ] = ' \0 ' ;
2012-01-08 23:32:05 +00:00
}
static void
pgui_seterr ( const char * fmt , . . . )
{
va_list ap ;
va_start ( ap , fmt ) ;
pgui_seterr_va ( fmt , ap ) ;
va_end ( ap ) ;
2009-01-19 21:33:14 +00:00
return ;
}
2010-08-11 09:50:38 +00:00
static void
2012-01-08 23:32:05 +00:00
pgui_raise_error_dialogue ( void )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
GtkWidget * dialog , * label ;
label = gtk_label_new ( pgui_errmsg ) ;
dialog = gtk_dialog_new_with_buttons ( _ ( " Error " ) , GTK_WINDOW ( window_main ) ,
GTK_DIALOG_MODAL & GTK_DIALOG_NO_SEPARATOR & GTK_DIALOG_DESTROY_WITH_PARENT ,
GTK_STOCK_OK , GTK_RESPONSE_OK , NULL ) ;
gtk_dialog_set_has_separator ( GTK_DIALOG ( dialog ) , FALSE ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( dialog ) , 5 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( GTK_DIALOG ( dialog ) - > vbox ) , 15 ) ;
gtk_container_add ( GTK_CONTAINER ( GTK_DIALOG ( dialog ) - > vbox ) , label ) ;
gtk_widget_show_all ( dialog ) ;
2012-12-21 10:01:39 +00:00
gtk_dialog_run ( GTK_DIALOG ( dialog ) ) ;
2012-01-08 23:32:05 +00:00
gtk_widget_destroy ( dialog ) ;
return ;
}
/*
* * Run a SQL command against the current connection .
*/
static int
pgui_exec ( const char * sql )
{
PGresult * res = NULL ;
ExecStatusType status ;
char sql_trunc [ 256 ] ;
/* We need a connection to do anything. */
if ( ! pg_connection ) return 0 ;
if ( ! sql ) return 0 ;
res = PQexec ( pg_connection , sql ) ;
status = PQresultStatus ( res ) ;
PQclear ( res ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* Did something unexpected happen? */
if ( ! ( status = = PGRES_COMMAND_OK | | status = = PGRES_TUPLES_OK ) )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
/* Log notices and return success. */
if ( status = = PGRES_NONFATAL_ERROR )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
pgui_logf ( " %s " , PQerrorMessage ( pg_connection ) ) ;
return 1 ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
/* Log errors and return failure. */
snprintf ( sql_trunc , 255 , " %s " , sql ) ;
pgui_logf ( " Failed SQL begins: \" %s \" " , sql_trunc ) ;
pgui_logf ( " Failed in pgui_exec(): %s " , PQerrorMessage ( pg_connection ) ) ;
return 0 ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
return 1 ;
2010-08-11 09:50:38 +00:00
}
/*
2012-01-08 23:32:05 +00:00
* * Start the COPY process .
*/
static int
pgui_copy_start ( const char * sql )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
PGresult * res = NULL ;
ExecStatusType status ;
char sql_trunc [ 256 ] ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* We need a connection to do anything. */
if ( ! pg_connection ) return 0 ;
if ( ! sql ) return 0 ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
res = PQexec ( pg_connection , sql ) ;
status = PQresultStatus ( res ) ;
PQclear ( res ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* Did something unexpected happen? */
if ( status ! = PGRES_COPY_IN )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
/* Log errors and return failure. */
snprintf ( sql_trunc , 255 , " %s " , sql ) ;
pgui_logf ( " Failed SQL begins: \" %s \" " , sql_trunc ) ;
pgui_logf ( " Failed in pgui_copy_start(): %s " , PQerrorMessage ( pg_connection ) ) ;
return 0 ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
return 1 ;
2010-08-11 09:50:38 +00:00
}
/*
2012-01-08 23:32:05 +00:00
* * Send a line ( row ) of data into the COPY procedure .
*/
static int
pgui_copy_write ( const char * line )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
char line_trunc [ 256 ] ;
/* We need a connection to do anything. */
if ( ! pg_connection ) return 0 ;
if ( ! line ) return 0 ;
/* Did something unexpected happen? */
if ( PQputCopyData ( pg_connection , line , strlen ( line ) ) < 0 )
2010-08-15 08:30:08 +00:00
{
2012-01-08 23:32:05 +00:00
/* Log errors and return failure. */
snprintf ( line_trunc , 255 , " %s " , line ) ;
pgui_logf ( " Failed row begins: \" %s \" " , line_trunc ) ;
pgui_logf ( " Failed in pgui_copy_write(): %s " , PQerrorMessage ( pg_connection ) ) ;
return 0 ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
/* Send linefeed to signify end of line */
PQputCopyData ( pg_connection , " \n " , 1 ) ;
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
return 1 ;
2010-08-11 09:50:38 +00:00
}
/*
2012-01-08 23:32:05 +00:00
* * Finish the COPY process .
*/
static int
pgui_copy_end ( const int rollback )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
char * errmsg = NULL ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* We need a connection to do anything. */
if ( ! pg_connection ) return 0 ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
if ( rollback ) errmsg = " Roll back the copy. " ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* Did something unexpected happen? */
if ( PQputCopyEnd ( pg_connection , errmsg ) < 0 )
2010-08-15 08:30:08 +00:00
{
2012-01-08 23:32:05 +00:00
/* Log errors and return failure. */
pgui_logf ( " Failed in pgui_copy_end(): %s " , PQerrorMessage ( pg_connection ) ) ;
return 0 ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
return 1 ;
2010-08-11 09:50:38 +00:00
}
/*
2012-01-08 23:32:05 +00:00
* Ensures that the filename field width is within the stated bounds , and
* ' appropriately ' sized , for some definition of ' appropriately ' .
2010-08-11 09:50:38 +00:00
*/
2010-08-15 08:30:08 +00:00
static void
2012-01-08 23:32:05 +00:00
update_filename_field_width ( void )
2010-08-11 09:50:38 +00:00
{
GtkTreeIter iter ;
2012-01-08 23:32:05 +00:00
gboolean is_valid ;
gchar * filename ;
int max_width ;
/* Loop through the list store to find the maximum length of an entry */
max_width = 0 ;
2012-02-04 00:39:24 +00:00
is_valid = gtk_tree_model_get_iter_first ( GTK_TREE_MODEL ( import_file_list_store ) , & iter ) ;
2012-01-08 23:32:05 +00:00
while ( is_valid )
{
/* Grab the length of the filename entry in characters */
2012-02-04 00:39:24 +00:00
gtk_tree_model_get ( GTK_TREE_MODEL ( import_file_list_store ) , & iter , IMPORT_FILENAME_COLUMN , & filename , - 1 ) ;
2012-01-08 23:32:05 +00:00
if ( strlen ( filename ) > max_width )
max_width = strlen ( filename ) ;
/* Get next entry */
2012-02-04 00:39:24 +00:00
is_valid = gtk_tree_model_iter_next ( GTK_TREE_MODEL ( import_file_list_store ) , & iter ) ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
/* 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 )
2012-02-04 00:39:24 +00:00
g_object_set ( import_filename_renderer , " width-chars " , SHAPEFIELDMAXWIDTH , NULL ) ;
2010-08-11 09:50:38 +00:00
else
2012-02-04 00:39:24 +00:00
g_object_set ( import_filename_renderer , " width-chars " , - 1 , NULL ) ;
2012-01-08 23:32:05 +00:00
return ;
2010-08-11 09:50:38 +00:00
}
/*
2012-01-08 23:32:05 +00:00
* This will create a connection to the database , just to see if it can .
* It cleans up after itself like a good little function and maintains
* the status of the valid_connection parameter .
2010-08-11 09:50:38 +00:00
*/
2012-01-08 23:32:05 +00:00
static int
connection_test ( void )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
char * connection_string = NULL ;
char * connection_sanitized = NULL ;
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
if ( ! ( connection_string = ShpDumperGetConnectionStringFromConn ( conn ) ) )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
pgui_raise_error_dialogue ( ) ;
valid_connection = 0 ;
return 0 ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
connection_sanitized = strdup ( connection_string ) ;
pgui_sanitize_connection_string ( connection_sanitized ) ;
pgui_logf ( " Connecting: %s " , connection_sanitized ) ;
free ( connection_sanitized ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
pg_connection = PQconnectdb ( connection_string ) ;
if ( PQstatus ( pg_connection ) = = CONNECTION_BAD )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
pgui_logf ( _ ( " Database connection failed: %s " ) , PQerrorMessage ( pg_connection ) ) ;
free ( connection_string ) ;
PQfinish ( pg_connection ) ;
pg_connection = NULL ;
valid_connection = 0 ;
return 0 ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
PQfinish ( pg_connection ) ;
pg_connection = NULL ;
free ( connection_string ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
valid_connection = 1 ;
return 1 ;
}
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* === Generic window functions === */
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
/* Delete event handler for popups that simply returns TRUE to prevent GTK from
destroying the window and then hides it manually */
static gint
pgui_event_popup_delete ( GtkWidget * widget , GdkEvent * event , gpointer data )
{
gtk_widget_hide ( GTK_WIDGET ( widget ) ) ;
return TRUE ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
/* === Progress window functions === */
2009-12-13 20:31:54 +00:00
static void
2012-01-08 23:32:05 +00:00
pgui_action_progress_cancel ( GtkDialog * dialog , gint response_id , gpointer user_data )
2009-12-13 20:31:54 +00:00
{
2012-01-08 23:32:05 +00:00
/* Stop the current import */
2012-02-04 00:39:24 +00:00
is_running = FALSE ;
2009-12-13 20:31:54 +00:00
return ;
}
2012-01-08 23:32:05 +00:00
static gint
pgui_action_progress_delete ( GtkWidget * widget , GdkEvent * event , gpointer data )
2009-12-13 20:31:54 +00:00
{
2012-01-08 23:32:05 +00:00
/* Stop the current import */
2012-02-04 00:39:24 +00:00
is_running = FALSE ;
2012-01-08 23:32:05 +00:00
return TRUE ;
2009-12-13 20:31:54 +00:00
}
2012-01-08 23:32:05 +00:00
2012-02-04 00:39:24 +00:00
/* === Loader option Window functions === */
2012-01-08 23:32:05 +00:00
/* Update the specified SHPLOADERCONFIG with the global settings from the Options dialog */
2009-12-13 20:31:54 +00:00
static void
2012-01-08 23:32:05 +00:00
update_loader_config_globals_from_options_ui ( SHPLOADERCONFIG * config )
2009-12-13 20:31:54 +00:00
{
const char * entry_encoding = gtk_entry_get_text ( GTK_ENTRY ( entry_options_encoding ) ) ;
2012-02-04 00:39:24 +00:00
gboolean preservecase = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( checkbutton_loader_options_preservecase ) ) ;
gboolean forceint = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( checkbutton_loader_options_forceint ) ) ;
gboolean createindex = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( checkbutton_loader_options_autoindex ) ) ;
gboolean dbfonly = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( checkbutton_loader_options_dbfonly ) ) ;
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 ) ) ;
2012-02-04 00:39:38 +00:00
gboolean simplegeoms = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( checkbutton_loader_options_simplegeoms ) ) ;
2012-01-08 23:32:05 +00:00
if ( geography )
2009-12-29 20:16:48 +00:00
{
2010-01-03 23:05:42 +00:00
config - > geography = 1 ;
2012-01-08 23:32:05 +00:00
if ( config - > geo_col )
free ( config - > geo_col ) ;
config - > geo_col = strdup ( GEOGRAPHY_DEFAULT ) ;
2010-08-11 09:50:38 +00:00
}
else
{
config - > geography = 0 ;
2012-01-08 23:32:05 +00:00
if ( config - > geo_col )
free ( config - > geo_col ) ;
config - > geo_col = strdup ( GEOMETRY_DEFAULT ) ;
2009-12-29 20:16:48 +00:00
}
2010-01-03 23:05:42 +00:00
/* Encoding */
2012-01-08 23:32:05 +00:00
if ( entry_encoding & & strlen ( entry_encoding ) > 0 )
2009-12-29 20:16:48 +00:00
{
2010-01-03 23:05:42 +00:00
if ( config - > encoding )
free ( config - > encoding ) ;
config - > encoding = strdup ( entry_encoding ) ;
2009-12-29 20:16:48 +00:00
}
2010-08-15 08:30:08 +00:00
2010-01-03 23:05:42 +00:00
/* Preserve case */
2012-01-08 23:32:05 +00:00
if ( preservecase )
2010-01-03 23:05:42 +00:00
config - > quoteidentifiers = 1 ;
else
config - > quoteidentifiers = 0 ;
/* No long integers in table */
2012-01-08 23:32:05 +00:00
if ( forceint )
2010-01-03 23:05:42 +00:00
config - > forceint4 = 1 ;
else
config - > forceint4 = 0 ;
2010-08-15 08:30:08 +00:00
2010-01-03 23:05:42 +00:00
/* Create spatial index after load */
2012-01-08 23:32:05 +00:00
if ( createindex )
2010-01-03 23:05:42 +00:00
config - > createindex = 1 ;
else
config - > createindex = 0 ;
2010-08-15 08:30:08 +00:00
2010-01-03 23:05:42 +00:00
/* Read the .shp file, don't ignore it */
2012-01-08 23:32:05 +00:00
if ( dbfonly )
2010-09-10 15:25:46 +00:00
{
2010-01-03 23:05:42 +00:00
config - > readshape = 0 ;
2012-01-08 23:32:05 +00:00
2010-09-10 15:25:46 +00:00
/* There will be no spatial column so don't create a spatial index */
config - > createindex = 0 ;
}
2010-01-03 23:05:42 +00:00
else
config - > readshape = 1 ;
/* Use COPY rather than INSERT format */
2012-01-08 23:32:05 +00:00
if ( dumpformat )
2010-01-03 23:05:42 +00:00
config - > dump_format = 1 ;
else
config - > dump_format = 0 ;
2012-01-08 23:32:05 +00:00
2012-02-04 00:39:38 +00:00
/* Simple geometries only */
if ( simplegeoms )
config - > simple_geometries = 1 ;
else
config - > simple_geometries = 0 ;
2010-01-03 23:05:42 +00:00
return ;
}
2012-02-04 00:39:24 +00:00
/* Update the loader options dialog with the current values from the global config */
2010-01-03 23:05:42 +00:00
static void
2012-01-08 23:32:05 +00:00
update_options_ui_from_loader_config_globals ( void )
2010-01-03 23:05:42 +00:00
{
2012-01-08 23:32:05 +00:00
gtk_entry_set_text ( GTK_ENTRY ( entry_options_encoding ) , global_loader_config - > encoding ) ;
2012-02-04 00:39:24 +00:00
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( checkbutton_loader_options_preservecase ) , global_loader_config - > quoteidentifiers ? TRUE : FALSE ) ;
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( checkbutton_loader_options_forceint ) , global_loader_config - > forceint4 ? TRUE : FALSE ) ;
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( checkbutton_loader_options_autoindex ) , global_loader_config - > createindex ? TRUE : FALSE ) ;
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( checkbutton_loader_options_dbfonly ) , global_loader_config - > readshape ? FALSE : TRUE ) ;
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 ) ;
2012-02-04 00:39:38 +00:00
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( checkbutton_loader_options_simplegeoms ) , global_loader_config - > simple_geometries ? TRUE : FALSE ) ;
2012-01-08 23:32:05 +00:00
return ;
}
/* Set the global config variables controlled by the options dialogue */
static void
pgui_set_loader_configs_from_options_ui ( )
{
GtkTreeIter iter ;
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 ) ;
2009-12-13 20:31:54 +00:00
2012-01-08 23:32:05 +00:00
/* Now also update the same settings for any existing files already added. We
do this by looping through all entries and updating their config too . */
2012-02-04 00:39:24 +00:00
is_valid = gtk_tree_model_get_iter_first ( GTK_TREE_MODEL ( import_file_list_store ) , & iter ) ;
2012-01-08 23:32:05 +00:00
while ( is_valid )
{
/* Get the SHPLOADERCONFIG for this file entry */
2012-02-04 00:39:24 +00:00
gtk_tree_model_get ( GTK_TREE_MODEL ( import_file_list_store ) , & iter , IMPORT_POINTER_COLUMN , & gptr , - 1 ) ;
2012-01-08 23:32:05 +00:00
loader_file_config = ( SHPLOADERCONFIG * ) gptr ;
/* Update it */
update_loader_config_globals_from_options_ui ( loader_file_config ) ;
/* Get next entry */
2012-02-04 00:39:24 +00:00
is_valid = gtk_tree_model_iter_next ( GTK_TREE_MODEL ( import_file_list_store ) , & iter ) ;
}
return ;
}
/* === Table selection dialog functions === */
/* Load the model with information from the database */
static void
update_table_chooser_from_database ( )
{
PGresult * result , * geocol_result ;
GtkTreeIter iter , geocol_iter ;
GtkListStore * dumper_geocol_combo_list ;
2012-12-21 10:01:39 +00:00
char * connection_string , * sql_form , * query , * schema , * table , * geocol_query , * geocol_name = NULL ;
2012-02-04 00:39:24 +00:00
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 " ;
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 + + )
{
gtk_list_store_insert_before ( chooser_table_list_store , & iter , NULL ) ;
/* Look up the geo columns; if there are none then we set the field to (None). If we have just one
column then we set the column name directly . If we have more than one then we create a combo
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
the data here , we don ' t actually display the geo column in this dialog . Instead we build the
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 " ) ) ;
2014-09-18 18:27:12 +00:00
gtk_list_store_insert_before ( dumper_geocol_combo_list , & geocol_iter , ( GtkTreeIter * ) TABLECHOOSER_GEOCOL_COMBO_TEXT ) ;
2012-02-04 00:39:24 +00:00
gtk_list_store_set ( dumper_geocol_combo_list , & geocol_iter ,
TABLECHOOSER_GEOCOL_COMBO_TEXT , geocol_name ,
- 1 ) ;
}
}
else
{
/* Add a "default" entry */
geocol_name = NULL ;
2014-09-18 18:27:12 +00:00
gtk_list_store_insert_before ( dumper_geocol_combo_list , & geocol_iter , ( GtkTreeIter * ) TABLECHOOSER_GEOCOL_COMBO_TEXT ) ;
2012-02-04 00:39:24 +00:00
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_SCHEMA_COLUMN , schema ,
TABLECHOOSER_TABLE_COLUMN , table ,
TABLECHOOSER_GEO_LISTSTORE_COLUMN , dumper_geocol_combo_list ,
TABLECHOOSER_GEO_COLUMN , geocol_name ,
TABLECHOOSER_HASGEO_COLUMN , hasgeo ,
- 1 ) ;
}
/* Clear up the result set */
PQclear ( result ) ;
/* Close the existing connection */
PQfinish ( pg_connection ) ;
pg_connection = NULL ;
return ;
}
/* GtkTreeModelFilter visibility function */
static gboolean
table_chooser_visibility_func ( GtkTreeModel * model , GtkTreeIter * iter , gpointer data )
{
/* 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
{
/* Otherwise we only show the tables with geo columns */
gtk_tree_model_get ( GTK_TREE_MODEL ( model ) , iter , TABLECHOOSER_HASGEO_COLUMN , & hasgeo , - 1 ) ;
if ( hasgeo )
return TRUE ;
else
return FALSE ;
}
return FALSE ;
}
/* === Dumper option Window functions === */
/* Update the specified SHPDUMPERCONFIG with the global settings from the Options dialog */
static void
update_dumper_config_globals_from_options_ui ( SHPDUMPERCONFIG * config )
{
gboolean includegid = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( checkbutton_dumper_options_includegid ) ) ;
gboolean keep_fieldname_case = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( checkbutton_dumper_options_keep_fieldname_case ) ) ;
gboolean unescapedattrs = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( checkbutton_dumper_options_unescapedattrs ) ) ;
/* Include gid or not */
if ( includegid )
config - > includegid = 1 ;
else
config - > includegid = 0 ;
/* Keep fieldname case */
if ( keep_fieldname_case )
config - > keep_fieldname_case = 1 ;
else
config - > keep_fieldname_case = 0 ;
/* Escape column names or not */
if ( unescapedattrs )
config - > unescapedattrs = 1 ;
else
config - > unescapedattrs = 0 ;
return ;
}
/* Update the options dialog with the current values from the global config */
static void
update_options_ui_from_dumper_config_globals ( void )
{
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 ;
}
/* Set the global config variables controlled by the options dialogue */
static void
pgui_set_dumper_configs_from_options_ui ( )
{
GtkTreeIter iter ;
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 ) ;
/* Now also update the same settings for any existing tables already added. We
do this by looping through all entries and updating their config too . */
is_valid = gtk_tree_model_get_iter_first ( GTK_TREE_MODEL ( export_table_list_store ) , & iter ) ;
while ( is_valid )
{
/* 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 ) ;
2012-01-08 23:32:05 +00:00
}
2012-02-04 00:39:24 +00:00
return ;
}
/* Signal handler for ticking/unticking the "only show geo columns" box */
static void
pgui_action_chooser_toggle_show_geocolumn ( GtkToggleButton * togglebutton , gpointer user_data )
{
/* Simply update the listview filter */
gtk_tree_model_filter_refilter ( GTK_TREE_MODEL_FILTER ( chooser_filtered_table_list_store ) ) ;
2012-01-08 23:32:05 +00:00
return ;
}
2009-12-13 20:31:54 +00:00
2012-02-04 00:39:24 +00:00
static void
pgui_action_dumper_options_open ( GtkWidget * widget , gpointer data )
{
update_options_ui_from_dumper_config_globals ( ) ;
gtk_widget_show_all ( dialog_dumper_options ) ;
return ;
}
static void
pgui_action_dumper_options_close ( GtkWidget * widget , gint response , gpointer data )
{
/* 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 ;
}
2009-12-13 20:31:54 +00:00
2012-01-08 23:32:05 +00:00
/* === Main window functions === */
2009-12-13 20:31:54 +00:00
2012-02-04 00:39:24 +00:00
/* Given a filename, generate a new loader configuration */
2012-01-08 23:32:05 +00:00
static SHPLOADERCONFIG *
create_new_file_config ( const char * filename )
{
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 + + ;
2009-12-13 20:31:54 +00:00
2012-01-08 23:32:05 +00:00
/* Roll back from end to first . character. */
table_end = loader_file_config - > shp_file + strlen ( loader_file_config - > shp_file ) ;
while ( * table_end ! = ' . ' & & table_end > loader_file_config - > shp_file & & table_end > table_start )
table_end - - ;
2009-12-13 20:31:54 +00:00
2012-01-08 23:32:05 +00:00
/* Copy the table name */
loader_file_config - > table = malloc ( table_end - table_start + 1 ) ;
memcpy ( loader_file_config - > table , table_start , table_end - table_start ) ;
loader_file_config - > table [ table_end - table_start ] = ' \0 ' ;
2009-12-13 20:31:54 +00:00
2012-01-08 23:32:05 +00:00
/* Force the table name to lower case */
for ( i = 0 ; i < table_end - table_start ; i + + )
2009-12-13 20:31:54 +00:00
{
2012-01-08 23:32:05 +00:00
if ( isupper ( loader_file_config - > table [ i ] ) ! = 0 )
loader_file_config - > table [ i ] = tolower ( loader_file_config - > table [ i ] ) ;
2009-12-13 20:31:54 +00:00
}
2012-01-08 23:32:05 +00:00
/* 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 ) ;
2010-08-11 09:50:38 +00:00
else
2012-01-08 23:32:05 +00:00
loader_file_config - > geo_col = strdup ( GEOMETRY_DEFAULT ) ;
return loader_file_config ;
}
2009-12-17 11:16:20 +00:00
2012-01-08 23:32:05 +00:00
/* Given the loader configuration, add a new row representing this file to the listview */
static void
add_loader_file_config_to_list ( SHPLOADERCONFIG * loader_file_config )
{
GtkTreeIter iter ;
2015-02-17 11:06:33 +00:00
# define MAXLEN 16
char srid [ MAXLEN + 1 ] ;
2012-01-08 23:32:05 +00:00
/* Convert SRID into string */
2015-02-17 11:06:33 +00:00
if ( MAXLEN + 1 < = snprintf ( srid , MAXLEN + 1 , " %d " , loader_file_config - > sr_id ) )
{
pgui_logf ( " Invalid SRID requiring more than %d digits: %d " , MAXLEN , loader_file_config - > sr_id ) ;
pgui_raise_error_dialogue ( ) ;
srid [ MAXLEN ] = ' \0 ' ;
}
2012-01-08 23:32:05 +00:00
2012-02-04 00:39:24 +00:00
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_FILENAME_COLUMN , loader_file_config - > shp_file ,
IMPORT_SCHEMA_COLUMN , loader_file_config - > schema ,
IMPORT_TABLE_COLUMN , loader_file_config - > table ,
IMPORT_GEOMETRY_COLUMN , loader_file_config - > geo_col ,
IMPORT_SRID_COLUMN , srid ,
IMPORT_MODE_COLUMN , _ ( " Create " ) ,
2012-01-08 23:32:05 +00:00
- 1 ) ;
/* Update the filename field width */
update_filename_field_width ( ) ;
2009-12-13 20:31:54 +00:00
return ;
}
2012-01-08 23:32:05 +00:00
/* Free up the specified SHPLOADERCONFIG */
static void
free_loader_config ( SHPLOADERCONFIG * config )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
if ( config - > table )
free ( config - > table ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
if ( config - > schema )
free ( config - > schema ) ;
if ( config - > geo_col )
free ( config - > geo_col ) ;
if ( config - > shp_file )
free ( config - > shp_file ) ;
if ( config - > encoding )
free ( config - > encoding ) ;
if ( config - > tablespace )
free ( config - > tablespace ) ;
if ( config - > idxtablespace )
free ( config - > idxtablespace ) ;
/* Free the config itself */
free ( config ) ;
2010-08-11 09:50:38 +00:00
}
2012-02-04 00:39:24 +00:00
/* Given a table selection, generate a new configuration */
static SHPDUMPERCONFIG *
create_new_table_config ( GtkTreeIter * iter )
{
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 ) ;
/* 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 ;
}
/* Given the dumper configuration, add a new row representing this file to the listview. The liststore and iter arguments
are optional , and enable the user to specify additional information to the view , e . g . geo column multi - choice . */
static void
add_dumper_table_config_to_list ( SHPDUMPERCONFIG * dumper_table_config , GtkListStore * chooser_liststore , GtkTreeIter * chooser_iter )
{
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_SCHEMA_COLUMN , dumper_table_config - > schema ,
EXPORT_TABLE_COLUMN , dumper_table_config - > table ,
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 )
{
/* Let's add a multi-choice geometry column to the table */
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 ;
}
/* Free up the specified SHPDUMPERCONFIG */
static void
free_dumper_config ( SHPDUMPERCONFIG * config )
{
if ( config - > table )
free ( config - > table ) ;
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 ) ;
}
2012-01-08 23:32:05 +00:00
/* Validate a single DBF column type against a PostgreSQL type: return either TRUE or FALSE depending
upon whether or not the type is ( broadly ) compatible */
2010-08-11 09:50:38 +00:00
static int
2012-01-08 23:32:05 +00:00
validate_shape_column_against_pg_column ( int dbf_fieldtype , char * pg_fieldtype )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
switch ( dbf_fieldtype )
{
case FTString :
/* Only varchar */
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 ;
}
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* Validate column compatibility for the given loader configuration against the table/column
list returned in result */
static int
validate_remote_loader_columns ( SHPLOADERCONFIG * config , PGresult * result )
{
ExecStatusType status ;
2012-02-04 00:39:24 +00:00
SHPLOADERSTATE * state ;
2012-01-08 23:32:05 +00:00
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 )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
ntuples = PQntuples ( result ) ;
switch ( config - > opt )
2010-08-15 08:30:08 +00:00
{
2012-01-08 23:32:05 +00:00
case ' c ' :
/* If we have a row matching the table given in the config, then it already exists */
if ( ntuples > 0 )
{
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 ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
case ' a ' :
/* If we are trying to append to a table but it doesn't exist, emit a warning */
if ( ntuples = = 0 )
{
pgui_seterr ( _ ( " ERROR: Destination table %s.%s could not be found for appending " ) , config - > schema , config - > table ) ;
response = SHPLOADERERR ;
}
else
{
/* If we have a row then lets do some simple column validation... */
state = ShpLoaderCreate ( config ) ;
ret = ShpLoaderOpenShape ( state ) ;
if ( ret ! = SHPLOADEROK )
{
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 + + )
{
/* Make sure we find a column */
found = 0 ;
for ( j = 0 ; j < ntuples ; j + + )
{
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 )
{
pgui_logf ( _ ( " Warning: DBF Field '%s' is not compatible with PostgreSQL column '%s' in %s.%s " ) , state - > field_names [ i ] , pg_fieldname , config - > schema , config - > table ) ;
response = SHPLOADERWARN ;
}
}
}
/* Flag a warning if we can't find a match */
if ( ! found )
{
pgui_logf ( _ ( " Warning: DBF Field '%s' within file %s could not be matched to a column within table %s.%s " ) ,
state - > field_names [ i ] , config - > shp_file , config - > schema , config - > table ) ;
response = SHPLOADERWARN ;
}
}
ShpLoaderDestroy ( state ) ;
}
break ;
2010-08-15 08:30:08 +00:00
}
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
else
{
pgui_seterr ( _ ( " ERROR: unable to process validation response from remote server " ) ) ;
response = SHPLOADERERR ;
}
return response ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
/* Terminate the main loop and exit the application. */
static void
pgui_quit ( GtkWidget * widget , gpointer data )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
gtk_main_quit ( ) ;
}
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
static void
pgui_action_about_open ( )
{
/* Display the dialog and hide it again upon exit */
gtk_dialog_run ( GTK_DIALOG ( dialog_about ) ) ;
gtk_widget_hide ( dialog_about ) ;
}
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
static void
pgui_action_cancel ( GtkWidget * widget , gpointer data )
{
2012-02-04 00:39:24 +00:00
if ( ! is_running )
2012-01-08 23:32:05 +00:00
pgui_quit ( widget , data ) ; /* quit if we're not running */
else
2012-02-04 00:39:24 +00:00
is_running = FALSE ;
2012-01-08 23:32:05 +00:00
}
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
static void
2012-02-04 00:39:24 +00:00
pgui_action_loader_options_open ( GtkWidget * widget , gpointer data )
2012-01-08 23:32:05 +00:00
{
update_options_ui_from_loader_config_globals ( ) ;
2012-02-04 00:39:24 +00:00
gtk_widget_show_all ( dialog_loader_options ) ;
2012-01-08 23:32:05 +00:00
return ;
}
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
static void
2012-02-04 00:39:24 +00:00
pgui_action_loader_options_close ( GtkWidget * widget , gint response , gpointer data )
2012-01-08 23:32:05 +00:00
{
/* Only update the configuration if the user hit OK */
if ( response = = GTK_RESPONSE_OK )
pgui_set_loader_configs_from_options_ui ( ) ;
/* Hide the dialog */
2012-02-04 00:39:24 +00:00
gtk_widget_hide ( dialog_loader_options ) ;
2012-01-08 23:32:05 +00:00
return ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
static void
pgui_action_open_file_dialog ( GtkWidget * widget , gpointer data )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
SHPLOADERCONFIG * loader_file_config ;
2012-02-04 01:17:33 +00:00
GSList * filename_list , * filename_item ;
gchar * filename ;
2012-03-30 14:17:42 +00:00
/* Make sure we deselect any files from the last time */
gtk_file_chooser_unselect_all ( GTK_FILE_CHOOSER ( dialog_filechooser ) ) ;
2012-01-08 23:32:05 +00:00
/* Run the dialog */
if ( gtk_dialog_run ( GTK_DIALOG ( dialog_filechooser ) ) = = GTK_RESPONSE_ACCEPT )
{
2012-02-04 01:17:33 +00:00
/* 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 ) ;
2012-01-08 23:32:05 +00:00
}
gtk_widget_hide ( dialog_filechooser ) ;
}
2010-08-11 09:50:38 +00:00
2012-02-04 00:39:24 +00:00
static void
pgui_action_open_table_dialog ( GtkWidget * widget , gpointer data )
{
SHPDUMPERCONFIG * dumper_table_config ;
GtkTreeSelection * chooser_selection ;
GtkTreeModel * model ;
GList * selected_rows_list , * selected_row ;
GtkTreeIter iter ;
GtkTreePath * tree_path ;
/* 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 " ) ) ;
pgui_raise_error_dialogue ( ) ;
/* Open the connections UI for the user */
update_conn_ui_from_conn_config ( ) ;
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 ) ) ;
/* Run the dialog */
gtk_widget_show_all ( dialog_tablechooser ) ;
if ( gtk_dialog_run ( GTK_DIALOG ( dialog_tablechooser ) ) = = GTK_RESPONSE_OK )
{
/* Create the new dumper configuration based upon the selected iters and add them to the listview */
chooser_selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( chooser_tree ) ) ;
selected_rows_list = gtk_tree_selection_get_selected_rows ( chooser_selection , & model ) ;
selected_row = g_list_first ( selected_rows_list ) ;
while ( selected_row )
{
/* 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 ) ;
/* 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 ) ;
}
/*
* Signal handler for the remove box . Performs no user interaction , simply
* removes the row from the table .
*/
static void
pgui_action_handle_table_remove ( GtkCellRendererToggle * renderer ,
gchar * path ,
gpointer user_data )
{
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 ) ;
}
2012-01-08 23:32:05 +00:00
static void
pgui_action_import ( GtkWidget * widget , gpointer data )
{
SHPLOADERCONFIG * loader_file_config ;
2012-02-04 00:39:24 +00:00
SHPLOADERSTATE * state ;
2012-01-08 23:32:05 +00:00
gint is_valid ;
gpointer gptr ;
GtkTreeIter iter ;
2015-02-17 11:06:33 +00:00
char * sql_form , * query , * connection_string , * progress_shapefile = NULL ;
char progress_text [ GUIMSG_LINE_MAXLEN + 1 ] ;
2012-01-08 23:32:05 +00:00
PGresult * result ;
2012-02-04 00:39:24 +00:00
2012-12-21 10:01:39 +00:00
int ret , i = 0 ;
2012-01-08 23:32:05 +00:00
char * header , * footer , * record ;
2012-01-10 12:28:30 +00:00
/* Get the first row of the import list */
2012-02-04 00:39:24 +00:00
is_valid = gtk_tree_model_get_iter_first ( GTK_TREE_MODEL ( import_file_list_store ) , & iter ) ;
2012-01-10 12:28:30 +00:00
if ( ! is_valid )
{
pgui_seterr ( _ ( " ERROR: You haven't specified any files to import " ) ) ;
pgui_raise_error_dialogue ( ) ;
return ;
}
2012-01-08 23:32:05 +00:00
/* Firstly make sure that we can connect to the database - if we can't then there isn't much
point doing anything else . . . */
if ( ! connection_test ( ) )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
pgui_seterr ( _ ( " Unable to connect to the database - please check your connection settings " ) ) ;
pgui_raise_error_dialogue ( ) ;
2012-01-10 12:28:46 +00:00
/* Open the connections UI for the user */
update_conn_ui_from_conn_config ( ) ;
gtk_widget_show_all ( GTK_WIDGET ( window_conn ) ) ;
2012-01-08 23:32:05 +00:00
return ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
/* Let's open a single connection to the remote DB for the duration of the validation pass;
note that we already know the connection string works , otherwise we would have bailed
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 " ;
2012-01-10 12:28:30 +00:00
/* Validation: we loop through each of the files in order to validate them as a separate pass */
2012-01-08 23:32:05 +00:00
while ( is_valid )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
/* Grab the SHPLOADERCONFIG for this row */
2012-02-04 00:39:24 +00:00
gtk_tree_model_get ( GTK_TREE_MODEL ( import_file_list_store ) , & iter , IMPORT_POINTER_COLUMN , & gptr , - 1 ) ;
2012-01-08 23:32:05 +00:00
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 */
2012-02-04 00:39:24 +00:00
is_valid = gtk_tree_model_iter_next ( GTK_TREE_MODEL ( import_file_list_store ) , & iter ) ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
/* Close our database connection */
PQfinish ( pg_connection ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* Once we've done the validation pass, now let's load the shapefile */
2012-02-04 00:39:24 +00:00
is_valid = gtk_tree_model_get_iter_first ( GTK_TREE_MODEL ( import_file_list_store ) , & iter ) ;
2012-01-08 23:32:05 +00:00
while ( is_valid )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
/* Grab the SHPLOADERCONFIG for this row */
2012-02-04 00:39:24 +00:00
gtk_tree_model_get ( GTK_TREE_MODEL ( import_file_list_store ) , & iter , IMPORT_POINTER_COLUMN , & gptr , - 1 ) ;
2012-01-08 23:32:05 +00:00
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
*/
2012-02-04 00:39:24 +00:00
is_running = TRUE ;
2012-01-08 23:32:05 +00:00
2012-01-10 12:28:23 +00:00
/* One connection per file, otherwise error handling becomes tricky... */
pg_connection = PQconnectdb ( connection_string ) ;
2012-01-08 23:32:05 +00:00
/* Disable the button to prevent multiple imports running at the same time */
gtk_widget_set_sensitive ( widget , FALSE ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* 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 ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* Open the shapefile */
2010-08-11 09:50:38 +00:00
ret = ShpLoaderOpenShape ( state ) ;
2010-08-15 08:30:08 +00:00
if ( ret ! = SHPLOADEROK )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
pgui_logf ( " %s " , state - > message ) ;
if ( ret = = SHPLOADERERR )
goto import_cleanup ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
/* For progress display, only show the "core" filename */
for ( i = strlen ( loader_file_config - > shp_file ) ; i > = 0
& & loader_file_config - > shp_file [ i - 1 ] ! = ' \\ ' & & loader_file_config - > shp_file [ i - 1 ] ! = ' / ' ; i - - ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
progress_shapefile = malloc ( strlen ( loader_file_config - > shp_file ) ) ;
strcpy ( progress_shapefile , & loader_file_config - > shp_file [ i ] ) ;
/* Display the progress dialog */
2015-02-17 11:06:33 +00:00
snprintf ( progress_text , GUIMSG_LINE_MAXLEN , _ ( " Importing shapefile %s (%d records)... " ) , progress_shapefile , ShpLoaderGetRecordCount ( state ) ) ;
progress_text [ GUIMSG_LINE_MAXLEN ] = ' \0 ' ;
2012-01-08 23:32:05 +00:00
gtk_label_set_text ( GTK_LABEL ( label_progress ) , progress_text ) ;
gtk_progress_bar_set_fraction ( GTK_PROGRESS_BAR ( progress ) , 0.0 ) ;
gtk_widget_show_all ( dialog_progress ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* If reading the whole shapefile, display its type */
if ( state - > config - > readshape )
{
pgui_logf ( " Shapefile type: %s " , SHPTypeName ( state - > shpfiletype ) ) ;
pgui_logf ( " PostGIS type: %s[%d] " , state - > pgtype , state - > pgdims ) ;
}
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* Get the header */
ret = ShpLoaderGetSQLHeader ( state , & header ) ;
if ( ret ! = SHPLOADEROK )
{
pgui_logf ( " %s " , state - > message ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
if ( ret = = SHPLOADERERR )
goto import_cleanup ;
}
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
/* Send the header to the remote server: if we are in COPY mode then the last
statement will be a COPY and so will change connection mode */
ret = pgui_exec ( header ) ;
free ( header ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
if ( ! ret )
goto import_cleanup ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* If we are in prepare mode, we need to skip the actual load. */
if ( state - > config - > opt ! = ' p ' )
{
2013-03-26 13:12:54 +00:00
int numrecords = ShpLoaderGetRecordCount ( state ) ;
int records_per_tick = ( numrecords / 200 ) - 1 ;
if ( records_per_tick < 1 )
records_per_tick = 1 ;
2012-01-08 23:32:05 +00:00
/* If we are in COPY (dump format) mode, output the COPY statement and enter COPY mode */
if ( state - > config - > dump_format )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
ret = ShpLoaderGetSQLCopyStatement ( state , & header ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
if ( ret ! = SHPLOADEROK )
2010-08-11 09:50:38 +00:00
{
2012-01-08 23:32:05 +00:00
pgui_logf ( " %s " , state - > message ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
if ( ret = = SHPLOADERERR )
goto import_cleanup ;
2010-08-11 09:50:38 +00:00
}
2012-01-08 23:32:05 +00:00
/* Send the result to the remote server: this should put us in COPY mode */
ret = pgui_copy_start ( header ) ;
free ( header ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
if ( ! ret )
goto import_cleanup ;
2010-08-11 09:50:38 +00:00
}
2010-08-15 08:30:08 +00:00
2010-08-11 09:50:38 +00:00
/* Main loop: iterate through all of the records and send them to stdout */
2013-03-26 13:12:54 +00:00
for ( i = 0 ; i < numrecords & & is_running ; i + + )
2010-08-11 09:50:38 +00:00
{
ret = ShpLoaderGenerateSQLRowStatement ( state , i , & record ) ;
2010-08-15 08:30:08 +00:00
switch ( ret )
2010-08-11 09:50:38 +00:00
{
2010-08-15 08:30:08 +00:00
case SHPLOADEROK :
/* Simply send the statement */
if ( state - > config - > dump_format )
ret = pgui_copy_write ( record ) ;
else
ret = pgui_exec ( record ) ;
/* Display a record number if we failed */
if ( ! ret )
2010-12-02 00:44:24 +00:00
pgui_logf ( _ ( " Import failed on record number %d " ) , i ) ;
2010-08-15 08:30:08 +00:00
free ( record ) ;
break ;
case SHPLOADERERR :
/* Display the error message then stop */
pgui_logf ( " %s \n " , state - > message ) ;
goto import_cleanup ;
break ;
case SHPLOADERWARN :
/* Display the warning, but continue */
pgui_logf ( " %s \n " , state - > message ) ;
if ( state - > config - > dump_format )
ret = pgui_copy_write ( record ) ;
else
ret = pgui_exec ( record ) ;
/* Display a record number if we failed */
if ( ! ret )
2010-12-02 00:44:24 +00:00
pgui_logf ( _ ( " Import failed on record number %d " ) , i ) ;
2010-08-15 08:30:08 +00:00
free ( record ) ;
break ;
case SHPLOADERRECDELETED :
/* Record is marked as deleted - ignore */
break ;
case SHPLOADERRECISNULL :
/* Record is NULL and should be ignored according to NULL policy */
break ;
2010-08-11 09:50:38 +00:00
}
2010-08-15 08:30:08 +00:00
2010-08-11 09:50:38 +00:00
/* Update the progress bar */
2013-03-26 13:12:54 +00:00
if ( i % records_per_tick = = 0 )
gtk_progress_bar_set_fraction ( GTK_PROGRESS_BAR ( progress ) , ( float ) i / numrecords ) ;
2010-08-15 08:30:08 +00:00
2010-08-11 09:50:38 +00:00
/* Allow GTK events to get a look in */
while ( gtk_events_pending ( ) )
gtk_main_iteration ( ) ;
}
2010-08-15 08:30:08 +00:00
2010-08-11 09:50:38 +00:00
/* If we are in COPY (dump format) mode, leave COPY mode */
2010-02-01 17:35:55 +00:00
if ( state - > config - > dump_format )
2010-08-11 09:50:38 +00:00
{
if ( ! pgui_copy_end ( 0 ) )
goto import_cleanup ;
2010-08-15 08:30:08 +00:00
2010-08-11 09:50:38 +00:00
result = PQgetResult ( pg_connection ) ;
if ( PQresultStatus ( result ) ! = PGRES_COMMAND_OK )
{
2010-12-02 00:44:24 +00:00
pgui_logf ( _ ( " COPY failed with the following error: %s " ) , PQerrorMessage ( pg_connection ) ) ;
2010-08-11 09:50:38 +00:00
ret = SHPLOADERERR ;
goto import_cleanup ;
}
}
} /* if (state->config->opt != 'p') */
2010-08-15 08:30:08 +00:00
2010-08-11 09:50:38 +00:00
/* Only continue if we didn't abort part way through */
2012-02-04 00:39:24 +00:00
if ( is_running )
2010-08-11 09:50:38 +00:00
{
/* Get the footer */
ret = ShpLoaderGetSQLFooter ( state , & footer ) ;
if ( ret ! = SHPLOADEROK )
{
pgui_logf ( " %s \n " , state - > message ) ;
2010-08-15 08:30:08 +00:00
2010-08-11 09:50:38 +00:00
if ( ret = = SHPLOADERERR )
goto import_cleanup ;
}
2010-08-15 08:30:08 +00:00
2012-01-14 13:10:27 +00:00
/* Just in case index creation takes a long time, update the progress text */
2012-01-08 23:32:05 +00:00
if ( state - > config - > createindex )
2010-08-11 09:50:38 +00:00
{
2012-01-14 13:10:27 +00:00
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 ( ) ;
2010-08-11 09:50:38 +00:00
}
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
/* Send the footer to the server */
ret = pgui_exec ( footer ) ;
free ( footer ) ;
if ( ! ret )
goto import_cleanup ;
}
import_cleanup :
/* Import has definitely stopped running */
2012-02-04 00:39:24 +00:00
is_running = FALSE ;
2012-01-08 23:32:05 +00:00
2012-01-10 12:28:23 +00:00
/* Close the existing connection */
PQfinish ( pg_connection ) ;
pg_connection = NULL ;
2012-01-08 23:32:05 +00:00
/* 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. " ) ) ;
else
pgui_logf ( _ ( " Shapefile import completed. " ) ) ;
/* Free the state object */
ShpLoaderDestroy ( state ) ;
/* Tidy up */
if ( progress_shapefile )
free ( progress_shapefile ) ;
/* Get next entry */
2012-02-04 00:39:24 +00:00
is_valid = gtk_tree_model_iter_next ( GTK_TREE_MODEL ( import_file_list_store ) , & iter ) ;
2012-01-08 23:32:05 +00:00
}
/* Import has definitely finished */
2012-02-04 00:39:24 +00:00
is_running = FALSE ;
2012-01-08 23:32:05 +00:00
/* Enable the button once again */
gtk_widget_set_sensitive ( widget , TRUE ) ;
/* Silly GTK bug means we have to hide and show the button for it to work again! */
gtk_widget_hide ( widget ) ;
gtk_widget_show ( widget ) ;
/* Hide the progress dialog */
gtk_widget_hide ( dialog_progress ) ;
/* Allow GTK events to get a look in */
while ( gtk_events_pending ( ) )
gtk_main_iteration ( ) ;
/* Tidy up */
free ( connection_string ) ;
return ;
}
static void
2012-02-04 00:39:24 +00:00
pgui_action_export ( GtkWidget * widget , gpointer data )
{
SHPDUMPERCONFIG * dumper_table_config ;
SHPDUMPERSTATE * state ;
gint is_valid ;
gpointer gptr ;
GtkTreeIter iter ;
2015-02-17 11:06:33 +00:00
char * output_shapefile , * orig_shapefile ;
char progress_text [ GUIMSG_LINE_MAXLEN + 1 ] ;
2012-02-04 00:39:24 +00:00
gchar * folder_path ;
2012-02-07 13:12:31 +00:00
int ret , success = FALSE , i = 0 ;
2012-02-04 00:39:24 +00:00
/* 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 )
2012-01-08 23:32:05 +00:00
{
2012-02-04 00:39:24 +00:00
pgui_seterr ( _ ( " ERROR: You haven't specified any tables to export " ) ) ;
pgui_raise_error_dialogue ( ) ;
2012-01-08 23:32:05 +00:00
return ;
}
2012-02-04 00:39:24 +00:00
/* Firstly make sure that we can connect to the database - if we can't then there isn't much
point doing anything else . . . */
if ( ! connection_test ( ) )
2012-01-08 23:32:05 +00:00
{
2012-02-04 00:39:24 +00:00
pgui_seterr ( _ ( " Unable to connect to the database - please check your connection settings " ) ) ;
pgui_raise_error_dialogue ( ) ;
/* Open the connections UI for the user */
update_conn_ui_from_conn_config ( ) ;
gtk_widget_show_all ( GTK_WIDGET ( window_conn ) ) ;
2012-01-08 23:32:05 +00:00
return ;
}
2012-02-04 00:39:24 +00:00
/* Now open the file selector dialog so the user can specify where they would like the output
files to reside */
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 ) ) ;
2012-02-04 02:36:44 +00:00
2012-02-04 00:39:24 +00:00
/* 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 ;
2012-02-04 02:36:44 +00:00
/* 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 ) ;
strcpy ( output_shapefile , folder_path ) ;
strcat ( output_shapefile , G_DIR_SEPARATOR_S ) ;
strcat ( output_shapefile , dumper_table_config - > shp_file ) ;
dumper_table_config - > shp_file = output_shapefile ;
2012-02-07 13:12:31 +00:00
/* Connect to the database */
ret = ShpDumperConnectDatabase ( state ) ;
if ( ret ! = SHPDUMPEROK )
{
pgui_seterr ( " %s " , state - > message ) ;
pgui_raise_error_dialogue ( ) ;
goto export_cleanup ;
}
2012-02-04 00:39:24 +00:00
/* 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 )
{
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 text */
2015-02-17 11:06:33 +00:00
snprintf ( progress_text , GUIMSG_LINE_MAXLEN , _ ( " Exporting table %s (%d records)... " ) , dumper_table_config - > table , ShpDumperGetRecordCount ( state ) ) ;
progress_text [ GUIMSG_LINE_MAXLEN ] = ' \0 ' ;
2012-02-04 00:39:24 +00:00
gtk_label_set_text ( GTK_LABEL ( label_progress ) , progress_text ) ;
/* Allow GTK events to get a look in */
while ( gtk_events_pending ( ) )
gtk_main_iteration ( ) ;
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 ( ) ;
}
/* Finish the dump */
ret = ShpDumperCloseTable ( 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 ( ) ;
}
}
/* Indicate success */
if ( is_running )
success = TRUE ;
export_cleanup :
/* Tidy up everything */
ShpDumperDestroy ( state ) ;
/* 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 ) ;
/* Silly GTK bug means we have to hide and show the button for it to work again! */
gtk_widget_hide ( widget ) ;
gtk_widget_show ( widget ) ;
/* 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 ;
}
/* === Import ListView functions and signal handlers === */
/* Creates a single file row in the list table given the URI of a file */
static void
process_single_uri ( char * uri )
{
SHPLOADERCONFIG * loader_file_config ;
char * filename = NULL ;
char * hostname ;
GError * error = NULL ;
if ( uri = = NULL )
{
pgui_logf ( _ ( " Unable to process drag URI. " ) ) ;
return ;
}
filename = g_filename_from_uri ( uri , & hostname , & error ) ;
g_free ( uri ) ;
if ( filename = = NULL )
{
pgui_logf ( _ ( " Unable to process filename: %s \n " ) , error - > message ) ;
g_error_free ( error ) ;
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 ) ;
2012-01-08 23:32:05 +00:00
g_free ( filename ) ;
g_free ( hostname ) ;
}
/* Update the SHPLOADERCONFIG to the values currently contained within the iter */
static void
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 */
2012-02-04 00:39:24 +00:00
gtk_tree_model_get ( GTK_TREE_MODEL ( import_file_list_store ) , iter ,
IMPORT_SCHEMA_COLUMN , & schema ,
IMPORT_TABLE_COLUMN , & table ,
IMPORT_GEOMETRY_COLUMN , & geo_col ,
IMPORT_SRID_COLUMN , & srid ,
2012-01-08 23:32:05 +00:00
- 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 ) ;
/* Free the values */
return ;
}
/*
* Here lives the magic of the drag - n - drop of the app . We really don ' t care
* about much of the provided tidbits . We only actually user selection_data
* and extract a list of filenames from it .
*/
static void
pgui_action_handle_file_drop ( GtkWidget * widget ,
GdkDragContext * dc ,
gint x , gint y ,
GtkSelectionData * selection_data ,
guint info , guint t , gpointer data )
{
const gchar * p , * q ;
if ( selection_data - > data = = NULL )
{
pgui_logf ( _ ( " Unable to process drag data. " ) ) ;
return ;
}
p = ( char * ) selection_data - > data ;
while ( p )
{
/* Only process non-comments */
if ( * p ! = ' # ' )
{
/* Trim leading whitespace */
while ( g_ascii_isspace ( * p ) )
p + + ;
q = p ;
/* Scan to the end of the string (null or newline) */
while ( * q & & ( * q ! = ' \n ' ) & & ( * q ! = ' \r ' ) )
q + + ;
if ( q > p )
{
/* Ignore terminating character */
q - - ;
/* Trim trailing whitespace */
while ( q > p & & g_ascii_isspace ( * q ) )
q - - ;
if ( q > p )
{
process_single_uri ( g_strndup ( p , q - p + 1 ) ) ;
}
}
}
/* Skip to the next entry */
p = strchr ( p , ' \n ' ) ;
if ( p )
p + + ;
}
}
/*
* This function is a signal handler for the load mode combo boxes .
*/
static void
pgui_action_handle_tree_combo ( GtkCellRendererCombo * combo ,
gchar * path_string ,
GtkTreeIter * new_iter ,
gpointer user_data )
{
GtkTreeIter iter ;
SHPLOADERCONFIG * loader_file_config ;
char opt ;
gchar * combo_text ;
gpointer gptr ;
2012-02-04 00:39:24 +00:00
/* 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 ) ;
2012-01-08 23:32:05 +00:00
loader_file_config = ( SHPLOADERCONFIG * ) gptr ;
/* Now grab the row selected within the combo box */
2012-02-04 00:39:24 +00:00
gtk_tree_model_get ( GTK_TREE_MODEL ( loader_mode_combo_list ) , new_iter , LOADER_MODE_COMBO_OPTION_CHAR , & opt , - 1 ) ;
2012-01-08 23:32:05 +00:00
/* 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 */
2012-02-04 00:39:24 +00:00
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 ) ;
2012-01-08 23:32:05 +00:00
return ;
}
/*
* This method is a signal listener for all text renderers in the file
* list table , including the empty ones . Edits of the empty table are
* passed to an appropriate function , while edits of existing file rows
* are applied and the various validations called .
*/
static void
2012-02-04 00:39:24 +00:00
pgui_action_handle_loader_edit ( GtkCellRendererText * renderer ,
2012-01-08 23:32:05 +00:00
gchar * path ,
gchar * new_text ,
gpointer column )
{
GtkTreeIter iter ;
gpointer gptr ;
gint columnindex ;
SHPLOADERCONFIG * loader_file_config ;
2015-02-17 11:06:33 +00:00
# define MAXLEN 16
char srid [ MAXLEN + 1 ] ;
2012-01-08 23:32:05 +00:00
/* Empty doesn't fly */
if ( strlen ( new_text ) = = 0 )
return ;
/* Update the model with the current edit change */
columnindex = * ( gint * ) column ;
2012-02-04 00:39:24 +00:00
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 ) ;
2012-01-08 23:32:05 +00:00
2012-02-04 00:39:24 +00:00
/* 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 ) ;
2012-01-08 23:32:05 +00:00
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 */
2015-02-17 11:06:33 +00:00
if ( MAXLEN + 1 < = snprintf ( srid , MAXLEN + 1 , " %d " , loader_file_config - > sr_id ) )
{
pgui_logf ( " Invalid SRID requiring more than %d digits: %d " , MAXLEN , loader_file_config - > sr_id ) ;
pgui_raise_error_dialogue ( ) ;
srid [ MAXLEN ] = ' \0 ' ;
}
2012-01-08 23:32:05 +00:00
2012-02-04 00:39:24 +00:00
gtk_list_store_set ( import_file_list_store , & iter ,
IMPORT_SCHEMA_COLUMN , loader_file_config - > schema ,
IMPORT_TABLE_COLUMN , loader_file_config - > table ,
IMPORT_GEOMETRY_COLUMN , loader_file_config - > geo_col ,
IMPORT_SRID_COLUMN , srid ,
2012-01-08 23:32:05 +00:00
- 1 ) ;
return ;
}
/*
* Signal handler for the remove box . Performs no user interaction , simply
* removes the row from the table .
*/
static void
2012-02-04 00:39:24 +00:00
pgui_action_handle_file_remove ( GtkCellRendererToggle * renderer ,
2012-01-08 23:32:05 +00:00
gchar * path ,
gpointer user_data )
{
GtkTreeIter iter ;
SHPLOADERCONFIG * loader_file_config ;
gpointer gptr ;
2012-02-04 00:39:24 +00:00
/* 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 ) ;
2012-01-08 23:32:05 +00:00
loader_file_config = ( SHPLOADERCONFIG * ) gptr ;
/* Free the configuration from memory */
free_loader_config ( loader_file_config ) ;
/* Remove the row from the list */
2012-02-04 00:39:24 +00:00
gtk_list_store_remove ( import_file_list_store , & iter ) ;
2012-01-08 23:32:05 +00:00
/* Update the filename field width */
update_filename_field_width ( ) ;
}
2010-08-15 08:30:08 +00:00
2009-12-13 20:31:54 +00:00
2012-02-04 00:39:24 +00:00
/* === Export ListView functions and signal handlers === */
/* Update the SHPDUMPERCONFIG to the values currently contained within the iter */
static void
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_TABLE_COLUMN , & table ,
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 ;
}
static void
pgui_action_handle_table_geocol_combo ( GtkCellRendererCombo * combo ,
gchar * path_string ,
GtkTreeIter * new_iter ,
gpointer user_data )
{
SHPDUMPERCONFIG * dumper_table_config ;
gchar * geocol_name ;
GtkTreeIter iter ;
GtkListStore * model ;
gpointer gptr ;
/* 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 ;
}
static void
pgui_action_handle_dumper_edit ( GtkCellRendererText * renderer ,
gchar * path ,
gchar * new_text ,
gpointer column )
{
GtkTreeIter iter ;
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 ,
EXPORT_TABLE_COLUMN , dumper_table_config - > table ,
EXPORT_GEOMETRY_COLUMN , dumper_table_config - > geo_col_name ,
EXPORT_FILENAME_COLUMN , dumper_table_config - > shp_file ,
- 1 ) ;
return ;
}
2009-12-22 12:28:35 +00:00
2012-01-08 23:32:05 +00:00
/* === Connection Window functions === */
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
/* Set the connection details UI from the current configuration */
static void
update_conn_ui_from_conn_config ( void )
{
if ( conn - > username )
gtk_entry_set_text ( GTK_ENTRY ( entry_pg_user ) , conn - > username ) ;
2012-01-10 12:28:46 +00:00
else
gtk_entry_set_text ( GTK_ENTRY ( entry_pg_user ) , " " ) ;
2012-01-08 23:32:05 +00:00
if ( conn - > password )
gtk_entry_set_text ( GTK_ENTRY ( entry_pg_pass ) , conn - > password ) ;
2012-01-10 12:28:46 +00:00
else
gtk_entry_set_text ( GTK_ENTRY ( entry_pg_pass ) , " " ) ;
2012-01-08 23:32:05 +00:00
if ( conn - > host )
gtk_entry_set_text ( GTK_ENTRY ( entry_pg_host ) , conn - > host ) ;
2012-01-10 12:28:46 +00:00
else
gtk_entry_set_text ( GTK_ENTRY ( entry_pg_host ) , " " ) ;
2012-01-08 23:32:05 +00:00
if ( conn - > port )
gtk_entry_set_text ( GTK_ENTRY ( entry_pg_port ) , conn - > port ) ;
2012-01-10 12:28:46 +00:00
else
gtk_entry_set_text ( GTK_ENTRY ( entry_pg_port ) , " " ) ;
2012-01-08 23:32:05 +00:00
if ( conn - > database )
gtk_entry_set_text ( GTK_ENTRY ( entry_pg_db ) , conn - > database ) ;
2012-01-10 12:28:46 +00:00
else
gtk_entry_set_text ( GTK_ENTRY ( entry_pg_db ) , " " ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
return ;
}
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
/* Set the current connection configuration from the connection details UI */
static void
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
conn - > host = NULL ;
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
text = gtk_entry_get_text ( GTK_ENTRY ( entry_pg_port ) ) ;
if ( conn - > port )
free ( conn - > port ) ;
if ( strlen ( text ) )
conn - > port = strdup ( text ) ;
else
conn - > port = NULL ;
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
text = gtk_entry_get_text ( GTK_ENTRY ( entry_pg_db ) ) ;
if ( conn - > database )
free ( conn - > database ) ;
if ( strlen ( text ) )
conn - > database = strdup ( text ) ;
else
conn - > database = NULL ;
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
return ;
}
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
/*
* Open the connection details dialog
*/
static void
pgui_action_connection_details ( GtkWidget * widget , gpointer data )
{
/* Update the UI with the current options */
update_conn_ui_from_conn_config ( ) ;
gtk_widget_show_all ( GTK_WIDGET ( window_conn ) ) ;
return ;
}
2010-02-01 17:35:55 +00:00
2012-01-08 23:32:05 +00:00
/* Validate the connection, returning true or false */
static int
pgui_validate_connection ( )
{
int i ;
2012-02-05 00:30:28 +00:00
if ( conn - > port & & strlen ( conn - > port ) )
2012-01-08 23:32:05 +00:00
{
for ( i = 0 ; i < strlen ( conn - > port ) ; i + + )
{
if ( ! isdigit ( conn - > port [ i ] ) )
{
pgui_seterr ( _ ( " The connection port must be numeric! " ) ) ;
return 0 ;
}
}
2009-12-13 20:31:54 +00:00
}
2012-01-08 23:32:05 +00:00
return 1 ;
}
2009-12-13 20:31:54 +00:00
2012-01-08 23:32:05 +00:00
static void
pgui_sanitize_connection_string ( char * connection_string )
{
char * ptr = strstr ( connection_string , " password " ) ;
if ( ptr )
{
ptr + = 10 ;
while ( * ptr ! = ' \' ' & & * ptr ! = ' \0 ' )
{
/* If we find a \, hide both it and the next character */
if ( * ptr = = ' \\ ' )
* ptr + + = ' * ' ;
* ptr + + = ' * ' ;
}
}
2009-12-13 20:31:54 +00:00
return ;
2009-01-19 21:33:14 +00:00
}
2012-01-08 23:32:05 +00:00
/*
* We retain the ability to explicitly request a test of the connection
* parameters . This is the button signal handler to do so .
*/
2009-01-19 21:33:14 +00:00
static void
2012-01-08 23:32:05 +00:00
pgui_action_connection_okay ( GtkWidget * widget , gpointer data )
2009-01-19 21:33:14 +00:00
{
2012-01-08 23:32:05 +00:00
/* 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 ( ) ;
}
else
{
pgui_logf ( _ ( " Connection succeeded. " ) ) ;
}
/* Hide the window after the test */
gtk_widget_hide ( GTK_WIDGET ( window_conn ) ) ;
2009-01-19 21:33:14 +00:00
}
2012-01-08 23:32:05 +00:00
/* === Window creation functions === */
2010-01-04 00:32:15 +00:00
static void
2012-01-08 23:32:05 +00:00
pgui_create_about_dialog ( void )
2010-01-04 00:32:15 +00:00
{
const char * authors [ ] =
2010-08-15 08:30:08 +00:00
{
2015-10-02 23:05:23 +00:00
" Paul Ramsey <pramsey@cleverelephant.ca> " ,
2012-05-20 09:27:37 +00:00
" Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> " ,
2015-10-02 23:05:23 +00:00
" Mark Leslie <mark.s.leslie@gmail.com> " ,
2010-08-15 08:30:08 +00:00
NULL
} ;
2012-02-24 22:41:09 +00:00
2010-01-04 00:32:15 +00:00
2012-01-08 23:32:05 +00:00
dialog_about = gtk_about_dialog_new ( ) ;
2012-02-04 00:39:31 +00:00
gtk_about_dialog_set_name ( GTK_ABOUT_DIALOG ( dialog_about ) , _ ( " PostGIS Shapefile Import/Export Manager " ) ) ;
2012-05-20 09:27:37 +00:00
gtk_about_dialog_set_comments ( GTK_ABOUT_DIALOG ( dialog_about ) , POSTGIS_LIB_VERSION ) ;
2013-01-16 14:24:35 +00:00
gtk_about_dialog_set_website ( GTK_ABOUT_DIALOG ( dialog_about ) , " http://postgis.net/ " ) ;
2012-01-08 23:32:05 +00:00
gtk_about_dialog_set_authors ( GTK_ABOUT_DIALOG ( dialog_about ) , authors ) ;
}
static void
pgui_create_filechooser_dialog ( void )
{
GtkFileFilter * file_filter_shape ;
/* Create the dialog */
2012-02-04 00:39:24 +00:00
dialog_filechooser = gtk_file_chooser_dialog_new ( _ ( " Select a Shape File " ) , GTK_WINDOW ( window_main ) ,
2012-01-08 23:32:05 +00:00
GTK_FILE_CHOOSER_ACTION_OPEN , GTK_STOCK_CANCEL , GTK_RESPONSE_CLOSE , GTK_STOCK_OPEN , GTK_RESPONSE_ACCEPT , NULL ) ;
/* Filter for .shp files */
file_filter_shape = gtk_file_filter_new ( ) ;
gtk_file_filter_add_pattern ( GTK_FILE_FILTER ( file_filter_shape ) , " *.shp " ) ;
gtk_file_filter_set_name ( GTK_FILE_FILTER ( file_filter_shape ) , _ ( " Shape Files (*.shp) " ) ) ;
gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER ( dialog_filechooser ) , file_filter_shape ) ;
/* Filter for .dbf files */
file_filter_shape = gtk_file_filter_new ( ) ;
gtk_file_filter_add_pattern ( GTK_FILE_FILTER ( file_filter_shape ) , " *.dbf " ) ;
gtk_file_filter_set_name ( GTK_FILE_FILTER ( file_filter_shape ) , _ ( " DBF Files (*.dbf) " ) ) ;
gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER ( dialog_filechooser ) , file_filter_shape ) ;
2012-02-04 01:17:33 +00:00
/* Allow multiple files to be selected */
g_object_set ( dialog_filechooser , " select-multiple " , TRUE , NULL ) ;
2012-01-08 23:32:05 +00:00
return ;
}
2012-02-04 00:39:24 +00:00
static void
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 ) ;
/* Filter for .shp files */
file_filter_shape = gtk_file_filter_new ( ) ;
gtk_file_filter_add_pattern ( GTK_FILE_FILTER ( file_filter_shape ) , " *.shp " ) ;
gtk_file_filter_set_name ( GTK_FILE_FILTER ( file_filter_shape ) , _ ( " Shape Files (*.shp) " ) ) ;
gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER ( dialog_folderchooser ) , file_filter_shape ) ;
/* Filter for .dbf files */
file_filter_shape = gtk_file_filter_new ( ) ;
gtk_file_filter_add_pattern ( GTK_FILE_FILTER ( file_filter_shape ) , " *.dbf " ) ;
gtk_file_filter_set_name ( GTK_FILE_FILTER ( file_filter_shape ) , _ ( " DBF Files (*.dbf) " ) ) ;
gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER ( dialog_folderchooser ) , file_filter_shape ) ;
return ;
}
2012-01-08 23:32:05 +00:00
static void
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 ) ;
gtk_window_set_keep_above ( GTK_WINDOW ( dialog_progress ) , TRUE ) ;
gtk_window_set_default_size ( GTK_WINDOW ( dialog_progress ) , 640 , - 1 ) ;
/* 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 ;
}
static void
pgui_create_options_dialog_add_label ( GtkWidget * table , const char * str , gfloat alignment , int row )
{
GtkWidget * align = gtk_alignment_new ( alignment , 0.5 , 0.0 , 1.0 ) ;
GtkWidget * label = gtk_label_new ( str ) ;
gtk_table_attach_defaults ( GTK_TABLE ( table ) , align , 1 , 3 , row , row + 1 ) ;
gtk_container_add ( GTK_CONTAINER ( align ) , label ) ;
2010-01-04 00:32:15 +00:00
}
2009-01-19 21:33:14 +00:00
static void
2012-02-04 00:39:24 +00:00
pgui_create_loader_options_dialog ( )
2009-01-19 21:33:14 +00:00
{
GtkWidget * table_options ;
GtkWidget * align_options_center ;
static int text_width = 12 ;
2009-12-29 20:16:48 +00:00
2012-02-04 00:39:24 +00:00
dialog_loader_options = gtk_dialog_new_with_buttons ( _ ( " Import Options " ) , GTK_WINDOW ( window_main ) , GTK_DIALOG_DESTROY_WITH_PARENT , GTK_STOCK_OK , GTK_RESPONSE_OK , NULL ) ;
2010-08-15 08:30:08 +00:00
2012-02-04 00:39:24 +00:00
gtk_window_set_modal ( GTK_WINDOW ( dialog_loader_options ) , TRUE ) ;
gtk_window_set_keep_above ( GTK_WINDOW ( dialog_loader_options ) , TRUE ) ;
gtk_window_set_default_size ( GTK_WINDOW ( dialog_loader_options ) , 180 , - 1 ) ;
2009-01-19 21:33:14 +00:00
table_options = gtk_table_new ( 7 , 3 , TRUE ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( table_options ) , 12 ) ;
gtk_table_set_row_spacings ( GTK_TABLE ( table_options ) , 5 ) ;
gtk_table_set_col_spacings ( GTK_TABLE ( table_options ) , 10 ) ;
2012-01-08 23:32:05 +00:00
pgui_create_options_dialog_add_label ( table_options , _ ( " DBF file character encoding " ) , 0.0 , 0 ) ;
2009-01-19 21:33:14 +00:00
entry_options_encoding = gtk_entry_new ( ) ;
gtk_entry_set_width_chars ( GTK_ENTRY ( entry_options_encoding ) , text_width ) ;
gtk_table_attach_defaults ( GTK_TABLE ( table_options ) , entry_options_encoding , 0 , 1 , 0 , 1 ) ;
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
pgui_create_options_dialog_add_label ( table_options , _ ( " Preserve case of column names " ) , 0.0 , 1 ) ;
2012-02-04 00:39:24 +00:00
checkbutton_loader_options_preservecase = gtk_check_button_new ( ) ;
2009-01-19 21:33:14 +00:00
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 , 1 , 2 ) ;
2012-02-04 00:39:24 +00:00
gtk_container_add ( GTK_CONTAINER ( align_options_center ) , checkbutton_loader_options_preservecase ) ;
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
pgui_create_options_dialog_add_label ( table_options , _ ( " Do not create 'bigint' columns " ) , 0.0 , 2 ) ;
2012-02-04 00:39:24 +00:00
checkbutton_loader_options_forceint = gtk_check_button_new ( ) ;
2012-01-08 23:32:05 +00:00
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 , 2 , 3 ) ;
2012-02-04 00:39:24 +00:00
gtk_container_add ( GTK_CONTAINER ( align_options_center ) , checkbutton_loader_options_forceint ) ;
2009-01-19 21:33:14 +00:00
2012-01-08 23:32:05 +00:00
pgui_create_options_dialog_add_label ( table_options , _ ( " Create spatial index automatically after load " ) , 0.0 , 3 ) ;
2012-02-04 00:39:24 +00:00
checkbutton_loader_options_autoindex = gtk_check_button_new ( ) ;
2012-01-08 23:32:05 +00:00
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 , 3 , 4 ) ;
2012-02-04 00:39:24 +00:00
gtk_container_add ( GTK_CONTAINER ( align_options_center ) , checkbutton_loader_options_autoindex ) ;
2009-01-19 21:33:14 +00:00
2012-01-08 23:32:05 +00:00
pgui_create_options_dialog_add_label ( table_options , _ ( " Load only attribute (dbf) data " ) , 0.0 , 4 ) ;
2012-02-04 00:39:24 +00:00
checkbutton_loader_options_dbfonly = gtk_check_button_new ( ) ;
2012-01-08 23:32:05 +00:00
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 , 4 , 5 ) ;
2012-02-04 00:39:24 +00:00
gtk_container_add ( GTK_CONTAINER ( align_options_center ) , checkbutton_loader_options_dbfonly ) ;
2009-01-19 21:33:14 +00:00
2012-01-08 23:32:05 +00:00
pgui_create_options_dialog_add_label ( table_options , _ ( " Load data using COPY rather than INSERT " ) , 0.0 , 5 ) ;
2012-02-04 00:39:24 +00:00
checkbutton_loader_options_dumpformat = gtk_check_button_new ( ) ;
2012-01-08 23:32:05 +00:00
align_options_center = gtk_alignment_new ( 0.5 , 0.5 , 0.0 , 0.0 ) ;
gtk_table_attach_defaults ( GTK_TABLE ( table_options ) , align_options_center , 0 , 1 , 5 , 6 ) ;
2012-02-04 00:39:24 +00:00
gtk_container_add ( GTK_CONTAINER ( align_options_center ) , checkbutton_loader_options_dumpformat ) ;
2009-01-19 21:33:14 +00:00
2012-01-08 23:32:05 +00:00
pgui_create_options_dialog_add_label ( table_options , _ ( " Load into GEOGRAPHY column " ) , 0.0 , 6 ) ;
2012-02-04 00:39:24 +00:00
checkbutton_loader_options_geography = gtk_check_button_new ( ) ;
2012-01-08 23:32:05 +00:00
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 , 6 , 7 ) ;
2012-02-04 00:39:24 +00:00
gtk_container_add ( GTK_CONTAINER ( align_options_center ) , checkbutton_loader_options_geography ) ;
2009-01-19 21:33:14 +00:00
2012-02-04 00:39:38 +00:00
pgui_create_options_dialog_add_label ( table_options , _ ( " Generate simple geometries instead of MULTI geometries " ) , 0.0 , 7 ) ;
checkbutton_loader_options_simplegeoms = gtk_check_button_new ( ) ;
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 ) ;
2012-01-08 23:32:05 +00:00
/* Catch the response from the dialog */
2012-02-04 00:39:24 +00:00
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 ) ;
2012-01-08 23:32:05 +00:00
/* Hook the delete event so we don't destroy the dialog (just hide) if cancelled */
2012-02-04 00:39:24 +00:00
gtk_signal_connect ( GTK_OBJECT ( dialog_loader_options ) , " delete_event " , GTK_SIGNAL_FUNC ( pgui_event_popup_delete ) , NULL ) ;
}
static void
pgui_create_dumper_options_dialog ( )
{
GtkWidget * table_options ;
GtkWidget * align_options_center ;
dialog_dumper_options = gtk_dialog_new_with_buttons ( _ ( " Export Options " ) , GTK_WINDOW ( window_main ) , GTK_DIALOG_DESTROY_WITH_PARENT , GTK_STOCK_OK , GTK_RESPONSE_OK , NULL ) ;
gtk_window_set_modal ( GTK_WINDOW ( dialog_dumper_options ) , TRUE ) ;
gtk_window_set_keep_above ( GTK_WINDOW ( dialog_dumper_options ) , TRUE ) ;
gtk_window_set_default_size ( GTK_WINDOW ( dialog_dumper_options ) , 180 , - 1 ) ;
table_options = gtk_table_new ( 3 , 3 , TRUE ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( table_options ) , 12 ) ;
gtk_table_set_row_spacings ( GTK_TABLE ( table_options ) , 5 ) ;
gtk_table_set_col_spacings ( GTK_TABLE ( table_options ) , 10 ) ;
pgui_create_options_dialog_add_label ( table_options , _ ( " Include gid column in the exported table " ) , 0.0 , 0 ) ;
checkbutton_dumper_options_includegid = gtk_check_button_new ( ) ;
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 ) ;
gtk_table_attach_defaults ( GTK_TABLE ( table_options ) , align_options_center , 0 , 1 , 1 , 2 ) ;
gtk_container_add ( GTK_CONTAINER ( align_options_center ) , checkbutton_dumper_options_keep_fieldname_case ) ;
pgui_create_options_dialog_add_label ( table_options , _ ( " Escape column names " ) , 0.0 , 2 ) ;
checkbutton_dumper_options_unescapedattrs = gtk_check_button_new ( ) ;
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 , 2 , 3 ) ;
gtk_container_add ( GTK_CONTAINER ( align_options_center ) , checkbutton_dumper_options_unescapedattrs ) ;
/* 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 ) ;
2009-01-19 21:33:14 +00:00
}
2010-08-11 09:50:38 +00:00
/*
* This function creates the UI artefacts for the file list table and hooks
* up all the pretty signals .
*/
static void
2012-02-04 00:39:24 +00:00
pgui_create_tablechooser_dialog ( )
{
GtkWidget * vbox_tree , * table_progress ;
GtkWidget * sw , * label ;
GtkTreeSelection * chooser_selection ;
/* 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 */
chooser_table_list_store = gtk_list_store_new ( TABLECHOOSER_N_COLUMNS ,
G_TYPE_STRING ,
G_TYPE_STRING ,
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_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW ( sw ) , GTK_SHADOW_ETCHED_IN ) ;
gtk_widget_set_size_request ( sw , 320 , 240 ) ;
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 ) ;
g_signal_connect ( G_OBJECT ( chooser_schema_renderer ) , " edited " , G_CALLBACK ( pgui_action_handle_loader_edit ) , NULL ) ;
chooser_schema_column = gtk_tree_view_column_new_with_attributes ( _ ( " Schema " ) ,
chooser_schema_renderer ,
" text " ,
TABLECHOOSER_SCHEMA_COLUMN ,
NULL ) ;
g_object_set ( chooser_schema_column , " resizable " , TRUE , " sizing " , GTK_TREE_VIEW_COLUMN_AUTOSIZE , NULL ) ;
gtk_tree_view_append_column ( GTK_TREE_VIEW ( chooser_tree ) , chooser_schema_column ) ;
/* Table Field */
chooser_table_renderer = gtk_cell_renderer_text_new ( ) ;
g_object_set ( chooser_table_renderer , " editable " , FALSE , NULL ) ;
g_signal_connect ( G_OBJECT ( chooser_table_renderer ) , " edited " , G_CALLBACK ( pgui_action_handle_loader_edit ) , NULL ) ;
2012-02-24 22:41:09 +00:00
chooser_table_column = gtk_tree_view_column_new_with_attributes ( _ ( " Table " ) ,
2012-02-04 00:39:24 +00:00
chooser_table_renderer ,
" text " ,
TABLECHOOSER_TABLE_COLUMN ,
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 ;
}
/*
* This function creates the UI artefacts for the file list table and hooks
* up all the pretty signals .
*/
static void
pgui_create_import_file_table ( GtkWidget * import_list_frame )
2010-08-11 09:50:38 +00:00
{
GtkWidget * vbox_tree ;
2012-01-08 23:32:05 +00:00
GtkWidget * sw ;
GtkTreeIter iter ;
gint * column_indexes ;
2012-02-04 00:39:24 +00:00
gtk_container_set_border_width ( GTK_CONTAINER ( import_list_frame ) , 0 ) ;
2010-08-11 09:50:38 +00:00
vbox_tree = gtk_vbox_new ( FALSE , 15 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( vbox_tree ) , 5 ) ;
2012-02-04 00:39:24 +00:00
gtk_container_add ( GTK_CONTAINER ( import_list_frame ) , vbox_tree ) ;
2010-08-11 09:50:38 +00:00
/* Setup a model */
2012-02-04 00:39:24 +00:00
import_file_list_store = gtk_list_store_new ( IMPORT_N_COLUMNS ,
2012-01-08 23:32:05 +00:00
G_TYPE_POINTER ,
2010-08-15 08:30:08 +00:00
G_TYPE_STRING ,
G_TYPE_STRING ,
G_TYPE_STRING ,
G_TYPE_STRING ,
G_TYPE_STRING ,
G_TYPE_STRING ,
G_TYPE_BOOLEAN ) ;
2012-01-08 23:32:05 +00:00
2010-08-11 09:50:38 +00:00
/* Create the view and such */
2012-02-04 00:39:24 +00:00
import_tree = gtk_tree_view_new_with_model ( GTK_TREE_MODEL ( import_file_list_store ) ) ;
2012-01-08 23:32:05 +00:00
/* 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 */
2012-02-04 00:39:24 +00:00
column_indexes = g_malloc ( sizeof ( gint ) * IMPORT_N_COLUMNS ) ;
2012-01-08 23:32:05 +00:00
/* 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 ) ;
2012-02-04 00:39:24 +00:00
gtk_container_add ( GTK_CONTAINER ( sw ) , import_tree ) ;
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
/* 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 ) ;
2010-08-11 09:50:38 +00:00
/* Filename Field */
2012-02-04 00:39:24 +00:00
import_filename_renderer = gtk_cell_renderer_text_new ( ) ;
g_object_set ( import_filename_renderer , " editable " , FALSE , NULL ) ;
column_indexes [ IMPORT_FILENAME_COLUMN ] = IMPORT_FILENAME_COLUMN ;
g_signal_connect ( G_OBJECT ( import_filename_renderer ) , " edited " , G_CALLBACK ( pgui_action_handle_loader_edit ) , & column_indexes [ IMPORT_FILENAME_COLUMN ] ) ;
import_filename_column = gtk_tree_view_column_new_with_attributes ( _ ( " Shapefile " ) ,
import_filename_renderer ,
2010-08-15 08:30:08 +00:00
" text " ,
2012-02-04 00:39:24 +00:00
IMPORT_FILENAME_COLUMN ,
2010-08-15 08:30:08 +00:00
NULL ) ;
2012-02-04 00:39:24 +00:00
g_object_set ( import_filename_column , " resizable " , TRUE , NULL ) ;
gtk_tree_view_append_column ( GTK_TREE_VIEW ( import_tree ) , import_filename_column ) ;
2010-08-11 09:50:38 +00:00
/* Schema Field */
2012-02-04 00:39:24 +00:00
import_schema_renderer = gtk_cell_renderer_text_new ( ) ;
g_object_set ( import_schema_renderer , " editable " , TRUE , NULL ) ;
column_indexes [ IMPORT_SCHEMA_COLUMN ] = IMPORT_SCHEMA_COLUMN ;
g_signal_connect ( G_OBJECT ( import_schema_renderer ) , " edited " , G_CALLBACK ( pgui_action_handle_loader_edit ) , & column_indexes [ IMPORT_SCHEMA_COLUMN ] ) ;
import_schema_column = gtk_tree_view_column_new_with_attributes ( _ ( " Schema " ) ,
import_schema_renderer ,
2010-08-15 08:30:08 +00:00
" text " ,
2012-02-04 00:39:24 +00:00
IMPORT_SCHEMA_COLUMN ,
2010-08-15 08:30:08 +00:00
NULL ) ;
2012-06-21 22:24:00 +00:00
g_object_set ( import_schema_column , " resizable " , TRUE , " expand " , TRUE , NULL ) ;
2012-02-04 00:39:24 +00:00
gtk_tree_view_append_column ( GTK_TREE_VIEW ( import_tree ) , import_schema_column ) ;
2010-08-15 08:30:08 +00:00
2010-08-11 09:50:38 +00:00
/* Table Field */
2012-02-04 00:39:24 +00:00
import_table_renderer = gtk_cell_renderer_text_new ( ) ;
g_object_set ( import_table_renderer , " editable " , TRUE , NULL ) ;
column_indexes [ IMPORT_TABLE_COLUMN ] = IMPORT_TABLE_COLUMN ;
g_signal_connect ( G_OBJECT ( import_table_renderer ) , " edited " , G_CALLBACK ( pgui_action_handle_loader_edit ) , & column_indexes [ IMPORT_TABLE_COLUMN ] ) ;
2012-02-24 22:41:09 +00:00
import_table_column = gtk_tree_view_column_new_with_attributes ( _ ( " Table " ) ,
2012-02-04 00:39:24 +00:00
import_table_renderer ,
2010-08-15 08:30:08 +00:00
" text " ,
2012-02-04 00:39:24 +00:00
IMPORT_TABLE_COLUMN ,
2010-08-15 08:30:08 +00:00
NULL ) ;
2012-06-21 22:24:00 +00:00
g_object_set ( import_table_column , " resizable " , TRUE , " expand " , TRUE , NULL ) ;
2012-02-04 00:39:24 +00:00
gtk_tree_view_append_column ( GTK_TREE_VIEW ( import_tree ) , import_table_column ) ;
2010-08-15 08:30:08 +00:00
2012-01-08 23:32:05 +00:00
/* Geo column field */
2012-02-04 00:39:24 +00:00
import_geom_column_renderer = gtk_cell_renderer_text_new ( ) ;
g_object_set ( import_geom_column_renderer , " editable " , TRUE , NULL ) ;
column_indexes [ IMPORT_GEOMETRY_COLUMN ] = IMPORT_GEOMETRY_COLUMN ;
g_signal_connect ( G_OBJECT ( import_geom_column_renderer ) , " edited " , G_CALLBACK ( pgui_action_handle_loader_edit ) , & column_indexes [ IMPORT_GEOMETRY_COLUMN ] ) ;
import_geom_column = gtk_tree_view_column_new_with_attributes ( _ ( " Geo Column " ) ,
import_geom_column_renderer ,
2010-08-15 08:30:08 +00:00
" text " ,
2012-02-04 00:39:24 +00:00
IMPORT_GEOMETRY_COLUMN ,
2010-08-15 08:30:08 +00:00
NULL ) ;
2012-06-21 22:24:00 +00:00
g_object_set ( import_geom_column , " resizable " , TRUE , " expand " , TRUE , NULL ) ;
2012-02-04 00:39:24 +00:00
gtk_tree_view_append_column ( GTK_TREE_VIEW ( import_tree ) , import_geom_column ) ;
2010-08-11 09:50:38 +00:00
/* SRID Field */
2012-02-04 00:39:24 +00:00
import_srid_renderer = gtk_cell_renderer_text_new ( ) ;
g_object_set ( import_srid_renderer , " editable " , TRUE , NULL ) ;
column_indexes [ IMPORT_SRID_COLUMN ] = IMPORT_SRID_COLUMN ;
g_signal_connect ( G_OBJECT ( import_srid_renderer ) , " edited " , G_CALLBACK ( pgui_action_handle_loader_edit ) , & column_indexes [ IMPORT_SRID_COLUMN ] ) ;
import_srid_column = gtk_tree_view_column_new_with_attributes ( " SRID " ,
import_srid_renderer ,
2010-08-15 08:30:08 +00:00
" text " ,
2012-02-04 00:39:24 +00:00
IMPORT_SRID_COLUMN ,
2010-08-15 08:30:08 +00:00
NULL ) ;
2012-06-21 22:24:00 +00:00
g_object_set ( import_srid_column , " resizable " , TRUE , " expand " , TRUE , NULL ) ;
2012-02-04 00:39:24 +00:00
gtk_tree_view_append_column ( GTK_TREE_VIEW ( import_tree ) , import_srid_column ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* Mode Combo Field */
2012-02-04 00:39:24 +00:00
loader_mode_combo_list = gtk_list_store_new ( LOADER_MODE_COMBO_COLUMNS ,
2012-01-08 23:32:05 +00:00
G_TYPE_STRING ,
G_TYPE_CHAR ) ;
2012-02-04 00:39:24 +00:00
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 ' ,
2012-01-08 23:32:05 +00:00
- 1 ) ;
2012-02-04 00:39:24 +00:00
gtk_list_store_insert ( loader_mode_combo_list , & iter , APPEND_MODE ) ;
gtk_list_store_set ( loader_mode_combo_list , & iter ,
LOADER_MODE_COMBO_TEXT , _ ( " Append " ) ,
LOADER_MODE_COMBO_OPTION_CHAR , ' a ' ,
2012-01-08 23:32:05 +00:00
- 1 ) ;
2012-02-04 00:39:24 +00:00
gtk_list_store_insert ( loader_mode_combo_list , & iter , DELETE_MODE ) ;
gtk_list_store_set ( loader_mode_combo_list , & iter ,
LOADER_MODE_COMBO_TEXT , _ ( " Delete " ) ,
LOADER_MODE_COMBO_OPTION_CHAR , ' d ' ,
2012-01-08 23:32:05 +00:00
- 1 ) ;
2012-02-04 00:39:24 +00:00
gtk_list_store_insert ( loader_mode_combo_list , & iter , PREPARE_MODE ) ;
gtk_list_store_set ( loader_mode_combo_list , & iter ,
LOADER_MODE_COMBO_TEXT , _ ( " Prepare " ) ,
LOADER_MODE_COMBO_OPTION_CHAR , ' p ' ,
2012-01-08 23:32:05 +00:00
- 1 ) ;
2012-02-04 00:39:24 +00:00
loader_mode_combo = gtk_combo_box_new_with_model ( GTK_TREE_MODEL ( loader_mode_combo_list ) ) ;
import_mode_renderer = gtk_cell_renderer_combo_new ( ) ;
gtk_cell_layout_pack_start ( GTK_CELL_LAYOUT ( loader_mode_combo ) ,
import_mode_renderer , TRUE ) ;
gtk_cell_layout_add_attribute ( GTK_CELL_LAYOUT ( loader_mode_combo ) ,
import_mode_renderer , " text " , 0 ) ;
g_object_set ( import_mode_renderer ,
" model " , loader_mode_combo_list ,
2010-08-15 08:30:08 +00:00
" editable " , TRUE ,
" has-entry " , FALSE ,
2012-02-04 00:39:24 +00:00
" text-column " , LOADER_MODE_COMBO_TEXT ,
2010-08-15 08:30:08 +00:00
NULL ) ;
2012-02-04 00:39:24 +00:00
import_mode_column = gtk_tree_view_column_new_with_attributes ( _ ( " Mode " ) ,
import_mode_renderer ,
2010-08-15 08:30:08 +00:00
" text " ,
2012-02-04 00:39:24 +00:00
IMPORT_MODE_COLUMN ,
2010-08-15 08:30:08 +00:00
NULL ) ;
2012-02-04 00:39:24 +00:00
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 ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* Remove Field */
2012-02-04 00:39:24 +00:00
import_remove_renderer = gtk_cell_renderer_toggle_new ( ) ;
g_object_set ( import_remove_renderer , " activatable " , TRUE , NULL ) ;
g_signal_connect ( G_OBJECT ( import_remove_renderer ) , " toggled " , G_CALLBACK ( pgui_action_handle_file_remove ) , NULL ) ;
import_remove_column = gtk_tree_view_column_new_with_attributes ( " Rm " ,
import_remove_renderer , NULL ) ;
g_object_set ( import_remove_column , " resizable " , TRUE , " expand " , FALSE , " fixed-width " , 64 , " sizing " , GTK_TREE_VIEW_COLUMN_FIXED , NULL ) ;
gtk_tree_view_append_column ( GTK_TREE_VIEW ( import_tree ) , import_remove_column ) ;
2010-08-15 08:30:08 +00:00
2010-08-11 09:50:38 +00:00
g_signal_connect ( G_OBJECT ( add_file_button ) , " clicked " , G_CALLBACK ( pgui_action_open_file_dialog ) , NULL ) ;
2010-08-15 08:30:08 +00:00
2010-08-11 09:50:38 +00:00
/* Drag n Drop wiring */
2010-08-15 08:30:08 +00:00
GtkTargetEntry drop_types [ ] =
{
2010-08-11 09:50:38 +00:00
{ " text/uri-list " , 0 , 0 }
} ;
2012-01-08 23:32:05 +00:00
2010-08-11 09:50:38 +00:00
gint n_drop_types = sizeof ( drop_types ) / sizeof ( drop_types [ 0 ] ) ;
2012-02-04 00:39:24 +00:00
gtk_drag_dest_set ( GTK_WIDGET ( import_tree ) ,
2010-08-15 08:30:08 +00:00
GTK_DEST_DEFAULT_ALL ,
drop_types , n_drop_types ,
GDK_ACTION_COPY ) ;
2012-02-04 00:39:24 +00:00
g_signal_connect ( G_OBJECT ( import_tree ) , " drag_data_received " ,
2010-08-15 08:30:08 +00:00
G_CALLBACK ( pgui_action_handle_file_drop ) , NULL ) ;
2012-01-08 23:32:05 +00:00
}
2010-08-15 08:30:08 +00:00
2012-02-04 00:39:24 +00:00
/*
* This function creates the UI artefacts for the file list table and hooks
* up all the pretty signals .
*/
static void
pgui_create_export_table_table ( GtkWidget * export_list_frame )
{
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_container_set_border_width ( GTK_CONTAINER ( vbox_tree ) , 5 ) ;
gtk_container_add ( GTK_CONTAINER ( export_list_frame ) , vbox_tree ) ;
/* Setup a model */
export_table_list_store = gtk_list_store_new ( EXPORT_N_COLUMNS ,
G_TYPE_POINTER ,
G_TYPE_STRING ,
G_TYPE_STRING ,
G_TYPE_STRING ,
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 ) ;
/* Place the "Add Table" button below the list view */
add_table_button = gtk_button_new_with_label ( _ ( " Add Table " ) ) ;
gtk_container_add ( GTK_CONTAINER ( vbox_tree ) , add_table_button ) ;
/* Schema Field */
export_schema_renderer = gtk_cell_renderer_text_new ( ) ;
2012-04-15 15:46:44 +00:00
g_object_set ( export_schema_renderer , " editable " , FALSE , NULL ) ;
2012-02-04 00:39:24 +00:00
column_indexes [ EXPORT_SCHEMA_COLUMN ] = EXPORT_SCHEMA_COLUMN ;
2012-04-15 15:47:41 +00:00
g_signal_connect ( G_OBJECT ( export_schema_renderer ) , " edited " , G_CALLBACK ( pgui_action_handle_loader_edit ) , & column_indexes [ EXPORT_SCHEMA_COLUMN ] ) ;
2012-02-04 00:39:24 +00:00
export_schema_column = gtk_tree_view_column_new_with_attributes ( _ ( " Schema " ) ,
export_schema_renderer ,
" text " ,
EXPORT_SCHEMA_COLUMN ,
NULL ) ;
g_object_set ( export_schema_column , " resizable " , TRUE , " expand " , TRUE , " sizing " , GTK_TREE_VIEW_COLUMN_AUTOSIZE , NULL ) ;
gtk_tree_view_append_column ( GTK_TREE_VIEW ( export_tree ) , export_schema_column ) ;
/* Table Field */
export_table_renderer = gtk_cell_renderer_text_new ( ) ;
g_object_set ( export_table_renderer , " editable " , FALSE , NULL ) ;
column_indexes [ EXPORT_TABLE_COLUMN ] = EXPORT_TABLE_COLUMN ;
g_signal_connect ( G_OBJECT ( export_table_renderer ) , " edited " , G_CALLBACK ( pgui_action_handle_loader_edit ) , & column_indexes [ EXPORT_TABLE_COLUMN ] ) ;
2012-02-24 22:41:09 +00:00
export_table_column = gtk_tree_view_column_new_with_attributes ( _ ( " Table " ) ,
2012-02-04 00:39:24 +00:00
export_table_renderer ,
" text " ,
EXPORT_TABLE_COLUMN ,
NULL ) ;
g_object_set ( export_table_column , " resizable " , TRUE , " expand " , TRUE , " sizing " , GTK_TREE_VIEW_COLUMN_AUTOSIZE , NULL ) ;
gtk_tree_view_append_column ( GTK_TREE_VIEW ( export_tree ) , export_table_column ) ;
/* Geo column field */
export_geom_column_combo = gtk_combo_box_new ( ) ;
export_geom_column_renderer = gtk_cell_renderer_combo_new ( ) ;
gtk_cell_layout_pack_start ( GTK_CELL_LAYOUT ( export_geom_column_combo ) ,
export_geom_column_renderer , TRUE ) ;
g_object_set ( export_geom_column_renderer ,
" editable " , TRUE ,
" has-entry " , FALSE ,
" text-column " , TABLECHOOSER_GEOCOL_COMBO_TEXT ,
NULL ) ;
2012-02-24 22:41:09 +00:00
export_geom_column = gtk_tree_view_column_new_with_attributes ( _ ( " Geo Column " ) ,
2012-02-04 00:39:24 +00:00
export_geom_column_renderer ,
" model " ,
EXPORT_GEOMETRY_LISTSTORE_COLUMN ,
" text " ,
EXPORT_GEOMETRY_COLUMN ,
NULL ) ;
g_object_set ( export_geom_column , " resizable " , TRUE , " sizing " , GTK_TREE_VIEW_COLUMN_AUTOSIZE , NULL ) ;
gtk_tree_view_append_column ( GTK_TREE_VIEW ( export_tree ) , export_geom_column ) ;
g_signal_connect ( G_OBJECT ( export_geom_column_renderer ) , " changed " , G_CALLBACK ( pgui_action_handle_table_geocol_combo ) , NULL ) ;
/* Filename Field */
export_filename_renderer = gtk_cell_renderer_text_new ( ) ;
g_object_set ( export_filename_renderer , " editable " , TRUE , NULL ) ;
column_indexes [ EXPORT_FILENAME_COLUMN ] = EXPORT_FILENAME_COLUMN ;
g_signal_connect ( G_OBJECT ( export_filename_renderer ) , " edited " , G_CALLBACK ( pgui_action_handle_dumper_edit ) , & column_indexes [ EXPORT_FILENAME_COLUMN ] ) ;
2012-02-24 22:41:09 +00:00
export_filename_column = gtk_tree_view_column_new_with_attributes ( _ ( " Filename " ) ,
2012-02-04 00:39:24 +00:00
export_filename_renderer ,
" text " ,
EXPORT_FILENAME_COLUMN ,
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 ) ;
g_signal_connect ( G_OBJECT ( export_remove_renderer ) , " toggled " , G_CALLBACK ( pgui_action_handle_table_remove ) , NULL ) ;
export_remove_column = gtk_tree_view_column_new_with_attributes ( " Rm " ,
export_remove_renderer , NULL ) ;
g_object_set ( export_remove_column , " resizable " , TRUE , " expand " , FALSE , " fixed-width " , 64 , " sizing " , GTK_TREE_VIEW_COLUMN_FIXED , NULL ) ;
gtk_tree_view_append_column ( GTK_TREE_VIEW ( export_tree ) , export_remove_column ) ;
g_signal_connect ( G_OBJECT ( add_table_button ) , " clicked " , G_CALLBACK ( pgui_action_open_table_dialog ) , NULL ) ;
}
2012-01-08 23:32:05 +00:00
static void
pgui_create_connection_window ( )
{
/* Default text width */
static int text_width = 12 ;
/* Vbox container */
GtkWidget * vbox ;
/* Reusable label handle */
GtkWidget * label ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* PgSQL section */
GtkWidget * frame_pg , * table_pg ;
/* OK button */
GtkWidget * button_okay ;
/* Create the main top level window with a 10px border */
window_conn = gtk_window_new ( GTK_WINDOW_TOPLEVEL ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( window_conn ) , 10 ) ;
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
*/
frame_pg = gtk_frame_new ( _ ( " PostGIS Connection " ) ) ;
table_pg = gtk_table_new ( 5 , 3 , TRUE ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( table_pg ) , 8 ) ;
gtk_table_set_col_spacings ( GTK_TABLE ( table_pg ) , 7 ) ;
gtk_table_set_row_spacings ( GTK_TABLE ( table_pg ) , 3 ) ;
/* User name row */
label = gtk_label_new ( _ ( " Username: " ) ) ;
entry_pg_user = gtk_entry_new ( ) ;
gtk_table_attach_defaults ( GTK_TABLE ( table_pg ) , label , 0 , 1 , 0 , 1 ) ;
gtk_table_attach_defaults ( GTK_TABLE ( table_pg ) , entry_pg_user , 1 , 3 , 0 , 1 ) ;
2010-08-11 09:50:38 +00:00
2012-01-08 23:32:05 +00:00
/* Password row */
label = gtk_label_new ( _ ( " Password: " ) ) ;
entry_pg_pass = gtk_entry_new ( ) ;
gtk_entry_set_visibility ( GTK_ENTRY ( entry_pg_pass ) , FALSE ) ;
gtk_table_attach_defaults ( GTK_TABLE ( table_pg ) , label , 0 , 1 , 1 , 2 ) ;
gtk_table_attach_defaults ( GTK_TABLE ( table_pg ) , entry_pg_pass , 1 , 3 , 1 , 2 ) ;
/* Host and port row */
label = gtk_label_new ( _ ( " Server Host: " ) ) ;
entry_pg_host = gtk_entry_new ( ) ;
gtk_entry_set_width_chars ( GTK_ENTRY ( entry_pg_host ) , text_width ) ;
gtk_table_attach_defaults ( GTK_TABLE ( table_pg ) , label , 0 , 1 , 2 , 3 ) ;
gtk_table_attach_defaults ( GTK_TABLE ( table_pg ) , entry_pg_host , 1 , 2 , 2 , 3 ) ;
entry_pg_port = gtk_entry_new ( ) ;
gtk_entry_set_width_chars ( GTK_ENTRY ( entry_pg_port ) , 8 ) ;
gtk_table_attach_defaults ( GTK_TABLE ( table_pg ) , entry_pg_port , 2 , 3 , 2 , 3 ) ;
/* Database row */
label = gtk_label_new ( _ ( " Database: " ) ) ;
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 */
2012-02-04 00:39:24 +00:00
GtkWidget * vbox_main , * vbox_loader , * vbox_dumper ;
2012-01-08 23:32:05 +00:00
/* PgSQL section */
2012-02-04 00:39:24 +00:00
GtkWidget * frame_pg , * import_list_frame , * export_list_frame , * frame_log ;
2012-01-08 23:32:05 +00:00
GtkWidget * button_pg_conn ;
/* Notebook */
GtkWidget * notebook ;
/* Button section */
2012-02-04 00:39:24 +00:00
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 ;
2012-01-08 23:32:05 +00:00
/* Log section */
GtkWidget * scrolledwindow_log ;
/* Create the main top level window with a 10px border */
window_main = gtk_window_new ( GTK_WINDOW_TOPLEVEL ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( window_main ) , 10 ) ;
2012-02-04 00:39:31 +00:00
gtk_window_set_title ( GTK_WINDOW ( window_main ) , _ ( " PostGIS Shapefile Import/Export Manager " ) ) ;
2012-01-08 23:32:05 +00:00
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
*/
g_signal_connect ( G_OBJECT ( window_main ) , " destroy " , G_CALLBACK ( pgui_quit ) , NULL ) ;
/* 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
*/
2012-02-04 00:39:24 +00:00
import_list_frame = gtk_frame_new ( _ ( " Import List " ) ) ;
pgui_create_import_file_table ( import_list_frame ) ;
2012-01-08 23:32:05 +00:00
/*
* * Row of action buttons
*/
2012-02-04 00:39:24 +00:00
loader_hbox_buttons = gtk_hbox_new ( TRUE , 15 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( loader_hbox_buttons ) , 0 ) ;
2012-01-08 23:32:05 +00:00
/* Create the buttons themselves */
2012-02-04 00:39:24 +00:00
loader_button_options = gtk_button_new_with_label ( _ ( " Options... " ) ) ;
loader_button_import = gtk_button_new_with_label ( _ ( " Import " ) ) ;
loader_button_cancel = gtk_button_new_with_label ( _ ( " Cancel " ) ) ;
loader_button_about = gtk_button_new_with_label ( _ ( " About " ) ) ;
2012-01-08 23:32:05 +00:00
/* Add actions to the buttons */
2012-02-04 00:39:24 +00:00
g_signal_connect ( G_OBJECT ( loader_button_import ) , " clicked " , G_CALLBACK ( pgui_action_import ) , NULL ) ;
g_signal_connect ( G_OBJECT ( loader_button_options ) , " clicked " , G_CALLBACK ( pgui_action_loader_options_open ) , NULL ) ;
g_signal_connect ( G_OBJECT ( loader_button_cancel ) , " clicked " , G_CALLBACK ( pgui_action_cancel ) , NULL ) ;
g_signal_connect ( G_OBJECT ( loader_button_about ) , " clicked " , G_CALLBACK ( pgui_action_about_open ) , NULL ) ;
2012-01-08 23:32:05 +00:00
/* And insert the buttons into the hbox */
2012-02-04 00:39:24 +00:00
gtk_box_pack_start ( GTK_BOX ( loader_hbox_buttons ) , loader_button_options , TRUE , TRUE , 0 ) ;
gtk_box_pack_end ( GTK_BOX ( loader_hbox_buttons ) , loader_button_cancel , TRUE , TRUE , 0 ) ;
gtk_box_pack_end ( GTK_BOX ( loader_hbox_buttons ) , loader_button_about , TRUE , TRUE , 0 ) ;
gtk_box_pack_end ( GTK_BOX ( loader_hbox_buttons ) , loader_button_import , TRUE , TRUE , 0 ) ;
/*
* * Table selector
*/
export_list_frame = gtk_frame_new ( _ ( " Export List " ) ) ;
pgui_create_export_table_table ( export_list_frame ) ;
/*
* * Row of action buttons
*/
dumper_hbox_buttons = gtk_hbox_new ( TRUE , 15 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( dumper_hbox_buttons ) , 0 ) ;
/* Create the buttons themselves */
dumper_button_options = gtk_button_new_with_label ( _ ( " Options... " ) ) ;
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 ) ;
g_signal_connect ( G_OBJECT ( dumper_button_cancel ) , " clicked " , G_CALLBACK ( pgui_action_cancel ) , NULL ) ;
g_signal_connect ( G_OBJECT ( dumper_button_about ) , " clicked " , G_CALLBACK ( pgui_action_about_open ) , NULL ) ;
2012-01-08 23:32:05 +00:00
2012-02-04 00:39:24 +00:00
/* And insert the buttons into the hbox */
gtk_box_pack_start ( GTK_BOX ( dumper_hbox_buttons ) , dumper_button_options , TRUE , TRUE , 0 ) ;
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 ) ;
2012-01-08 23:32:05 +00:00
/*
* * Log window
*/
frame_log = gtk_frame_new ( _ ( " Log Window " ) ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( frame_log ) , 0 ) ;
gtk_widget_set_size_request ( frame_log , - 1 , 200 ) ;
textview_log = gtk_text_view_new ( ) ;
textbuffer_log = gtk_text_buffer_new ( NULL ) ;
scrolledwindow_log = gtk_scrolled_window_new ( NULL , NULL ) ;
gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrolledwindow_log ) , GTK_POLICY_AUTOMATIC , GTK_POLICY_ALWAYS ) ;
gtk_text_view_set_buffer ( GTK_TEXT_VIEW ( textview_log ) , textbuffer_log ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( textview_log ) , 5 ) ;
gtk_text_view_set_editable ( GTK_TEXT_VIEW ( textview_log ) , FALSE ) ;
gtk_text_view_set_cursor_visible ( GTK_TEXT_VIEW ( textview_log ) , FALSE ) ;
gtk_text_view_set_wrap_mode ( GTK_TEXT_VIEW ( textview_log ) , GTK_WRAP_WORD ) ;
gtk_container_add ( GTK_CONTAINER ( scrolledwindow_log ) , textview_log ) ;
gtk_container_add ( GTK_CONTAINER ( frame_log ) , scrolledwindow_log ) ;
/*
* * Main window
*/
vbox_main = gtk_vbox_new ( FALSE , 10 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( vbox_main ) , 0 ) ;
/* 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 ) ;
2012-02-04 00:39:24 +00:00
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 ) ;
2012-01-08 23:32:05 +00:00
gtk_notebook_append_page ( GTK_NOTEBOOK ( notebook ) , vbox_loader , gtk_label_new ( _ ( " Import " ) ) ) ;
2012-02-04 00:39:24 +00:00
/* 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 " ) ) ) ;
2012-01-08 23:32:05 +00:00
/* 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 ) ;
return ;
}
2010-08-11 09:50:38 +00:00
2009-12-15 23:44:02 +00:00
static void
usage ( )
{
2012-01-31 20:46:18 +00:00
printf ( " RCSID: %s RELEASE: %s \n " , S2P_RCSID , POSTGIS_VERSION ) ;
2009-12-15 23:44:02 +00:00
printf ( " USAGE: shp2pgsql-gui [options] \n " ) ;
printf ( " OPTIONS: \n " ) ;
printf ( " -U <username> \n " ) ;
printf ( " -W <password> \n " ) ;
printf ( " -h <host> \n " ) ;
printf ( " -p <port> \n " ) ;
printf ( " -d <database> \n " ) ;
printf ( " -? Display this help screen \n " ) ;
}
2009-01-19 21:33:14 +00:00
int
main ( int argc , char * argv [ ] )
{
2011-03-18 19:43:25 +00:00
int c ;
2009-12-15 23:44:02 +00:00
2012-01-14 00:49:14 +00:00
# ifdef ENABLE_NLS
setlocale ( LC_ALL , " " ) ;
bindtextdomain ( PACKAGE , PGSQL_LOCALEDIR ) ;
textdomain ( PACKAGE ) ;
2010-12-02 00:44:24 +00:00
# endif
2010-08-11 09:50:38 +00:00
/* Parse command line options and set configuration */
2012-01-08 23:32:05 +00:00
global_loader_config = malloc ( sizeof ( SHPLOADERCONFIG ) ) ;
set_loader_config_defaults ( global_loader_config ) ;
2012-02-04 00:39:24 +00:00
global_dumper_config = malloc ( sizeof ( SHPDUMPERCONFIG ) ) ;
set_dumper_config_defaults ( global_dumper_config ) ;
2009-12-27 17:16:19 +00:00
/* Here we override any defaults for the GUI */
2012-01-08 23:32:05 +00:00
global_loader_config - > createindex = 1 ;
global_loader_config - > geo_col = strdup ( GEOMETRY_DEFAULT ) ;
2012-01-10 12:28:36 +00:00
global_loader_config - > dump_format = 1 ;
2012-01-08 23:32:05 +00:00
2009-12-15 23:44:02 +00:00
conn = malloc ( sizeof ( SHPCONNECTIONCONFIG ) ) ;
memset ( conn , 0 , sizeof ( SHPCONNECTIONCONFIG ) ) ;
2012-01-08 23:32:05 +00:00
/* Here we override any defaults for the connection */
conn - > host = strdup ( " localhost " ) ;
conn - > port = strdup ( " 5432 " ) ;
2009-12-15 23:44:02 +00:00
2010-01-02 06:57:08 +00:00
while ( ( c = pgis_getopt ( argc , argv , " U:p:W:d:h: " ) ) ! = - 1 )
2009-12-15 23:44:02 +00:00
{
switch ( c )
{
2010-08-15 08:30:08 +00:00
case ' U ' :
2012-01-08 23:32:05 +00:00
conn - > username = strdup ( pgis_optarg ) ;
2010-08-15 08:30:08 +00:00
break ;
case ' p ' :
2012-01-08 23:32:05 +00:00
conn - > port = strdup ( pgis_optarg ) ;
2010-08-15 08:30:08 +00:00
break ;
case ' W ' :
2012-01-08 23:32:05 +00:00
conn - > password = strdup ( pgis_optarg ) ;
2010-08-15 08:30:08 +00:00
break ;
case ' d ' :
2012-01-08 23:32:05 +00:00
conn - > database = strdup ( pgis_optarg ) ;
2010-08-15 08:30:08 +00:00
break ;
case ' h ' :
2012-01-08 23:32:05 +00:00
conn - > host = strdup ( pgis_optarg ) ;
2010-08-15 08:30:08 +00:00
break ;
default :
usage ( ) ;
free ( conn ) ;
2012-01-08 23:32:05 +00:00
free ( global_loader_config ) ;
2010-08-15 08:30:08 +00:00
exit ( 0 ) ;
2009-12-15 23:44:02 +00:00
}
}
2009-01-19 21:33:14 +00:00
/* initialize the GTK stack */
gtk_init ( & argc , & argv ) ;
2012-01-08 23:32:05 +00:00
2009-01-19 21:33:14 +00:00
/* set up the user interface */
2009-12-15 23:44:02 +00:00
pgui_create_main_window ( conn ) ;
2012-01-08 23:32:05 +00:00
pgui_create_connection_window ( ) ;
2012-02-04 00:39:24 +00:00
pgui_create_loader_options_dialog ( ) ;
pgui_create_dumper_options_dialog ( ) ;
2012-01-08 23:32:05 +00:00
pgui_create_about_dialog ( ) ;
pgui_create_filechooser_dialog ( ) ;
pgui_create_progress_dialog ( ) ;
2012-02-04 00:39:24 +00:00
pgui_create_tablechooser_dialog ( ) ;
pgui_create_folderchooser_dialog ( ) ;
2009-01-19 21:33:14 +00:00
/* start the main loop */
gtk_main ( ) ;
2009-12-13 20:31:54 +00:00
/* Free the configuration */
2009-12-15 23:44:02 +00:00
free ( conn ) ;
2012-01-08 23:32:05 +00:00
free ( global_loader_config ) ;
2009-12-13 20:31:54 +00:00
2009-01-19 21:33:14 +00:00
return 0 ;
}