ede/efiler/EDE_FileDetailsView.h
2008-10-29 11:17:11 +00:00

172 lines
4.6 KiB
C++

/*
* $Id$
*
* EDE FileView class
* Part of edelib.
* Copyright (c) 2005-2007 EDE Authors.
*
* This program is licenced under terms of the
* GNU General Public Licence version 2 or newer.
* See COPYING for details.
*/
#ifndef EDE_FileDetailsView_H
#define EDE_FileDetailsView_H
#include <FL/Fl_Input.H>
#include <FL/Fl_Image.H>
#include <edelib/String.h>
#include "EDE_Browser.h"
//#include "EDE_FileView.h"
// Sometimes I accidentaly "drag" an icon - don't want dnd to trigger
#define MIN_DISTANCE_FOR_DND 10
class FileDetailsView : public EDE_Browser {
private:
// EDE_Browser* browser; - yada
// internal list of items
/* struct myfileitem {
struct FileItem *item;
myfileitem* previous;
myfileitem* next;
} *firstitem;*/
// EditBox is displayed when renaming a file
// We subclass Fl_Input so we can handle keyboard events
class EditBox : public Fl_Input {
public:
EditBox(int x, int y, int w, int h, const char* label = 0) : Fl_Input(x,y,w,h,label) {}
int handle (int e);
}* editbox_;
int editbox_row;
// show editbox at specified row and make the row "invisible" (bgcolor same as fgcolor)
void show_editbox(int row);
void hide_editbox();
// This is called to actually rename file (when user presses Enter in editbox)
void finish_rename();
// Try various names and sizes for icons
Fl_Image* try_icon(edelib::String icon_name);
// Find row number corresponding to realpath (encoded in data())
int findrow(edelib::String realpath) {
for (int i=1; i<=size(); i++) {
char *tmp = (char*)data(i);
if (realpath==tmp) return i;
}
return 0;
}
// Callbacks
rename_callback_type* rename_callback_;
paste_callback_type* paste_callback_;
Fl_Callback* context_callback_;
// Deallocator 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 :)
// -- The reason we need such class is that there are no insert_copy() or
// data_copy() methods in Fl_Browser (cf. label_copy() in Fl_Widget)
#define MEM_STEP 1000
class Deallocator {
void** items;
int size, capacity;
public:
Deallocator() : size(0), capacity(MEM_STEP) {
items = (void**)malloc(sizeof(void*)*capacity);
for (int i=0; i<capacity; i++) items[i]=0;
}
~Deallocator() { empty(); free(items); }
void add(void* p) {
if (size>=capacity) {
capacity+=MEM_STEP;
items = (void**)realloc(items,sizeof(void*)*capacity);
for (int i=capacity-MEM_STEP; 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);
// ~FileDetailsView() { delete browser; }
// Methods for manipulating items
// They are named similarly to Browser methods, except that they take
// struct FileItem (defined in EDE_FileView.h)
void insert(int row, FileItem *item);
void add(FileItem *item) { insert(size()+1, item); }
void remove(FileItem *item) {
int row = findrow(item->realpath);
if (row) EDE_Browser::remove(row);
}
void remove(int row) { EDE_Browser::remove(row); } // doesnt work without this method :(
void update(FileItem *item); // refresh one row without reloading the whole list
// This method is needed because update() uses path to find item in list
void update_path(const char* oldpath,const char* newpath);
// Make row look "disabled" (actually we use it for cut operation)
void gray(int row);
void ungray(int row);
// Overloaded handle for: context menu, file renaming and dnd support
int handle(int e);
// Callback when user renames a file (takes const char* filename)
void rename_callback(rename_callback_type* cb) { rename_callback_ = cb; }
// Callback that is called by FL_PASTE event (such as drag&drop)
// (takes const char* paste_target /e.g. target directory or 0 for current directory/)
void paste_callback(paste_callback_type* cb) { paste_callback_ = cb; }
// Callback that is called on right mouse click (for e.g. context menu)
void context_callback(Fl_Callback* cb) { context_callback_ = cb; }
// Avoid memory leak
void clear() {
bucket.empty();
EDE_Browser::clear();
}
int visible() { return Fl_Widget::visible(); }
// Aliases for better compatibility with other views
const char*path(int row) { return (const char*)data(row); }
void show_item(int row) { middleline(row); }
void start_rename() { show_editbox(get_focus()); }
};
#endif
/* $Id */