mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
- Beggining of dnd support
- Click on selected item to rename - Fix problems reported by Valgrind
This commit is contained in:
parent
67cc5824ec
commit
87ef0c5509
@ -118,6 +118,10 @@ void EDE_Browser::sort(int column, SortType type, bool reverse) {
|
||||
int hlen=strlen(h);
|
||||
char colchar = Fl_Icon_Browser::column_char();
|
||||
|
||||
// FIXME sort() shouldn't call column_header() because that calls show_header() and that
|
||||
// deletes all buttons from header (so they could be recreated). This cause valgrind errors
|
||||
// since sort is called in button callback - you can't delete a widget in its own callback
|
||||
|
||||
// Remove old sort direction symbol (if any) from header
|
||||
char *delim = 0;
|
||||
int col=0;
|
||||
@ -125,7 +129,7 @@ void EDE_Browser::sort(int column, SortType type, bool reverse) {
|
||||
bool found=false;
|
||||
while (delim=strchr(h, colchar)) {
|
||||
if (col==sort_column) {
|
||||
strncpy(delim-SYMLEN+1,delim,strlen(delim)+1);
|
||||
for (int i=0; i<=strlen(delim); i++) delim[i-SYMLEN+1]=delim[i];
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
@ -211,8 +215,6 @@ EDE_Browser::EDE_Browser(int X,int Y,int W,int H,const char *L) : Fl_Icon_Browse
|
||||
totalwidth_(0), column_header_(0), sort_column(0), sort_type(NO_SORT), sort_direction(false) {
|
||||
|
||||
|
||||
fprintf (stderr, "ctor(%d,%d,%d,%d)\n",X,Y,W,H);
|
||||
|
||||
heading = new Heading(X,Y,W,buttonheight);
|
||||
heading->end();
|
||||
heading->hide();
|
||||
@ -236,10 +238,20 @@ fprintf (stderr, "ctor(%d,%d,%d,%d)\n",X,Y,W,H);
|
||||
}
|
||||
|
||||
|
||||
// Deallocate all memory used by header labels
|
||||
void EDE_Browser::cleanup_header() {
|
||||
// Deallocate old button labels
|
||||
for (int i=0; i<heading->children(); i++) {
|
||||
char *l = (char*)heading->child(i)->label();
|
||||
if (l && l[0]!='\0') free(l);
|
||||
}
|
||||
heading->clear();
|
||||
}
|
||||
|
||||
//make buttons invisible
|
||||
void EDE_Browser::hide_header() {
|
||||
if (heading->visible()) resize(x(),y()-buttonheight,w(),h()+buttonheight);
|
||||
heading->clear();
|
||||
cleanup_header();
|
||||
heading->hide();
|
||||
}
|
||||
|
||||
@ -248,7 +260,7 @@ void EDE_Browser::show_header() {
|
||||
int button_x=0;
|
||||
char *hdr = column_header_;
|
||||
const int* l = Fl_Icon_Browser::column_widths();
|
||||
heading->clear();
|
||||
cleanup_header();
|
||||
for (int i=0; i==0||l[i-1]; i++) {
|
||||
// If the button is last, calculate size
|
||||
int button_w = l[i];
|
||||
@ -278,7 +290,6 @@ void EDE_Browser::show_header() {
|
||||
hdr=delim+1; // next field
|
||||
}
|
||||
}
|
||||
fprintf (stderr, "showheader calls resize(%d,%d,%d,%d)\n",x(),y(),w(),h());
|
||||
if (!heading->visible()) resize(x(),y()+buttonheight,w(),h()-buttonheight);
|
||||
heading->resizable(0); // We will resize the heading and individual buttons manually
|
||||
heading->show();
|
||||
@ -293,17 +304,19 @@ void EDE_Browser::column_widths(const int* l) {
|
||||
// if (total>=scroll->w()) {
|
||||
// Fl_Icon_Browser::size(total,h());
|
||||
// }
|
||||
fprintf(stderr, "Total width is: %d\n", totalwidth_);
|
||||
// If there was heading before, regenerate
|
||||
if (heading->visible())
|
||||
heading->size(totalwidth_,buttonheight);
|
||||
// show_header();
|
||||
|
||||
// Second array for the Fl_Browser
|
||||
int *tmp = new int[i]; // FIXME: Someone should cleanup this memory sometimes...
|
||||
static int *tmp = 0;
|
||||
if (tmp) delete[] tmp;
|
||||
tmp=new int[i]; // FIXME: Dtor should cleanup this memory
|
||||
for (int j=0; j<i-1; j++) tmp[j]=l[j];
|
||||
tmp[i-1]=0;
|
||||
Fl_Icon_Browser::column_widths(tmp);
|
||||
// delete[] tmp; -- can't do this, browser goes berserk
|
||||
|
||||
// Redraw parent so we don't get ugly artifacts after shrinking last button
|
||||
// Doesn't work anymore!
|
||||
@ -315,7 +328,9 @@ const int* EDE_Browser::column_widths() const {
|
||||
const int *l=Fl_Icon_Browser::column_widths();
|
||||
for (i=0; l[i]; i++) total+=l[i];
|
||||
|
||||
int *tmp = new int[i+2]; // FIXME: Someone should cleanup this memory sometimes...
|
||||
static int *tmp = 0;
|
||||
if (tmp) delete[] tmp;
|
||||
tmp=new int[i+2]; // FIXME: Someone should cleanup this memory sometimes...
|
||||
for (int j=0; l[j]; j++) tmp[j]=l[j];
|
||||
|
||||
tmp[i]=(totalwidth_-total);
|
||||
@ -521,7 +536,7 @@ int EDE_Browser::Heading::handle(int event) {
|
||||
EDE_Browser*b = (EDE_Browser*)parent();
|
||||
b->column_widths(columns);
|
||||
b->redraw(); // OPTIMIZE (some smart damage in column_widths() ?)
|
||||
free(columns);
|
||||
delete[] columns;
|
||||
|
||||
// There will be many RELEASE events, so we update sx (used when calculating dx)
|
||||
sx=Fl::event_x();
|
||||
|
@ -81,6 +81,7 @@ private:
|
||||
SortType sort_type;
|
||||
bool sort_direction;
|
||||
|
||||
void cleanup_header();
|
||||
void hide_header();
|
||||
void show_header();
|
||||
|
||||
@ -92,6 +93,7 @@ public:
|
||||
|
||||
~EDE_Browser() {
|
||||
delete[] column_sort_types_;
|
||||
cleanup_header();
|
||||
delete heading;
|
||||
// delete scroll;
|
||||
delete hscrollbar;
|
||||
|
@ -40,86 +40,10 @@ struct FileItem {
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
/*// Event handler for EditBox
|
||||
int EditBox::handle(int event) {
|
||||
if (!this->visible()) return parent()->handle(event);
|
||||
bool above=false;
|
||||
//fprintf(stderr,"Editbox event: %d (%s)\n",event,event_name(event));
|
||||
|
||||
// Change filename
|
||||
if (event==KEY && (event_key()==ReturnKey || event_key()==KeypadEnter)) {
|
||||
// split old filename to path and file
|
||||
char path[PATH_MAX], file[PATH_MAX];
|
||||
strcpy(path, (char*)editing_->user_data());
|
||||
if (path[strlen(path)-1] == '/') path[strlen(path)-1]='\0';
|
||||
char *p = strrchr(path,'/');
|
||||
if (p==0 || *p=='\0') {
|
||||
strcpy(file,path);
|
||||
path[0]='\0';
|
||||
} else { // usual case
|
||||
p++;
|
||||
strcpy(file,p);
|
||||
*p='\0';
|
||||
}
|
||||
|
||||
if (strlen(file)!=strlen(text()) || strcmp(file,text())!=0) {
|
||||
// Create new filename
|
||||
strncat(path, text(), PATH_MAX-strlen(path));
|
||||
char oldname[PATH_MAX];
|
||||
strcpy(oldname, (char*)editing_->user_data());
|
||||
if (rename(oldname, path) == -1) {
|
||||
alert(tsprintf(_("Could not rename file! Error was:\n\t%s"), strerror(errno)));
|
||||
} else {
|
||||
// Update browser
|
||||
free(editing_->user_data());
|
||||
editing_->user_data(strdup(path));
|
||||
const char* l = editing_->label();
|
||||
editing_->label(tasprintf("%s%s",text(),strchr(l, '\t')));
|
||||
}
|
||||
}
|
||||
|
||||
above=true;
|
||||
}
|
||||
|
||||
// Hide editbox
|
||||
if (above || ( event==KEY && event_key()==EscapeKey ) ) {
|
||||
this->hide();
|
||||
return 1;
|
||||
}
|
||||
Input::handle(event);
|
||||
}
|
||||
|
||||
|
||||
// We override hide method to ensure certain things done
|
||||
void EditBox::hide() {
|
||||
Input::hide();
|
||||
// Remove box so it doesn't get in the way
|
||||
this->x(0);
|
||||
this->y(0);
|
||||
this->w(0);
|
||||
this->h(0);
|
||||
// Return the browser item into "visible" state
|
||||
if (editing_) {
|
||||
editing_->textcolor(textcolor());
|
||||
editing_->redraw();
|
||||
parent()->take_focus();
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Type for rename_callback
|
||||
// I don't know how to do this without creating a new type :(
|
||||
typedef void (my_callback)(const char*);
|
||||
typedef void (rename_callback_type)(const char*);
|
||||
typedef void (paste_callback_type)(const char*,const char*);
|
||||
|
||||
|
||||
|
||||
@ -164,17 +88,20 @@ private:
|
||||
|
||||
return 1; // don't send keys to view
|
||||
}
|
||||
if (e==FL_MOUSEWHEEL && visible()) view->hide_editbox();
|
||||
return Fl_Input::handle(e);
|
||||
}
|
||||
}* editbox_;
|
||||
int editbox_row;
|
||||
|
||||
my_callback* rename_callback_;
|
||||
rename_callback_type* rename_callback_;
|
||||
paste_callback_type* dnd_callback_;
|
||||
|
||||
// show editbox at specified row and make the row "invisible" (bgcolor same as fgcolor)
|
||||
void show_editbox(int row) {
|
||||
if (!rename_callback_) return;
|
||||
if (row<1 || row>size()) return; // nothing selected
|
||||
if (strcmp(text(row), "..")==0) return; // can't rename "go up" button
|
||||
if (text(row)[0]=='.' && text(row)[1]=='.' && text(row)[2]==column_char()) return; // can't rename "go up" button
|
||||
|
||||
// unselect the row with focus - it's prettier that way
|
||||
select(row,0);
|
||||
@ -229,7 +156,37 @@ private:
|
||||
//hide_editbox();
|
||||
}
|
||||
|
||||
|
||||
// Bucket class is used to prevent memleaks
|
||||
// It stores pointers to allocated memory that will be cleaned up later
|
||||
// Just remember to call empty() when needed - everything else is automatic :)
|
||||
class Bucket {
|
||||
void** items;
|
||||
int size, capacity;
|
||||
public:
|
||||
Bucket() : size(0), capacity(1000), items((void**)malloc(sizeof(void*)*1000)) {
|
||||
for (int i=0; i<capacity; i++) items[i]=0;
|
||||
}
|
||||
~Bucket() { empty(); free(items); }
|
||||
void add(void* p) {
|
||||
if (size>=capacity) {
|
||||
capacity+=1000;
|
||||
items = (void**)realloc(items,sizeof(void*)*capacity);
|
||||
for (int i=capacity-1000; i<capacity; i++)
|
||||
items[i]=0;
|
||||
}
|
||||
items[size++]=p;
|
||||
}
|
||||
void empty() {
|
||||
for (int i=0; i<size; i++) {
|
||||
if (items[i]) free(items[i]);
|
||||
items[i]=0;
|
||||
}
|
||||
size=0;
|
||||
}
|
||||
void debug() {
|
||||
fprintf(stderr, "Bucket size %d, capacity %d\n", size, capacity);
|
||||
}
|
||||
} bucket;
|
||||
|
||||
public:
|
||||
FileDetailsView(int X, int Y, int W, int H, char*label=0) : EDE_Browser(X,Y,W,H,label) {
|
||||
@ -255,6 +212,9 @@ public:
|
||||
editbox_->parent(this);
|
||||
editbox_->textsize(12); // FIXME: hack for font size
|
||||
editbox_->hide();
|
||||
|
||||
rename_callback_ = 0;
|
||||
dnd_callback_ = 0;
|
||||
}
|
||||
// ~FileDetailsView() { delete browser; }
|
||||
|
||||
@ -262,7 +222,9 @@ public:
|
||||
// Construct browser line
|
||||
edelib::String value;
|
||||
value = item->name+"\t"+item->description+"\t"+item->size+"\t"+item->date+"\t"+item->permissions;
|
||||
EDE_Browser::insert(row, value.c_str(), strdup(item->realpath.c_str())); // put realpath into data
|
||||
char* realpath = strdup(item->realpath.c_str());
|
||||
EDE_Browser::insert(row, value.c_str(), realpath); // put realpath into data
|
||||
bucket.add(realpath);
|
||||
fprintf (stderr, "value: %s\n", value.c_str());
|
||||
|
||||
// Get icon
|
||||
@ -278,24 +240,42 @@ fprintf (stderr, "value: %s\n", value.c_str());
|
||||
int row = findrow(item->realpath);
|
||||
if (row) EDE_Browser::remove(row);
|
||||
}
|
||||
void remove(int row) { EDE_Browser::remove(row); } // why???
|
||||
void update(FileItem *item) {
|
||||
int row=findrow(item->realpath);
|
||||
if (row==0) return;
|
||||
EDE_Browser::remove(row);
|
||||
insert(row, item);
|
||||
// FIXME: this will lose focus, making it impossible to click on something while
|
||||
|
||||
//EDE_Browser::remove(row);
|
||||
//insert(row, item);
|
||||
// this was reimplemented because a) it's unoptimized, b) adds stuff at the end,
|
||||
// c) causes browser to lose focus, making it impossible to click on something while
|
||||
// directory is loading
|
||||
|
||||
|
||||
edelib::String value;
|
||||
value = item->name+"\t"+item->description+"\t"+item->size+"\t"+item->date+"\t"+item->permissions;
|
||||
char* realpath = strdup(item->realpath.c_str());
|
||||
text(row, value.c_str());
|
||||
data(row, realpath);
|
||||
bucket.add(realpath);
|
||||
fprintf (stderr, "value: %s\n", value.c_str());
|
||||
|
||||
// Get icon
|
||||
edelib::String icon = edelib::IconTheme::get(item->icon.c_str(),edelib::ICON_SIZE_TINY);
|
||||
if (icon=="") icon = edelib::IconTheme::get("misc",edelib::ICON_SIZE_TINY,edelib::ICON_CONTEXT_MIMETYPE);
|
||||
set_icon(row, Fl_Shared_Image::get(icon.c_str()));
|
||||
}
|
||||
|
||||
// Change color of row to gray
|
||||
void gray(int row) {
|
||||
if (text(row)[0] == '@' && text(row)[1] == 'C') return; // already greyed
|
||||
|
||||
char *ntext = (char*)malloc(sizeof(char)*strlen(text(row))+4); // add 4 places for format chars
|
||||
char *ntext = (char*)malloc(sizeof(char)*strlen(text(row))+5); // add 4 places for format chars
|
||||
strncpy(ntext+4, text(row), strlen(text(row)));
|
||||
ntext[0]='@'; ntext[1]='C'; ntext[2]='2'; ntext[3]='5';
|
||||
ntext[0]='@'; ntext[1]='C'; ntext[2]='2'; ntext[3]='5'; // @C25 - nice shade of gray
|
||||
ntext[strlen(text(row))+4]='\0'; // in case text(row) was broken
|
||||
text(row,ntext);
|
||||
free(ntext);
|
||||
bucket.add(ntext);
|
||||
|
||||
// grey icon - but how to ungray?
|
||||
Fl_Image* im = get_icon(row)->copy();
|
||||
@ -310,7 +290,7 @@ fprintf (stderr, "value: %s\n", value.c_str());
|
||||
char *ntext = (char*)malloc(sizeof(char)*strlen(text(row))-4); // 4 places for format chars
|
||||
strncpy(ntext, text(row)+4, strlen(text(row))-4);
|
||||
text(row,ntext);
|
||||
free(ntext);
|
||||
bucket.add(ntext);
|
||||
|
||||
// don't work
|
||||
//Fl_Image* im = get_icon(row);
|
||||
@ -319,8 +299,8 @@ fprintf (stderr, "value: %s\n", value.c_str());
|
||||
//redraw(); // OPTIMIZE
|
||||
}
|
||||
|
||||
// Renaming support
|
||||
int handle(int e) {
|
||||
// Rename support
|
||||
if (e==FL_KEYBOARD) {
|
||||
if (Fl::event_key()==FL_F+2) {
|
||||
if (editbox_->visible())
|
||||
@ -330,12 +310,101 @@ fprintf (stderr, "value: %s\n", value.c_str());
|
||||
}
|
||||
}
|
||||
if (e==FL_PUSH && editbox_->visible() && !Fl::event_inside(editbox_))
|
||||
hide_editbox(); // hide editbox when click outside it
|
||||
hide_editbox(); // hide editbox when user clicks outside of it
|
||||
if (e==FL_MOUSEWHEEL && editbox_->visible())
|
||||
hide_editbox(); // hide editbox when scrolling mouse
|
||||
|
||||
// Click once on item that is already selected AND focused to rename it
|
||||
static bool renaming=false;
|
||||
if (e==FL_PUSH) renaming=false;
|
||||
if (e==FL_PUSH && !editbox_->visible() && Fl::event_clicks()==0 && Fl::event_button()==1) {
|
||||
const int* l = column_widths();
|
||||
if (Fl::event_x()<x() || Fl::event_x()>x()+l[0])
|
||||
return Fl_Icon_Browser::handle(e); // we're only interested in first column
|
||||
|
||||
void* item = item_first();
|
||||
int focusy=y()-position();
|
||||
for (int i=1; i<get_focus(); i++) {
|
||||
focusy+=item_height(item);
|
||||
if (focusy>Fl::event_y()) break;
|
||||
item=item_next(item);
|
||||
}
|
||||
if (Fl::event_y()<focusy || Fl::event_y()>focusy+item_height(item))
|
||||
return Fl_Icon_Browser::handle(e); // Click outside selected item
|
||||
if (selected(get_focus())!=1)
|
||||
return Fl_Icon_Browser::handle(e); // allow to select item if it's just focused
|
||||
|
||||
renaming=true;
|
||||
}
|
||||
if (e==FL_RELEASE && renaming && Fl::event_clicks()==0) {
|
||||
show_editbox(get_focus());
|
||||
renaming=false;
|
||||
return 1; // don't pass mouse event, otherwise item will become selected again
|
||||
}
|
||||
|
||||
// Drag&drop support
|
||||
static int paste_event_y;
|
||||
|
||||
/*--- This is to get dnd events from non-fltk apps ---
|
||||
static bool dragging=false;
|
||||
if (e==FL_PUSH) dragging=false;
|
||||
if (e==FL_DND_ENTER) dragging=true;
|
||||
if (e==FL_RELEASE && dragging) {
|
||||
paste_event_y=Fl::event_y();
|
||||
Fl::paste(*this,0);
|
||||
dragging=false;
|
||||
}
|
||||
/*--- End ugly hack ---*/
|
||||
|
||||
// Don't unselect on FL_PUSH cause that could be dragging
|
||||
if (e==FL_PUSH && Fl::event_clicks()!=1) return 1;
|
||||
|
||||
if (e==FL_DRAG) {
|
||||
edelib::String selected_items;
|
||||
for (int i=1; i<=size(); i++)
|
||||
if (selected(i)==1) {
|
||||
if (selected_items != "") selected_items += ",";
|
||||
selected_items += (char*)data(i);
|
||||
}
|
||||
Fl::copy(selected_items.c_str(),selected_items.length(),0);
|
||||
Fl::dnd();
|
||||
return 1; // don't do the multiple selection thing from Fl_Browser
|
||||
}
|
||||
|
||||
if (e==FL_DND_RELEASE) {
|
||||
paste_event_y=Fl::event_y();
|
||||
Fl::paste(*this,0);
|
||||
}
|
||||
if (e==FL_PASTE) {
|
||||
if (!Fl::event_text() || !Fl::event_length()) return 1;
|
||||
|
||||
// Where is the user dropping?
|
||||
void* item = item_first();
|
||||
int itemy=y()-position();
|
||||
int i;
|
||||
for (i=1; i<=size(); i++) {
|
||||
itemy+=item_height(item);
|
||||
if (itemy>paste_event_y) break;
|
||||
}
|
||||
dnd_callback_(Fl::event_text(),(const char*)data(i));
|
||||
}
|
||||
// if (e==FL_DND_ENTER) { take_focus(); Fl::focus(this); Fl::belowmouse(this); Fl_Icon_Browser::handle(FL_FOCUS); }
|
||||
// if (e==FL_DND_LEAVE) { take_focus(); Fl::focus(this); Fl::belowmouse(this); Fl_Icon_Browser::handle(FL_FOCUS); }
|
||||
//fprintf (stderr, "Event: %d\n", e);
|
||||
|
||||
return Fl_Icon_Browser::handle(e);
|
||||
}
|
||||
|
||||
// Setup callback that will be used when renaming
|
||||
void rename_callback(my_callback* cb) { rename_callback_ = cb; }
|
||||
// Setup callback that will be used when renaming and dnd
|
||||
void rename_callback(rename_callback_type* cb) { rename_callback_ = cb; }
|
||||
void dnd_callback(paste_callback_type* cb) { dnd_callback_ = cb; }
|
||||
|
||||
// Avoid memory leak
|
||||
void clear() {
|
||||
fprintf(stderr, "Call FileView::clear()\n");
|
||||
bucket.empty();
|
||||
EDE_Browser::clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -157,6 +157,7 @@ char *simpleopener(const char* mimetype) {
|
||||
if (buf[0]=='\0' || buf[1]=='\0' || buf[0]=='#') continue;
|
||||
buf[strlen(buf)-1]='\0';
|
||||
char *tmp = strstr(buf, "||");
|
||||
if (!tmp) continue; // malformatted opener
|
||||
*tmp = '\0';
|
||||
sopeners* q = new sopeners;
|
||||
q->type=strdup(buf);
|
||||
@ -215,7 +216,7 @@ void loaddir(const char *path) {
|
||||
if (path[0] == '~') // Expand tilde
|
||||
snprintf(current_dir,PATH_MAX,"%s/%s",getenv("HOME"),path+1);
|
||||
else
|
||||
strcpy(current_dir,path);
|
||||
if (path!=current_dir) strcpy(current_dir,path);
|
||||
} else
|
||||
strcpy(current_dir,getenv("HOME"));
|
||||
|
||||
@ -255,7 +256,9 @@ fprintf (stderr, "loaddir(%s) = (%s)\n",path,current_dir);
|
||||
}
|
||||
|
||||
// set window label
|
||||
win->label(tasprintf(_("%s - File manager"), current_dir));
|
||||
// unlike fltk2, labels can be pointers to static char
|
||||
win->label(tsprintf(_("%s - File manager"), current_dir));
|
||||
statusbar->label(tsprintf(_("Scanning directory %s..."), current_dir));
|
||||
|
||||
view->clear();
|
||||
|
||||
@ -264,6 +267,7 @@ fprintf (stderr, "loaddir(%s) = (%s)\n",path,current_dir);
|
||||
|
||||
for (int i=0; i<size; i++) {
|
||||
char *n = files[i]->d_name; //shortcut
|
||||
if (i>0) free(files[i-1]); // see scandir(3)
|
||||
|
||||
// don't show . (current directory)
|
||||
if (strcmp(n,".")==0) continue;
|
||||
@ -301,6 +305,7 @@ fprintf (stderr, "loaddir(%s) = (%s)\n",path,current_dir);
|
||||
|
||||
item_list[fsize++] = item;
|
||||
}
|
||||
free(files[size-1]); free(files); // see scandir(3)
|
||||
|
||||
|
||||
// Populate view
|
||||
@ -355,7 +360,7 @@ fprintf (stderr, "ICON: %s !!!!!\n", icon.c_str());
|
||||
// f_bfree is size available to root
|
||||
double percent = double(statfs_buffer.f_blocks-statfs_buffer.f_bavail)/statfs_buffer.f_blocks*100;
|
||||
char *tmp = strdup(nice_size(totalsize)); // nice_size() operates on a static char buffer, we can't use two calls at the same time
|
||||
statusbar->label(tasprintf(_("Filesystem %s, Size %s, Free %s (%4.1f%% used)"), find_fs_for(current_dir), tmp, nice_size(freesize), percent));
|
||||
statusbar->label(tsprintf(_("Filesystem %s, Size %s, Free %s (%4.1f%% used)"), find_fs_for(current_dir), tmp, nice_size(freesize), percent));
|
||||
free(tmp);
|
||||
} else
|
||||
statusbar->label(_("Error reading filesystem information!"));
|
||||
@ -363,11 +368,6 @@ fprintf (stderr, "ICON: %s !!!!!\n", icon.c_str());
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
File moving and copying operations
|
||||
-------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
Main menu callbacks
|
||||
-------------------------------------------------------------------*/
|
||||
@ -386,9 +386,6 @@ fprintf (stderr,"enter\n");
|
||||
tm=newtm;
|
||||
if (view->value()==0) return; // This can happen while efiler is loading
|
||||
|
||||
char* filename = strdup(view->text(view->value()));
|
||||
if (char*k = strchr(filename, view->column_char())) *k='\0';
|
||||
|
||||
char* path = (char*)view->data(view->value());
|
||||
fprintf(stderr, "Path: %s (ev %d)\n",path,Fl::event());
|
||||
|
||||
@ -411,15 +408,21 @@ fprintf (stderr,"enter\n");
|
||||
|
||||
const char *o2 = tsprintf(opener,path);
|
||||
fprintf (stderr, "run_program: %s\n", o2);
|
||||
|
||||
// construct filename for the message
|
||||
char* filename = strdup(view->text(view->value()));
|
||||
if (char*k = strchr(filename, view->column_char())) *k='\0';
|
||||
|
||||
if (opener) {
|
||||
int k=edelib::run_program(o2,false); fprintf(stderr, "retval: %d\n", k);
|
||||
} else
|
||||
statusbar->label(tasprintf(_("No program to open %s!"), filename));
|
||||
statusbar->label(tsprintf(_("No program to open %s!"), filename));
|
||||
|
||||
free(filename);
|
||||
|
||||
rlim->rlim_cur = old_rlimit;
|
||||
setrlimit (RLIMIT_CORE, rlim);
|
||||
free(rlim);
|
||||
|
||||
}
|
||||
} // open_cb
|
||||
@ -525,6 +528,7 @@ edelib::IconTheme::init("crystalsvg");
|
||||
view->callback(open_cb);
|
||||
// callback for renaming
|
||||
view->rename_callback(do_rename);
|
||||
view->dnd_callback(dnd_cb);
|
||||
|
||||
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);
|
||||
|
@ -88,9 +88,9 @@ void do_cut_copy(bool m_copy) {
|
||||
|
||||
// Update statusbar
|
||||
if (m_copy)
|
||||
statusbar->label(tasprintf(_("Selected %d items for copying"), nselected));
|
||||
statusbar->label(tsprintf(_("Selected %d items for copying"), nselected));
|
||||
else
|
||||
statusbar->label(tasprintf(_("Selected %d items for moving"), nselected));
|
||||
statusbar->label(tsprintf(_("Selected %d items for moving"), nselected));
|
||||
}
|
||||
|
||||
|
||||
@ -149,19 +149,20 @@ bool my_copy(const char* src, const char* dest) {
|
||||
if (q == 0) return true; else return false;
|
||||
}
|
||||
|
||||
if ( !edelib::file_writeable(dest) )
|
||||
// edelib::file_writeable() returns false if dest doesn't exist
|
||||
/* if ( !edelib::file_writeable(dest) )
|
||||
{
|
||||
// here was choice_alert
|
||||
int q = fl_choice(tsprintf(_("Cannot create file %s"),dest), _("&Stop"), _("&Continue"), 0);
|
||||
if (q == 0) return true; else return false;
|
||||
}
|
||||
}*/
|
||||
|
||||
// we will try to preserve permissions etc. cause that's usually what people want
|
||||
if (!edelib::file_copy(src,dest,true))
|
||||
fl_alert(tsprintf(_("Error copying %s to %s"),src,dest));
|
||||
|
||||
fclose(fold);
|
||||
fclose(fnew);
|
||||
// fclose(fold);
|
||||
// fclose(fnew);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -239,6 +240,7 @@ void do_paste() {
|
||||
}
|
||||
rename(cut_copy_buffer[i],newname);
|
||||
free(cut_copy_buffer[i]);
|
||||
free(newname);
|
||||
}
|
||||
free(cut_copy_buffer);
|
||||
cut_copy_buffer=0;
|
||||
@ -263,6 +265,7 @@ void do_paste() {
|
||||
|
||||
if (strcmp(srcdir,current_dir)==0) {
|
||||
fl_alert(_("You cannot copy a file onto itself!"));
|
||||
free(srcdir);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -333,13 +336,22 @@ void do_paste() {
|
||||
}
|
||||
progress_window->hide();
|
||||
|
||||
// Deallocate files_list[][]
|
||||
for (int i=0; i<list_size; i++)
|
||||
free(files_list[i]);
|
||||
free(files_list);
|
||||
|
||||
// Reload current dir
|
||||
loaddir(current_dir);
|
||||
|
||||
// select the just pasted files and cleanup memory
|
||||
for (int i=0; i<list_size; i++) {
|
||||
char* tmp = strrchr(files_list[i],'/')+1;
|
||||
// if (!tmp) { fprintf (stderr, "not found\n"); continue; }
|
||||
// tmp++;
|
||||
for (int j=1; j<=view->size(); j++)
|
||||
if (strncmp(tmp, view->text(j), strlen(tmp))==0)
|
||||
view->select(j,1);
|
||||
free(files_list[i]);
|
||||
}
|
||||
|
||||
free(files_list);
|
||||
free(srcdir);
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,11 +362,9 @@ void do_delete() {
|
||||
int list_size = 0, list_capacity = 1000;
|
||||
char** files_list = (char**)malloc(sizeof(char**)*list_capacity);
|
||||
|
||||
for (int i=1; i<=view->size(); i++) {
|
||||
if (view->selected(i)==1) {
|
||||
for (int i=1; i<=view->size(); i++)
|
||||
if (view->selected(i)==1)
|
||||
expand_dirs((char*)view->data(i), files_list, list_size, list_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
if (list_size==0) { //nothing selected, use the focused item
|
||||
int i=view->get_focus();
|
||||
@ -374,7 +384,10 @@ void do_delete() {
|
||||
// delete
|
||||
for (int i=0; i<list_size; i++)
|
||||
edelib::file_remove(files_list[i]);
|
||||
loaddir(current_dir);
|
||||
// loaddir(current_dir); - optimized
|
||||
for (int i=1; i<=view->size(); i++)
|
||||
if (view->selected(i)==1)
|
||||
view->remove(i);
|
||||
}
|
||||
|
||||
|
||||
@ -405,3 +418,52 @@ void do_rename(const char* c) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Drag & drop callback - mostly copied from do_cut_copy()
|
||||
void dnd_cb(const char* from,const char* to) {
|
||||
fprintf (stderr, "PASTE from '%s', to '%s'\n",from,to);
|
||||
return;
|
||||
|
||||
char *t = (char*)to;
|
||||
if (!fl_filename_isdir(to))
|
||||
t=current_dir;
|
||||
|
||||
|
||||
/*
|
||||
// Clear cut/copy buffer and optionally ungray the previously cutted icons
|
||||
if (cut_copy_buffer) {
|
||||
for (int i=0; cut_copy_buffer[i]; i++)
|
||||
free(cut_copy_buffer[i]);
|
||||
free(cut_copy_buffer);
|
||||
if (!operation_is_copy) {
|
||||
for (int i=1; i<=num; i++)
|
||||
view->ungray(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate buffer
|
||||
cut_copy_buffer = (char**)malloc(sizeof(char*) * (nselected+2));
|
||||
|
||||
// Add selected files to buffer
|
||||
int buf=0;
|
||||
for (int i=1; i<=num; i++)
|
||||
if (view->selected(i)==1)
|
||||
cut_copy_buffer[buf++] = strdup((char*)view->data(i));
|
||||
// We don't know yet if this is cut or copy, so no need to gray anything
|
||||
|
||||
//
|
||||
|
||||
// Clear cut/copy buffer and optionally ungray the previously cutted icons
|
||||
if (cut_copy_buffer) {
|
||||
for (int i=0; cut_copy_buffer[i]; i++)
|
||||
free(cut_copy_buffer[i]);
|
||||
free(cut_copy_buffer);
|
||||
if (!operation_is_copy) {
|
||||
for (int i=1; i<=num; i++)
|
||||
view->ungray(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int c = fl_choice(tsprintf(_("Do you want to copy or move file %s to directory %s?"), k+1), _("Do&n't delete"), _("&Delete"), 0);*/
|
||||
}
|
||||
|
@ -20,6 +20,9 @@ void do_delete();
|
||||
// Rename the file with focus to given name
|
||||
void do_rename(const char*);
|
||||
|
||||
// Callback for drag&drop operations
|
||||
void dnd_cb(const char*from,const char*to);
|
||||
|
||||
|
||||
extern FileDetailsView* view;
|
||||
extern Fl_Box* statusbar;
|
||||
|
Loading…
Reference in New Issue
Block a user