diff --git a/efiler/OpenWith.cpp b/efiler/OpenWith.cpp new file mode 100644 index 0000000..a8b6426 --- /dev/null +++ b/efiler/OpenWith.cpp @@ -0,0 +1,147 @@ +#include "OpenWith.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // getenv() +#include +#include + +#include "Util.h" + +void openwith_cancel_cb(Fl_Widget*w, void*) { + Fl_Window* win = (Fl_Window*)w->parent(); + win->hide(); +} + +void openwith_ok_cb(Fl_Widget*w, void*i) { + Fl_Input* inpt = (Fl_Input*)i; + OpenWith* win = (OpenWith*)w->parent(); +fprintf(stderr, "Opening %s '%s'\n", inpt->value(), win->file()); + int k = edelib::run_program(tsprintf("%s '%s'", inpt->value(), win->file()), /*wait=*/false); +fprintf(stderr, "retval: %d\n", k); + win->hide(); +} + +void openwith_browse_cb(Fl_Widget*w, void*i) { + Fl_Input* inpt = (Fl_Input*)i; + char *file = fl_file_chooser(_("Choose program"),0,0); + inpt->value(file); +} + +void program_input_cb(Fl_Widget*w, void*p) { + edelib::list* progs = (edelib::list*)p; + Fl_Input *inpt = (Fl_Input*)w; + Fl_Window *win = (Fl_Window*)w->parent(); + + if (Fl::event()==FL_KEYDOWN && Fl::event_key()!=FL_BackSpace && Fl::event_key()!=FL_Delete) { + const char* loc = inpt->value(); // shortcut + if (strlen(loc)<1 || loc[strlen(loc)-1]=='/') return; + uint pos = inpt->position(); + if (pos!=strlen(loc)) return; // cursor in the middle + int mark = inpt->mark(); + + if (Fl::event_key()==FL_Enter) { + inpt->mark(pos); + // Move focus to Ok button + win->child(3)->take_focus(); + return; + } + + edelib::list::iterator it1, it2; + it1 = progs->begin(); + it2 = progs->end(); + while (it1 != it2) { + if (strncmp(loc, (*it1).c_str(), strlen(loc))==0) break; + ++it1; + } + if (it1==it2) return; + + inpt->replace(pos, mark, (*it1).c_str()+pos); + inpt->position(pos); + inpt->mark(strlen((*it1).c_str())); + } +} + + +OpenWith::OpenWith() : edelib::Window(410,110, _("Choose program")), _file(0) { + set_modal(); + + edelib::list::iterator it1, it2; + dirent **files; + struct stat buf; + char pn[FL_PATH_MAX]; + + Fl_Group *gr; + Fl_Box *img, *txt; + Fl_Button *but1, *but2, *but3; + Fl_Image* i; + + // Extract all parts of $PATH + char* path = strdup(getenv("PATH")); // original would get destroyed + char *pathpart = strtok(path, ":"); + while (pathpart) { + // Get list of files in pathpart + int size = scandir(pathpart, &files,0,alphasort); + for (int i=0; id_name; + snprintf (pn,FL_PATH_MAX-1,"%s/%s",pathpart,n); + if (stat(pn,&buf)) continue; + if (!S_ISDIR(buf.st_mode) && (buf.st_mode&S_IXOTH)) { + // Not directory, executable + edelib::String name(n); + it1=programs.begin(); it2=programs.end(); + bool exists=false; + while (it1 != it2) { + if (*it1==name) { exists=true;break;} + ++it1; + } + if (!exists) programs.push_back(n); + } + } + pathpart=strtok(NULL, ":"); + } + free(path); + + programs.sort(); + + // Window design + begin(); + img = new Fl_Box(10, 10, 60, 55); + + txt = new Fl_Box(75, 10, w()-85, 25, _("Enter the name of application to open this file with:")); + inpt = new Fl_Input(75, 40, w()-175, 25); + + txt->align(FL_ALIGN_INSIDE | FL_ALIGN_LEFT | FL_ALIGN_WRAP); + + but1 = new Fl_Return_Button(w()-200, 75, 90, 25, "&Ok"); + but2 = new Fl_Button(w()-100, 75, 90, 25, "&Cancel"); + but3 = new Fl_Button(w()-90, 40, 80, 25, "&Browse..."); + + end(); + + but1->callback(openwith_ok_cb,inpt); + but2->callback(openwith_cancel_cb); + but3->callback(openwith_browse_cb,inpt); + + inpt->when(FL_WHEN_ENTER_KEY_CHANGED); + inpt->callback(program_input_cb, &programs); + + // Set icon + if(!edelib::IconTheme::inited()) return; + i = Fl_Shared_Image::get(edelib::IconTheme::get("dialog-question", edelib::ICON_SIZE_MEDIUM).c_str()); + if(!i) return; + + img->image(i); +} diff --git a/efiler/OpenWith.h b/efiler/OpenWith.h new file mode 100644 index 0000000..680e36d --- /dev/null +++ b/efiler/OpenWith.h @@ -0,0 +1,27 @@ +#ifndef _OpenWith_h_ +#define _OpenWith_h_ + +#include +#include +#include +#include + +#include + +class OpenWith : public edelib::Window { +private: + const char* _file; + edelib::list programs; + Fl_Input *inpt; +public: + OpenWith(); + const char* file() { return _file; } + void show(const char* pfile) { + _file=pfile; + inpt->value(""); + edelib::Window::show(); + } +}; + + +#endif diff --git a/efiler/efiler.cpp b/efiler/efiler.cpp index 0f5885b..172b85d 100644 --- a/efiler/efiler.cpp +++ b/efiler/efiler.cpp @@ -45,6 +45,7 @@ #include "EDE_FileView.h" // our file view widget #include "EDE_DirTree.h" // directory tree #include "Util.h" // ex-edelib +#include "OpenWith.h" // Open with... window #include "fileops.h" // file operations #include "filesystem.h" // filesystem support @@ -53,6 +54,7 @@ + edelib::Window* win; FileView* view; Fl_Menu_Bar* main_menu; @@ -62,6 +64,7 @@ Fl_Tile* tile; Fl_Group* location_bar; Fl_File_Input* location_input; Fl_Menu_Button* context_menu; +OpenWith *ow; edelib::Resource app_config; edelib::MimeType mime_resolver; @@ -493,7 +496,7 @@ void file_open(const char* path, MailcapAction action) { fprintf (stderr, "run_program: %s\n", o2); if (action == MAILCAP_EXEC) { - int k=edelib::run_program(path,false); fprintf(stderr, "retval: %d\n", k); + int k=edelib::run_program(path,false); fprintf(stderr, "Xretval: %d\n", k); } else if (opener) { int k=edelib::run_program(o2,false); fprintf(stderr, "retval: %d\n", k); } else { @@ -545,9 +548,12 @@ void open_cb(Fl_Widget*w, void*data) { // File > Open with... // TODO: make a list of openers etc. void openwith_cb(Fl_Widget*, void*) { - const char* app = edelib::input(_("Enter the name of application to open this file with:")); + +// 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); +// edelib::run_program(tsprintf("%s '%s'", app, file), /*wait=*/false); + ow->show(file); +// Fl::run(); } // File > New (efiler window) @@ -1105,6 +1111,8 @@ FL_NORMAL_SIZE=12; dirtree->show_hidden(showhidden); dirtree->ignore_case(ignorecase); + ow = new OpenWith(); + // Read user preferences load_preferences();