mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Synced code with edelib changes.
Directory notifier added (still needs a work). Internal changes for easier directory events handling.
This commit is contained in:
parent
7a299bc70c
commit
b571876fe6
@ -19,10 +19,10 @@
|
||||
#include <FL/Fl_Shared_Image.h>
|
||||
#include <FL/Fl_Menu_Button.h>
|
||||
#include <FL/x.h>
|
||||
#include <FL/fl_ask.h>
|
||||
|
||||
#include <edelib/Debug.h>
|
||||
#include <edelib/IconTheme.h>
|
||||
#include <edelib/MessageBox.h>
|
||||
#include <edelib/Nls.h>
|
||||
|
||||
#define USE_SHAPE 1
|
||||
@ -63,7 +63,7 @@ void rename_cb(Fl_Widget*, void* d) {
|
||||
DesktopIcon* di = (DesktopIcon*)d;
|
||||
EASSERT(di != NULL);
|
||||
|
||||
const char* new_name = fl_input(_("New name"), di->label());
|
||||
const char* new_name = edelib::input(_("New name"), di->label());
|
||||
if(!new_name)
|
||||
return;
|
||||
if(new_name[0] == '\0')
|
||||
@ -261,6 +261,10 @@ void DesktopIcon::rename(const char* str) {
|
||||
redraw();
|
||||
}
|
||||
|
||||
const edelib::String& DesktopIcon::path(void) {
|
||||
return settings->full_path;
|
||||
}
|
||||
|
||||
void DesktopIcon::fast_redraw(void) {
|
||||
EASSERT(parent() != NULL && "Impossible !");
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
#ifndef __DESKTOPICON_H__
|
||||
#define __DESKTOPICON_H__
|
||||
|
||||
#include <edelib/String.h>
|
||||
|
||||
#include <FL/Fl_Widget.h>
|
||||
#include <FL/Fl_Window.h>
|
||||
#include <FL/Fl_Box.h>
|
||||
@ -77,6 +79,12 @@ class DesktopIcon : public Fl_Widget {
|
||||
Fl_Image* icon_image(void) { return image(); }
|
||||
|
||||
void rename(const char* str);
|
||||
|
||||
/*
|
||||
* make sure this returns String since operator== is
|
||||
* further used, especially in Desktop
|
||||
*/
|
||||
const edelib::String& path(void);
|
||||
};
|
||||
|
||||
class MovableIcon : public Fl_Window {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <edelib/File.h>
|
||||
#include <edelib/DesktopFile.h>
|
||||
#include <edelib/Directory.h>
|
||||
#include <edelib/DirWatch.h>
|
||||
#include <edelib/MimeType.h>
|
||||
#include <edelib/StrUtil.h>
|
||||
#include <edelib/IconTheme.h>
|
||||
@ -34,6 +35,8 @@
|
||||
#include <FL/Fl_Menu_Button.h>
|
||||
#include <FL/fl_ask.h>
|
||||
|
||||
#include <unistd.h> // sleep
|
||||
|
||||
#if 0
|
||||
#include <X11/extensions/Xdamage.h>
|
||||
#endif
|
||||
@ -111,6 +114,10 @@ void restart_signal(int signum) {
|
||||
EDEBUG(ESTRLOC ": Restarting (got signal %d)\n", signum);
|
||||
}
|
||||
|
||||
void dir_watch_cb(const char* dir, const char* changed, int flags, void* data) {
|
||||
Desktop::instance()->dir_watch(dir, changed, flags);
|
||||
}
|
||||
|
||||
int desktop_xmessage_handler(int event) {
|
||||
#if 0
|
||||
if(fl_xevent->type == xevent_base + XDamageNotify) {
|
||||
@ -158,6 +165,7 @@ int desktop_xmessage_handler(int event) {
|
||||
Desktop::Desktop() : DESKTOP_WINDOW(0, 0, 100, 100, "") {
|
||||
selection_x = selection_y = 0;
|
||||
moving = false;
|
||||
do_dirwatch = true;
|
||||
|
||||
selbox = new SelectionOverlay;
|
||||
selbox->x = selbox->y = selbox->w = selbox->h = 0;
|
||||
@ -174,6 +182,8 @@ Desktop::~Desktop() {
|
||||
delete dsett;
|
||||
delete selbox;
|
||||
delete notify;
|
||||
|
||||
edelib::DirWatch::shutdown();
|
||||
}
|
||||
|
||||
void Desktop::init_internals(void) {
|
||||
@ -333,85 +343,148 @@ void Desktop::read_config(void) {
|
||||
return;
|
||||
}
|
||||
dd += "/Desktop";
|
||||
load_icons(dd.c_str(), conf);
|
||||
|
||||
/*
|
||||
* Setup watcher on ~/Desktop directory. All further events will
|
||||
* be reported to dir_watch()
|
||||
*/
|
||||
if(edelib::dir_exists(dd.c_str())) {
|
||||
load_icons(dd.c_str(), &conf);
|
||||
|
||||
edelib::DirWatch::init();
|
||||
edelib::DirWatch::callback(dir_watch_cb);
|
||||
|
||||
if(!edelib::DirWatch::add(dd.c_str(),
|
||||
edelib::DW_CREATE | edelib::DW_MODIFY | edelib::DW_RENAME | edelib::DW_DELETE)) {
|
||||
|
||||
EWARNING(ESTRLOC ": Can't load %s; icons will not be loaded\n", dd.c_str());
|
||||
edelib::DirWatch::shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Desktop::save_config(void) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Desktop::load_icons(const char* path, edelib::Config& conf) {
|
||||
void Desktop::load_icons(const char* path, edelib::Config* conf) {
|
||||
EASSERT(path != NULL);
|
||||
|
||||
if(!edelib::dir_exists(path)) {
|
||||
EDEBUG(ESTRLOC ": %s does not exists\n", path);
|
||||
return;
|
||||
}
|
||||
|
||||
edelib::vector<edelib::String> lst;
|
||||
|
||||
// list without full path, so we can use name as entry in config file
|
||||
if(!dir_list(path, lst)) {
|
||||
edelib::list<edelib::String> lst;
|
||||
// list with full path; icon basename is extracted in add_icon_pathed()
|
||||
if(!dir_list(path, lst, true)) {
|
||||
EDEBUG(ESTRLOC ": Can't read %s\n", path);
|
||||
return;
|
||||
}
|
||||
|
||||
const char* name = NULL;
|
||||
int icon_x = 0;
|
||||
int icon_y = 0;
|
||||
edelib::String full_path;
|
||||
full_path.reserve(256);
|
||||
edelib::list<edelib::String>::iterator it, it_end;
|
||||
for(it = lst.begin(), it_end = lst.end(); it != it_end; ++it)
|
||||
add_icon_pathed((*it).c_str(), conf);
|
||||
}
|
||||
|
||||
bool Desktop::add_icon_pathed(const char* path, edelib::Config* conf) {
|
||||
EASSERT(path != NULL);
|
||||
|
||||
IconSettings is;
|
||||
bool can_add = false;
|
||||
const char* base = get_basename(path);
|
||||
|
||||
edelib::MimeType mt;
|
||||
|
||||
unsigned int sz = lst.size();
|
||||
for(unsigned int i = 0; i < sz; i++) {
|
||||
name = lst[i].c_str();
|
||||
/*
|
||||
* see is possible .desktop file; icon, name fields are filled from read_desktop_file()
|
||||
*
|
||||
* FIXME: maybe the good thing is to use MimeType to check .desktop;
|
||||
* extension does not have to be always present, or .desktop does not have to be
|
||||
* Desktop File at all
|
||||
*/
|
||||
if(edelib::str_ends(path, ".desktop")) {
|
||||
if(read_desktop_file(path, is))
|
||||
can_add = true;
|
||||
} else {
|
||||
edelib::MimeType mt;
|
||||
|
||||
full_path = path;
|
||||
full_path += '/';
|
||||
full_path += name;
|
||||
// then try to figure out it's mime; if fails, ignore it
|
||||
if(mt.set(path)) {
|
||||
EDEBUG(ESTRLOC ": Loading icon as mime-type %s\n", mt.icon_name().c_str());
|
||||
is.icon = mt.icon_name();
|
||||
// icon label path's basename
|
||||
is.name = base;
|
||||
is.type = ICON_FILE;
|
||||
|
||||
can_add = false;
|
||||
|
||||
IconSettings is;
|
||||
|
||||
// see is possible .desktop file, icon, name fields are filled from read_desktop_file()
|
||||
if(edelib::str_ends(name, ".desktop")) {
|
||||
if(read_desktop_file(full_path.c_str(), is))
|
||||
can_add = true;
|
||||
can_add = true;
|
||||
} else {
|
||||
// then try to figure out it's mime; if fails, ignore it
|
||||
if(mt.set(full_path.c_str())) {
|
||||
EDEBUG(ESTRLOC ": Loading icon as mime-type %s\n", mt.icon_name().c_str());
|
||||
is.icon = mt.icon_name();
|
||||
// icon label is name of file
|
||||
is.name = name;
|
||||
is.type = ICON_FILE;
|
||||
|
||||
can_add = true;
|
||||
} else {
|
||||
EDEBUG(ESTRLOC ": Failed mime-type for %s, ignoring...\n", name);
|
||||
can_add = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(can_add) {
|
||||
is.key_name = name;
|
||||
// random_pos() is used if X/Y keys are not found
|
||||
conf.get(name, "X", icon_x, random_pos(w() - 10));
|
||||
conf.get(name, "Y", icon_y, random_pos(h() - 10));
|
||||
|
||||
EDEBUG(ESTRLOC ": %s found with: %i %i\n", name, icon_x, icon_y);
|
||||
is.x = icon_x;
|
||||
is.y = icon_y;
|
||||
|
||||
DesktopIcon* dic = new DesktopIcon(&gisett, &is, dsett->color);
|
||||
add_icon(dic);
|
||||
EDEBUG(ESTRLOC ": Failed mime-type for %s, ignoring...\n", path);
|
||||
can_add = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(can_add) {
|
||||
/*
|
||||
* key_name is section in config file with icon X/Y values
|
||||
* FIXME: this should be named 'section_name'
|
||||
*/
|
||||
is.key_name = base;
|
||||
|
||||
// random_pos() is used if X/Y keys are not found
|
||||
int icon_x = random_pos(w() - 10);
|
||||
int icon_y = random_pos(w() - 10);
|
||||
|
||||
if(conf) {
|
||||
conf->get(base, "X", icon_x, icon_x);
|
||||
conf->get(base, "Y", icon_y, icon_y);
|
||||
}
|
||||
|
||||
EDEBUG(ESTRLOC ": %s found with: %i %i\n", base, icon_x, icon_y);
|
||||
is.x = icon_x;
|
||||
is.y = icon_y;
|
||||
is.full_path = path;
|
||||
|
||||
DesktopIcon* dic = new DesktopIcon(&gisett, &is, dsett->color);
|
||||
add_icon(dic);
|
||||
}
|
||||
|
||||
return can_add;
|
||||
}
|
||||
|
||||
DesktopIcon* Desktop::find_icon_pathed(const char* path) {
|
||||
EASSERT(path != NULL);
|
||||
|
||||
if(icons.empty())
|
||||
return NULL;
|
||||
|
||||
DesktopIconListIter it, it_end;
|
||||
for(it = icons.begin(), it_end = icons.end(); it != it_end; ++it) {
|
||||
if((*it)->path() == path)
|
||||
return (*it);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool Desktop::remove_icon_pathed(const char* path) {
|
||||
EASSERT(path != NULL);
|
||||
|
||||
if(icons.empty())
|
||||
return false;
|
||||
|
||||
DesktopIconListIter it, it_end;
|
||||
bool found = false;
|
||||
|
||||
for(it = icons.begin(), it_end = icons.end(); it != it_end; ++it) {
|
||||
if((*it)->path() == path) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(found) {
|
||||
DesktopIcon* ic = (*it);
|
||||
icons.erase(it);
|
||||
// Fl_Group::remove() does not delete child, just pops it out
|
||||
remove(ic);
|
||||
delete ic;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
// read .desktop files
|
||||
@ -425,7 +498,7 @@ bool Desktop::read_desktop_file(const char* path, IconSettings& is) {
|
||||
|
||||
edelib::DesktopFile dconf;
|
||||
if(!dconf.load(path)) {
|
||||
EWARNING(ESTRLOC ": Can't read %s\n", path);
|
||||
EWARNING(ESTRLOC ": Can't read %s (%s)\n", path, dconf.strerror());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -482,11 +555,12 @@ void Desktop::add_icon(DesktopIcon* ic) {
|
||||
}
|
||||
|
||||
void Desktop::unfocus_all(void) {
|
||||
unsigned int sz = icons.size();
|
||||
DesktopIcon* ic;
|
||||
DesktopIconListIter it, it_end;
|
||||
|
||||
for(it = icons.begin(), it_end = icons.end(); it != it_end; ++it) {
|
||||
ic = (*it);
|
||||
|
||||
for(unsigned int i = 0; i < sz; i++) {
|
||||
ic = icons[i];
|
||||
if(ic->is_focused()) {
|
||||
ic->do_unfocus();
|
||||
ic->fast_redraw();
|
||||
@ -524,9 +598,13 @@ void Desktop::select_only(DesktopIcon* ic) {
|
||||
bool Desktop::in_selection(const DesktopIcon* ic) {
|
||||
EASSERT(ic != NULL);
|
||||
|
||||
unsigned int sz = selectionbuff.size();
|
||||
for(unsigned int i = 0; i < sz; i++) {
|
||||
if(ic == selectionbuff[i])
|
||||
if(selectionbuff.empty())
|
||||
return false;
|
||||
|
||||
DesktopIconListIter it, it_end;
|
||||
|
||||
for(it = selectionbuff.begin(), it_end = selectionbuff.end(); it != it_end; ++it) {
|
||||
if((*it) == ic)
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -534,15 +612,16 @@ bool Desktop::in_selection(const DesktopIcon* ic) {
|
||||
}
|
||||
|
||||
void Desktop::move_selection(int x, int y, bool apply) {
|
||||
unsigned int sz = selectionbuff.size();
|
||||
if(sz == 0)
|
||||
if(selectionbuff.empty())
|
||||
return;
|
||||
|
||||
int prev_x, prev_y, tmp_x, tmp_y;
|
||||
DesktopIcon* ic;
|
||||
|
||||
for(unsigned int i = 0; i < sz; i++) {
|
||||
ic = selectionbuff[i];
|
||||
DesktopIconListIter it, it_end;
|
||||
|
||||
for(it = selectionbuff.begin(), it_end = selectionbuff.end(); it != it_end; ++it) {
|
||||
ic = (*it);
|
||||
|
||||
prev_x = ic->drag_icon_x();
|
||||
prev_y = ic->drag_icon_y();
|
||||
@ -575,11 +654,11 @@ void Desktop::move_selection(int x, int y, bool apply) {
|
||||
* and bad things be hapened.
|
||||
*/
|
||||
DesktopIcon* Desktop::below_mouse(int px, int py) {
|
||||
unsigned int sz = icons.size();
|
||||
|
||||
DesktopIcon* ic = NULL;
|
||||
for(unsigned int i = 0; i < sz; i++) {
|
||||
ic = icons[i];
|
||||
DesktopIconListIter it, it_end;
|
||||
|
||||
for(it = icons.begin(), it_end = icons.end(); it != it_end; ++it) {
|
||||
ic = (*it);
|
||||
if(ic->x() < px && ic->y() < py && px < (ic->x() + ic->h()) && py < (ic->y() + ic->h()))
|
||||
return ic;
|
||||
}
|
||||
@ -613,11 +692,11 @@ void Desktop::select_in_area(void) {
|
||||
* but selbox use relative (event_root). It will work as expected if desktop is at x=0 y=0.
|
||||
* This should be checked further.
|
||||
*/
|
||||
unsigned int sz = icons.size();
|
||||
DesktopIcon* ic = NULL;
|
||||
DesktopIconListIter it, it_end;
|
||||
|
||||
for(unsigned int i = 0; i < sz; i++) {
|
||||
ic = icons[i];
|
||||
for(it = icons.begin(), it_end = icons.end(); it != it_end; ++it) {
|
||||
ic = (*it);
|
||||
EASSERT(ic != NULL && "Impossible to happen");
|
||||
|
||||
if(intersects(ax, ay, ax+aw, ay+ah, ic->x(), ic->y(), ic->w()+ic->x(), ic->h()+ic->y())) {
|
||||
@ -831,6 +910,53 @@ void Desktop::draw(void) {
|
||||
clear_damage();
|
||||
}
|
||||
|
||||
void Desktop::dir_watch(const char* dir, const char* changed, int flags) {
|
||||
if(!do_dirwatch || !changed || flags == edelib::DW_REPORT_NONE)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Check first we don't get any temporary files (starting with '.'
|
||||
* or ending with '~', like vim does when editing file). For now these
|
||||
* are only conditions, but I will probably add them more when issues occured.
|
||||
*
|
||||
* FIXME: use strcmp() family ?
|
||||
*/
|
||||
edelib::String tmp(changed);
|
||||
if(tmp.empty() || tmp[0] == '.' || tmp[tmp.length()-1] == '~')
|
||||
return;
|
||||
|
||||
sleep(1);
|
||||
|
||||
if(flags == edelib::DW_REPORT_CREATE) {
|
||||
EDEBUG(ESTRLOC ": adding %s\n", changed);
|
||||
|
||||
if(find_icon_pathed(changed)) {
|
||||
EDEBUG(ESTRLOC ": %s already registered; skipping...\n", changed);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Uh; looks like kernel report event faster than file is created
|
||||
* (in some cases). This can be bad for .desktop files when are copied
|
||||
* (eg. on my machine after 'cp Home.desktop foo.desktop', will fail
|
||||
* to load foo.desktop since it's content is not fully copied).
|
||||
* Due that we stop for one sec (use usleep() ???)
|
||||
*/
|
||||
//sleep(1);
|
||||
|
||||
if(add_icon_pathed(changed, 0))
|
||||
redraw();
|
||||
|
||||
} else if(flags == edelib::DW_REPORT_MODIFY) {
|
||||
EDEBUG(ESTRLOC ": modified %s\n", changed);
|
||||
} else if(flags == edelib::DW_REPORT_DELETE) {
|
||||
EDEBUG(ESTRLOC ": deleted %s\n", changed);
|
||||
if(remove_icon_pathed(changed))
|
||||
redraw();
|
||||
} else
|
||||
EDEBUG(ESTRLOC ": %s changed with %i\n", changed, flags);
|
||||
}
|
||||
|
||||
int Desktop::handle(int event) {
|
||||
switch(event) {
|
||||
case FL_FOCUS:
|
||||
@ -958,9 +1084,10 @@ int Desktop::handle(int event) {
|
||||
if(!selectionbuff.empty())
|
||||
selectionbuff.clear();
|
||||
|
||||
for(unsigned int i = 0; i < icons.size(); i++) {
|
||||
if(icons[i]->is_focused())
|
||||
select(icons[i], false);
|
||||
DesktopIconListIter it, it_end;
|
||||
for(it = icons.begin(), it_end = icons.end(); it != it_end; ++it) {
|
||||
if((*it)->is_focused())
|
||||
select((*it), false);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -976,7 +1103,7 @@ int Desktop::handle(int event) {
|
||||
* command for all selected icons ?
|
||||
*/
|
||||
if(selectionbuff.size() == 1 && !moving)
|
||||
selectionbuff[0]->handle(FL_RELEASE);
|
||||
(*selectionbuff.begin())->handle(FL_RELEASE);
|
||||
|
||||
moving = false;
|
||||
return 1;
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include <edelib/String.h>
|
||||
#include <edelib/Config.h>
|
||||
#include <edelib/Vector.h>
|
||||
#include <edelib/List.h>
|
||||
|
||||
#define EDAMAGE_CHILD_LABEL 0x10
|
||||
#define EDAMAGE_OVERLAY 0x20
|
||||
@ -78,7 +78,8 @@ class NotifyBox;
|
||||
|
||||
class Fl_Menu_Button;
|
||||
|
||||
typedef edelib::vector<DesktopIcon*> DesktopIconList;
|
||||
typedef edelib::list<DesktopIcon*> DesktopIconList;
|
||||
typedef edelib::list<DesktopIcon*>::iterator DesktopIconListIter;
|
||||
|
||||
#define DESKTOP_WINDOW Fl_Window
|
||||
|
||||
@ -88,6 +89,7 @@ class Desktop : public DESKTOP_WINDOW {
|
||||
|
||||
int selection_x, selection_y;
|
||||
bool moving;
|
||||
bool do_dirwatch;
|
||||
|
||||
SelectionOverlay* selbox;
|
||||
|
||||
@ -103,10 +105,14 @@ class Desktop : public DESKTOP_WINDOW {
|
||||
|
||||
void init_internals(void);
|
||||
|
||||
void load_icons(const char* path, edelib::Config& conf);
|
||||
void load_icons(const char* path, edelib::Config* conf);
|
||||
bool read_desktop_file(const char* path, IconSettings& is);
|
||||
|
||||
void add_icon(DesktopIcon* ic);
|
||||
bool add_icon_pathed(const char* path, edelib::Config* conf);
|
||||
DesktopIcon* find_icon_pathed(const char* path);
|
||||
bool remove_icon_pathed(const char* path);
|
||||
bool update_icon_pathed(const char* path);
|
||||
|
||||
void unfocus_all(void);
|
||||
|
||||
@ -145,6 +151,10 @@ class Desktop : public DESKTOP_WINDOW {
|
||||
void notify_box(const char* msg, bool copy = false);
|
||||
void notify_box_color(Fl_Color col);
|
||||
void notify_desktop_changed(void);
|
||||
|
||||
void dir_watch(const char* dir, const char* changed, int flags);
|
||||
void dir_watch_on(void) { do_dirwatch = true; }
|
||||
void dir_watch_off(void) { do_dirwatch = false; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user