X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/56b9b9a752e89913fa19001ab85dffa7f95ef307..f5dd8adbec0c362f609e2f115ff5859ce4969d09:/unix/gtkdlg.c diff --git a/unix/gtkdlg.c b/unix/gtkdlg.c index 42998667..1b58d141 100644 --- a/unix/gtkdlg.c +++ b/unix/gtkdlg.c @@ -307,15 +307,18 @@ void dlg_listbox_clear(union control *ctrl, void *dlg) { struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); - GtkContainer *cont; assert(uc->ctrl->generic.type == CTRL_EDITBOX || uc->ctrl->generic.type == CTRL_LISTBOX); assert(uc->menu != NULL || uc->list != NULL); - cont = (uc->menu ? GTK_CONTAINER(uc->menu) : GTK_CONTAINER(uc->list)); - - gtk_container_foreach(cont, container_remove_and_destroy, cont); + if (uc->menu) { + gtk_container_foreach(GTK_CONTAINER(uc->menu), + container_remove_and_destroy, + GTK_CONTAINER(uc->menu)); + } else { + gtk_list_clear_items(GTK_LIST(uc->list), 0, -1); + } } void dlg_listbox_del(union control *ctrl, void *dlg, int index) @@ -486,6 +489,8 @@ int dlg_listbox_index(union control *ctrl, void *dlg) if (uc->menu) activeitem = gtk_menu_get_active(GTK_MENU(uc->menu)); + else + activeitem = NULL; /* unnecessarily placate gcc */ children = gtk_container_children(GTK_CONTAINER(uc->menu ? uc->menu : uc->list)); @@ -1964,7 +1969,7 @@ int do_config_box(const char *title, Config *cfg, int midsession) window = gtk_dialog_new(); ctrlbox = ctrl_new_box(); - setup_config_box(ctrlbox, &sl, midsession, 0); + setup_config_box(ctrlbox, &sl, midsession, cfg->protocol); unix_setup_config_box(ctrlbox, midsession, window); gtk_window_set_title(GTK_WINDOW(window), title); @@ -2269,6 +2274,19 @@ static int string_width(char *text) return req.width; } +int reallyclose(void *frontend) +{ + char *title = dupcat(appname, " Exit Confirmation", NULL); + int ret = messagebox(GTK_WIDGET(get_window(frontend)), + title, "Are you sure you want to close this session?", + string_width("Most of the width of the above text"), + "Yes", 'y', +1, 1, + "No", 'n', -1, 0, + NULL); + sfree(title); + return ret; +} + void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype, char *keystr, char *fingerprint) { @@ -2495,6 +2513,9 @@ struct eventlog_stuff { union control *listctrl; char **events; int nevents, negsize; + char *seldata; + int sellen; + int ignore_selchange; }; static void eventlog_destroy(GtkWidget *widget, gpointer data) @@ -2502,6 +2523,7 @@ static void eventlog_destroy(GtkWidget *widget, gpointer data) struct eventlog_stuff *es = (struct eventlog_stuff *)data; es->window = NULL; + sfree(es->seldata); dlg_cleanup(&es->dp); ctrl_free_box(es->eventbox); } @@ -2525,8 +2547,82 @@ static void eventlog_list_handler(union control *ctrl, void *dlg, dlg_listbox_add(ctrl, dlg, es->events[i]); } dlg_update_done(ctrl, dlg); + } else if (event == EVENT_SELCHANGE) { + int i; + int selsize = 0; + + /* + * If this SELCHANGE event is happening as a result of + * deliberate deselection because someone else has grabbed + * the selection, the last thing we want to do is pre-empt + * them. + */ + if (es->ignore_selchange) + return; + + /* + * Construct the data to use as the selection. + */ + sfree(es->seldata); + es->seldata = NULL; + es->sellen = 0; + for (i = 0; i < es->nevents; i++) { + if (dlg_listbox_issel(ctrl, dlg, i)) { + int extralen = strlen(es->events[i]); + + if (es->sellen + extralen + 2 > selsize) { + selsize = es->sellen + extralen + 512; + es->seldata = sresize(es->seldata, selsize, char); + } + + strcpy(es->seldata + es->sellen, es->events[i]); + es->sellen += extralen; + es->seldata[es->sellen++] = '\n'; + } + } + + if (gtk_selection_owner_set(es->window, GDK_SELECTION_PRIMARY, + GDK_CURRENT_TIME)) { + extern GdkAtom compound_text_atom; + + gtk_selection_add_target(es->window, GDK_SELECTION_PRIMARY, + GDK_SELECTION_TYPE_STRING, 1); + gtk_selection_add_target(es->window, GDK_SELECTION_PRIMARY, + compound_text_atom, 1); + } + } } + +void eventlog_selection_get(GtkWidget *widget, GtkSelectionData *seldata, + guint info, guint time_stamp, gpointer data) +{ + struct eventlog_stuff *es = (struct eventlog_stuff *)data; + + gtk_selection_data_set(seldata, seldata->target, 8, + es->seldata, es->sellen); +} + +gint eventlog_selection_clear(GtkWidget *widget, GdkEventSelection *seldata, + gpointer data) +{ + struct eventlog_stuff *es = (struct eventlog_stuff *)data; + struct uctrl *uc; + + /* + * Deselect everything in the list box. + */ + uc = dlg_find_byctrl(&es->dp, es->listctrl); + es->ignore_selchange = 1; + gtk_list_unselect_all(GTK_LIST(uc->list)); + es->ignore_selchange = 0; + + sfree(es->seldata); + es->sellen = 0; + es->seldata = NULL; + return TRUE; +} + void showeventlog(void *estuff, void *parentwin) { struct eventlog_stuff *es = (struct eventlog_stuff *)estuff; @@ -2610,6 +2706,10 @@ void showeventlog(void *estuff, void *parentwin) GTK_SIGNAL_FUNC(eventlog_destroy), es); gtk_signal_connect(GTK_OBJECT(window), "key_press_event", GTK_SIGNAL_FUNC(win_key_press), &es->dp); + gtk_signal_connect(GTK_OBJECT(window), "selection_get", + GTK_SIGNAL_FUNC(eventlog_selection_get), es); + gtk_signal_connect(GTK_OBJECT(window), "selection_clear_event", + GTK_SIGNAL_FUNC(eventlog_selection_clear), es); } void *eventlogstuff_new(void) @@ -2644,3 +2744,31 @@ void logevent_dlg(void *estuff, char *string) } es->nevents++; } + +int askappend(void *frontend, Filename filename) +{ + static const char msgtemplate[] = + "The session log file \"%.*s\" already exists. " + "You can overwrite it with a new session log, " + "append your session log to the end of it, " + "or disable session logging for this session."; + char *message; + char *mbtitle; + int mbret; + + message = dupprintf(msgtemplate, FILENAME_MAX, filename.path); + mbtitle = dupprintf("%s Log to File", appname); + + mbret = messagebox(get_window(frontend), mbtitle, message, + string_width("LINE OF TEXT SUITABLE FOR THE" + " ASKAPPEND WIDTH"), + "Overwrite", 'o', 1, 2, + "Append", 'a', 0, 1, + "Disable", 'd', -1, 0, + NULL); + + sfree(message); + sfree(mbtitle); + + return mbret; +}