EFiler v0.2.2:

- Use edelib::Window (fixes problem with titlebar icon and some cruft in main)
- Store user preferences in edelib::Resource
- Work better with edeneu icon theme, follow fdo icon-naming-spec
- Expand . in directory path (e.g. when called from command line), show just last part of path in window title, full width status bar :)
- Some fixes to ExpandableGroup usage, use EG by default
- In fileops, don't update view manually when notify is available
- Improve documentation of EDE_FileView.h
- Temporary "Open with" callback for testing
This commit is contained in:
Vedran Ljubovic 2008-06-03 21:53:58 +00:00
parent 011180b70b
commit ff505dc732

View File

@ -40,6 +40,8 @@
#include <edelib/IconTheme.h> // for setting the icon theme #include <edelib/IconTheme.h> // for setting the icon theme
#include <edelib/MessageBox.h> #include <edelib/MessageBox.h>
#include <edelib/DirWatch.h> #include <edelib/DirWatch.h>
#include <edelib/Window.h>
#include <edelib/Resource.h>
#include "EDE_FileView.h" // our file view widget #include "EDE_FileView.h" // our file view widget
#include "EDE_DirTree.h" // directory tree #include "EDE_DirTree.h" // directory tree
@ -51,7 +53,7 @@
Fl_Window* win; edelib::Window* win;
FileView* view; FileView* view;
Fl_Menu_Bar* main_menu; Fl_Menu_Bar* main_menu;
Fl_Box* statusbar; Fl_Box* statusbar;
@ -61,6 +63,8 @@ Fl_Group* location_bar;
Fl_File_Input* location_input; Fl_File_Input* location_input;
Fl_Menu_Button* context_menu; Fl_Menu_Button* context_menu;
edelib::Resource app_config;
char current_dir[FL_PATH_MAX]; char current_dir[FL_PATH_MAX];
bool showhidden; bool showhidden;
bool semaphore; bool semaphore;
@ -69,6 +73,7 @@ bool ignorecase;
bool showtree; bool showtree;
bool showlocation; bool showlocation;
int tree_width; int tree_width;
bool notify_available;
// constants // constants
@ -89,11 +94,11 @@ int default_tree_width=150;
void iconsview_cb(Fl_Widget*, void*); void iconsview_cb(Fl_Widget*, void*);
void listview_cb(Fl_Widget*, void*); void listview_cb(Fl_Widget*, void*);
class EFiler_Window : public Fl_Double_Window { class EFiler_Window : public edelib::Window {
public: public:
EFiler_Window (int W, int H, const char* title=0) : Fl_Double_Window(W,H,title) {} EFiler_Window (int W, int H, const char* title=0) : edelib::Window(W,H,title) {}
EFiler_Window (int X, int Y, int W, int H, const char* title=0) : EFiler_Window (int X, int Y, int W, int H, const char* title=0) :
Fl_Double_Window(X,Y,W,H,title) {} edelib::Window(X,Y,W,H,title) {}
int handle(int e) { int handle(int e) {
// Have F8 function as switch between active views // Have F8 function as switch between active views
@ -106,7 +111,7 @@ public:
} }
return 1; return 1;
} }
return Fl_Double_Window::handle(e); return edelib::Window::handle(e);
} }
}; };
@ -337,7 +342,10 @@ void loaddir(const char *path) {
if (path[0] == '~' && path[1] == '/') {// Expand tilde if (path[0] == '~' && path[1] == '/') {// Expand tilde
snprintf(current_dir,FL_PATH_MAX,"%s/%s",getenv("HOME"),tmpath+1); snprintf(current_dir,FL_PATH_MAX,"%s/%s",getenv("HOME"),tmpath+1);
} else if (path[0] != '/') { // Relative path } else if (path[0] != '/') { // Relative path
snprintf(current_dir,FL_PATH_MAX,"%s/%s",getenv("PWD"),tmpath); char *t = tmpath;
if (path[0] == '.' && path[1] == '/') t+=2; // remove .
else if (path[0] == '.' && path[1] != '.') t+=1;
snprintf(current_dir,FL_PATH_MAX,"%s/%s",getenv("PWD"),t);
} else { } else {
if (path!=current_dir) strncpy(current_dir,tmpath,strlen(tmpath)+1); if (path!=current_dir) strncpy(current_dir,tmpath,strlen(tmpath)+1);
} }
@ -386,12 +394,12 @@ void loaddir(const char *path) {
edelib::DirWatch::add(current_dir, edelib::DW_CREATE | edelib::DW_DELETE | edelib::DW_ATTRIB | edelib::DW_RENAME | edelib::DW_MODIFY); edelib::DirWatch::add(current_dir, edelib::DW_CREATE | edelib::DW_DELETE | edelib::DW_ATTRIB | edelib::DW_RENAME | edelib::DW_MODIFY);
// Update directory tree // Update directory tree
dirtree->set_current(current_dir); if (showtree) dirtree->set_current(current_dir);
location_input->value(current_dir); location_input->value(current_dir);
// set window label // set window label
// copy_label() is a method that calls strdup() and later free() // copy_label() is a method that calls strdup() and later free()
win->copy_label(tsprintf(_("%s - File manager"), current_dir)); win->copy_label(tsprintf(_("%s - File manager"), my_filename_name(current_dir)));
statusbar->copy_label(tsprintf(_("Scanning directory %s..."), current_dir)); statusbar->copy_label(tsprintf(_("Scanning directory %s..."), current_dir));
view->clear(); view->clear();
@ -423,7 +431,9 @@ void loaddir(const char *path) {
item->date = nice_time(stat_buffer.st_mtime); item->date = nice_time(stat_buffer.st_mtime);
item->permissions = permission_text(stat_buffer.st_mode,stat_buffer.st_uid,stat_buffer.st_gid); item->permissions = permission_text(stat_buffer.st_mode,stat_buffer.st_uid,stat_buffer.st_gid);
if (strcmp(n,"..")==0) { if (strcmp(n,"..")==0) {
item->icon = "undo"; // item->icon = "go-up"; // undo is prettier?!
// in edeneu theme, I prefer go-jump rotated 180 degree.. in crystalsvg, undo is best
item->icon = "edit-undo";
item->description = "Go up"; item->description = "Go up";
item->size = ""; item->size = "";
} else if (S_ISDIR(stat_buffer.st_mode)) { // directory } else if (S_ISDIR(stat_buffer.st_mode)) { // directory
@ -433,7 +443,10 @@ void loaddir(const char *path) {
item->size = ""; item->size = "";
item->realpath += "/"; item->realpath += "/";
} else { } else {
item->icon = "unknown"; item->icon = "empty"; //in crystalsvg "misc" is better...
// NOTE: "empty" is *not* listed in icon-naming-spec [1], but is present in
// both KDE and GNOME themes.
// [1] http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-0.8.html
item->description = "Unknown"; item->description = "Unknown";
item->size = nice_size(stat_buffer.st_size); item->size = nice_size(stat_buffer.st_size);
} }
@ -599,6 +612,7 @@ void locationbar_cb(Fl_Widget*, void*) {
win->redraw(); win->redraw();
win->resizable(tile); win->resizable(tile);
win->redraw(); win->redraw();
// FIXME tile still doesn't resize :(
} }
} }
@ -625,9 +639,16 @@ void dirsfirst_cb(Fl_Widget*, void*) {
// Implemented after menu definition // Implemented after menu definition
void update_menu_item(const char* label, bool value); void update_menu_item(const char* label, bool value);
// Open with... callback
// TODO: make a list of openers etc.
void ow_cb(Fl_Widget*, void*) {
const char* app = edelib::input(_("Enter the name of application to open this file with:"));
const char* file = view->path(view->get_focus());
edelib::run_program(tsprintf("%s %s", app, file), /*wait=*/false);
}
// dummy callbacks - TODO // dummy callbacks - TODO
void ow_cb(Fl_Widget*, void*) { fprintf(stderr, "callback\n"); } // make a list of openers
void pref_cb(Fl_Widget*, void*) { fprintf(stderr, "callback\n"); } void pref_cb(Fl_Widget*, void*) { fprintf(stderr, "callback\n"); }
void iconsview_cb(Fl_Widget*, void*) { void iconsview_cb(Fl_Widget*, void*) {
if (view->type() != FILE_ICON_VIEW) { if (view->type() != FILE_ICON_VIEW) {
@ -819,6 +840,61 @@ void context_cb(Fl_Widget*, void*) {
} }
/*-----------------------------------------------------------------
Load / store user preferences
-------------------------------------------------------------------*/
void load_preferences() {
bool icons_view=false;
int winw, winh;
app_config.load("efiler");
app_config.get("gui","show_hidden",showhidden,false); // Show hidden files
app_config.get("gui","dirs_first",dirsfirst,true); // Directories before ordinary files
app_config.get("gui","ignore_case",ignorecase,true); // Ignore case when sorting
app_config.get("gui","show_location",showlocation,true); // Show location bar
// app_config.get("gui","show_tree",showtree,false); // Show directory tree
app_config.get("gui","icons_view",icons_view,false); // Show icons (if false, show details)
app_config.get("gui","window_width",winw,600); // Window dimensions
app_config.get("gui","window_height",winh,400);
// Apply settings
if (winw!=default_window_width || winh!=default_window_height)
win->resize(win->x(),win->y(),winw,winh);
if (location_bar->visible() != showlocation) {
showlocation = !showlocation; //locationbar_cb will return
locationbar_cb(win,0);
update_menu_item(_("&Location bar"),showlocation);
}
// showing/hiding tree is bugged
/* if ((dirtree->w()>0)!=showtree) {
showtree = !showtree; // showtree_cb will return
showtree_cb(win,0);
win->redraw(); // to actually show the tree
update_menu_item(_("Directory &tree"),showtree);
}*/
if (icons_view) iconsview_cb(win,0); else listview_cb(win,0);
update_menu_item(_("&Hidden files"),showhidden);
update_menu_item(_("D&irectories first"),dirsfirst);
}
void save_preferences() {
app_config.set("gui","show_hidden",showhidden); // Show hidden files
app_config.set("gui","dirs_first",dirsfirst); // Directories before ordinary files
app_config.set("gui","ignore_case",ignorecase); // Ignore case when sorting
app_config.set("gui","show_location",showlocation); // Show location bar
app_config.set("gui","show_tree",showtree); // Show directory tree
app_config.set("gui","icons_view",(view->type()==FILE_ICON_VIEW)); // Show icons (if false, show details)
app_config.set("gui","window_width",win->w()); // Window dimensions
app_config.set("gui","window_height",win->h());
app_config.save("efiler");
}
/*----------------------------------------------------------------- /*-----------------------------------------------------------------
GUI design GUI design
-------------------------------------------------------------------*/ -------------------------------------------------------------------*/
@ -895,20 +971,24 @@ int main (int argc, char **argv) {
strncpy(current_dir, argv[unknown], strlen(argv[unknown])+1); strncpy(current_dir, argv[unknown], strlen(argv[unknown])+1);
} }
fl_register_images(); //edelib::IconTheme::init("crystalsvg");
edelib::IconTheme::init("crystalsvg");
edelib::DirWatch::init(); edelib::DirWatch::init();
edelib::DirWatch::callback(directory_change_cb); edelib::DirWatch::callback(directory_change_cb);
// Let other components know if we have notify
if (edelib::DirWatch::notifier() == edelib::DW_NONE)
notify_available=false;
else
notify_available=true;
FL_NORMAL_SIZE=12; FL_NORMAL_SIZE=12;
fl_message_font(FL_HELVETICA, 12); fl_message_font(FL_HELVETICA, 12);
// Required by the new edelib::MessageBox class
edelib::themed_dialog_icons(MSGBOX_ICON_INFO, MSGBOX_ICON_WARNING, MSGBOX_ICON_QUESTION, MSGBOX_ICON_QUESTION, MSGBOX_ICON_PASSWORD);
// Main GUI design // Main GUI design
win = new EFiler_Window(default_window_width, default_window_height); win = new EFiler_Window(default_window_width, default_window_height);
win->init(); // new method required by edelib::Window
// win->color(FL_WHITE); // win->color(FL_WHITE);
win->begin(); win->begin();
main_menu = new Fl_Menu_Bar(0,0,default_window_width,menubar_height); main_menu = new Fl_Menu_Bar(0,0,default_window_width,menubar_height);
@ -938,15 +1018,15 @@ edelib::themed_dialog_icons(MSGBOX_ICON_INFO, MSGBOX_ICON_WARNING, MSGBOX_ICON_Q
view->context_callback(context_cb); view->context_callback(context_cb);
tile->end(); tile->end();
// Status bar group
Fl_Group *sbgroup = new Fl_Group(0, default_window_height-statusbar_height, default_window_width, statusbar_height); Fl_Group *sbgroup = new Fl_Group(0, default_window_height-statusbar_height, default_window_width, statusbar_height);
statusbar = new Fl_Box(2, default_window_height-statusbar_height+2, statusbar_width, statusbar_height-4); statusbar = new Fl_Box(2, default_window_height-statusbar_height+2, //statusbar_width,
default_window_width-4, statusbar_height-4);
statusbar->box(FL_DOWN_BOX); statusbar->box(FL_DOWN_BOX);
statusbar->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP); statusbar->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP);
statusbar->label(_("EFiler is starting...")); statusbar->label(_("EFiler is starting..."));
Fl_Box* filler = new Fl_Box(statusbar_width+2, default_window_height-statusbar_height+2, default_window_width-statusbar_width, statusbar_height-4);
sbgroup->end(); sbgroup->end();
sbgroup->resizable(filler); sbgroup->resizable(statusbar);
context_menu = new Fl_Menu_Button (0,0,0,0); context_menu = new Fl_Menu_Button (0,0,0,0);
context_menu->type(Fl_Menu_Button::POPUP3); context_menu->type(Fl_Menu_Button::POPUP3);
@ -958,18 +1038,18 @@ edelib::themed_dialog_icons(MSGBOX_ICON_INFO, MSGBOX_ICON_WARNING, MSGBOX_ICON_Q
// win->resizable(view); // win->resizable(view);
// Set application (window manager) icon // Set application (window manager) icon
// FIXME: due to fltk bug this icon doesn't have transparency // TODO: use icon from theme (e.g. system-file-manager)
fl_open_display(); win->window_icon(efiler_xpm); // new method in edelib::Window
Pixmap p, mask;
XpmCreatePixmapFromData(fl_display, DefaultRootWindow(fl_display), (char**)efiler_xpm, &p, &mask, NULL);
win->icon((char*)p);
// TODO remember previous configuration // Read user preferences
showhidden=false; dirsfirst=true; ignorecase=true; semaphore=false; showtree=true; showlocation=true; load_preferences();
tree_width = default_tree_width;
//Fl::visual(FL_DOUBLE|FL_INDEX); // see Fl_Double_Window docs
semaphore=false; // semaphore for loaddir
showtree=true;
Fl::visual(FL_DOUBLE|FL_INDEX); // see Fl_Double_Window docs
win->show(argc,argv); win->show(argc,argv);
view->take_focus(); view->take_focus();
dirtree->init(); dirtree->init();
@ -982,6 +1062,7 @@ edelib::themed_dialog_icons(MSGBOX_ICON_INFO, MSGBOX_ICON_WARNING, MSGBOX_ICON_Q
// Cleanup and shutdowns // Cleanup and shutdowns
edelib::DirWatch::shutdown(); edelib::DirWatch::shutdown();
save_preferences();
return 0; return 0;
} }