DesktopFiles::DesktopFiles(QObject *parent) : QObject(parent), m_interface("io.papyros.session", "/PapyrosSession", "io.papyros.launcher", QDBusConnection::sessionBus()) { QStringList iconSearchPaths; iconSearchPaths << "/usr/share/icons" << "/usr/share/pixmaps" << QDir::homePath() + "/.local/share/icons"; QIcon::setThemeSearchPaths(iconSearchPaths); QStringList paths; paths << QDir::homePath() + "/.local/share/applications" << "/usr/local/share/applications" << "/usr/share/applications"; QStringList filter; filter << "*.desktop"; QStringList files = filesInPaths(paths, filter); for (QString fileName : files) { DesktopFile *desktopFile = new DesktopFile(fileName, this); if (desktopFile->isShown()) desktopList << desktopFile; } desktopList.sort(DesktopFiles::compare); fileWatcher = new QFileSystemWatcher(files, this); dirWatcher = new QFileSystemWatcher(paths, this); connect(fileWatcher, &QFileSystemWatcher::fileChanged, this, &DesktopFiles::onFileChanged); connect(dirWatcher, &QFileSystemWatcher::directoryChanged, this, &DesktopFiles::onDirectoryChanged); }
int DesktopFiles::indexOfName(QString name) { for (int i = 0; i < desktopList.length(); i++) { DesktopFile *desktopFile = desktopList.at(i); if (desktopFile->name().startsWith(name, Qt::CaseInsensitive)) return i; } return -1; }
bool Desktop::rename_icon(DesktopIcon *di, const char *name) { di->copy_label(name); di->update_label_font_and_size(); di->fast_redraw(); /* open file and try to change the name */ DesktopFile df; E_RETURN_VAL_IF_FAIL(df.load(di->get_path()) == true, false); df.set_name(name); return df.save(di->get_path()); }
DesktopIcon *Desktop::read_desktop_file(const char *path, const char *base, DesktopConfig *pos) { DesktopIcon *ret = NULL; if(file_test(path, FILE_TEST_IS_DIR)) { ret = new DesktopIcon(_("No Name")); ret->set_icon_type(DESKTOP_ICON_TYPE_FOLDER); /* hardcoded */ ret->set_image("folder"); /* copy label explicitly, as DesktopIcon() will only store a pointer */ ret->copy_label(base); } else { /* * try to load it as plain .desktop file by looking only at extension * TODO: MimeType can be used here too */ if(!str_ends(path, EDE_DESKTOP_DESKTOP_EXT)) return ret; DesktopFile df; char buf[PATH_MAX]; E_RETURN_VAL_IF_FAIL(df.load(path), ret); E_RETURN_VAL_IF_FAIL(df.type() != DESK_FILE_TYPE_UNKNOWN, ret); ret = new DesktopIcon(_("No Name")); ret->set_icon_type(DESKTOP_ICON_TYPE_NORMAL); if(df.name(buf, sizeof(buf))) ret->copy_label(buf); ret->set_image(df.icon(buf, sizeof(buf)) ? buf : NULL); if(df.comment(buf, sizeof(buf))) ret->set_tooltip(buf); } /* try to put random icon position in the middle of the desktop, so it is easier to notice */ int X = (rand() % (w() / 4)) + (w() / 4); int Y = (rand() % (h() / 4)) + (h() / 4); /* lookup icons locations if possible */ if(base && pos && *pos) { pos->get(base, "X", X, X); pos->get(base, "Y", Y, Y); } E_DEBUG("Setting icon '%s' (%i,%i)\n", base, X, Y); ret->position(X, Y); /* use loaded icon options */ ret->set_options(icon_opts); ret->set_path(path); return ret; }
static void ok_cb(Fl_Widget*, void *d) { if(is_empty_input(name) || is_empty_input(execute) || !img->image()) { /* do nothing */ win->hide(); return; } Desktop *self = (Desktop*)d; DesktopFile df; df.create_new(DESK_FILE_TYPE_APPLICATION); df.set_name(name->value()); if(comment->value()) df.set_comment(comment->value()); df.set_icon((img_path.length() > 1) ? img_path.c_str() : DEFAULT_ICON); df.set_exec(execute->value()); if(!is_empty_input(workdir)) df.set_path(workdir->value()); df.set_startup_notify(start_notify->value()); df.set_terminal(run_in_terminal->value()); /* determine filename and save it */ String file = name->value(); const char *fp = file.c_str(); str_tolower((unsigned char*)fp); 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) { 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()); } win->hide(); }
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; df = NULL; int ret = ask(_("Unable to load .desktop file for this icon. Would you like to create a 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(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(); 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); win->end(); win->set_modal(); delete df; delete buf; Fl::focus(name); win->show(); }