From bee5fd8fb98fbc430ea13e0e2c8df1c667a03bce Mon Sep 17 00:00:00 2001 From: Sanel Zukan Date: Mon, 24 Jun 2013 14:40:28 +0000 Subject: [PATCH] Removing old ede-desktop.h. Adding support for editing existing icons. Editing will be done simply by creating first .desktop file and letting ede-desktop to read it, performing some checks to determin if only content was changed or file was renamed. Using this scheme, beside it simplify the code, it addresses the cases when icon was modified outside the desktop or removed. These things could be solved by using DirWatch, but I'm trying to rely less on OS notification system... --- ede-desktop/Desktop.cpp | 8 +- ede-desktop/Desktop.h | 1 + ede-desktop/DesktopIcon.cpp | 24 +++-- ede-desktop/Globals.h | 2 + ede-desktop/IconDialog.cpp | 92 +++++++++++++++--- ede-desktop/IconDialog.h | 4 +- ede-desktop/Wallpaper.cpp | 2 +- ede-desktop/ede-desktop.h | 180 ------------------------------------ 8 files changed, 108 insertions(+), 205 deletions(-) delete mode 100644 ede-desktop/ede-desktop.h diff --git a/ede-desktop/Desktop.cpp b/ede-desktop/Desktop.cpp index 0cf3ca1..ab3df29 100644 --- a/ede-desktop/Desktop.cpp +++ b/ede-desktop/Desktop.cpp @@ -365,7 +365,7 @@ DesktopIcon *Desktop::read_desktop_file(const char *path, const char *base, Desk * try to load it as plain .desktop file by looking only at extension * TODO: MimeType can be used here too */ - if(!str_ends(path, ".desktop")) + if(!str_ends(path, EDE_DESKTOP_DESKTOP_EXT)) return ret; DesktopFile df; @@ -435,7 +435,7 @@ bool Desktop::remove_icon(DesktopIcon *di, bool real_delete) { if(real_delete) { if(di->get_icon_type() == DESKTOP_ICON_TYPE_FOLDER) { if(!dir_empty(di->get_path())) { - alert(_("This folder is not empty. Recursive removal of not empty folders is not yet implemented :S")); + alert(_("This folder is not empty. Recursive removal of not empty folders is not yet supported")); return false; } ret = dir_remove(di->get_path()); @@ -462,6 +462,10 @@ bool Desktop::rename_icon(DesktopIcon *di, const char *name) { return df.save(di->get_path()); } +void Desktop::edit_icon(DesktopIcon *di) { + icon_dialog_icon_edit(this, di); +} + bool Desktop::save_icons_positions(void) { DesktopConfig pos; DesktopIcon *o; diff --git a/ede-desktop/Desktop.h b/ede-desktop/Desktop.h index 7ea3997..50410a4 100644 --- a/ede-desktop/Desktop.h +++ b/ede-desktop/Desktop.h @@ -80,6 +80,7 @@ public: void arrange_icons(void); bool remove_icon(DesktopIcon *di, bool real_delete); bool rename_icon(DesktopIcon *di, const char *name); + void edit_icon(DesktopIcon *di); bool save_icons_positions(void); bool create_folder(const char *name); diff --git a/ede-desktop/DesktopIcon.cpp b/ede-desktop/DesktopIcon.cpp index 2734852..bcbaf9b 100644 --- a/ede-desktop/DesktopIcon.cpp +++ b/ede-desktop/DesktopIcon.cpp @@ -60,12 +60,12 @@ EDELIB_NS_USING(ICON_SIZE_TINY) EDELIB_NS_USING(ICON_SIZE_HUGE) static void open_cb(Fl_Widget*, void* d); -static void rename_cb(Fl_Widget*, void* d); +static void edit_cb(Fl_Widget*, void* d); static void delete_cb(Fl_Widget*, void* d); static MenuItem icon_menu[] = { {_("&Open"), 0, open_cb, 0}, - {_("&Rename"), 0, rename_cb, 0}, + {_("&Edit"), 0, edit_cb, 0}, {_("&Delete"), 0, delete_cb, 0}, {0} }; @@ -80,23 +80,30 @@ static MenuItem icon_trash_menu[] = { #endif static void open_cb(Fl_Widget*, void* d) { - DesktopIcon* o = (DesktopIcon*)d; + DesktopIcon *o = (DesktopIcon*)d; run_async("ede-launch %s", o->get_cmd()); } -static void rename_cb(Fl_Widget*, void* d) { - DesktopIcon* di = (DesktopIcon*)d; +static void edit_cb(Fl_Widget*, void* d) { + DesktopIcon *di = (DesktopIcon*)d; + ((Desktop*)di->parent())->edit_icon(di); +} - const char* new_name = input(_("Change desktop icon name to:"), di->label()); +# if 0 +static void rename_cb(Fl_Widget*, void* d) { + DesktopIcon *di = (DesktopIcon*)d; + + const char *new_name = input(_("Change desktop icon name to:"), di->label()); if(new_name) { bool saved = ((Desktop*)di->parent())->rename_icon(di, new_name); if(!saved) alert(_("Unable to rename this icon. Please check if you have enough permissions to do so")); } } +#endif static void delete_cb(Fl_Widget*, void* d) { - DesktopIcon* di = (DesktopIcon*)d; + DesktopIcon *di = (DesktopIcon*)d; if(ask(_("This icon will be permanently deleted. Are you sure?"))) ((Desktop*)di->parent())->remove_icon(di, true); @@ -135,7 +142,7 @@ void DesktopIcon::set_image(const char *name) { E_RETURN_IF_FAIL(IconLoader::set(this, name, ICON_SIZE_HUGE)); /* fetch image object for sizes */ - Fl_Image* img = image(); + Fl_Image *img = image(); int img_w = img->w(), img_h = img->h(); @@ -360,6 +367,7 @@ int DesktopIcon::handle(int event) { /* MenuItem::popup() by default does not call callbacks */ const MenuItem *m = imenu->menu()->popup(Fl::event_x(), Fl::event_y()); + /* call menu callbacks, passing correct parameters */ if(m && m->callback()) m->do_callback(0, this); } diff --git a/ede-desktop/Globals.h b/ede-desktop/Globals.h index 61105d8..a936b9d 100644 --- a/ede-desktop/Globals.h +++ b/ede-desktop/Globals.h @@ -30,4 +30,6 @@ EDELIB_NS_USING_AS(Resource, DesktopConfig) #define EDE_DESKTOP_DAMAGE_OVERLAY 0x20 #define EDE_DESKTOP_DAMAGE_CLEAR_OVERLAY 0x30 +#define EDE_DESKTOP_DESKTOP_EXT ".desktop" + #endif diff --git a/ede-desktop/IconDialog.cpp b/ede-desktop/IconDialog.cpp index baa9ae4..fc6527b 100644 --- a/ede-desktop/IconDialog.cpp +++ b/ede-desktop/IconDialog.cpp @@ -19,6 +19,7 @@ */ #include +#include #include #include @@ -44,8 +45,9 @@ #include "IconDialog.h" #include "DesktopIcon.h" #include "Desktop.h" +#include "Globals.h" -EDELIB_NS_USING_LIST(10, (str_tolower, icon_chooser, dir_home, build_filename, alert, +EDELIB_NS_USING_LIST(12, (str_tolower, icon_chooser, dir_home, build_filename, alert, ask, file_remove, ICON_SIZE_HUGE, String, IconLoader, DesktopFile, DESK_FILE_TYPE_APPLICATION)) #define DEFAULT_ICON "empty" @@ -55,7 +57,8 @@ static Fl_Window *win; static Fl_Button *img, *browse, *ok, *cancel; static Fl_Input *name, *comment, *execute; static Fl_Choice *icon_type; -static String img_path; +static String img_path, old_desktop_path; +static DesktopIcon *curr_icon; /* the only supported type for now is application */ static Fl_Menu_Item menu_items[] = { @@ -105,18 +108,36 @@ static void ok_cb(Fl_Widget*, void *d) { const char *fp = file.c_str(); str_tolower((unsigned char*)fp); - file += ".desktop"; + file += EDE_DESKTOP_DESKTOP_EXT; /* go through the file and replace spaces with '_' */ for(String::size_type i = 0; i < file.length(); i++) if(isspace(file[i])) file[i] = '_'; String path = build_filename(self->desktop_path(), file.c_str()); + + int X = 0, Y = 0; + if(curr_icon) { + X = curr_icon->x(); + Y = curr_icon->y(); + /* try to remove icon from filesystem only when we can't overwrite old icon path */ + self->remove_icon(curr_icon, old_desktop_path != path); + } if(df.save(path.c_str())) { DesktopIcon *ic = self->read_desktop_file(path.c_str(), file.c_str()); - if(ic) self->add(ic); + if(ic) { + if(X > 0 || Y > 0) ic->position(X, Y); + self->add(ic); + } + self->redraw(); + + /* + * In case when we rename icon, icon position will not be saved (because they are saved by icon basename). So + * with different paths we are assured the name was changed and we proceed further. + */ + if(old_desktop_path != path) self->save_icons_positions(); } else { alert(_("Unable to create '%s' file. Received error is: %s\n"), path.c_str(), df.strerror()); } @@ -133,21 +154,68 @@ static void img_browse_cb(Fl_Widget*, void*) { static void file_browse_cb(Fl_Widget*, void*) { const char *p = fl_file_chooser(_("Choose program path to execute"), "*", 0, 0); - if(!p) return; - execute->value(p); + if(p) execute->value(p); } -void icon_dialog_icon_create(Desktop *self) { - win = new Fl_Window(430, 170, _("Create desktop icon")); +#define BUFSIZE PATH_MAX + +void icon_dialog_icon_edit(Desktop *self, DesktopIcon *d) { + const char *lbl = d ? _("Edit desktop icon") : _("Create desktop icon"); + DesktopFile *df = NULL; + char *buf = NULL; + old_desktop_path = ""; + curr_icon = d; + + if(d) { + df = new DesktopFile(); + if(!df->load(d->get_path())) { + delete df; + + int ret = ask(_("Unable to load .desktop file for this icon. Would you like to create new icon instead?")); + if(!ret) return; + + /* force NULL on icon, so we can run dialog in 'create' mode */ + d = NULL; + } + + buf = new char[BUFSIZE]; + old_desktop_path = d->get_path(); + } + + win = new Fl_Window(430, 170, lbl); img = new Fl_Button(10, 10, 75, 75); img->callback(img_browse_cb); img->tooltip(_("Click to select icon")); - IconLoader::set(img, DEFAULT_ICON, ICON_SIZE_HUGE); + + if(d) { + E_ASSERT(df != NULL); + if(df->icon(buf, BUFSIZE)) { + IconLoader::set(img, buf, ICON_SIZE_HUGE); + img_path = buf; + } + } + + /* handles even the case when we are creating the new icon */ + if(!img->image()) { + IconLoader::set(img, DEFAULT_ICON, ICON_SIZE_HUGE); + img_path = DEFAULT_ICON; + } + name = new Fl_Input(205, 10, 215, 25, _("Name:")); + if(d && df->name(buf, BUFSIZE)) + name->value(buf); + comment = new Fl_Input(205, 40, 215, 25, _("Comment:")); + if(d && df->comment(buf, BUFSIZE)) + comment->value(buf); + execute = new Fl_Input(205, 70, 185, 25, _("Execute:")); + if(d && df->exec(buf, BUFSIZE)) + execute->value(buf); + browse = new Fl_Button(395, 70, 25, 25, "..."); browse->callback(file_browse_cb); + icon_type = new Fl_Choice(205, 100, 215, 25, _("Type:")); icon_type->down_box(FL_BORDER_BOX); icon_type->menu(menu_items); @@ -158,10 +226,10 @@ void icon_dialog_icon_create(Desktop *self) { cancel->callback(cancel_cb); win->end(); win->set_modal(); + + delete df; + delete buf; Fl::focus(name); win->show(); } - -void icon_dialog_icon_property(DesktopIcon *d) { -} diff --git a/ede-desktop/IconDialog.h b/ede-desktop/IconDialog.h index 46dad69..96c2cde 100644 --- a/ede-desktop/IconDialog.h +++ b/ede-desktop/IconDialog.h @@ -24,7 +24,7 @@ class DesktopIcon; class Desktop; -void icon_dialog_icon_create(Desktop *d); -void icon_dialog_icon_property(DesktopIcon *d); +void icon_dialog_icon_edit(Desktop *self, DesktopIcon *di); +inline void icon_dialog_icon_create(Desktop *d) { icon_dialog_icon_edit(d, NULL); } #endif diff --git a/ede-desktop/Wallpaper.cpp b/ede-desktop/Wallpaper.cpp index f83eac6..b9f3652 100644 --- a/ede-desktop/Wallpaper.cpp +++ b/ede-desktop/Wallpaper.cpp @@ -476,7 +476,7 @@ int Wallpaper::handle(int event) { void Wallpaper::resize(int X, int Y, int W, int H) { if(X == x() && Y == y() && W == w() && H == h()) return; - + Fl_Box::resize(X, Y, W, H); if(image()) { /* diff --git a/ede-desktop/ede-desktop.h b/ede-desktop/ede-desktop.h deleted file mode 100644 index 60b95ec..0000000 --- a/ede-desktop/ede-desktop.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * $Id$ - * - * ede-desktop, desktop and icon manager - * Part of Equinox Desktop Environment (EDE). - * Copyright (c) 2006-2009 EDE Authors. - * - * This program is licensed under terms of the - * GNU General Public License version 2 or newer. - * See COPYING for details. - */ - -#ifndef __EDE_DESKTOP_H__ -#define __EDE_DESKTOP_H__ - -#ifdef USE_EDELIB_WINDOW -# include -# define EDE_DESKTOP_WINDOW edelib::Window -#else -# include -# include -# define EDE_DESKTOP_WINDOW Fl_Window -#endif - -#include - -#include -#include -#include -#include - -#ifdef EDELIB_HAVE_DBUS -# include -#endif - -#define EDAMAGE_CHILD_LABEL 0x10 -#define EDAMAGE_OVERLAY 0x20 - -#define ICON_NORMAL 1 // .desktop file -#define ICON_TRASH 2 // trash.desktop (specific since have two icons for empty/full) -#define ICON_FILE 3 // real file -#define ICON_SYMLINK 4 // symbolic link - -#define ICON_FACE_ONE 1 // use icon -#define ICON_FACE_TWO 2 // use icon2 - -struct GlobalIconSettings { - int label_background; - int label_foreground; - int label_font; - int label_fontsize; - int label_maxwidth; - bool label_transparent; - bool label_draw; - bool one_click_exec; - bool auto_arrange; - bool same_size; -}; - -/* - * Settings representing related to icon on desktop. To complicate our lives - * (and to, at least, simplify code) it can be: - * - .desktop file content (normal or trash like) - * - real file copied/moved inside ~/Desktop directory - * - symlink in ~/Desktop directory pointing to the real file - */ -struct IconSettings { - int x, y; - int type; // ICON_NORMAL, ICON_TRASH,... - bool cmd_is_url; // interpret cmd as url, like system:/,trash:/,$HOME - - edelib::String name; - edelib::String cmd; - edelib::String icon; - edelib::String icon2; // for stateable icons, like trash (empty/full) - edelib::String key_name; // name used as key when storing positions - edelib::String full_path; // for tracking changes -}; - -/* selection overlay */ -struct SelectionOverlay { - int x, y, w, h; - bool show; -}; - -class Wallpaper; -class DesktopIcon; - -typedef edelib::list DesktopIconList; -typedef edelib::list::iterator DesktopIconListIter; - -typedef edelib::list StringList; -typedef edelib::list::iterator StringListIter; - -class Desktop : public EDE_DESKTOP_WINDOW { -private: - static Desktop* pinstance; - - int selection_x, selection_y; - - /* last recorded pointer position, so icon can be created at position where menu is clicked */ - int last_px, last_py; - - bool moving; - bool do_dirwatch; - - edelib::String desktop_dir_path; - - SelectionOverlay* selbox; - - GlobalIconSettings* gisett; - - edelib::MenuButton* dmenu; - Wallpaper* wallpaper; - -#ifdef EDELIB_HAVE_DBUS - edelib::EdbusConnection* dbus; -#endif - - DesktopIconList icons; - DesktopIconList selectionbuf; - - void init_internals(void); - - void load_icons(const char* path); - void save_icons_positions(void); - IconSettings* read_desktop_file(const char* path); - - void add_icon(DesktopIcon* ic); - - DesktopIcon* find_icon_by_path(const char* path, DesktopIconListIter* pos); - bool remove_icon_by_path(const char* path); - - void auto_arrange(void); - - void unfocus_all(void); - - void select(DesktopIcon* ic, bool do_redraw = true); - void select_only(DesktopIcon* ic); - bool in_selection(const DesktopIcon* ic); - void move_selection(int x, int y, bool apply); - - void select_in_area(void); - - //void dnd_drop_source(const char* src, int src_len, int x, int y); - - DesktopIcon* below_mouse(int px, int py); - -public: - Desktop(); - ~Desktop(); - - virtual void show(void); - virtual void hide(void); - virtual void draw(void); - virtual int handle(int event); - - static void init(void); - static void shutdown(void); - static Desktop* instance(void); - - void read_config(void); - - bool add_icon_by_path(const char* path, edelib::Resource* conf); - bool remove_icon(DesktopIcon *d, bool real_delete); - bool rename_icon(DesktopIcon *d, const char *n); - - void update_workarea(void); - void area(int& X, int& Y, int& W, int& H) { X = x(); Y = y(); W = w(); H = h(); } - - 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; } - - const char *desktop_path(void) { return desktop_dir_path.c_str(); } -}; - -#endif