+static gint
+compare_display_names (ModestAccountSettings *a,
+ ModestAccountSettings *b)
+{
+ return strcmp (modest_account_settings_get_display_name (a),
+ modest_account_settings_get_display_name (b));
+}
+
+/* We use this function to prevent the send&receive CSM to be shown
+ when there are less than two account */
+static gboolean
+tap_and_hold_query_cb (GtkWidget *widget, GdkEvent *event)
+{
+ return TRUE;
+}
+
+static void
+update_menus (ModestMainWindow* self)
+{
+ GSList *account_names, *iter, *accounts;
+ ModestMainWindowPrivate *priv;
+ ModestWindowPrivate *parent_priv;
+ ModestAccountMgr *mgr;
+ gint i, num_accounts;
+ GList *groups;
+ gchar *default_account;
+ const gchar *active_account_name;
+ GtkWidget *send_receive_button, *item;
+ GtkAction *send_receive_all = NULL;
+ GSList *radio_group;
+
+ priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
+ parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
+
+ /* Get enabled account IDs */
+ mgr = modest_runtime_get_account_mgr ();
+ account_names = modest_account_mgr_account_names (mgr, TRUE);
+ iter = account_names;
+ accounts = NULL;
+
+ while (iter) {
+ ModestAccountSettings *settings =
+ modest_account_mgr_load_account_settings (mgr, (gchar*) iter->data);
+ accounts = g_slist_prepend (accounts, settings);
+
+ iter = iter->next;
+ }
+ modest_account_mgr_free_account_names (account_names);
+ account_names = NULL;
+
+ /* Order the list of accounts by its display name */
+ accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
+ num_accounts = g_slist_length (accounts);
+
+ send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
+ "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
+ gtk_action_set_visible (send_receive_all, num_accounts > 0);
+
+ /* Delete old send&receive popup items. We can not just do a
+ menu_detach because it does not work well with
+ tap_and_hold */
+ if (priv->accounts_popup)
+ gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
+ (GtkCallback) gtk_widget_destroy, NULL);
+
+ /* Delete old entries in the View menu. Do not free groups, it
+ belongs to Gtk+ */
+ groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
+ while (groups) {
+ if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
+ gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
+ gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
+ GTK_ACTION_GROUP (groups->data));
+ groups = NULL;
+ /* Remove uis */
+ if (priv->merge_ids) {
+ for (i = 0; i < priv->merge_ids->len; i++)
+ gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
+ g_byte_array_free (priv->merge_ids, TRUE);
+ }
+ /* We need to call this in order to ensure
+ that the new actions are added in the right
+ order (alphabetical) */
+ gtk_ui_manager_ensure_update (parent_priv->ui_manager);
+ } else
+ groups = g_list_next (groups);
+ }
+ priv->merge_ids = g_byte_array_sized_new (num_accounts);
+
+ /* Get send receive button */
+ send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
+ "/ToolBar/ToolbarSendReceive");
+
+ /* Create the menu */
+ if (num_accounts > 1) {
+ if (!priv->accounts_popup)
+ priv->accounts_popup = gtk_menu_new ();
+ item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
+ g_signal_connect (G_OBJECT (item),
+ "activate",
+ G_CALLBACK (on_send_receive_csm_activated),
+ NULL);
+ item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
+ }
+
+ /* Create a new action group */
+ default_account = modest_account_mgr_get_default_account (mgr);
+ active_account_name = modest_window_get_active_account (MODEST_WINDOW (self));
+
+ if (!active_account_name)
+ modest_window_set_active_account (MODEST_WINDOW (self), default_account);
+
+ priv->view_additions_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
+ radio_group = NULL;
+ for (i = 0; i < num_accounts; i++) {
+ gchar *display_name = NULL;
+ const gchar *account_name;
+ ModestAccountSettings *settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
+
+ if (!settings) {
+ g_warning ("%s: BUG: account_data == NULL", __FUNCTION__);
+ continue;
+ }
+ account_name = modest_account_settings_get_account_name (settings);
+
+ if (default_account && account_name &&
+ !(strcmp (default_account, account_name) == 0)) {
+ display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
+ modest_account_settings_get_display_name (settings));
+ } else {
+ display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
+ modest_account_settings_get_display_name (settings));
+ }
+
+ /* Create action and add it to the action group. The
+ action name must be the account name, this way we
+ could know in the handlers the account to show */
+ if (settings && account_name) {
+ gchar* item_name, *refresh_action_name;
+ guint8 merge_id = 0;
+ GtkAction *view_account_action, *refresh_account_action;
+
+ view_account_action = GTK_ACTION (gtk_radio_action_new (account_name,
+ display_name, NULL, NULL, 0));
+ gtk_action_group_add_action (priv->view_additions_group, view_account_action);
+ gtk_radio_action_set_group (GTK_RADIO_ACTION (view_account_action), radio_group);
+ radio_group = gtk_radio_action_get_group (GTK_RADIO_ACTION (view_account_action));
+
+ if (active_account_name) {
+ if (active_account_name && account_name &&
+ (strcmp (active_account_name, account_name) == 0)) {
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (view_account_action), TRUE);
+ }
+ }
+
+ /* Add ui from account data. We allow 2^9-1 account
+ changes in a single execution because we're
+ downcasting the guint to a guint8 in order to use a
+ GByteArray. It should be enough. */
+ item_name = g_strconcat (account_name, "Menu", NULL);
+ merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
+ priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
+ gtk_ui_manager_add_ui (parent_priv->ui_manager,
+ merge_id,
+ "/MenuBar/ViewMenu/ViewMenuAdditions",
+ item_name,
+ account_name,
+ GTK_UI_MANAGER_MENUITEM,
+ FALSE);
+
+ /* Connect the action signal "activate" */
+ g_signal_connect_after (G_OBJECT (view_account_action),
+ "toggled",
+ G_CALLBACK (on_show_account_action_toggled),
+ self);
+
+ /* Create the items for the Tools->Send&Receive submenu */
+ refresh_action_name = g_strconcat ("SendReceive", account_name, NULL);
+ refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
+ display_name, NULL, NULL);
+ gtk_action_group_add_action (priv->view_additions_group, refresh_account_action);
+
+ merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
+ priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
+ gtk_ui_manager_add_ui (parent_priv->ui_manager,
+ merge_id,
+ "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
+ item_name,
+ refresh_action_name,
+ GTK_UI_MANAGER_MENUITEM,
+ FALSE);
+ g_free (refresh_action_name);
+
+ g_signal_connect_data (G_OBJECT (refresh_account_action),
+ "activate",
+ G_CALLBACK (on_refresh_account_action_activated),
+ g_strdup (account_name),
+ (GClosureNotify) g_free,
+ 0);
+
+ /* Create item and add it to the send&receive
+ CSM. If there is only one account then
+ it'll be no menu */
+ if (num_accounts > 1) {
+ GtkWidget *label = gtk_label_new(NULL);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ if (default_account && (strcmp(account_name, default_account) == 0)) {
+ gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
+ gtk_label_set_markup (GTK_LABEL (label), escaped);
+ g_free (escaped);
+ } else {
+ gtk_label_set_text (GTK_LABEL (label), display_name);
+ }
+
+ item = gtk_menu_item_new ();
+ gtk_container_add (GTK_CONTAINER (item), label);
+
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
+ g_signal_connect_data (G_OBJECT (item),
+ "activate",
+ G_CALLBACK (on_send_receive_csm_activated),
+ g_strdup (account_name),
+ (GClosureNotify) g_free,
+ 0);
+ }
+ g_free (item_name);
+ }
+
+ /* Frees */
+ g_free (display_name);
+ }
+
+ gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
+
+ /* We cannot do this in the loop above because this relies on the action
+ * group being inserted. This makes the default account appear in bold.
+ * I agree it is a rather ugly way, but I don't see another possibility. armin. */
+ for (i = 0; i < num_accounts; i++) {
+ gchar *item_name, *path;
+ GtkWidget *item;
+ ModestAccountSettings *settings;
+ const gchar *account_name;
+ gboolean is_default;
+
+ settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
+ account_name = modest_account_settings_get_account_name (settings);
+ is_default = (account_name && default_account && !strcmp (account_name, default_account));
+
+ /* Get the item of the view menu */
+ item_name = g_strconcat (account_name, "Menu", NULL);
+ path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
+ item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
+ g_free(path);
+
+ if (item) {
+ GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
+ if (GTK_IS_LABEL (child)) {
+ const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
+ if (is_default) {
+ gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
+ gtk_label_set_markup (GTK_LABEL (child), bold_name);
+ g_free (bold_name);
+ }
+ gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_END);
+ }
+ }
+
+ /* Get the item of the tools menu */
+ path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
+ item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
+ g_free (path);
+
+ if (item) {
+ GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
+ if (GTK_IS_LABEL (child)) {
+ const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
+ if (is_default) {
+ gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
+ gtk_label_set_markup (GTK_LABEL (child), bold_name);
+ g_free (bold_name);
+ }
+ gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_END);
+ }
+ }
+
+ g_free(item_name);
+ g_object_unref (settings);
+ }
+
+ if (num_accounts > 1) {
+ /* Disconnect the tap-and-hold-query if it's connected */
+ if (modest_signal_mgr_is_connected (priv->sighandlers,
+ G_OBJECT (send_receive_button),
+ "tap-and-hold-query"))
+ priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
+ G_OBJECT (send_receive_button),
+ "tap-and-hold-query");
+
+ /* Mandatory in order to view the menu contents */
+ gtk_widget_show_all (priv->accounts_popup);
+
+ /* Setup tap_and_hold just if was not done before*/
+ if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
+ gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
+ } else {
+ /* Connect the tap-and-hold-query in order not to show the CSM */
+ if (!modest_signal_mgr_is_connected (priv->sighandlers,
+ G_OBJECT (send_receive_button),
+ "tap-and-hold-query"))
+ priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
+ G_OBJECT (send_receive_button),
+ "tap-and-hold-query",
+ G_CALLBACK (tap_and_hold_query_cb),
+ NULL);
+ }
+
+ /* Frees */
+ g_slist_free (accounts);
+ g_free (default_account);
+
+
+ /* Make sure that at least one account is viewed if there are any
+ * accounts, for instance when adding the first account: */
+ set_at_least_one_account_visible (self);
+}
+