diff options
-rw-r--r-- | ChangeLog-20000414 | 49 | ||||
-rw-r--r-- | docs/recommended-books.html | 167 | ||||
-rw-r--r-- | libnautilus-extensions/gnome-icon-container.c | 8 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-icon-factory.c | 101 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-icon-factory.h | 12 | ||||
-rw-r--r-- | libnautilus-private/gnome-icon-container.c | 8 | ||||
-rw-r--r-- | libnautilus-private/nautilus-icon-factory.c | 101 | ||||
-rw-r--r-- | libnautilus-private/nautilus-icon-factory.h | 12 | ||||
-rw-r--r-- | libnautilus/gnome-icon-container.c | 8 | ||||
-rw-r--r-- | libnautilus/nautilus-icon-factory.c | 101 | ||||
-rw-r--r-- | libnautilus/nautilus-icon-factory.h | 12 | ||||
-rw-r--r-- | src/file-manager/fm-directory-view.c | 60 |
12 files changed, 556 insertions, 83 deletions
diff --git a/ChangeLog-20000414 b/ChangeLog-20000414 index fbd315606..cd7e170f2 100644 --- a/ChangeLog-20000414 +++ b/ChangeLog-20000414 @@ -1,3 +1,30 @@ +2000-02-18 Darin Adler <darin@eazel.com> + + * src/file-manager/fm-directory-view.c: + (use_eazel_theme_icons_cb), (finish_adding_menu_item), + (add_menu_item), (add_check_menu_item), + (fm_directory_view_real_append_background_context_menu_items): + Hooked up the menu item for using the Eazel Theme Icons so people + can try out the icons that are tuned at different sizes. + + * libnautilus/nautilus-icon-factory.h: + * libnautilus/nautilus-icon-factory.c, + (nautilus_icon_factory_get), (nautilus_icon_factory_new), + (nautilus_icon_factory_initialize), + (nautilus_icon_factory_initialize_class), + (nautilus_icon_factory_get_theme), + (nautilus_icon_factory_set_theme): Added a signal "theme_changed" + to the icon factory, and had to add a visible icon factory object + so clients can connect to the signal. + + * libnautilus/gnome-icon-container.c, + (gnome_icon_container_initialize), + (gnome_icon_container_request_update_all): Update all icons when + the theme changes. + + * docs/recommended-books.html: Added this since + style-guide.html refers to it. + 2000-02-18 John Sullivan <sullivan@eazel.com> Made bookmarks (including in history list) for file system @@ -73,29 +100,31 @@ 2000-02-17 Andy Hertzfeld <andy@eazel.com> - improved index panel command buttons. There's still a problem with the button box removal, though. + Improved index panel command buttons. There's still a problem + with the button box removal, though. * libnautilus/nautilus-mime-type.c: - changed how command strings are structured to a simpler scheme with no substitution + Changed how command strings are structured to a simpler scheme + with no substitution. * src/ntl-index-panel.c: - improved the way commands are launched and fixed a bug in the button removal code, but - there's still some problems. + Improved the way commands are launched and fixed a bug in the + button removal code, but there's still some problems. 2000-02-17 Andy Hertzfeld <andy@eazel.com> implemented command buttons for the index panel. - * libnautilus/nautilus-mime-type.c,h: - this is interim code for associating applications with mime-types; we + * libnautilus/nautilus-mime-type.c, libnautilus/nautilus-mime-type.h: + This is interim code for associating applications with mime-types; we will eventually keep this in OAF or GConf or at least in a file - somewhere, but for now it's just scaffolding so we can work on the UI + somewhere, but for now it's just scaffolding so we can work on the UI. * libnautilus/Makefile.am: - make nautilus-mime-type.c,h build + Make nautilus-mime-type.c,h build. * stc/ntl-index-panel.c: - added code to call nautilus-mime-types to get relevant commands based + Added code to call nautilus-mime-types to get relevant commands based on the mime-type, and then generate corresponding buttons in the index - panel + panel. 2000-02-17 Darin Adler <darin@eazel.com> diff --git a/docs/recommended-books.html b/docs/recommended-books.html new file mode 100644 index 000000000..ee79eeed2 --- /dev/null +++ b/docs/recommended-books.html @@ -0,0 +1,167 @@ +<html> + +<head> +<title>Eazel: Darin's Recommended Programming Books</title> +</head> + +<body> + +<p>This document was really more for Eazel than for all Nautilus hackers, +but since the style guide references it, I checked it into the Nautilus CVS +for now. Later we can figure out what to do with it.</p> + +<p>This document is left over from when Eazel was doing a program in C++. +Soon, I'll rearrange the document so it doesn't put all the C++ stuff first, +since C++ is immaterial for the current Nautilus project.</p> + +<p>If you buy books from Amazon.com using the links on this page, Darin will get a small kickback from Amazon.</p> + +<p>One of the main reasons for creating this list is that there are many poor C++ books out there. +I've picked out a small number of extremely useful books so you won't have to wade through the weaker ones.</p> + +<h2>C++ Reference Books</h2> + +<p>These books cover the C++ language and library. All of them except for the +C++ standard itself also contain useful introductory material. For some +programmers, these are enough to explain the features of the language.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201889544/dianepattersonstA"><b><i>The C++ Programming Language, Third Edition</i></b></a>, +Bjarne Stroustrup. This is the book by the creator of the C++ language. This third edition is far superior +to the first two, and covers the ISO Standard version of the language in detail, including the library. +Any serious C++ programmer should read this book. There have been many corrections since the first printing, so get +the newest printing you can. Bjarne has <a href="http://www.research.att.com/~bs/3rd.html">supporting materials</a> +for the book on the web, including the errata lists that enumerate all changes between printings.</p> + +<p><a name="Josuttis" href="http://www.amazon.com/exec/obidos/ASIN/0201379260/dianepattersonstA"><b><i>The C++ Standard Library</i></b></a>, +Nicolai M. Josuttis. This book has the best coverage of the library. There have been tons of others that cover +the library, or focus on the STL or streams. But Josuttis covers all these subjects better than any of his +predecessors. Since we use the library extensively in Eazel projects, this is a must read. +The author has some useful <a href="http://josuttis.com/libbook">supporting materials</a> on the web.</p> + +<h2>C++ Technique Books</h2> + +<p>These books are about specific programming techniques for writing code in C++. +They can help you understand idioms you'll find in our code. +This kind of idiomatic programming is important in C++, because the language +gives you so much freedom to write unusable, unmaintainable code.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201615622/dianepattersonstA"><b><i>Exceptional C++</i></b></a>, +Herb Sutter. This is a collection of material that was originally part of Herb's +<a href="http://www.peerdirect.com/resources"><i>Guru of the Week</i></a>. This includes much of the most +advanced C++ information available. I learned many of the most important techniques from Herb, including +the swap technique for writing safe assignment operators. Herb covers each topic thoroughly.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201423391/dianepattersonstA"><b><i>Ruminations on C++</i></b></a>, +Andrew Koenig and Barbara Moo.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201924889/dianepattersonstA"><b><i>Effective C++, Second Edition</i></b></a> +and <a href="http://www.amazon.com/exec/obidos/ASIN/020163371X/dianepattersonstA"><b><i>More Effective C++</i></b></a>, +Scott Meyers. These books contain a laundry list of important C++ idioms. The books are a bit less +important now than when they were first released, but still full of valuable stuff. There's also a +<a href="http://www.amazon.com/exec/obidos/ASIN/0201310155/dianepattersonstA">CD edition</a> +(there's a <a href="http://mox.eazel.com/mec">copy</a> of it on Rob's machine) +that contains both books in electronic form. The publisher's web site has a good collection of +supporting materials for both +<a href="http://cseng.aw.com/bookdetail.qry?ISBN=0-201-92488-9">the original</a> and +<a href="http://cseng.aw.com/bookdetail.qry?ISBN=0-201-63371-X">the second book</a></p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201543303/dianepattersonstA"><b><i>The Design and Evolution of C++</i></b></a>, +Bjarne Stroustrup. While this book doesn't prescribe any specific techniques, it will help you understand the +tradeoffs behind all the language features, and how C++ got to be what it is. I highly recommend it.</p> + +<h2>C++ Tutorial Books</h2> + +<p>These books explain C++ programming from scratch. These particular examples are so good that they +can be useful even for experienced programmers who already know C++ well.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201485184/dianepattersonstA"><b><i>Essential C++</i></b></a>, +Stanley Lippman. This tutorial is much more useful than the longer and more complete works, like +<a href="#Primer"><i>C++ Primer</i></a>. +It covers the features and the reasons for the features quite well. In particular, it has a good explanation +of references and pointers and why you'd use one or the other. It covers templates and exceptions fairly well.</p> + +<h2>Gtk Books</h2> + +<p>OK, so I'm not an expert on Gtk yet. But I'm becoming one.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201924889/dianepattersonstA"><b><i>Gtk+/Gnome Application Development</i></b></a>, +Havoc Pennington. I learned a lot from this book. But it's all Gtk+ and C; things are done +a bit differently with Gtk-- from C++. It's still worth reading.</p> + +<h2>Programming Technique Books</h2> + +<p>These books are valuable because of the ideas in them, but are not specific to a particular programming language or toolkit.</p> + +<p><a name="Refactoring" href="http://www.amazon.com/exec/obidos/ASIN/0201485672/dianepattersonstA"><b><i>Refactoring</i></b></a>, +Martin Fowler. This book outlines a philosophy of programming that we embrace at Eazel. The ideas +about changing existing code to improve it so it can be modified are extremely important. The ideas +about unit testing as a means to this end shape the way we use unit testing at Eazel. +All the examples in the book are in Java, but the ideas apply well to C++.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/020161586X/dianepattersonstA"><b><i>The Practice of Programming</i></b></a>, +Brian Kernighan, Rob Pike. This book, by two of the most famous UNIX programmers, covers a lot of basic +programming smarts. I don't agree with everything they have to say, but the book is great as a whole.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201657880/dianepattersonstA"><b><i>Programming Pearls, Second Edition</i></b></a>, +Jon Bentley. This classic has recently been updated with a second edition. I haven't read the second edition +yet, but I'm sure it's great. When I read it, I'll put more specific comments here.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201633612/dianepattersonstA"><b><i>Design Patterns</i></b></a>. +There's also a <a href="http://www.amazon.com/exec/obidos/ASIN/0201634988/dianepattersonstA">CD edition</a> +(there's a <a href="http://mox.eazel.com/dp">copy</a> of it on Rob's machine).</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201350882/dianepattersonstA"><b><i>Algorithms in C++, Third Edition</i></b></a>, +Robert Sedgewick. The <a href="http://www.amazon.com/exec/obidos/ASIN/0201314525/dianepattersonstA">original version</a> is in C. +There's also an upcoming <a href="http://www.amazon.com/exec/obidos/ASIN/0201361205/dianepattersonstA">Java version</a>.</p> + +<h2>Books I Have Read, But Do Not Recommend</h2> + +<p>I've also read many books on these topics that were less useful than the ones listed above. +Here are a few that were not as exemplary. I won't try to sort out the ones that I found simply "not as useful as the best ones" +from the truly awful. If you see a book that's not on this list, it might be one I'd recommend. Maybe +I haven't read it.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201498413/dianepattersonstA"><b><i>C Interfaces and Implementations</i></b></a>.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201596415/dianepattersonstA"><b><i>C++ IOStreams Handbook</i></b></a>, +Steve Teale. <a href="Josuttis">Josuttis</a> covers streams better.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201616416/dianepattersonstA"><b><i>Extreme Programming Explained</i></b></a>. +My love for <a href="Refactoring"><i>Refactoring</i></a> had me excited about this one, but it was a disappointment.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201309564/dianepattersonstA"><b><i>Generic Programming and the STL</i></b></a>, +Matt Austern. I don't know of anyone who knows more about the STL than Matt Austern, who's currently +maintaining the main implementation at SGI. But <a href="Josuttis">Josuttis</a> covers the STL better.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0131209655/dianepattersonstA"><b><i>Industrial Strength C++</i></b></a>.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201834545/dianepattersonstA"><b><i>Inside the C++ Object Model</i></b></a>.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201633620/dianepattersonstA"><b><i>Large-Scale C++ Software Design</i></b></a>, +John Lakos.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0130142697/dianepattersonstA"><b><i>Objects Unencapsulated: Java, Eiffel and C++??</i></b></a>. +This is a basically an "Eiffel is great, C++ sucks" book. Some interesting insights, but a lot of sloppy thinking.</p> + +<h2>Books That Need Review</h2> + +<p>This is a list of possibly important books that I haven't checked out yet.</p> + +<p><a name="Primer" href="http://www.amazon.com/exec/obidos/ASIN/0201824701/dianepattersonstA"><b><i>C++ Primer, Third Edition</i></b></a>, +Stanley Lippman, Josee Lajoie. The earlier editions were good but not great. But I have reason +to believe that this one might be better than those were.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201309939/dianepattersonstA"><b><i>C++ Primer Answer Book</i></b></a>. +I checked, and this answer book does go with the third edition of <i>C++ Primer</i>.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0201309599/dianepattersonstA"><b><i>Design Patterns and Contracts</i></b></a>.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0735700214/dianepattersonstA"><b><i>Developing Linux Applications with GTK+ and GDK</i></b></a>.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0764546406/dianepattersonstA"><b><i>Linux Gnome/Gtk Programming Bible</i></b></a>.</p> + +<p><a href="http://www.amazon.com/exec/obidos/ASIN/0672318296/dianepattersonstA"><b><i>Sams Teach Yourself Gtk+ Programming in 21 Days</i></b></a>.</p> + +</body> + +</html> diff --git a/libnautilus-extensions/gnome-icon-container.c b/libnautilus-extensions/gnome-icon-container.c index 118bd3d91..59444ee20 100644 --- a/libnautilus-extensions/gnome-icon-container.c +++ b/libnautilus-extensions/gnome-icon-container.c @@ -2077,6 +2077,12 @@ gnome_icon_container_initialize (GnomeIconContainer *container) /* Request update. */ add_idle (container); + + /* Make sure that we find out if the theme changes. */ + gtk_signal_connect_object_while_alive (nautilus_icon_factory_get (), + "theme_changed", + gnome_icon_container_request_update_all, + GTK_OBJECT (container)); } @@ -2465,6 +2471,8 @@ gnome_icon_container_request_update_all (GnomeIconContainer *container) { GList *p; + g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); + for (p = container->details->icons; p != NULL; p = p->next) update_icon (container, p->data); } diff --git a/libnautilus-extensions/nautilus-icon-factory.c b/libnautilus-extensions/nautilus-icon-factory.c index f046b1329..4d68539b7 100644 --- a/libnautilus-extensions/nautilus-icon-factory.c +++ b/libnautilus-extensions/nautilus-icon-factory.c @@ -29,6 +29,7 @@ #include <string.h> #include <stdio.h> +#include <gtk/gtksignal.h> #include <libgnome/gnome-defs.h> #include <libgnome/gnome-mime-info.h> #include <libgnome/gnome-util.h> @@ -37,6 +38,7 @@ #include "nautilus-default-file-icon.h" #include "nautilus-metadata.h" #include "nautilus-lib-self-check-functions.h" +#include "nautilus-gtk-macros.h" #define ICON_NAME_DIRECTORY "i-directory.png" #define ICON_NAME_DIRECTORY_CLOSED "i-dirclosed.png" @@ -79,10 +81,13 @@ struct NautilusCircularList { }; /* The icon factory. - * These are actually globals, but they're in a structure so we can - * have multiple icon factories some day if we want to. + * These are just globals, but they're in an object so we can + * connect signals and have multiple icon factories some day + * if we want to. */ typedef struct { + GtkObject object; + char *theme_name; /* A hash table so we pass out the same scalable icon pointer @@ -107,6 +112,16 @@ typedef struct { GdkPixbuf *symbolic_link_overlay; } NautilusIconFactory; +typedef struct { + GtkObjectClass parent_class; +} NautilusIconFactoryClass; + +enum { + THEME_CHANGED, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL]; + /* A scalable icon, which is basically the name and path of an icon, * before we load the actual pixels of the icons's image. */ @@ -134,25 +149,30 @@ typedef struct { /* forward declarations */ -static NautilusIconFactory * nautilus_get_current_icon_factory (void); -static NautilusIconFactory * nautilus_icon_factory_new (const char *theme_name); -static NautilusScalableIcon *nautilus_scalable_icon_get (const char *uri, - const char *name, - gboolean is_symbolic_link); -static guint nautilus_scalable_icon_hash (gconstpointer p); -static gboolean nautilus_scalable_icon_equal (gconstpointer a, - gconstpointer b); -static void nautilus_icon_cache_key_destroy (NautilusIconCacheKey *key); -static guint nautilus_icon_cache_key_hash (gconstpointer p); -static gboolean nautilus_icon_cache_key_equal (gconstpointer a, - gconstpointer b); -static GdkPixbuf * get_image_from_cache (NautilusScalableIcon *scalable_icon, - guint size_in_pixels, - gboolean picky, - gboolean custom); +static GtkType nautilus_icon_factory_get_type (void); +static void nautilus_icon_factory_initialize_class (NautilusIconFactoryClass *class); +static void nautilus_icon_factory_initialize (NautilusIconFactory *factory); +static NautilusIconFactory * nautilus_get_current_icon_factory (void); +static NautilusIconFactory * nautilus_icon_factory_new (const char *theme_name); +static NautilusScalableIcon *nautilus_scalable_icon_get (const char *uri, + const char *name, + gboolean is_symbolic_link); +static guint nautilus_scalable_icon_hash (gconstpointer p); +static gboolean nautilus_scalable_icon_equal (gconstpointer a, + gconstpointer b); +static void nautilus_icon_cache_key_destroy (NautilusIconCacheKey *key); +static guint nautilus_icon_cache_key_hash (gconstpointer p); +static gboolean nautilus_icon_cache_key_equal (gconstpointer a, + gconstpointer b); +static GdkPixbuf * get_image_from_cache (NautilusScalableIcon *scalable_icon, + guint size_in_pixels, + gboolean picky, + gboolean custom); + +NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusIconFactory, nautilus_icon_factory, GTK_TYPE_OBJECT) /* Return a pointer to the single global icon factory. */ -NautilusIconFactory * +static NautilusIconFactory * nautilus_get_current_icon_factory (void) { static NautilusIconFactory *global_icon_factory = NULL; @@ -161,15 +181,28 @@ nautilus_get_current_icon_factory (void) return global_icon_factory; } +GtkObject * +nautilus_icon_factory_get (void) +{ + return GTK_OBJECT (nautilus_get_current_icon_factory ()); +} + /* Create the icon factory. */ static NautilusIconFactory * nautilus_icon_factory_new (const char *theme_name) { NautilusIconFactory *factory; - factory = g_new0 (NautilusIconFactory, 1); + factory = (NautilusIconFactory *) gtk_object_new (nautilus_icon_factory_get_type (), NULL); factory->theme_name = g_strdup (theme_name); + + return factory; +} + +static void +nautilus_icon_factory_initialize (NautilusIconFactory *factory) +{ factory->scalable_icons = g_hash_table_new (nautilus_scalable_icon_hash, nautilus_scalable_icon_equal); factory->icon_cache = g_hash_table_new (nautilus_icon_cache_key_hash, @@ -178,8 +211,24 @@ nautilus_icon_factory_new (const char *theme_name) /* Empty out the recently-used list. */ factory->recently_used_dummy_head.next = &factory->recently_used_dummy_head; factory->recently_used_dummy_head.prev = &factory->recently_used_dummy_head; +} - return factory; +static void +nautilus_icon_factory_initialize_class (NautilusIconFactoryClass *class) +{ + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS (class); + + signals[THEME_CHANGED] + = gtk_signal_new ("theme_changed", + GTK_RUN_LAST, + object_class->type, + 0, + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); } /* Destroy one image in the cache. */ @@ -285,6 +334,13 @@ nautilus_icon_factory_schedule_sweep (void) factory); } +/* Get the name of the current theme. */ +char * +nautilus_icon_factory_get_theme (void) +{ + return g_strdup (nautilus_get_current_icon_factory ()->theme_name); +} + /* Change the theme. */ void nautilus_icon_factory_set_theme (const char *theme_name) @@ -297,6 +353,9 @@ nautilus_icon_factory_set_theme (const char *theme_name) g_free (factory->theme_name); factory->theme_name = g_strdup (theme_name); + + gtk_signal_emit (GTK_OBJECT (factory), + signals[THEME_CHANGED]); } /* Use the MIME type to get the icon name. */ diff --git a/libnautilus-extensions/nautilus-icon-factory.h b/libnautilus-extensions/nautilus-icon-factory.h index 9ee1abbba..46f9151db 100644 --- a/libnautilus-extensions/nautilus-icon-factory.h +++ b/libnautilus-extensions/nautilus-icon-factory.h @@ -69,10 +69,22 @@ typedef enum { typedef struct _NautilusScalableIcon NautilusScalableIcon; +/* Instead of a class declaration here, I will just document + * the signals. + * + * "theme_changed", no parameters + */ + +/* There's a single NautilusIconFactory object. + * The only thing you need it for is to connect to its signals. + */ +GtkObject * nautilus_icon_factory_get (void); + /* Relationship between zoom levels and icons sizes. */ guint nautilus_get_icon_size_for_zoom_level (NautilusZoomLevel zoom_level); /* Switch themes. */ +char * nautilus_icon_factory_get_theme (void); void nautilus_icon_factory_set_theme (const char *theme_name); /* Choose the appropriate icon, but don't render it yet. */ diff --git a/libnautilus-private/gnome-icon-container.c b/libnautilus-private/gnome-icon-container.c index 118bd3d91..59444ee20 100644 --- a/libnautilus-private/gnome-icon-container.c +++ b/libnautilus-private/gnome-icon-container.c @@ -2077,6 +2077,12 @@ gnome_icon_container_initialize (GnomeIconContainer *container) /* Request update. */ add_idle (container); + + /* Make sure that we find out if the theme changes. */ + gtk_signal_connect_object_while_alive (nautilus_icon_factory_get (), + "theme_changed", + gnome_icon_container_request_update_all, + GTK_OBJECT (container)); } @@ -2465,6 +2471,8 @@ gnome_icon_container_request_update_all (GnomeIconContainer *container) { GList *p; + g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); + for (p = container->details->icons; p != NULL; p = p->next) update_icon (container, p->data); } diff --git a/libnautilus-private/nautilus-icon-factory.c b/libnautilus-private/nautilus-icon-factory.c index f046b1329..4d68539b7 100644 --- a/libnautilus-private/nautilus-icon-factory.c +++ b/libnautilus-private/nautilus-icon-factory.c @@ -29,6 +29,7 @@ #include <string.h> #include <stdio.h> +#include <gtk/gtksignal.h> #include <libgnome/gnome-defs.h> #include <libgnome/gnome-mime-info.h> #include <libgnome/gnome-util.h> @@ -37,6 +38,7 @@ #include "nautilus-default-file-icon.h" #include "nautilus-metadata.h" #include "nautilus-lib-self-check-functions.h" +#include "nautilus-gtk-macros.h" #define ICON_NAME_DIRECTORY "i-directory.png" #define ICON_NAME_DIRECTORY_CLOSED "i-dirclosed.png" @@ -79,10 +81,13 @@ struct NautilusCircularList { }; /* The icon factory. - * These are actually globals, but they're in a structure so we can - * have multiple icon factories some day if we want to. + * These are just globals, but they're in an object so we can + * connect signals and have multiple icon factories some day + * if we want to. */ typedef struct { + GtkObject object; + char *theme_name; /* A hash table so we pass out the same scalable icon pointer @@ -107,6 +112,16 @@ typedef struct { GdkPixbuf *symbolic_link_overlay; } NautilusIconFactory; +typedef struct { + GtkObjectClass parent_class; +} NautilusIconFactoryClass; + +enum { + THEME_CHANGED, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL]; + /* A scalable icon, which is basically the name and path of an icon, * before we load the actual pixels of the icons's image. */ @@ -134,25 +149,30 @@ typedef struct { /* forward declarations */ -static NautilusIconFactory * nautilus_get_current_icon_factory (void); -static NautilusIconFactory * nautilus_icon_factory_new (const char *theme_name); -static NautilusScalableIcon *nautilus_scalable_icon_get (const char *uri, - const char *name, - gboolean is_symbolic_link); -static guint nautilus_scalable_icon_hash (gconstpointer p); -static gboolean nautilus_scalable_icon_equal (gconstpointer a, - gconstpointer b); -static void nautilus_icon_cache_key_destroy (NautilusIconCacheKey *key); -static guint nautilus_icon_cache_key_hash (gconstpointer p); -static gboolean nautilus_icon_cache_key_equal (gconstpointer a, - gconstpointer b); -static GdkPixbuf * get_image_from_cache (NautilusScalableIcon *scalable_icon, - guint size_in_pixels, - gboolean picky, - gboolean custom); +static GtkType nautilus_icon_factory_get_type (void); +static void nautilus_icon_factory_initialize_class (NautilusIconFactoryClass *class); +static void nautilus_icon_factory_initialize (NautilusIconFactory *factory); +static NautilusIconFactory * nautilus_get_current_icon_factory (void); +static NautilusIconFactory * nautilus_icon_factory_new (const char *theme_name); +static NautilusScalableIcon *nautilus_scalable_icon_get (const char *uri, + const char *name, + gboolean is_symbolic_link); +static guint nautilus_scalable_icon_hash (gconstpointer p); +static gboolean nautilus_scalable_icon_equal (gconstpointer a, + gconstpointer b); +static void nautilus_icon_cache_key_destroy (NautilusIconCacheKey *key); +static guint nautilus_icon_cache_key_hash (gconstpointer p); +static gboolean nautilus_icon_cache_key_equal (gconstpointer a, + gconstpointer b); +static GdkPixbuf * get_image_from_cache (NautilusScalableIcon *scalable_icon, + guint size_in_pixels, + gboolean picky, + gboolean custom); + +NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusIconFactory, nautilus_icon_factory, GTK_TYPE_OBJECT) /* Return a pointer to the single global icon factory. */ -NautilusIconFactory * +static NautilusIconFactory * nautilus_get_current_icon_factory (void) { static NautilusIconFactory *global_icon_factory = NULL; @@ -161,15 +181,28 @@ nautilus_get_current_icon_factory (void) return global_icon_factory; } +GtkObject * +nautilus_icon_factory_get (void) +{ + return GTK_OBJECT (nautilus_get_current_icon_factory ()); +} + /* Create the icon factory. */ static NautilusIconFactory * nautilus_icon_factory_new (const char *theme_name) { NautilusIconFactory *factory; - factory = g_new0 (NautilusIconFactory, 1); + factory = (NautilusIconFactory *) gtk_object_new (nautilus_icon_factory_get_type (), NULL); factory->theme_name = g_strdup (theme_name); + + return factory; +} + +static void +nautilus_icon_factory_initialize (NautilusIconFactory *factory) +{ factory->scalable_icons = g_hash_table_new (nautilus_scalable_icon_hash, nautilus_scalable_icon_equal); factory->icon_cache = g_hash_table_new (nautilus_icon_cache_key_hash, @@ -178,8 +211,24 @@ nautilus_icon_factory_new (const char *theme_name) /* Empty out the recently-used list. */ factory->recently_used_dummy_head.next = &factory->recently_used_dummy_head; factory->recently_used_dummy_head.prev = &factory->recently_used_dummy_head; +} - return factory; +static void +nautilus_icon_factory_initialize_class (NautilusIconFactoryClass *class) +{ + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS (class); + + signals[THEME_CHANGED] + = gtk_signal_new ("theme_changed", + GTK_RUN_LAST, + object_class->type, + 0, + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); } /* Destroy one image in the cache. */ @@ -285,6 +334,13 @@ nautilus_icon_factory_schedule_sweep (void) factory); } +/* Get the name of the current theme. */ +char * +nautilus_icon_factory_get_theme (void) +{ + return g_strdup (nautilus_get_current_icon_factory ()->theme_name); +} + /* Change the theme. */ void nautilus_icon_factory_set_theme (const char *theme_name) @@ -297,6 +353,9 @@ nautilus_icon_factory_set_theme (const char *theme_name) g_free (factory->theme_name); factory->theme_name = g_strdup (theme_name); + + gtk_signal_emit (GTK_OBJECT (factory), + signals[THEME_CHANGED]); } /* Use the MIME type to get the icon name. */ diff --git a/libnautilus-private/nautilus-icon-factory.h b/libnautilus-private/nautilus-icon-factory.h index 9ee1abbba..46f9151db 100644 --- a/libnautilus-private/nautilus-icon-factory.h +++ b/libnautilus-private/nautilus-icon-factory.h @@ -69,10 +69,22 @@ typedef enum { typedef struct _NautilusScalableIcon NautilusScalableIcon; +/* Instead of a class declaration here, I will just document + * the signals. + * + * "theme_changed", no parameters + */ + +/* There's a single NautilusIconFactory object. + * The only thing you need it for is to connect to its signals. + */ +GtkObject * nautilus_icon_factory_get (void); + /* Relationship between zoom levels and icons sizes. */ guint nautilus_get_icon_size_for_zoom_level (NautilusZoomLevel zoom_level); /* Switch themes. */ +char * nautilus_icon_factory_get_theme (void); void nautilus_icon_factory_set_theme (const char *theme_name); /* Choose the appropriate icon, but don't render it yet. */ diff --git a/libnautilus/gnome-icon-container.c b/libnautilus/gnome-icon-container.c index 118bd3d91..59444ee20 100644 --- a/libnautilus/gnome-icon-container.c +++ b/libnautilus/gnome-icon-container.c @@ -2077,6 +2077,12 @@ gnome_icon_container_initialize (GnomeIconContainer *container) /* Request update. */ add_idle (container); + + /* Make sure that we find out if the theme changes. */ + gtk_signal_connect_object_while_alive (nautilus_icon_factory_get (), + "theme_changed", + gnome_icon_container_request_update_all, + GTK_OBJECT (container)); } @@ -2465,6 +2471,8 @@ gnome_icon_container_request_update_all (GnomeIconContainer *container) { GList *p; + g_return_if_fail (GNOME_IS_ICON_CONTAINER (container)); + for (p = container->details->icons; p != NULL; p = p->next) update_icon (container, p->data); } diff --git a/libnautilus/nautilus-icon-factory.c b/libnautilus/nautilus-icon-factory.c index f046b1329..4d68539b7 100644 --- a/libnautilus/nautilus-icon-factory.c +++ b/libnautilus/nautilus-icon-factory.c @@ -29,6 +29,7 @@ #include <string.h> #include <stdio.h> +#include <gtk/gtksignal.h> #include <libgnome/gnome-defs.h> #include <libgnome/gnome-mime-info.h> #include <libgnome/gnome-util.h> @@ -37,6 +38,7 @@ #include "nautilus-default-file-icon.h" #include "nautilus-metadata.h" #include "nautilus-lib-self-check-functions.h" +#include "nautilus-gtk-macros.h" #define ICON_NAME_DIRECTORY "i-directory.png" #define ICON_NAME_DIRECTORY_CLOSED "i-dirclosed.png" @@ -79,10 +81,13 @@ struct NautilusCircularList { }; /* The icon factory. - * These are actually globals, but they're in a structure so we can - * have multiple icon factories some day if we want to. + * These are just globals, but they're in an object so we can + * connect signals and have multiple icon factories some day + * if we want to. */ typedef struct { + GtkObject object; + char *theme_name; /* A hash table so we pass out the same scalable icon pointer @@ -107,6 +112,16 @@ typedef struct { GdkPixbuf *symbolic_link_overlay; } NautilusIconFactory; +typedef struct { + GtkObjectClass parent_class; +} NautilusIconFactoryClass; + +enum { + THEME_CHANGED, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL]; + /* A scalable icon, which is basically the name and path of an icon, * before we load the actual pixels of the icons's image. */ @@ -134,25 +149,30 @@ typedef struct { /* forward declarations */ -static NautilusIconFactory * nautilus_get_current_icon_factory (void); -static NautilusIconFactory * nautilus_icon_factory_new (const char *theme_name); -static NautilusScalableIcon *nautilus_scalable_icon_get (const char *uri, - const char *name, - gboolean is_symbolic_link); -static guint nautilus_scalable_icon_hash (gconstpointer p); -static gboolean nautilus_scalable_icon_equal (gconstpointer a, - gconstpointer b); -static void nautilus_icon_cache_key_destroy (NautilusIconCacheKey *key); -static guint nautilus_icon_cache_key_hash (gconstpointer p); -static gboolean nautilus_icon_cache_key_equal (gconstpointer a, - gconstpointer b); -static GdkPixbuf * get_image_from_cache (NautilusScalableIcon *scalable_icon, - guint size_in_pixels, - gboolean picky, - gboolean custom); +static GtkType nautilus_icon_factory_get_type (void); +static void nautilus_icon_factory_initialize_class (NautilusIconFactoryClass *class); +static void nautilus_icon_factory_initialize (NautilusIconFactory *factory); +static NautilusIconFactory * nautilus_get_current_icon_factory (void); +static NautilusIconFactory * nautilus_icon_factory_new (const char *theme_name); +static NautilusScalableIcon *nautilus_scalable_icon_get (const char *uri, + const char *name, + gboolean is_symbolic_link); +static guint nautilus_scalable_icon_hash (gconstpointer p); +static gboolean nautilus_scalable_icon_equal (gconstpointer a, + gconstpointer b); +static void nautilus_icon_cache_key_destroy (NautilusIconCacheKey *key); +static guint nautilus_icon_cache_key_hash (gconstpointer p); +static gboolean nautilus_icon_cache_key_equal (gconstpointer a, + gconstpointer b); +static GdkPixbuf * get_image_from_cache (NautilusScalableIcon *scalable_icon, + guint size_in_pixels, + gboolean picky, + gboolean custom); + +NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusIconFactory, nautilus_icon_factory, GTK_TYPE_OBJECT) /* Return a pointer to the single global icon factory. */ -NautilusIconFactory * +static NautilusIconFactory * nautilus_get_current_icon_factory (void) { static NautilusIconFactory *global_icon_factory = NULL; @@ -161,15 +181,28 @@ nautilus_get_current_icon_factory (void) return global_icon_factory; } +GtkObject * +nautilus_icon_factory_get (void) +{ + return GTK_OBJECT (nautilus_get_current_icon_factory ()); +} + /* Create the icon factory. */ static NautilusIconFactory * nautilus_icon_factory_new (const char *theme_name) { NautilusIconFactory *factory; - factory = g_new0 (NautilusIconFactory, 1); + factory = (NautilusIconFactory *) gtk_object_new (nautilus_icon_factory_get_type (), NULL); factory->theme_name = g_strdup (theme_name); + + return factory; +} + +static void +nautilus_icon_factory_initialize (NautilusIconFactory *factory) +{ factory->scalable_icons = g_hash_table_new (nautilus_scalable_icon_hash, nautilus_scalable_icon_equal); factory->icon_cache = g_hash_table_new (nautilus_icon_cache_key_hash, @@ -178,8 +211,24 @@ nautilus_icon_factory_new (const char *theme_name) /* Empty out the recently-used list. */ factory->recently_used_dummy_head.next = &factory->recently_used_dummy_head; factory->recently_used_dummy_head.prev = &factory->recently_used_dummy_head; +} - return factory; +static void +nautilus_icon_factory_initialize_class (NautilusIconFactoryClass *class) +{ + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS (class); + + signals[THEME_CHANGED] + = gtk_signal_new ("theme_changed", + GTK_RUN_LAST, + object_class->type, + 0, + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); } /* Destroy one image in the cache. */ @@ -285,6 +334,13 @@ nautilus_icon_factory_schedule_sweep (void) factory); } +/* Get the name of the current theme. */ +char * +nautilus_icon_factory_get_theme (void) +{ + return g_strdup (nautilus_get_current_icon_factory ()->theme_name); +} + /* Change the theme. */ void nautilus_icon_factory_set_theme (const char *theme_name) @@ -297,6 +353,9 @@ nautilus_icon_factory_set_theme (const char *theme_name) g_free (factory->theme_name); factory->theme_name = g_strdup (theme_name); + + gtk_signal_emit (GTK_OBJECT (factory), + signals[THEME_CHANGED]); } /* Use the MIME type to get the icon name. */ diff --git a/libnautilus/nautilus-icon-factory.h b/libnautilus/nautilus-icon-factory.h index 9ee1abbba..46f9151db 100644 --- a/libnautilus/nautilus-icon-factory.h +++ b/libnautilus/nautilus-icon-factory.h @@ -69,10 +69,22 @@ typedef enum { typedef struct _NautilusScalableIcon NautilusScalableIcon; +/* Instead of a class declaration here, I will just document + * the signals. + * + * "theme_changed", no parameters + */ + +/* There's a single NautilusIconFactory object. + * The only thing you need it for is to connect to its signals. + */ +GtkObject * nautilus_icon_factory_get (void); + /* Relationship between zoom levels and icons sizes. */ guint nautilus_get_icon_size_for_zoom_level (NautilusZoomLevel zoom_level); /* Switch themes. */ +char * nautilus_icon_factory_get_theme (void); void nautilus_icon_factory_set_theme (const char *theme_name); /* Choose the appropriate icon, but don't render it yet. */ diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c index 210036bc7..80cd4af27 100644 --- a/src/file-manager/fm-directory-view.c +++ b/src/file-manager/fm-directory-view.c @@ -28,7 +28,7 @@ #include <gtk/gtksignal.h> #include <gtk/gtkmain.h> #include <gtk/gtkmenu.h> -#include <gtk/gtkmenuitem.h> +#include <gtk/gtkcheckmenuitem.h> #include <libgnome/gnome-i18n.h> #include <libgnomevfs/gnome-vfs-async-ops.h> #include <libgnomevfs/gnome-vfs-directory-list.h> @@ -36,8 +36,10 @@ #include <libgnomevfs/gnome-vfs-uri.h> #include <libgnomevfs/gnome-vfs-utils.h> #include <libnautilus/nautilus-alloc.h> +#include <libnautilus/nautilus-string.h> #include <libnautilus/nautilus-gtk-macros.h> #include <libnautilus/nautilus-gtk-extensions.h> +#include <libnautilus/nautilus-icon-factory.h> #define DISPLAY_TIMEOUT_INTERVAL_MSECS 500 @@ -405,9 +407,16 @@ zoom_out_cb (GtkMenuItem *item, FMDirectoryView *directory_view) } static void -use_eazel_theme_icons_cb (GtkMenuItem *item, FMDirectoryView *directory_view) +use_eazel_theme_icons_cb (GtkCheckMenuItem *item, FMDirectoryView *directory_view) { - /* FIXME: This isn't implemented yet. */ + char *theme; + + theme = nautilus_icon_factory_get_theme (); + if (nautilus_strcmp (theme, "eazel") == 0) + nautilus_icon_factory_set_theme (NULL); + else + nautilus_icon_factory_set_theme ("eazel"); + g_free (theme); } static gboolean @@ -795,8 +804,16 @@ open_in_new_window_cb (GtkMenuItem *item, NautilusFile *file) } static void +finish_adding_menu_item (GtkMenu *menu, GtkWidget *menu_item, gboolean sensitive) +{ + gtk_widget_set_sensitive (menu_item, sensitive); + gtk_widget_show (menu_item); + gtk_menu_append (menu, menu_item); +} + +static void add_menu_item (FMDirectoryView *view, GtkMenu *menu, const char *label, - void (*activate_handler) (GtkMenuItem *, FMDirectoryView *), + void (* activate_handler) (GtkMenuItem *, FMDirectoryView *), gboolean sensitive) { GtkWidget *menu_item; @@ -804,19 +821,42 @@ add_menu_item (FMDirectoryView *view, GtkMenu *menu, const char *label, menu_item = gtk_menu_item_new_with_label (label); gtk_signal_connect (GTK_OBJECT (menu_item), "activate", GTK_SIGNAL_FUNC (activate_handler), view); - gtk_widget_set_sensitive (menu_item, sensitive); - gtk_widget_show (menu_item); - gtk_menu_append (menu, menu_item); + finish_adding_menu_item (menu, menu_item, sensitive); +} + +static void +add_check_menu_item (FMDirectoryView *view, GtkMenu *menu, const char *label, + void (* toggled_handler) (GtkCheckMenuItem *, FMDirectoryView *), + gboolean sensitive, + gboolean active) +{ + GtkWidget *menu_item; + + menu_item = gtk_check_menu_item_new_with_label (label); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), active); + gtk_signal_connect (GTK_OBJECT (menu_item), "toggled", + GTK_SIGNAL_FUNC (toggled_handler), view); + finish_adding_menu_item (menu, menu_item, sensitive); } static void fm_directory_view_real_append_background_context_menu_items (FMDirectoryView *view, GtkMenu *menu) { + char *theme; + + theme = nautilus_icon_factory_get_theme (); + add_menu_item (view, menu, _("Select All"), select_all_cb, TRUE); - add_menu_item (view, menu, _("Zoom In"), zoom_in_cb, fm_directory_view_can_zoom_in (view)); - add_menu_item (view, menu, _("Zoom Out"), zoom_out_cb, fm_directory_view_can_zoom_out (view)); - add_menu_item (view, menu, _("Use Eazel Theme Icons"), use_eazel_theme_icons_cb, FALSE); + add_menu_item (view, menu, _("Zoom In"), zoom_in_cb, + fm_directory_view_can_zoom_in (view)); + add_menu_item (view, menu, _("Zoom Out"), zoom_out_cb, + fm_directory_view_can_zoom_out (view)); + add_check_menu_item (view, menu, _("Use Eazel Theme Icons"), + use_eazel_theme_icons_cb, + TRUE, nautilus_strcmp (theme, "eazel") == 0); + + g_free (theme); } static void |