void vik_layers_panel_delete_selected ( VikLayersPanel *vlp ) { gint type; GtkTreeIter iter; if ( ! vik_treeview_get_selected_iter ( vlp->vt, &iter ) ) /* Nothing to do */ return; type = vik_treeview_item_get_type ( vlp->vt, &iter ); if ( type == VIK_TREEVIEW_TYPE_LAYER ) { // Get confirmation from the user if ( ! a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_WIDGET(vlp), _("Are you sure you want to delete %s?"), vik_layer_get_name ( VIK_LAYER(vik_treeview_item_get_pointer ( vlp->vt, &iter )) ) ) ) return; VikAggregateLayer *parent = vik_treeview_item_get_parent ( vlp->vt, &iter ); if ( parent ) { /* reset trigger if trigger deleted */ if ( vik_layers_panel_get_selected ( vlp ) == vik_viewport_get_trigger ( vlp->vvp ) ) vik_viewport_set_trigger ( vlp->vvp, NULL ); if (IS_VIK_AGGREGATE_LAYER(parent)) { if ( vik_aggregate_layer_delete ( parent, &iter ) ) vik_layers_panel_emit_update ( vlp ); } } else a_dialog_info_msg ( VIK_GTK_WINDOW_FROM_WIDGET(vlp), _("You cannot delete the Top Layer.") ); } else if (type == VIK_TREEVIEW_TYPE_SUBLAYER) { VikLayer *sel = vik_layers_panel_get_selected ( vlp ); if ( vik_layer_get_interface(sel->type)->delete_item ) { gint subtype = vik_treeview_item_get_data( vlp->vt, &iter); vik_layer_get_interface(sel->type)->delete_item ( sel, subtype, vik_treeview_item_get_pointer(sel->vt, &iter) ); } } }
VikLayer *vik_layers_panel_get_layer_of_type ( VikLayersPanel *vlp, gint type ) { VikLayer *rv = vik_layers_panel_get_selected ( vlp ); if ( rv == NULL || rv->type != type ) if ( VIK_LAYER(vlp->toplayer)->visible ) return vik_aggregate_layer_get_top_visible_layer_of_type ( vlp->toplayer, type ); else return NULL; else return rv; }
gboolean vik_layers_panel_tool ( VikLayersPanel *vlp, guint16 layer_type, VikToolInterfaceFunc tool_func, GdkEventButton *event, VikViewport *vvp ) { VikLayer *vl = vik_layers_panel_get_selected ( vlp ); if ( vl && vl->type == layer_type ) { tool_func ( vl, event, vvp ); return TRUE; } else if ( VIK_LAYER(vlp->toplayer)->visible && vik_aggregate_layer_tool ( vlp->toplayer, layer_type, tool_func, event, vvp ) != 1 ) /* either accepted or rejected, but a layer was found */ return TRUE; return FALSE; }
void vik_layers_panel_cut_selected ( VikLayersPanel *vlp ) { gint type; GtkTreeIter iter; if ( ! vik_treeview_get_selected_iter ( vlp->vt, &iter ) ) /* Nothing to do */ return; type = vik_treeview_item_get_type ( vlp->vt, &iter ); if ( type == VIK_TREEVIEW_TYPE_LAYER ) { VikAggregateLayer *parent = vik_treeview_item_get_parent ( vlp->vt, &iter ); if ( parent ) { /* reset trigger if trigger deleted */ if ( vik_layers_panel_get_selected ( vlp ) == vik_viewport_get_trigger ( vlp->vvp ) ) vik_viewport_set_trigger ( vlp->vvp, NULL ); a_clipboard_copy_selected ( vlp ); if (IS_VIK_AGGREGATE_LAYER(parent)) { if ( vik_aggregate_layer_delete ( parent, &iter ) ) vik_layers_panel_emit_update ( vlp ); } } else a_dialog_info_msg ( VIK_GTK_WINDOW_FROM_WIDGET(vlp), _("You cannot cut the Top Layer.") ); } else if (type == VIK_TREEVIEW_TYPE_SUBLAYER) { VikLayer *sel = vik_layers_panel_get_selected ( vlp ); if ( vik_layer_get_interface(sel->type)->cut_item ) { gint subtype = vik_treeview_item_get_data( vlp->vt, &iter); vik_layer_get_interface(sel->type)->cut_item ( sel, subtype, vik_treeview_item_get_pointer(sel->vt, &iter) ); } } }
static void clip_add_wp(VikLayersPanel *vlp, struct LatLon *coord) { VikCoord vc; VikLayer *sel = vik_layers_panel_get_selected ( vlp ); vik_coord_load_from_latlon ( &vc, VIK_COORD_LATLON, coord ); if (sel && sel->type == VIK_LAYER_TRW) { vik_trw_layer_new_waypoint ( VIK_TRW_LAYER(sel), VIK_GTK_WINDOW_FROM_LAYER(sel), &vc ); } else { a_dialog_error_msg_extra ( VIK_GTK_WINDOW_FROM_WIDGET(GTK_WIDGET(vlp)), _("In order to paste a waypoint, please select an appropriate layer to paste into."), NULL); } }
/** * Load a single JPG into a Trackwaypoint Layer as a waypoint * * @top: The Aggregate layer that a new TRW layer may be created in * @filename: The JPG filename * @vvp: The viewport * * Returns: Whether the loading was a success or not * * If the JPG has geotag information then the waypoint will be created with the appropriate position. * Otherwise the waypoint will be positioned at the current screen center. * If a TRW layer is already selected the waypoint will be created in that layer. */ gboolean a_jpg_load_file ( VikAggregateLayer *top, const gchar *filename, VikViewport *vvp ) { gboolean auto_zoom = TRUE; VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(top))); VikLayersPanel *vlp = vik_window_layers_panel ( vw ); // Auto load into TrackWaypoint layer if one is selected VikLayer *vtl = vik_layers_panel_get_selected ( vlp ); gboolean create_layer = FALSE; if ( vtl == NULL || vtl->type != VIK_LAYER_TRW ) { // Create layer if necessary vtl = vik_layer_create ( VIK_LAYER_TRW, vvp, FALSE ); vik_layer_rename ( vtl, a_file_basename ( filename ) ); create_layer = TRUE; } gchar *name = NULL; VikWaypoint *wp = NULL; #ifdef VIK_CONFIG_GEOTAG wp = a_geotag_create_waypoint_from_file ( filename, vik_viewport_get_coord_mode (vvp), &name ); #endif if ( wp ) { // Create name if geotag method didn't return one if ( !name ) name = g_strdup ( a_file_basename ( filename ) ); vik_trw_layer_filein_add_waypoint ( VIK_TRW_LAYER(vtl), name, wp ); g_free ( name ); } else { wp = vik_waypoint_new (); wp->visible = TRUE; vik_trw_layer_filein_add_waypoint ( VIK_TRW_LAYER(vtl), (gchar*) a_file_basename(filename), wp ); vik_waypoint_set_image ( wp, filename ); // Simply set position to the current center wp->coord = *( vik_viewport_get_center ( vvp ) ); auto_zoom = FALSE; } // Complete the setup vik_layer_post_read ( vtl, vvp, TRUE ); if ( create_layer ) vik_aggregate_layer_add_layer ( top, vtl, FALSE ); if ( auto_zoom ) vik_trw_layer_auto_set_view ( VIK_TRW_LAYER(vtl), vvp ); // ATM This routine can't fail return TRUE; }
/* our own data type */ static void clip_receive_viking ( GtkClipboard *c, GtkSelectionData *sd, gpointer p ) { VikLayersPanel *vlp = p; vik_clipboard_t *vc; if (sd->length == -1) { g_warning ( _("paste failed") ); return; } // g_print("clip receive: target = %s, type = %s\n", gdk_atom_name(sd->target), gdk_atom_name(sd->type)); g_assert(!strcmp(gdk_atom_name(sd->target), target_table[0].target)); vc = (vik_clipboard_t *)sd->data; // g_print(" sd->data = %p, sd->length = %d, vc->len = %d\n", sd->data, sd->length, vc->len); if (sd->length != sizeof(*vc) + vc->len) { g_warning ( _("wrong clipboard data size") ); return; } if ( vc->type == VIK_CLIPBOARD_DATA_LAYER ) { VikLayer *new_layer = vik_layer_unmarshall ( vc->data, vc->len, vik_layers_panel_get_viewport(vlp) ); vik_layers_panel_add_layer ( vlp, new_layer ); } else if ( vc->type == VIK_CLIPBOARD_DATA_SUBLAYER ) { VikLayer *sel = vik_layers_panel_get_selected ( vlp ); if ( sel && sel->type == vc->layer_type) { if ( vik_layer_get_interface(vc->layer_type)->paste_item ) vik_layer_get_interface(vc->layer_type)->paste_item ( sel, vc->subtype, vc->data, vc->len); } else a_dialog_error_msg_extra ( VIK_GTK_WINDOW_FROM_WIDGET(GTK_WIDGET(vlp)), _("The clipboard contains sublayer data for %s layers. " "You must select a layer of this type to paste the clipboard data."), vik_layer_get_interface(vc->layer_type)->name ); } }
/** * a_clipboard_copy_selected: * * Make a copy of selected object and associate ourselves with the clipboard. */ void a_clipboard_copy_selected ( VikLayersPanel *vlp ) { VikLayer *sel = vik_layers_panel_get_selected ( vlp ); GtkTreeIter iter; VikClipboardDataType type; guint16 layer_type = 0; gint subtype = 0; guint8 *data = NULL; guint len; const gchar *name = NULL; if ( ! sel ) return; vik_treeview_get_selected_iter ( sel->vt, &iter ); layer_type = sel->type; if ( vik_treeview_item_get_type ( sel->vt, &iter ) == VIK_TREEVIEW_TYPE_SUBLAYER ) { type = VIK_CLIPBOARD_DATA_SUBLAYER; if ( vik_layer_get_interface(layer_type)->copy_item) { subtype = vik_treeview_item_get_data(sel->vt, &iter); vik_layer_get_interface(layer_type)->copy_item(sel, subtype, vik_treeview_item_get_pointer(sel->vt, &iter), &data, &len ); // This name is used in setting the text representation of the item on the clipboard. name = vik_treeview_item_get_name(sel->vt, &iter); } } else { gint ilen; type = VIK_CLIPBOARD_DATA_LAYER; vik_layer_marshall ( sel, &data, &ilen ); len = ilen; name = vik_layer_get_name ( vik_treeview_item_get_pointer(sel->vt, &iter) ); } if (data) { a_clipboard_copy( type, layer_type, subtype, len, name, data); } }
/* this routine is the worker thread. there is only one simultaneous download allowed */ static void get_from_anything ( w_and_interface_t *wi ) { gchar *cmd = wi->cmd; gchar *extra = wi->extra; gboolean result = TRUE; VikTrwLayer *vtl = NULL; gboolean creating_new_layer = TRUE; acq_dialog_widgets_t *w = wi->w; VikDataSourceInterface *source_interface = wi->w->source_interface; g_free ( wi ); wi = NULL; gdk_threads_enter(); if (source_interface->mode == VIK_DATASOURCE_ADDTOLAYER) { VikLayer *current_selected = vik_layers_panel_get_selected ( w->vlp ); if ( IS_VIK_TRW_LAYER(current_selected) ) { vtl = VIK_TRW_LAYER(current_selected); creating_new_layer = FALSE; } } if ( creating_new_layer ) { vtl = VIK_TRW_LAYER ( vik_layer_create ( VIK_LAYER_TRW, w->vvp, NULL, FALSE ) ); vik_layer_rename ( VIK_LAYER ( vtl ), _(source_interface->layer_title) ); gtk_label_set_text ( GTK_LABEL(w->status), _("Working...") ); } gdk_threads_leave(); switch ( source_interface->type ) { case VIK_DATASOURCE_GPSBABEL_DIRECT: result = a_babel_convert_from (vtl, cmd, (BabelStatusFunc) progress_func, extra, w); break; case VIK_DATASOURCE_URL: result = a_babel_convert_from_url (vtl, cmd, extra, (BabelStatusFunc) progress_func, w); break; case VIK_DATASOURCE_SHELL_CMD: result = a_babel_convert_from_shellcommand ( vtl, cmd, extra, (BabelStatusFunc) progress_func, w); break; default: g_critical("Houston, we've had a problem."); } g_free ( cmd ); g_free ( extra ); if (!result) { gdk_threads_enter(); gtk_label_set_text ( GTK_LABEL(w->status), _("Error: acquisition failed.") ); if ( creating_new_layer ) g_object_unref ( G_OBJECT ( vtl ) ); gdk_threads_leave(); } else { gdk_threads_enter(); if (w->ok) { gtk_label_set_text ( GTK_LABEL(w->status), _("Done.") ); if ( creating_new_layer ) { /* Only create the layer if it actually contains anything useful */ if ( g_hash_table_size (vik_trw_layer_get_tracks(vtl)) || g_hash_table_size (vik_trw_layer_get_waypoints(vtl)) ) vik_aggregate_layer_add_layer( vik_layers_panel_get_top_layer(w->vlp), VIK_LAYER(vtl)); else gtk_label_set_text ( GTK_LABEL(w->status), _("No data.") ); } /* View this data if available and is desired */ if ( vtl && source_interface->autoview ) { vik_trw_layer_auto_set_view ( vtl, vik_layers_panel_get_viewport(w->vlp) ); vik_layers_panel_emit_update (w->vlp); } if ( source_interface->keep_dialog_open ) { gtk_dialog_set_response_sensitive ( GTK_DIALOG(w->dialog), GTK_RESPONSE_ACCEPT, TRUE ); gtk_dialog_set_response_sensitive ( GTK_DIALOG(w->dialog), GTK_RESPONSE_REJECT, FALSE ); } else { gtk_dialog_response ( GTK_DIALOG(w->dialog), GTK_RESPONSE_ACCEPT ); } } else { /* canceled */ if ( creating_new_layer ) g_object_unref(vtl); } } if ( source_interface->cleanup_func ) source_interface->cleanup_func ( w->user_data ); if ( w->ok ) { w->ok = FALSE; } else { g_free ( w ); } gdk_threads_leave(); g_thread_exit ( NULL ); }
/* depending on type of filter, often only vtl or track will be given. * the other can be NULL. */ static void acquire ( VikWindow *vw, VikLayersPanel *vlp, VikViewport *vvp, VikDataSourceInterface *source_interface, VikTrwLayer *vtl, VikTrack *track ) { /* for manual dialogs */ GtkWidget *dialog = NULL; GtkWidget *status; gchar *cmd = NULL; gchar *extra = NULL; gchar *cmd_off = NULL; gchar *extra_off = NULL; acq_dialog_widgets_t *w; gpointer user_data; gpointer options = NULL; /* for UI builder */ gpointer pass_along_data; VikLayerParamData *paramdatas = NULL; w_and_interface_t *wi; /*** INIT AND CHECK EXISTENCE ***/ if ( source_interface->init_func ) user_data = source_interface->init_func(); else user_data = NULL; pass_along_data = user_data; if ( source_interface->check_existence_func ) { gchar *error_str = source_interface->check_existence_func(); if ( error_str ) { a_dialog_error_msg ( GTK_WINDOW(vw), error_str ); g_free ( error_str ); return; } } /* BUILD UI & GET OPTIONS IF NECESSARY. */ /* POSSIBILITY 0: NO OPTIONS. DO NOTHING HERE. */ /* POSSIBILITY 1: ADD_SETUP_WIDGETS_FUNC */ if ( source_interface->add_setup_widgets_func ) { dialog = gtk_dialog_new_with_buttons ( "", GTK_WINDOW(vw), 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL ); gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT ); GtkWidget *response_w = NULL; #if GTK_CHECK_VERSION (2, 20, 0) response_w = gtk_dialog_get_widget_for_response ( GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT ); #endif source_interface->add_setup_widgets_func(dialog, vvp, user_data); gtk_window_set_title ( GTK_WINDOW(dialog), _(source_interface->window_title) ); if ( response_w ) gtk_widget_grab_focus ( response_w ); if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) != GTK_RESPONSE_ACCEPT ) { source_interface->cleanup_func(user_data); gtk_widget_destroy(dialog); return; } } /* POSSIBILITY 2: UI BUILDER */ else if ( source_interface->params ) { paramdatas = a_uibuilder_run_dialog ( source_interface->window_title, GTK_WINDOW(vw), source_interface->params, source_interface->params_count, source_interface->params_groups, source_interface->params_groups_count, source_interface->params_defaults ); if ( paramdatas ) pass_along_data = paramdatas; else return; /* TODO: do we have to free anything here? */ } /* CREATE INPUT DATA & GET COMMAND STRING */ if ( source_interface->inputtype == VIK_DATASOURCE_INPUTTYPE_TRWLAYER ) { gchar *name_src = write_tmp_trwlayer ( vtl ); ((VikDataSourceGetCmdStringFuncWithInput) source_interface->get_cmd_string_func) ( pass_along_data, &cmd, &extra, name_src ); g_free ( name_src ); /* TODO: delete the tmp file? or delete it only after we're done with it? */ } else if ( source_interface->inputtype == VIK_DATASOURCE_INPUTTYPE_TRWLAYER_TRACK ) { gchar *name_src = write_tmp_trwlayer ( vtl ); gchar *name_src_track = write_tmp_track ( track ); ((VikDataSourceGetCmdStringFuncWithInputInput) source_interface->get_cmd_string_func) ( pass_along_data, &cmd, &extra, name_src, name_src_track ); g_free ( name_src ); g_free ( name_src_track ); } else if ( source_interface->inputtype == VIK_DATASOURCE_INPUTTYPE_TRACK ) { gchar *name_src_track = write_tmp_track ( track ); ((VikDataSourceGetCmdStringFuncWithInput) source_interface->get_cmd_string_func) ( pass_along_data, &cmd, &extra, name_src_track ); g_free ( name_src_track ); } else if ( source_interface->get_cmd_string_func ) source_interface->get_cmd_string_func ( pass_along_data, &cmd, &extra, &options ); /* Get data for Off command */ if ( source_interface->off_func ) { source_interface->off_func ( pass_along_data, &cmd_off, &extra_off ); } /* cleanup for option dialogs */ if ( source_interface->add_setup_widgets_func ) { gtk_widget_destroy(dialog); dialog = NULL; } else if ( source_interface->params ) { a_uibuilder_free_paramdatas ( paramdatas, source_interface->params, source_interface->params_count ); } w = g_malloc(sizeof(*w)); wi = g_malloc(sizeof(*wi)); wi->w = w; wi->w->source_interface = source_interface; wi->cmd = cmd; wi->extra = extra; /* usually input data type (?) */ wi->options = options; wi->vtl = vtl; wi->creating_new_layer = (!vtl); dialog = gtk_dialog_new_with_buttons ( "", GTK_WINDOW(vw), 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL ); gtk_dialog_set_response_sensitive ( GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT, FALSE ); gtk_window_set_title ( GTK_WINDOW(dialog), _(source_interface->window_title) ); w->dialog = dialog; w->running = TRUE; status = gtk_label_new (_("Working...")); gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), status, FALSE, FALSE, 5 ); gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT ); // May not want to see the dialog at all if ( source_interface->is_thread || source_interface->keep_dialog_open ) gtk_widget_show_all(dialog); w->status = status; w->vw = vw; w->vlp = vlp; w->vvp = vvp; if ( source_interface->add_progress_widgets_func ) { source_interface->add_progress_widgets_func ( dialog, user_data ); } w->user_data = user_data; if (source_interface->mode == VIK_DATASOURCE_ADDTOLAYER) { VikLayer *current_selected = vik_layers_panel_get_selected ( w->vlp ); if ( IS_VIK_TRW_LAYER(current_selected) ) { wi->vtl = VIK_TRW_LAYER(current_selected); wi->creating_new_layer = FALSE; } } else if ( source_interface->mode == VIK_DATASOURCE_MANUAL_LAYER_MANAGEMENT ) { // Don't create in acquire - as datasource will perform the necessary actions wi->creating_new_layer = FALSE; VikLayer *current_selected = vik_layers_panel_get_selected ( w->vlp ); if ( IS_VIK_TRW_LAYER(current_selected) ) wi->vtl = VIK_TRW_LAYER(current_selected); } if ( wi->creating_new_layer ) { wi->vtl = VIK_TRW_LAYER ( vik_layer_create ( VIK_LAYER_TRW, w->vvp, NULL, FALSE ) ); vik_layer_rename ( VIK_LAYER ( wi->vtl ), _(source_interface->layer_title) ); } if ( source_interface->is_thread ) { if ( cmd ) { g_thread_create((GThreadFunc)get_from_anything, wi, FALSE, NULL ); gtk_dialog_run ( GTK_DIALOG(dialog) ); if (w->running) { // Cancel and mark for thread to finish w->running = FALSE; // NB Thread will free memory } else { if ( cmd_off ) { /* Turn off */ a_babel_convert_from (NULL, cmd_off, extra_off, NULL, NULL, NULL); g_free ( cmd_off ); } if ( extra_off ) g_free ( extra_off ); // Thread finished by normal completion - free memory g_free ( w ); g_free ( wi ); } } else { // This shouldn't happen... gtk_label_set_text ( GTK_LABEL(w->status), _("Unable to create command\nAcquire method failed.") ); gtk_dialog_run (GTK_DIALOG (dialog)); } } else { // bypass thread method malarkly - you'll just have to wait... if ( source_interface->process_func ) { gboolean result = source_interface->process_func ( wi->vtl, cmd, extra, (BabelStatusFunc) progress_func, w, options ); if ( !result ) a_dialog_msg ( GTK_WINDOW(vw), GTK_MESSAGE_ERROR, _("Error: acquisition failed."), NULL ); } g_free ( cmd ); g_free ( extra ); g_free ( options ); on_complete_process ( wi ); // Actually show it if necessary if ( wi->w->source_interface->keep_dialog_open ) gtk_dialog_run ( GTK_DIALOG(dialog) ); g_free ( w ); g_free ( wi ); } gtk_widget_destroy ( dialog ); }