⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtkdlg.c

📁 远程登陆工具软件源码 用于远程登陆unix
💻 C
📖 第 1 页 / 共 5 页
字号:
	gtk_container_add(GTK_CONTAINER(uc->menu), menuitem);
	gtk_widget_show(menuitem);

	gtk_object_set_data(GTK_OBJECT(menuitem), "user-data",
			    GINT_TO_POINTER(id));
	gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
			   GTK_SIGNAL_FUNC(menuitem_activate), dp);
    } else if (!uc->entry) {
	/*
	 * List item in a non-combo-box list box. We make all of
	 * these Columns containing GtkLabels. This allows us to do
	 * the nasty force_left hack irrespective of whether there
	 * are tabs in the thing.
	 */
	GtkWidget *listitem = gtk_list_item_new();
	GtkWidget *cols = columns_new(10);
	gint *percents;
	int i, ncols;

	/* Count the tabs in the text, and hence determine # of columns. */
	ncols = 1;
	for (i = 0; text[i]; i++)
	    if (text[i] == '\t')
		ncols++;

	assert(ncols <=
	       (uc->ctrl->listbox.ncols ? uc->ctrl->listbox.ncols : 1));
	percents = snewn(ncols, gint);
	percents[ncols-1] = 100;
	for (i = 0; i < ncols-1; i++) {
	    percents[i] = uc->ctrl->listbox.percentages[i];
	    percents[ncols-1] -= percents[i];
	}
	columns_set_cols(COLUMNS(cols), ncols, percents);
	sfree(percents);

	for (i = 0; i < ncols; i++) {
	    int len = strcspn(text, "\t");
	    char *dup = dupprintf("%.*s", len, text);
	    GtkWidget *label;

	    text += len;
	    if (*text) text++;
	    label = gtk_label_new(dup);
	    sfree(dup);

	    columns_add(COLUMNS(cols), label, i, 1);
	    columns_force_left_align(COLUMNS(cols), label);
	    gtk_widget_show(label);
	}
	gtk_container_add(GTK_CONTAINER(listitem), cols);
	gtk_widget_show(cols);
	gtk_container_add(GTK_CONTAINER(uc->list), listitem);
	gtk_widget_show(listitem);

        if (ctrl->listbox.multisel) {
            gtk_signal_connect(GTK_OBJECT(listitem), "key_press_event",
                               GTK_SIGNAL_FUNC(listitem_multi_key), uc->adj);
        } else {
            gtk_signal_connect(GTK_OBJECT(listitem), "key_press_event",
                               GTK_SIGNAL_FUNC(listitem_single_key), uc->adj);
        }
        gtk_signal_connect(GTK_OBJECT(listitem), "focus_in_event",
                           GTK_SIGNAL_FUNC(widget_focus), dp);
	gtk_signal_connect(GTK_OBJECT(listitem), "button_press_event",
			   GTK_SIGNAL_FUNC(listitem_button), dp);
	gtk_object_set_data(GTK_OBJECT(listitem), "user-data",
			    GINT_TO_POINTER(id));
    } else {
	/*
	 * List item in a combo-box list, which means the sensible
	 * thing to do is make it a perfectly normal label. Hence
	 * tabs are disregarded.
	 */
	GtkWidget *listitem = gtk_list_item_new_with_label(text);

	gtk_container_add(GTK_CONTAINER(uc->list), listitem);
	gtk_widget_show(listitem);

	gtk_object_set_data(GTK_OBJECT(listitem), "user-data",
			    GINT_TO_POINTER(id));
    }

    dp->flags &= ~FLAG_UPDATING_COMBO_LIST;
}

int dlg_listbox_getid(union control *ctrl, void *dlg, int index)
{
    struct dlgparam *dp = (struct dlgparam *)dlg;
    struct uctrl *uc = dlg_find_byctrl(dp, ctrl);
    GList *children;
    GtkObject *item;

    assert(uc->ctrl->generic.type == CTRL_EDITBOX ||
	   uc->ctrl->generic.type == CTRL_LISTBOX);
    assert(uc->menu != NULL || uc->list != NULL);

    children = gtk_container_children(GTK_CONTAINER(uc->menu ? uc->menu :
						    uc->list));
    item = GTK_OBJECT(g_list_nth_data(children, index));
    g_list_free(children);

    return GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(item), "user-data"));
}

/* dlg_listbox_index returns <0 if no single element is selected. */
int dlg_listbox_index(union control *ctrl, void *dlg)
{
    struct dlgparam *dp = (struct dlgparam *)dlg;
    struct uctrl *uc = dlg_find_byctrl(dp, ctrl);
    GList *children;
    GtkWidget *item, *activeitem;
    int i;
    int selected = -1;

    assert(uc->ctrl->generic.type == CTRL_EDITBOX ||
	   uc->ctrl->generic.type == CTRL_LISTBOX);
    assert(uc->menu != NULL || uc->list != NULL);

    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));
    for (i = 0; children!=NULL && (item = GTK_WIDGET(children->data))!=NULL;
	 i++, children = children->next) {
	if (uc->menu ? activeitem == item :
	    GTK_WIDGET_STATE(item) == GTK_STATE_SELECTED) {
	    if (selected == -1)
		selected = i;
	    else
		selected = -2;
	}
    }
    g_list_free(children);
    return selected < 0 ? -1 : selected;
}

int dlg_listbox_issel(union control *ctrl, void *dlg, int index)
{
    struct dlgparam *dp = (struct dlgparam *)dlg;
    struct uctrl *uc = dlg_find_byctrl(dp, ctrl);
    GList *children;
    GtkWidget *item, *activeitem;

    assert(uc->ctrl->generic.type == CTRL_EDITBOX ||
	   uc->ctrl->generic.type == CTRL_LISTBOX);
    assert(uc->menu != NULL || uc->list != NULL);

    children = gtk_container_children(GTK_CONTAINER(uc->menu ? uc->menu :
						    uc->list));
    item = GTK_WIDGET(g_list_nth_data(children, index));
    g_list_free(children);

    if (uc->menu) {
	activeitem = gtk_menu_get_active(GTK_MENU(uc->menu));
	return item == activeitem;
    } else {
	return GTK_WIDGET_STATE(item) == GTK_STATE_SELECTED;
    }
}

void dlg_listbox_select(union control *ctrl, void *dlg, int index)
{
    struct dlgparam *dp = (struct dlgparam *)dlg;
    struct uctrl *uc = dlg_find_byctrl(dp, ctrl);

    assert(uc->ctrl->generic.type == CTRL_EDITBOX ||
	   uc->ctrl->generic.type == CTRL_LISTBOX);
    assert(uc->optmenu != NULL || uc->list != NULL);

    if (uc->optmenu) {
	gtk_option_menu_set_history(GTK_OPTION_MENU(uc->optmenu), index);
    } else {
	gtk_list_select_item(GTK_LIST(uc->list), index);
    }
}

void dlg_text_set(union control *ctrl, void *dlg, char const *text)
{
    struct dlgparam *dp = (struct dlgparam *)dlg;
    struct uctrl *uc = dlg_find_byctrl(dp, ctrl);

    assert(uc->ctrl->generic.type == CTRL_TEXT);
    assert(uc->text != NULL);

    gtk_label_set_text(GTK_LABEL(uc->text), text);
}

void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn)
{
    struct dlgparam *dp = (struct dlgparam *)dlg;
    struct uctrl *uc = dlg_find_byctrl(dp, ctrl);
    assert(uc->ctrl->generic.type == CTRL_FILESELECT);
    assert(uc->entry != NULL);
    gtk_entry_set_text(GTK_ENTRY(uc->entry), fn.path);
}

void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn)
{
    struct dlgparam *dp = (struct dlgparam *)dlg;
    struct uctrl *uc = dlg_find_byctrl(dp, ctrl);
    assert(uc->ctrl->generic.type == CTRL_FILESELECT);
    assert(uc->entry != NULL);
    strncpy(fn->path, gtk_entry_get_text(GTK_ENTRY(uc->entry)),
	    lenof(fn->path));
    fn->path[lenof(fn->path)-1] = '\0';
}

void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec fs)
{
    struct dlgparam *dp = (struct dlgparam *)dlg;
    struct uctrl *uc = dlg_find_byctrl(dp, ctrl);
    assert(uc->ctrl->generic.type == CTRL_FONTSELECT);
    assert(uc->entry != NULL);
    gtk_entry_set_text(GTK_ENTRY(uc->entry), fs.name);
}

void dlg_fontsel_get(union control *ctrl, void *dlg, FontSpec *fs)
{
    struct dlgparam *dp = (struct dlgparam *)dlg;
    struct uctrl *uc = dlg_find_byctrl(dp, ctrl);
    assert(uc->ctrl->generic.type == CTRL_FONTSELECT);
    assert(uc->entry != NULL);
    strncpy(fs->name, gtk_entry_get_text(GTK_ENTRY(uc->entry)),
	    lenof(fs->name));
    fs->name[lenof(fs->name)-1] = '\0';
}

/*
 * Bracketing a large set of updates in these two functions will
 * cause the front end (if possible) to delay updating the screen
 * until it's all complete, thus avoiding flicker.
 */
void dlg_update_start(union control *ctrl, void *dlg)
{
    /*
     * Apparently we can't do this at all in GTK. GtkCList supports
     * freeze and thaw, but not GtkList. Bah.
     */
}

void dlg_update_done(union control *ctrl, void *dlg)
{
    /*
     * Apparently we can't do this at all in GTK. GtkCList supports
     * freeze and thaw, but not GtkList. Bah.
     */
}

void dlg_set_focus(union control *ctrl, void *dlg)
{
    struct dlgparam *dp = (struct dlgparam *)dlg;
    struct uctrl *uc = dlg_find_byctrl(dp, ctrl);

    switch (ctrl->generic.type) {
      case CTRL_CHECKBOX:
      case CTRL_BUTTON:
        /* Check boxes and buttons get the focus _and_ get toggled. */
        gtk_widget_grab_focus(uc->toplevel);
        break;
      case CTRL_FILESELECT:
      case CTRL_FONTSELECT:
      case CTRL_EDITBOX:
        /* Anything containing an edit box gets that focused. */
        gtk_widget_grab_focus(uc->entry);
        break;
      case CTRL_RADIO:
        /*
         * Radio buttons: we find the currently selected button and
         * focus it.
         */
        {
            int i;
            for (i = 0; i < ctrl->radio.nbuttons; i++)
                if (gtk_toggle_button_get_active
                    (GTK_TOGGLE_BUTTON(uc->buttons[i]))) {
                    gtk_widget_grab_focus(uc->buttons[i]);
                }
        }
        break;
      case CTRL_LISTBOX:
        /*
         * If the list is really an option menu, we focus it.
         * Otherwise we tell it to focus one of its children, which
         * appears to do the Right Thing.
         */
        if (uc->optmenu) {
            gtk_widget_grab_focus(uc->optmenu);
        } else {
            assert(uc->list != NULL);
            gtk_container_focus(GTK_CONTAINER(uc->list), GTK_DIR_TAB_FORWARD);
        }
        break;
    }
}

/*
 * During event processing, you might well want to give an error
 * indication to the user. dlg_beep() is a quick and easy generic
 * error; dlg_error() puts up a message-box or equivalent.
 */
void dlg_beep(void *dlg)
{
    gdk_beep();
}

static void errmsg_button_clicked(GtkButton *button, gpointer data)
{
    gtk_widget_destroy(GTK_WIDGET(data));
}

static void set_transient_window_pos(GtkWidget *parent, GtkWidget *child)
{
    gint x, y, w, h, dx, dy;
    GtkRequisition req;
    gtk_window_set_position(GTK_WINDOW(child), GTK_WIN_POS_NONE);
    gtk_widget_size_request(GTK_WIDGET(child), &req);

    gdk_window_get_origin(GTK_WIDGET(parent)->window, &x, &y);
    gdk_window_get_size(GTK_WIDGET(parent)->window, &w, &h);

    /*
     * One corner of the transient will be offset inwards, by 1/4
     * of the parent window's size, from the corresponding corner
     * of the parent window. The corner will be chosen so as to
     * place the transient closer to the centre of the screen; this
     * should avoid transients going off the edge of the screen on
     * a regular basis.
     */
    if (x + w/2 < gdk_screen_width() / 2)
        dx = x + w/4;                  /* work from left edges */
    else
        dx = x + 3*w/4 - req.width;    /* work from right edges */
    if (y + h/2 < gdk_screen_height() / 2)
        dy = y + h/4;                  /* work from top edges */
    else
        dy = y + 3*h/4 - req.height;   /* work from bottom edges */
    gtk_widget_set_uposition(GTK_WIDGET(child), dx, dy);
}

void dlg_error_msg(void *dlg, char *msg)
{
    struct dlgparam *dp = (struct dlgparam *)dlg;
    GtkWidget *window, *hbox, *text, *ok;

    window = gtk_dialog_new();
    text = gtk_label_new(msg);
    gtk_misc_set_alignment(GTK_MISC(text), 0.0, 0.0);
    hbox = gtk_hbox_new(FALSE, 0);
    gtk_box_pack_start(GTK_BOX(hbox), text, FALSE, FALSE, 20);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox),
                       hbox, FALSE, FALSE, 20);
    gtk_widget_show(text);
    gtk_widget_show(hbox);
    gtk_window_set_title(GTK_WINDOW(window), "Error");
    gtk_label_set_line_wrap(GTK_LABEL(text), TRUE);
    ok = gtk_button_new_with_label("OK");
    gtk_box_pack_end(GTK_BOX(GTK_DIALOG(window)->action_area),
                     ok, FALSE, FALSE, 0);
    gtk_widget_show(ok);
    GTK_WIDGET_SET_FLAGS(ok, GTK_CAN_DEFAULT);
    gtk_window_set_default(GTK_WINDOW(window), ok);
    gtk_signal_connect(GTK_OBJECT(ok), "clicked",
                       GTK_SIGNAL_FUNC(errmsg_button_clicked), window);
    gtk_signal_connect(GTK_OBJECT(window), "destroy",
                       GTK_SIGNAL_FUNC(window_destroy), NULL);
    gtk_window_set_modal(GTK_WINDOW(window), TRUE);
    gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(dp->window));
    set_transient_window_pos(dp->window, window);
    gtk_widget_show(window);
    gtk_main();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -