Logo Search packages:      
Sourcecode: launchpad-integration version File versions

launchpad-integration.c

/* -*- mode: C; c-basic-offset: 4 -*- */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include "launchpad-integration.h"
#include <sys/types.h>
#include <unistd.h>

#include <glib/gi18n.h>
#include <gtk/gtk.h>

static const char *sourcepackagename = NULL;

void
launchpad_integration_set_sourcepackagename (const char *name)
{
    sourcepackagename = name;
}


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

/* wrapper for gettext that sets up our translation domain on first use */
static void
initialise_gettext_domain (void)
{
    static gboolean initialised = FALSE;

    if (initialised) return;

    bindtextdomain (PACKAGE, LOCALEDIR);
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
    bind_textdomain_codeset (PACKAGE, "UTF-8");
#endif
    initialised = TRUE;
}

static G_CONST_RETURN char *
lpint_gettext (const char *str)
{
    initialise_gettext_domain();

    return dgettext (PACKAGE, str);
}

#undef gettext
#define gettext lpint_gettext

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

static void
child_watch (GPid pid, gint status, gpointer user_data)
{
    if (status != 0) {
      GtkWidget *dialog;

      dialog = gtk_message_dialog_new_with_markup
          (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
           "<span weight=\"bold\">%s</span>",
           _("The Launchpad helper application failed"));
      gtk_message_dialog_format_secondary_text
          (GTK_MESSAGE_DIALOG (dialog),
           _("The exit status was %d"), status);
      g_signal_connect (G_OBJECT (dialog), "response",
                    G_CALLBACK (gtk_widget_destroy),
                    NULL);
      gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
      gtk_widget_show (dialog);
    }
}

static void
invoke_launchpad_integration (const char *mode)
{
    const char *argv[] = { "launchpad-integration", NULL, NULL, NULL, NULL };
    pid_t pid;
    char *pidstr = NULL;
    GPid child_pid;
    GError *error = NULL;

    argv[1] = mode;

    if (sourcepackagename != NULL) {
      argv[2] = "--package";
      argv[3] = sourcepackagename;
    } else {
      argv[2] = "--pid";
      argv[3] = pidstr = g_strdup_printf ("%ld", (long)getpid());
    }

    if (!g_spawn_async (NULL, (gchar**)argv, NULL,
                  G_SPAWN_SEARCH_PATH,
                  NULL, NULL, &child_pid, &error)) {
      GtkWidget *dialog;

      dialog = gtk_message_dialog_new_with_markup
          (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
           "<span weight=\"bold\">%s</span>",
           _("An error occurred while starting the Launchpad helper"));
      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                      "%s", error->message);
      g_signal_connect (G_OBJECT (dialog), "response",
                    G_CALLBACK (gtk_widget_destroy),
                    NULL);
      gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
      gtk_widget_show (dialog);
      g_error_free (error);
    } else {
      /* check for error returns from the spawned child */
      g_child_watch_add (child_pid, child_watch, NULL);
    }
    g_free (pidstr);
}

void
launchpad_integration_show_info (void)
{
    invoke_launchpad_integration ("--info");
}

void
launchpad_integration_show_translations (void)
{
    invoke_launchpad_integration ("--translate");
}

void
launchpad_integration_show_bugs (void)
{
    invoke_launchpad_integration ("--bugs");
}

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

static GtkActionEntry actions[] = {
    { "LaunchpadAppInfo", "lpi-help", 
      N_("Get Help Online..."), NULL, 
      N_("Connect to the Launchpad website for online help"),
      G_CALLBACK (launchpad_integration_show_info) },
    { "LaunchpadAppTranslate", "lpi-translate", 
      N_("Translate This Application..."), NULL, 
      N_("Connect to the Launchpad website to help translate this application"),
      G_CALLBACK (launchpad_integration_show_translations) },
    { "LaunchpadAppBugs", "lpi-bug",
      N_("Report a Problem"), NULL, NULL, 
      G_CALLBACK (launchpad_integration_show_bugs) },
};
 
 

static GtkActionGroup*
launchpad_integration_new_action_group (void)
{
    GtkActionGroup *action_group;

    launchpad_integration_add_item_factory ();

    action_group = gtk_action_group_new ("LaunchpadIntegration");
    initialise_gettext_domain ();
    gtk_action_group_set_translation_domain (action_group, PACKAGE);
    gtk_action_group_add_actions (action_group,
                          actions, G_N_ELEMENTS (actions),
                          NULL);
    return action_group;
}

GtkActionGroup*
launchpad_integration_get_action_group (void)
{
    static GtkActionGroup *action_group;

    if (!action_group) {
        action_group = launchpad_integration_new_action_group ();
    }
    return action_group;
}

void
launchpad_integration_add_ui (GtkUIManager *ui, const char *path)
{
    GtkActionGroup *action_group;
    guint merge_id;
    int i;

    g_return_if_fail (GTK_IS_UI_MANAGER (ui));
    g_return_if_fail (path != NULL);

    /* add action group to UI manager */
    action_group = launchpad_integration_new_action_group ();
    gtk_ui_manager_insert_action_group (ui, action_group, -1);
    g_object_unref (action_group);

    /* add actions at given path in UI tree */
    merge_id = gtk_ui_manager_new_merge_id (ui);
    for (i = 0; i < G_N_ELEMENTS (actions); i++) {
      gtk_ui_manager_add_ui (ui,
                         merge_id,
                         path,
                         actions[i].name,
                         actions[i].name,
                         GTK_UI_MANAGER_AUTO,
                         FALSE);
    }
}

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

static void
count_children (GtkWidget *widget, gpointer user_data)
{
    int *counter = user_data;

    ++*counter;
}

void
launchpad_integration_add_items (GtkWidget *helpmenu, int position,
                         gboolean separator_before,
                         gboolean separator_after)
{
    gint n_children = 0, i;
    GtkActionGroup *action_group;
    GtkWidget *item;

    g_return_if_fail (GTK_IS_MENU (helpmenu));

#if 1 // enable this and see gnome-terminal explode (Ubuntu #17309)
    GtkAccelGroup *acg = gtk_menu_get_accel_group (GTK_MENU(helpmenu));
    if(acg == NULL)
      acg = gtk_accel_group_new ();
#endif

    gtk_container_foreach (GTK_CONTAINER (helpmenu),
                     count_children, &n_children);
    if (position < 0) {
      position += n_children;
    }

    g_return_if_fail (position >= 0 && position <= n_children);

    if (separator_before) {
      item = gtk_separator_menu_item_new ();
      gtk_menu_shell_insert (GTK_MENU_SHELL (helpmenu), item, position++);
      gtk_widget_show (item);
    }

    action_group = launchpad_integration_get_action_group ();
    for (i = 0; i < G_N_ELEMENTS (actions); i++) {
      GtkAction *action;

      action = gtk_action_group_get_action (action_group, actions[i].name);
#if 1 // enable this and see gnome-terminal explode (Ubuntu #17309)
      gtk_action_set_accel_group(action, acg);
#endif
      item = gtk_action_create_menu_item (action);
      gtk_menu_shell_insert (GTK_MENU_SHELL (helpmenu), item, position++);
      gtk_widget_show (item);
    }    

    if (separator_after) {
      item = gtk_separator_menu_item_new ();
      gtk_menu_shell_insert (GTK_MENU_SHELL (helpmenu), item, position++);
      gtk_widget_show (item);
    }
}

/* helper to make sure the icons are loaded and available */
void launchpad_integration_add_item_factory ()
{
    /* create the icons for l-p-i */
    GtkIconFactory* icon_factory;
    GtkIconSet *icon_set;
    GtkIconTheme *icon_theme;
    GError *error = NULL;
    GdkPixbuf *pixbuf;
    int i;

    icon_factory = gtk_icon_factory_new ();
    gtk_icon_factory_add_default (icon_factory);
    icon_theme = gtk_icon_theme_get_default ();

    for(i = 0; i < G_N_ELEMENTS (actions); i++) {
      if(actions[i].stock_id == NULL)
          continue;

      pixbuf = gtk_icon_theme_load_icon (icon_theme,
                                 actions[i].stock_id, /* icon name */
                                 16,
                                 0,
                                 &error);

      if(pixbuf != NULL) {
          icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
          gtk_icon_factory_add (icon_factory, actions[i].stock_id, icon_set);
          g_object_unref (pixbuf); 
      } else {
            GtkStockItem s;
            if (!gtk_stock_lookup(actions[i].stock_id, &s))
                g_critical ("failed to load icon '%s': %s", actions[i].stock_id, error->message);
        }
    }
}

Generated by  Doxygen 1.6.0   Back to index