diff --git a/gnome/ChangeLog b/gnome/ChangeLog index f6fe23cc1..20354c9b9 100644 --- a/gnome/ChangeLog +++ b/gnome/ChangeLog @@ -1,3 +1,23 @@ +1998-12-06 Federico Mena Quintero + + * gdesktop.c (drag_data_received): We do not need to call + gtk_drag_finish(), since we are using the GTK_DEST_DEFAULT_DROP + flag for drops on the desktop. + (desktop_icon_info_event): Reload the desktop icons after + executing a command from the popup menu. This kind of sucks, but + will do for now. + (desktop_icon_info_event): Upon receiving a button-1 press, if the + icon was already selected in the first place, delay the + re-selection phase until we get a mouse release event. This lets + us start a multiple-selection drag without having the initial + click clear the selection first. + (desktop_icon_info_event): Open the file or directory when the + desktop icon receives a double click. + + * gmain.c (beep): Made it void, since it does not (need to) return + anything. + (xtoolkit_end): Likewise. + 1998-12-05 Miguel de Icaza * gscreen.c (panel_build_selected_file_list): Provide space for diff --git a/gnome/gdesktop.c b/gnome/gdesktop.c index 201fcc5c6..46208c3e8 100644 --- a/gnome/gdesktop.c +++ b/gnome/gdesktop.c @@ -235,6 +235,123 @@ desktop_icon_info_place (struct desktop_icon_info *dii, int auto_pos, int xpos, g_free (filename); } +/* Returns TRUE if there is already an icon in the desktop for the specified filename, FALSE otherwise. */ +static int +icon_exists (char *filename) +{ + int i; + GList *l; + struct desktop_icon_info *dii; + + for (i = 0; i < (layout_cols * layout_rows); i++) + for (l = layout_slots[i].icons; l; l = l->next) { + dii = l->data; + if (strcmp (filename, dii->filename) == 0) + return TRUE; + } + + return FALSE; +} + +/* Reads the ~/Desktop directory and creates the desktop icons. If incremental is TRUE, then an + * icon will not be created for a file if there is already an icon for it, and icons will be created + * starting at the specified position. + */ +static void +load_desktop_icons (int incremental, int xpos, int ypos) +{ + struct dirent *dirent; + DIR *dir; + char *full_name; + int have_pos, x, y; + struct desktop_icon_info *dii; + GSList *need_position_list, *l; + + dir = mc_opendir (desktop_directory); + if (!dir) { + message (FALSE, + _("Warning"), + _("Could not open %s; will not have initial desktop icons"), + desktop_directory); + return; + } + + /* First create the icons for all the files that do have their icon position set. Build a + * list of the icons that do not have their position set. + */ + + need_position_list = NULL; + + while ((dirent = mc_readdir (dir)) != NULL) { + if (((dirent->d_name[0] == '.') && (dirent->d_name[1] == 0)) + || ((dirent->d_name[0] == '.') && (dirent->d_name[1] == '.') && (dirent->d_name[2] == 0))) + continue; + + if (incremental && icon_exists (dirent->d_name)) + continue; + + full_name = g_concat_dir_and_file (desktop_directory, dirent->d_name); + + have_pos = gmeta_get_icon_pos (full_name, &x, &y); + + if (have_pos) { + dii = desktop_icon_info_new (dirent->d_name, FALSE, x, y); + gtk_widget_show (dii->dicon); + + g_free (full_name); + } else + need_position_list = g_slist_prepend (need_position_list, g_strdup (dirent->d_name)); + } + + mc_closedir (dir); + + /* Now create the icons for all the files that did not have their position set. This makes + * auto-placement work correctly without overlapping icons. + */ + + need_position_list = g_slist_reverse (need_position_list); + + for (l = need_position_list; l; l = l->next) { + dii = desktop_icon_info_new (l->data, TRUE, xpos, ypos); + gtk_widget_show (dii->dicon); + g_free (l->data); + } + + g_slist_free (need_position_list); +} + +/* Destroys all the current desktop icons */ +static void +destroy_desktop_icons (void) +{ + int i; + GList *l; + struct desktop_icon_info *dii; + + for (i = 0; i < (layout_cols * layout_rows); i++) { + l = layout_slots[i].icons; + + while (l) { + dii = l->data; + l = l->next; + + desktop_icon_info_free (dii); + } + } +} + +/* Reloads the desktop icons. If incremental is TRUE, then the existing icons will not be destroyed + * first, and the new icons will be put at the specified position. + */ +static void +reload_desktop_icons (int incremental, int x, int y) +{ + if (!incremental) + destroy_desktop_icons (); + + load_desktop_icons (incremental, x, y); +} + /* Unselects all the desktop icons */ static void unselect_all (void) @@ -351,6 +468,15 @@ select_icon (struct desktop_icon_info *dii, GdkEventButton *event) select_range (dii, TRUE); } +/* Creates a file entry structure and fills it with information appropriate to the specified file. */ +static file_entry * +file_entry_from_file (char *filename) +{ + /* FIXME */ + + return NULL; +} + /* Handler for events on desktop icons. The on_text flag specifies whether the event ocurred on the * text item in the icon or not. */ @@ -364,14 +490,19 @@ desktop_icon_info_event (struct desktop_icon_info *dii, GdkEvent *event, int on_ switch (event->type) { case GDK_BUTTON_PRESS: - if ((event->button.button == 1) && !(on_text && dii->selected)) { + if ((event->button.button == 1) && !dii->selected) { + /* If the icon was not selected, we select it. Otherwise, we delay + * selection until button_release. This is needed so that we can drag a + * multiple selection without having the click that starts the drag unselect + * all the icons first. + */ select_icon (dii, (GdkEventButton *) event); retval = TRUE; } else if (event->button.button == 3) { filename = g_concat_dir_and_file (desktop_directory, dii->filename); if (gpopup_do_popup ((GdkEventButton *) event, NULL, 0, filename) != -1) - ; /* FIXME: reread the desktop if this returns something other than -1 */ + reload_desktop_icons (FALSE, 0, 0); /* blean */ g_free (filename); retval = TRUE; @@ -383,8 +514,23 @@ desktop_icon_info_event (struct desktop_icon_info *dii, GdkEvent *event, int on_ if (event->button.button != 1) break; - /* FIXME: activate icon */ + filename = g_concat_dir_and_file (desktop_directory, dii->filename); + if (dii->type == ICON_DIRECTORY) + new_panel_at (filename); + else { + file_entry *fe; + + fe = file_entry_from_file (filename); + do_enter_on_file_entry (fe); + /* FIXME: free the file entry */ + } + + retval = TRUE; + break; + + case GDK_BUTTON_RELEASE: + select_icon (dii, (GdkEventButton *) event); retval = TRUE; break; @@ -769,123 +915,6 @@ create_desktop_dir (void) } } -/* Returns TRUE if there is already an icon in the desktop for the specified filename, FALSE otherwise. */ -static int -icon_exists (char *filename) -{ - int i; - GList *l; - struct desktop_icon_info *dii; - - for (i = 0; i < (layout_cols * layout_rows); i++) - for (l = layout_slots[i].icons; l; l = l->next) { - dii = l->data; - if (strcmp (filename, dii->filename) == 0) - return TRUE; - } - - return FALSE; -} - -/* Reads the ~/Desktop directory and creates the desktop icons. If incremental is TRUE, then an - * icon will not be created for a file if there is already an icon for it, and icons will be created - * starting at the specified position. - */ -static void -load_desktop_icons (int incremental, int xpos, int ypos) -{ - struct dirent *dirent; - DIR *dir; - char *full_name; - int have_pos, x, y; - struct desktop_icon_info *dii; - GSList *need_position_list, *l; - - dir = mc_opendir (desktop_directory); - if (!dir) { - message (FALSE, - _("Warning"), - _("Could not open %s; will not have initial desktop icons"), - desktop_directory); - return; - } - - /* First create the icons for all the files that do have their icon position set. Build a - * list of the icons that do not have their position set. - */ - - need_position_list = NULL; - - while ((dirent = mc_readdir (dir)) != NULL) { - if (((dirent->d_name[0] == '.') && (dirent->d_name[1] == 0)) - || ((dirent->d_name[0] == '.') && (dirent->d_name[1] == '.') && (dirent->d_name[2] == 0))) - continue; - - if (incremental && icon_exists (dirent->d_name)) - continue; - - full_name = g_concat_dir_and_file (desktop_directory, dirent->d_name); - - have_pos = gmeta_get_icon_pos (full_name, &x, &y); - - if (have_pos) { - dii = desktop_icon_info_new (dirent->d_name, FALSE, x, y); - gtk_widget_show (dii->dicon); - - g_free (full_name); - } else - need_position_list = g_slist_prepend (need_position_list, g_strdup (dirent->d_name)); - } - - mc_closedir (dir); - - /* Now create the icons for all the files that did not have their position set. This makes - * auto-placement work correctly without overlapping icons. - */ - - need_position_list = g_slist_reverse (need_position_list); - - for (l = need_position_list; l; l = l->next) { - dii = desktop_icon_info_new (l->data, TRUE, xpos, ypos); - gtk_widget_show (dii->dicon); - g_free (l->data); - } - - g_slist_free (need_position_list); -} - -/* Destroys all the current desktop icons */ -static void -destroy_desktop_icons (void) -{ - int i; - GList *l; - struct desktop_icon_info *dii; - - for (i = 0; i < (layout_cols * layout_rows); i++) { - l = layout_slots[i].icons; - - while (l) { - dii = l->data; - l = l->next; - - desktop_icon_info_free (dii); - } - } -} - -/* Reloads the desktop icons. If incremental is TRUE, then the existing icons will not be destroyed - * first, and the new icons will be put at the specified position. - */ -static void -reload_desktop_icons (int incremental, int x, int y) -{ - if (!incremental) - destroy_desktop_icons (); - - load_desktop_icons (incremental, x, y); -} - /* Sets up a proxy window for DnD on the specified X window. Courtesy of Owen Taylor */ static gboolean setup_xdnd_proxy (guint32 xid, GdkWindow *proxy_window) @@ -1000,15 +1029,11 @@ drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gint y, if (retval) reload_desktop_icons (TRUE, x, y); - /* FIXME: return TRUE for delete if appropriate */ - gtk_drag_finish (context, retval, FALSE, time); return; default: break; } - - gtk_drag_finish (context, FALSE, FALSE, time); } /* Sets up drag and drop to the desktop root window */ diff --git a/gnome/gmain.c b/gnome/gmain.c index d260a9989..46330d0f1 100644 --- a/gnome/gmain.c +++ b/gnome/gmain.c @@ -111,18 +111,16 @@ interactive_display (char *filename, char *node) /* FIXME: Implement gnome version */ } -int +void beep (void) { gdk_beep (); - - return 0; } -int +void xtoolkit_end (void) { - return 1; + /* Do nothing */ } /* diff --git a/gnome/gmain.h b/gnome/gmain.h index bcb62752b..1340e5942 100644 --- a/gnome/gmain.h +++ b/gnome/gmain.h @@ -5,7 +5,7 @@ #include "widget.h" int xtoolkit_init (int *argc, char *argv []); -int xtoolkit_end (void); +void xtoolkit_end (void); extern Dlg_head *desktop_dlg; extern int nowindows; diff --git a/src/ChangeLog b/src/ChangeLog index c21062ce0..b2c25e8a4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +1998-12-06 Federico Mena Quintero + + * screen.c (do_enter_on_file_entry): New public function that + implements the functionality in do_enter(), but based on a file + entry rather than on a panel. + (do_enter): Use do_enter_on_file_entry() with the selection of the + panel as an argument. + 1998-12-04 Miguel de Icaza * cmd.c, tree.c: Updated to the new file.c api. diff --git a/src/panel.h b/src/panel.h index f218d7873..09684cb19 100644 --- a/src/panel.h +++ b/src/panel.h @@ -260,6 +260,7 @@ void do_file_mark (WPanel *panel, int index, int val); int file_compute_color (int attr, file_entry *fe); int file_entry_color (file_entry *fe); void do_file_mark_range (WPanel *panel, int r1, int r2); +int do_enter_on_file_entry (file_entry *fe); int do_enter (WPanel *panel); /* NOTE: Have to be ifdefed for HAVE_X */ diff --git a/src/screen.c b/src/screen.c index f19993e5e..9797c0921 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2029,20 +2029,19 @@ start_search (WPanel *panel) } int -do_enter (WPanel *panel) +do_enter_on_file_entry (file_entry *fe) { - if (S_ISDIR (selection (panel)->buf.st_mode) - || link_isdir (selection (panel))){ - do_cd (selection (panel)->fname, cd_exact); + if (S_ISDIR (fe->buf.st_mode) || link_isdir (fe)) { + do_cd (fe->fname, cd_exact); return 1; } else { - if (is_exe (selection (panel)->buf.st_mode) && - if_link_is_exe (selection (panel))) { + if (is_exe (fe->buf.st_mode) && + if_link_is_exe (fe)) { #ifdef USE_VFS if (vfs_current_is_local ()) #endif { - char *tmp = name_quote (selection (panel)->fname, 0); + char *tmp = name_quote (fe->fname, 0); char *cmd = copy_strings (".", PATH_SEP_STR, tmp, 0); if (!confirm_execute || (query_dialog (_(" The Midnight Commander "), _(" Do you really want to execute? "), @@ -2058,7 +2057,7 @@ do_enter (WPanel *panel) call... -- pavel@ucw.cz*/ char *tmp; - tmp = concat_dir_and_file (vfs_get_current_dir(), selection (panel)->fname); + tmp = concat_dir_and_file (vfs_get_current_dir(), fe->fname); if (!mc_setctl (tmp, MCCTL_EXTFS_RUN, NULL)) message (1, _(" Warning "), _(" No action taken ")); @@ -2069,13 +2068,19 @@ do_enter (WPanel *panel) } else { char *p; - p = regex_command (selection (panel)->fname, "Open", NULL, 0); + p = regex_command (fe->fname, "Open", NULL, 0); if (p && (strcmp (p, "Success") == 0)) return 1; else return 0; } } +} + +int +do_enter (WPanel *panel) +{ + do_enter_on_file_entry (selection (panel)); } static void