- Beggining of dnd support

- Click on selected item to rename
- Fix problems reported by Valgrind
This commit is contained in:
Vedran Ljubovic 2007-07-27 08:36:05 +00:00
parent 67cc5824ec
commit 87ef0c5509
6 changed files with 286 additions and 131 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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();
}
};

View File

@ -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);

View File

@ -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);*/
}

View File

@ -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;