static void
e_mapi_config_ui_extension_shell_view_toggled_cb (EShellView *shell_view,
						  EMapiConfigUIExtension *ui_ext)
{
	EShellViewClass *shell_view_class;
	EShellWindow *shell_window;
	GtkUIManager *ui_manager;
	gpointer key = NULL, value = NULL;
	const gchar *ui_def;
	gboolean is_active, need_update;

	g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
	g_return_if_fail (ui_ext != NULL);

	shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
	g_return_if_fail (shell_view_class != NULL);

	shell_window = e_shell_view_get_shell_window (shell_view);
	ui_manager = e_shell_window_get_ui_manager (shell_window);

	need_update = ui_ext->current_ui_id != 0;
	if (ui_ext->current_ui_id) {
		gtk_ui_manager_remove_ui (ui_manager, ui_ext->current_ui_id);
		ui_ext->current_ui_id = 0;
	}

	is_active = e_shell_view_is_active (shell_view);
	if (!is_active) {
		if (need_update)
			gtk_ui_manager_ensure_update (ui_manager);

		return;
	}

	if (!g_hash_table_lookup_extended (ui_ext->ui_definitions, shell_view_class->ui_manager_id, &key, &value)) {
		gchar *ui_definition = NULL;

		e_mapi_config_utils_init_ui (shell_view, shell_view_class->ui_manager_id, &ui_definition);
		g_hash_table_insert (ui_ext->ui_definitions, g_strdup (shell_view_class->ui_manager_id), ui_definition);
	}

	ui_def = g_hash_table_lookup (ui_ext->ui_definitions, shell_view_class->ui_manager_id);
	if (ui_def) {
		GError *error = NULL;

		ui_ext->current_ui_id = gtk_ui_manager_add_ui_from_string (ui_manager, ui_def, -1, &error);
		need_update = TRUE;

		if (error) {
			g_warning ("%s: Failed to add ui definition: %s", G_STRFUNC, error->message);
			g_error_free (error);
		}
	}

	if (need_update)
		gtk_ui_manager_ensure_update (ui_manager);
}
Beispiel #2
0
/*  Remove a data plugin page from a window. */
void
gnc_embedded_window_close_page (GncEmbeddedWindow *window,
                                GncPluginPage *page)
{
    GncEmbeddedWindowPrivate *priv;

    g_return_if_fail (GNC_IS_EMBEDDED_WINDOW (window));
    g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
    priv = GNC_EMBEDDED_WINDOW_GET_PRIVATE(window);
    g_return_if_fail (priv->page == page);

    ENTER("window %p, page %p", window, page);

    if (!page->notebook_page)
    {
        LEAVE("no displayed widget");
        return;
    }

    gtk_container_remove (GTK_CONTAINER(window), GTK_WIDGET(page->notebook_page));
    priv->page = NULL;
    gnc_plugin_page_removed (page);

    gnc_plugin_page_unmerge_actions (page, window->ui_merge);
    gtk_ui_manager_ensure_update (window->ui_merge);

    gnc_plugin_page_destroy_widget (page);
    g_object_unref(page);
    LEAVE(" ");
}
Beispiel #3
0
/**
 * Update the clickable list of closed accounts and target
 * accounts to move a transaction, in menu.
 *
 * \param
 * \return FALSE
 * */
gboolean gsb_menu_update_accounts_in_menus ( void )
{
    GSList *list_tmp;
    GtkActionGroup * action_group;

    if ( move_to_account_merge_id != -1 )
        gtk_ui_manager_remove_ui ( ui_manager, move_to_account_merge_id );

    move_to_account_merge_id = gtk_ui_manager_new_merge_id ( ui_manager );
    action_group = gtk_action_group_new ( "Group3" );

    /* create the closed accounts and accounts in the menu to move a transaction */
    list_tmp = gsb_data_account_get_list_accounts ();

    while ( list_tmp )
    {
        gint i;

        i = gsb_data_account_get_no_account ( list_tmp -> data );

        if ( !gsb_data_account_get_closed_account ( i ) )
        {
            gchar *tmp_name;
            gchar *account_name;
            GtkAction *action;

            tmp_name = g_strdup_printf ( "MoveToAccount%d", i );
            account_name = gsb_data_account_get_name ( i );
            if ( !account_name )
                account_name = _("Unnamed account");

            action = gtk_action_new ( tmp_name, account_name, "", "" );

            if ( gsb_gui_navigation_get_current_account () == i )
                gtk_action_set_sensitive ( action, FALSE );

            gtk_action_group_add_action ( action_group, action );
            g_signal_connect ( action,
                        "activate",
                        G_CALLBACK ( move_selected_operation_to_account_nb ),
                        GINT_TO_POINTER ( i ) );

            gtk_ui_manager_add_ui ( ui_manager,
                        move_to_account_merge_id,
                        "/menubar/EditMenu/MoveToAnotherAccount/",
                        tmp_name,
                        tmp_name,
                        GTK_UI_MANAGER_MENUITEM,
                        FALSE );
            g_free ( tmp_name );
        }

        list_tmp = list_tmp -> next;
    }

    gtk_ui_manager_insert_action_group ( ui_manager, action_group, 2 );
    gtk_ui_manager_ensure_update ( ui_manager );

    return FALSE;
}
Beispiel #4
0
static void
usage_view_activate (PlannerView *view)
{
	PlannerUsageViewPriv *priv;
	gchar		     *filename;

	priv = PLANNER_USAGE_VIEW (view)->priv;

	priv->actions = gtk_action_group_new ("TimeTableView");
	gtk_action_group_set_translation_domain (priv->actions, GETTEXT_PACKAGE);

	gtk_action_group_add_actions (priv->actions, entries, G_N_ELEMENTS (entries), view);

	gtk_ui_manager_insert_action_group (priv->ui_manager, priv->actions, 0);
	filename = mrp_paths_get_ui_dir ("time-table-view.ui");
	priv->merged_id = gtk_ui_manager_add_ui_from_file (priv->ui_manager,
							   filename,
							   NULL);
	g_free (filename);
	gtk_ui_manager_ensure_update (priv->ui_manager);

        usage_view_update_zoom_sensitivity (view);

	gtk_widget_grab_focus (priv->tree);
}
Beispiel #5
0
static void
windows_menu_display_reorder (GimpContainer *container,
                              GimpDisplay   *display,
                              gint           new_index,
                              GimpUIManager *manager)
{
  gint n_display = gimp_container_get_n_children (container);
  gint i;

  for (i = new_index; i < n_display; i++)
    {
      GimpObject *d = gimp_container_get_child_by_index (container, i);

      windows_menu_display_remove (container, GIMP_DISPLAY (d), manager);
    }

  /* If I don't ensure the menu items are effectively removed, adding
   * the same ones may simply cancel the effect of the removal, hence
   * losing the menu reordering.
   */
  gtk_ui_manager_ensure_update (GTK_UI_MANAGER (manager));

  for (i = new_index; i < n_display; i++)
    {
      GimpObject *d = gimp_container_get_child_by_index (container, i);

      windows_menu_display_add (container, GIMP_DISPLAY (d), manager);
    }
}
static void
composer_setup_charset_menu (EMsgComposer *composer)
{
	EHTMLEditor *editor;
	GtkUIManager *ui_manager;
	const gchar *path;
	GList *list;
	guint merge_id;

	editor = e_msg_composer_get_editor (composer);
	ui_manager = e_html_editor_get_ui_manager (editor);
	path = "/main-menu/options-menu/charset-menu";
	merge_id = gtk_ui_manager_new_merge_id (ui_manager);

	list = gtk_action_group_list_actions (composer->priv->charset_actions);
	list = g_list_sort (list, (GCompareFunc) e_action_compare_by_label);

	while (list != NULL) {
		GtkAction *action = list->data;

		gtk_ui_manager_add_ui (
			ui_manager, merge_id, path,
			gtk_action_get_name (action),
			gtk_action_get_name (action),
			GTK_UI_MANAGER_AUTO, FALSE);

		list = g_list_delete_link (list, list);
	}

	gtk_ui_manager_ensure_update (ui_manager);
}
Beispiel #7
0
G_MODULE_EXPORT void
plugin_init (PlannerPlugin *plugin)
{
	PlannerPluginPriv *priv;
	GtkUIManager      *ui;
	gchar             *filename;

	priv = g_new0 (PlannerPluginPriv, 1);
	plugin->priv = priv;

	priv->actions = gtk_action_group_new ("HTML plugin actions");
	gtk_action_group_set_translation_domain (priv->actions, GETTEXT_PACKAGE);

	gtk_action_group_add_actions (priv->actions,
				      action_entries,
				      G_N_ELEMENTS (action_entries),
				      plugin);

	ui = planner_window_get_ui_manager (plugin->main_window);
	gtk_ui_manager_insert_action_group (ui, priv->actions, 0);

	filename = mrp_paths_get_ui_dir ("html-plugin.ui");
	gtk_ui_manager_add_ui_from_file (ui, filename, NULL);
	g_free (filename);

	gtk_ui_manager_ensure_update (ui);
}
Beispiel #8
0
/** Create a new gnc embedded window plugin. */
GncEmbeddedWindow *
gnc_embedded_window_new (const gchar *action_group_name,
                         GtkActionEntry *action_entries,
                         gint n_action_entries,
                         const gchar *ui_filename,
                         GtkWidget *enclosing_win,
                         gboolean add_accelerators,
                         gpointer user_data)
{
    GncEmbeddedWindowPrivate *priv;
    GncEmbeddedWindow *window;
    gchar *ui_fullname;
    GError *error = NULL;
    guint merge_id;

    ENTER("group %s, first %p, num %d, ui file %s, parent %p, add accelerators %d, user data %p",
          action_group_name, action_entries, n_action_entries, ui_filename,
          enclosing_win, add_accelerators, user_data);
    window = g_object_new (GNC_TYPE_EMBEDDED_WINDOW, NULL);
    priv = GNC_EMBEDDED_WINDOW_GET_PRIVATE(window);

    /* Determine the full pathname of the ui file */
    ui_fullname = gnc_filepath_locate_ui_file (ui_filename);
    g_return_val_if_fail (ui_fullname != NULL, NULL);

    priv->parent_window = enclosing_win;

    /* Create menu and toolbar information */
    priv->action_group = gtk_action_group_new (action_group_name);
    gnc_gtk_action_group_set_translation_domain(priv->action_group, GETTEXT_PACKAGE);
    gtk_action_group_add_actions (priv->action_group, action_entries,
                                  n_action_entries, user_data);
    gtk_ui_manager_insert_action_group (window->ui_merge, priv->action_group, 0);
    merge_id = gtk_ui_manager_add_ui_from_file (window->ui_merge, ui_fullname,
               &error);

    /* Error checking */
    g_assert(merge_id || error);
    if (error)
    {
        g_critical("Failed to load ui file.\n  Filename %s\n  Error %s",
                   ui_fullname, error->message);
        g_error_free(error);
        g_free(ui_fullname);
        LEAVE("window %p", window);
        return window;
    }

    /* Add accelerators (if wanted) */
    if (add_accelerators)
        gtk_window_add_accel_group (GTK_WINDOW(enclosing_win),
                                    gtk_ui_manager_get_accel_group(window->ui_merge));

    gtk_ui_manager_ensure_update (window->ui_merge);
    g_free(ui_fullname);
    LEAVE("window %p", window);
    return window;
}
Beispiel #9
0
static void
killswitch_state_changed (GObject    *gobject,
                          GParamSpec *pspec,
                          gpointer    user_data)
{
	GObject *object;
	BluetoothApplet *applet = BLUETOOTH_APPLET (gobject);
	BluetoothKillswitchState state = bluetooth_applet_get_killswitch_state (applet);
	gboolean sensitive = TRUE;
	gboolean bstate = FALSE;
	const char *label, *status_label;

	if (state == BLUETOOTH_KILLSWITCH_STATE_NO_ADAPTER) {
		object = gtk_builder_get_object (xml, "bluetooth-applet-popup");
		gtk_menu_popdown (GTK_MENU (object));
		update_icon_visibility ();
		return;
	}

	if (state == BLUETOOTH_KILLSWITCH_STATE_SOFT_BLOCKED) {
		label = N_("Turn on Bluetooth");
		status_label = N_("Bluetooth: Off");
		bstate = FALSE;
	} else if (state == BLUETOOTH_KILLSWITCH_STATE_UNBLOCKED) {
		label = N_("Turn off Bluetooth");
		status_label = N_("Bluetooth: On");
		bstate = TRUE;
	} else if (state == BLUETOOTH_KILLSWITCH_STATE_HARD_BLOCKED) {
		sensitive = FALSE;
		label = NULL;
		status_label = N_("Bluetooth: Disabled");
	} else {
		g_assert_not_reached ();
	}

	object = gtk_builder_get_object (xml, "killswitch-label");
	gtk_action_set_label (GTK_ACTION (object), _(status_label));
	gtk_action_set_visible (GTK_ACTION (object), TRUE);

	object = gtk_builder_get_object (xml, "killswitch");
	gtk_action_set_visible (GTK_ACTION (object), sensitive);
	gtk_action_set_label (GTK_ACTION (object), _(label));

	if (sensitive != FALSE) {
		gtk_action_set_label (GTK_ACTION (object), _(label));
		g_object_set_data (object, "bt-active", GINT_TO_POINTER (bstate));
	}

	object = gtk_builder_get_object (xml, "bluetooth-applet-ui-manager");
	gtk_ui_manager_ensure_update (GTK_UI_MANAGER (object));

	update_icon_visibility ();
}
static void
call_plugin_deactivate (PlumaPlugin *plugin,
			PlumaWindow *window)
{
	pluma_plugin_deactivate (plugin, window);

	/* ensure update of ui manager, because we suspect it does something
	   with expected static strings in the type module (when unloaded the
	   strings don't exist anymore, and ui manager updates in an idle
	   func) */
	gtk_ui_manager_ensure_update (pluma_window_get_ui_manager (window));
}
Beispiel #11
0
int
clip_GTK_UIMANAGERENSUREUPDATE(ClipMachine * ClipMachineMemory)
{
   C_object *cmanager = _fetch_co_arg(ClipMachineMemory);

   CHECKARG2(1, MAP_type_of_ClipVarType, NUMERIC_type_of_ClipVarType);
   CHECKCOBJ(cmanager, GTK_IS_UI_MANAGER(cmanager->object));

   gtk_ui_manager_ensure_update(GTK_UI_MANAGER(cmanager->object));

   return 0;
 err:
   return 1;
}
static void
empathy_mic_menu_clean (EmpathyMicMenu *self)
{
  EmpathyMicMenuPrivate *priv = self->priv;
  GtkUIManager *ui_manager;

  if (priv->ui_id == 0)
    return;

  ui_manager = empathy_call_window_get_ui_manager (priv->window);

  gtk_ui_manager_remove_ui (ui_manager, priv->ui_id);
  gtk_ui_manager_ensure_update (ui_manager);
  priv->ui_id = 0;
}
Beispiel #13
0
static void
task_view_activate (PlannerView *view)
{
    PlannerTaskViewPriv *priv;
    gboolean             show_critical;
    gboolean             show_nostd_days;
    gchar               *filename;

    priv = PLANNER_TASK_VIEW (view)->priv;

    priv->actions = gtk_action_group_new ("TaskView");
    gtk_action_group_set_translation_domain (priv->actions, GETTEXT_PACKAGE);

    gtk_action_group_add_actions (priv->actions, entries,
                                  G_N_ELEMENTS (entries),
                                  view);
    gtk_action_group_add_toggle_actions (priv->actions, toggle_entries,
                                         G_N_ELEMENTS (toggle_entries),
                                         view);

    gtk_ui_manager_insert_action_group (priv->ui_manager, priv->actions, 0);
    filename = mrp_paths_get_ui_dir ("task-view.ui");
    priv->merged_id = gtk_ui_manager_add_ui_from_file (priv->ui_manager,
                      filename,
                      NULL);
    g_free (filename);
    gtk_ui_manager_ensure_update (priv->ui_manager);

    /* Set the initial UI state. */
    show_critical =   planner_conf_get_bool (CRITICAL_PATH_KEY, NULL);
    show_nostd_days = planner_conf_get_bool (NOSTDDAYS_PATH_KEY, NULL);
    planner_task_tree_set_highlight_critical (PLANNER_TASK_TREE (priv->tree),
            show_critical);
    planner_task_tree_set_nonstandard_days (PLANNER_TASK_TREE (priv->tree),
                                            show_nostd_days);

    gtk_toggle_action_set_active (
        GTK_TOGGLE_ACTION (gtk_action_group_get_action (priv->actions, "HighlightCriticalTasks")),
        show_critical);

    gtk_toggle_action_set_active (
        GTK_TOGGLE_ACTION (gtk_action_group_get_action (priv->actions, "NonstandardDays")),
        show_nostd_days);

    task_view_selection_changed_cb (PLANNER_TASK_TREE (priv->tree), view);

    gtk_widget_grab_focus (priv->tree);
}
Beispiel #14
0
static void
build_menu (GaleonEncodingMenu *menu, GList *recent, GList *related)
{
	GaleonEncodingMenuPrivate *p = menu->priv;

	/* clear the menu */
	if (p->merge_id > 0)
	{
		gtk_ui_manager_remove_ui (p->merge, p->merge_id);
		gtk_ui_manager_ensure_update (p->merge);
	}

	/* build the new menu */
	p->merge_id = gtk_ui_manager_new_merge_id (p->merge);

	gtk_ui_manager_add_ui (p->merge, p->merge_id,
			       ENCODING_PLACEHOLDER_PATH,
			       "ViewEncodingAutomaticItem",
			       "ViewEncodingAutomatic",
			       GTK_UI_MANAGER_MENUITEM, FALSE);

	gtk_ui_manager_add_ui (p->merge, p->merge_id,
			       ENCODING_PLACEHOLDER_PATH,
			       "Sep1Item", "Sep1",
			       GTK_UI_MANAGER_SEPARATOR, FALSE);

	g_list_foreach (recent, (GFunc) add_menu_item, menu);

	gtk_ui_manager_add_ui (p->merge, p->merge_id,
			       ENCODING_PLACEHOLDER_PATH,
			       "Sep2Item", "Sep2",
			       GTK_UI_MANAGER_SEPARATOR, FALSE);

	g_list_foreach (related, (GFunc) add_menu_item, menu);

	gtk_ui_manager_add_ui (p->merge, p->merge_id,
			       ENCODING_PLACEHOLDER_PATH,
			       "Sep3Item", "Sep3",
			       GTK_UI_MANAGER_SEPARATOR, FALSE);

	gtk_ui_manager_add_ui (p->merge, p->merge_id,
			       ENCODING_PLACEHOLDER_PATH,
			       "ViewEncodingOtherItem",
			       "ViewEncodingOther",
			       GTK_UI_MANAGER_MENUITEM, FALSE);
}
Beispiel #15
0
PUSS_EXPORT void  puss_plugin_destroy(void* self) {
	GtkUIManager* ui_mgr;

	if( !g_self )
		return;

	ui_mgr = GTK_UI_MANAGER(gtk_builder_get_object(g_self->app->get_ui_builder(), "main_ui_manager"));
	gtk_ui_manager_remove_ui(ui_mgr, g_self->favory_merge_id);
	gtk_ui_manager_remove_ui(ui_mgr, g_self->merge_id);
	gtk_ui_manager_remove_action_group(ui_mgr, g_self->action_group);
	gtk_ui_manager_ensure_update(ui_mgr);

	g_object_unref(g_self->action_group);
	g_list_free(g_self->favory_language_list);

	g_free(g_self);
	g_self = 0;
}
Beispiel #16
0
static void
action_set_bold (GtkUIManager *manager, GtkAction *action, const char *path)
{
	GtkWidget *widget;
	char *str;
	const char *label;

	/* That sucks, but otherwise the widget might not exist */
	gtk_ui_manager_ensure_update (manager);

	widget = gtk_ui_manager_get_widget (manager, path);
	g_assert (widget);

	label = gtk_action_get_label (action);
	str = g_strdup_printf ("<b>%s</b>", label);
	gtk_label_set_markup (GTK_LABEL (gtk_bin_get_child (GTK_BIN (widget))), str);
	g_free (str);
}
Beispiel #17
0
G_MODULE_EXPORT void
plugin_init (PlannerPlugin *plugin)
{
	PlannerPluginPriv *priv;
	GtkUIManager      *ui;
	gint               i = -1;
	gchar             *filename;

	priv = g_new0 (PlannerPluginPriv, 1);
	plugin->priv = priv;

	gda_init (PACKAGE, VERSION, 0, NULL);

	g_object_set_data (G_OBJECT (plugin->main_window),
			   PROJECT_ID,
			   GINT_TO_POINTER (i));
	g_object_set_data (G_OBJECT (plugin->main_window),
			   "sql-plugin-revision",
			   GINT_TO_POINTER (i));

	g_object_set_data (G_OBJECT (plugin->main_window),
			   "sql-plugin",
			   plugin);

	/* Create the actions, get the ui manager and merge the whole */
	priv->actions = gtk_action_group_new ("SQL plugin actions");
	gtk_action_group_set_translation_domain (priv->actions, GETTEXT_PACKAGE);

	gtk_action_group_add_actions (priv->actions,
				      entries,
				      G_N_ELEMENTS (entries),
				      plugin);

	ui = planner_window_get_ui_manager (plugin->main_window);
	gtk_ui_manager_insert_action_group (ui, priv->actions, 0);

	filename = mrp_paths_get_ui_dir ("sql-plugin.ui");
	gtk_ui_manager_add_ui_from_file (ui, filename, NULL);
	g_free (filename);

	gtk_ui_manager_ensure_update (ui);
}
Beispiel #18
0
/* Helper for plugin_ui_hook_merge_ui() */
static void
plugin_ui_hook_merge_foreach (GtkUIManager *manager,
                              const gchar *ui_definition,
                              GHashTable *hash_table)
{
	guint merge_id;
	GError *error = NULL;

	/* Merge the UI definition into the manager. */
	merge_id = gtk_ui_manager_add_ui_from_string (
		manager, ui_definition, -1, &error);
	gtk_ui_manager_ensure_update (manager);
	if (error != NULL) {
		g_warning ("%s", error->message);
		g_error_free (error);
	}

	/* Merge ID will be 0 on error, which is what we want. */
	g_hash_table_insert (hash_table, manager, GUINT_TO_POINTER (merge_id));
}
/** Add one extension item to the UI manager.  This function creates a
 *  per-callback data structure for easy access to the opaque Scheme
 *  data block in the callback.  It then adds the action to the UI
 *  manager.
 *
 *  @param ext_info The extension info data block.
 *
 *  @param per_window The per-window data block maintained by the
 *  plugin. */
static void
gnc_menu_additions_menu_setup_one (ExtensionInfo *ext_info,
                                   GncPluginMenuAdditionsPerWindow *per_window)
{
    GncMainWindowActionData *cb_data;

    DEBUG( "Adding %s/%s [%s] as [%s]", ext_info->path, ext_info->ae.label,
           ext_info->ae.name, ext_info->typeStr );

    cb_data = g_new0 (GncMainWindowActionData, 1);
    cb_data->window = per_window->window;
    cb_data->data = ext_info->extension;

    if (ext_info->type == GTK_UI_MANAGER_MENUITEM)
        ext_info->ae.callback = (GCallback)gnc_plugin_menu_additions_action_cb;

    gtk_action_group_add_actions_full(per_window->group, &ext_info->ae, 1,
                                      cb_data, g_free);
    gtk_ui_manager_add_ui(per_window->ui_manager, per_window->merge_id,
                          ext_info->path, ext_info->ae.label, ext_info->ae.name,
                          ext_info->type, FALSE);
    gtk_ui_manager_ensure_update(per_window->ui_manager);
}
Beispiel #20
0
static void
mail_shell_view_toggled (EShellView *shell_view)
{
	EMailShellViewPrivate *priv;
	EShellWindow *shell_window;
	GtkUIManager *ui_manager;
	const gchar *basename;
	gboolean view_is_active;

	priv = E_MAIL_SHELL_VIEW_GET_PRIVATE (shell_view);

	shell_window = e_shell_view_get_shell_window (shell_view);
	ui_manager = e_shell_window_get_ui_manager (shell_window);
	view_is_active = e_shell_view_is_active (shell_view);
	basename = E_MAIL_READER_UI_DEFINITION;

	if (view_is_active && priv->merge_id == 0) {
		EMailView *mail_view;

		priv->merge_id = e_load_ui_manager_definition (
			ui_manager, basename);
		mail_view = e_mail_shell_content_get_mail_view (
			priv->mail_shell_content);
		e_mail_reader_create_charset_menu (
			E_MAIL_READER (mail_view),
			ui_manager, priv->merge_id);
	} else if (!view_is_active && priv->merge_id != 0) {
		gtk_ui_manager_remove_ui (ui_manager, priv->merge_id);
		gtk_ui_manager_ensure_update (ui_manager);
		priv->merge_id = 0;
	}

	/* Chain up to parent's toggled() method. */
	E_SHELL_VIEW_CLASS (e_mail_shell_view_parent_class)->
		toggled (shell_view);
}
Beispiel #21
0
static void
plugin_ui_hook_register_manager (EPluginUIHook *hook,
                                 GtkUIManager *manager,
                                 const gchar *ui_definition,
                                 gpointer user_data)
{
	EPlugin *plugin;
	EPluginUIInitFunc func;
	guint merge_id = 0;

	plugin = ((EPluginHook *) hook)->plugin;
	func = e_plugin_get_symbol (plugin, E_PLUGIN_UI_INIT_FUNC);

	/* Pass the manager and user_data to the plugin's e_plugin_ui_init()
	 * function (if it defined one).  The plugin should install whatever
	 * GtkActions and GtkActionGroups are neccessary to implement the
	 * action names in its UI definition. */
	if (func != NULL && !func (manager, user_data))
		return;

	if (plugin->enabled) {
		GError *error = NULL;

		/* Merge the UI definition into the manager. */
		merge_id = gtk_ui_manager_add_ui_from_string (
			manager, ui_definition, -1, &error);
		gtk_ui_manager_ensure_update (manager);
		if (error != NULL) {
			g_warning ("%s", error->message);
			g_error_free (error);
		}
	}

	/* Save merge ID's for later use. */
	plugin_ui_registry_insert (hook, manager, merge_id);
}
Beispiel #22
0
GtkWidget *editor_new(const gchar *title, EDITOR *e)
{
	GtkActionGroup *action_group;
	GtkUIManager *manager;
	GtkWidget *editor;
	GError *error = NULL;

	editor = gtkhtml_editor_new();
	e->window = editor;
	e->html_widget =
	    GTK_WIDGET(gtkhtml_editor_get_html(GTKHTML_EDITOR(editor)));
	gtk_window_set_title(GTK_WINDOW(editor), title);

	set_window_icon(GTK_WINDOW(editor));

	manager = gtkhtml_editor_get_ui_manager(GTKHTML_EDITOR(editor));
	if (e->type == STUDYPAD_EDITOR)
		gtk_ui_manager_add_ui_from_string(manager, file_ui, -1,
						  &error);
	else
		gtk_ui_manager_add_ui_from_string(manager, note_file_ui,
						  -1, &error);

	handle_error(&error);

	gtk_ui_manager_add_ui_from_string(manager, view_ui, -1, &error);
	handle_error(&error);

	if (e->type == STUDYPAD_EDITOR)
		gtk_ui_manager_add_ui_from_string(manager,
						  main_ui_studypad, -1,
						  &error);
	else
		gtk_ui_manager_add_ui_from_string(manager, main_ui_note,
						  -1, &error);

	handle_error(&error);

	action_group = gtk_action_group_new("file");
	gtk_action_group_set_translation_domain(action_group,
						GETTEXT_PACKAGE);
	gtk_action_group_add_actions(action_group, file_entries,
				     G_N_ELEMENTS(file_entries), e);
	gtk_ui_manager_insert_action_group(manager, action_group, 0);

	action_group = gtk_action_group_new("view");
	gtk_action_group_set_translation_domain(action_group,
						GETTEXT_PACKAGE);
	gtk_action_group_add_actions(action_group, view_entries,
				     G_N_ELEMENTS(view_entries), editor);
	gtk_ui_manager_insert_action_group(manager, action_group, 0);

	action_group = gtk_action_group_new("main");
	gtk_action_group_set_translation_domain(action_group,
						GETTEXT_PACKAGE);
	gtk_action_group_add_actions(action_group, main_entries,
				     G_N_ELEMENTS(main_entries), e);
	gtk_ui_manager_insert_action_group(manager, action_group, 0);

	action_group = gtk_action_group_new("context-menu");
	gtk_action_group_set_translation_domain(action_group,
						GETTEXT_PACKAGE);
	gtk_action_group_add_actions(action_group, test_entries,
				     G_N_ELEMENTS(test_entries), e);
	gtk_ui_manager_insert_action_group(manager, action_group, 0);

	gtk_ui_manager_ensure_update(manager);
	gtk_widget_show(editor);

	gtkhtml_editor_drop_undo(GTKHTML_EDITOR(e->window));
	gtkhtml_editor_set_changed(GTKHTML_EDITOR(e->window), FALSE);

	g_signal_connect(editor, "delete-event",
			 G_CALLBACK(app_delete_cb), (EDITOR *)e);
	return editor;
}
static void
toolbar_visibility_refresh (EggEditableToolbar *etoolbar)
{
  EggEditableToolbarPrivate *priv = etoolbar->priv;
  gint n_toolbars, n_items, i, j, k;
  GtkToggleAction *action;
  GList *list;
  GString *string;
  gboolean showing;
  char action_name[40];
  char *action_label;
  char *tmp;

  if (priv == NULL || priv->model == NULL || priv->manager == NULL ||
      priv->visibility_paths == NULL || priv->actions == NULL)
    {
      return;
    }

  if (priv->visibility_actions == NULL)
    {
      priv->visibility_actions = g_ptr_array_new ();
    }

  if (priv->visibility_id != 0)
    {
      gtk_ui_manager_remove_ui (priv->manager, priv->visibility_id);
    }

  priv->visibility_id = gtk_ui_manager_new_merge_id (priv->manager);

  showing = gtk_widget_get_visible (GTK_WIDGET (etoolbar));

  n_toolbars = egg_toolbars_model_n_toolbars (priv->model);
  for (i = 0; i < n_toolbars; i++)
    {
      string = g_string_sized_new (0);
      n_items = egg_toolbars_model_n_items (priv->model, i);
      for (k = 0, j = 0; j < n_items; j++)
        {
          GValue value = { 0, };
          GtkAction *action;
          const char *name;

          name = egg_toolbars_model_item_nth (priv->model, i, j);
          if (name == NULL) continue;
          action = find_action (etoolbar, name);
          if (action == NULL) continue;

          g_value_init (&value, G_TYPE_STRING);
          g_object_get_property (G_OBJECT (action), "label", &value);
          name = g_value_get_string (&value);
          if (name == NULL)
	    {
		g_value_unset (&value);
		continue;
	    }
	  k += g_utf8_strlen (name, -1) + 2;
	  if (j > 0)
	    {
	      g_string_append (string, ", ");
	      if (j > 1 && k > 25)
		{
		  g_value_unset (&value);
		  break;
		}
	    }
	  g_string_append (string, name);
	  g_value_unset (&value);
	}
      if (j < n_items)
        {
	  g_string_append (string, " ...");
        }

      tmp = g_string_free (string, FALSE);
      for (j = 0, k = 0; tmp[j]; j++)
      {
	if (tmp[j] == '_') continue;
	tmp[k] = tmp[j];
	k++;
      }
      tmp[k] = 0;
      /* Translaters: This string is for a toggle to display a toolbar.
       * The name of the toolbar is automatically computed from the widgets
       * on the toolbar, and is placed at the %s. Note the _ before the %s
       * which is used to add mnemonics. We know that this is likely to
       * produce duplicates, but don't worry about it. If your language
       * normally has a mnemonic at the start, please use the _. If not,
       * please remove. */
      action_label = g_strdup_printf (_("Show “_%s”"), tmp);
      g_free (tmp);

      sprintf(action_name, "ToolbarToggle%d", i);

      if (i >= priv->visibility_actions->len)
        {
	  action = gtk_toggle_action_new (action_name, action_label, NULL, NULL);
	  g_ptr_array_add (priv->visibility_actions, action);
	  g_signal_connect_object (action, "toggled",
				   G_CALLBACK (toggled_visibility_cb),
				   etoolbar, 0);
	  gtk_action_group_add_action (priv->actions, GTK_ACTION (action));
	}
      else
        {
	  action = g_ptr_array_index (priv->visibility_actions, i);
	  g_object_set (action, "label", action_label, NULL);
        }

      gtk_action_set_visible (GTK_ACTION (action), (egg_toolbars_model_get_flags (priv->model, i)
						    & EGG_TB_MODEL_NOT_REMOVABLE) == 0);
      gtk_action_set_sensitive (GTK_ACTION (action), showing);
      gtk_toggle_action_set_active (action, gtk_widget_get_visible
				    (get_dock_nth (etoolbar, i)));

      for (list = priv->visibility_paths; list != NULL; list = g_list_next (list))
        {
	  gtk_ui_manager_add_ui (priv->manager, priv->visibility_id,
				 (const char *)list->data, action_name, action_name,
				 GTK_UI_MANAGER_MENUITEM, FALSE);
	}

      g_free (action_label);
    }

  gtk_ui_manager_ensure_update (priv->manager);

  while (i < priv->visibility_actions->len)
    {
      action = g_ptr_array_index (priv->visibility_actions, i);
      g_ptr_array_remove_index_fast (priv->visibility_actions, i);
      gtk_action_group_remove_action (priv->actions, GTK_ACTION (action));
      i++;
    }
}
Beispiel #24
0
/* Helper for gtkhtml_editor_update_context() */
static void
editor_spell_checkers_foreach (GtkhtmlSpellChecker *checker,
                               GtkhtmlEditor *editor)
{
	const GtkhtmlSpellLanguage *language;
	const gchar *language_code;
	GtkActionGroup *action_group;
	GtkUIManager *manager;
	GtkHTML *html;
	GList *list;
	gchar *path;
	gchar *word;
	gint count = 0;
	guint merge_id;

	language = gtkhtml_spell_checker_get_language (checker);
	language_code = gtkhtml_spell_language_get_code (language);

	html = gtkhtml_editor_get_html (editor);
	word = html_engine_get_spell_word (html->engine);
	list = gtkhtml_spell_checker_get_suggestions (checker, word, -1);

	manager = gtkhtml_editor_get_ui_manager (editor);
	action_group = editor->priv->suggestion_actions;
	merge_id = editor->priv->spell_suggestions_merge_id;

	path = g_strdup_printf (
		"/context-menu/context-spell-suggest/"
		"context-spell-suggest-%s-menu", language_code);

	while (list != NULL) {
		gchar *suggestion = list->data;
		gchar *action_name;
		gchar *action_label;
		GtkAction *action;
		GtkWidget *child;
		GSList *proxies;

		/* Action name just needs to be unique. */
		action_name = g_strdup_printf (
			"suggest-%s-%d", language_code, count++);

		action_label = g_markup_printf_escaped (
			"<b>%s</b>", suggestion);

		action = gtk_action_new (
			action_name, action_label, NULL, NULL);

		g_object_set_data_full (
			G_OBJECT (action), "word",
			g_strdup (suggestion), g_free);

		g_signal_connect (
			action, "activate", G_CALLBACK (
			action_context_spell_suggest_cb), editor);

		gtk_action_group_add_action (action_group, action);

		gtk_ui_manager_add_ui (
			manager, merge_id, path,
			action_name, action_name,
			GTK_UI_MANAGER_AUTO, FALSE);

		/* XXX GtkAction offers no supports for Pango markup,
		 *     so we have to manually set "use-markup" on the
		 *     child of the proxy widget. */
		gtk_ui_manager_ensure_update (manager);
		proxies = gtk_action_get_proxies (action);
		child = gtk_bin_get_child (proxies->data);
		g_object_set (child, "use-markup", TRUE, NULL);

		g_free (suggestion);
		g_free (action_name);
		g_free (action_label);

		list = g_list_delete_link (list, list);
	}

	g_free (path);
	g_free (word);
}
Beispiel #25
0
static void
editor_inline_spelling_suggestions (GtkhtmlEditor *editor,
                                    GtkhtmlSpellChecker *checker)
{
	GtkActionGroup *action_group;
	GtkUIManager *manager;
	GtkHTML *html;
	GList *list;
	const gchar *path;
	gchar *word;
	guint count = 0;
	guint length;
	guint merge_id;
	guint threshold;

	html = gtkhtml_editor_get_html (editor);
	word = html_engine_get_spell_word (html->engine);
	list = gtkhtml_spell_checker_get_suggestions (checker, word, -1);

	path = "/context-menu/context-spell-suggest/";
	manager = gtkhtml_editor_get_ui_manager (editor);
	action_group = editor->priv->suggestion_actions;
	merge_id = editor->priv->spell_suggestions_merge_id;

	/* Calculate how many suggestions to put directly in the
	 * context menu.  The rest will go in a secondary menu. */
	length = g_list_length (list);
	if (length <= MAX_LEVEL1_SUGGESTIONS)
		threshold = length;
	else if (length - MAX_LEVEL1_SUGGESTIONS < MIN_LEVEL2_SUGGESTIONS)
		threshold = length;
	else
		threshold = MAX_LEVEL1_SUGGESTIONS;

	while (list != NULL) {
		gchar *suggestion = list->data;
		gchar *action_name;
		gchar *action_label;
		GtkAction *action;
		GtkWidget *child;
		GSList *proxies;

		/* Once we reach the threshold, put all subsequent
		 * spelling suggestions in a secondary menu. */
		if (count == threshold)
			path = "/context-menu/context-more-suggestions-menu/";

		/* Action name just needs to be unique. */
		action_name = g_strdup_printf ("suggest-%d", count++);

		action_label = g_markup_printf_escaped (
			"<b>%s</b>", suggestion);

		action = gtk_action_new (
			action_name, action_label, NULL, NULL);

		g_object_set_data_full (
			G_OBJECT (action), "word",
			g_strdup (suggestion), g_free);

		g_signal_connect (
			action, "activate", G_CALLBACK (
			action_context_spell_suggest_cb), editor);

		gtk_action_group_add_action (action_group, action);

		gtk_ui_manager_add_ui (
			manager, merge_id, path,
			action_name, action_name,
			GTK_UI_MANAGER_AUTO, FALSE);

		/* XXX GtkAction offers no support for Pango markup,
		 *     so we have to manually set "use-markup" on the
		 *     child of the proxy widget. */
		gtk_ui_manager_ensure_update (manager);
		proxies = gtk_action_get_proxies (action);
		child = gtk_bin_get_child (proxies->data);
		g_object_set (child, "use-markup", TRUE, NULL);

		g_free (suggestion);
		g_free (action_name);
		g_free (action_label);

		list = g_list_delete_link (list, list);
	}

	g_free (word);
}
Beispiel #26
0
void 
gui_create_tasks(GUI *appGUI) {

GtkWidget           *vbox1;
GtkWidget           *vbox2;
GtkWidget           *table;
GtkWidget           *label;
GtkWidget           *top_scrolledwindow;
GtkWidget           *hseparator;
GtkWidget           *close_button;
GtkCellRenderer     *renderer;
GtkWidget           *top_viewport;
GtkWidget           *bottom_viewport;
GtkTextBuffer       *text_buffer;
GError              *error = NULL;
GtkActionGroup      *action_group = NULL;
gchar tmpbuf[BUFFER_SIZE];

 const gchar *ui_info =
"  <toolbar name=\"toolbar\">\n"
"    <toolitem name=\"add\" action=\"add\" />\n"
"    <toolitem name=\"delete\" action=\"delete\" />\n"
"    <separator name=\"sep1\" />\n"
"    <toolitem name=\"edit\" action=\"edit\" />\n"
"  </toolbar>\n";

GtkActionEntry entries[] = {
  { "add", OSMO_STOCK_TASKS_ADD, _("New task"), NULL, _("New task"), NULL },
  { "edit", OSMO_STOCK_TASKS_EDIT, _("Edit task"), NULL, _("Edit task"), NULL },
  { "delete", OSMO_STOCK_TASKS_REMOVE, _("Remove task"), NULL, _("Remove task"), NULL },
};

guint n_entries = G_N_ELEMENTS (entries);

    appGUI->tsk->filter_index = 0;

    label = gtk_label_new(NULL);
    gtk_label_set_angle (GTK_LABEL(label), -90.0);
    sprintf(tmpbuf, "<b>%s</b>", _("Tasks"));
    gtk_label_set_markup (GTK_LABEL (label), tmpbuf);

    vbox1 = gtk_vbox_new (FALSE, 1);
    gtk_widget_show (vbox1);
    gtk_container_set_border_width (GTK_CONTAINER (vbox1), 8);
    gtk_notebook_append_page(GTK_NOTEBOOK(appGUI->notebook), vbox1, label);
    appGUI->tsk->vbox = GTK_BOX(vbox1);

    /*-------------------------------------------------------------------------------------*/

    action_group = gtk_action_group_new ("_actions");
    gtk_action_group_add_actions (action_group, entries, n_entries, NULL);
    gtk_action_group_set_sensitive(action_group, TRUE);

    appGUI->tsk->tasks_uim_widget = gtk_ui_manager_new ();

    gtk_ui_manager_insert_action_group (appGUI->tsk->tasks_uim_widget, action_group, 0);
    g_signal_connect (appGUI->tsk->tasks_uim_widget, "add_widget", G_CALLBACK (add_tasks_toolbar_widget), appGUI);

    if (!gtk_ui_manager_add_ui_from_string (appGUI->tsk->tasks_uim_widget, ui_info, -1, &error)) {
        g_message ("building toolbar failed: %s", error->message);
        g_error_free (error);
    }
    gtk_ui_manager_ensure_update (appGUI->tsk->tasks_uim_widget);

    gtk_toolbar_set_style (appGUI->tsk->tasks_toolbar, GTK_TOOLBAR_ICONS);
    gtk_toolbar_set_tooltips (appGUI->tsk->tasks_toolbar, config.enable_tooltips);

    /*-------------------------------------------------------------------------------------*/
    /* assign callbacks */

    g_signal_connect (G_OBJECT(gtk_ui_manager_get_widget (appGUI->tsk->tasks_uim_widget, "/toolbar/add")), "clicked", 
                      G_CALLBACK(tasks_add_item_cb), appGUI);
    g_signal_connect (G_OBJECT(gtk_ui_manager_get_widget (appGUI->tsk->tasks_uim_widget, "/toolbar/edit")), "clicked", 
                      G_CALLBACK(tasks_edit_item_cb), appGUI);
    g_signal_connect (G_OBJECT(gtk_ui_manager_get_widget (appGUI->tsk->tasks_uim_widget, "/toolbar/delete")), "clicked", 
                      G_CALLBACK(tasks_remove_item_cb), appGUI);

    /*-------------------------------------------------------------------------------------*/

    gtk_widget_set_sensitive(gtk_ui_manager_get_widget (appGUI->tsk->tasks_uim_widget, "/toolbar/edit"), FALSE);
    gtk_widget_set_sensitive(gtk_ui_manager_get_widget (appGUI->tsk->tasks_uim_widget, "/toolbar/delete"), FALSE);

    hseparator = gtk_hseparator_new ();
    gtk_widget_show (hseparator);
    gtk_box_pack_start (GTK_BOX (vbox1), hseparator, FALSE, TRUE, 6);

    table = gtk_table_new (1, 4, FALSE);
    gtk_widget_show (table);
    gtk_box_pack_start (GTK_BOX (vbox1), table, FALSE, TRUE, 0);
    gtk_table_set_col_spacings (GTK_TABLE (table), 8);

    sprintf(tmpbuf, "<b>%s:</b>", _("Category filter"));
    label = gtk_label_new (tmpbuf);
    gtk_widget_show (label);
    gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
                     (GtkAttachOptions) (GTK_FILL),
                     (GtkAttachOptions) (0), 0, 0);
    gtk_label_set_use_markup (GTK_LABEL (label), TRUE);

    appGUI->tsk->cf_combobox = gtk_combo_box_new_text ();
    gtk_widget_show (appGUI->tsk->cf_combobox);
    gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (appGUI->tsk->cf_combobox), FALSE);
    GTK_WIDGET_UNSET_FLAGS(appGUI->tsk->cf_combobox, GTK_CAN_FOCUS);
    gtk_table_attach (GTK_TABLE (table), appGUI->tsk->cf_combobox, 1, 2, 0, 1,
                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                     (GtkAttachOptions) (GTK_FILL), 0, 0);
    g_signal_connect(appGUI->tsk->cf_combobox, "changed", 
                     G_CALLBACK(category_filter_cb), appGUI);
    g_signal_connect(G_OBJECT(appGUI->tsk->cf_combobox), "focus", 
                     G_CALLBACK(category_combo_box_focus_cb), NULL);

    appGUI->tsk->n_items_label = gtk_label_new ("");
    gtk_widget_show (appGUI->tsk->n_items_label);
    gtk_widget_set_size_request (appGUI->tsk->n_items_label, 100, -1);
    gtk_table_attach (GTK_TABLE (table), appGUI->tsk->n_items_label, 3, 4, 0, 1,
                     (GtkAttachOptions) (GTK_FILL),
                     (GtkAttachOptions) (0), 0, 0);
    gtk_label_set_use_markup (GTK_LABEL (appGUI->tsk->n_items_label), TRUE);

    hseparator = gtk_hseparator_new ();
    gtk_widget_show (hseparator);
    gtk_box_pack_start (GTK_BOX (vbox1), hseparator, FALSE, TRUE, 6);

    /*-------------------------------------------------------------------------------------*/

    appGUI->tsk->tasks_paned = gtk_vpaned_new();
    gtk_widget_show (appGUI->tsk->tasks_paned);
    gtk_paned_set_position(GTK_PANED(appGUI->tsk->tasks_paned), 99999);
    gtk_box_pack_start(GTK_BOX(vbox1), appGUI->tsk->tasks_paned, TRUE, TRUE, 0);

    top_viewport = gtk_viewport_new (NULL, NULL);
    gtk_widget_show (top_viewport);
    gtk_viewport_set_shadow_type (GTK_VIEWPORT (top_viewport), GTK_SHADOW_NONE);
    gtk_paned_pack1 (GTK_PANED (appGUI->tsk->tasks_paned), top_viewport, FALSE, TRUE);

    top_scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
    gtk_widget_show (top_scrolledwindow);
    gtk_container_add (GTK_CONTAINER (top_viewport), top_scrolledwindow);

    gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (top_scrolledwindow), GTK_SHADOW_IN);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (top_scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

    appGUI->tsk->tasks_list_store = gtk_list_store_new(TASKS_NUM_COLUMNS, 
                                         G_TYPE_BOOLEAN,
                                         G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING,
                                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);

    appGUI->tsk->tasks_filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(appGUI->tsk->tasks_list_store), NULL);
    gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER(appGUI->tsk->tasks_filter), 
                                            (GtkTreeModelFilterVisibleFunc)tasks_list_filter_cb, 
                                            appGUI, NULL);

    appGUI->tsk->tasks_sort = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(appGUI->tsk->tasks_filter));

    appGUI->tsk->tasks_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(appGUI->tsk->tasks_sort));
    gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(appGUI->tsk->tasks_list), config.tasks_rules_hint);
    gtk_widget_show (appGUI->tsk->tasks_list);
    GTK_WIDGET_SET_FLAGS (appGUI->tsk->tasks_list, GTK_CAN_DEFAULT);
    gtk_widget_modify_fg(GTK_WIDGET(appGUI->tsk->tasks_list), GTK_STATE_SELECTED,
                         (& GTK_WIDGET(appGUI->tsk->tasks_list)->style->base[GTK_STATE_SELECTED]));
    gtk_widget_modify_fg(GTK_WIDGET(appGUI->tsk->tasks_list), GTK_STATE_NORMAL,
                         (& GTK_WIDGET(appGUI->tsk->tasks_list)->style->bg[GTK_STATE_NORMAL]));

    g_signal_connect(G_OBJECT(appGUI->tsk->tasks_list), "button_press_event",
                     G_CALLBACK(list_dbclick_cb), appGUI);

    appGUI->tsk->tasks_list_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (appGUI->tsk->tasks_list));
    g_signal_connect(G_OBJECT(appGUI->tsk->tasks_list_selection), "changed",
                     G_CALLBACK(tasks_item_selected), appGUI);

    /* create columns */

    renderer = gtk_cell_renderer_toggle_new();
    appGUI->tsk->tasks_columns[COLUMN_DONE] = gtk_tree_view_column_new_with_attributes (_("Done"),
                             renderer,
                             "active", COLUMN_DONE,
                             NULL);
    gtk_tree_view_append_column (GTK_TREE_VIEW(appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[COLUMN_DONE]);

    g_signal_connect (renderer, "toggled", G_CALLBACK (done_toggled), appGUI);

    renderer = gtk_cell_renderer_text_new();
    appGUI->tsk->tasks_columns[COLUMN_DUE_DATE] = gtk_tree_view_column_new_with_attributes(_("Due date"),
                              renderer,
                              "text", COLUMN_DUE_DATE,
                              "strikethrough", COLUMN_DONE,
                              "foreground", COLUMN_COLOR,
                              NULL);
    gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[COLUMN_DUE_DATE], config.visible_due_date_column);
    gtk_tree_view_append_column(GTK_TREE_VIEW(appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[COLUMN_DUE_DATE]);

    renderer = gtk_cell_renderer_text_new();
    appGUI->tsk->tasks_columns[COLUMN_DUE_DATE_JULIAN] = gtk_tree_view_column_new_with_attributes(NULL,
                              renderer,
                              "text", COLUMN_DUE_DATE_JULIAN,
                              "strikethrough", COLUMN_DONE,
                              "foreground", COLUMN_COLOR,
                              NULL);
    gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[COLUMN_DUE_DATE_JULIAN], FALSE);
    gtk_tree_view_append_column(GTK_TREE_VIEW(appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[COLUMN_DUE_DATE_JULIAN]);

    renderer = gtk_cell_renderer_text_new();
    appGUI->tsk->tasks_columns[COLUMN_START_DATE_JULIAN] = gtk_tree_view_column_new_with_attributes(NULL,
                              renderer,
                              "text", COLUMN_START_DATE_JULIAN,
                              "strikethrough", COLUMN_DONE,
                              "foreground", COLUMN_COLOR,
                              NULL);
    gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[COLUMN_START_DATE_JULIAN], FALSE);
    gtk_tree_view_append_column(GTK_TREE_VIEW(appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[COLUMN_START_DATE_JULIAN]);

    renderer = gtk_cell_renderer_text_new();
    appGUI->tsk->tasks_columns[COLUMN_PRIORITY] = gtk_tree_view_column_new_with_attributes(_("Priority"),
                              renderer,
                              "text", COLUMN_PRIORITY,
                              "strikethrough", COLUMN_DONE,
                              "foreground", COLUMN_COLOR,
                              NULL);
    gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[COLUMN_PRIORITY], config.visible_priority_column);
    gtk_tree_view_append_column(GTK_TREE_VIEW(appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[COLUMN_PRIORITY]);

    renderer = gtk_cell_renderer_text_new();
    appGUI->tsk->tasks_columns[COLUMN_CATEGORY] = gtk_tree_view_column_new_with_attributes(_("Category"),
                              renderer,
                              "text", COLUMN_CATEGORY,
                              "strikethrough", COLUMN_DONE,
                              "foreground", COLUMN_COLOR,
                              NULL);
    gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[COLUMN_CATEGORY], config.visible_category_column);
    gtk_tree_view_append_column(GTK_TREE_VIEW(appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[COLUMN_CATEGORY]);

    renderer = gtk_cell_renderer_text_new();
    g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
    gtk_cell_renderer_set_fixed_size(renderer, 0, -1);
    appGUI->tsk->tasks_columns[COLUMN_SUMMARY] = gtk_tree_view_column_new_with_attributes(_("Summary"),
                              renderer,
                              "text", COLUMN_SUMMARY,
                              "strikethrough", COLUMN_DONE,
                              "foreground", COLUMN_COLOR,
                              NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[COLUMN_SUMMARY]);


    renderer = gtk_cell_renderer_text_new();
    appGUI->tsk->tasks_columns[COLUMN_DESCRIPTION] = gtk_tree_view_column_new_with_attributes(_("Description"),
                              renderer,
                              "text", COLUMN_DESCRIPTION,
                              NULL);
    gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[COLUMN_DESCRIPTION], FALSE);
    gtk_tree_view_append_column(GTK_TREE_VIEW(appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[COLUMN_DESCRIPTION]);

    renderer = gtk_cell_renderer_text_new();
    appGUI->tsk->tasks_columns[COLUMN_COLOR] = gtk_tree_view_column_new_with_attributes(NULL,
                              renderer,
                              "text", COLUMN_COLOR,
                              NULL);
    gtk_tree_view_column_set_visible (appGUI->tsk->tasks_columns[COLUMN_COLOR], FALSE);
    gtk_tree_view_append_column(GTK_TREE_VIEW(appGUI->tsk->tasks_list), appGUI->tsk->tasks_columns[COLUMN_COLOR]);

    /* configure list options */

    gtk_container_add (GTK_CONTAINER (top_scrolledwindow), appGUI->tsk->tasks_list);
    gtk_tree_view_set_enable_search (GTK_TREE_VIEW(appGUI->tsk->tasks_list), FALSE);

    /* configure sorting */

    gtk_tree_sortable_set_sort_func((GtkTreeSortable *)appGUI->tsk->tasks_sort, 0, 
                                    (GtkTreeIterCompareFunc)custom_tasks_sort_function, NULL, NULL);

    gtk_tree_sortable_set_sort_column_id((GtkTreeSortable *)appGUI->tsk->tasks_sort, COLUMN_DUE_DATE, config.tasks_sorting_order);
    gtk_tree_sortable_set_sort_column_id((GtkTreeSortable *)appGUI->tsk->tasks_sort, COLUMN_PRIORITY, config.tasks_sorting_order);
    gtk_tree_sortable_set_sort_column_id((GtkTreeSortable *)appGUI->tsk->tasks_sort, COLUMN_DONE, config.tasks_sorting_order);

    /*----------------------------------------------------------------------------*/

    bottom_viewport = gtk_viewport_new (NULL, NULL);
    gtk_widget_show (bottom_viewport);
    gtk_viewport_set_shadow_type (GTK_VIEWPORT (bottom_viewport), GTK_SHADOW_NONE);
    gtk_paned_pack2 (GTK_PANED (appGUI->tsk->tasks_paned), bottom_viewport, TRUE, TRUE);

    vbox2 = gtk_vbox_new (FALSE, 0);
    gtk_widget_show (vbox2);
    gtk_container_set_border_width (GTK_CONTAINER (vbox2), 0);
    gtk_container_add (GTK_CONTAINER (bottom_viewport), vbox2);

    appGUI->tsk->panel_hbox = gtk_hbox_new (FALSE, 0);
    gtk_box_pack_start (GTK_BOX (vbox2), appGUI->tsk->panel_hbox, FALSE, FALSE, 0);
    gtk_widget_show(appGUI->tsk->panel_hbox);

    sprintf(tmpbuf, "%s:", _("Task details"));
    label = gtk_label_new (tmpbuf);
    gtk_widget_show (label);
    gtk_box_pack_start (GTK_BOX (appGUI->tsk->panel_hbox), label, FALSE, FALSE, 0);

    if (config.default_stock_icons) {
        close_button = gui_stock_button(GTK_STOCK_CLOSE, FALSE);
    } else {
        close_button = gui_stock_button(OSMO_STOCK_BUTTON_CLOSE, FALSE);
    }
    GTK_WIDGET_UNSET_FLAGS(close_button, GTK_CAN_FOCUS);
    gtk_button_set_relief (GTK_BUTTON(close_button), GTK_RELIEF_NONE);
    gtk_tooltips_set_tip (appGUI->osmo_tooltips, close_button, _("Close description panel"), NULL);
    gtk_box_pack_end (GTK_BOX (appGUI->tsk->panel_hbox), close_button, FALSE, FALSE, 0);
    g_signal_connect (G_OBJECT (close_button), "clicked",
                        G_CALLBACK (panel_close_desc_cb), appGUI);

    appGUI->tsk->panel_scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
    gtk_widget_show (appGUI->tsk->panel_scrolledwindow);
    gtk_box_pack_start (GTK_BOX (vbox2), appGUI->tsk->panel_scrolledwindow, TRUE, TRUE, 0);
    gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (appGUI->tsk->panel_scrolledwindow), GTK_SHADOW_IN);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (appGUI->tsk->panel_scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

    appGUI->tsk->tasks_desc_textview = gtk_text_view_new ();
    gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (appGUI->tsk->tasks_desc_textview), GTK_WRAP_WORD);
    gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(appGUI->tsk->tasks_desc_textview), 4);
    gtk_text_view_set_left_margin(GTK_TEXT_VIEW(appGUI->tsk->tasks_desc_textview), 4);
    gtk_text_view_set_right_margin(GTK_TEXT_VIEW(appGUI->tsk->tasks_desc_textview), 4);
    gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(appGUI->tsk->tasks_desc_textview), FALSE);
    gtk_text_view_set_editable(GTK_TEXT_VIEW(appGUI->tsk->tasks_desc_textview), FALSE);
    gtk_widget_show (appGUI->tsk->tasks_desc_textview);
    gtk_container_add (GTK_CONTAINER (appGUI->tsk->panel_scrolledwindow), appGUI->tsk->tasks_desc_textview);

    text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(appGUI->tsk->tasks_desc_textview));
    gtk_text_buffer_create_tag (text_buffer, "italic",
                  "style", PANGO_STYLE_ITALIC, NULL);
    appGUI->tsk->font_tag_object = gtk_text_buffer_create_tag (text_buffer, "info_font",
                      "font", (gchar *) config.task_info_font, NULL);

}
Beispiel #27
0
static void fill_favory_language_menu() {
	GError* err = 0;
	GtkUIManager* ui_mgr;
	gchar* ui_info;
	GString* gstr;

	if( !g_self->favory_language_list )
		return;

	ui_mgr = GTK_UI_MANAGER(gtk_builder_get_object(g_self->app->get_ui_builder(), "main_ui_manager"));

	if( g_self->favory_merge_id ) {
		gtk_ui_manager_remove_ui(ui_mgr, g_self->favory_merge_id);
		gtk_ui_manager_ensure_update(ui_mgr);
	}

	// favory selector menu
	// 
	gstr = g_string_new(0);
	g_list_foreach(g_self->favory_language_list, (GFunc)&fill_languages, gstr);

	ui_info = g_strdup_printf(
		"<ui>"
		"  <menubar name='main_menubar'>"
		"     <menu action='view_menu'>\n"
		"      <placeholder name='view_menu_extend_place'>"
		"        <menu action='language_selector_open'>"
		"          <placeholder name='pls_favory_menu_place'>"
		"            <separator/>"
		"            %s"
		"          </placeholder>"
		"        </menu>"
		"      </placeholder>"
		"    </menu>"
		"  </menubar>"
		""
		"  <toolbar name='main_toolbar'>"
		"    <placeholder name='main_toolbar_view_place'>"
		"      <toolitem action='language_selector_toolmenu_open'>"
		"        <menu action='language_selector_toolmenu_open'>"
		"          <separator/>"
		"          <placeholder name='pls_favory_toolmenu_place'>"
		"            <separator/>"
		"            %s"
		"          </placeholder>"
		"        </menu>"
		"      </toolitem>"
		"    </placeholder>"
        "  </toolbar>"
		"</ui>"
		, gstr->str
		, gstr->str
	);

	g_self->favory_merge_id = gtk_ui_manager_add_ui_from_string(ui_mgr, ui_info, -1, &err);
	if( err ) {
		g_printerr("%s", err->message);
		g_error_free(err);
	}
	g_free(ui_info);
	g_string_free(gstr, TRUE);

	gtk_ui_manager_ensure_update(ui_mgr);
}
Beispiel #28
0
/**
 * Add menu items to the "Recent files" submenu.
 */
gboolean affiche_derniers_fichiers_ouverts ( void )
{
    gint i;
    GtkActionGroup * action_group;

    efface_derniers_fichiers_ouverts ();

    if ( conf.nb_derniers_fichiers_ouverts > conf.nb_max_derniers_fichiers_ouverts )
    {
        conf.nb_derniers_fichiers_ouverts = conf.nb_max_derniers_fichiers_ouverts;
    }

    if ( ! conf.nb_derniers_fichiers_ouverts || ! conf.nb_max_derniers_fichiers_ouverts )
    {
        return FALSE;
    }

    action_group = gtk_action_group_new ( "Group2" );

    for ( i = 0 ; i < conf.nb_derniers_fichiers_ouverts ; i++ )
    {
        gchar *tmp_name;
        GtkAction *action;

        tmp_name = g_strdup_printf ( "LastFile%d", i );

        action = gtk_action_new ( tmp_name,
                        tab_noms_derniers_fichiers_ouverts[i],
                        "",
                        "" );
        g_free ( tmp_name );
        g_signal_connect ( action,
                        "activate",
                        G_CALLBACK ( gsb_file_open_direct_menu ),
                        GINT_TO_POINTER ( i ) );
        gtk_action_group_add_action ( action_group, action );
    }

    gtk_ui_manager_insert_action_group ( ui_manager, action_group, 1 );

    recent_files_merge_id = gtk_ui_manager_new_merge_id ( ui_manager );

    for ( i=0 ; i < conf.nb_derniers_fichiers_ouverts ; i++ )
    {
        gchar *tmp_name;
        gchar *tmp_label;

        tmp_name = g_strdup_printf ( "LastFile%d", i );
        tmp_label = g_strdup_printf ( "_%d LastFile%d", i, i );

        gtk_ui_manager_add_ui ( ui_manager,
                    recent_files_merge_id,
                    "/menubar/FileMenu/RecentFiles/",
                    tmp_label,
                    tmp_name,
                    GTK_UI_MANAGER_MENUITEM,
                    FALSE );

        g_free ( tmp_name );
        g_free ( tmp_label );
    }

    /* add a separator */
    gtk_ui_manager_add_ui ( ui_manager,
                    merge_id,
                    "/menubar/FileMenu/Open/",
                    NULL,
                    NULL,
                    GTK_UI_MANAGER_SEPARATOR,
                    FALSE );

    gtk_ui_manager_ensure_update ( ui_manager );

#ifdef GTKOSXAPPLICATION
    grisbi_osx_app_update_menus_cb ( );
#endif /* GTKOSXAPPLICATION */
    return FALSE;
}
Beispiel #29
0
static void
update_device_list (BluetoothApplet *applet,
					gpointer user_data)
{
	GtkUIManager *uimanager;
	GList *actions, *devices, *l;
	gboolean has_devices = FALSE;

	uimanager = GTK_UI_MANAGER (gtk_builder_get_object (xml, "bluetooth-applet-ui-manager"));

	devices = bluetooth_applet_get_devices (applet);

	if (devices == NULL) {
		/* No devices? Remove everything */
		actions = gtk_action_group_list_actions (devices_action_group);
		g_list_foreach (actions, (GFunc) remove_action_item, uimanager);
		g_list_free (actions);
		goto done;
	}

	/* Get a list of actions, and we'll remove the ones with a
	 * device in the list. We remove the submenu items first */
	actions = gtk_action_group_list_actions (devices_action_group);
	for (l = actions; l != NULL; l = l->next) {
		if (bluetooth_verify_address (gtk_action_get_name (l->data)) == FALSE)
			l->data = NULL;
	}
	actions = g_list_remove_all (actions, NULL);

	for (l = devices; l != NULL; l = g_list_next (l)) {
		BluetoothSimpleDevice *device = l->data;
		GtkAction *action, *status, *oper;
		char *name;

		if (device_has_submenu (device) == FALSE) {
			g_boxed_free (BLUETOOTH_TYPE_SIMPLE_DEVICE, device);
			continue;
		}

		has_devices = TRUE;

		action = gtk_action_group_get_action (devices_action_group, device->bdaddr);
		oper = NULL;
		status = NULL;
		if (action) {
			char *action_name;

			actions = g_list_remove (actions, action);

			action_name = g_strdup_printf ("%s-status", device->bdaddr);
			status = gtk_action_group_get_action (devices_action_group, action_name);
			g_free (action_name);

			action_name = g_strdup_printf ("%s-action", device->bdaddr);
			oper = gtk_action_group_get_action (devices_action_group, action_name);
			g_free (action_name);
		}

		name = escape_label_for_action (device->alias);

		if (action == NULL) {
			guint menu_merge_id;
			char *action_path;

			/* The menu item with descendants */
			action = gtk_action_new (device->bdaddr, name, NULL, NULL);

			gtk_action_group_add_action (devices_action_group, action);
			g_object_unref (action);
			menu_merge_id = gtk_ui_manager_new_merge_id (uimanager);
			gtk_ui_manager_add_ui (uimanager, menu_merge_id,
					       "/bluetooth-applet-popup/devices-placeholder", device->bdaddr, device->bdaddr,
					       GTK_UI_MANAGER_MENU, FALSE);
			g_object_set_data_full (G_OBJECT (action),
						"merge-id", GUINT_TO_POINTER (menu_merge_id), NULL);

			/* The status menu item */
			status = add_menu_item (device->bdaddr,
						"status",
						device->connected ? _("Connected") : _("Disconnected"),
						uimanager,
						menu_merge_id,
						NULL);
			gtk_action_set_sensitive (status, FALSE);

			if (device->can_connect) {
				action_path = g_strdup_printf ("/bluetooth-applet-popup/devices-placeholder/%s/%s-status",
							       device->bdaddr, device->bdaddr);
				action_set_bold (uimanager, status, action_path);
				g_free (action_path);
			} else {
				gtk_action_set_visible (status, FALSE);
			}

			/* The connect button */
			oper = add_menu_item (device->bdaddr,
					      "action",
					      device->connected ? _("Disconnect") : _("Connect"),
					      uimanager,
					      menu_merge_id,
					      G_CALLBACK (on_connect_activate));
			if (!device->can_connect)
				gtk_action_set_visible (oper, FALSE);

			add_separator_item (device->bdaddr, "connect-sep", uimanager, menu_merge_id);

			/* The Send to... button */
			if (device->capabilities & BLUETOOTH_CAPABILITIES_OBEX_PUSH) {
				add_menu_item (device->bdaddr,
					       "sendto",
					       _("Send files..."),
					       uimanager,
					       menu_merge_id,
					       G_CALLBACK (sendto_callback));
				g_object_set_data_full (G_OBJECT (action),
							"alias", g_strdup (device->alias), g_free);
			}
			if (device->capabilities & BLUETOOTH_CAPABILITIES_OBEX_FILE_TRANSFER) {
				add_menu_item (device->bdaddr,
					       "browse",
					       _("Browse files..."),
					       uimanager,
					       menu_merge_id,
					       G_CALLBACK (browse_callback));
			}

			add_separator_item (device->bdaddr, "files-sep", uimanager, menu_merge_id);

			if (device->type == BLUETOOTH_TYPE_KEYBOARD && program_available (GNOMECC)) {
				add_menu_item (device->bdaddr,
					       "keyboard",
					       _("Keyboard Settings"),
					       uimanager,
					       menu_merge_id,
					       G_CALLBACK (keyboard_callback));
			}
			if (device->type == BLUETOOTH_TYPE_MOUSE && program_available (GNOMECC)) {
				add_menu_item (device->bdaddr,
					       "mouse",
					       _("Mouse and Touchpad Settings"),
					       uimanager,
					       menu_merge_id,
					       G_CALLBACK (mouse_callback));
			}
			if ((device->type == BLUETOOTH_TYPE_HEADSET ||
			     device->type == BLUETOOTH_TYPE_HEADPHONES ||
			     device->type == BLUETOOTH_TYPE_OTHER_AUDIO) && program_available (GNOMECC)) {
				add_menu_item (device->bdaddr,
					       "sound",
					       _("Sound Settings"),
					       uimanager,
					       menu_merge_id,
					       G_CALLBACK (sound_callback));
			}
		} else {
			gtk_action_set_label (action, name);

			if (device->can_connect) {
				gtk_action_set_visible (status, TRUE);
				gtk_action_set_visible (oper, TRUE);
				set_device_status_label (device->bdaddr, device->connected ? CONNECTED : DISCONNECTED);
				gtk_action_set_label (oper, device->connected ? _("Disconnect") : _("Connect"));
			} else {
				gtk_action_set_visible (status, FALSE);
				gtk_action_set_visible (oper, FALSE);
			}
		}
		g_free (name);

		if (oper != NULL) {
			g_object_set_data_full (G_OBJECT (oper),
						"connected", GINT_TO_POINTER (device->connected ? CONNECTED : DISCONNECTED), NULL);
			g_object_set_data_full (G_OBJECT (oper),
						"device-path", g_strdup (device->device_path), g_free);
		}

		/* And now for the trick of the day */
		if (device->connected != FALSE) {
			char *path;

			path = g_strdup_printf ("/bluetooth-applet-popup/devices-placeholder/%s", device->bdaddr);
			action_set_bold (uimanager, action, path);
			g_free (path);
		}

		g_boxed_free (BLUETOOTH_TYPE_SIMPLE_DEVICE, device);
	}

	/* Remove the left-over devices */
	g_list_foreach (actions, (GFunc) remove_action_item, uimanager);
	g_list_free (actions);

	/* Cleanup */
	g_list_free (devices);
done:
	gtk_ui_manager_ensure_update (uimanager);

	gtk_action_set_visible (GTK_ACTION (gtk_builder_get_object (xml, "devices-label")),
				has_devices);
}
Beispiel #30
0
static void
update_device_list (GtkTreeIter *parent)
{
	GtkUIManager *uimanager;
	GtkTreeIter iter;
	gboolean cont;
	guint num_devices;
	GList *actions, *l;

	num_devices = 0;

	uimanager = GTK_UI_MANAGER (gtk_builder_get_object (xml, "bluetooth-applet-ui-manager"));

	if (parent == NULL) {
		/* No default adapter? Remove everything */
		actions = gtk_action_group_list_actions (devices_action_group);
		g_list_foreach (actions, (GFunc) remove_action_item, uimanager);
		g_list_free (actions);
		goto done;
	}

	/* Get a list of actions, and we'll remove the ones with a
	 * device in the list. We remove the submenu items first */
	actions = gtk_action_group_list_actions (devices_action_group);
	for (l = actions; l != NULL; l = l->next) {
		if (bluetooth_verify_address (gtk_action_get_name (l->data)) == FALSE)
			l->data = NULL;
	}
	actions = g_list_remove_all (actions, NULL);

	cont = gtk_tree_model_iter_children (devices_model, &iter, parent);
	while (cont) {
		GHashTable *services;
		DBusGProxy *proxy;
		char *alias, *address, **uuids, *name;
		gboolean is_connected;
		BluetoothType type;
		GtkAction *action, *status, *oper;

		gtk_tree_model_get (devices_model, &iter,
				    BLUETOOTH_COLUMN_PROXY, &proxy,
				    BLUETOOTH_COLUMN_ADDRESS, &address,
				    BLUETOOTH_COLUMN_SERVICES, &services,
				    BLUETOOTH_COLUMN_ALIAS, &alias,
				    BLUETOOTH_COLUMN_UUIDS, &uuids,
				    BLUETOOTH_COLUMN_TYPE, &type,
				    -1);

		if (device_has_submenu ((const char **) uuids, services, type) == FALSE ||
		    address == NULL || proxy == NULL || alias == NULL) {
			if (proxy != NULL)
				g_object_unref (proxy);

			if (services != NULL)
				g_hash_table_unref (services);
			g_strfreev (uuids);
			g_free (alias);
			g_free (address);
			cont = gtk_tree_model_iter_next (devices_model, &iter);
			continue;
		}

		action = gtk_action_group_get_action (devices_action_group, address);
		oper = NULL;
		status = NULL;
		if (action) {
			char *action_name;

			actions = g_list_remove (actions, action);

			action_name = g_strdup_printf ("%s-status", address);
			status = gtk_action_group_get_action (devices_action_group, action_name);
			g_free (action_name);

			action_name = g_strdup_printf ("%s-action", address);
			oper = gtk_action_group_get_action (devices_action_group, action_name);
			g_free (action_name);
		}

		/* If one service is connected, then we're connected */
		is_connected = FALSE;
		if (services != NULL) {
			GList *list, *l;

			list = g_hash_table_get_values (services);
			for (l = list; l != NULL; l = l->next) {
				BluetoothStatus val = GPOINTER_TO_INT (l->data);
				if (val == BLUETOOTH_STATUS_CONNECTED ||
				    val == BLUETOOTH_STATUS_PLAYING) {
					is_connected = TRUE;
					break;
				}
			}
			g_list_free (list);
		}

		name = escape_label_for_action (alias);

		if (action == NULL) {
			guint menu_merge_id;
			char *action_path;

			/* The menu item with descendants */
			action = gtk_action_new (address, name, NULL, NULL);

			gtk_action_group_add_action (devices_action_group, action);
			g_object_unref (action);
			menu_merge_id = gtk_ui_manager_new_merge_id (uimanager);
			gtk_ui_manager_add_ui (uimanager, menu_merge_id,
					       "/bluetooth-applet-popup/devices-placeholder", address, address,
					       GTK_UI_MANAGER_MENU, FALSE);
			g_object_set_data_full (G_OBJECT (action),
						"merge-id", GUINT_TO_POINTER (menu_merge_id), NULL);

			/* The status menu item */
			status = add_menu_item (address,
						"status",
						is_connected ? _("Connected") : _("Disconnected"),
						uimanager,
						menu_merge_id,
						NULL);
			gtk_action_set_sensitive (status, FALSE);

			if (services != NULL) {
				action_path = g_strdup_printf ("/bluetooth-applet-popup/devices-placeholder/%s/%s-status",
							       address, address);
				action_set_bold (uimanager, status, action_path);
				g_free (action_path);
			} else {
				gtk_action_set_visible (status, FALSE);
			}

			/* The connect button */
			oper = add_menu_item (address,
					      "action",
					      is_connected ? _("Disconnect") : _("Connect"),
					      uimanager,
					      menu_merge_id,
					      G_CALLBACK (on_connect_activate));
			if (services == NULL)
				gtk_action_set_visible (oper, FALSE);

			add_separator_item (address, "connect-sep", uimanager, menu_merge_id);

			/* The Send to... button */
			if (device_has_uuid ((const char **) uuids, "OBEXObjectPush") != FALSE) {
				add_menu_item (address,
					       "sendto",
					       _("Send files..."),
					       uimanager,
					       menu_merge_id,
					       G_CALLBACK (sendto_callback));
				g_object_set_data_full (G_OBJECT (action),
							"alias", g_strdup (alias), g_free);
			}
			if (device_has_uuid ((const char **) uuids, "OBEXFileTransfer") != FALSE) {
				add_menu_item (address,
					       "browse",
					       _("Browse files..."),
					       uimanager,
					       menu_merge_id,
					       G_CALLBACK (browse_callback));
			}

			add_separator_item (address, "files-sep", uimanager, menu_merge_id);

			if (type == BLUETOOTH_TYPE_KEYBOARD && program_available (KEYBOARD_PREFS)) {
				add_menu_item (address,
					       "keyboard",
					       _("Open Keyboard Preferences..."),
					       uimanager,
					       menu_merge_id,
					       G_CALLBACK (keyboard_callback));
			}
			if (type == BLUETOOTH_TYPE_MOUSE && program_available (MOUSE_PREFS)) {
				add_menu_item (address,
					       "mouse",
					       _("Open Mouse Preferences..."),
					       uimanager,
					       menu_merge_id,
					       G_CALLBACK (mouse_callback));
			}
			if ((type == BLUETOOTH_TYPE_HEADSET ||
			     type == BLUETOOTH_TYPE_HEADPHONES ||
			     type == BLUETOOTH_TYPE_OTHER_AUDIO) && program_available (SOUND_PREFS)) {
				add_menu_item (address,
					       "sound",
					       _("Open Sound Preferences..."),
					       uimanager,
					       menu_merge_id,
					       G_CALLBACK (sound_callback));
			}
		} else {
			gtk_action_set_label (action, name);

			gtk_action_set_visible (status, services != NULL);
			gtk_action_set_visible (oper, services != NULL);
			if (services != NULL) {
				set_device_status_label (address, is_connected ? CONNECTED : DISCONNECTED);
				gtk_action_set_label (oper, is_connected ? _("Disconnect") : _("Connect"));
			}
		}
		g_free (name);

		if (oper != NULL) {
			g_object_set_data_full (G_OBJECT (oper),
						"connected", GINT_TO_POINTER (is_connected ? CONNECTED : DISCONNECTED), NULL);
			g_object_set_data_full (G_OBJECT (oper),
						"device-path", g_strdup (dbus_g_proxy_get_path (proxy)), g_free);
		}

		/* And now for the trick of the day */
		if (is_connected != FALSE) {
			char *path;

			path = g_strdup_printf ("/bluetooth-applet-popup/devices-placeholder/%s", address);
			action_set_bold (uimanager, action, path);
			g_free (path);
		}

		num_devices++;

		if (proxy != NULL)
			g_object_unref (proxy);

		if (services != NULL)
			g_hash_table_unref (services);
		g_strfreev (uuids);
		g_free (alias);
		g_free (address);
		cont = gtk_tree_model_iter_next (devices_model, &iter);
	}

	/* Remove the left-over devices */
	g_list_foreach (actions, (GFunc) remove_action_item, uimanager);
	g_list_free (actions);

done:
	gtk_ui_manager_ensure_update (uimanager);

	gtk_action_set_visible (GTK_ACTION (gtk_builder_get_object (xml, "devices-label")),
				num_devices > 0);
}