Changeset 2348

Show
Ignore:
Timestamp:
06/06/07 05:19:13 (2 years ago)
Author:
isak
Message:

Merged the fix-root-uninstall branch to trunk. This means the (gtk) manager doesn't spawn itself anymore when uninstalling root owned packages. It now calls 'package remove <foo>' instead and keeps running.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • frontend/trunk/manager/ChangeLog

    r2332 r2348  
     12007-05-25  Isak Savo  <isak.savo@gmail.com> 
     2 
     3        * frontend-gtk/gui_cb.c (show_uninstall_error_message): Ooops.. missing 'break;' in case statement 
     4 
     52007-05-24  Isak Savo  <isak.savo@gmail.com> 
     6 
     7        * frontend-gtk/manager-gtk.h: New file! Moved app global declarations here instead of having them at the top of main.c. 
     8 
     9        * frontend-gtk/main.c: Removed a bunch of the global variables and made them either function private or attached them to GObjects using g_object_set_data() 
     10 
     11        * frontend-gtk/gui_cb.c: New file! Moved all gui callbacks and their helper functions to this file. 
     12        (remove_clicked_cb): Changed so that we now call 'package remove <shortname>' for root owned packages instead of spawning a new manager as root. 
     13        This is much more intuitive behavior. Should fix #21 and may also fix #1. 
     14        (show_uninstall_error_message): Much better error reporting in case something goes wrong when a package is uninstalled. 
     15 
    1162007-05-23  Isak Savo  <isak.savo@gmail.com> 
    217 
  • frontend/trunk/manager/frontend-gtk/Makefile.am

    r2307 r2348  
    55 
    66bin_PROGRAMS = autopackage-manager-gtk 
    7 autopackage_manager_gtk_SOURCES = main.c prefix.c 
     7autopackage_manager_gtk_SOURCES = main.c prefix.c gui_cb.c 
    88autopackage_manager_gtk_LDFLAGS = `pkg-config --libs gtk+-2.0 libglade-2.0 gmodule-2.0 gthread-2.0` 
    99autopackage_manager_gtk_LDADD   = $(top_builddir)/managercore/libcore.a -lpthread 
  • frontend/trunk/manager/frontend-gtk/main.c

    r2328 r2348  
    2424 */ 
    2525 
    26 #ifdef HAVE_CONFIG_H 
    27 # include <config.h> 
    28 #endif 
    2926#include <string.h> 
    3027#include <stdio.h> 
    3128#include <unistd.h> 
    3229#include <stdlib.h> 
    33 #include <assert.h> 
    3430#include <unistd.h> 
    3531#include <time.h> 
    3632#include <sys/types.h> 
    37 #include <sys/wait.h> 
    38 #include <libintl.h> 
    3933 
    4034#include <gtk/gtk.h> 
    4135#include <gmodule.h> 
    42 #include <glade/glade.h> 
    4336#include <gdk-pixbuf/gdk-pixbuf.h> 
    4437 
     
    4639 
    4740#include "prefix.h" 
    48  
    49 #include "../managercore/frontend-interface.h" 
    50  
    51 static void add_to_list (ApplicationInfo *info); 
     41#include "manager-gtk.h" 
     42 
     43 
    5244 
    5345int logging = 0; 
    5446GladeXML *xml; 
    55 GtkListStore *store; 
    5647gchar *selfpath = NULL; 
    5748gchar *prefix = NULL; 
    5849ApplicationInfo *selected; 
    5950 
    60 static gboolean pulse_progress_id = FALSE; 
    61  
    62 #define TRACE(s...) if (logging) { printf("autopackage-manager-gtk: "); printf(s); } 
     51guint pulse_progress_id = 0; 
    6352 
    6453/* This determines what apps to show in the list (see frontend-interface.h for details) */ 
    65 AutoPackageAppType filter = APP_TYPE_DESKTOP; 
    66  
    67 GList *pkg_list = NULL; 
    68 /* 
    69  * Standard gettext macros. 
    70  */ 
    71 #ifdef ENABLE_NLS 
    72 #  include <libintl.h> 
    73 #  undef _ 
    74 #  define _(String) dgettext (GETTEXT_PACKAGE, String) 
    75 #  ifdef gettext_noop 
    76 #    define N_(String) gettext_noop (String) 
    77 #  else 
    78 #    define N_(String) (String) 
    79 #  endif 
    80 #else 
    81 #  define textdomain(String) (String) 
    82 #  define gettext(String) (String) 
    83 #  define dgettext(Domain,Message) (Message) 
    84 #  define dcgettext(Domain,Message,Type) (Message) 
    85 #  define bindtextdomain(Domain,Directory) (Domain) 
    86 #  define _(String) (String) 
    87 #  define N_(String) (String) 
    88 #endif 
    89  
    90 #define W(x) glade_xml_get_widget (xml, x) 
    91  
    92 /* Done in C for portability <sigh> */ 
    93  
    94 enum 
    95 
    96     COL_PIXBUF, 
    97     COL_NAME, 
    98     COL_INFO, 
    99     COL_DETAILS, 
    100     NUM_COLS 
    101 }; 
     54//AutoPackageAppType filter = APP_TYPE_DESKTOP; 
    10255 
    10356/* To simplify pointer comparisons */ 
     
    11063 *                 If 'str' is null, the empty string ("") is returned! 
    11164 * 
    112  * Returns: the (ev. partially) converted string. This must always be free()'d 
     65 * Returns: the converted string. This must always be free()'d 
    11366 *          since this function never returns NULL. 
    11467 */ 
     
    13487        { 
    13588                g_free (retval); 
    136  
    137                 g_error_free (err); 
    138                 err = NULL; 
     89                clear_error(&err); 
    13990                if (bytes_read > 0) 
    14091                        valid_utf8bytes = bytes_read; 
     
    170121} 
    171122 
    172 // Called every time the selected app changes 
    173 static void update_selection(ApplicationInfo *info) 
    174 
    175         if (info == NULL) 
    176         { 
    177                 TRACE("user has nothing selected\n "); 
    178                 gtk_widget_hide (W("rootwarning")); 
    179                 gtk_widget_set_sensitive(W("remove"), FALSE); 
    180         } 
    181         else 
    182         { 
    183                 TRACE("user selected %s, %s\n", info->name, info->root ? "root install" : "user install"); 
    184                 if (info->root && geteuid() != 0) 
    185                         gtk_widget_show(W("rootwarning")); 
    186                 else 
    187                         gtk_widget_hide(W("rootwarning")); 
    188                  
    189                 gtk_widget_set_sensitive(W("remove"), TRUE); 
    190         } 
    191         selected = info; 
    192 
    193  
    194 static void clear_error(GError **error) 
     123 
     124void clear_error(GError **error) 
    195125{ 
    196126    if (*error) 
     
    331261} 
    332262 
    333 static gchar * 
    334 nice_date(char *timestamp) 
     263static gchar *nice_date(char *timestamp) 
    335264{ 
    336265        gchar **components, **date, **stime; 
     
    379308} 
    380309 
    381 static void add_to_list (ApplicationInfo *info) 
     310void add_to_list (ApplicationInfo *info) 
    382311{ 
    383312        GdkPixbuf *pixbuf = lookup_icon(info->icon); 
    384313        gchar *details, *size, *date; 
    385314        gchar *namestr; 
    386  
     315        GtkListStore *store = GTK_LIST_STORE ( gtk_tree_view_get_model(GTK_TREE_VIEW(W("packagelist"))) ); 
    387316         
    388317        /* FIXME: These should use MiB and KiB instead */ 
     
    435364{ 
    436365    ApplicationInfo *info = (ApplicationInfo *) ptr; 
     366    AutoPackageAppType filter = gtk_option_menu_get_history (GTK_OPTION_MENU (W("appfilter"))); 
    437367 
    438368    TRACE("application_found: %p\n", ptr); 
     
    448378        return FALSE; 
    449379    } 
    450  
    451     pkg_list = g_list_append (pkg_list, info); 
     380    GList *pkg_list = g_object_get_data (G_OBJECT(W("packagelist")), "pkglist"); 
     381    g_object_set_data (G_OBJECT(W("packagelist")), "pkglist", g_list_append (pkg_list, info)); 
    452382     
    453383    if (info->type == APP_TYPE_DESKTOP) { 
     
    469399} 
    470400 
    471 /* runs in a separate thread, so marshal it back to the main thread */ 
     401/* Runs in a separate thread, so marshal it back to the main thread 
     402 * (g_idle_add is thread safe) */ 
    472403static void application_found_callback(ApplicationInfo *info) 
    473404{ 
     
    476407} 
    477408 
    478 void filter_changed_cb (GtkOptionMenu *optionmenu, gpointer data) 
    479 
    480         GList *node = pkg_list; 
    481         filter = gtk_option_menu_get_history (GTK_OPTION_MENU (W("appfilter"))); 
    482         TRACE ("Filter changed: %s\n", filter == APP_TYPE_DESKTOP ? "APP_TYPE_DESKTOP" : "APP_TYPE_SYSTEM"); 
    483  
    484         gtk_list_store_clear (GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (W("packagelist"))))); 
    485  
    486         while (node) { 
    487                 ApplicationInfo *i = node->data; 
    488                 switch (filter) { 
    489                         case APP_TYPE_DESKTOP: 
    490                                 if (i->type == APP_TYPE_DESKTOP) 
    491                                         add_to_list(i); 
    492                                 break; 
    493                                  
    494                         case APP_TYPE_SYSTEM: 
    495                                 add_to_list(i); 
    496                                 break; 
    497                 } 
    498          
    499                 node = node->next; 
    500         } 
    501 
    502  
    503 static void packagelist_selection_changed(GtkTreeSelection *selection,  gpointer data) 
    504 
    505     GtkTreeIter iter; 
    506     GtkTreeModel *model; 
    507  
    508     if (gtk_tree_selection_get_selected(selection, &model, &iter)) 
    509     { 
    510             ApplicationInfo *info; 
    511              
    512             gtk_tree_model_get(model, &iter, COL_INFO, &info, -1); 
    513             update_selection(info); 
    514     } 
    515     else 
    516             update_selection(NULL); 
    517 
    518  
    519 static gboolean pulse_progress(gpointer widget) 
    520 
    521         gtk_progress_bar_pulse(GTK_PROGRESS_BAR(widget)); 
     409 
     410gboolean pulse_progress (GtkWidget *progressbar) 
     411
     412        gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progressbar)); 
    522413        return TRUE; 
    523414} 
    524415 
    525 static void enable_disable_gui(gboolean enabled) 
    526 { 
    527     gtk_widget_set_sensitive(W("packagelist"), enabled); 
    528     gtk_widget_set_sensitive(W("remove"), enabled); 
    529     gtk_widget_set_sensitive(W("close"), enabled); 
    530     gtk_widget_set_sensitive(W("appfilter"), enabled); 
    531 } 
    532  
    533 static gboolean uninstall_completed_callback(gpointer _errorcode) 
    534 { 
    535     int errorcode = GPOINTER_TO_INT(_errorcode); 
    536     TRACE("uninstall completed, errorcode=%d\n", errorcode); 
    537  
    538     GtkWidget *view = W("packagelist"); 
    539     if (errorcode == 0) 
    540     { 
    541         GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); 
    542         GtkTreeIter iter; 
    543         GtkTreeModel *model; 
    544  
    545         gtk_tree_selection_get_selected(sel, &model, &iter); 
    546         GdkPixbuf *pixbuf; 
    547         gtk_tree_model_get(model, &iter, COL_PIXBUF, &pixbuf, -1); 
    548         if (pixbuf) gdk_pixbuf_unref(pixbuf); 
    549         gtk_list_store_remove(store, &iter); 
    550  
    551         /* remove from internal list */ 
    552         pkg_list = g_list_remove(pkg_list, selected); 
    553          
    554         /* select the first item */ 
    555         GtkTreePath *path = gtk_tree_path_new_from_string("0"); 
    556         gtk_tree_view_set_cursor(GTK_TREE_VIEW(view), path, NULL, FALSE); 
    557         gtk_tree_path_free(path); 
    558     } 
    559  
    560     gtk_label_set_text(GTK_LABEL(W("status")), 
    561         (const gchar *) _("Select the application you want to uninstall and click \"Remove\".")); 
    562      
    563     enable_disable_gui(TRUE); 
    564     gtk_widget_grab_focus(view); 
    565     gtk_timeout_remove(pulse_progress_id); 
    566     gtk_widget_hide(W("removing")); 
    567     gtk_widget_show(W("appfilter")); 
    568     return FALSE; 
    569 } 
    570  
    571  
    572 static void uninstall_completed_callback_marshaller(int errorcode) 
    573 { 
    574     g_idle_add(uninstall_completed_callback, GINT_TO_POINTER(errorcode)); 
    575 } 
    576  
    577 void remove_clicked(GtkWidget *button, gpointer data) 
    578 { 
    579     assert( selected ); 
    580     TRACE("remove clicked for %s\n", selected->name); 
    581  
    582     GtkLabel *status = GTK_LABEL(W("status")); 
    583  
    584     char *text = g_strdup_printf((const gchar *) _("Removing %s..."), selected->name); 
    585     gtk_label_set_text(status, text); 
    586  
    587     enable_disable_gui(FALSE); 
    588  
    589     gtk_widget_show(W("removing")); 
    590     gtk_widget_hide(W("appfilter")); 
    591     // clearlooks can send us into an infinite loop with this line so hide it instead 
    592     pulse_progress_id = gtk_timeout_add(20, pulse_progress, W("removing")); 
    593  
    594  
    595     if (selected->root && geteuid() != 0) 
    596     { 
    597             TRACE("Need elevated privileges to remove selected package!\n"); 
    598         gpointer gnomesu_spawn_async2; 
    599         GModule *mod = g_module_open("libgnomesu.so.0", G_MODULE_BIND_LAZY ); 
    600  
    601         if (mod && g_module_symbol(mod, "gnomesu_spawn_async2", &gnomesu_spawn_async2)) 
    602         { 
    603                 TRACE("Using libgnomesu to spawn '%s'\n", selfpath); 
    604             /* libgnomesu is available */ 
    605             typedef gboolean (*GnomesuSpawnAsync2) (const gchar *user, const gchar **argv, GPid *pid, 
    606                                                 GdkPixbuf *icon, const gchar *title, gboolean show_command); 
    607             const gchar *argv[3]; 
    608  
    609             argv[0] = selfpath; 
    610             argv[1] = "--rootmode"; 
    611             argv[2] = NULL; 
    612             gtk_widget_hide(W("window1")); 
    613             ((GnomesuSpawnAsync2) gnomesu_spawn_async2)(NULL, argv, NULL, 
    614                 NULL, _("Manage 3rd party software"), FALSE); 
    615             exit(0); 
    616  
    617         } else 
    618         { 
    619             gchar *autosu = NULL; 
    620             gchar *home = g_strdup_printf("%s/.local/libexec/autopackage/autosu", g_get_home_dir()); 
    621  
    622             if (g_file_test("/usr/libexec/autopackage/autosu-gtk", G_FILE_TEST_IS_REGULAR)) 
    623                 autosu = g_strdup("/usr/libexec/autopackage/autosu-gtk"); 
    624             else if (g_file_test(home, G_FILE_TEST_IS_REGULAR)) 
    625                 autosu = g_strdup(home); 
    626             g_free (home); 
    627             TRACE("Using autosu (%s) to spawn '%s'\n", autosu, selfpath); 
    628             if (!autosu) 
    629             { 
    630                     uninstall_completed_callback(GINT_TO_POINTER(-1)); 
    631                     GtkWidget *dlg = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, 
    632                                                             GTK_MESSAGE_ERROR, 
    633                                                             GTK_BUTTONS_OK, 
    634                                                             "Cannot uninstall the selected package because the program used to switch to root (autosu) could not be found\n" 
    635                                                             "You need to start the 'autopackage-manager-gtk' as root directly to remove this application'"); 
    636                     gtk_dialog_run(GTK_DIALOG(dlg)); 
    637                     gtk_widget_destroy(dlg); 
    638                     return; 
    639                                                             
    640             } 
    641             GError *err = NULL; 
    642             gint child_exitstatus; 
    643             gchar *argv[7]; 
    644             argv[0] = autosu; 
    645             argv[1] = "--root-only"; 
    646             argv[2] = "-m"; 
    647             argv[3] = "manage"; 
    648             argv[4] = (gchar *) selfpath; 
    649             argv[5] = "--rootmode"; 
    650             argv[6] = NULL; 
    651             if (!g_spawn_sync (NULL, argv, NULL, G_SPAWN_CHILD_INHERITS_STDIN, 
    652                                NULL, NULL, NULL /* stdout */, NULL /* stderr */, &child_exitstatus, &err)) 
    653             { 
    654                     uninstall_completed_callback(GINT_TO_POINTER(-2)); 
    655                     GtkWidget *dlg = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, 
    656                                                             GTK_MESSAGE_ERROR, 
    657                                                             GTK_BUTTONS_OK, 
    658                                                             "Cannot uninstall the selected package because the program used to switch " 
    659                                                             "to root (autosu) could not be launched.\n\n" 
    660                                                             "The error reported was: %s", err->message); 
    661                     gtk_dialog_run(GTK_DIALOG(dlg)); 
    662                     g_error_free(err); 
    663                     gtk_widget_destroy(dlg); 
    664                     return; 
    665                      
    666             } 
    667             child_exitstatus = WEXITSTATUS(child_exitstatus); 
    668             TRACE ("Exitstatus of autosu: %d\n", child_exitstatus); 
    669             if (child_exitstatus == 0) 
    670                     exit(0); 
    671             uninstall_completed_callback(GINT_TO_POINTER(-3)); 
    672         } 
    673  
    674     } else 
    675         uninstallPackage(selected, uninstall_completed_callback_marshaller); 
    676 } 
    677416 
    678417static gboolean post_gui_init(gpointer ptr) 
     
    680419    TRACE("post gui init\n"); 
    681420 
    682     store = gtk_list_store_new(NUM_COLS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING); 
     421    GtkListStore *store = gtk_list_store_new (NUM_COLS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING); 
    683422     
    684423    GtkCellRenderer *textrenderer = gtk_cell_renderer_text_new(); 
     
    687426     
    688427    GtkTreeView *view = GTK_TREE_VIEW(W("packagelist")); 
    689     assert( view ); 
     428    g_assert (view); 
    690429 
    691430 
     
    704443 
    705444    gtk_tree_view_insert_column_with_attributes(view, -1, _("Icon"), 
    706             iconrenderer, "pixbuf", COL_PIXBUF, NULL); 
     445                                               iconrenderer, "pixbuf", COL_PIXBUF, NULL); 
    707446 
    708447    if (expando) 
     
    728467    GtkTreeSelection *select = gtk_tree_view_get_selection(view); 
    729468    gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE); 
    730     g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(packagelist_selection_changed), NULL); 
     469    g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(pkglst_selection_changed_cb), NULL); 
    731470 
    732471    g_signal_connect(G_OBJECT(W("window1")), "delete_event", G_CALLBACK(gtk_main_quit), NULL); 
     
    816555    gtk_widget_show(W("searching")); 
    817556    g_idle_add(post_gui_init, NULL); 
    818     pulse_progress_id = gtk_timeout_add(20, pulse_progress, W("searching")); 
     557    pulse_progress_id = gtk_timeout_add(20, (GSourceFunc) pulse_progress, W("searching")); 
    819558    gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(W("searching")), 0.01); 
    820559     
  • frontend/trunk/manager/frontend-gtk/manager-gtk.glade

    r2315 r2348  
    191191              <property name="relief">GTK_RELIEF_NORMAL</property> 
    192192               
    193               <signal name="clicked" handler="remove_clicked" last_modification_time="Tue, 28 Dec 2004 21:22:10 GMT"/> 
     193              <signal name="clicked" handler="remove_clicked_cb" last_modification_time="Tue, 28 Dec 2004 21:22:10 GMT"/> 
    194194 
    195195              <child>