1 /***************************************************
2 TODO option for maximum items to cache
3 TODO keep common list for recent file instances
9 #include <Efreet_Trash.h>
11 #define MOD_CONFIG_FILE_EPOCH 0x0001
12 #define MOD_CONFIG_FILE_GENERATION 0x008d
13 #define MOD_CONFIG_FILE_VERSION \
14 ((MOD_CONFIG_FILE_EPOCH << 16) | MOD_CONFIG_FILE_GENERATION)
18 #define TERM_ACTION_DIR "%s"
21 #define CMD_SHOW_ROOT 1
22 #define CMD_SHOW_HIDDEN 2
23 #define CMD_SHOW_PARENT 3
29 #define ACT_SORT_DATE 5
30 #define ACT_SORT_NAME 6
32 #define ONE_DAY 86400.0
33 #define SIX_DAYS_AGO (ecore_time_unix_get() - ONE_DAY * 6)
37 * #define DBG(...) ERR(__VA_ARGS__) */
39 typedef struct _Plugin Plugin;
40 typedef struct _Data Data;
41 typedef struct _Module_Config Module_Config;
48 const char *directory;
51 unsigned int min_query;
53 Eina_Bool show_hidden;
55 Eina_Bool show_recent;
56 Eina_Bool sort_by_date;
59 Ecore_File_Monitor *dir_mon;
60 int waiting_to_finish;
79 unsigned char show_homedir;
80 unsigned char show_recent;
81 unsigned char search_recent;
82 unsigned char cache_dirs;
83 unsigned char search_cache;
87 Eina_List *search_dirs;
93 static const Evry_API *evry = NULL;
94 static Evry_Module *evry_module = NULL;
96 static Module_Config *_conf;
97 static char _module_icon[] = "system-file-manager";
98 static Eina_List *_plugins = NULL;
99 static Eina_List *_actions = NULL;
100 static const char *_mime_dir;
101 static const char *_mime_mount;
102 static const char *_mime_unknown;
103 static Eina_Bool clear_cache = EINA_FALSE;
105 /***************************************************************************/
108 _item_fill(Evry_Item_File *file)
112 const char *mime = efreet_mime_type_get(file->path);
115 file->mime = eina_stringshare_ref(mime);
117 file->mime = eina_stringshare_add("unknown");
120 if ((file->mime == _mime_dir) ||
121 (file->mime == _mime_mount))
122 EVRY_ITEM(file)->browseable = EINA_TRUE;
124 EVRY_ITEM(file)->context = eina_stringshare_ref(file->mime);
126 if (!EVRY_ITEM(file)->detail)
127 evry->util_file_detail_set(file);
129 evry->util_file_detail_set(file);
133 _cb_sort(const void *data1, const void *data2)
135 const Evry_Item *it1 = data1;
136 const Evry_Item *it2 = data2;
138 if (it1->browseable && !it2->browseable)
141 if (!it1->browseable && it2->browseable)
144 if (it1->fuzzy_match && it2->fuzzy_match)
145 if (it1->fuzzy_match - it2->fuzzy_match)
146 return it1->fuzzy_match - it2->fuzzy_match;
148 return strcasecmp(it1->label, it2->label);
152 _cb_sort_date(const void *data1, const void *data2)
154 const Evry_Item_File *it1 = data1;
155 const Evry_Item_File *it2 = data2;
157 return it2->modified - it1->modified;
161 _scan_func(void *data, Ecore_Thread *thread)
165 Eina_File_Direct_Info *info;
166 Evry_Item_File *file;
168 if (!(ls = eina_file_stat_ls(d->directory)))
171 EINA_ITERATOR_FOREACH (ls, info)
173 if ((d->plugin->show_hidden) != (*(info->path + info->name_start) == '.'))
176 file = EVRY_ITEM_NEW(Evry_Item_File, d->plugin, NULL, NULL, evry_item_file_free);
177 file->path = strdup(info->path);
178 EVRY_ITEM(file)->label = strdup(info->path + info->name_start);
179 EVRY_ITEM(file)->browseable = (info->type == EINA_FILE_DIR);
181 d->files = eina_list_append(d->files, file);
182 /* TODO dont append files in thread, run mime scan
183 * simultaneously. ecore_thread_feedback(thread, file); */
185 if (ecore_thread_check(thread))
189 eina_iterator_free(ls);
193 _scan_mime_func(void *data, Ecore_Thread *thread)
196 Evry_Item_File *file;
200 EINA_LIST_FOREACH (d->files, l, file)
202 if (ecore_thread_check(thread))
205 if ((file->mime = efreet_mime_type_get(file->path)))
207 if (!strncmp(file->mime, "inode/", 6) &&
208 ecore_file_is_dir(file->path))
209 EVRY_ITEM(file)->browseable = EINA_TRUE;
212 file->mime = _mime_unknown;
214 if (cnt++ > MAX_ITEMS * d->run_cnt) break;
219 _files_filter(Plugin *p)
225 unsigned int len = p->input ? strlen(p->input) : 0;
227 EVRY_PLUGIN_ITEMS_CLEAR(p);
229 if (!p->command && p->min_query)
233 if (len < p->min_query)
237 EINA_LIST_FOREACH (p->files, l, it)
239 if (cnt >= MAX_SHOWN) break;
241 if (p->dirs_only && !it->browseable)
244 if (len && (match = evry->fuzzy_match(it->label, p->input)))
246 it->fuzzy_match = match;
249 EVRY_PLUGIN_ITEM_APPEND(p, it);
256 EVRY_PLUGIN_ITEM_APPEND(p, it);
264 _scan_cancel_func(void *data, Ecore_Thread *thread __UNUSED__)
267 Plugin *p = d->plugin;
268 Evry_Item_File *file;
270 /* EINA_LIST_FREE(p->files, file)
271 * EVRY_ITEM_FREE(file); */
273 EINA_LIST_FREE (d->files, file)
275 if (file->base.label) free((char *)(file->base.label));
276 if (file->path) free((char *)file->path);
282 if (p->waiting_to_finish)
290 _cache_mime_get(History_Types *ht, Evry_Item_File *file)
296 if ((he = eina_hash_find(ht->types, file->path)))
298 EINA_LIST_FOREACH (he->items, l, hi)
304 file->mime = hi->data;
307 EVRY_ITEM(file)->hi = hi;
314 _cache_dir_add(Eina_List *files)
321 EINA_LIST_REVERSE_FOREACH (files, l, item)
323 GET_FILE(file, item);
326 (hi = evry->history_item_add(item, NULL, NULL)))
328 hi->last_used = SIX_DAYS_AGO;
329 hi->usage = MIN_USAGE * (double)cnt++;
330 hi->data = eina_stringshare_ref(file->mime);
333 else if (item->hi && (item->hi->count == 1) &&
334 (item->hi->last_used < SIX_DAYS_AGO))
336 item->hi->last_used = SIX_DAYS_AGO;
337 item->hi->usage = MIN_USAGE * (double)cnt++;
343 _file_add(Plugin *p, Evry_Item *item)
345 GET_FILE(file, item);
347 char *filename = (char *)item->label;
348 char *path = (char *)file->path;
350 file->path = eina_stringshare_add(path);
351 file->mime = eina_stringshare_ref(file->mime);
353 item->label = eina_stringshare_add(filename);
354 item->id = eina_stringshare_ref(file->path);
355 item->context = eina_stringshare_ref(file->mime);
357 evry->util_file_detail_set(file);
359 p->files = eina_list_append(p->files, file);
366 _scan_end_func(void *data, Ecore_Thread *thread __UNUSED__)
369 Plugin *p = d->plugin;
371 Evry_Item_File *file;
373 History_Types *ht = NULL;
375 if (_conf->cache_dirs)
376 ht = evry->history_types_get(EVRY_TYPE_FILE);
378 if (!d->run_cnt) /* _scan_func finished */
380 EINA_LIST_FOREACH_SAFE (d->files, l, ll, item)
382 GET_FILE(file, item);
384 if (item->browseable)
385 file->mime = _mime_dir;
387 _cache_mime_get(ht, file);
391 d->files = eina_list_remove_list(d->files, l);
396 /* sort files by name for mimetypes scan */
398 d->files = eina_list_sort(d->files, -1, _cb_sort);
400 else /* _scan_mime_func finished */
402 EINA_LIST_FREE (d->files, file)
404 if (!file->mime) break;
405 _file_add(p, (Evry_Item *)file);
409 if (d->files) /* scan mimetypes */
412 p->thread = ecore_thread_run(_scan_mime_func,
414 _scan_cancel_func, d);
416 /* wait for first mime scan to finish */
417 if (d->run_cnt == 1) return;
419 else /* finished all file/mime scan */
425 if (_conf->cache_dirs && !(p->command == CMD_SHOW_HIDDEN))
426 _cache_dir_add(p->files);
429 p->files = eina_list_sort(p->files, -1, _cb_sort);
433 EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD);
437 _dir_watcher(void *data, Ecore_File_Monitor *em __UNUSED__, Ecore_File_Event event, const char *path)
440 Evry_Item_File *file;
446 case ECORE_FILE_EVENT_DELETED_SELF:
447 EINA_LIST_FREE (p->files, file)
448 evry->item_free(EVRY_ITEM(file));
451 case ECORE_FILE_EVENT_CREATED_DIRECTORY:
452 case ECORE_FILE_EVENT_CREATED_FILE:
453 label = ecore_file_file_get(path);
455 file = EVRY_ITEM_NEW(Evry_Item_File, p, label, NULL, evry_item_file_free);
456 file->path = eina_stringshare_add(path);
458 if (event == ECORE_FILE_EVENT_CREATED_DIRECTORY)
459 file->mime = eina_stringshare_ref(_mime_dir);
462 p->files = eina_list_append(p->files, file);
465 case ECORE_FILE_EVENT_DELETED_FILE:
466 case ECORE_FILE_EVENT_DELETED_DIRECTORY:
467 label = eina_stringshare_add(path);
469 EINA_LIST_FOREACH_SAFE (p->files, l, ll, file)
471 if (file->path != label) continue;
473 p->files = eina_list_remove_list(p->files, l);
475 EVRY_ITEM_FREE(file);
478 eina_stringshare_del(label);
487 EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD);
491 _read_directory(Plugin *p)
493 Data *d = E_NEW(Data, 1);
495 d->directory = strdup(p->directory);
498 p->thread = ecore_thread_run(_scan_func, _scan_end_func, _scan_cancel_func, d);
501 ecore_file_monitor_del(p->dir_mon);
503 p->dir_mon = ecore_file_monitor_add(p->directory, _dir_watcher, p);
507 _browse(Evry_Plugin *plugin, const Evry_Item *it)
511 if (!it || !(CHECK_TYPE(it, EVRY_TYPE_FILE)))
516 if (!evry->file_path_get(file) ||
517 !ecore_file_is_dir(file->path))
520 EVRY_PLUGIN_INSTANCE(p, plugin);
522 p->directory = eina_stringshare_add(file->path);
523 p->parent = EINA_TRUE;
527 return EVRY_PLUGIN(p);
531 _begin(Evry_Plugin *plugin, const Evry_Item *it)
537 const char *dir = NULL;
539 if ((CHECK_TYPE(it, EVRY_TYPE_FILE)) ||
540 (CHECK_SUBTYPE(it, EVRY_TYPE_FILE)))
544 if (!evry->file_path_get(file))
547 if (!ecore_file_is_dir(file->path))
549 char *tmp = ecore_file_dir_get(file->path);
550 dir = eina_stringshare_add(tmp);
555 dir = eina_stringshare_add(file->path);
561 if (!CHECK_TYPE(it, EVRY_TYPE_ACTION))
566 dir = eina_stringshare_add(e_user_homedir_get());
568 EVRY_PLUGIN_INSTANCE(p, plugin);
570 p->parent = EINA_FALSE;
574 return EVRY_PLUGIN(p);
578 /* provide subject */
579 EVRY_PLUGIN_INSTANCE(p, plugin);
580 p->parent = EINA_FALSE;
581 p->directory = eina_stringshare_add(e_user_homedir_get());
582 p->min_query = plugin->config->min_query;
585 return EVRY_PLUGIN(p);
592 _folder_item_add(Plugin *p, const char *path, int prio)
594 Evry_Item_File *file;
596 file = EVRY_ITEM_NEW(Evry_Item_File, p, path, NULL, evry_item_file_free);
597 file->path = eina_stringshare_add(path);
598 file->mime = eina_stringshare_ref(_mime_dir);
599 EVRY_ITEM(file)->browseable = EINA_TRUE;
600 EVRY_ITEM(file)->priority = prio;
601 EVRY_ITEM(file)->usage = -1;
602 p->files = eina_list_append(p->files, file);
603 EVRY_PLUGIN_ITEM_APPEND(p, file);
607 _free_files(Plugin *p)
609 Evry_Item_File *file;
611 EVRY_PLUGIN_ITEMS_CLEAR(p);
614 ecore_thread_cancel(p->thread);
617 EINA_LIST_FREE (p->files, file)
618 EVRY_ITEM_FREE(file);
621 ecore_file_monitor_del(p->dir_mon);
626 _finish(Evry_Plugin *plugin)
628 GET_PLUGIN(p, plugin);
630 IF_RELEASE(p->input);
631 IF_RELEASE(p->directory);
634 p->waiting_to_finish = 1;
638 if (!p->waiting_to_finish)
643 _fetch(Evry_Plugin *plugin, const char *input)
645 GET_PLUGIN(p, plugin);
646 unsigned int len = (input ? strlen(input) : 0);
649 EVRY_PLUGIN_ITEMS_CLEAR(p);
651 IF_RELEASE(p->input);
653 if (!p->parent && input && !strncmp(input, "/", 1))
657 if (p->command != CMD_SHOW_ROOT)
661 IF_RELEASE(p->directory);
665 p->directory = eina_stringshare_add(path);
670 p->directory = eina_stringshare_add("/");
675 p->command = CMD_SHOW_ROOT;
679 int len = strlen(p->directory);
680 len = (len == 1) ? len : len + 1;
682 p->input = eina_stringshare_add(input + len);
684 else if (p->directory && input && !strncmp(input, "..", 2))
686 if (p->command != CMD_SHOW_PARENT)
692 if (strncmp(p->directory, "/", 1))
697 strncpy(buf, p->directory, PATH_MAX);
699 _folder_item_add(p, p->directory, prio++);
701 while (strlen(buf) > 1)
703 buf[PATH_MAX - 1] = 0;
705 _folder_item_add(p, dir, prio++);
706 strncpy(buf, dir, PATH_MAX);
709 p->command = CMD_SHOW_PARENT;
713 else if (p->directory && input && !strncmp(input, ".", 1))
715 if (p->command != CMD_SHOW_HIDDEN)
719 p->show_hidden = EINA_TRUE;
722 p->command = CMD_SHOW_HIDDEN;
726 p->input = eina_stringshare_add(input);
730 /* clear command items */
733 if (p->command == CMD_SHOW_ROOT)
735 IF_RELEASE(p->directory);
736 p->directory = eina_stringshare_add(e_user_homedir_get());
739 p->command = CMD_NONE;
740 p->show_hidden = EINA_FALSE;
745 if (input && !p->command)
746 p->input = eina_stringshare_add(input);
748 if ((p->command) || (!p->min_query) || (len >= p->min_query))
751 return EVRY_PLUGIN_HAS_ITEMS(p);
754 /***************************************************************************/
758 _cb_sort_recent(const void *data1, const void *data2)
760 const Evry_Item *it1 = data1;
761 const Evry_Item *it2 = data2;
763 if (it1->browseable && !it2->browseable)
766 if (!it1->browseable && it2->browseable)
769 if (it1->hi && it2->hi)
770 return it1->hi->last_used > it2->hi->last_used ? -1 : 1;
772 if (it1->fuzzy_match && it2->fuzzy_match)
773 if (it1->fuzzy_match - it2->fuzzy_match)
774 return it1->fuzzy_match - it2->fuzzy_match;
776 return strcasecmp(it1->label, it2->label);
780 _recentf_files_filter(Plugin *p)
785 Eina_List *l, *new = NULL;
787 EVRY_PLUGIN_ITEMS_CLEAR(p);
789 EINA_LIST_FOREACH (p->files, l, it)
791 if (p->dirs_only && !it->browseable)
798 new = eina_list_append(new, it);
802 if (it->fuzzy_match <= 0)
804 if ((match = evry->fuzzy_match(it->label, p->input)) ||
805 (match = evry->fuzzy_match(EVRY_FILE(it)->path, p->input)))
806 it->fuzzy_match = match;
810 DBG("check match %d %s", it->fuzzy_match, it->label);
817 new = eina_list_append(new, it);
821 new = eina_list_sort(new, -1, _cb_sort_recent);
823 EINA_LIST_FREE (new, it)
825 if (cnt++ < MAX_SHOWN)
826 EVRY_PLUGIN_ITEM_APPEND(p, it);
833 /* use thread only to not block ui for ecore_file_exists ... */
836 _recentf_func(void *data)
840 Evry_Item_File *file;
842 EINA_LIST_FOREACH (d->files, l, file)
844 if ((!evry->file_path_get(file)) ||
845 (!ecore_file_exists(file->path)))
847 EVRY_ITEM(file)->hi->last_used -= ONE_DAY;
848 EVRY_ITEM(file)->hi = NULL;
854 _recentf_cancel_func(void *data)
857 Plugin *p = d->plugin;
858 Evry_Item_File *file;
860 EINA_LIST_FREE (d->files, file)
861 EVRY_ITEM_FREE(file);
865 if (p->waiting_to_finish)
870 _recentf_end_func(void *data)
873 Plugin *p = d->plugin;
876 EINA_LIST_FREE (d->files, it)
889 it->hi->data = eina_stringshare_ref(file->mime);
891 p->files = eina_list_append(p->files, it);
894 _recentf_files_filter(p);
896 EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD);
905 _recentf_items_add_cb(const Eina_Hash *hash __UNUSED__, const void *key, void *data, void *fdata)
907 History_Entry *he = data;
908 History_Item *hi = NULL, *hi2;
910 Evry_Item_File *file;
911 double last_used = 0.0;
913 Plugin *p = d->plugin;
918 EINA_LIST_FOREACH (he->items, l, hi2)
919 if (hi2->last_used > last_used)
921 last_used = hi2->last_used;
930 DBG("clear %s", (char *)key);
932 /* transient marks them for deletion */
946 if (!_conf->search_cache)
948 if ((hi->count == 1) && (hi->last_used < SIX_DAYS_AGO))
952 path = (const char *)key;
954 if (!(label = ecore_file_file_get(path)))
957 path = eina_stringshare_add(path);
959 EINA_LIST_FOREACH (p->files, ll, file)
961 if (file->path == path)
963 eina_stringshare_del(path);
964 EVRY_ITEM(file)->fuzzy_match = -1;
969 /* searching subdirs */
972 /* dont show recent files from same dir */
973 int len = strlen(p->directory);
974 char *end = strrchr(path, '/');
975 if (strncmp(path, p->directory, len) ||
978 /* DBG("not in dir %s", path); */
979 eina_stringshare_del(path);
984 if (!(match = evry->fuzzy_match(label, p->input)) &&
985 !(match = evry->fuzzy_match(path, p->input)))
987 eina_stringshare_del(path);
991 file = EVRY_ITEM_NEW(Evry_Item_File, p, label, NULL, evry_item_file_free);
995 file->mime = eina_stringshare_add(hi->data);
997 EVRY_ITEM(file)->hi = hi;
998 EVRY_ITEM(file)->fuzzy_match = match;
999 EVRY_ITEM(file)->id = eina_stringshare_ref(file->path);
1004 hi->data = eina_stringshare_ref(file->mime);
1006 d->files = eina_list_append(d->files, file);
1008 if (eina_list_count(d->files) > 100)
1014 static Evry_Plugin *
1015 _recentf_browse(Evry_Plugin *plugin, const Evry_Item *it)
1019 if (!it || !CHECK_TYPE(it, EVRY_TYPE_FILE))
1024 if (!evry->file_path_get(file) ||
1025 !ecore_file_is_dir(file->path))
1028 EVRY_PLUGIN_INSTANCE(p, plugin);
1029 p->directory = eina_stringshare_add(file->path);
1030 p->parent = EINA_TRUE;
1032 return EVRY_PLUGIN(p);
1035 static Evry_Plugin *
1036 _recentf_begin(Evry_Plugin *plugin, const Evry_Item *it)
1040 if (it && !CHECK_TYPE(it, EVRY_TYPE_ACTION))
1043 EVRY_PLUGIN_INSTANCE(p, plugin);
1044 p->parent = EINA_FALSE;
1048 /* provide object */
1052 /* provide subject */
1053 p->min_query = plugin->config->min_query;
1057 History_Types *ht = evry->history_types_get(EVRY_TYPE_FILE);
1059 eina_hash_foreach(ht->types, _recentf_items_add_cb, p);
1061 clear_cache = EINA_FALSE;
1065 return EVRY_PLUGIN(p);
1069 _recentf_fetch(Evry_Plugin *plugin, const char *input)
1071 GET_PLUGIN(p, plugin);
1072 Evry_Item_File *file;
1074 size_t len = (input ? strlen(input) : 0);
1076 IF_RELEASE(p->input);
1079 * ecore_thread_cancel(p->thread);
1080 * p->thread = NULL; */
1082 if (input && isspace(input[len - 1]))
1083 return EVRY_PLUGIN_HAS_ITEMS(p);
1085 if (len >= plugin->config->min_query)
1088 p->input = eina_stringshare_add(input);
1090 if ((ht = evry->history_types_get(EVRY_TYPE_FILE)))
1092 Data *d = E_NEW(Data, 1);
1094 eina_hash_foreach(ht->types, _recentf_items_add_cb, d);
1095 EINA_LIST_FREE (d->files, file)
1096 p->files = eina_list_append(p->files, file);
1099 _recentf_files_filter(p);
1101 /* _recentf_end_func(d);
1102 * p->thread = NULL; */
1103 /* p->thread = ecore_thread_run(_recentf_func, _recentf_end_func,
1104 * _recentf_cancel_func, d); */
1106 return EVRY_PLUGIN_HAS_ITEMS(p);
1109 EVRY_PLUGIN_ITEMS_CLEAR(p);
1114 /***************************************************************************/
1118 _open_folder_check(Evry_Action *act __UNUSED__, const Evry_Item *it)
1120 return it->browseable && e_action_find("fileman");
1124 _open_folder_action(Evry_Action *act)
1130 if (!(action = e_action_find("fileman")))
1133 GET_FILE(file, act->it1.item);
1135 if (!(evry->file_path_get(file)))
1138 m = e_manager_list();
1140 if (!IS_BROWSEABLE(file))
1142 dir = ecore_file_dir_get(file->path);
1144 action->func.go(E_OBJECT(m->data), dir);
1149 action->func.go(E_OBJECT(m->data), file->path);
1156 _file_trash_action(Evry_Action *act)
1160 int force = (EVRY_ITEM_DATA_INT_GET(act) == ACT_DELETE);
1162 GET_FILE(file, act->it1.item);
1164 if (!(evry->file_url_get(file)))
1167 euri = efreet_uri_decode(file->url);
1171 ok = efreet_trash_delete_uri(euri, force);
1172 efreet_uri_free(euri);
1179 _file_copy_action(Evry_Action *act)
1181 GET_FILE(src, act->it1.item);
1182 GET_FILE(dst, act->it2.item);
1187 if (!(evry->file_path_get(src)))
1190 if (!(evry->file_path_get(dst)))
1193 if (!ecore_file_is_dir(dst->path))
1194 ddst = ecore_file_dir_get(dst->path);
1196 ddst = strdup(dst->path);
1200 snprintf(buf, sizeof(buf), "%s/%s", ddst, ecore_file_file_get(src->path));
1203 DBG(" %s -> %s\n", src->path, buf);
1205 if (EVRY_ITEM_DATA_INT_GET(act) == ACT_COPY)
1207 return ecore_file_cp(src->path, buf);
1209 else if (EVRY_ITEM_DATA_INT_GET(act) == ACT_MOVE)
1211 return ecore_file_mv(src->path, buf);
1218 _sort_by_date(Plugin *p)
1221 Evry_Item_File *file;
1224 EINA_LIST_FOREACH (p->files, l, file)
1229 if (lstat(file->path, &s) == 0)
1230 file->modified = s.st_mtime;
1232 EVRY_ITEM(file)->usage = -1;
1235 p->files = eina_list_sort(p->files, -1, _cb_sort_date);
1238 EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD);
1242 _sort_by_name(Plugin *p)
1247 EINA_LIST_FOREACH (p->files, l, it)
1250 p->files = eina_list_sort(p->files, -1, _cb_sort);
1253 EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD);
1257 _file_sort_action(Evry_Action *act)
1259 GET_PLUGIN(p, act->it1.item);
1262 if (EVRY_ITEM_DATA_INT_GET(act) == ACT_SORT_DATE)
1275 _cb_key_down(Evry_Plugin *plugin, const Ecore_Event_Key *ev)
1277 GET_PLUGIN(p, plugin);
1279 if (!strcmp(ev->key, "F1"))
1284 if (!strcmp(ev->key, "F2"))
1294 _plugins_init(const Evry_API *api)
1296 Evry_Action *act, *act_sort_date, *act_sort_name;
1299 const char *config_path;
1303 if (!evry->api_version_check(EVRY_API_VERSION))
1306 config_path = eina_stringshare_add("launcher/everything-files");
1307 _mime_dir = eina_stringshare_add("inode/directory");
1308 _mime_mount = eina_stringshare_add("inode/mountpoint");
1309 _mime_unknown = eina_stringshare_add("unknown");
1311 #define ACTION_NEW(_name, _type2, _icon, _act, _check, _register) \
1312 act = EVRY_ACTION_NEW(_name, EVRY_TYPE_FILE, _type2, _icon, _act, _check); \
1313 if (_register) evry->action_register(act, prio++); \
1314 _actions = eina_list_append(_actions, act); \
1316 ACTION_NEW("Copy To ...", EVRY_TYPE_FILE, "go-next",
1317 _file_copy_action, NULL, 1);
1318 act->it2.subtype = EVRY_TYPE_DIR;
1319 EVRY_ITEM_DATA_INT_SET(act, ACT_COPY);
1321 ACTION_NEW("Move To ...", EVRY_TYPE_FILE, "go-next",
1322 _file_copy_action, NULL, 1);
1323 act->it2.subtype = EVRY_TYPE_DIR;
1324 EVRY_ITEM_DATA_INT_SET(act, ACT_MOVE);
1326 ACTION_NEW("Move to Trash", 0, "user-trash",
1327 _file_trash_action, NULL, 1);
1328 EVRY_ITEM_DATA_INT_SET(act, ACT_TRASH);
1330 ACTION_NEW("Open Folder (EFM)", 0, "folder-open",
1331 _open_folder_action, _open_folder_check, 1);
1332 act->remember_context = EINA_TRUE;
1334 ACTION_NEW("Sort by Date", 0, "go-up",
1335 _file_sort_action, NULL, 0);
1336 EVRY_ITEM_DATA_INT_SET(act, ACT_SORT_DATE);
1337 act_sort_date = act;
1339 ACTION_NEW("Sort by Name", 0, "go-up",
1340 _file_sort_action, NULL, 0);
1341 EVRY_ITEM_DATA_INT_SET(act, ACT_SORT_NAME);
1342 act_sort_name = act;
1346 p = EVRY_PLUGIN_BASE("Files", _module_icon, EVRY_TYPE_FILE,
1347 _begin, _finish, _fetch);
1348 p->input_type = EVRY_TYPE_FILE;
1349 p->cb_key_down = &_cb_key_down;
1350 p->browse = &_browse;
1351 p->config_path = eina_stringshare_ref(config_path);
1352 p->actions = eina_list_append(p->actions, act_sort_date);
1353 p->actions = eina_list_append(p->actions, act_sort_name);
1354 _plugins = eina_list_append(_plugins, p);
1356 if (evry->plugin_register(p, EVRY_PLUGIN_SUBJECT, 2))
1357 p->config->min_query = 1;
1359 p = EVRY_PLUGIN_BASE("Files", _module_icon, EVRY_TYPE_FILE,
1360 _begin, _finish, _fetch);
1361 p->cb_key_down = &_cb_key_down;
1362 p->browse = &_browse;
1363 p->config_path = eina_stringshare_ref(config_path);
1364 p->actions = eina_list_append(p->actions, act_sort_date);
1365 p->actions = eina_list_append(p->actions, act_sort_name);
1366 _plugins = eina_list_append(_plugins, p);
1367 evry->plugin_register(p, EVRY_PLUGIN_OBJECT, 2);
1369 if (!_conf->show_recent && !_conf->search_recent)
1372 p = EVRY_PLUGIN_BASE("Recent Files", _module_icon, EVRY_TYPE_FILE,
1373 _recentf_begin, _finish, _recentf_fetch);
1374 p->browse = &_recentf_browse;
1375 p->config_path = eina_stringshare_ref(config_path);
1377 if (evry->plugin_register(p, EVRY_PLUGIN_SUBJECT, 3))
1379 p->config->top_level = EINA_FALSE;
1380 p->config->min_query = 3;
1382 _plugins = eina_list_append(_plugins, p);
1384 p = EVRY_PLUGIN_BASE("Recent Files", _module_icon, EVRY_TYPE_FILE,
1385 _recentf_begin, _finish, _recentf_fetch);
1386 p->browse = &_recentf_browse;
1387 p->config_path = eina_stringshare_ref(config_path);
1389 if (evry->plugin_register(p, EVRY_PLUGIN_OBJECT, 3))
1391 p->config->top_level = EINA_FALSE;
1392 p->config->min_query = 3;
1394 _plugins = eina_list_append(_plugins, p);
1395 eina_stringshare_del(config_path);
1401 _plugins_shutdown(void)
1406 eina_stringshare_del(_mime_dir);
1407 eina_stringshare_del(_mime_mount);
1408 eina_stringshare_del(_mime_unknown);
1410 EINA_LIST_FREE (_plugins, p)
1413 eina_list_free(p->actions);
1414 EVRY_PLUGIN_FREE(p);
1417 EINA_LIST_FREE (_actions, act)
1418 evry->action_free(act);
1421 /***************************************************************************/
1423 static E_Config_DD *conf_edd = NULL;
1425 struct _E_Config_Dialog_Data
1434 static void *_create_data(E_Config_Dialog *cfd);
1435 static void _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
1436 static void _fill_data(E_Config_Dialog_Data *cfdata);
1437 static Evas_Object *_basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
1438 static int _basic_apply(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
1440 static E_Config_Dialog *
1441 _conf_dialog(E_Container *con, const char *params __UNUSED__)
1443 E_Config_Dialog *cfd = NULL;
1444 E_Config_Dialog_View *v = NULL;
1446 if (e_config_dialog_find("everything-files", "extensions/everything-files")) return NULL;
1448 v = E_NEW(E_Config_Dialog_View, 1);
1449 if (!v) return NULL;
1451 v->create_cfdata = _create_data;
1452 v->free_cfdata = _free_data;
1453 v->basic.create_widgets = _basic_create;
1454 v->basic.apply_cfdata = _basic_apply;
1456 cfd = e_config_dialog_new(con, _("Everything Files"), "everything-files",
1457 "extensions/everything-files", _module_icon, 0, v, NULL);
1464 _clear_cache_cb(void *data __UNUSED__, void *data2 __UNUSED__)
1466 clear_cache = EINA_TRUE;
1469 static Evas_Object *
1470 _basic_create(E_Config_Dialog *cfd __UNUSED__, Evas *evas, E_Config_Dialog_Data *cfdata)
1472 Evas_Object *o = NULL, *of = NULL, *ow = NULL;
1474 o = e_widget_list_add(evas, 0, 0);
1476 of = e_widget_framelist_add(evas, _("General"), 0);
1477 e_widget_framelist_content_align_set(of, 0.0, 0.0);
1479 /* ow = e_widget_check_add(evas, _("Show home directory"),
1480 * &(cfdata->show_homedir));
1481 * e_widget_framelist_object_append(of, ow); */
1483 ow = e_widget_check_add(evas, _("Show recent files"),
1484 &(cfdata->show_recent));
1485 e_widget_framelist_object_append(of, ow);
1487 ow = e_widget_check_add(evas, _("Search recent files"),
1488 &(cfdata->search_recent));
1489 e_widget_framelist_object_append(of, ow);
1491 ow = e_widget_check_add(evas, _("Search cached files"),
1492 &(cfdata->search_cache));
1493 e_widget_framelist_object_append(of, ow);
1495 ow = e_widget_check_add(evas, _("Cache visited directories"),
1496 &(cfdata->cache_dirs));
1497 e_widget_framelist_object_append(of, ow);
1499 ow = e_widget_button_add(evas, _("Clear cache"), NULL,
1502 e_widget_framelist_object_append(of, ow);
1504 e_widget_list_object_append(o, of, 1, 1, 0.5);
1509 _create_data(E_Config_Dialog *cfd __UNUSED__)
1511 E_Config_Dialog_Data *cfdata = NULL;
1513 cfdata = E_NEW(E_Config_Dialog_Data, 1);
1519 _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
1526 _fill_data(E_Config_Dialog_Data *cfdata)
1528 #define C(_name) cfdata->_name = _conf->_name;
1538 _basic_apply(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
1540 #define C(_name) _conf->_name = cfdata->_name;
1548 e_config_domain_save("module.everything-files", conf_edd, _conf);
1549 e_config_save_queue();
1556 _conf = E_NEW(Module_Config, 1);
1557 _conf->version = (MOD_CONFIG_FILE_EPOCH << 16);
1559 #define IFMODCFG(v) if ((_conf->version & 0xffff) < v) {
1560 #define IFMODCFGEND }
1562 /* setup defaults */
1564 _conf->show_recent = 0;
1565 _conf->show_homedir = 1;
1566 _conf->search_recent = 1;
1567 _conf->cache_dirs = 0;
1568 _conf->search_cache = 0;
1571 _conf->version = MOD_CONFIG_FILE_VERSION;
1581 _conf_init(E_Module *m)
1585 snprintf(title, sizeof(title), "%s: %s", _("Everything Plugin"), _("Files"));
1587 e_configure_registry_item_add("launcher/everything-files", 110, title,
1588 NULL, _module_icon, _conf_dialog);
1590 conf_edd = E_CONFIG_DD_NEW("Module_Config", Module_Config);
1594 #define T Module_Config
1596 E_CONFIG_VAL(D, T, version, INT);
1597 E_CONFIG_VAL(D, T, show_homedir, UCHAR);
1598 E_CONFIG_VAL(D, T, show_recent, UCHAR);
1599 E_CONFIG_VAL(D, T, search_recent, UCHAR);
1600 E_CONFIG_VAL(D, T, search_cache, UCHAR);
1601 E_CONFIG_VAL(D, T, cache_dirs, UCHAR);
1605 _conf = e_config_domain_load("module.everything-files", conf_edd);
1607 if (_conf && !e_util_module_config_check(_("Everything Files"),
1609 MOD_CONFIG_FILE_VERSION))
1612 if (!_conf) _conf_new();
1618 _conf_shutdown(void)
1620 e_configure_registry_item_del("launcher/everything-files");
1623 E_CONFIG_DD_FREE(conf_edd);
1626 /***************************************************************************/
1629 evry_plug_files_init(E_Module *m)
1633 EVRY_MODULE_NEW(evry_module, evry, _plugins_init, _plugins_shutdown);
1639 evry_plug_files_shutdown(void)
1641 EVRY_MODULE_FREE(evry_module);
1647 evry_plug_files_save(void)
1649 e_config_domain_save("module.everything-files", conf_edd, _conf);