mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Open with... dialog with autocompletion
This commit is contained in:
parent
29e2efe9b8
commit
11922d5035
147
efiler/OpenWith.cpp
Normal file
147
efiler/OpenWith.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
#include "OpenWith.h"
|
||||
|
||||
#include <edelib/IconTheme.h>
|
||||
#include <edelib/Run.h>
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Group.H>
|
||||
#include <FL/Fl_Box.H>
|
||||
#include <FL/Fl_Input.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
#include <FL/Fl_Return_Button.H>
|
||||
#include <FL/Fl_Shared_Image.H>
|
||||
#include <FL/Fl_File_Chooser.H>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // getenv()
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#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<edelib::String>* progs = (edelib::list<edelib::String>*)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<edelib::String>::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<edelib::String>::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; i<size; i++) {
|
||||
// Attach filename to directory to get full path
|
||||
char *n = files[i]->d_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);
|
||||
}
|
27
efiler/OpenWith.h
Normal file
27
efiler/OpenWith.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef _OpenWith_h_
|
||||
#define _OpenWith_h_
|
||||
|
||||
#include <edelib/Nls.h>
|
||||
#include <edelib/Window.h>
|
||||
#include <edelib/String.h>
|
||||
#include <edelib/List.h>
|
||||
|
||||
#include <FL/Fl_Input.H>
|
||||
|
||||
class OpenWith : public edelib::Window {
|
||||
private:
|
||||
const char* _file;
|
||||
edelib::list<edelib::String> programs;
|
||||
Fl_Input *inpt;
|
||||
public:
|
||||
OpenWith();
|
||||
const char* file() { return _file; }
|
||||
void show(const char* pfile) {
|
||||
_file=pfile;
|
||||
inpt->value("");
|
||||
edelib::Window::show();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user