240 lines
6.3 KiB
C
240 lines
6.3 KiB
C
/* Copyright (C) 2008-2015 Davide Andreoli (see AUTHORS)
|
|
*
|
|
* This file is part of extramenu.
|
|
* extramenu is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* extramenu 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 Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with extramenu. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <e.h>
|
|
#include "e_mod_main.h"
|
|
#include "config.h"
|
|
|
|
static int _extramenu_new(const char *file);
|
|
static void _extramenu_prepare_menu(void *data, E_Menu *em);
|
|
static void _extramenu_generate_menu(void *data, E_Menu *em);
|
|
static void _extramenu_desktop_run(void *data, E_Menu *m, E_Menu_Item *mi);
|
|
static void _extramenu_set_menuitem_icon(const char *icon, E_Menu_Item *mi);
|
|
static void _extramenu_parse_dir(const char *dir);
|
|
static void _extramenu_clear_all_menus(void);
|
|
static void _extramenu_monitor_cb(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path);
|
|
|
|
static Eina_List *extramenu_menus;
|
|
Ecore_File_Monitor *extramenu_mon1, *extramenu_mon2;
|
|
|
|
/***************************************************************************/
|
|
|
|
/* module setup */
|
|
EAPI E_Module_Api e_modapi =
|
|
{
|
|
E_MODULE_API_VERSION,
|
|
"Extra Menu"
|
|
};
|
|
|
|
|
|
EAPI void *
|
|
e_modapi_init(E_Module *m)
|
|
{
|
|
char dir[PATH_MAX];
|
|
|
|
/* search in user dir */
|
|
snprintf(dir, PATH_MAX, "%s/"MENU_USER_DIR, e_user_homedir_get());
|
|
_extramenu_parse_dir(dir);
|
|
|
|
/* search in system dir */
|
|
_extramenu_parse_dir(MENU_SYSTEM_DIR);
|
|
|
|
/* keep the folder monitored for changes */
|
|
extramenu_mon1 = ecore_file_monitor_add(dir, _extramenu_monitor_cb, NULL);
|
|
extramenu_mon2 = ecore_file_monitor_add(MENU_SYSTEM_DIR, _extramenu_monitor_cb, NULL);
|
|
|
|
return m;
|
|
}
|
|
|
|
EAPI int
|
|
e_modapi_shutdown(E_Module *m)
|
|
{
|
|
E_FREE_FUNC(extramenu_mon1, ecore_file_monitor_del);
|
|
E_FREE_FUNC(extramenu_mon2, ecore_file_monitor_del);
|
|
_extramenu_clear_all_menus();
|
|
|
|
return 1;
|
|
}
|
|
|
|
EAPI int
|
|
e_modapi_save(E_Module *m)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
static void
|
|
_extramenu_parse_dir(const char *dir)
|
|
{
|
|
Eina_List *files;
|
|
char *filename;
|
|
char buf[PATH_MAX];
|
|
|
|
files = ecore_file_ls(dir);
|
|
EINA_LIST_FREE(files, filename)
|
|
{
|
|
snprintf(buf, sizeof(buf), "%s/%s", dir, filename);
|
|
_extramenu_new(buf);
|
|
free(filename);
|
|
}
|
|
}
|
|
|
|
static int
|
|
_extramenu_new(const char *file)
|
|
{
|
|
Efreet_Menu *efreet_menu;
|
|
Extra_Menu *menu;
|
|
char *placement = NULL;
|
|
|
|
efreet_menu = efreet_menu_parse(file);
|
|
if (!efreet_menu || !efreet_menu->name) return 0;
|
|
|
|
menu = E_NEW(Extra_Menu, 1);
|
|
if (!menu) return 0;
|
|
|
|
if (efreet_menu->desktop && efreet_menu->desktop->x)
|
|
placement = eina_hash_find(efreet_menu->desktop->x, "X-Enlightenment-Menu");
|
|
if (!placement)
|
|
placement = DEFAULT_MENU_PLACEMENT;
|
|
|
|
menu->menu = eina_stringshare_add(placement);
|
|
menu->maug = e_int_menus_menu_augmentation_add(placement,
|
|
_extramenu_prepare_menu,
|
|
efreet_menu,
|
|
NULL, NULL);
|
|
menu->efreet_menu = efreet_menu;
|
|
extramenu_menus = eina_list_append(extramenu_menus, menu);
|
|
return 1;
|
|
}
|
|
|
|
static void
|
|
_extramenu_prepare_menu(void *data, E_Menu *em)
|
|
{
|
|
Efreet_Menu *menu = data;
|
|
E_Menu_Item *mi;
|
|
E_Menu *m;
|
|
|
|
if (!menu || !em) return;
|
|
|
|
mi = e_menu_item_new(em);
|
|
e_menu_item_label_set(mi, menu->name);
|
|
_extramenu_set_menuitem_icon(menu->icon, mi);
|
|
|
|
m = e_menu_new();
|
|
e_menu_item_submenu_set(mi, m);
|
|
|
|
e_menu_pre_activate_callback_set(m, _extramenu_generate_menu, menu);
|
|
}
|
|
|
|
static void
|
|
_extramenu_generate_menu(void *data, E_Menu *em)
|
|
{
|
|
Efreet_Menu *menu = data;
|
|
E_Menu_Item *mi;
|
|
Efreet_Menu *sub;
|
|
Eina_List *l;
|
|
|
|
//printf("**GENERATE MENU: %s (type: %d size: %d)\n", menu->name,
|
|
// menu->type, ecore_list_count(menu->entries));
|
|
|
|
EINA_LIST_FOREACH(menu->entries, l, sub)
|
|
{
|
|
switch (sub->type)
|
|
{
|
|
case EFREET_MENU_ENTRY_MENU:
|
|
_extramenu_prepare_menu(sub, em);
|
|
break;
|
|
case EFREET_MENU_ENTRY_DESKTOP:
|
|
mi = e_menu_item_new(em);
|
|
e_menu_item_label_set(mi, sub->desktop->name);
|
|
_extramenu_set_menuitem_icon(sub->desktop->icon, mi);
|
|
e_menu_item_callback_set(mi, _extramenu_desktop_run, sub->desktop);
|
|
break;
|
|
case EFREET_MENU_ENTRY_SEPARATOR:
|
|
mi = e_menu_item_new(em);
|
|
e_menu_item_separator_set(mi, 1);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
e_menu_pre_activate_callback_set(em, NULL, NULL);
|
|
}
|
|
|
|
static void
|
|
_extramenu_desktop_run(void *data, E_Menu *m, E_Menu_Item *mi)
|
|
{
|
|
e_exec(m->zone, (Efreet_Desktop *)data, NULL, NULL, "menu/apps");
|
|
}
|
|
|
|
static void
|
|
_extramenu_set_menuitem_icon(const char *icon, E_Menu_Item *mi)
|
|
{
|
|
const char *file = NULL;
|
|
|
|
if (!icon || !mi) return;
|
|
|
|
if (icon[0] == '/')
|
|
e_menu_item_icon_file_set(mi, icon);
|
|
else
|
|
{
|
|
file = efreet_icon_path_find(e_config->icon_theme, icon, 24);
|
|
if (file)
|
|
e_menu_item_icon_file_set(mi, file);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_extramenu_clear_all_menus(void)
|
|
{
|
|
Extra_Menu *menu;
|
|
|
|
EINA_LIST_FREE(extramenu_menus, menu)
|
|
{
|
|
e_int_menus_menu_augmentation_del(menu->menu, menu->maug);
|
|
E_FREE_FUNC(menu->efreet_menu, efreet_menu_free);
|
|
E_FREE_FUNC(menu->menu, eina_stringshare_del);
|
|
free(menu);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_extramenu_monitor_cb(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path)
|
|
{
|
|
char dir[PATH_MAX];
|
|
|
|
switch (event)
|
|
{
|
|
case ECORE_FILE_EVENT_NONE:
|
|
case ECORE_FILE_EVENT_CREATED_DIRECTORY:
|
|
return;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* destroy all menus */
|
|
_extramenu_clear_all_menus();
|
|
|
|
/* recreate all menus */
|
|
snprintf(dir, PATH_MAX, "%s/"MENU_USER_DIR, e_user_homedir_get());
|
|
_extramenu_parse_dir(dir);
|
|
_extramenu_parse_dir(MENU_SYSTEM_DIR);
|
|
}
|
|
|
|
|