1st cut at the property browser for drag and drop customization
1st cut at the property browser for drag and drop customization
78
ChangeLog
|
@ -1,3 +1,81 @@
|
|||
2000-05-02 Andy Hertzfeld <andy@eazel.com>
|
||||
|
||||
1st cut at property browser for drag and drop customization;
|
||||
Backgrounds are fully implemented, emblems are only partially there,
|
||||
more coming soon
|
||||
|
||||
* src/Makefile.am: added property browser source files
|
||||
* src/nautilus-property-browser.c,h:
|
||||
new class that implements the property browser
|
||||
|
||||
* src/nautilus-window-menus.c:
|
||||
added "customize" menu item and a callback that brings up
|
||||
the property browser
|
||||
|
||||
* src/ntl-index-panel.c:
|
||||
changed index panel to accept "property/bgimage" drag type and
|
||||
change the background image accordingly
|
||||
|
||||
* libnautilus-extensions/nautilus-icon-dnd.c:
|
||||
changed icon canvas to accept "property/bgimage" drag type and
|
||||
change the background image accordingly; removed the old shift key hack
|
||||
|
||||
* libnautilus-extensions/nautilus-icon-dnd.h:
|
||||
defined constants for the new drag type
|
||||
|
||||
* configure.in: two new data directories for backgrounds and emblems
|
||||
* data/Makefile.am: added two new directories
|
||||
* data/browser.xml: xml file that defines the categories
|
||||
|
||||
added some background images to play with:
|
||||
|
||||
* data/backgrounds/.cvsignore
|
||||
* data/backgrounds/Makefile.am
|
||||
* data/backgrounds/baize.png
|
||||
* data/backgrounds/bricks.jpg
|
||||
* data/backgrounds/bubbles.png
|
||||
* data/backgrounds/buffedwood.jpg
|
||||
* data/backgrounds/burlap.jpg
|
||||
* data/backgrounds/chalk.jpg
|
||||
* data/backgrounds/cherrywood.jpg
|
||||
* data/backgrounds/cork.png
|
||||
* data/backgrounds/dark-gnome.jpg
|
||||
* data/backgrounds/darkwood.png
|
||||
* data/backgrounds/frost.jpg
|
||||
* data/backgrounds/gnome.jpg
|
||||
* data/backgrounds/gold.jpg
|
||||
* data/backgrounds/grass.png
|
||||
* data/backgrounds/gray_fabric.png
|
||||
* data/backgrounds/greenery.jpg
|
||||
* data/backgrounds/manila.jpg
|
||||
* data/backgrounds/pink_fabric.png
|
||||
* data/backgrounds/puzzle.jpg
|
||||
* data/backgrounds/raindrops.png
|
||||
* data/backgrounds/sky.jpg
|
||||
* data/backgrounds/stucco.jpg
|
||||
* data/backgrounds/white_marble.jpg
|
||||
* data/backgrounds/white_paper.jpg
|
||||
* data/backgrounds/yellow_paper.jpg
|
||||
|
||||
added some emblem images:
|
||||
|
||||
* data/emblems/.cvsignore
|
||||
* data/emblems/Makefile.am
|
||||
* data/emblems/certified.gif
|
||||
* data/emblems/changed.gif
|
||||
* data/emblems/confidential.gif
|
||||
* data/emblems/encrypted.gif
|
||||
* data/emblems/important.gif
|
||||
* data/emblems/new.gif
|
||||
* data/emblems/personal.gif
|
||||
* data/emblems/remote.gif
|
||||
|
||||
added images for the top-level categories
|
||||
|
||||
* icons/Makefile.am: added 2 images to Makefile
|
||||
* icons/backgrounds.png
|
||||
* icons/emblems.png
|
||||
|
||||
2000-05-02 Maciej Stachowiak <mjs@eazel.com>
|
||||
|
||||
* RENAMING: Added some idl-related renamings.
|
||||
|
|
|
@ -295,6 +295,8 @@ icons/Makefile
|
|||
icons/eazel/Makefile
|
||||
data/Makefile
|
||||
data/top/Makefile
|
||||
data/backgrounds/Makefile
|
||||
data/emblems/Makefile
|
||||
idl/Makefile
|
||||
librsvg/Makefile
|
||||
libnautilus/Makefile
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
NULL=
|
||||
|
||||
SUBDIRS =\
|
||||
infodir = $(datadir)/nautilus
|
||||
|
||||
info_DATA = \
|
||||
browser.xml \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST = $(info_DATA)
|
||||
|
||||
SUBDIRS = \
|
||||
backgrounds \
|
||||
emblems \
|
||||
top \
|
||||
$(NULL)
|
||||
|
|
2
data/backgrounds/.cvsignore
Normal file
|
@ -0,0 +1,2 @@
|
|||
Makefile
|
||||
Makefile.in
|
33
data/backgrounds/Makefile.am
Normal file
|
@ -0,0 +1,33 @@
|
|||
NULL=
|
||||
|
||||
backdir = $(datadir)/nautilus/backgrounds
|
||||
|
||||
back_DATA = \
|
||||
baize.png \
|
||||
bricks.jpg \
|
||||
bubbles.png \
|
||||
buffedwood.jpg \
|
||||
burlap.jpg \
|
||||
chalk.jpg \
|
||||
cherrywood.jpg \
|
||||
cork.png \
|
||||
dark-gnome.jpg \
|
||||
darkwood.png \
|
||||
frost.jpg \
|
||||
gnome.jpg \
|
||||
gold.jpg \
|
||||
grass.png \
|
||||
gray_fabric.png \
|
||||
greenery.jpg \
|
||||
manila.jpg \
|
||||
pink_fabric.png \
|
||||
puzzle.jpg \
|
||||
raindrops.png \
|
||||
sky.jpg \
|
||||
stucco.jpg \
|
||||
white_marble.jpg \
|
||||
white_paper.jpg \
|
||||
yellow_paper.jpg \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST = $(back_DATA)
|
BIN
data/backgrounds/baize.png
Normal file
After Width: | Height: | Size: 470 B |
BIN
data/backgrounds/bricks.jpg
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
data/backgrounds/bubbles.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
data/backgrounds/buffedwood.jpg
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
data/backgrounds/burlap.jpg
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
data/backgrounds/chalk.jpg
Normal file
After Width: | Height: | Size: 821 B |
BIN
data/backgrounds/cherrywood.jpg
Normal file
After Width: | Height: | Size: 680 B |
BIN
data/backgrounds/cork.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
data/backgrounds/dark-gnome.jpg
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
data/backgrounds/darkwood.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
data/backgrounds/frost.jpg
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
data/backgrounds/gnome.jpg
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
data/backgrounds/gold.jpg
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
data/backgrounds/grass.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
data/backgrounds/gray_fabric.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
data/backgrounds/greenery.jpg
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
data/backgrounds/manila.jpg
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
data/backgrounds/pink_fabric.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
data/backgrounds/puzzle.jpg
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
data/backgrounds/raindrops.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
data/backgrounds/sky.jpg
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
data/backgrounds/stucco.jpg
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
data/backgrounds/white_marble.jpg
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
data/backgrounds/white_paper.jpg
Normal file
After Width: | Height: | Size: 451 B |
BIN
data/backgrounds/yellow_paper.jpg
Normal file
After Width: | Height: | Size: 828 B |
5
data/browser.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0"?>
|
||||
<categories>
|
||||
<category name="backgrounds" image="nautilus/backgrounds.png" mode="directory" path="nautilus/backgrounds" type="property/bgimage"/>
|
||||
<category name="emblems" image="nautilus/emblems.png" mode="directory" path="nautilus/emblems" type="property/emblem"/>
|
||||
</categories>
|
2
data/emblems/.cvsignore
Normal file
|
@ -0,0 +1,2 @@
|
|||
Makefile
|
||||
Makefile.in
|
16
data/emblems/Makefile.am
Normal file
|
@ -0,0 +1,16 @@
|
|||
NULL=
|
||||
|
||||
emblemsdir = $(datadir)/nautilus/emblems
|
||||
|
||||
emblems_DATA = \
|
||||
certified.gif \
|
||||
changed.gif \
|
||||
confidential.gif \
|
||||
encrypted.gif \
|
||||
important.gif \
|
||||
new.gif \
|
||||
personal.gif \
|
||||
remote.gif \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST = $(emblems_DATA)
|
BIN
data/emblems/certified.gif
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
data/emblems/changed.gif
Normal file
After Width: | Height: | Size: 969 B |
BIN
data/emblems/confidential.gif
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
data/emblems/encrypted.gif
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
data/emblems/important.gif
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
data/emblems/new.gif
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
data/emblems/personal.gif
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
data/emblems/remote.gif
Normal file
After Width: | Height: | Size: 1.1 KiB |
|
@ -3,6 +3,7 @@ SUBDIRS = eazel
|
|||
icondir = $(datadir)/pixmaps/nautilus
|
||||
|
||||
icon_DATA = \
|
||||
backgrounds.png \
|
||||
computer.png \
|
||||
eazel-logo.gif \
|
||||
emblem-certified.gif \
|
||||
|
@ -14,6 +15,7 @@ icon_DATA = \
|
|||
emblem-personal.gif \
|
||||
emblem-remote.gif \
|
||||
emblem-symbolic-link.png \
|
||||
emblems.png \
|
||||
gnome-audio-x-mp3.png \
|
||||
gnome-compressed.png \
|
||||
gnome-library.png \
|
||||
|
|
BIN
icons/backgrounds.png
Normal file
After Width: | Height: | Size: 7 KiB |
BIN
icons/emblems.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
|
@ -82,7 +82,8 @@ static GtkTargetEntry drop_types [] = {
|
|||
{ NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST },
|
||||
{ NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST },
|
||||
{ NAUTILUS_ICON_DND_URL_TYPE, 0, NAUTILUS_ICON_DND_URL },
|
||||
{ NAUTILUS_ICON_DND_COLOR_TYPE, 0, NAUTILUS_ICON_DND_COLOR }
|
||||
{ NAUTILUS_ICON_DND_COLOR_TYPE, 0, NAUTILUS_ICON_DND_COLOR },
|
||||
{ NAUTILUS_ICON_DND_BGIMAGE_TYPE, 0, NAUTILUS_ICON_DND_BGIMAGE }
|
||||
};
|
||||
|
||||
static GnomeCanvasItem *
|
||||
|
@ -496,7 +497,9 @@ drag_data_received_callback (GtkWidget *widget,
|
|||
nautilus_icon_container_dropped_icon_feedback (widget, data, x, y);
|
||||
break;
|
||||
case NAUTILUS_ICON_DND_COLOR:
|
||||
case NAUTILUS_ICON_DND_BGIMAGE:
|
||||
/* Save the data so we can do the actual work on drop. */
|
||||
|
||||
dnd_info->selection_data = nautilus_gtk_selection_data_copy_deep (data);
|
||||
break;
|
||||
default:
|
||||
|
@ -665,20 +668,11 @@ nautilus_icon_canvas_item_can_accept_items (NautilusIconContainer *container,
|
|||
}
|
||||
|
||||
static void
|
||||
receive_dropped_tile_image (NautilusIconContainer *container)
|
||||
receive_dropped_tile_image (NautilusIconContainer *container, gpointer data)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
/* We only accept the image if it's the only thing dragged. */
|
||||
list = container->details->dnd_info->selection_list;
|
||||
g_assert (list != NULL);
|
||||
if (list->next != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert(data != NULL);
|
||||
nautilus_background_set_tile_image_uri
|
||||
(nautilus_get_widget_background (GTK_WIDGET (container)),
|
||||
((DndSelectionItem *) list->data)->uri);
|
||||
(nautilus_get_widget_background (GTK_WIDGET (container)), data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -697,22 +691,11 @@ nautilus_icon_container_receive_dropped_icons (NautilusIconContainer *container,
|
|||
GdkPoint *source_item_locations;
|
||||
int index;
|
||||
int count;
|
||||
GdkModifierType modifiers;
|
||||
|
||||
if (container->details->dnd_info->selection_list == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the shift key is down, then this is a drag that customizes
|
||||
* the background tile image.
|
||||
*/
|
||||
gdk_window_get_pointer (GTK_WIDGET (container)->window,
|
||||
NULL, NULL, &modifiers);
|
||||
if ((modifiers & GDK_SHIFT_MASK) != 0) {
|
||||
receive_dropped_tile_image (container);
|
||||
return;
|
||||
}
|
||||
|
||||
gnome_canvas_window_to_world (GNOME_CANVAS (container),
|
||||
x, y, &world_x, &world_y);
|
||||
|
||||
|
@ -1147,6 +1130,9 @@ drag_drop_callback (GtkWidget *widget,
|
|||
widget, x, y, dnd_info->selection_data);
|
||||
gtk_drag_finish (context, TRUE, FALSE, time);
|
||||
break;
|
||||
case NAUTILUS_ICON_DND_BGIMAGE:
|
||||
receive_dropped_tile_image (NAUTILUS_ICON_CONTAINER (widget), dnd_info->selection_data->data);
|
||||
break;
|
||||
default:
|
||||
gtk_drag_finish (context, FALSE, FALSE, time);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,8 @@ enum NautilusIconDndTargetType {
|
|||
NAUTILUS_ICON_DND_GNOME_ICON_LIST,
|
||||
NAUTILUS_ICON_DND_URI_LIST,
|
||||
NAUTILUS_ICON_DND_URL,
|
||||
NAUTILUS_ICON_DND_COLOR
|
||||
NAUTILUS_ICON_DND_COLOR,
|
||||
NAUTILUS_ICON_DND_BGIMAGE
|
||||
};
|
||||
|
||||
/* DnD target names. */
|
||||
|
@ -48,6 +49,7 @@ enum NautilusIconDndTargetType {
|
|||
#define NAUTILUS_ICON_DND_URI_LIST_TYPE "text/uri-list"
|
||||
#define NAUTILUS_ICON_DND_URL_TYPE "_NETSCAPE_URL"
|
||||
#define NAUTILUS_ICON_DND_COLOR_TYPE "application/x-color"
|
||||
#define NAUTILUS_ICON_DND_BGIMAGE_TYPE "property/bgimage"
|
||||
|
||||
/* DnD-related information. */
|
||||
struct NautilusIconDndInfo {
|
||||
|
|
|
@ -82,7 +82,8 @@ static GtkTargetEntry drop_types [] = {
|
|||
{ NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST },
|
||||
{ NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST },
|
||||
{ NAUTILUS_ICON_DND_URL_TYPE, 0, NAUTILUS_ICON_DND_URL },
|
||||
{ NAUTILUS_ICON_DND_COLOR_TYPE, 0, NAUTILUS_ICON_DND_COLOR }
|
||||
{ NAUTILUS_ICON_DND_COLOR_TYPE, 0, NAUTILUS_ICON_DND_COLOR },
|
||||
{ NAUTILUS_ICON_DND_BGIMAGE_TYPE, 0, NAUTILUS_ICON_DND_BGIMAGE }
|
||||
};
|
||||
|
||||
static GnomeCanvasItem *
|
||||
|
@ -496,7 +497,9 @@ drag_data_received_callback (GtkWidget *widget,
|
|||
nautilus_icon_container_dropped_icon_feedback (widget, data, x, y);
|
||||
break;
|
||||
case NAUTILUS_ICON_DND_COLOR:
|
||||
case NAUTILUS_ICON_DND_BGIMAGE:
|
||||
/* Save the data so we can do the actual work on drop. */
|
||||
|
||||
dnd_info->selection_data = nautilus_gtk_selection_data_copy_deep (data);
|
||||
break;
|
||||
default:
|
||||
|
@ -665,20 +668,11 @@ nautilus_icon_canvas_item_can_accept_items (NautilusIconContainer *container,
|
|||
}
|
||||
|
||||
static void
|
||||
receive_dropped_tile_image (NautilusIconContainer *container)
|
||||
receive_dropped_tile_image (NautilusIconContainer *container, gpointer data)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
/* We only accept the image if it's the only thing dragged. */
|
||||
list = container->details->dnd_info->selection_list;
|
||||
g_assert (list != NULL);
|
||||
if (list->next != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert(data != NULL);
|
||||
nautilus_background_set_tile_image_uri
|
||||
(nautilus_get_widget_background (GTK_WIDGET (container)),
|
||||
((DndSelectionItem *) list->data)->uri);
|
||||
(nautilus_get_widget_background (GTK_WIDGET (container)), data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -697,22 +691,11 @@ nautilus_icon_container_receive_dropped_icons (NautilusIconContainer *container,
|
|||
GdkPoint *source_item_locations;
|
||||
int index;
|
||||
int count;
|
||||
GdkModifierType modifiers;
|
||||
|
||||
if (container->details->dnd_info->selection_list == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the shift key is down, then this is a drag that customizes
|
||||
* the background tile image.
|
||||
*/
|
||||
gdk_window_get_pointer (GTK_WIDGET (container)->window,
|
||||
NULL, NULL, &modifiers);
|
||||
if ((modifiers & GDK_SHIFT_MASK) != 0) {
|
||||
receive_dropped_tile_image (container);
|
||||
return;
|
||||
}
|
||||
|
||||
gnome_canvas_window_to_world (GNOME_CANVAS (container),
|
||||
x, y, &world_x, &world_y);
|
||||
|
||||
|
@ -1147,6 +1130,9 @@ drag_drop_callback (GtkWidget *widget,
|
|||
widget, x, y, dnd_info->selection_data);
|
||||
gtk_drag_finish (context, TRUE, FALSE, time);
|
||||
break;
|
||||
case NAUTILUS_ICON_DND_BGIMAGE:
|
||||
receive_dropped_tile_image (NAUTILUS_ICON_CONTAINER (widget), dnd_info->selection_data->data);
|
||||
break;
|
||||
default:
|
||||
gtk_drag_finish (context, FALSE, FALSE, time);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,8 @@ enum NautilusIconDndTargetType {
|
|||
NAUTILUS_ICON_DND_GNOME_ICON_LIST,
|
||||
NAUTILUS_ICON_DND_URI_LIST,
|
||||
NAUTILUS_ICON_DND_URL,
|
||||
NAUTILUS_ICON_DND_COLOR
|
||||
NAUTILUS_ICON_DND_COLOR,
|
||||
NAUTILUS_ICON_DND_BGIMAGE
|
||||
};
|
||||
|
||||
/* DnD target names. */
|
||||
|
@ -48,6 +49,7 @@ enum NautilusIconDndTargetType {
|
|||
#define NAUTILUS_ICON_DND_URI_LIST_TYPE "text/uri-list"
|
||||
#define NAUTILUS_ICON_DND_URL_TYPE "_NETSCAPE_URL"
|
||||
#define NAUTILUS_ICON_DND_COLOR_TYPE "application/x-color"
|
||||
#define NAUTILUS_ICON_DND_BGIMAGE_TYPE "property/bgimage"
|
||||
|
||||
/* DnD-related information. */
|
||||
struct NautilusIconDndInfo {
|
||||
|
|
|
@ -45,6 +45,8 @@ nautilus_SOURCES =\
|
|||
nautilus-index-title.h \
|
||||
nautilus-location-bar.c \
|
||||
nautilus-location-bar.h \
|
||||
nautilus-property-browser.c \
|
||||
nautilus-property-browser.h \
|
||||
nautilus-self-check-functions.c \
|
||||
nautilus-self-check-functions.h \
|
||||
nautilus-signaller.c \
|
||||
|
|
|
@ -91,12 +91,14 @@ static void add_command_buttons (NautilusIndexPanel *ind
|
|||
enum {
|
||||
TARGET_URI_LIST,
|
||||
TARGET_COLOR,
|
||||
TARGET_BGIMAGE,
|
||||
TARGET_GNOME_URI_LIST
|
||||
};
|
||||
|
||||
static GtkTargetEntry target_table[] = {
|
||||
{ "text/uri-list", 0, TARGET_URI_LIST },
|
||||
{ "application/x-color", 0, TARGET_COLOR },
|
||||
{ "property/bgimage", 0, TARGET_BGIMAGE },
|
||||
{ "special/x-gnome-icon-list", 0, TARGET_GNOME_URI_LIST }
|
||||
};
|
||||
|
||||
|
@ -393,7 +395,11 @@ nautilus_index_panel_drag_data_received (GtkWidget *widget, GdkDragContext *cont
|
|||
case TARGET_COLOR:
|
||||
receive_dropped_color (index_panel, x, y, selection_data);
|
||||
break;
|
||||
|
||||
case TARGET_BGIMAGE:
|
||||
|
||||
if (hit_test (index_panel, x, y) == BACKGROUND_PART)
|
||||
receive_dropped_uri_list (index_panel, x, y, selection_data);
|
||||
break;
|
||||
default:
|
||||
g_warning ("unknown drop type");
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include "nautilus-signaller.h"
|
||||
#include "ntl-app.h"
|
||||
#include "ntl-window-private.h"
|
||||
#include "nautilus-property-browser.h"
|
||||
|
||||
#include "libnautilus-extensions/nautilus-undo-manager.h"
|
||||
|
||||
#include <libnautilus/nautilus-bonobo-ui.h>
|
||||
|
@ -70,6 +72,7 @@ typedef struct {
|
|||
* don't want other code relying on their existence.
|
||||
*/
|
||||
#define NAUTILUS_MENU_PATH_GENERAL_SETTINGS_ITEM "/Settings/General Settings"
|
||||
#define NAUTILUS_MENU_PATH_CUSTOMIZE_ITEM "/Settings/Customize"
|
||||
#define NAUTILUS_MENU_PATH_USE_EAZEL_THEME_ICONS_ITEM "/Settings/Use Eazel Theme Icons"
|
||||
#define NAUTILUS_MENU_PATH_DEBUG_MENU "/Debug"
|
||||
#define NAUTILUS_MENU_PATH_SHOW_COLOR_SELECTOR_ITEM "/Debug/Show Color Selector"
|
||||
|
@ -247,6 +250,14 @@ settings_menu_general_settings_callback (BonoboUIHandler *ui_handler,
|
|||
nautilus_global_preferences_show_dialog ();
|
||||
}
|
||||
|
||||
static void
|
||||
settings_menu_customize_callback (BonoboUIHandler *ui_handler,
|
||||
gpointer user_data,
|
||||
const char *path)
|
||||
{
|
||||
nautilus_property_browser_new();
|
||||
}
|
||||
|
||||
static void
|
||||
settings_menu_use_eazel_theme_icons_callback (BonoboUIHandler *ui_handler,
|
||||
gpointer user_data,
|
||||
|
@ -800,6 +811,18 @@ nautilus_window_initialize_menus (NautilusWindow *window)
|
|||
settings_menu_general_settings_callback,
|
||||
NULL);
|
||||
|
||||
bonobo_ui_handler_menu_new_item (ui_handler,
|
||||
NAUTILUS_MENU_PATH_CUSTOMIZE_ITEM,
|
||||
_("_Customize..."),
|
||||
_("Displays the Property Browser, to add properties to objects and customize appearance"),
|
||||
-1,
|
||||
BONOBO_UI_HANDLER_PIXMAP_NONE,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
settings_menu_customize_callback,
|
||||
NULL);
|
||||
|
||||
/* It's called SEPARATOR_AFTER_USER_LEVELS because "General Settings" is
|
||||
* going to expand into the user level choices plus the choice that brings
|
||||
* up the user-level-details customizing dialog.
|
||||
|
|
684
src/nautilus-property-browser.c
Normal file
|
@ -0,0 +1,684 @@
|
|||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
|
||||
/* Nautilus
|
||||
* Copyright (C) 2000 Eazel, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Andy Hertzfeld <andy@eazel.com>
|
||||
*
|
||||
* This is the implementation of the property browser window, which gives the user access to an
|
||||
* extensible palette of properties which can be dropped on various elements of the user interface
|
||||
* to customize them
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <math.h>
|
||||
#include "nautilus-property-browser.h"
|
||||
|
||||
#include <parser.h>
|
||||
#include <xmlmemory.h>
|
||||
|
||||
#include <libgnomevfs/gnome-vfs.h>
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gnome.h>
|
||||
|
||||
#include <libnautilus-extensions/nautilus-background.h>
|
||||
#include <libnautilus-extensions/nautilus-directory.h>
|
||||
#include <libnautilus-extensions/nautilus-file.h>
|
||||
#include <libnautilus-extensions/nautilus-glib-extensions.h>
|
||||
#include <libnautilus-extensions/nautilus-gtk-extensions.h>
|
||||
#include <libnautilus-extensions/nautilus-gtk-macros.h>
|
||||
#include <libnautilus-extensions/nautilus-metadata.h>
|
||||
#include <libnautilus-extensions/nautilus-string.h>
|
||||
#include <libnautilus-extensions/nautilus-mime-type.h>
|
||||
|
||||
struct NautilusPropertyBrowserDetails {
|
||||
GtkVBox *container;
|
||||
|
||||
GtkWidget *content_frame;
|
||||
GtkWidget *content_table;
|
||||
|
||||
GtkWidget *title_box;
|
||||
GtkWidget *title_label;
|
||||
|
||||
char *path;
|
||||
char *category;
|
||||
char *dragged_file;
|
||||
char *drag_type;
|
||||
};
|
||||
|
||||
static void nautilus_property_browser_initialize_class (GtkObjectClass *object_klass);
|
||||
static void nautilus_property_browser_initialize (GtkObject *object);
|
||||
static void nautilus_property_browser_destroy (GtkObject *object);
|
||||
static void nautilus_property_browser_update_contents (NautilusPropertyBrowser *property_browser);
|
||||
static void nautilus_property_browser_set_category (NautilusPropertyBrowser *property_browser,
|
||||
const char *new_category);
|
||||
static void nautilus_property_browser_set_dragged_file (NautilusPropertyBrowser *property_browser,
|
||||
const char *dragged_file_name);
|
||||
static void nautilus_property_browser_set_drag_type (NautilusPropertyBrowser *property_browser,
|
||||
const char *new_drag_type);
|
||||
static void title_clicked_cb (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
NautilusPropertyBrowser *propery_browser);
|
||||
|
||||
static void nautilus_property_browser_drag_end (GtkWidget *widget, GdkDragContext *context);
|
||||
static void nautilus_property_browser_drag_data_get (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint32 time);
|
||||
|
||||
#define BROWSER_BACKGROUND_COLOR "rgb:DDDD/EEEE/FFFF"
|
||||
#define BROWSER_TITLE_IMAGE "white_marble.jpg"
|
||||
#define BROWSER_CATEGORIES_FILE_NAME "nautilus/browser.xml"
|
||||
|
||||
#define PROPERTY_BROWSER_WIDTH 480
|
||||
#define PROPERTY_BROWSER_HEIGHT 360
|
||||
|
||||
#define MAX_ICON_WIDTH 64
|
||||
#define MAX_ICON_HEIGHT 64
|
||||
|
||||
#define CONTENT_TABLE_WIDTH 6
|
||||
#define CONTENT_TABLE_HEIGHT 4
|
||||
|
||||
enum {
|
||||
PROPERTY_TYPE,
|
||||
};
|
||||
|
||||
static GtkTargetEntry drag_types[] = {
|
||||
{ "text/uri-list", 0, PROPERTY_TYPE }
|
||||
};
|
||||
|
||||
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusPropertyBrowser, nautilus_property_browser, GTK_TYPE_WINDOW)
|
||||
|
||||
/* initializing the class object by installing the operations we override */
|
||||
static void
|
||||
nautilus_property_browser_initialize_class (GtkObjectClass *object_klass)
|
||||
{
|
||||
NautilusPropertyBrowserClass *klass;
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (object_klass);
|
||||
|
||||
klass = NAUTILUS_PROPERTY_BROWSER_CLASS (object_klass);
|
||||
|
||||
object_klass->destroy = nautilus_property_browser_destroy;
|
||||
widget_class->drag_data_get = nautilus_property_browser_drag_data_get;
|
||||
widget_class->drag_end = nautilus_property_browser_drag_end;
|
||||
}
|
||||
|
||||
|
||||
/* initialize the instance's fields, create the necessary subviews, etc. */
|
||||
|
||||
static void
|
||||
nautilus_property_browser_initialize (GtkObject *object)
|
||||
{
|
||||
NautilusBackground *background;
|
||||
NautilusPropertyBrowser *property_browser;
|
||||
char *background_path, *background_uri;
|
||||
GtkWidget* widget, *temp_hbox, *temp_frame;
|
||||
|
||||
property_browser = NAUTILUS_PROPERTY_BROWSER (object);
|
||||
widget = GTK_WIDGET (object);
|
||||
|
||||
property_browser->details = g_new0 (NautilusPropertyBrowserDetails, 1);
|
||||
|
||||
property_browser->details->path = NULL;
|
||||
property_browser->details->category = NULL;
|
||||
property_browser->details->dragged_file = NULL;
|
||||
property_browser->details->drag_type = NULL;
|
||||
|
||||
/* set the initial size of the property browser */
|
||||
gtk_widget_set_usize (widget, PROPERTY_BROWSER_WIDTH, PROPERTY_BROWSER_HEIGHT);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (object), 0);
|
||||
|
||||
/* set up the background */
|
||||
|
||||
background = nautilus_get_widget_background (GTK_WIDGET (property_browser));
|
||||
nautilus_background_set_color (background, BROWSER_BACKGROUND_COLOR);
|
||||
|
||||
/* create the container box */
|
||||
property_browser->details->container = GTK_VBOX (gtk_vbox_new (FALSE, 0));
|
||||
gtk_container_set_border_width (GTK_CONTAINER (property_browser->details->container), 0);
|
||||
gtk_widget_show (GTK_WIDGET (property_browser->details->container));
|
||||
gtk_container_add (GTK_CONTAINER (property_browser),
|
||||
GTK_WIDGET (property_browser->details->container));
|
||||
|
||||
|
||||
/* create the title box */
|
||||
|
||||
property_browser->details->title_box = gtk_event_box_new();
|
||||
gtk_widget_show(property_browser->details->title_box);
|
||||
|
||||
background_path = gnome_datadir_file ("nautilus/backgrounds");
|
||||
background_uri = g_strdup_printf("file://%s/BROWSER_TITLE_IMAGE", background_path);
|
||||
background = nautilus_get_widget_background(property_browser->details->title_box);
|
||||
nautilus_background_set_tile_image_uri(background, background_uri);
|
||||
g_free(background_path);
|
||||
g_free(background_uri);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX(property_browser->details->container), property_browser->details->title_box, FALSE, FALSE, 0);
|
||||
gtk_signal_connect(GTK_OBJECT (property_browser->details->title_box), "button_press_event",
|
||||
GTK_SIGNAL_FUNC(title_clicked_cb), property_browser);
|
||||
|
||||
temp_frame = gtk_frame_new(NULL);
|
||||
gtk_frame_set_shadow_type(GTK_FRAME(temp_frame), GTK_SHADOW_OUT);
|
||||
gtk_widget_show(temp_frame);
|
||||
gtk_container_add(GTK_CONTAINER(property_browser->details->title_box), temp_frame);
|
||||
|
||||
temp_hbox = gtk_hbox_new(FALSE, 0);
|
||||
gtk_widget_show(temp_hbox);
|
||||
gtk_container_add(GTK_CONTAINER(temp_frame), temp_hbox);
|
||||
|
||||
property_browser->details->title_label = gtk_label_new("Select A Category:");
|
||||
nautilus_gtk_widget_set_font_by_name(property_browser->details->title_label, "-*-helvetica-medium-r-normal-*-18-*-*-*-*-*-*-*");
|
||||
gtk_widget_show(property_browser->details->title_label);
|
||||
gtk_box_pack_start (GTK_BOX(temp_hbox), property_browser->details->title_label, FALSE, FALSE, 8);
|
||||
|
||||
property_browser->details->content_frame = NULL;
|
||||
|
||||
/* initially, display the top level */
|
||||
nautilus_property_browser_set_path(property_browser, BROWSER_CATEGORIES_FILE_NAME);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_property_browser_destroy (GtkObject *object)
|
||||
{
|
||||
NautilusPropertyBrowser *property_browser;
|
||||
|
||||
property_browser = NAUTILUS_PROPERTY_BROWSER (object);
|
||||
|
||||
if (property_browser->details->path)
|
||||
g_free (property_browser->details->path);
|
||||
if (property_browser->details->category)
|
||||
g_free (property_browser->details->category);
|
||||
if (property_browser->details->dragged_file)
|
||||
g_free (property_browser->details->dragged_file);
|
||||
if (property_browser->details->drag_type)
|
||||
g_free (property_browser->details->drag_type);
|
||||
|
||||
g_free (property_browser->details);
|
||||
|
||||
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
|
||||
}
|
||||
|
||||
/* create a new instance */
|
||||
NautilusPropertyBrowser *
|
||||
nautilus_property_browser_new (void)
|
||||
{
|
||||
NautilusPropertyBrowser *browser = NAUTILUS_PROPERTY_BROWSER (gtk_type_new (nautilus_property_browser_get_type ()));
|
||||
|
||||
gtk_container_set_border_width (GTK_CONTAINER (browser), 2);
|
||||
gtk_window_set_policy (GTK_WINDOW(browser), FALSE, FALSE, FALSE);
|
||||
gtk_widget_show (GTK_WIDGET(browser));
|
||||
|
||||
return browser;
|
||||
}
|
||||
|
||||
/* remember the name of the dragged file */
|
||||
static void
|
||||
nautilus_property_browser_set_dragged_file (NautilusPropertyBrowser *property_browser, const char *dragged_file_name)
|
||||
{
|
||||
if (property_browser->details->dragged_file)
|
||||
g_free (property_browser->details->dragged_file);
|
||||
property_browser->details->dragged_file = g_strdup (dragged_file_name);
|
||||
}
|
||||
|
||||
/* remember the drag type */
|
||||
static void
|
||||
nautilus_property_browser_set_drag_type (NautilusPropertyBrowser *property_browser, const char *new_drag_type)
|
||||
{
|
||||
if (property_browser->details->drag_type)
|
||||
g_free (property_browser->details->drag_type);
|
||||
property_browser->details->drag_type = g_strdup (new_drag_type);
|
||||
}
|
||||
|
||||
/* drag and drop data get handler */
|
||||
|
||||
static void
|
||||
nautilus_property_browser_drag_data_get (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint32 time)
|
||||
{
|
||||
char *temp_str, *path, *image_file_uri;
|
||||
NautilusPropertyBrowser *property_browser = NAUTILUS_PROPERTY_BROWSER(widget);
|
||||
|
||||
g_return_if_fail (widget != NULL);
|
||||
g_return_if_fail (context != NULL);
|
||||
|
||||
switch (info) {
|
||||
case PROPERTY_TYPE:
|
||||
temp_str = g_strdup_printf("nautilus/%s", property_browser->details->category);
|
||||
path = gnome_datadir_file (temp_str);
|
||||
image_file_uri = g_strdup_printf("file://%s/%s", path, property_browser->details->dragged_file);
|
||||
|
||||
gtk_selection_data_set(selection_data, selection_data->target, 8, image_file_uri, strlen(image_file_uri));
|
||||
|
||||
g_free(temp_str);
|
||||
g_free(path);
|
||||
g_free(image_file_uri);
|
||||
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
/* drag and drop end handler, where we destroy ourselves, since the transaction is complete */
|
||||
|
||||
static void
|
||||
nautilus_property_browser_drag_end(GtkWidget *widget, GdkDragContext *context)
|
||||
{
|
||||
gtk_object_destroy(GTK_OBJECT(widget));
|
||||
}
|
||||
|
||||
/* utility routine to scale the passed-in pixbuf to be smaller than the maximum allowed size, if necessary */
|
||||
|
||||
static GdkPixbuf*
|
||||
scale_pixbuf_to_fit(GdkPixbuf* pixbuf)
|
||||
{
|
||||
double scale_factor;
|
||||
double h_scale = 1.0;
|
||||
double v_scale = 1.0;
|
||||
|
||||
gint width = gdk_pixbuf_get_width(pixbuf);
|
||||
gint height = gdk_pixbuf_get_height(pixbuf);
|
||||
|
||||
if (width > MAX_ICON_WIDTH) {
|
||||
h_scale = MAX_ICON_WIDTH / (double) width;
|
||||
}
|
||||
if (height > MAX_ICON_HEIGHT) {
|
||||
v_scale = MAX_ICON_HEIGHT / (double) height;
|
||||
}
|
||||
scale_factor = MIN (h_scale, v_scale);
|
||||
|
||||
if (scale_factor < 1.0) {
|
||||
GdkPixbuf *scaled_pixbuf;
|
||||
int scaled_width = floor(width * scale_factor + .5);
|
||||
int scaled_height = floor(height * scale_factor + .5);
|
||||
|
||||
scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf, scaled_width, scaled_height, GDK_INTERP_BILINEAR);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
pixbuf = scaled_pixbuf;
|
||||
}
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
/* create the appropriate pixbuf for the passed in file */
|
||||
static GdkPixbuf*
|
||||
make_drag_image(NautilusPropertyBrowser *property_browser, const char* file_name)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
char *temp_str = g_strdup_printf("nautilus/%s", property_browser->details->category);
|
||||
char *path = gnome_datadir_file (temp_str);
|
||||
|
||||
char *image_file_name = g_strdup_printf("%s/%s", path, file_name);
|
||||
pixbuf = scale_pixbuf_to_fit(gdk_pixbuf_new_from_file(image_file_name));
|
||||
|
||||
g_free(image_file_name);
|
||||
g_free(temp_str);
|
||||
g_free(path);
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
/* this callback handles button presses on the category widget */
|
||||
|
||||
static void
|
||||
category_clicked_cb(GtkWidget *widget, char *category_name)
|
||||
{
|
||||
NautilusPropertyBrowser *property_browser = NAUTILUS_PROPERTY_BROWSER(gtk_object_get_user_data(GTK_OBJECT(widget)));
|
||||
nautilus_property_browser_set_category(property_browser, category_name);
|
||||
}
|
||||
|
||||
/* handle clicks on the title bar */
|
||||
static void
|
||||
title_clicked_cb(GtkWidget *widget, GdkEventButton *event, NautilusPropertyBrowser *property_browser)
|
||||
{
|
||||
/* for now, all clicks on the title bar return to the main level */
|
||||
nautilus_property_browser_set_category(property_browser, NULL);
|
||||
}
|
||||
|
||||
/* this callback handles clicks on the content elements */
|
||||
|
||||
static void
|
||||
element_clicked_cb(GtkWidget *widget, GdkEventButton *event, char *element_name)
|
||||
{
|
||||
GtkTargetList *target_list;
|
||||
GdkDragContext *context;
|
||||
GtkWidget *pixwidget;
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkPixmap *pixmap_for_dragged_file;
|
||||
GdkBitmap *mask_for_dragged_file;
|
||||
int pixmap_width, pixmap_height;
|
||||
int x_delta, y_delta;
|
||||
NautilusPropertyBrowser *property_browser = NAUTILUS_PROPERTY_BROWSER(gtk_object_get_user_data(GTK_OBJECT(widget)));
|
||||
|
||||
/* set up the drag and drop type corresponding to the category */
|
||||
drag_types[0].target = property_browser->details->drag_type;
|
||||
target_list = gtk_target_list_new (drag_types, NAUTILUS_N_ELEMENTS (drag_types));
|
||||
|
||||
nautilus_property_browser_set_dragged_file(property_browser, element_name);
|
||||
|
||||
context = gtk_drag_begin (GTK_WIDGET (property_browser),
|
||||
target_list,
|
||||
GDK_ACTION_MOVE | GDK_ACTION_COPY,
|
||||
event->button,
|
||||
(GdkEvent *) event);
|
||||
|
||||
/* compute the offsets for dragging */
|
||||
|
||||
pixwidget = GTK_BIN(widget)->child;
|
||||
gtk_pixmap_get(GTK_PIXMAP(pixwidget), &pixmap_for_dragged_file, &mask_for_dragged_file);
|
||||
gdk_window_get_size((GdkWindow*) pixmap_for_dragged_file, &pixmap_width, &pixmap_height);
|
||||
x_delta = floor(event->x + .5) - ((widget->allocation.width - pixmap_width) >> 1);
|
||||
y_delta = floor(event->y + .5) - ((widget->allocation.height - pixmap_height) >> 1);
|
||||
|
||||
/* set the pixmap and mask for dragging */
|
||||
pixbuf = make_drag_image(property_browser, element_name);
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf,
|
||||
&pixmap_for_dragged_file,
|
||||
&mask_for_dragged_file,
|
||||
128);
|
||||
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
gtk_drag_set_icon_pixmap (context,
|
||||
gtk_widget_get_colormap (GTK_WIDGET (property_browser)),
|
||||
pixmap_for_dragged_file,
|
||||
mask_for_dragged_file,
|
||||
x_delta, y_delta);
|
||||
|
||||
/* hide the property browser - it will later be destroyed when the drag ends */
|
||||
gtk_widget_hide(GTK_WIDGET(property_browser));
|
||||
}
|
||||
|
||||
/* utility routine to strip the extension from the passed in string */
|
||||
static char*
|
||||
strip_extension(const char* string_to_strip)
|
||||
{
|
||||
char *result_str, *temp_str;
|
||||
if (string_to_strip == NULL)
|
||||
return NULL;
|
||||
|
||||
result_str = g_strdup(string_to_strip);
|
||||
temp_str = strrchr(result_str, '.');
|
||||
if (temp_str)
|
||||
*temp_str = '\0';
|
||||
return result_str;
|
||||
}
|
||||
|
||||
/* utility routine to add the passed-in widget to the content table */
|
||||
|
||||
static void
|
||||
add_to_content_table(NautilusPropertyBrowser *property_browser, GtkWidget* widget, int position, int padding)
|
||||
{
|
||||
int column_pos = position % CONTENT_TABLE_WIDTH;
|
||||
int row_pos = position / CONTENT_TABLE_WIDTH;
|
||||
|
||||
gtk_table_attach(GTK_TABLE(property_browser->details->content_table), widget,
|
||||
column_pos, column_pos + 1, row_pos ,row_pos + 1,
|
||||
GTK_FILL, GTK_FILL, padding, padding);
|
||||
}
|
||||
|
||||
/* make_category_path generates widgets corresponding all of the objects in the passed in directory */
|
||||
|
||||
static void
|
||||
make_category_path(NautilusPropertyBrowser *property_browser, const char* path, const char* mode)
|
||||
{
|
||||
NautilusBackground *background;
|
||||
int index = 0;
|
||||
/* case out on the mode: if the mode is directory, handle by iterating through the directory */
|
||||
if (!strcmp(mode, "directory")) {
|
||||
GnomeVFSResult result;
|
||||
GnomeVFSFileInfo *current_file_info;
|
||||
GnomeVFSDirectoryList *list;
|
||||
|
||||
char *temp_str = g_strdup_printf("nautilus/%s", property_browser->details->category);
|
||||
char *xml_path = gnome_datadir_file (temp_str);
|
||||
char *xml_uri = g_strdup_printf("file://%s", xml_path);
|
||||
|
||||
result = gnome_vfs_directory_list_load(&list, xml_uri, GNOME_VFS_FILE_INFO_GETMIMETYPE, NULL, NULL);
|
||||
g_free(temp_str);
|
||||
g_free(xml_uri);
|
||||
|
||||
if (result != GNOME_VFS_OK) {
|
||||
g_free(xml_path);
|
||||
return;
|
||||
}
|
||||
/* interate through the directory for each file */
|
||||
current_file_info = gnome_vfs_directory_list_first(list);
|
||||
while (current_file_info != NULL) {
|
||||
/* if the file is an image, generate a widget corresponding to it */
|
||||
if (nautilus_str_has_prefix(current_file_info->mime_type, "image/")) {
|
||||
/* load a pixbuf scaled to the proper size, then create a pixbuf widget to hold it */
|
||||
char *image_file_name, *filtered_name;
|
||||
GdkPixmap *pixmap;
|
||||
GdkBitmap *mask;
|
||||
GdkPixbuf *pixbuf;
|
||||
GtkWidget *event_box, *temp_vbox;
|
||||
GtkWidget *pixmap_widget, *label;
|
||||
|
||||
image_file_name = g_strdup_printf("%s/%s", xml_path, current_file_info->name);
|
||||
pixbuf = gdk_pixbuf_new_from_file(image_file_name);
|
||||
g_free(image_file_name);
|
||||
|
||||
pixbuf = scale_pixbuf_to_fit(pixbuf);
|
||||
|
||||
/* make a pixmap and mask to pass to the widget */
|
||||
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &mask, 128);
|
||||
gdk_pixbuf_unref (pixbuf);
|
||||
|
||||
/* allocate a pixmap and insert it into the table */
|
||||
temp_vbox = gtk_vbox_new(FALSE, 0);
|
||||
gtk_widget_show(temp_vbox);
|
||||
|
||||
event_box = gtk_event_box_new();
|
||||
gtk_widget_show(event_box);
|
||||
|
||||
background = nautilus_get_widget_background (GTK_WIDGET (event_box));
|
||||
nautilus_background_set_color (background, BROWSER_BACKGROUND_COLOR);
|
||||
|
||||
pixmap_widget = GTK_WIDGET (gtk_pixmap_new (pixmap, mask));
|
||||
gtk_widget_show (pixmap_widget);
|
||||
gtk_container_add(GTK_CONTAINER(event_box), pixmap_widget);
|
||||
gtk_box_pack_start(GTK_BOX(temp_vbox), event_box, FALSE, FALSE, 0);
|
||||
|
||||
filtered_name = strip_extension(current_file_info->name);
|
||||
label = gtk_label_new(filtered_name);
|
||||
g_free(filtered_name);
|
||||
gtk_box_pack_start (GTK_BOX(temp_vbox), label, FALSE, FALSE, 0);
|
||||
gtk_widget_show(label);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT (event_box), "button_press_event",
|
||||
GTK_SIGNAL_FUNC(element_clicked_cb), g_strdup(current_file_info->name));
|
||||
gtk_object_set_user_data(GTK_OBJECT(event_box), property_browser);
|
||||
|
||||
add_to_content_table(property_browser, temp_vbox, index++, 2);
|
||||
}
|
||||
|
||||
current_file_info = gnome_vfs_directory_list_next(list);
|
||||
}
|
||||
|
||||
gnome_vfs_directory_list_destroy(list);
|
||||
g_free(xml_path);
|
||||
|
||||
} else if (!strcmp(mode, "xml")) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* this is a utility routine to generate a category link widget and install it in the browser */
|
||||
|
||||
static void
|
||||
make_category_link(NautilusPropertyBrowser *property_browser, char* name, char* image, gint index)
|
||||
{
|
||||
GtkWidget *label, *pix_widget, *button, *temp_vbox;
|
||||
char *file_name = gnome_pixmap_file (image);
|
||||
GtkWidget* temp_box = gtk_vbox_new(FALSE, 0);
|
||||
|
||||
/* generate a pixmap widget from the image file name */
|
||||
pix_widget = GTK_WIDGET (gnome_pixmap_new_from_file (file_name));
|
||||
gtk_widget_show (pix_widget);
|
||||
gtk_box_pack_start (GTK_BOX(temp_box), pix_widget, FALSE, FALSE, 0);
|
||||
|
||||
button = gtk_button_new();
|
||||
gtk_widget_show(button);
|
||||
gtk_widget_set_usize(button, 96, 80);
|
||||
|
||||
/* use the name as a label */
|
||||
label = gtk_label_new(name);
|
||||
gtk_box_pack_start (GTK_BOX(temp_box), label, FALSE, FALSE, 0);
|
||||
gtk_widget_show(label);
|
||||
|
||||
/* put the button in a vbox so it won't grow vertically */
|
||||
temp_vbox = gtk_vbox_new(FALSE, 0);
|
||||
gtk_widget_show(temp_vbox);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX(temp_vbox), button, FALSE, FALSE, 8);
|
||||
add_to_content_table(property_browser, temp_vbox, index, 8);
|
||||
gtk_container_add (GTK_CONTAINER(button), temp_box);
|
||||
gtk_widget_show(temp_box);
|
||||
|
||||
/* add a signal to handle clicks */
|
||||
gtk_signal_connect(GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (category_clicked_cb), g_strdup(name));
|
||||
gtk_object_set_user_data(GTK_OBJECT(button), property_browser);
|
||||
|
||||
g_free (file_name);
|
||||
}
|
||||
|
||||
/* update_contents populates the property browser with information specified by the path and other state variables */
|
||||
|
||||
void
|
||||
nautilus_property_browser_update_contents (NautilusPropertyBrowser *property_browser)
|
||||
{
|
||||
char *xml_path;
|
||||
xmlNodePtr cur_node;
|
||||
xmlDocPtr document;
|
||||
NautilusBackground *background;
|
||||
GtkWidget *viewport;
|
||||
gint index = 0;
|
||||
|
||||
/* load the xml document corresponding to the path and selection */
|
||||
xml_path = gnome_datadir_file (property_browser->details->path);
|
||||
document = xmlParseFile (xml_path);
|
||||
g_free(xml_path);
|
||||
if (document == NULL)
|
||||
return;
|
||||
|
||||
/* remove the existing content box, if any, and allocate a new one */
|
||||
|
||||
if (property_browser->details->content_frame) {
|
||||
gtk_widget_destroy(property_browser->details->content_frame);
|
||||
}
|
||||
|
||||
/* allocate a new container, with a scrollwindow and viewport */
|
||||
|
||||
property_browser->details->content_frame = gtk_scrolled_window_new (NULL, NULL);
|
||||
viewport = gtk_viewport_new(NULL, NULL);
|
||||
gtk_widget_show(viewport);
|
||||
gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
|
||||
background = nautilus_get_widget_background (viewport);
|
||||
nautilus_background_set_color (background, BROWSER_BACKGROUND_COLOR);
|
||||
gtk_container_add (GTK_CONTAINER (property_browser->details->container), property_browser->details->content_frame);
|
||||
gtk_widget_show (property_browser->details->content_frame);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (property_browser->details->content_frame), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||
|
||||
/* allocate a table to hold the content widgets */
|
||||
property_browser->details->content_table = gtk_table_new(CONTENT_TABLE_WIDTH, CONTENT_TABLE_HEIGHT, FALSE);
|
||||
gtk_container_add(GTK_CONTAINER(viewport), property_browser->details->content_table);
|
||||
gtk_container_add (GTK_CONTAINER (property_browser->details->content_frame), viewport);
|
||||
gtk_widget_show (GTK_WIDGET (property_browser->details->content_table));
|
||||
|
||||
/* iterate through the xml file to generate the widgets */
|
||||
cur_node = document->root->childs;
|
||||
while (cur_node != NULL) {
|
||||
if (!strcmp(cur_node->name, "category")) {
|
||||
char* category_name = xmlGetProp (cur_node, "name");
|
||||
char* category_image = xmlGetProp (cur_node, "image");
|
||||
char* category_type = xmlGetProp (cur_node, "type");
|
||||
|
||||
if (property_browser->details->category && !strcmp(property_browser->details->category, category_name)) {
|
||||
char *category_path = xmlGetProp (cur_node, "path");
|
||||
char *category_mode = xmlGetProp (cur_node, "mode");
|
||||
|
||||
make_category_path(property_browser, category_path, category_mode);
|
||||
nautilus_property_browser_set_drag_type(property_browser, category_type);
|
||||
break;
|
||||
}
|
||||
else if (property_browser->details->category == NULL)
|
||||
make_category_link(property_browser, category_name, category_image, index++);
|
||||
}
|
||||
cur_node = cur_node->next;
|
||||
}
|
||||
|
||||
/* release the xml document and we're done */
|
||||
if (document)
|
||||
xmlFreeDoc(document);
|
||||
|
||||
/* update the title */
|
||||
if (property_browser->details->category == NULL)
|
||||
gtk_label_set_text(GTK_LABEL(property_browser->details->title_label), "Select A Category:");
|
||||
else {
|
||||
char *label_text = g_strdup_printf("Categories: %s", property_browser->details->category);
|
||||
gtk_label_set_text(GTK_LABEL(property_browser->details->title_label), label_text);
|
||||
g_free(label_text);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* set the category and regenerate contents as necessary */
|
||||
|
||||
static void
|
||||
nautilus_property_browser_set_category (NautilusPropertyBrowser *property_browser, const char *new_category)
|
||||
{
|
||||
/* there's nothing to do if the category is the same as the current one */
|
||||
if (nautilus_strcmp (property_browser->details->category, new_category) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (property_browser->details->category)
|
||||
g_free (property_browser->details->category);
|
||||
if (new_category)
|
||||
property_browser->details->category = g_strdup (new_category);
|
||||
else
|
||||
property_browser->details->category = NULL;
|
||||
|
||||
/* populate the per-uri box with the info */
|
||||
nautilus_property_browser_update_contents (property_browser);
|
||||
}
|
||||
|
||||
|
||||
/* here is the routine that populates the property browser with the appropriate information
|
||||
when the path changes */
|
||||
|
||||
void
|
||||
nautilus_property_browser_set_path (NautilusPropertyBrowser *property_browser,
|
||||
const char* new_path)
|
||||
{
|
||||
/* there's nothing to do if the uri is the same as the current one */
|
||||
if (nautilus_strcmp (property_browser->details->path, new_path) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (property_browser->details->path)
|
||||
g_free (property_browser->details->path);
|
||||
property_browser->details->path = g_strdup (new_path);
|
||||
|
||||
/* populate the per-uri box with the info */
|
||||
nautilus_property_browser_update_contents (property_browser);
|
||||
}
|
64
src/nautilus-property-browser.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
|
||||
/* Nautilus
|
||||
* Copyright (C) 2000 Eazel, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Andy Hertzfeld <andy@eazel.com>
|
||||
*
|
||||
* This is the header file for the property browser window, which gives the user access to an
|
||||
* extensible palette of properties which can be dropped on various elements of the user interface
|
||||
* to customize them
|
||||
*/
|
||||
|
||||
#ifndef NTL_PROPERTY_BROWSER_H
|
||||
#define NTL_PROPERTY_BROWSER_H
|
||||
|
||||
#include <gtk/gtkwindow.h>
|
||||
|
||||
typedef struct NautilusPropertyBrowser NautilusPropertyBrowser;
|
||||
typedef struct NautilusPropertyBrowserClass NautilusPropertyBrowserClass;
|
||||
|
||||
#define NAUTILUS_TYPE_PROPERTY_BROWSER \
|
||||
(nautilus_property_browser_get_type ())
|
||||
#define NAUTILUS_PROPERTY_BROWSER(obj) \
|
||||
(GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_PROPERTY_BROWSER, NautilusPropertyBrowser))
|
||||
#define NAUTILUS_PROPERTY_BROWSER_CLASS(klass) \
|
||||
(GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_PROPERTY_BROWSER, NautilusPropertyBrowserClass))
|
||||
#define NAUTILUS_IS_PROPERTY_BROWSER(obj) \
|
||||
(GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_PROPERTY_BROWSER))
|
||||
#define NAUTILUS_IS_PROPERTY_BROWSER_CLASS(klass) \
|
||||
(GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_PROPERTY_BROWSER))
|
||||
|
||||
typedef struct NautilusPropertyBrowserDetails NautilusPropertyBrowserDetails;
|
||||
|
||||
struct NautilusPropertyBrowser
|
||||
{
|
||||
GtkWindow window;
|
||||
NautilusPropertyBrowserDetails *details;
|
||||
};
|
||||
|
||||
struct NautilusPropertyBrowserClass
|
||||
{
|
||||
GtkWindowClass parent_class;
|
||||
};
|
||||
|
||||
GtkType nautilus_property_browser_get_type (void);
|
||||
NautilusPropertyBrowser *nautilus_property_browser_new (void);
|
||||
void nautilus_property_browser_set_path (NautilusPropertyBrowser *panel,
|
||||
const char *new_path);
|
||||
|
||||
#endif /* NTL_PROPERTY_BROWSER_H */
|
|
@ -91,12 +91,14 @@ static void add_command_buttons (NautilusIndexPanel *ind
|
|||
enum {
|
||||
TARGET_URI_LIST,
|
||||
TARGET_COLOR,
|
||||
TARGET_BGIMAGE,
|
||||
TARGET_GNOME_URI_LIST
|
||||
};
|
||||
|
||||
static GtkTargetEntry target_table[] = {
|
||||
{ "text/uri-list", 0, TARGET_URI_LIST },
|
||||
{ "application/x-color", 0, TARGET_COLOR },
|
||||
{ "property/bgimage", 0, TARGET_BGIMAGE },
|
||||
{ "special/x-gnome-icon-list", 0, TARGET_GNOME_URI_LIST }
|
||||
};
|
||||
|
||||
|
@ -393,7 +395,11 @@ nautilus_index_panel_drag_data_received (GtkWidget *widget, GdkDragContext *cont
|
|||
case TARGET_COLOR:
|
||||
receive_dropped_color (index_panel, x, y, selection_data);
|
||||
break;
|
||||
|
||||
case TARGET_BGIMAGE:
|
||||
|
||||
if (hit_test (index_panel, x, y) == BACKGROUND_PART)
|
||||
receive_dropped_uri_list (index_panel, x, y, selection_data);
|
||||
break;
|
||||
default:
|
||||
g_warning ("unknown drop type");
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include "nautilus-signaller.h"
|
||||
#include "ntl-app.h"
|
||||
#include "ntl-window-private.h"
|
||||
#include "nautilus-property-browser.h"
|
||||
|
||||
#include "libnautilus-extensions/nautilus-undo-manager.h"
|
||||
|
||||
#include <libnautilus/nautilus-bonobo-ui.h>
|
||||
|
@ -70,6 +72,7 @@ typedef struct {
|
|||
* don't want other code relying on their existence.
|
||||
*/
|
||||
#define NAUTILUS_MENU_PATH_GENERAL_SETTINGS_ITEM "/Settings/General Settings"
|
||||
#define NAUTILUS_MENU_PATH_CUSTOMIZE_ITEM "/Settings/Customize"
|
||||
#define NAUTILUS_MENU_PATH_USE_EAZEL_THEME_ICONS_ITEM "/Settings/Use Eazel Theme Icons"
|
||||
#define NAUTILUS_MENU_PATH_DEBUG_MENU "/Debug"
|
||||
#define NAUTILUS_MENU_PATH_SHOW_COLOR_SELECTOR_ITEM "/Debug/Show Color Selector"
|
||||
|
@ -247,6 +250,14 @@ settings_menu_general_settings_callback (BonoboUIHandler *ui_handler,
|
|||
nautilus_global_preferences_show_dialog ();
|
||||
}
|
||||
|
||||
static void
|
||||
settings_menu_customize_callback (BonoboUIHandler *ui_handler,
|
||||
gpointer user_data,
|
||||
const char *path)
|
||||
{
|
||||
nautilus_property_browser_new();
|
||||
}
|
||||
|
||||
static void
|
||||
settings_menu_use_eazel_theme_icons_callback (BonoboUIHandler *ui_handler,
|
||||
gpointer user_data,
|
||||
|
@ -800,6 +811,18 @@ nautilus_window_initialize_menus (NautilusWindow *window)
|
|||
settings_menu_general_settings_callback,
|
||||
NULL);
|
||||
|
||||
bonobo_ui_handler_menu_new_item (ui_handler,
|
||||
NAUTILUS_MENU_PATH_CUSTOMIZE_ITEM,
|
||||
_("_Customize..."),
|
||||
_("Displays the Property Browser, to add properties to objects and customize appearance"),
|
||||
-1,
|
||||
BONOBO_UI_HANDLER_PIXMAP_NONE,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
settings_menu_customize_callback,
|
||||
NULL);
|
||||
|
||||
/* It's called SEPARATOR_AFTER_USER_LEVELS because "General Settings" is
|
||||
* going to expand into the user level choices plus the choice that brings
|
||||
* up the user-level-details customizing dialog.
|
||||
|
|
|
@ -91,12 +91,14 @@ static void add_command_buttons (NautilusIndexPanel *ind
|
|||
enum {
|
||||
TARGET_URI_LIST,
|
||||
TARGET_COLOR,
|
||||
TARGET_BGIMAGE,
|
||||
TARGET_GNOME_URI_LIST
|
||||
};
|
||||
|
||||
static GtkTargetEntry target_table[] = {
|
||||
{ "text/uri-list", 0, TARGET_URI_LIST },
|
||||
{ "application/x-color", 0, TARGET_COLOR },
|
||||
{ "property/bgimage", 0, TARGET_BGIMAGE },
|
||||
{ "special/x-gnome-icon-list", 0, TARGET_GNOME_URI_LIST }
|
||||
};
|
||||
|
||||
|
@ -393,7 +395,11 @@ nautilus_index_panel_drag_data_received (GtkWidget *widget, GdkDragContext *cont
|
|||
case TARGET_COLOR:
|
||||
receive_dropped_color (index_panel, x, y, selection_data);
|
||||
break;
|
||||
|
||||
case TARGET_BGIMAGE:
|
||||
|
||||
if (hit_test (index_panel, x, y) == BACKGROUND_PART)
|
||||
receive_dropped_uri_list (index_panel, x, y, selection_data);
|
||||
break;
|
||||
default:
|
||||
g_warning ("unknown drop type");
|
||||
}
|
||||
|
|