mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
- Add new entries to mailcap using Open with.. dialog
- Start of work on Properties window. For now, the code is very ugly and it is read only.
This commit is contained in:
parent
08261736b7
commit
03a987a90d
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
SubDir TOP efiler ;
|
SubDir TOP efiler ;
|
||||||
|
|
||||||
SOURCE = Fl_Icon_Browser.cxx EDE_Browser.cpp EDE_DirTree.cpp Util.cpp efiler.cpp fileops.cpp filesystem.cpp Flu_Wrap_Group.cpp EDE_FileIconView.cpp EDE_FileDetailsView.cpp ede_strverscmp.c mailcap.cpp OpenWith.cpp ;
|
SOURCE = Fl_Icon_Browser.cxx EDE_Browser.cpp EDE_DirTree.cpp Util.cpp efiler.cpp fileops.cpp filesystem.cpp Flu_Wrap_Group.cpp EDE_FileIconView.cpp EDE_FileDetailsView.cpp ede_strverscmp.c mailcap.cpp OpenWith.cpp Properties.cpp ;
|
||||||
|
|
||||||
LinkAgainst efiler : -lXpm ;
|
LinkAgainst efiler : -lXpm ;
|
||||||
|
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* EFiler - EDE File Manager
|
||||||
|
* Part of Equinox Desktop Environment (EDE).
|
||||||
|
* Copyright (c) 2000-2007 EDE Authors.
|
||||||
|
*
|
||||||
|
* This program is licenced under terms of the
|
||||||
|
* GNU General Public Licence version 2 or newer.
|
||||||
|
* See COPYING for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Open with.. dialog window
|
||||||
|
|
||||||
|
|
||||||
#include "OpenWith.h"
|
#include "OpenWith.h"
|
||||||
|
|
||||||
#include <edelib/IconTheme.h>
|
#include <edelib/IconTheme.h>
|
||||||
@ -18,18 +34,32 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
#include "mailcap.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define DIALOG_WIDTH 410
|
||||||
|
#define DIALOG_HEIGHT 145
|
||||||
|
|
||||||
|
// Callbacks
|
||||||
|
|
||||||
void openwith_cancel_cb(Fl_Widget*w, void*) {
|
void openwith_cancel_cb(Fl_Widget*w, void*) {
|
||||||
Fl_Window* win = (Fl_Window*)w->parent();
|
Fl_Window* win = (Fl_Window*)w->parent();
|
||||||
win->hide();
|
win->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function is friend of OpenWith because it needs to access
|
||||||
|
// _type and _file
|
||||||
void openwith_ok_cb(Fl_Widget*w, void*i) {
|
void openwith_ok_cb(Fl_Widget*w, void*i) {
|
||||||
Fl_Input* inpt = (Fl_Input*)i;
|
Fl_Input* inpt = (Fl_Input*)i;
|
||||||
OpenWith* win = (OpenWith*)w->parent();
|
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);
|
// Handle Always use... button
|
||||||
fprintf(stderr, "retval: %d\n", k);
|
if (win->always_use->value() == 1) {
|
||||||
|
mailcap_add_type(win->_type, inpt->value());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run program
|
||||||
|
int k = edelib::run_program(tsprintf("%s '%s'", inpt->value(), win->_file), /*wait=*/false);
|
||||||
win->hide();
|
win->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +69,7 @@ void openwith_browse_cb(Fl_Widget*w, void*i) {
|
|||||||
inpt->value(file);
|
inpt->value(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Callback that handles "autocomplete" in the openwith dialog
|
||||||
void program_input_cb(Fl_Widget*w, void*p) {
|
void program_input_cb(Fl_Widget*w, void*p) {
|
||||||
edelib::list<edelib::String>* progs = (edelib::list<edelib::String>*)p;
|
edelib::list<edelib::String>* progs = (edelib::list<edelib::String>*)p;
|
||||||
Fl_Input *inpt = (Fl_Input*)w;
|
Fl_Input *inpt = (Fl_Input*)w;
|
||||||
@ -74,7 +105,10 @@ void program_input_cb(Fl_Widget*w, void*p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OpenWith::OpenWith() : edelib::Window(410,110, _("Choose program")), _file(0) {
|
// OpenWith constructor
|
||||||
|
// Also initializes various internal arrays
|
||||||
|
|
||||||
|
OpenWith::OpenWith() : edelib::Window(DIALOG_WIDTH, DIALOG_HEIGHT, _("Choose program")), _file(0) {
|
||||||
set_modal();
|
set_modal();
|
||||||
|
|
||||||
edelib::list<edelib::String>::iterator it1, it2;
|
edelib::list<edelib::String>::iterator it1, it2;
|
||||||
@ -83,23 +117,64 @@ OpenWith::OpenWith() : edelib::Window(410,110, _("Choose program")), _file(0) {
|
|||||||
char pn[FL_PATH_MAX];
|
char pn[FL_PATH_MAX];
|
||||||
|
|
||||||
Fl_Group *gr;
|
Fl_Group *gr;
|
||||||
Fl_Box *img, *txt;
|
Fl_Box *img;
|
||||||
Fl_Button *but1, *but2, *but3;
|
|
||||||
Fl_Image* i;
|
Fl_Image* i;
|
||||||
|
Fl_Button *but1, *but2, *but3;
|
||||||
|
|
||||||
// Extract all parts of $PATH
|
// Window design
|
||||||
|
begin();
|
||||||
|
img = new Fl_Box(10, 10, 60, 55); // icon
|
||||||
|
|
||||||
|
// informative text
|
||||||
|
txt = new Fl_Box(75, 10, w()-85, 25);
|
||||||
|
txt->align(FL_ALIGN_INSIDE | FL_ALIGN_LEFT | FL_ALIGN_WRAP);
|
||||||
|
|
||||||
|
// input for program name
|
||||||
|
inpt = new Fl_Input(75, 45, w()-175, 25);
|
||||||
|
inpt->when(FL_WHEN_ENTER_KEY_CHANGED);
|
||||||
|
inpt->callback(program_input_cb, &programs);
|
||||||
|
|
||||||
|
// Ok & Cancel buttons
|
||||||
|
but1 = new Fl_Return_Button(w()-200, 115, 90, 25, "&Ok");
|
||||||
|
but2 = new Fl_Button(w()-100, 115, 90, 25, "&Cancel");
|
||||||
|
but1->callback(openwith_ok_cb,inpt);
|
||||||
|
but2->callback(openwith_cancel_cb);
|
||||||
|
|
||||||
|
// Browse button
|
||||||
|
but3 = new Fl_Button(w()-90, 45, 80, 25, "&Browse...");
|
||||||
|
but3->callback(openwith_browse_cb,inpt);
|
||||||
|
|
||||||
|
// Always use this program...
|
||||||
|
always_use = new Fl_Check_Button(75, 80, w()-85, 20);
|
||||||
|
always_use->align(FL_ALIGN_INSIDE | FL_ALIGN_LEFT | FL_ALIGN_TOP | FL_ALIGN_WRAP);
|
||||||
|
|
||||||
|
end();
|
||||||
|
|
||||||
|
// Set icon
|
||||||
|
if(edelib::IconTheme::inited()) {
|
||||||
|
i = Fl_Shared_Image::get(edelib::IconTheme::get("dialog-question", edelib::ICON_SIZE_MEDIUM).c_str());
|
||||||
|
if(!i) return;
|
||||||
|
|
||||||
|
img->image(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -- Find all executables in $PATH and add them to programs list
|
||||||
|
|
||||||
|
// Split $PATH at ':' character
|
||||||
char* path = strdup(getenv("PATH")); // original would get destroyed
|
char* path = strdup(getenv("PATH")); // original would get destroyed
|
||||||
char *pathpart = strtok(path, ":");
|
char *pathpart = strtok(path, ":");
|
||||||
while (pathpart) {
|
while (pathpart) {
|
||||||
// Get list of files in pathpart
|
// Get list of files in pathpart
|
||||||
int size = scandir(pathpart, &files,0,alphasort);
|
int size = scandir(pathpart, &files, 0, alphasort);
|
||||||
for (int i=0; i<size; i++) {
|
for (int i=0; i<size; i++) {
|
||||||
// Attach filename to directory to get full path
|
// Attach filename to directory to get full path
|
||||||
char *n = files[i]->d_name;
|
char *n = files[i]->d_name;
|
||||||
snprintf (pn,FL_PATH_MAX-1,"%s/%s",pathpart,n);
|
snprintf (pn,FL_PATH_MAX-1,"%s/%s",pathpart,n);
|
||||||
if (stat(pn,&buf)) continue;
|
if (stat(pn,&buf)) continue; // some kind of error
|
||||||
|
|
||||||
|
// Skip all directories and non-executables
|
||||||
if (!S_ISDIR(buf.st_mode) && (buf.st_mode&S_IXOTH)) {
|
if (!S_ISDIR(buf.st_mode) && (buf.st_mode&S_IXOTH)) {
|
||||||
// Not directory, executable
|
|
||||||
edelib::String name(n);
|
edelib::String name(n);
|
||||||
it1=programs.begin(); it2=programs.end();
|
it1=programs.begin(); it2=programs.end();
|
||||||
bool exists=false;
|
bool exists=false;
|
||||||
@ -109,39 +184,30 @@ OpenWith::OpenWith() : edelib::Window(410,110, _("Choose program")), _file(0) {
|
|||||||
}
|
}
|
||||||
if (!exists) programs.push_back(n);
|
if (!exists) programs.push_back(n);
|
||||||
}
|
}
|
||||||
|
Fl::check();
|
||||||
}
|
}
|
||||||
pathpart=strtok(NULL, ":");
|
pathpart=strtok(NULL, ":");
|
||||||
|
Fl::check();
|
||||||
}
|
}
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
programs.sort();
|
programs.sort();
|
||||||
|
|
||||||
// Window design
|
}
|
||||||
begin();
|
|
||||||
img = new Fl_Box(10, 10, 60, 55);
|
|
||||||
|
void OpenWith::show(const char* pfile, const char* ptype, const char* pcomment) {
|
||||||
txt = new Fl_Box(75, 10, w()-85, 25, _("Enter the name of application to open this file with:"));
|
_file=pfile;
|
||||||
inpt = new Fl_Input(75, 40, w()-175, 25);
|
_type=ptype;
|
||||||
|
|
||||||
txt->align(FL_ALIGN_INSIDE | FL_ALIGN_LEFT | FL_ALIGN_WRAP);
|
// Clear input box
|
||||||
|
inpt->value("");
|
||||||
but1 = new Fl_Return_Button(w()-200, 75, 90, 25, "&Ok");
|
|
||||||
but2 = new Fl_Button(w()-100, 75, 90, 25, "&Cancel");
|
// Set textual description
|
||||||
but3 = new Fl_Button(w()-90, 40, 80, 25, "&Browse...");
|
txt->copy_label(tsprintf(_("Enter the name of application used to open file \"%s\":"),fl_filename_name(pfile)));
|
||||||
|
|
||||||
end();
|
// Set "always use" label
|
||||||
|
always_use->copy_label(tsprintf(_("Always use this program for opening files of type \"%s\""), pcomment));
|
||||||
but1->callback(openwith_ok_cb,inpt);
|
|
||||||
but2->callback(openwith_cancel_cb);
|
edelib::Window::show();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* EFiler - EDE File Manager
|
||||||
|
* Part of Equinox Desktop Environment (EDE).
|
||||||
|
* Copyright (c) 2000-2007 EDE Authors.
|
||||||
|
*
|
||||||
|
* This program is licenced under terms of the
|
||||||
|
* GNU General Public Licence version 2 or newer.
|
||||||
|
* See COPYING for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Open with.. dialog window
|
||||||
|
|
||||||
|
|
||||||
#ifndef _OpenWith_h_
|
#ifndef _OpenWith_h_
|
||||||
#define _OpenWith_h_
|
#define _OpenWith_h_
|
||||||
|
|
||||||
@ -7,20 +23,29 @@
|
|||||||
#include <edelib/List.h>
|
#include <edelib/List.h>
|
||||||
|
|
||||||
#include <FL/Fl_Input.H>
|
#include <FL/Fl_Input.H>
|
||||||
|
#include <FL/Fl_Check_Button.H>
|
||||||
|
#include <FL/Fl_Box.H>
|
||||||
|
|
||||||
class OpenWith : public edelib::Window {
|
class OpenWith : public edelib::Window {
|
||||||
private:
|
private:
|
||||||
const char* _file;
|
const char* _file, * _type;
|
||||||
edelib::list<edelib::String> programs;
|
edelib::list<edelib::String> programs;
|
||||||
Fl_Input *inpt;
|
Fl_Input *inpt;
|
||||||
|
Fl_Check_Button *always_use;
|
||||||
|
Fl_Box *txt;
|
||||||
public:
|
public:
|
||||||
|
// Create and initialize OpenWith dialog
|
||||||
OpenWith();
|
OpenWith();
|
||||||
const char* file() { return _file; }
|
|
||||||
void show(const char* pfile) {
|
// Show openwith dialog for file
|
||||||
_file=pfile;
|
// - pfile - full path to file
|
||||||
inpt->value("");
|
// - ptype - mimetype string e.g. "text/plain"
|
||||||
edelib::Window::show();
|
// - pcomment - mimetype description e.g. "Plain text document"
|
||||||
}
|
void show(const char* pfile, const char* ptype, const char* pcomment);
|
||||||
|
|
||||||
|
// This function is friend of OpenWith because it needs to access
|
||||||
|
// _type and _file
|
||||||
|
friend void openwith_ok_cb(Fl_Widget*w, void*i);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
306
efiler/Properties.cpp
Normal file
306
efiler/Properties.cpp
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
/*
|
||||||
|
* $Id$ *
|
||||||
|
* EFiler - EDE File Manager
|
||||||
|
* Part of Equinox Desktop Environment (EDE).
|
||||||
|
* Copyright (c) 2000-2007 EDE Authors.
|
||||||
|
*
|
||||||
|
* This program is licenced under terms of the
|
||||||
|
* GNU General Public Licence version 2 or newer.
|
||||||
|
* See COPYING for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// File properties window
|
||||||
|
|
||||||
|
#include "Properties.h"
|
||||||
|
|
||||||
|
#include <stdlib.h> // for free()
|
||||||
|
#include <stdio.h> // for snprintf()
|
||||||
|
#include <sys/stat.h> // for stat
|
||||||
|
#include <unistd.h> // for getuid()
|
||||||
|
#include <sys/types.h> // for getuid()
|
||||||
|
#include <pwd.h> // for getpwent()
|
||||||
|
#include <grp.h> // for getgrent()
|
||||||
|
|
||||||
|
#include <edelib/Nls.h>
|
||||||
|
|
||||||
|
#include <FL/Fl_Tabs.H>
|
||||||
|
#include <FL/Fl_Button.H>
|
||||||
|
#include <FL/Fl_Return_Button.H>
|
||||||
|
#include <FL/Fl_Check_Button.H>
|
||||||
|
#include <FL/Fl_Box.H>
|
||||||
|
#include <FL/Fl_Shared_Image.H>
|
||||||
|
#include <FL/filename.H>
|
||||||
|
#include <FL/Fl_Input.H>
|
||||||
|
#include <FL/Fl_Choice.H>
|
||||||
|
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
#define DIALOG_WIDTH 320
|
||||||
|
#define DIALOG_HEIGHT 290
|
||||||
|
|
||||||
|
|
||||||
|
void properties_cancel_cb(Fl_Widget*w, void*) {
|
||||||
|
Fl_Window* win = (Fl_Window*)w->parent();
|
||||||
|
win->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void properties_ok_cb(Fl_Widget*w, void*i) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Properties::Properties(const char* file) : edelib::Window(DIALOG_WIDTH, DIALOG_HEIGHT, _("File properties")), _file(0) {
|
||||||
|
_file=file;
|
||||||
|
set_modal();
|
||||||
|
|
||||||
|
Fl_Tabs *tabs;
|
||||||
|
Fl_Group *file_tab, *perms_tab, *progs_tab;
|
||||||
|
Fl_Button *ok_but, *canc_but;
|
||||||
|
|
||||||
|
// Create path from filename
|
||||||
|
int k=0;
|
||||||
|
char filename[FL_PATH_MAX], filepath[FL_PATH_MAX];
|
||||||
|
strncpy(filename, file, FL_PATH_MAX-1);
|
||||||
|
|
||||||
|
// Fix bug in fl_filename_name which returns nothing for directories
|
||||||
|
if (filename[strlen(filename)-1] == '/') {
|
||||||
|
filename[strlen(filename)-1]='\0';
|
||||||
|
k--;
|
||||||
|
}
|
||||||
|
const char *tmp = fl_filename_name(filename);
|
||||||
|
strcpy(filename, tmp);
|
||||||
|
|
||||||
|
k+=strlen(file)-strlen(filename);
|
||||||
|
if (k>FL_PATH_MAX-1) k=FL_PATH_MAX-1;
|
||||||
|
strncpy(filepath, file, k);
|
||||||
|
filepath[k]='\0';
|
||||||
|
|
||||||
|
|
||||||
|
// Init mimetype
|
||||||
|
mime_resolver.set(file);
|
||||||
|
|
||||||
|
// Stat for current file
|
||||||
|
bool stat_succeeded = false; // shouldn't happen
|
||||||
|
struct stat64 stat_buffer;
|
||||||
|
|
||||||
|
const char* owner_name, *group_name;
|
||||||
|
bool can_rename=false, can_chown=false, can_chmod=false;
|
||||||
|
int is_executable=0, n_owner=0, n_group=0, n_others=0;
|
||||||
|
char mode_nr[5];
|
||||||
|
|
||||||
|
int owner_uid=0, owner_gid=0;
|
||||||
|
|
||||||
|
int user_uid=getuid(), user_gid=getgid();
|
||||||
|
if (user_uid==0) can_chown=true; // FIXME
|
||||||
|
|
||||||
|
if (!stat64(file,&stat_buffer)) {
|
||||||
|
stat_succeeded = true;
|
||||||
|
owner_uid=stat_buffer.st_uid;
|
||||||
|
owner_gid=stat_buffer.st_gid;
|
||||||
|
if (owner_uid==user_uid || owner_gid==user_gid) can_chmod=true;
|
||||||
|
|
||||||
|
// Read modes
|
||||||
|
mode_t mode = stat_buffer.st_mode;
|
||||||
|
int m0=0, m1=0, m2=0, m3=0;
|
||||||
|
if (mode&S_ISUID) m0+=4; if (mode&S_ISGID) m0+=2; if (mode&S_ISVTX) m0+=1;
|
||||||
|
if (mode&S_IRUSR) m1+=4; if (mode&S_IWUSR) m1+=2; if (mode&S_IXUSR) m1+=1;
|
||||||
|
if (mode&S_IRGRP) m2+=4; if (mode&S_IWGRP) m2+=2; if (mode&S_IXGRP) m2+=1;
|
||||||
|
if (mode&S_IROTH) m3+=4; if (mode&S_IWOTH) m3+=2; if (mode&S_IXOTH) m3+=1;
|
||||||
|
snprintf(mode_nr, 5, "%d%d%d%d", m0, m1, m2, m3);
|
||||||
|
|
||||||
|
// Simple modes
|
||||||
|
if (mode&S_IXUSR) is_executable=1;
|
||||||
|
if (mode&S_IWUSR) n_owner=0;
|
||||||
|
else if (mode&S_IRUSR) n_owner=1;
|
||||||
|
else n_owner=2;
|
||||||
|
if (mode&S_IWGRP) n_group=0;
|
||||||
|
else if (mode&S_IRGRP) n_group=1;
|
||||||
|
else n_group=2;
|
||||||
|
if (mode&S_IWOTH) n_others=0;
|
||||||
|
else if (mode&S_IROTH) n_others=1;
|
||||||
|
else n_others=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stat for directory the file resides in
|
||||||
|
// Needed to see if user can rename file
|
||||||
|
if (!stat64(filepath,&stat_buffer)) {
|
||||||
|
if (stat_buffer.st_uid==user_uid || stat_buffer.st_gid==user_gid)
|
||||||
|
can_rename=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// List of users
|
||||||
|
char *users_list[65535];
|
||||||
|
for (int i=0; i<65535; i++) users_list[i]=0;
|
||||||
|
struct passwd *pwent;
|
||||||
|
setpwent();
|
||||||
|
while (pwent = getpwent()) {
|
||||||
|
if (strcmp(pwent->pw_gecos, pwent->pw_name)==0 || strlen(pwent->pw_gecos)<2) // just one char
|
||||||
|
users_list[pwent->pw_uid] = strdup(pwent->pw_name);
|
||||||
|
else
|
||||||
|
users_list[pwent->pw_uid] = tasprintf("%s (%s)", pwent->pw_gecos, pwent->pw_name);
|
||||||
|
}
|
||||||
|
endpwent();
|
||||||
|
|
||||||
|
// List of groups
|
||||||
|
char *groups_list[65535];
|
||||||
|
for (int i=0; i<65535; i++) groups_list[i]=0;
|
||||||
|
struct group *grent;
|
||||||
|
setgrent();
|
||||||
|
while (grent = getgrent()) {
|
||||||
|
groups_list[grent->gr_gid] = strdup(grent->gr_name);
|
||||||
|
}
|
||||||
|
endgrent();
|
||||||
|
|
||||||
|
// Window design
|
||||||
|
begin();
|
||||||
|
tabs = new Fl_Tabs(0, 2, w(), h()-37);
|
||||||
|
tabs->begin();
|
||||||
|
file_tab = new Fl_Group(0, 25, w(), h()-60, _("&File"));
|
||||||
|
file_tab->begin();
|
||||||
|
// Icon
|
||||||
|
if(edelib::IconTheme::inited()) {
|
||||||
|
Fl_Box *img = new Fl_Box(10, 35, 65, 65);
|
||||||
|
//img->box(FL_DOWN_BOX);
|
||||||
|
edelib::String icon = edelib::IconTheme::get(mime_resolver.icon_name().c_str(), edelib::ICON_SIZE_HUGE);
|
||||||
|
if (icon=="") icon = edelib::IconTheme::get("empty", edelib::ICON_SIZE_HUGE, edelib::ICON_CONTEXT_MIMETYPE);
|
||||||
|
Fl_Image *i = Fl_Shared_Image::get(icon.c_str());
|
||||||
|
if(i) img->image(i);
|
||||||
|
} else {
|
||||||
|
// Icon theme doesn't work!?
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filename
|
||||||
|
{
|
||||||
|
Fl_Input *fn = new Fl_Input (135, 35, w()-145, 20, _("Name:"));
|
||||||
|
if (!can_rename) {
|
||||||
|
// filename->deactivate();
|
||||||
|
// this looks prettier
|
||||||
|
fn->readonly(1);
|
||||||
|
fn->color(FL_BACKGROUND_COLOR);
|
||||||
|
}
|
||||||
|
fn->value(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Directory
|
||||||
|
{
|
||||||
|
Fl_Input *fp = new Fl_Input (135, 65, w()-145, 20, _("Location:"));
|
||||||
|
fp->readonly(1);
|
||||||
|
fp->color(FL_BACKGROUND_COLOR);
|
||||||
|
fp->value(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size
|
||||||
|
{
|
||||||
|
Fl_Box *sizelabel = new Fl_Box (75, 95, 60, 20, _("Size:"));
|
||||||
|
sizelabel->align (FL_ALIGN_RIGHT | FL_ALIGN_INSIDE);
|
||||||
|
|
||||||
|
Fl_Box *sizebox = new Fl_Box (135, 95, w()-145, 20);
|
||||||
|
sizebox->align (FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
|
||||||
|
if (stat_succeeded) sizebox->copy_label(nice_size(stat_buffer.st_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type
|
||||||
|
{
|
||||||
|
Fl_Box *typelabel = new Fl_Box (10, 125, 60, 20, _("Type:"));
|
||||||
|
typelabel->align (FL_ALIGN_RIGHT | FL_ALIGN_INSIDE);
|
||||||
|
|
||||||
|
Fl_Box *typebox = new Fl_Box (70, 125, w()-80, 20);
|
||||||
|
typebox->align (FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
|
||||||
|
typebox->copy_label(mime_resolver.type().c_str());
|
||||||
|
|
||||||
|
Fl_Box *ntypebox = new Fl_Box (70, 145, w()-80, 20);
|
||||||
|
ntypebox->align (FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
|
||||||
|
ntypebox->copy_label(mime_resolver.comment().c_str());
|
||||||
|
}
|
||||||
|
file_tab->end();
|
||||||
|
|
||||||
|
perms_tab = new Fl_Group(0, 25, w(), h()-60, _("&Permissions"));
|
||||||
|
perms_tab->begin();
|
||||||
|
// Owner
|
||||||
|
{
|
||||||
|
Fl_Choice *owner = new Fl_Choice (70, 35, w()-80, 20, _("Owner:"));
|
||||||
|
int j=-1, selected=0;
|
||||||
|
for (int i=0; i<65535; i++)
|
||||||
|
if (users_list[i]!=0) {
|
||||||
|
owner->add(users_list[i]);
|
||||||
|
free(users_list[i]);
|
||||||
|
j++;
|
||||||
|
if (i==owner_uid) selected=j;
|
||||||
|
}
|
||||||
|
owner->value(selected);
|
||||||
|
if (!can_chown) owner->deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group
|
||||||
|
{
|
||||||
|
Fl_Choice *group = new Fl_Choice (70, 65, w()-80, 20, _("Group:"));
|
||||||
|
int j=-1, selected=0;
|
||||||
|
for (int i=0; i<65535; i++)
|
||||||
|
if (groups_list[i]!=0) {
|
||||||
|
group->add(groups_list[i]);
|
||||||
|
free(groups_list[i]);
|
||||||
|
j++;
|
||||||
|
if (i==owner_gid) selected=j;
|
||||||
|
}
|
||||||
|
group->value(selected);
|
||||||
|
if (!can_chown) group->deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executable
|
||||||
|
{
|
||||||
|
Fl_Check_Button *exec = new Fl_Check_Button (10, 95, w()-20, 20, _("File is an executable program"));
|
||||||
|
if (stat_succeeded) exec->value(is_executable);
|
||||||
|
if (!can_chmod) exec->deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Owner permissions
|
||||||
|
{
|
||||||
|
Fl_Choice *ownerperms = new Fl_Choice (135, 125, w()-145, 20, _("Owner permissions:"));
|
||||||
|
ownerperms->add(_("Read and write"));
|
||||||
|
ownerperms->add(_("Read only"));
|
||||||
|
ownerperms->add(_("Not allowed"));
|
||||||
|
if (stat_succeeded) ownerperms->value(n_owner);
|
||||||
|
if (!can_chmod) ownerperms->deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group permissions
|
||||||
|
{
|
||||||
|
Fl_Choice *groupperms = new Fl_Choice (135, 155, w()-145, 20, _("Group permissions:"));
|
||||||
|
groupperms->add(_("Read and write"));
|
||||||
|
groupperms->add(_("Read only"));
|
||||||
|
groupperms->add(_("Not allowed"));
|
||||||
|
if (stat_succeeded) groupperms->value(n_group);
|
||||||
|
if (!can_chmod) groupperms->deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Others permissions
|
||||||
|
{
|
||||||
|
Fl_Choice *otherperms = new Fl_Choice (135, 185, w()-145, 20, _("Others permissions:"));
|
||||||
|
otherperms->add(_("Read and write"));
|
||||||
|
otherperms->add(_("Read only"));
|
||||||
|
otherperms->add(_("Not allowed"));
|
||||||
|
if (stat_succeeded) otherperms->value(n_others);
|
||||||
|
if (!can_chmod) otherperms->deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number
|
||||||
|
// TODO: move to advanced window
|
||||||
|
{
|
||||||
|
Fl_Input *modenr = new Fl_Input (135, 215, 50, 20, _("Mode number:"));
|
||||||
|
if (stat_succeeded) modenr->value(mode_nr);
|
||||||
|
if (!can_chmod) modenr->deactivate();
|
||||||
|
}
|
||||||
|
perms_tab->end();
|
||||||
|
|
||||||
|
progs_tab = new Fl_Group(0, 25, w(), h()-60, _("P&rograms"));
|
||||||
|
progs_tab->begin();
|
||||||
|
progs_tab->end();
|
||||||
|
tabs->end();
|
||||||
|
|
||||||
|
// Ok & Cancel buttons
|
||||||
|
ok_but = new Fl_Return_Button(w()-200, h()-30, 90, 25, "&Ok");
|
||||||
|
canc_but = new Fl_Button(w()-100, h()-30, 90, 25, "&Cancel");
|
||||||
|
ok_but->callback(properties_ok_cb);
|
||||||
|
canc_but->callback(properties_cancel_cb);
|
||||||
|
end();
|
||||||
|
}
|
40
efiler/Properties.h
Normal file
40
efiler/Properties.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* EFiler - EDE File Manager
|
||||||
|
* Part of Equinox Desktop Environment (EDE).
|
||||||
|
* Copyright (c) 2000-2007 EDE Authors.
|
||||||
|
*
|
||||||
|
* This program is licenced under terms of the
|
||||||
|
* GNU General Public Licence version 2 or newer.
|
||||||
|
* See COPYING for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// File properties window
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _Properties_h_
|
||||||
|
#define _Properties_h_
|
||||||
|
|
||||||
|
#include <edelib/Window.h>
|
||||||
|
#include <edelib/MimeType.h>
|
||||||
|
|
||||||
|
class Properties : public edelib::Window {
|
||||||
|
private:
|
||||||
|
const char* _file;
|
||||||
|
|
||||||
|
// We need our own MIME resolver
|
||||||
|
edelib::MimeType mime_resolver;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Construct window
|
||||||
|
Properties(const char* file);
|
||||||
|
|
||||||
|
// This function is friend of Properties because it needs to access
|
||||||
|
// values of various widgets
|
||||||
|
friend void properties_ok_cb(Fl_Widget*w, void*i);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -46,6 +46,7 @@
|
|||||||
#include "EDE_DirTree.h" // directory tree
|
#include "EDE_DirTree.h" // directory tree
|
||||||
#include "Util.h" // ex-edelib
|
#include "Util.h" // ex-edelib
|
||||||
#include "OpenWith.h" // Open with... window
|
#include "OpenWith.h" // Open with... window
|
||||||
|
#include "Properties.h" // File properties window
|
||||||
|
|
||||||
#include "fileops.h" // file operations
|
#include "fileops.h" // file operations
|
||||||
#include "filesystem.h" // filesystem support
|
#include "filesystem.h" // filesystem support
|
||||||
@ -496,12 +497,22 @@ void file_open(const char* path, MailcapAction action) {
|
|||||||
fprintf (stderr, "run_program: %s\n", o2);
|
fprintf (stderr, "run_program: %s\n", o2);
|
||||||
|
|
||||||
if (action == MAILCAP_EXEC) {
|
if (action == MAILCAP_EXEC) {
|
||||||
|
// File is an executable - run it
|
||||||
int k=edelib::run_program(path,false); fprintf(stderr, "Xretval: %d\n", k);
|
int k=edelib::run_program(path,false); fprintf(stderr, "Xretval: %d\n", k);
|
||||||
|
} else if (mime_resolver.type() == "application/x-executable") {
|
||||||
|
edelib::MessageBox mb;
|
||||||
|
mb.label(_("Warning"));
|
||||||
|
mb.set_text(tsprintf(_("The file \"%s\" is an executable program. Do you want to run it? It might be a virus!"), fl_filename_name(path)));
|
||||||
|
mb.set_theme_icon(MSGBOX_ICON_WARNING);
|
||||||
|
mb.add_button(_("&No"), edelib::MSGBOX_BUTTON_RETURN);
|
||||||
|
mb.add_button(_("&Yes"));
|
||||||
|
int k=mb.run();
|
||||||
|
if (k==1) k=edelib::run_program(path,false); fprintf(stderr, "Xretval: %d\n", k);
|
||||||
} else if (opener) {
|
} else if (opener) {
|
||||||
int k=edelib::run_program(o2,false); fprintf(stderr, "retval: %d\n", k);
|
int k=edelib::run_program(o2,false); fprintf(stderr, "retval: %d\n", k);
|
||||||
} else {
|
} else {
|
||||||
statusbar->copy_label(tsprintf(_("No program to open %s! (%s)"), fl_filename_name(path),mime_resolver.type().c_str()));
|
// Show "Open with..." dialog
|
||||||
// TODO: open with...
|
ow->show(path, mime_resolver.type().c_str(), mime_resolver.type().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dumpcore_on_exec) {
|
if (dumpcore_on_exec) {
|
||||||
@ -549,11 +560,9 @@ void open_cb(Fl_Widget*w, void*data) {
|
|||||||
// TODO: make a list of openers etc.
|
// TODO: make a list of openers etc.
|
||||||
void openwith_cb(Fl_Widget*, void*) {
|
void openwith_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());
|
const char* file = view->path(view->get_focus());
|
||||||
// edelib::run_program(tsprintf("%s '%s'", app, file), /*wait=*/false);
|
mime_resolver.set(file);
|
||||||
ow->show(file);
|
ow->show(file, mime_resolver.type().c_str(), mime_resolver.comment().c_str());
|
||||||
// Fl::run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// File > New (efiler window)
|
// File > New (efiler window)
|
||||||
@ -681,7 +690,11 @@ void fileprint_cb(Fl_Widget*w, void*) {
|
|||||||
void fileexec_cb(Fl_Widget*w, void*) {
|
void fileexec_cb(Fl_Widget*w, void*) {
|
||||||
file_open(view->path(view->get_focus()), MAILCAP_EXEC);
|
file_open(view->path(view->get_focus()), MAILCAP_EXEC);
|
||||||
}
|
}
|
||||||
void pref_cb(Fl_Widget*, void*) { fprintf(stderr, "callback\n"); }
|
void props_cb(Fl_Widget*, void*) {
|
||||||
|
Properties p(view->path(view->get_focus()));
|
||||||
|
p.show();
|
||||||
|
Fl::run();
|
||||||
|
}
|
||||||
// Other options use callbacks from Edit menu
|
// Other options use callbacks from Edit menu
|
||||||
|
|
||||||
|
|
||||||
@ -926,7 +939,7 @@ Fl_Menu_Item main_menu_definition[] = {
|
|||||||
{_("&Paste"), FL_CTRL+'v', paste_cb},
|
{_("&Paste"), FL_CTRL+'v', paste_cb},
|
||||||
{_("&Rename"), FL_F+2, viewrename_cb},
|
{_("&Rename"), FL_F+2, viewrename_cb},
|
||||||
{_("&Delete"), FL_Delete, delete_cb, 0, FL_MENU_DIVIDER},
|
{_("&Delete"), FL_Delete, delete_cb, 0, FL_MENU_DIVIDER},
|
||||||
{_("Pre&ferences"), FL_CTRL+'p', pref_cb},
|
{_("Prop&erties"), FL_CTRL+'p', props_cb},
|
||||||
{0},
|
{0},
|
||||||
|
|
||||||
{_("&View"), 0, 0, 0, FL_SUBMENU},
|
{_("&View"), 0, 0, 0, FL_SUBMENU},
|
||||||
@ -969,13 +982,13 @@ Fl_Menu_Item context_menu_definition[] = {
|
|||||||
{_("&View"), 0, open_cb, 0, FL_MENU_INVISIBLE},
|
{_("&View"), 0, open_cb, 0, FL_MENU_INVISIBLE},
|
||||||
{_("&Edit"), 0, fileedit_cb, 0, FL_MENU_INVISIBLE},
|
{_("&Edit"), 0, fileedit_cb, 0, FL_MENU_INVISIBLE},
|
||||||
{_("Pri&nt"), 0, fileprint_cb, 0, FL_MENU_INVISIBLE},
|
{_("Pri&nt"), 0, fileprint_cb, 0, FL_MENU_INVISIBLE},
|
||||||
{_("&Execute"), 0, fileexec_cb, 0,FL_MENU_INVISIBLE},
|
{_("&Execute"), 0, fileexec_cb, 0, FL_MENU_INVISIBLE},
|
||||||
{_("Open &with..."), 0, openwith_cb, 0,FL_MENU_DIVIDER},
|
{_("Open &with..."), 0, openwith_cb, 0, FL_MENU_DIVIDER},
|
||||||
{_("&Cut"), 0, cut_cb},
|
{_("&Cut"), 0, cut_cb},
|
||||||
{_("Co&py"), 0, copy_cb},
|
{_("Co&py"), 0, copy_cb},
|
||||||
{_("Pa&ste"), 0, paste_cb},
|
{_("Pa&ste"), 0, paste_cb},
|
||||||
{_("&Delete"), 0, delete_cb, 0,FL_MENU_DIVIDER},
|
{_("&Delete"), 0, delete_cb, 0, FL_MENU_DIVIDER},
|
||||||
{_("P&references..."), 0, pref_cb},
|
{_("P&roperties..."), 0, props_cb},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,6 +35,13 @@
|
|||||||
// FIXME: use favourite aplications to find xterm
|
// FIXME: use favourite aplications to find xterm
|
||||||
#define TERM "xterm"
|
#define TERM "xterm"
|
||||||
|
|
||||||
|
// Maximum length of a mailcap spec
|
||||||
|
// We could've used edelib::String, but that would make the whole code a bit
|
||||||
|
// more complex and a bit slower. There's no reason for mailcap to be longer
|
||||||
|
// (very long mailcaps are usually application specific codes /e.g. mutt/ which
|
||||||
|
// isn't useful to us)
|
||||||
|
#define BUFLEN 1000
|
||||||
|
|
||||||
|
|
||||||
using namespace edelib; // this drastically shortened the code...
|
using namespace edelib; // this drastically shortened the code...
|
||||||
|
|
||||||
@ -45,9 +52,15 @@ struct mime_db_struct {
|
|||||||
String createcmd;
|
String createcmd;
|
||||||
String editcmd;
|
String editcmd;
|
||||||
String printcmd;
|
String printcmd;
|
||||||
|
bool copiousoutput;
|
||||||
|
bool needsterminal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// database of parsed mimetypes
|
||||||
list<mime_db_struct> mime_db;
|
list<mime_db_struct> mime_db;
|
||||||
|
|
||||||
|
// flag to know if we should call read_files()
|
||||||
bool files_read=false;
|
bool files_read=false;
|
||||||
|
|
||||||
|
|
||||||
@ -56,9 +69,9 @@ bool files_read=false;
|
|||||||
|
|
||||||
String mailcap_sanitize(char* cmd, String type) {
|
String mailcap_sanitize(char* cmd, String type) {
|
||||||
String s(cmd);
|
String s(cmd);
|
||||||
unsigned int k = s.find("%s");
|
|
||||||
|
|
||||||
// no %s, file should be piped to stdin
|
// no %s, file should be piped to stdin
|
||||||
|
unsigned int k = s.find("%s");
|
||||||
if (k==String::npos) {
|
if (k==String::npos) {
|
||||||
s = String("cat '%s' | ") + cmd;
|
s = String("cat '%s' | ") + cmd;
|
||||||
} else {
|
} else {
|
||||||
@ -87,12 +100,14 @@ String mailcap_sanitize(char* cmd, String type) {
|
|||||||
s = s.substr(0,k) + s.substr(k+2);
|
s = s.substr(0,k) + s.substr(k+2);
|
||||||
k = s.find("}",k); // there has to be a closing brace...
|
k = s.find("}",k); // there has to be a closing brace...
|
||||||
if (k!=String::npos) s= s.substr(0,k) + s.substr(k+1);
|
if (k!=String::npos) s= s.substr(0,k) + s.substr(k+1);
|
||||||
k = s.find("%{",k);
|
k = s.find("%{",k+1);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Read contents of mailcap file
|
||||||
|
|
||||||
void read_files() {
|
void read_files() {
|
||||||
list<String> locations;
|
list<String> locations;
|
||||||
|
|
||||||
@ -100,7 +115,7 @@ void read_files() {
|
|||||||
stringtok(locations, String(MAILCAPS), ":");
|
stringtok(locations, String(MAILCAPS), ":");
|
||||||
// Add ~/.mailcap
|
// Add ~/.mailcap
|
||||||
locations.push_front(dir_home() + E_DIR_SEPARATOR_STR".mailcap");
|
locations.push_front(dir_home() + E_DIR_SEPARATOR_STR".mailcap");
|
||||||
// Add EDE specific configuracion
|
// Add EDE specific configuration
|
||||||
if (user_config_dir() != "")
|
if (user_config_dir() != "")
|
||||||
locations.push_front(user_config_dir() + E_DIR_SEPARATOR_STR"ede"E_DIR_SEPARATOR_STR"mailcap");
|
locations.push_front(user_config_dir() + E_DIR_SEPARATOR_STR"ede"E_DIR_SEPARATOR_STR"mailcap");
|
||||||
|
|
||||||
@ -120,8 +135,8 @@ void read_files() {
|
|||||||
|
|
||||||
// Read data into list
|
// Read data into list
|
||||||
FILE *fp = fopen(mailcap,"r");
|
FILE *fp = fopen(mailcap,"r");
|
||||||
char buffer[1000];
|
char buffer[BUFLEN];
|
||||||
while (fgets(buffer,1000,fp)) {
|
while (fgets(buffer,BUFLEN,fp)) {
|
||||||
str_trim(buffer);
|
str_trim(buffer);
|
||||||
if (buffer[0]=='#') continue; //comment
|
if (buffer[0]=='#') continue; //comment
|
||||||
if (strlen(buffer)<2) continue; //empty line
|
if (strlen(buffer)<2) continue; //empty line
|
||||||
@ -129,15 +144,15 @@ void read_files() {
|
|||||||
// Multiline
|
// Multiline
|
||||||
if (buffer[strlen(buffer)-1]=='\\') {
|
if (buffer[strlen(buffer)-1]=='\\') {
|
||||||
String line(buffer); //Use string for dynamic growing
|
String line(buffer); //Use string for dynamic growing
|
||||||
while (fgets(buffer,1000,fp)) {
|
while (fgets(buffer,BUFLEN,fp)) {
|
||||||
str_trim(buffer);
|
str_trim(buffer);
|
||||||
line = line.substr(0, line.length()-2);
|
line = line.substr(0, line.length()-2);
|
||||||
line += buffer;
|
line += buffer;
|
||||||
if (buffer[strlen(buffer)-1]!='\\') break;
|
if (buffer[strlen(buffer)-1]!='\\') break;
|
||||||
}
|
}
|
||||||
// Use just the first 1000 chars
|
// Use just the first BUFLEN chars
|
||||||
strncpy(buffer, line.c_str(), 1000);
|
strncpy(buffer, line.c_str(), BUFLEN);
|
||||||
buffer[999]='\0';
|
buffer[BUFLEN]='\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse line
|
// Parse line
|
||||||
@ -146,20 +161,20 @@ void read_files() {
|
|||||||
str_trim(tmp);
|
str_trim(tmp);
|
||||||
parsed.type=tmp;
|
parsed.type=tmp;
|
||||||
|
|
||||||
// View command
|
// Command for viewing file
|
||||||
tmp = strtok(NULL, ";");
|
tmp = strtok(NULL, ";");
|
||||||
if (tmp==NULL) continue; // no view cmd in line!?
|
if (tmp==NULL) continue; // no view cmd in line!?
|
||||||
str_trim(tmp);
|
str_trim(tmp);
|
||||||
parsed.viewcmd = mailcap_sanitize(tmp, parsed.type);
|
parsed.viewcmd = mailcap_sanitize(tmp, parsed.type);
|
||||||
|
|
||||||
// Other mailcap parameters...
|
// Other mailcap parameters...
|
||||||
|
parsed.copiousoutput = parsed.needsterminal = false;
|
||||||
while ((tmp = strtok(NULL, ";")) != NULL) {
|
while ((tmp = strtok(NULL, ";")) != NULL) {
|
||||||
str_trim(tmp);
|
str_trim(tmp);
|
||||||
if (strcmp(tmp,"copiousoutput")==0)
|
if (strcmp(tmp,"copiousoutput")==0)
|
||||||
// TODO: use enotepad? when it supports stdin
|
parsed.copiousoutput = true;
|
||||||
parsed.viewcmd = TERM" -e \"" + parsed.viewcmd + " | less\"";
|
|
||||||
else if (strcmp(tmp,"needsterminal")==0)
|
else if (strcmp(tmp,"needsterminal")==0)
|
||||||
parsed.viewcmd = TERM" -e \"" + parsed.viewcmd + "\"";
|
parsed.needsterminal = true;
|
||||||
else if (strncmp(tmp,"compose=",8)==0)
|
else if (strncmp(tmp,"compose=",8)==0)
|
||||||
parsed.createcmd = mailcap_sanitize(tmp+8, parsed.type);
|
parsed.createcmd = mailcap_sanitize(tmp+8, parsed.type);
|
||||||
else if (strncmp(tmp,"print=",6)==0)
|
else if (strncmp(tmp,"print=",6)==0)
|
||||||
@ -175,6 +190,9 @@ void read_files() {
|
|||||||
files_read=true;
|
files_read=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Helper function for searching mime_db
|
||||||
|
|
||||||
list<mime_db_struct>::iterator find_type(const char* type) {
|
list<mime_db_struct>::iterator find_type(const char* type) {
|
||||||
list<mime_db_struct>::iterator it = mime_db.begin(), it_end = mime_db.end();
|
list<mime_db_struct>::iterator it = mime_db.begin(), it_end = mime_db.end();
|
||||||
for(; it != it_end; ++it)
|
for(; it != it_end; ++it)
|
||||||
@ -189,17 +207,36 @@ list<mime_db_struct>::iterator find_type(const char* type) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Command for performing given action on files of given type
|
||||||
|
|
||||||
const char* mailcap_opener(const char* type, MailcapAction action) {
|
const char* mailcap_opener(const char* type, MailcapAction action) {
|
||||||
|
static char buffer[BUFLEN];
|
||||||
if (!files_read) read_files();
|
if (!files_read) read_files();
|
||||||
list<mime_db_struct>::iterator it = find_type(type);
|
list<mime_db_struct>::iterator it = find_type(type);
|
||||||
if (it==0) return 0;
|
if (it==0) return 0;
|
||||||
if (action==MAILCAP_VIEW) return (*it).viewcmd.c_str();
|
|
||||||
|
if (action==MAILCAP_VIEW) {
|
||||||
|
const char *c = (*it).viewcmd.c_str();
|
||||||
|
if ((*it).copiousoutput) {
|
||||||
|
// copiousoutput and needsterminal are mutually exclusive [2]
|
||||||
|
// TODO: use enotepad? - when it supports stdin
|
||||||
|
snprintf(buffer, BUFLEN-1, TERM" -e \"%s\" | less", c);
|
||||||
|
} else if ((*it).needsterminal) {
|
||||||
|
snprintf(buffer, BUFLEN-1, TERM" -e \"%s\"", c);
|
||||||
|
} else return c;
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
else if (action==MAILCAP_CREATE) return (*it).createcmd.c_str();
|
else if (action==MAILCAP_CREATE) return (*it).createcmd.c_str();
|
||||||
else if (action==MAILCAP_EDIT) return (*it).editcmd.c_str();
|
else if (action==MAILCAP_EDIT) return (*it).editcmd.c_str();
|
||||||
else if (action==MAILCAP_PRINT) return (*it).printcmd.c_str();
|
else if (action==MAILCAP_PRINT) return (*it).printcmd.c_str();
|
||||||
else return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// List of actions available for given type
|
||||||
|
|
||||||
int mailcap_actions(const char* type) {
|
int mailcap_actions(const char* type) {
|
||||||
if (!files_read) read_files();
|
if (!files_read) read_files();
|
||||||
list<mime_db_struct>::iterator it = find_type(type);
|
list<mime_db_struct>::iterator it = find_type(type);
|
||||||
@ -211,3 +248,62 @@ int mailcap_actions(const char* type) {
|
|||||||
if ((*it).printcmd != "") result += MAILCAP_PRINT;
|
if ((*it).printcmd != "") result += MAILCAP_PRINT;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Add a new opener for given type
|
||||||
|
// NOTE: This will be written in EDE-specific location. If EDE-specific
|
||||||
|
// mailcap file doesn't exist, it will be created and existing mimetypes
|
||||||
|
// will be added. Thus, users of EDE will get a new type in addition to
|
||||||
|
// old ones, however other applications will not.
|
||||||
|
|
||||||
|
void mailcap_add_type(const char* type, const char* opener) {
|
||||||
|
// Find old type, edit if it exists
|
||||||
|
list<mime_db_struct>::iterator it = find_type(type);
|
||||||
|
if (it != 0) {
|
||||||
|
(*it).viewcmd = opener;
|
||||||
|
(*it).viewcmd += " %s";
|
||||||
|
} else {
|
||||||
|
mime_db_struct newtype;
|
||||||
|
newtype.type = type;
|
||||||
|
newtype.viewcmd = opener;
|
||||||
|
newtype.viewcmd += " %s";
|
||||||
|
newtype.createcmd = "";
|
||||||
|
newtype.editcmd = "";
|
||||||
|
newtype.printcmd = "";
|
||||||
|
newtype.copiousoutput = false;
|
||||||
|
newtype.needsterminal = false;
|
||||||
|
mime_db.push_back(newtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write mime_db contents to file
|
||||||
|
String ede_mailcap = user_config_dir() + E_DIR_SEPARATOR_STR"ede"E_DIR_SEPARATOR_STR"mailcap";
|
||||||
|
FILE *fp = fopen(ede_mailcap.c_str(),"w");
|
||||||
|
|
||||||
|
it = mime_db.begin();
|
||||||
|
list<mime_db_struct>::iterator it_end = mime_db.end();
|
||||||
|
while (it != it_end) {
|
||||||
|
char buffer[BUFLEN];
|
||||||
|
snprintf(buffer, BUFLEN-1, "%s; %s", (*it).type.c_str(), (*it).viewcmd.c_str());
|
||||||
|
if ((*it).createcmd != "") {
|
||||||
|
strncat(buffer, "; compose=", BUFLEN-1-strlen(buffer));
|
||||||
|
strncat(buffer, (*it).createcmd.c_str(), BUFLEN-1-strlen(buffer));
|
||||||
|
}
|
||||||
|
if ((*it).editcmd != "") {
|
||||||
|
strncat(buffer, "; edit=", BUFLEN-1-strlen(buffer));
|
||||||
|
strncat(buffer, (*it).editcmd.c_str(), BUFLEN-1-strlen(buffer));
|
||||||
|
}
|
||||||
|
if ((*it).printcmd != "") {
|
||||||
|
strncat(buffer, "; print=", BUFLEN-1-strlen(buffer));
|
||||||
|
strncat(buffer, (*it).printcmd.c_str(), BUFLEN-1-strlen(buffer));
|
||||||
|
}
|
||||||
|
if (strlen(buffer)>BUFLEN-2)
|
||||||
|
// Even if line is too long, we don't want to mangle the next one
|
||||||
|
buffer[strlen(buffer)-1]='\n';
|
||||||
|
else
|
||||||
|
strcat(buffer, "\n");
|
||||||
|
fputs(buffer, fp);
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -28,7 +28,6 @@ enum MailcapAction {
|
|||||||
// with filename. Parameter MAILCAP_TYPE indicates the type of action to
|
// with filename. Parameter MAILCAP_TYPE indicates the type of action to
|
||||||
// be performed
|
// be performed
|
||||||
|
|
||||||
|
|
||||||
const char* mailcap_opener(const char* type, MailcapAction action=MAILCAP_VIEW);
|
const char* mailcap_opener(const char* type, MailcapAction action=MAILCAP_VIEW);
|
||||||
|
|
||||||
|
|
||||||
@ -37,4 +36,9 @@ const char* mailcap_opener(const char* type, MailcapAction action=MAILCAP_VIEW);
|
|||||||
int mailcap_actions(const char* type);
|
int mailcap_actions(const char* type);
|
||||||
|
|
||||||
|
|
||||||
|
// Add new type to the list of actions
|
||||||
|
|
||||||
|
void mailcap_add_type(const char* type, const char* opener);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user