proposal of GtkFileSeletion replacement's API
- From: Vlad Harchev <hvv hippo ru>
- To: gtk-devel-list gnome org
- Cc: gtkfilesel-devel lists sourceforge net
- Subject: proposal of GtkFileSeletion replacement's API
- Date: Sun, 3 Sep 2000 18:59:38 +0500 (SAMST)
Hello,
There were some discussions here and on
gtkfilesel-devel@lists.sourceforge.net about the API of new filesel widget.
Here I propose API I designed, with idea of hooking arbitrary filesel "engine"
in mind. This API doesn't make any assumptions on the widgets that are in the
filesel window (thus it allows arbitrary file selectors, like nautilus' view
or selector present in current gtk-1.2) (well, both mentioned candidates won't
select multiplie file selection, but can be easily used for single file
selection).
I'm open to your ideas on this topic.
Intro:
The file selection window is GtkObject derived from GtkWindow. I didn't
decide how to call that widget, but I suggest GtkFileSelectionWindow
(though I call it GtkFileSelector in the text below).
All API functions below that start with '_' in realty should start with
prefix depending on the name we choose for new fileselection widget.
All arguments with name 'fs' are meant to be pointers to the instance of
GtkFileSelector. GtkFileSelector is supposed to support multiplie and single
file selectors (allowing to select a set of files in different directories
at once for multifile selectors). Also, support for differentiation of
save and open dialogs is done.
There is a notion of 'filesel engine' - the 'struct GtkFileSelEngine'
with virtual functions (pointed by a member 'filesel_engine' of
GtkFileSelector) corresponding to each engine-dependant API function.
The virtual functions will be called with validated and cloned values, so
filesel engine writers shouldn't bother strdupping and memcpy'ing values
(or cutting and pasting code :)
It's assumed that filesel engines will be distributed as gmodules. User
will have to add a path to their favourite filesel gmodule to the
environment variable $GTK_MODULES (probably gnome control center will
provide ability to select filesel engine and configure it, as it allows
with window managers).
/*code for managing engines*/
/*
Engine at the top of stack is used for creating filesel windows (but the
(*new_instance) method of that engine can order to use different engine
in the returned GtkFileSelector* (by setting 'filesel_engine' member to
something else).
By default, the builting implementation of file selector is on top of the
stack.
*/
void _engine_push(GtkFileSelEngine* engine);
void _engine_pop();
GtkFileSelEngine* _default_engine();//to allow pushing it.
void _engine_register(GtkFileSelEngine* engine);
GList* _query_engines();
/*
So, each filesel engine should call _engine_register(self) and
_engine_push(self) when its gmodule's init function is called.
*/
typedef enum
{
GTK_FILESEL_MODE_SINGLE,
GTK_FILESEL_MODE_MULTIPLIE
} GtkFileSelMode;
typedef enum
{
GTK_FILESEL_ROLE_OPEN,
/* for example open for viewing or executing documents (primary
type of documents application can open).
*/
GTK_FILESEL_ROLE_SAVE,
/* for saving versions of the primary document type that application can
open directly (i.e. images for image editor).
*/
GTK_FILESEL_ROLE_AUX_OPEN,
GTK_FILESEL_ROLE_AUX_SAVE,
/* just for use - like selecting style/skin for use, etc - i.e. for
documents of kind secondary to this application.
Documents opened with this role won't be added to 'recently opened'
or 'recently edited' lists.
For example, when one opens mp3 file in xmms, then the role of the
file selector dialog should be GTK_FILESEL_ROLE_OPEN (thus that file
will probably be added to 'recently opened..' list. But when skin
selector is opened for xmms, the role of that filesel dialog should
be GTK_FILESEL_ROLE_AUX_OPEN since viewing skins is not a primary
usage of xmms.
*/
} GtkFileSelRole;
typedef enum
{
GTK_FILESEL_REGISTER_CLASS_GENERIC,
GTK_FILESEL_REGISTER_CLASS_IMPORTANT,
GTK_FILESEL_REGISTER_CLASS_UNIMPORTANT,
GTK_FILESEL_REGISTER_CLASS_DONT,
} GtkFileSelRegisterImportance;
/*
'detail' specifies the description of this file operation. It's a
string, that needn't be human-readable (and it neend't be
translated to user's language). This string should uniquely
describe the use of this file option in
the given application, and it will
propably be used as a key for retriving settings of the dialog
assigned by the user and/or widget itself (for example, recently
opened filename, recently used directory that are specific to this
operation). This string won't be shown to the user in the dialog
(but will probably be used as a key, together with app name, in
some config file). A good example of value 'detail' is "skin"
or "texture", bad are "xmms-skin-open" (since name of
application and type of operation are already known to the widget,
there is no need to duplicate this information).
Using GTK_FILESEL_MODE_MULTIPLIE and GTK_FILESEL_ROLE_*SAVE is
prohibbited.
*/
GtkFileSelector* _new(GtkFileSelMode mode,GtkFileSelRole role,char* detail);
/* moves to specified directory and selects or places filename into
filename prompt. It's not recommended to call this function.
*/
void _set_path(GtkFileSelector* fs,char* directory,char* filename);
void _clear_selection(fs);
/* allows to peek at list of selected files. The order of the files is
implementation-dependant.
*/
GList* _get_selection(fs);
/*
The list is owned by caller (so it should be freed by caller).
Implementation can reorder the list of filenames in any way it likes.
If 'filenames' is NULL, then selection is cleared.
*/
void _set_selection(fs,GList* filenames)
/* returns first item in the list (mostly for use by single file
selectors).
*/
char* _get_filename(fs);
/* clears selection. Selects only one file. If it's single fileselector,
then dirname of 'filename' becomes current directory of filesel.
*/
void _set_filename(fs,char* filename);
struct _GtkFileSelectorExtensionInfo
{
char* description;
/* will be shown in popup or the like,
e.g. "TIFF file format (.tiff)" - can be "" - then description
will be constructed from patterns. If NULL, then it marks the last
item in the array of extension infos.
*/
char* canon_tail;
/* e.g. ".tiff", - exactly that string will be appended to
basename when that format is selected. If NULL, then 1st item
in 'patterns[]' will be used.
*/
char* patterns[8];
/* a list of suffixes, each element - one suffix, e.g.
".tiff". Use NULL to teminate the list. Suffixes will be matched
case-insensitive.*/
gpointer user_data;
/*
Arbitrary data writable by the user.
*/
gpointer engine_data;
/*
Arbitrary data that shouldn't be changed by the user.
*/
};
typedef struct _GtkFileSelectorExtensionInfo GtkFileSelectorExtensionInfo;
/*
Set extension infos. The item with NULL in .description terminates
the array. 'default' is the index of default extension or -1 for
"All files".
Widget will strdup these infos.
It's safe to call this only once.
*/
void _set_extension_info(fs,GtkFileSelectorExtensionInfo* extinfo, int default);
/*
This sets index of default extension. -1 means "all files". Used mainly
for setting widget's arguments.
*/
void _set_default_extension_info_index(fs,int idx);
/*
Returns extension info of default filename. If user didn't set any
extinfo information, then extinfo corresponding to 'all files' will
be returned.
*/
GtkFileSelectorExtensionInfo* _get_default_extension_info(fs);
/*auxilary functions follow - no virtual function correspond to them.*/
/*
This is auxilary function used by engine implementation for freeing
duplicated array of GtkFileSelectorExtensionInfo (every "valid"
string member will be freed).
*/
void _free_extension_info(GtkFileSelectorExtensionInfo* extinfo)
/*
This will return strdupped string.
step 1: If filename doesn't contain slash, than name of filesel's current dir
is prepended.
step 2: If mode is GTK_FILESEL_MODE_SINGLE and role is GTK_FILESEL_ROLE_*OPEN,
this will do the following:
if that file exist, it will return name verbatim.
if that file doesn't exist and its suffix matches current
filter's suffix, filename will be returned verbatim;
otherwise canonical suffix for currently selected extension info
will be appended to filename and returned
otherwise result of step 1 will be returned.
*/
char* _get_filename_with_extension(GtkFileSelectorExtensionInfo* fs,
char* filename)
typedef struct _GtkFileSelEngine
{
/*
This is used for quering various implementation-specific parameters
(like engine name, version, properties).
*/
GtkData data;
/*
This could return object of type derived from 'GtkFileSelector'
(thus extending a set of arguments).
*/
GtkFileSelector* (*new_instance)(GtkFileSelMode mode,GtkFileSelRole role,
char* detail);
/* the following member correspond to functions for dealing with FileSel*/
/* moves to specified directory and selects or places filename into
filename prompt. Engine should check whether the dir exists and do
all things like running signal handlers.
*/
void (*set_path)(GtkFileSelector* fs,char* directory,char* filename);
void (*clear_selection)(GtkFileSelector* fs);
/* allows to peek at list of selected files. The order of the files is
implementation-dependant.
*/
GList* (*get_selection)(GtkFileSelector* fs);
/*
The list is owned by caller (so it should be freed by caller).
Implementation can reorder the list of filenames in any way it likes.
If 'filenames' is NULL, then selection is cleared.
*/
void (*set_selection)(GtkFileSelector* fs,GList* filenames)
/* returns first item in the list (mostly for use by single file
selectors).
*/
char* (*get_filename)(GtkFileSelector* fs);
/* clears selection. Selects only one file. If it's single fileselector,
then dirname of 'filename' becomes current directory of filesel.
*/
void (*set_filename)(GtkFileSelector* fs,char* filename);
/*
Set extension infos. The item with NULL in .description terminates
the array. 'default' is the index of default extension or -1 for
"All files".
The extinfo will be strdupped and "normalized". All that fs engine
should do is to free previous info using _free_extension_info, set the
members to fs to new values (passed as argument) and recreate
the widget that allows selection of extension.
*/
void (*set_extension_info)(fs,GtkFileSelectorExtensionInfo* newextinfo,
int newdefault);
/*
This sets index of default extension. -1 means "all files".
The value passed will already be validated.
*/
void (*set_default_extension_info_index)(fs,int newidx);
} GtkFileSelEngine;
struct _GtkFileSelector
{
GtkWindow window;/*it's derived from gtkwindow*/
/*all members shouldn't be modified by apps*/
GtkFileSelEngine* filesel_engine;
/*next 2 members are private to implementation*/
gpointer engine_data;
gpointer widget_data;
GtkFileSelMode mode;
GtkFileSelRole role;
char* detail;/*that value is managed by the widget.*/
/*current directory*/
char* current_directory;
/*number of files and dirs (excluding . and ..) shown.*/
guint nfiles;
guint ndirs;
/*these values contain filenames or NULL if nothing is focused.*/
char* focused_file;
char* focused_directory;
char* filename;/*the filename typed by user (most probably it will be
equal to either 'focused_file' or 'focused_directory'.*/
GtkFileSelectorExtensionInfo* extinfo;
guint numextinfos;
int current_extinfo;
/* the buttons will already have title appropriate for operation, but in
rare cases app can change them. */
GtkWidget* ok_button;/*even if selection of file is performed by
double click, this button will be clicked by filesel implementation.
So app should trap dialog closing using this button. */
GtkWidget* cancel_button;
GtkWidget* free_vbox;/*vbox to the right of the widget, where app can place
buttons*/
GtkWidget* buttons_free_hbox;/*hbox where app can add additional buttons*/
};
signals (exported by GtkFileSelector):
/*
Called to check whether filename can be added to selection (only makes
sense for mutlifile selection). If 1 is returned, then file can be
added.
Callback can popup something. If no handlers are attached, then
it's assumed that the file can be selected.
Not used for single file selector.
*/
gboolean "check-can-select-filename" (fs,filename,data);
/*
Called to check whether filename can be removed to selection (only
makes sense for mutlifile selection). If 1 is returned, then file can
be added. Callback can popup some dialog.
Not used for single file selector.
*/
gboolean "check-can-deselect-filename" (fs,filename,data);
/*
The next two are used for filtering of contents.
*/
gboolean "can-show-filename"(fs,filename,data);
gboolean "can-show-dirname"(fs,filename,data);
/*
Not used for single file selector.
*/
void "selection-changed"(fs,data);
/*
This will be called when directory is changed or current directory
content is reloaded. Current directory name can be read directly from
the widget.
*/
void "directory-changed"(fs,char* olddirname,data);
/*
This is called when modifies filename to save to by editing its name in
the entry (this has nothing to do with file renaming existing file).
*/
void "filename-changed"(fs,data);
/*
will be called when user puts focus on some file. 'file' is an object
that is not directory and not symlink to directory.
*/
void "file-focus-in"(fs,char* filename,data)
void "file-focus-out"(fs,char* filename,data)
/*
will be called when user puts focus on some directory. 'directory' is
an object that is directory or a symlink to directory.
It's guaranteed that that extactly zero or one file and directory will
be focused at time (i.e., one dir and one file, dir only, file only
or nothing can be focused at a time).
*/
void "dir-focus-in"(fs,char* filename,data)
void "dir-focus-out"(fs,char* filename,data)
/*
Current filter settings can be read directly from the widget.
*/
void "extension-filter-changed"(fs,GtkFileSelectorExtensionInfo* old,data);
signals end
/*A typical use of file selector will be */
GtkFileSelector* fs =_new(GTK_FILESEL_MODE_SINGLE,GTK_FILESEL_ROLE_OPEN,"doc");
gtk_signal_connect(fs->ok_button,"clicked",ok_handler,NULL);
gtk_signal_connect(fs->cancel_button,"clicked",cancel_handler,NULL);
gtk_widget_show_all(GTK_WIDGET(fs));
/*....*/
char* filename = strdup(_get_filename(fs));
gtk_widget_destroy(GTK_WIDGET(fs));
Best regards,
-Vlad
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]