enlightenment-module-extramenu/src/e_mod_main.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);
}