my homework was late :-)
[midnight-commander.git] / gnome / glayout.c
blob29171f089cf5df7887577db09141f6612da7071c
1 /*
2 * Layout routines for the GNOME edition of the GNU Midnight Commander
4 * (C) 1998 the Free Software Foundation
6 * Author: Miguel de Icaza (miguel@kernel.org)
7 */
8 #include <config.h>
9 #include "x.h"
10 #include <stdio.h>
11 #include <sys/stat.h>
12 #include <unistd.h>
13 #include "global.h"
14 #include "dir.h"
15 #include "panel.h"
16 #include "gscreen.h"
17 #include "main.h"
18 #include "gmain.h"
19 #include "cmd.h"
20 #include "dialog.h"
21 #include "boxes.h"
22 #include "panelize.h"
23 #include "gcmd.h"
24 #include "gdesktop.h"
25 #include "setup.h"
26 #include "../vfs/vfs.h"
27 #include "gprefs.h"
28 #include "gsession.h"
29 #include "listing-iconic.xpm"
30 #include "listing-brief-list.xpm"
31 #include "listing-list.xpm"
32 #include "listing-custom.xpm"
35 #define UNDEFINED_INDEX -1
37 /* Keep these two arrays in sync! */
39 GnomeUIInfo panel_view_menu_uiinfo[] = {
40 GNOMEUIINFO_RADIOITEM (N_("_Icon View"),
41 N_("Switch view to an icon display"),
42 gnome_icon_view_cmd, NULL),
43 GNOMEUIINFO_RADIOITEM (N_("_Brief View"),
44 N_("Switch view to show just file name and type"),
45 gnome_brief_view_cmd, NULL),
46 GNOMEUIINFO_RADIOITEM (N_("_Detailed View"),
47 N_("Switch view to show detailed file statistics"),
48 gnome_detailed_view_cmd, NULL),
49 GNOMEUIINFO_RADIOITEM (N_("_Custom View"),
50 N_("Switch view to show user-defined statistics"),
51 gnome_custom_view_cmd, NULL),
52 GNOMEUIINFO_END
55 GnomeUIInfo panel_view_toolbar_uiinfo[] = {
56 GNOMEUIINFO_RADIOITEM (N_("Icons"),
57 N_("Switch view to an icon display"),
58 gnome_icon_view_cmd, listing_iconic_xpm),
59 GNOMEUIINFO_RADIOITEM (N_("Brief"),
60 N_("Switch view to show just file name and type"),
61 gnome_brief_view_cmd, listing_brief_list_xpm),
62 GNOMEUIINFO_RADIOITEM (N_("Detailed"),
63 N_("Switch view to show detailed file statistics"),
64 gnome_detailed_view_cmd, listing_list_xpm),
65 GNOMEUIINFO_RADIOITEM (N_("Custom"),
66 N_("Switch view to show user-defined statistics"),
67 gnome_custom_view_cmd, listing_custom_xpm),
68 GNOMEUIINFO_END
71 GList *containers = 0;
73 int output_lines = 0;
74 int command_prompt = 1;
75 int keybar_visible = 1;
76 int message_visible = 1;
77 int xterm_hintbar = 0;
79 PanelContainer *current_panel_ptr, *other_panel_ptr;
81 WPanel *
82 get_current_panel (void)
84 if (current_panel_ptr)
85 return current_panel_ptr->panel;
86 else
87 return NULL;
90 WPanel *
91 get_other_panel (void)
93 if (other_panel_ptr)
94 return other_panel_ptr->panel;
95 else
96 return NULL;
99 /* FIXME: we probably want to get rid of this code */
101 get_current_index (void)
103 GList *p;
104 int i;
106 for (i = 0, p = containers; p; p = p->next, i++){
107 if (p->data == current_panel_ptr)
108 return i;
110 printf ("FATAL: current panel is not in the list\n");
111 g_assert_not_reached ();
112 return -1; /* keep -Wall happy */
116 get_other_index (void)
118 GList *p;
119 int i;
121 for (i = 0, p = containers; p; p = p->next, i++){
122 if (p->data == other_panel_ptr)
123 return i;
125 return UNDEFINED_INDEX;
128 void
129 set_current_panel (WPanel *panel)
131 GList *p;
133 if (g_list_length (containers) > 1)
134 other_panel_ptr = current_panel_ptr;
136 for (p = containers; p; p = p->next){
137 if (((PanelContainer *)p->data)->panel == panel){
138 current_panel_ptr = p->data;
139 break;
145 * Tries to assign other_panel (ie, if there is anything to assign to
147 static void
148 assign_other (void)
150 GList *p;
152 other_panel_ptr = NULL;
153 for (p = containers; p; p = p->next)
154 if (p->data != current_panel_ptr){
155 other_panel_ptr = p->data;
156 break;
161 * This keeps track of the current_panel_ptr and other_panel_ptr as
162 * well as the list of active containers
164 void
165 layout_panel_gone (WPanel *panel)
167 PanelContainer *pc_holder = 0;
168 int len = g_list_length (containers);
169 GList *p;
171 for (p = containers; p; p = p->next){
172 PanelContainer *pc = p->data;
174 if (pc->panel == panel){
175 pc_holder = pc;
176 break;
180 if (len > 1){
181 containers = g_list_remove (containers, pc_holder);
184 /* Check if this is not the current panel */
185 if (current_panel_ptr->panel == panel){
186 if (other_panel_ptr){
187 current_panel_ptr = other_panel_ptr;
188 assign_other ();
189 } else {
190 current_panel_ptr = NULL;
192 } else if (other_panel_ptr->panel == panel){
193 /* Check if it was the other panel */
194 if (len == 1){
195 other_panel_ptr = 0;
196 } else
197 assign_other ();
198 } else {
201 if (len == 1){
202 g_free (containers->data);
203 g_list_free (containers);
204 containers = NULL;
205 } else
206 g_free (pc_holder);
209 void
210 set_hintbar (char *str)
212 /*gtk_label_set (GTK_LABEL (current_panel_ptr->panel->status), str);*/
213 /* x_flush_events (); */
216 void
217 print_vfs_message (char *msg, ...)
219 va_list ap;
220 char str [256];
222 va_start(ap, msg);
223 vsprintf(str, msg, ap);
224 va_end(ap);
225 if (midnight_shutdown)
226 return;
228 set_hintbar(str);
231 void
232 rotate_dash (void)
237 get_current_type (void)
239 return view_listing;
244 get_other_type (void)
246 return other_panel_ptr ? view_listing : view_nothing;
250 get_display_type (int index)
252 GList *p;
254 if (index == UNDEFINED_INDEX)
255 return -1;
257 p = g_list_nth (containers, index);
258 if (p)
259 return ((PanelContainer *)p->data)->panel->list_type;
260 else
261 return -1;
264 void
265 use_dash (int ignore)
267 /* we dont care in the gnome edition */
270 Widget *
271 get_panel_widget (int index)
273 GList *p;
275 for (p = containers; index; p = p->next)
276 index--;
277 return (Widget *) ((PanelContainer *)p->data)->panel;
280 /* FIXME: This routine is wrong. It should follow what the original save_panel_types
281 * does. I can not remember which problem the original routine was trying to address
282 * when I did the "New {Left|Rigth} Panel" sections.
284 void
285 save_panel_types (void)
287 GList *p;
289 for (p = containers; p; p = p->next){
290 PanelContainer *pc = p->data;
292 if (!is_a_desktop_panel (pc->panel))
293 panel_save_setup (pc->panel, pc->panel->panel_name);
297 static void
298 run_cmd (void)
300 char *cmd = _("Enter command to run");
302 cmd = input_dialog (cmd, cmd, "");
303 if (cmd){
304 if (*cmd){
305 my_system (EXECUTE_AS_SHELL, shell, cmd);
307 g_free (cmd);
311 static void
312 gnome_exit (void)
314 GtkWidget *w;
315 int v;
317 w = gnome_message_box_new (
318 _("Notice that if you choose to terminate the file manager, you will\n"
319 "also terminate the GNOME desktop handler.\n\n"
320 "Are you sure you want to exit?"),
321 GNOME_MESSAGE_BOX_WARNING,
322 GNOME_STOCK_BUTTON_YES,
323 GNOME_STOCK_BUTTON_NO,
324 NULL);
325 v = gnome_dialog_run (GNOME_DIALOG (w));
326 if (v != 0)
327 return;
329 w = gnome_message_box_new (
330 _("The file manager and the desktop handler are now terminating\n\n"
331 "If you want to start up again the desktop handler or the file manager\n"
332 "you can launch it from the Panel, or you can run the UNIX command `gmc'\n\n"
333 "Press OK to terminate the application, or cancel to continue using it."),
334 GNOME_MESSAGE_BOX_INFO,
335 GNOME_STOCK_BUTTON_OK,
336 GNOME_STOCK_BUTTON_CANCEL,
337 NULL);
338 v = gnome_dialog_run (GNOME_DIALOG (w));
339 if (v == 0) {
341 * We do not want to be restarted by the session manager now
343 session_set_restart (FALSE);
344 gmc_do_quit ();
348 static void
349 do_rescan_desktop (void)
351 desktop_reload_icons (FALSE, 0, 0);
354 static void
355 gnome_launch_mime_editor (void)
357 my_system (EXECUTE_AS_SHELL, shell, "mime-type-capplet");
360 void configure_box (void);
362 GtkCheckMenuItem *gnome_toggle_snap (void);
364 static GnomeUIInfo gnome_panel_new_menu [] = {
365 GNOMEUIINFO_ITEM_NONE(N_("_Terminal"),
366 N_("Launch a new terminal in the current directory"), gnome_open_terminal),
367 /* If this ever changes, make sure you update create_new_menu accordingly. */
368 GNOMEUIINFO_ITEM_NONE(N_("_Directory..."),
369 N_("Creates a new directory"), gnome_mkdir_cmd),
370 GNOMEUIINFO_ITEM_NONE(N_("_File..."),
371 N_("Creates a new file in this directory"), gnome_newfile_cmd),
372 GNOMEUIINFO_END
376 GnomeUIInfo gnome_panel_file_menu [] = {
377 GNOMEUIINFO_MENU_NEW_WINDOW_ITEM(gnome_open_panel, NULL),
378 /*GNOMEUIINFO_MENU_NEW_ITEM(N_("New _Window"), N_("Opens a new window"), gnome_open_panel, NULL),*/
380 /* We want to make a new menu entry here... */
381 /* For example: */
382 /* New-> */
383 /* Command Prompt */
384 /* Gimp Image */
385 /* Gnumeric Spreadsheet */
386 /* Text Document */
387 /* etc... */
388 GNOMEUIINFO_MENU_NEW_SUBTREE(gnome_panel_new_menu),
389 GNOMEUIINFO_SEPARATOR,
390 GNOMEUIINFO_MENU_OPEN_ITEM(gnome_open_files, NULL),
391 /* GNOMEUIINFO_ITEM_NONE(N_("Open _FTP site"), N_("Opens an FTP site"), ftplink_cmd },*/
392 GNOMEUIINFO_ITEM_STOCK(N_("_Copy..."), N_("Copy files"), copy_cmd, GNOME_STOCK_PIXMAP_COPY),
393 GNOMEUIINFO_ITEM_STOCK(N_("_Delete..."), N_("Delete files"), delete_cmd, GNOME_STOCK_PIXMAP_TRASH),
394 GNOMEUIINFO_ITEM_NONE(N_("_Move..."), N_("Rename or move files"), ren_cmd),
395 GNOMEUIINFO_SEPARATOR,
396 GNOMEUIINFO_ITEM_NONE(N_("Show directory sizes"), N_("Shows the disk space used by each directory"), dirsizes_cmd),
397 GNOMEUIINFO_SEPARATOR,
398 { GNOME_APP_UI_ITEM, N_("Close window"), N_("Closes this window"),
399 gnome_close_panel, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_CLOSE,
400 'w', GDK_CONTROL_MASK, NULL },
401 GNOMEUIINFO_END
404 GnomeUIInfo gnome_panel_edit_menu [] = {
405 { GNOME_APP_UI_ITEM, N_("Select _All"), N_("Select all files in the current Panel"), gnome_select_all_cmd,
406 NULL, NULL, 0, NULL, 'a', GDK_CONTROL_MASK },
407 GNOMEUIINFO_ITEM_NONE(N_("_Select Files..."), N_("Select a group of files"), gnome_select),
408 GNOMEUIINFO_ITEM_NONE(N_("_Invert Selection"), N_("Reverses the list of tagged files"),
409 gnome_reverse_selection_cmd_panel),
410 GNOMEUIINFO_SEPARATOR,
411 { GNOME_APP_UI_ITEM, N_("Search"), N_("Search for a file in the current Panel"), gnome_start_search,
412 NULL, NULL, 0, NULL, 's', GDK_CONTROL_MASK },
413 GNOMEUIINFO_SEPARATOR,
414 GNOMEUIINFO_ITEM_NONE(N_("_Rescan Directory"), N_("Rescan the directory contents"), reread_cmd),
415 GNOMEUIINFO_END
418 GnomeUIInfo gnome_panel_settings_menu [] = {
419 GNOMEUIINFO_MENU_PREFERENCES_ITEM(gnome_configure_box, NULL),
420 GNOMEUIINFO_END
423 GnomeUIInfo gnome_panel_layout_menu [] = {
424 GNOMEUIINFO_ITEM_NONE(N_("_Sort By..."), N_("Filename sort order"), gnome_sort_cmd),
425 GNOMEUIINFO_ITEM_NONE(N_("_Filter View..."), N_("Filename filtering settings"), gnome_filter_cmd),
426 GNOMEUIINFO_SEPARATOR,
427 GNOMEUIINFO_RADIOLIST(panel_view_menu_uiinfo),
428 GNOMEUIINFO_END
431 GnomeUIInfo gnome_panel_commands_menu [] = {
432 GNOMEUIINFO_ITEM_STOCK(N_("_Find File..."), N_("Locate files on disk"), find_cmd, GNOME_STOCK_MENU_JUMP_TO),
434 /* { GNOME_APP_UI_ITEM, N_("_Compare panels..."), N_("Compare two panel contents"), gnome_compare_panels },*/
435 GNOMEUIINFO_ITEM_NONE(N_("_Edit mime types..."), N_("Edits the MIME type bindings"),
436 gnome_launch_mime_editor),
437 { GNOME_APP_UI_ITEM, N_("_Run Command..."), N_("Runs a command"), run_cmd, NULL,
438 NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN, GDK_F2, 0 },
439 GNOMEUIINFO_ITEM_NONE(N_("_Run Command in panel..."),N_("Run a command and put the results in a panel"), gnome_external_panelize),
441 #ifdef USE_VFS
442 /* GNOMEUIINFO_ITEM_NONE(N_("_Active VFS list..."),N_("List of active virtual file systems"), reselect_vfs), */
443 #endif
444 #ifdef USE_EXT2FSLIB
445 /*does this do anything?*/
446 /* GNOMEUIINFO_ITEM_NONE(N_("_Undelete files (ext2fs only)..."), N_("Recover deleted files"), undelete_cmd),*/
447 #endif
448 #ifdef WITH_BACKGROUND
449 GNOMEUIINFO_ITEM_NONE(N_("_Background jobs..."), N_("List of background operations"), jobs_cmd),
450 #endif
451 GNOMEUIINFO_SEPARATOR,
452 GNOMEUIINFO_ITEM_STOCK (N_("Exit"), N_("Terminates the file manager and the desktop"),
453 gnome_exit, GNOME_STOCK_PIXMAP_QUIT),
454 GNOMEUIINFO_END
458 GnomeUIInfo gnome_panel_about_menu [] = {
459 GNOMEUIINFO_MENU_ABOUT_ITEM(gnome_about_cmd, NULL),
460 GNOMEUIINFO_HELP ("gmc"),
461 GNOMEUIINFO_END
464 GnomeUIInfo gnome_panel_desktop_menu [] = {
465 GNOMEUIINFO_SUBTREE(N_("_Arrange Icons"), desktop_arrange_icons_items),
466 GNOMEUIINFO_SEPARATOR,
467 GNOMEUIINFO_ITEM_NONE (N_("Rescan _Desktop Directory"), NULL, do_rescan_desktop),
468 GNOMEUIINFO_ITEM_NONE (N_("Rescan De_vices"), NULL, desktop_rescan_devices),
469 GNOMEUIINFO_ITEM_NONE (N_("Recreate Default _Icons"), NULL, desktop_recreate_default_icons),
470 GNOMEUIINFO_END
473 GnomeUIInfo gnome_panel_menu_with_desktop [] = {
474 GNOMEUIINFO_MENU_FILE_TREE(gnome_panel_file_menu),
475 GNOMEUIINFO_MENU_EDIT_TREE(gnome_panel_edit_menu),
476 GNOMEUIINFO_SUBTREE(N_("_Settings"),gnome_panel_settings_menu),
477 GNOMEUIINFO_SUBTREE(N_("_Layout"),gnome_panel_layout_menu),
478 GNOMEUIINFO_SUBTREE(N_("_Commands"),gnome_panel_commands_menu),
479 GNOMEUIINFO_SUBTREE(N_("_Desktop"), gnome_panel_desktop_menu),
480 GNOMEUIINFO_SUBTREE(N_("_Help"), gnome_panel_about_menu),
481 GNOMEUIINFO_END
484 GnomeUIInfo gnome_panel_menu_without_desktop [] = {
485 GNOMEUIINFO_MENU_FILE_TREE(gnome_panel_file_menu),
486 GNOMEUIINFO_MENU_EDIT_TREE(gnome_panel_edit_menu),
487 GNOMEUIINFO_SUBTREE(N_("_Settings"),gnome_panel_settings_menu),
488 GNOMEUIINFO_SUBTREE(N_("_Layout"),gnome_panel_layout_menu),
489 GNOMEUIINFO_SUBTREE(N_("_Commands"),gnome_panel_commands_menu),
490 GNOMEUIINFO_SUBTREE(N_("_Help"), gnome_panel_about_menu),
491 GNOMEUIINFO_END
494 GtkCheckMenuItem *
495 gnome_toggle_snap (void)
497 return NULL; /*GTK_CHECK_MENU_ITEM (gnome_panel_desktop_menu [1].widget);*/
500 void
501 gnome_init_panels (void)
503 current_panel_ptr = NULL;
504 other_panel_ptr = NULL;
507 static int
508 gnome_close_panel_event (GtkWidget *widget, GdkEvent *event, WPanel *panel)
510 gnome_close_panel (widget, panel);
511 return TRUE;
514 static void
515 panel_enter_event (GtkWidget *widget, GdkEvent *event, WPanel *panel)
517 /* Avoid unnecessary code execution */
518 if (get_current_panel () == panel)
519 return;
521 set_current_panel (panel);
522 dlg_select_widget (panel->widget.parent, panel);
523 send_message (panel->widget.parent, (Widget *) panel, WIDGET_FOCUS, 0);
526 void
527 destroy_gde (GtkWidget *unused, void *data)
529 gnome_desktop_entry_free ((GnomeDesktopEntry *) (data));
532 gint
533 create_new_menu_from (char *file, GtkWidget *shell, gint pos)
535 DIR *dir;
536 struct stat filedata;
537 gboolean add_separator = TRUE;
538 struct dirent *dirstruc;
539 GnomeDesktopEntry *gde;
540 GtkWidget *menu;
541 char *file2;
543 g_return_val_if_fail (shell != NULL, pos);
545 if (shell == NULL){
546 return pos;
549 dir = opendir (file);
550 if (dir == NULL)
551 return pos;
553 while ((dirstruc = readdir (dir)) != NULL){
554 if (dirstruc->d_name[0] == '.')
555 continue;
557 file2 = g_concat_dir_and_file (file, dirstruc->d_name);
559 if ((stat (file2, &filedata) != -1) && (S_ISREG (filedata.st_mode))){
560 char *path;
561 int len;
562 const int desktoplen = sizeof (".desktop") - 1;
564 len = strlen (dirstruc->d_name);
565 if (strcmp (dirstruc->d_name + len - desktoplen, ".desktop") != 0) {
566 g_free (file2);
567 continue;
570 gde = gnome_desktop_entry_load (file2);
571 if (gde == NULL) {
572 g_free (file2);
573 continue;
576 path = gnome_is_program_in_path (gde->tryexec);
577 g_free (path);
578 if (!path){
579 gnome_desktop_entry_free (gde);
580 g_free (file2);
581 continue;
584 if (add_separator) {
585 menu = gtk_menu_item_new ();
586 gtk_widget_show (menu);
587 gtk_menu_shell_insert (GTK_MENU_SHELL (shell), menu, pos++);
588 add_separator = !add_separator;
591 menu = gtk_menu_item_new_with_label (gde->name);
592 gtk_widget_show (menu);
593 gtk_menu_shell_insert (GTK_MENU_SHELL (shell), menu, pos++);
595 /* This is really bad, but it works. */
596 /* FIXME: it doesn't work if we free the gde below. --
597 * need to do this right sometime -jrb
599 if (gde->comment)
600 gtk_object_set_data (GTK_OBJECT (menu),
601 "apphelper_statusbar_hint",
602 gde->comment);
603 gtk_signal_connect (GTK_OBJECT (menu), "activate",
604 GTK_SIGNAL_FUNC (gnome_run_new),
605 gde);
606 gtk_signal_connect (GTK_OBJECT (menu), "destroy",
607 GTK_SIGNAL_FUNC (destroy_gde),
608 gde);
610 g_free (file2);
612 closedir (dir);
614 return pos;
618 * create_new_menu:
620 * Creates the child New menu items
622 static void
623 create_new_menu (GnomeApp *app, WPanel *panel)
625 gchar *file, *file2;
626 gint pos;
627 GtkWidget *shell;
629 shell = gnome_app_find_menu_pos (app->menubar, _("File/New/Directory..."), &pos);
631 file = gnome_unconditional_datadir_file ("mc/templates");
632 pos = create_new_menu_from (file, shell, pos);
634 file2 = gnome_datadir_file ("mc/templates");
635 if (file2 != NULL){
636 if (strcmp (file, file2) != 0)
637 create_new_menu_from (file2, shell, pos);
640 g_free (file);
641 g_free (file2);
645 * This routine is a menu relay.
647 * This is called before the actual command specified in the GnomeUIInfo
648 * structure. This allows me to select the panel (ie, set the global cpanel
649 * variable to which this menu is bound).
651 * This is important, as we can have a menu tearoffed. And the current hack
652 * of setting cpanel on the focus-in event wont work.
655 static void
656 panel_menu_relay (GtkObject *object, WPanel *panel)
658 void (*real_func)(GtkObject *object, WPanel *panel);
660 real_func = gtk_object_get_user_data (object);
661 set_current_panel (panel);
662 (*real_func)(object, panel);
665 static void
666 my_menu_signal_connect (GnomeUIInfo *uiinfo, gchar *signal_name,
667 GnomeUIBuilderData *uibdata)
669 gtk_object_set_user_data (GTK_OBJECT (uiinfo->widget), uiinfo->moreinfo);
670 gtk_signal_connect (GTK_OBJECT (uiinfo->widget),
671 signal_name, panel_menu_relay, uibdata->data ?
672 uibdata->data : uiinfo->user_data);
675 static void
676 my_app_create_menus (GnomeApp *app, GnomeUIInfo *uiinfo, void *data)
678 GnomeUIBuilderData uibdata;
680 g_return_if_fail (app != NULL);
681 g_return_if_fail (GNOME_IS_APP (app));
682 g_return_if_fail (uiinfo != NULL);
684 uibdata.connect_func = my_menu_signal_connect;
685 uibdata.data = data;
686 uibdata.is_interp = FALSE;
687 uibdata.relay_func = NULL;
688 uibdata.destroy_func = NULL;
690 gnome_app_create_menus_custom (app, uiinfo, &uibdata);
694 * copy_uiinfo_widgets:
695 * @uiinfo: A GnomeUIInfo array
697 * Allocates an array of widgets and copies the widgets from the uiinfo array to
698 * it. The array will be NULL-terminated.
700 * Returns: The allocated array of widgets.
702 gpointer *
703 copy_uiinfo_widgets (GnomeUIInfo *uiinfo)
705 gpointer *dest;
706 int n;
707 int i;
709 g_return_val_if_fail (uiinfo != NULL, NULL);
711 /* Count number of items */
713 for (n = 0; uiinfo[n].type != GNOME_APP_UI_ENDOFINFO; n++);
715 /* Copy the widgets */
717 dest = g_new (gpointer, n + 1);
719 for (i = 0; i < n; i++)
720 dest[i] = uiinfo[i].widget;
722 dest[i] = NULL;
724 return dest;
727 WPanel *
728 create_container (Dlg_head *h, const char *name, const char *geometry)
730 PanelContainer *container;
731 WPanel *panel;
732 GtkWidget *app, *vbox;
733 int xpos, ypos, width, height;
734 GnomeUIInfo *uiinfo;
735 char buf[50];
737 container = g_new (PanelContainer, 1);
739 gnome_parse_geometry (geometry, &xpos, &ypos, &width, &height);
741 container->splitted = 0;
742 app = gnome_app_new ("gmc", name);
744 /* Geometry configuration */
745 if (width != -1 && height != -1)
746 gtk_window_set_default_size (GTK_WINDOW (app), width, height);
747 else
748 gtk_window_set_default_size (GTK_WINDOW (app), 540, 360);
750 if (xpos != -1 && ypos != -1)
751 gtk_widget_set_uposition (GTK_WIDGET (app), xpos, ypos);
753 panel = panel_new (name);
755 /* Set the unique name for session management */
757 sprintf (buf, "%d", panel->id);
758 gtk_window_set_wmclass (GTK_WINDOW (app), "gmc", buf);
760 /* Create the holder for the contents */
762 vbox = gtk_vbox_new (FALSE, 0);
763 gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
764 gnome_app_set_contents (GNOME_APP (app), vbox);
766 if (desktop_wm_is_gnome_compliant == 1)
767 uiinfo = gnome_panel_menu_without_desktop;
768 else
769 uiinfo = gnome_panel_menu_with_desktop;
771 my_app_create_menus (GNOME_APP (app), uiinfo, panel);
772 panel->view_menu_items = copy_uiinfo_widgets (panel_view_menu_uiinfo);
774 create_new_menu (GNOME_APP (app), panel);
776 panel->ministatus = GNOME_APPBAR(gnome_appbar_new(FALSE, TRUE, GNOME_PREFERENCES_NEVER));
777 gnome_app_set_statusbar(GNOME_APP (app), GTK_WIDGET(panel->ministatus));
779 if (desktop_wm_is_gnome_compliant)
780 gnome_app_install_menu_hints (GNOME_APP (app), gnome_panel_menu_without_desktop);
781 else
782 gnome_app_install_menu_hints (GNOME_APP (app), gnome_panel_menu_with_desktop);
784 gtk_signal_connect (GTK_OBJECT (app),
785 "enter_notify_event",
786 GTK_SIGNAL_FUNC (panel_enter_event),
787 panel);
788 gtk_signal_connect (GTK_OBJECT (app),
789 "delete_event",
790 GTK_SIGNAL_FUNC (gnome_close_panel_event),
791 panel);
792 /* Ultra nasty hack follows:
793 * I am setting the panel->widget.wdata value here before the
794 * panel X stuff gets created in the INIT message section of the
795 * widget. There I put a pointer to the vbox where the panel
796 * should pack itself
798 panel->widget.wdata = (widget_data) vbox;
799 container->panel = panel;
801 containers = g_list_append (containers, container);
803 if (!current_panel_ptr){
804 current_panel_ptr = container;
805 } else if (!other_panel_ptr)
806 other_panel_ptr = container;
808 bind_gtk_keys (GTK_WIDGET (app), h);
809 return panel;
812 WPanel *
813 new_panel_with_geometry_at (const char *dir, const char *geometry)
815 WPanel *panel;
817 mc_chdir ((char *) dir);
818 panel = create_container (desktop_dlg, dir, geometry);
819 set_current_panel (panel);
820 add_widget (desktop_dlg, panel);
821 #if 0
822 x_flush_events ();
823 #endif
825 return panel;
828 WPanel *
829 new_panel_at (const char *dir)
831 return new_panel_with_geometry_at (dir, NULL);
834 void
835 setup_panels (void)
837 load_hint ();
841 * GNOME's implementation of the update_panels routine
843 void
844 update_panels (int force_update, char *current_file)
846 int reload_others = !(force_update & UP_ONLY_CURRENT);
847 GList *p;
849 /* Test if there are panels open */
850 if (!cpanel)
851 return;
853 if (!is_a_desktop_panel (cpanel))
854 update_one_panel_widget (cpanel, force_update, current_file);
856 if (reload_others){
857 for (p = containers; p; p = p->next){
858 PanelContainer *pc = p->data;
860 if (p->data == current_panel_ptr)
861 continue;
863 if (!is_a_desktop_panel (pc->panel))
864 update_one_panel_widget (pc->panel, force_update, UP_KEEPSEL);
867 mc_chdir (cpanel->cwd);