2012-04-25 20:28:09 +04:00
|
|
|
/*
|
2013-05-30 17:07:49 +04:00
|
|
|
* $Id: ede-panel.cpp 3463 2012-12-17 15:49:33Z karijes $
|
2012-04-25 20:28:09 +04:00
|
|
|
*
|
2014-02-25 22:16:10 +04:00
|
|
|
* Copyright (C) 2006-2014 Sanel Zukan
|
2013-05-30 17:07:49 +04:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2012-04-25 20:28:09 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <ctype.h>
|
2013-06-24 18:40:28 +04:00
|
|
|
#include <limits.h>
|
2012-04-25 20:28:09 +04:00
|
|
|
|
|
|
|
#include <FL/Fl_Window.H>
|
|
|
|
#include <FL/Fl.H>
|
|
|
|
#include <FL/Fl_Button.H>
|
|
|
|
#include <FL/Fl_Input.H>
|
|
|
|
#include <FL/Fl_Choice.H>
|
2012-05-07 12:53:13 +04:00
|
|
|
#include <FL/Fl_Menu_Item.H>
|
2012-04-25 20:28:09 +04:00
|
|
|
#include <FL/Fl_Shared_Image.H>
|
2012-05-10 15:19:19 +04:00
|
|
|
#include <FL/Fl_File_Chooser.H>
|
2014-02-25 22:16:10 +04:00
|
|
|
#include <FL/Fl_Tabs.H>
|
|
|
|
#include <FL/Fl_Group.H>
|
|
|
|
#include <FL/Fl_Check_Button.H>
|
2012-04-25 20:28:09 +04:00
|
|
|
|
|
|
|
#include <edelib/Nls.h>
|
|
|
|
#include <edelib/String.h>
|
|
|
|
#include <edelib/IconChooser.h>
|
|
|
|
#include <edelib/DesktopFile.h>
|
|
|
|
#include <edelib/Debug.h>
|
|
|
|
#include <edelib/Directory.h>
|
|
|
|
#include <edelib/File.h>
|
|
|
|
#include <edelib/StrUtil.h>
|
|
|
|
#include <edelib/Util.h>
|
|
|
|
#include <edelib/MessageBox.h>
|
2012-05-15 16:49:16 +04:00
|
|
|
#include <edelib/IconLoader.h>
|
2012-04-25 20:28:09 +04:00
|
|
|
|
|
|
|
#include "IconDialog.h"
|
|
|
|
#include "DesktopIcon.h"
|
2013-05-30 17:07:49 +04:00
|
|
|
#include "Desktop.h"
|
2013-06-24 18:40:28 +04:00
|
|
|
#include "Globals.h"
|
2012-04-25 20:28:09 +04:00
|
|
|
|
2013-06-24 18:40:28 +04:00
|
|
|
EDELIB_NS_USING_LIST(12, (str_tolower, icon_chooser, dir_home, build_filename, alert, ask, file_remove,
|
2012-05-15 16:49:16 +04:00
|
|
|
ICON_SIZE_HUGE, String, IconLoader, DesktopFile, DESK_FILE_TYPE_APPLICATION))
|
|
|
|
|
|
|
|
#define DEFAULT_ICON "empty"
|
2012-04-25 20:28:09 +04:00
|
|
|
|
|
|
|
/* it is safe to be globals */
|
2014-02-25 22:16:10 +04:00
|
|
|
static Fl_Window *win;
|
|
|
|
static Fl_Button *img, *browse, *ok, *cancel;
|
|
|
|
static Fl_Input *name, *comment, *execute, *workdir;
|
|
|
|
static Fl_Choice *icon_type;
|
|
|
|
static Fl_Check_Button *run_in_terminal, *start_notify;
|
|
|
|
static String img_path, old_desktop_path;
|
|
|
|
static DesktopIcon *curr_icon;
|
2012-04-25 20:28:09 +04:00
|
|
|
|
2012-05-07 12:53:13 +04:00
|
|
|
/* the only supported type for now is application */
|
|
|
|
static Fl_Menu_Item menu_items[] = {
|
|
|
|
{_("Application"), 0, 0, 0},
|
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
2012-04-25 20:28:09 +04:00
|
|
|
static bool is_empty(const char *str) {
|
|
|
|
if(!str) return true;
|
|
|
|
const char *p = str;
|
|
|
|
|
2014-02-25 22:16:10 +04:00
|
|
|
while(*p++) {
|
2012-04-25 20:28:09 +04:00
|
|
|
if(!isspace(*p)) return false;
|
2014-02-25 22:16:10 +04:00
|
|
|
}
|
2012-04-25 20:28:09 +04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool is_empty_input(Fl_Input *i) {
|
|
|
|
return is_empty(i->value());
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cancel_cb(Fl_Widget*, void*) {
|
|
|
|
win->hide();
|
|
|
|
}
|
|
|
|
|
2013-05-30 17:07:49 +04:00
|
|
|
static void ok_cb(Fl_Widget*, void *d) {
|
2012-04-25 20:28:09 +04:00
|
|
|
if(is_empty_input(name) || is_empty_input(execute) || !img->image()) {
|
|
|
|
/* do nothing */
|
|
|
|
win->hide();
|
|
|
|
return;
|
|
|
|
}
|
2013-05-30 17:07:49 +04:00
|
|
|
|
|
|
|
Desktop *self = (Desktop*)d;
|
|
|
|
|
2012-04-25 20:28:09 +04:00
|
|
|
DesktopFile df;
|
|
|
|
df.create_new(DESK_FILE_TYPE_APPLICATION);
|
|
|
|
df.set_name(name->value());
|
|
|
|
|
|
|
|
if(comment->value())
|
|
|
|
df.set_comment(comment->value());
|
|
|
|
|
2012-12-26 05:53:08 +04:00
|
|
|
df.set_icon((img_path.length() > 1) ? img_path.c_str() : DEFAULT_ICON);
|
2012-04-25 20:28:09 +04:00
|
|
|
df.set_exec(execute->value());
|
2014-02-25 22:16:10 +04:00
|
|
|
|
|
|
|
if(!is_empty_input(workdir))
|
|
|
|
df.set_path(workdir->value());
|
|
|
|
|
|
|
|
df.set_startup_notify(start_notify->value());
|
|
|
|
df.set_terminal(run_in_terminal->value());
|
2012-04-25 20:28:09 +04:00
|
|
|
|
|
|
|
/* determine filename and save it */
|
|
|
|
String file = name->value();
|
|
|
|
const char *fp = file.c_str();
|
|
|
|
|
|
|
|
str_tolower((unsigned char*)fp);
|
2013-06-24 18:40:28 +04:00
|
|
|
file += EDE_DESKTOP_DESKTOP_EXT;
|
2012-04-25 20:28:09 +04:00
|
|
|
|
2012-05-18 16:06:32 +04:00
|
|
|
/* go through the file and replace spaces with '_' */
|
2013-05-30 17:07:49 +04:00
|
|
|
for(String::size_type i = 0; i < file.length(); i++)
|
|
|
|
if(isspace(file[i])) file[i] = '_';
|
2012-05-18 16:06:32 +04:00
|
|
|
|
2013-05-30 17:07:49 +04:00
|
|
|
String path = build_filename(self->desktop_path(), file.c_str());
|
2013-06-24 18:40:28 +04:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2012-04-25 20:28:09 +04:00
|
|
|
|
|
|
|
if(df.save(path.c_str())) {
|
2013-05-30 17:07:49 +04:00
|
|
|
DesktopIcon *ic = self->read_desktop_file(path.c_str(), file.c_str());
|
2013-06-24 18:40:28 +04:00
|
|
|
if(ic) {
|
|
|
|
if(X > 0 || Y > 0) ic->position(X, Y);
|
|
|
|
self->add(ic);
|
|
|
|
}
|
|
|
|
|
2013-05-30 17:07:49 +04:00
|
|
|
self->redraw();
|
2013-06-24 18:40:28 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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();
|
2012-04-25 20:28:09 +04:00
|
|
|
} else {
|
|
|
|
alert(_("Unable to create '%s' file. Received error is: %s\n"), path.c_str(), df.strerror());
|
|
|
|
}
|
|
|
|
|
|
|
|
win->hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void img_browse_cb(Fl_Widget*, void*) {
|
|
|
|
img_path = icon_chooser(ICON_SIZE_HUGE);
|
|
|
|
|
2013-01-04 19:01:55 +04:00
|
|
|
if(!img_path.empty())
|
|
|
|
IconLoader::set(img, img_path.c_str(), ICON_SIZE_HUGE);
|
2012-04-25 20:28:09 +04:00
|
|
|
}
|
|
|
|
|
2012-05-10 15:19:19 +04:00
|
|
|
static void file_browse_cb(Fl_Widget*, void*) {
|
|
|
|
const char *p = fl_file_chooser(_("Choose program path to execute"), "*", 0, 0);
|
2013-06-24 18:40:28 +04:00
|
|
|
if(p) execute->value(p);
|
2012-05-10 15:19:19 +04:00
|
|
|
}
|
|
|
|
|
2014-02-25 22:16:10 +04:00
|
|
|
static void dir_browse_cb(Fl_Widget*, void*) {
|
|
|
|
const char *p = fl_dir_chooser(_("Choose directory"), "*", 0);
|
|
|
|
if(p) workdir->value(p);
|
|
|
|
}
|
|
|
|
|
2013-06-24 18:40:28 +04:00
|
|
|
#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;
|
2014-02-25 22:16:10 +04:00
|
|
|
df = NULL;
|
2013-06-24 18:40:28 +04:00
|
|
|
|
2014-02-25 22:16:10 +04:00
|
|
|
int ret = ask(_("Unable to load .desktop file for this icon. Would you like to create a new icon instead?"));
|
2013-06-24 18:40:28 +04:00
|
|
|
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();
|
|
|
|
}
|
2014-02-25 22:16:10 +04:00
|
|
|
|
|
|
|
win = new Fl_Window(450, 220, lbl);
|
|
|
|
Fl_Tabs *tabs = new Fl_Tabs(10, 10, 430, 165);
|
|
|
|
tabs->begin();
|
|
|
|
Fl_Group *g1 = new Fl_Group(15, 30, 415, 140, _("Basic"));
|
|
|
|
g1->begin();
|
|
|
|
img = new Fl_Button(20, 45, 80, 75);
|
|
|
|
img->callback(img_browse_cb);
|
|
|
|
img->tooltip(_("Click to select icon"));
|
|
|
|
|
|
|
|
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(210, 45, 215, 25, _("Name:"));
|
|
|
|
if(d && df->name(buf, BUFSIZE)) name->value(buf);
|
|
|
|
|
|
|
|
comment = new Fl_Input(210, 75, 215, 25, _("Comment:"));
|
|
|
|
if(d && df->comment(buf, BUFSIZE)) comment->value(buf);
|
|
|
|
|
|
|
|
execute = new Fl_Input(210, 105, 185, 25, _("Execute:"));
|
|
|
|
if(d && df->exec(buf, BUFSIZE)) execute->value(buf);
|
|
|
|
|
|
|
|
browse = new Fl_Button(400, 105, 25, 25, "...");
|
|
|
|
browse->callback(file_browse_cb);
|
|
|
|
|
|
|
|
icon_type = new Fl_Choice(210, 135, 215, 25, _("Type:"));
|
|
|
|
icon_type->down_box(FL_BORDER_BOX);
|
|
|
|
icon_type->menu(menu_items);
|
|
|
|
g1->end();
|
2013-06-24 18:40:28 +04:00
|
|
|
|
2014-02-25 22:16:10 +04:00
|
|
|
Fl_Group *g2 = new Fl_Group(15, 30, 420, 140, _("Details"));
|
|
|
|
g2->hide();
|
|
|
|
g2->begin();
|
|
|
|
run_in_terminal = new Fl_Check_Button(195, 80, 235, 25, _("Run in terminal"));
|
|
|
|
run_in_terminal->down_box(FL_DOWN_BOX);
|
|
|
|
if(df) run_in_terminal->value(df->terminal());
|
|
|
|
|
|
|
|
workdir = new Fl_Input(195, 45, 205, 25, _("Working directory:"));
|
|
|
|
if(df && df->path(buf, BUFSIZE)) workdir->value(buf);
|
|
|
|
|
|
|
|
Fl_Button *browsedir = new Fl_Button(405, 45, 25, 25, "...");
|
|
|
|
browsedir->callback(dir_browse_cb);
|
|
|
|
|
|
|
|
start_notify = new Fl_Check_Button(195, 110, 235, 25, _("Use startup notification"));
|
|
|
|
start_notify->down_box(FL_DOWN_BOX);
|
|
|
|
if(df) start_notify->value(df->startup_notify());
|
|
|
|
g2->end();
|
|
|
|
tabs->end();
|
|
|
|
|
|
|
|
ok = new Fl_Button(255, 185, 90, 25, _("&OK"));
|
|
|
|
ok->callback(ok_cb, self);
|
|
|
|
cancel = new Fl_Button(350, 185, 90, 25, _("&Cancel"));
|
|
|
|
cancel->callback(cancel_cb);
|
2012-04-25 20:28:09 +04:00
|
|
|
|
|
|
|
win->end();
|
2012-05-07 12:53:13 +04:00
|
|
|
win->set_modal();
|
2013-06-24 18:40:28 +04:00
|
|
|
|
|
|
|
delete df;
|
|
|
|
delete buf;
|
2012-05-15 16:51:09 +04:00
|
|
|
|
|
|
|
Fl::focus(name);
|
2012-04-25 20:28:09 +04:00
|
|
|
win->show();
|
2014-02-25 22:16:10 +04:00
|
|
|
}
|