/* pharmacy.c * This file is part of "Pharmacy: A GNOME CVS front-end" * Copyright 1998 Reklaw (N. Adam Walker) * Copyright 2000, 2001 Matthias Kranz * "Pharmacy" is released under the GPL. * See the LICENCE for more details. */ #include #include #include #include #include "dirtree.h" #include "serverdlg.h" #include "pharmacy.h" #include "console.h" #include "update.h" #include "checkout.h" #include "filelist.h" #include "login.h" #include "preferences.h" #include "status.h" #include "commit.h" #include "remove.h" #include "add.h" #include "diff.h" /* Icons */ #include "stock.h" static gchar *idle_text = NULL; static void set_icon (GdkWindow * w); void about_cb (GtkWidget * widget, void *data); void quit_cb (GtkWidget * widget, void *data); void login_cb (GtkWidget * widget, void *data); void prepare_app (); void parse_args (int argc, char *argv[]); GtkMenuFactory *create_menu (); void load_prefs (); GnomeUIInfo toolbar[] = { GNOMEUIINFO_ITEM_STOCK (N_("Status"), N_("Refresh Status"), status_cb, /*redlight_xpm */ GNOME_STOCK_PIXMAP_REFRESH), GNOMEUIINFO_ITEM_STOCK (N_("Update"), N_("Update"), update_cb, PHARMACY_STOCK_PIXMAP_BOLT), GNOMEUIINFO_ITEM_STOCK (N_("Checkout"), N_("Checkout"), checkout_cb, PHARMACY_STOCK_PIXMAP_CHECKOUT), GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_ITEM_STOCK (N_("Commit"), N_("Commit changes"), commit_cb, GNOME_STOCK_BUTTON_APPLY), GNOMEUIINFO_ITEM_STOCK (N_("Remove"), N_("Remove files"), remove_cb, GNOME_STOCK_PIXMAP_TRASH), GNOMEUIINFO_ITEM_STOCK (N_("Recover"), N_("Recover removed files"), remove_recover_cb, GNOME_STOCK_PIXMAP_UNDELETE), GNOMEUIINFO_ITEM_STOCK (N_("Add"), N_("Add files"), add_cb, GNOME_STOCK_PIXMAP_ADD), GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_ITEM_STOCK (N_("Stop"), N_("Stop"), stop_menu_cb, GNOME_STOCK_PIXMAP_STOP), GNOMEUIINFO_ITEM_STOCK (N_("Exit"), N_("Exit"), quit_cb, GNOME_STOCK_PIXMAP_QUIT), GNOMEUIINFO_END }; /* Prototypes */ static gint save_state (GnomeClient * client, gint phase, GnomeRestartStyle save_style, gint shutdown, GnomeInteractStyle interact_style, gint fast, gpointer client_data); static gint die (GnomeClient * client, gpointer client_data); static GtkWidget *app; int restarted = 0; /* Old Session state (it shouldn't be global variables, but i couldn't find a simple better way) */ int os_x = 0, os_y = 0, os_w = 0, os_h = 0; /* The menu definitions: File/Exit and Help/About are mandatory */ static GnomeUIInfo help_menu[] = { GNOMEUIINFO_SEPARATOR, {GNOME_APP_UI_HELP, NULL, NULL, "pharmacy"}, GNOMEUIINFO_END }; GnomeUIInfo program_menu[] = { { GNOME_APP_UI_ITEM, N_("_About..."), N_("Info about Pharmacy"), about_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT, 0, (GdkModifierType) 0, NULL}, GNOMEUIINFO_SUBTREE (N_("_Help"), help_menu), GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("E_xit"), N_("Exit Pharmacy"), quit_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_QUIT, 'Q', GDK_CONTROL_MASK, NULL}, GNOMEUIINFO_END }; GnomeUIInfo view_menu[] = { { GNOME_APP_UI_ITEM, N_("Get _Status"), N_("Update the status of the current directory."), status_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_REFRESH, 'S', GDK_CONTROL_MASK, NULL}, GNOMEUIINFO_END }; GnomeUIInfo repository_menu[] = { { GNOME_APP_UI_ITEM, N_("_Servers..."), N_("Setup servers."), server_dlg_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, (GdkModifierType) 0, NULL}, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("_Login"), N_("Log in to the repository."), login_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL}, { GNOME_APP_UI_ITEM, N_("_Update"), N_("Update directory or selected files."), update_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, PHARMACY_STOCK_PIXMAP_BOLT, 'U', GDK_CONTROL_MASK, NULL}, { GNOME_APP_UI_ITEM, N_("_Get lastest version"), N_ ("Get the latest version of a directory or file overwriting any changes."), get_latest_version_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL}, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("_Checkout..."), N_("Get a new directory from CVS."), checkout_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, PHARMACY_STOCK_PIXMAP_CHECKOUT, 0, 0, NULL}, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("_Remove"), N_("Remove a file from the repository."), remove_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_TRASH, 0, 0, NULL}, { GNOME_APP_UI_ITEM, N_("R_ecover"), N_("Recover a removed file."), remove_recover_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_UNDELETE, 0, 0, NULL}, { GNOME_APP_UI_ITEM, N_("_Add..."), N_("Add a file to the repository."), add_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_ADD, 0, 0, NULL}, { GNOME_APP_UI_ITEM, N_("C_ommit"), N_("Save your changes to CVS."), commit_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_BUTTON_APPLY, 0, 0, NULL}, GNOMEUIINFO_END }; GnomeUIInfo tools_menu[] = { { GNOME_APP_UI_ITEM, N_("_View local file"), N_("View a local file using your selected pager."), pharmacy_nop, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL}, { GNOME_APP_UI_ITEM, N_("_Edit local file"), N_("Edit a local file using your selected editor."), pharmacy_nop, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL}, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("_Preferences..."), N_("Setup your CVS preferences for this Server/PWD pair."), preferences_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PREF, 0, 0, NULL}, GNOMEUIINFO_END }; GnomeUIInfo console_menu[] = { { GNOME_APP_UI_ITEM, N_("_Go"), N_("Perform the command entered on the console."), go_menu_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_FORWARD, 'G', GDK_CONTROL_MASK, NULL}, { GNOME_APP_UI_ITEM, N_("_Stop"), N_("Stop executing the current command."), stop_menu_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_STOP, 'K', GDK_CONTROL_MASK, NULL}, GNOMEUIINFO_SEPARATOR, { GNOME_APP_UI_ITEM, N_("_Clear"), N_("Clear the output of the console."), console_clear_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_CLEAR, 0, 0, NULL}, { GNOME_APP_UI_ITEM, N_("_Print"), N_("Print the console log."), console_print_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PRINT, 0, 0, NULL}, GNOMEUIINFO_END }; //#ifdef DEBUG #if 1 static void test_rebuild_cb () { filelist_rebuild_list (pharmacy_get_filelist (), pharmacy_get_console ()->pCurrentNode); } static GnomeUIInfo test_menu[] = { { GNOME_APP_UI_ITEM, N_("Test agent"), N_("test.agent"), pharmacy_nop, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL}, { GNOME_APP_UI_ITEM, N_("Test filelist rebuild"), N_("test rebuild"), test_rebuild_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL}, GNOMEUIINFO_END }; #endif GnomeUIInfo main_menu[] = { GNOMEUIINFO_SUBTREE (N_("_Program"), program_menu), GNOMEUIINFO_SUBTREE (N_("_Repository"), repository_menu), GNOMEUIINFO_SUBTREE (N_("_Console"), console_menu), GNOMEUIINFO_SUBTREE (N_("_View"), view_menu), GNOMEUIINFO_SUBTREE (N_("_Tools"), tools_menu), /*GNOMEUIINFO_SUBTREE(N_("Help"), help_menu), */ //#ifdef DEBUG #if 1 GNOMEUIINFO_SUBTREE (N_("Test"), test_menu), #endif GNOMEUIINFO_END }; /* True if parsing determined that all the work is already done. */ char *just_exit = NULL; /* These are the arguments that our application supports. */ static const struct poptOption options[] = { {"discard-session", '\0', POPT_ARG_STRING, &just_exit, 0, N_("Discard session"), N_("ID")}, {NULL, '\0', 0, NULL, 0} }; static GnomeAppClass *parent_class = NULL; static void pharmacy_class_init (PharmacyClass * klass); static void pharmacy_destroy (GtkObject * object); static void pharmacy_init (Pharmacy * object); static void pharmacy_build_ui (Pharmacy * app); static void pharmacy_ui_update_cb () { /* Test menu */ if (main_menu[5].widget) { if (g_bExper) { gtk_widget_show (main_menu[5].widget); } else { gtk_widget_hide (main_menu[5].widget); } } } static void pharmacy_class_init (PharmacyClass * klass) { gint signal; GtkObjectClass *objectclass = GTK_OBJECT_CLASS (klass); objectclass->destroy = pharmacy_destroy; signal = gtk_signal_new (PHARMACY_UI_UPDATE_SIGNAL, GTK_RUN_FIRST, objectclass->type, GTK_SIGNAL_OFFSET (PharmacyClass, ui_update), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); gtk_object_class_add_signals (objectclass, &signal, 1); klass->ui_update = pharmacy_ui_update_cb; } static void pharmacy_destroy (GtkObject * object) { } GtkWidget * pharmacy_new () { GtkWidget *retval = NULL; Pharmacy *pharmacy = NULL; retval = gtk_type_new (pharmacy_get_type ()); pharmacy = PHARMACY (retval); gnome_app_construct (GNOME_APP (&(pharmacy->app)), "pharmacy", _("Pharmacy")); gtk_object_set (GTK_OBJECT (pharmacy), "GtkWindow::allow_shrink", TRUE, NULL); /*pharmacy_build_ui(pharmacy); */ return retval; } guint pharmacy_get_type () { static guint pharmacy_type = 0; if (!pharmacy_type) { GtkTypeInfo info = { "Pharmacy", sizeof (Pharmacy), sizeof (PharmacyClass), (GtkClassInitFunc) pharmacy_class_init, (GtkObjectInitFunc) pharmacy_init, (GtkArgSetFunc) NULL, (GtkArgGetFunc) NULL }; pharmacy_type = gtk_type_unique (gnome_app_get_type (), &info); parent_class = gtk_type_class (gnome_app_get_type ()); } return pharmacy_type; } void pharmacy_death () { locations_save_list (pharmacy_get_locations ()); dirtree_save_size (PHARMACY (app)->dirtree); filelist_save_size (PHARMACY (app)->filelist); gnome_config_sync (); } static void add_loc_to_tree_cb (LocationData * pData, GtkCTree * pTree) { GtkCTreeNode *pItem = NULL; static GdkPixmap *pBoltPix = NULL, *pBoltMask = NULL; gchar *paText[] = { NULL, NULL }; if (!pBoltPix) { gnome_stock_pixmap_gdk (PHARMACY_STOCK_PIXMAP_FISH, GNOME_STOCK_PIXMAP_REGULAR, &pBoltPix, &pBoltMask); } if (pData && pTree) { paText[0] = g_strdup (locationdata_get_name (pData)); pItem = gtk_ctree_insert_node (pTree, NULL, NULL, paText, 4, pBoltPix, pBoltMask, pBoltPix, pBoltMask, FALSE, FALSE); gtk_ctree_node_set_row_data (pTree, pItem, dirtreenode_new_root (pData)); dirtree_set_last_location (pData); dirtree_fill_tree (pTree, pItem, locationdata_get_workdir (pData), 0, 0); } } CVSConsole * pharmacy_get_console () { return PHARMACY (app)->cvscon; } FileList * pharmacy_get_filelist () { return FILE_LIST (GTK_CLIST (PHARMACY (app)->filelist)); } int main (int argc, char *argv[]) { GnomeClient *client; Pharmacy *pApp = NULL; /* Initialize the i18n stuff */ bindtextdomain (PACKAGE, GNOMELOCALEDIR); textdomain (PACKAGE); idle_text = g_strconcat (PACKAGE, " ", VERSION, " : ", _("Ready"), NULL); /* gnome_init() is always called at the beginning of a program. it takes care of initializing both Gtk and GNOME. It also parses the command-line arguments. */ gnome_init_with_popt_table ("pharmacy", VERSION, argc, argv, options, 0, NULL); if (just_exit) { /* This should discard the saved information about this client. Unfortunatlly is doesn't do so, yet. */ gnome_config_clean_file (just_exit); gnome_config_sync (); /* We really do not need to connect to the session manager in this case, because we'll just exit after the gnome_init call. */ gnome_client_disable_master_connection (); return 0; } /* Get the master client, that was hopefully connected to the session manager int the 'gnome_init' call. All communication to the session manager will be done with this master client. */ client = gnome_master_client (); /* Arrange to be told when something interesting happens. */ gtk_signal_connect (GTK_OBJECT (client), "save_yourself", GTK_SIGNAL_FUNC (save_state), (gpointer) argv[0]); gtk_signal_connect (GTK_OBJECT (client), "die", GTK_SIGNAL_FUNC (die), NULL); if (GNOME_CLIENT_CONNECTED (client)) { /* Get the client, that may hold the configuration for this program. This client may be NULL. That meens, that this client has not been restarted. I.e. 'gnome_cloned_client' is only non NULL, if this application was called with the '--sm-client-id' or the '-sm-cloned-id' command line option, but this is something, the gnome libraries and the session manager take care for you. */ //GnomeClient *cloned = gnome_cloned_client (); //if (cloned) { /* If cloned is non NULL, we have been restarted. */ // restarted = 1; /* We restore information that was stored once before. Note, that we use the cloned client here, because it may be that we are a clone of another client, which has another client id than we have. */ //gnome_config_push_prefix (gnome_client_get_config_prefix (cloned)); //os_x = gnome_config_get_int ("Geometry/x"); //os_y = gnome_config_get_int ("Geometry/y"); //os_w = gnome_config_get_int ("Geometry/w"); //os_h = gnome_config_get_int ("Geometry/h"); //gnome_config_pop_prefix (); } /* We could even use 'gnome_client_get_config_prefix' is cloned is NULL. In this case, we would get "/pharmacy-4-SM/" as config prefix. This is usefull, if the pharmacy-4-SM config file holds some default values for our application. */ } app = pharmacy_new (); pApp = PHARMACY (app); pApp->pLocations = g_list_alloc (); load_prefs (); pharmacy_build_ui (pApp); gtk_main (); return 0; } void pharmacy_init (Pharmacy * app) { app->hpane = NULL; app->vpane = NULL; app->dirtree = NULL; app->filelist = NULL; app->buildlist = NULL; app->statusbar = NULL; app->notebook = NULL; app->cvscon = NULL; app->pLocations = NULL; } static void pharmacy_build_ui (Pharmacy * app) { GtkWidget *button; GtkWidget *console = NULL; GtkWidget *label; GtkWidget *filelist_box = NULL; gchar *titles[5]; gboolean bRelieved = FALSE; gint nStyle = GTK_TOOLBAR_BOTH; pharmacy_stock_init (); /* Make the main window and binds the delete event so you can close the program from your WM */ gtk_widget_realize (GTK_WIDGET (app)); gtk_signal_connect (GTK_OBJECT (app), "delete_event", GTK_SIGNAL_FUNC (quit_cb), NULL); if (restarted) { //gtk_widget_set_uposition (GTK_WIDGET (app), os_x, os_y); // gtk_widget_set_usize (GTK_WIDGET (app), os_w, os_h); } /* AppBar */ app->statusbar = gnome_appbar_new ( /*Progress */ FALSE, /*Status */ TRUE, /*GnomePreferencesType */ TRUE); gnome_app_set_statusbar (GNOME_APP (app), app->statusbar); gnome_appbar_set_default (GNOME_APPBAR (app->statusbar), idle_text); /* Now that we've the main window we'll make the menues */ gnome_app_create_menus (GNOME_APP (app), main_menu); gnome_app_create_toolbar_with_data (GNOME_APP (app), toolbar, app); app->hpane = gtk_hpaned_new (); app->vpane = gtk_vpaned_new (); app->dirtree = gtk_ctree_new (1, 0); // gtk_widget_set_usize(app->dirtree,500,500); g_assert (app->dirtree); titles[0] = _("File name"); titles[1] = _("Version"); titles[2] = _("Status"); titles[3] = _("Date"); titles[4] = NULL; app->filelist = filelist_new_with_titles (4, titles); gtk_clist_set_column_width (GTK_CLIST (app->filelist), 0, 100); gtk_clist_set_column_width (GTK_CLIST (app->filelist), 1, 66); app->dir_label = gtk_label_new (_("Please select a directory.")); app->buildlist = gtk_clist_new (1); app->notebook = gtk_notebook_new (); /* FIXME: Add an option to display the que gtk_notebook_append_page(GTK_NOTEBOOK(app->notebook), app->buildlist, GTK_WIDGET(gtk_label_new(_("Que")))); */ app->cvscon = console_new (); console = console_get_widget (app->cvscon); gtk_notebook_append_page (GTK_NOTEBOOK (app->notebook), console, GTK_WIDGET (gtk_label_new (_("Console")))); gtk_notebook_append_page (GTK_NOTEBOOK (app->notebook), app->que = gtk_label_new ("TODO"), GTK_WIDGET (gtk_label_new (_("Queue")))); gtk_notebook_append_page (GTK_NOTEBOOK (app->notebook), app->log = gtk_label_new ("TODO"), GTK_WIDGET (gtk_label_new (_("Log")))); app->diff = diffcontrol_new (); gtk_notebook_append_page (GTK_NOTEBOOK (app->notebook), diffcontrol_get_widget (app->diff), GTK_WIDGET (gtk_label_new (_("Difference")))); gtk_paned_pack1 (GTK_PANED (app->vpane), app->hpane, FALSE, TRUE); gtk_paned_pack2 (GTK_PANED (app->vpane), app->notebook, FALSE, TRUE); gtk_paned_pack1 (GTK_PANED (app->hpane), util_contain_in_scrolled (app->dirtree), FALSE, TRUE); filelist_box = gtk_vbox_new (0, 0); gtk_box_pack_start (GTK_BOX (filelist_box), app->dir_label, FALSE, TRUE, 3); gtk_box_pack_start (GTK_BOX (filelist_box), util_contain_in_scrolled (app->filelist), TRUE, TRUE, 0); gtk_widget_show (filelist_box); gtk_paned_pack2 (GTK_PANED (app->hpane), filelist_box, TRUE, TRUE); gnome_app_set_contents (GNOME_APP (app), app->vpane); dirtree_load_size (app->dirtree); filelist_load_size (app->filelist); gtk_signal_connect (GTK_OBJECT (app), PHARMACY_UI_UPDATE_SIGNAL, checkout_ui_update_cb, NULL); gtk_signal_connect (GTK_OBJECT (app), PHARMACY_UI_UPDATE_SIGNAL, login_ui_update_cb, NULL); gtk_signal_connect (GTK_OBJECT (app), PHARMACY_UI_UPDATE_SIGNAL, update_ui_update_cb, NULL); gtk_signal_connect (GTK_OBJECT (app), PHARMACY_UI_UPDATE_SIGNAL, commit_ui_update_cb, NULL); gtk_signal_connect (GTK_OBJECT (app), PHARMACY_UI_UPDATE_SIGNAL, remove_ui_update_cb, NULL); gtk_signal_connect (GTK_OBJECT (app), PHARMACY_UI_UPDATE_SIGNAL, preferences_ui_update_cb, NULL); gtk_signal_connect (GTK_OBJECT (app), PHARMACY_UI_UPDATE_SIGNAL, add_ui_update_cb, NULL); /* show windows */ gtk_widget_show (app->buildlist); gtk_widget_show (app->notebook); gtk_widget_show (app->filelist); gtk_widget_show (app->dirtree); gtk_widget_show (app->hpane); gtk_widget_show (app->vpane); gtk_widget_show (app->log); gtk_widget_show (app->que); gtk_widget_show (app->dir_label); /* show main window LAST */ gtk_widget_show (GTK_WIDGET (app)); locations_load_list (app->pLocations); dirtree_init (GTK_CTREE (app->dirtree)); status_init (); pharmacy_rebuild_entire_dirtree (); /*FIXME: This function causes a SEGFAULT much later down the road under GNOME versions 1.0.3 and 1.0.5. set_icon (GTK_WIDGET (app)->window); */ pharmacy_update_ui ("init"); } /* Callbacks functions */ void quit_cb (GtkWidget * widget, void *data) { pharmacy_death (); gtk_main_quit (); return; } void about_cb (GtkWidget * widget, void *data) { GtkWidget *about; const gchar *authors[] = { /* Here should be your names */ "N. Adam Walker ", NULL }; about = gnome_about_new (_("Pharmacy"), VERSION, /* copyright notice */ "(C) 1998-1999 by N. Adam Walker", authors, /* another comments */ _("Pharmacy intends to be a GNOME compliant " "front-end to CVS. Currently, it provides " "a limited user interface to CVS commands " "and a \"console\" for the lazy power-user." " Pharmacy is released under the GPL " "(GNU General Public License)"), NULL); gtk_widget_show (about); return; } /* Session management */ static gint save_state (GnomeClient * client, gint phase, GnomeRestartStyle save_style, gint shutdown, GnomeInteractStyle interact_style, gint fast, gpointer client_data) { gchar *session_id; gchar *argv[3]; gint x, y, w, h; session_id = gnome_client_get_id (client); /* Get the state here. */ gdk_window_get_geometry (app->window, &x, &y, &w, &h, NULL); /* Save the state using gnome-config stuff. */ gnome_config_push_prefix (gnome_client_get_config_prefix (client)); gnome_config_set_int ("Geometry/x", x); gnome_config_set_int ("Geometry/y", y); gnome_config_set_int ("Geometry/w", w); gnome_config_set_int ("Geometry/h", h); gnome_config_pop_prefix (); pharmacy_death (); gnome_config_sync (); /* Here is the real SM code. We set the argv to the parameters needed to restart/discard the session that we've just saved and call the gnome_session_set_*_command to tell the session manager it. */ argv[0] = (char *) client_data; argv[1] = "--discard-session"; argv[2] = gnome_client_get_config_prefix (client); gnome_client_set_discard_command (client, 3, argv); /* Set commands to clone and restart this application. Note that we use the same values for both -- the session management code will automatically add whatever magic option is required to set the session id on startup. */ gnome_client_set_clone_command (client, 1, argv); gnome_client_set_restart_command (client, 1, argv); return TRUE; } static gint die (GnomeClient * client, gpointer client_data) { /* Just exit in a friendly way. We don't need to save any state here, because the session manager should have sent us a save_yourself-message before. */ gtk_exit (0); return FALSE; } void pharmacy_nop () { gnome_app_message (GNOME_APP (app), _("this function does nothing.")); } /* Misc functions */ void pharmacy_rebuild_entire_dirtree () { dirtree_purge (pharmacy_get_dirtree (), NULL); g_list_foreach (PHARMACY (app)->pLocations, (GFunc) add_loc_to_tree_cb, PHARMACY (app)->dirtree); } GList * pharmacy_get_locations () { return PHARMACY (app)->pLocations; } DiffControl * pharmacy_get_diff () { return PHARMACY (app)->diff; } GnomeAppBar * pharmacy_get_appbar () { return GNOME_APPBAR (PHARMACY (app)->statusbar); } GnomeApp * pharmacy_get_app () { return GNOME_APP (app); } GtkCTree * pharmacy_get_dirtree () { return GTK_CTREE (PHARMACY (app)->dirtree); } void pharmacy_update_ui (gchar * pgcHint) { gdk_flush (); gtk_signal_emit_by_name (GTK_OBJECT (app), PHARMACY_UI_UPDATE_SIGNAL, pgcHint); } Agent * pharmacy_get_agent () { g_return_val_if_fail (app && PHARMACY (app)->cvscon, NULL); return PHARMACY (app)->cvscon->pAgent; } /* Stolen from Balsa */ static void set_icon (GdkWindow * w) { GdkImlibImage *im = NULL; GdkWindow *ic_win; GdkWindowAttr att; XIconSize *is; gint i, count, j; GdkPixmap *pmap, *mask; if ((XGetIconSizes (GDK_DISPLAY (), GDK_ROOT_WINDOW (), &is, &count)) && (count > 0)) { i = 0; /* use first icon size - not much point using the others */ att.width = is[i].max_width; att.height = is[i].max_height; /* * raster had: * att.height = 3 * att.width / 4; * but this didn't work (it scaled the icons incorrectly */ /* make sure the icon is inside the min and max sizes */ if (att.height < is[i].min_height) att.height = is[i].min_height; if (att.height > is[i].max_height) att.height = is[i].max_height; if (is[i].width_inc > 0) { j = ((att.width - is[i].min_width) / is[i].width_inc); att.width = is[i].min_width + (j * is[i].width_inc); } if (is[i].height_inc > 0) { j = ((att.height - is[i].min_height) / is[i].height_inc); att.height = is[i].min_height + (j * is[i].height_inc); } XFree (is); } else /* no icon size hints at all? ok - invent our own size */ { att.width = 32; att.height = 24; } att.wclass = GDK_INPUT_OUTPUT; att.window_type = GDK_WINDOW_TOPLEVEL; att.x = 0; att.y = 0; att.visual = gdk_imlib_get_visual (); att.colormap = gdk_imlib_get_colormap (); ic_win = gdk_window_new (NULL, &att, GDK_WA_VISUAL | GDK_WA_COLORMAP); im = gdk_imlib_load_image (gnome_unconditional_pixmap_file ("pharmacy.png")); gdk_window_set_icon (w, ic_win, NULL, NULL); gdk_imlib_render (im, att.width, att.height); pmap = gdk_imlib_move_image (im); mask = gdk_imlib_move_mask (im); gdk_window_set_back_pixmap (ic_win, pmap, FALSE); gdk_window_clear (ic_win); gdk_window_shape_combine_mask (ic_win, mask, 0, 0); gdk_imlib_free_pixmap (pmap); gdk_imlib_destroy_image (im); }