Progress on GtkFileChooser
- From: Owen Taylor <otaylor redhat com>
- To: gtk-devel-list gnome org
- Subject: Progress on GtkFileChooser
- Date: 27 Mar 2003 17:54:28 -0500
I've just imported a bunch of code and header files
into the gtkfilechooser/ module in GNOME CVS.
There's lots of stuff working in there - UNIX and
gnome-vfs backends, incremental filling, simple
completion.
But even more not - icons, bookmarks, having the
file selector return filenames typed in in Save
mode.
Some questions that might be asked:
- Why didn't you start from Y? You should look at
Y, it is much better than the pitiful attempt
attempt at a UI you have there.
My concern here was largely the API and a clean
split between interface/GUI implementation/
file system implementation. While other filesel
implementations almost certainly farther along
in functionality, I thought it was easiest to
start from a clean slate.
- Why doesn't your UI do X?
A) Because I haven't implemented it yet. B) Because
you haven't implemented it yet. C) Because it's
the wrong thing to do.
The user interface is there because I couldn't test
out the pieces without a user interface but it
is not meant as any sort of proposal for the
final UI.
(I think there are some neat things about what I
did for the UI, I suspect that some people
will like it. But nonetheless it is most likely
wrong.)
I'm hoping at this point we can start a UI design
process where we figure out some concrete criteria for
the UI and get some mockups and functional prototypes
for people to pay with.
- Didn't you just do all the fun stuff and leave all
the hard details for other people to do?
Yes. So?
Actually, I think there is plenty of fun stuff
left on the UI side of things, both in design
and implementation. While I did grab off most
of the API/architecture design work, and I think
what I ended up is pretty functional, there is
still room for adjustment there, and even major
changes if someone has better ideas.
- How the @$ ! do I compile this thing? Could you have
made it any harder?
It isn't *that* bad. It only requires glib-head, gtk-head,
and a couple of patches to both. (Details in the
README.) Presumably, we'll get properties-on-interfaces
into GLib at some time in the near future and the
GtkTreeView fixes into GTK+.
- Aren't you just trying to steal all the oil?
README and TODO attached.
Regards,
Owen
Introduction
============
The code in this directory is the start of an implementation of the
file selector designed proposed in:
http://people.redhat.com/otaylor/fosdem2003/file-selector.html
What is found here includes:
- Header files for public, semi-public, and private interfaces that
allow for flexible choices of UI backend and file systme back end.
- Implementations of these interfaces.
- A sample user interface backend .. GtkFileChooserImplDefault.
- Several reusable components that are used to build
GtkFileChooserImplDefault:
GtkFileSystemModel - GtkTreeModel wrapping a GtkFileSystem
GtkFileChooserEntry - entry with completion
- Two sample file system backends: GtkFileSystemUnix and
GtkFilesystemGnomeVFS.
- A small test program
It should be emphasized here that the user interface here should *not*
be considered final, or even a proposal as to what the final user
interface.
I'm not interested in critiques of this user interface; what would be
more useful would be complete proposals for how the user interface
should look including:
- What elements should be present and how they should interact
- Some rational for the above (how will people be using the file
selector, what are the important tasks that should be easy to do,
what is the relationship to file selectors that people are already
familiar with, if any.)
Designs could be text only, or include mocked-up-screenshots, or
screenshots of a existing implementation. They could even include a
working or semi-working implementation along the lines of
GtkFileChooseImplDefault, but that's far from necessary.
API Design
==========
>From the application programmer's perspective, the API is extremely
simple:
GtkFileChooser is an interface that represents a graphical file
selecctor in a pretty straightforward fashion.
GtkFileChooserWidget implements GtkFileChooser as an embeddable
widget.
GtkFileChooserWidget implements GtkFileChooser as an embeddable
widget.
There is a second level of semi-public interfaces that won't be
exposed to applications but will be installed so that people can write
custom file system models. The two interfaces that a custom file
system model needs to implement are:
GtkFileSystem - an entire file system
GtkFileFolder - one folder within a GtkFileSystem
There are some auxiliary types that are used with GtkFileSystem and
GtkFileFolder... in particular, GtkFileInfo holds information about
the properties of a single file.
Implementation
==============
Just a few notes about the implementation here:
- The intent was to break up the code so that relatively little
code was actually in GtkFileChooserImplDefault and as much
as possible in reusable components such as GtkFileChooserEntry
and GtkFileSystemModel.
This is to allow people to experiment with alternate UIs
without having to duplicate a lot of code.
- The way that GtkFileChooserDialog and GtkFileChooserWidget
are implemented may be a little confusing. They way they
work is that they "delegate" the methods and properties
GtkFileChooser to their child widget.
The utilities in gtkfilechooserutils.c are largely to
avoid having to duplicate a bunch of code to do the
delegation between the two widgets.
Compiling
=========
The code here makes extensive use of properties on interfaces, which
aren't yet an official part of GLib, so you'll need to apply the
included glib-interface-properties-0.2.patch to your GLib.
It also uses instance-private-data, so you'll need to use CVS head of
GLib.
The GtkTreeView patches attached to:
http://bugzilla.gnome.org/show_bug.cgi?id=109289
http://bugzilla.gnome.org/show_bug.cgi?id=109292
Are also probably useful. The first fixes a warning that this code
triggers, the second is a massive performance improvement for
GtkTreeModelSort.
Files
=====
Public APIs:
gtkfilechooser.[ch]
Abstract interface for file selector GUIs
gtkfilechooserwidget.[ch]
Embeddable file selector widget
gtkfilechooserdialog.[ch]
File selector dialog
Semi-public APIs:
gtkfilesystem.[ch]
File selector dialog
Implementation details:
gtkfilechooserentry.[ch]
Entry with filename completion
gtkfilechooserimpldefault.[ch]
Default implementation of GtkFileChooser
gtkfilechooserutils.[ch]
Private utility functions useful for implementing a
GtkFileChooser interface
gtkfilesystemgnomevfs.[ch]
Implementation of GtkFileSystem for gnome-vfs
gtkfilesystemmodel.[ch]
GtkTreeModel wrapping a GtkFileSystem
gtkfilesystemunix.[ch]
Default implementation of GtkFileSystem for UNIX-like systems
Auto-generated enumeration types:
gtkfilechooserenums.[ch]
Test Code:
testfilechooser.c
Test program
prop-editor.c
Property editor code copied from gtk+/tests
Credits
=======
Many people contributed to ideas that appear in this code; the basic
organization is partly derived from a proposal by Havoc Pennington who
did a massive API review of existing file selectors.
Various ideas were taking from EggFileSystem as implemented by Bastien
Nocera.
Credit should also be given to all those people who wrote alternate
GTK+ file selectors that I foolishly ignored when writing this. Among
others Jacob Berkman and the Anjuta team have done file selectors
that are prettier, more functional and perhaps even better designed
than this.
License
=======
The code in this directory is licensed under the GNU Library General
Public License (see the COPYING file.)
Most code here is copyright Red Hat Inc, 2003. gtkfilesystemgnomevfs.c
also contains a small amount of code taken from libeel and copyright
1999, 2000 Eazel, Inc.
Owen Taylor
26 March 2003
Not yet implemented
===================
- The filename portions of the GtkFileChooser API ... currently,
only the URI based function calls are present.
- Preview widget. The properties and API for this are mostly there,
but there is no implementation in
GtkFileChooserImplDefault. Implementing this should be relatively
easy (basically just packing the widget into the chooser); a test
case of some sort would also need to be added to testfilechooser.
- Filtering. gtkfilechooser.h has some bits that are #if 0'ed out,
but they aren't finalized and absolutely nothing has been
implemented. gtkfilesystemmodel.c:file_model_node_is_visible
- A reference widget. For displaying authentication dialogs, and some
types of error dialogs the file system *model* needs to get a
pointer to a window to use as a transient parent.
- Icons. Nothing is currently implemented in this area at all. There
probably needs to be some adaptation of the current API so that
sizes can be worked out properly. One possibility is that instead
of of GdkPixbuf, GdkIconInfo should contain a handle that can be
rendered at multiple sizes. This is especially important if, as
currently, one GdkIconInfo is cached for multiple views.
- Mime types for GtkFileSystemUnix ... we should probably include an
implementation of the new standard mime type spec being discussed
on xdg-list freedesktop org
- Loading notification. GtkFileFolder should probably have signals so
that someone that is using it can tell when the initial load
finishes and display appropriate feedback to the user. You'd then
want to propagate that in some way to the GtkFileSystemModel
interface (is any referenced folder currently loading?) to allow
the file selector to display feedback or keep the selected row
scrolled visible during the incremental load.
- Network URI's for GtkFileSystemGnomeVFS ... there is a need to tie
every URI back to a file system root, at least for the sample
chooser user interface with the tree. (And for sanity, in general.)
Probably the right way to do this is to have a special root - say
'network-servers:' that has as children the toplevel URI for every
referenced network folder:
network-servers:
http://www.gnome.org/
ftp://ftp.gnome.og
Or whatever.
- Most-recently-used and/or bookmarks. The file system object should
provide a change notified list or lists. Should it also have ways
of adding bookmarks and/or a "do the manage bookmarks thing" call?
- Interaction of the entry line with the "selected_uris" In single
selection mode, it's something like:
- In save mode contents of the entry line should be the result
unless it is empty, in which case if there is a file selected in
the list view, it should be the result. In open mode, the
selected URI in the list view is canonical since an existing
file must be selected.
- If the user types a file in the entry line that matches the name
of a file in the list view, that file should be selected and
scrolled to.
In multiple selection mode, things get more complicated.
GtkFileSelection has the right logic for this (involving a concept
of the last file selected)
- Folder mode ... not really working with GtkFileChooserImplDefault
- The final mechanism for selecting a GtkFileSystem and loading
it from a dynamically loaded module needs to be decided upon.
When that is done, the file-system construct property for
GtkFileChooser can be removed.
Possible major API changes
==========================
- Right now, there are two types of file/folder identifications in
the API - filenames and URI's. There is a fairly strong argument
for changing this to a threeway split:
Opaque Reference
File
URI
With vfuncs in GtkFileSystem for converting opaque references to
either files or URIs. Using URI's all over the api works well for
GtkFileSystemGnomeVFS but badly/inefficiently for
GtkFileSystemUnix.
The opaque reference could either be just a string ... simplest but
can involve copies, or it could be some sort of more complex
reference counted object. (See EggFileSystemItem (?) in libegg for
an example of how this could work.)
Note that GtkFileSystemModel needs to be able to sort the
references for the children of a model in a way that is stable
against multiple readdirs/insertions/deletions, which it currently
does with strcmp() against the URI.
We also need to decide exactly how the encoding of file:// URIs
work:
The GLib scheme of file:// uri's always being UTF-8 encoded (then
octet encoded) has the problem of not being able to represent
invalid-encoded URI's at all. It also depends on the receiver and
the sender thinking the same things about how filenames are encoded
on diesk.
The Nautilus scheme of matching the filesystem encoding encoded as
octets may not be entirely RFC compliant (it wasn't very clear last
time I looked) displaying the URI's contents to the user may also be
difficult (but no harder than displaying a filename.)
API tweaks
==========
- We need GTK_FILE_SYSTEM_ERROR_PERMISSION
- The names gtk_file_info_get_is_folder(), etc, are a little
strange. Maybe it would be better to go with the asymmetrical pair
gtk_file_info_set_is_folder()/gtk_file_info_is_folder()
- The docs for gtk_file_system_parse() describe it looking at the
file system, but neither implementation does so
currently. (Authentication might require blocking, so we can't tell
definitively whether some directory exists in a synchronous
fashion.)
- Moving the GtkFileChooserIface structure private would simplifiy
the public headers and also allow us to refer to
GtkFileSystem-specific stuff in the virtual functions if necessary.
- The GtkFileChooserIface functions would look cleaner if they didn't
have _uri() in the names. Since we don't have the filename/uri
pairs in the vfuncs, there probably is no need for the _uri() in
the names.
- There is no way of telling whether a display name is an exact
reconvertable representation of the filename or an approximation of
a misencoded filename. This is needed to know whether we should
fill in the entry or not. Possible API:
gtk_file_info_set_display_name (info, display_name, exact);
gtk_file_info_get_display_name (info)
gtk_file_info_get_display_name_exact (info)
Implementation strutural changes
================================
- Right now, every GtkFileSystemModel and GtkFileEntry separately
talks the GtkFileSystemModel. This results in duplicate loading and
duplicate storage. A better model might be:
GtkFileSytemModel GtkFileSystemModel GtkFileEntry
| | |
\-------------------|----------------/
|
GtkFileStore
|
GtkFileSystem
Where GtKFileStore would basically be the tree of nodes in
GtkFileSystemModel and GtkFileSystemModel would be a lightweight
object.
There are some things that would make this rather challenging:
- Paths are different for each GtkFileSystemModel attached to the
same GtkFileStore, which makes it difficult when we need to emit
notificatins.
- Visibility is different for each GtkFileSystemModel. (idea -
limit it to 32 Models for each Store, use a bitfield.)
- Whether you have dummy nodes or not is different .. Probably
the way you want to do a dummy node is to use a second field in
the iter structure to indicate that "this iter points to a dummy
child of iter->user_data" rather than actually storing dummy
nodes.
Implementation Details
======================
- Going to an unreadable directory crashes the file selector
currently. We probably should detect when a directory is obviously
unreadable and not allow the user to go there at all (possibly gray
out the directory if we have a directory tree) However for remote
file systems we won't find about the unreadability until later.
The KDE file selector allows you to go into an unreadable directory
then shows something along the lines of "you don't have permissions
to read this directory" instead of the file list.
- The stat() calls in gtkfilesystemunix.c probably aren't properly
gettting the sizes of >2GB files. Do we need to
-D_FILE_OFFSET_BITS=64? I think gnome-vfs probably has the right
configure checks.
- Error checking is messy and sloppy currently. All the places with a
/* NULL-GError */ comment need to be checked through to see whether
we actually should be propagated the error back up, displaying it
to the user.
- Currently, there are memory leaks all over the place, effort has to
be spent to make sure that folders get unreferenced, that when they
get unreferenced fully, everything gets freed, etc.
- GtkFileSystemModel has considerable duplicated in the area of
creating child nodes and creating dummy nodes that should be
factored out.
- GtkFileSystemGnomeVFS has duplicated code to create and fill in
FolderChild structures that should be factored out.
- GtkFileSystemGnomeVFS shares folders between callers, but if the
second caller wants more types of information than the first
caller, things don't work. ensure_types() needs to be
implemented. (Note that refetching information may need to cause a
::changed signal if the already existing information is changed.
Also, the refetch should likely be done using the GnomeVFS async
API's) This is not particularly simple.
- gtkfilesystemmodel.c:model_refilter_recurse() doesn't properly
handle inserting the dummy node if on refiltering there are no
visible nodes.
Efficiency improvements
=======================
- Many parts of FileModelNode are folder-only. It's probably better
to use a union for file-only and folder-only parts and then just
allocate the node as big as necessary. (This requires knowing
file-vs-folder when before allocating the node, but we always check
immediately after anyways.)
- When we create a new GtkFileSystemModel, we first create it showing
both files and folders, then call set_show_files() or
set_show_folders(), causing an immediate
refilter. show_files/show_folders probably should be arguments to
the constructor.
- gtkfilesystmemodel.c:do_files_removed() has to walk through all the
child nodes just to figure out whether a dummy node needs to be
inserted.
We probably should track the visible count in the node rather than
just a one bit flag. (See above comment about using different sized
nodes for folders and files.)
Though removing nodes isn't common, so this doesn't matter a whole
lot; it's just a bit ugly.
Other stuff
===========
- Documentation comments for all public and semi-public functions
need to be finished.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]