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;
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);
130 evry->util_file_detail_set(file);
134 _cb_sort(const void *data1, const void *data2)
136 const Evry_Item *it1 = data1;
137 const Evry_Item *it2 = data2;
139 if (it1->browseable && !it2->browseable)
142 if (!it1->browseable && it2->browseable)
145 if (it1->fuzzy_match && it2->fuzzy_match)
146 if (it1->fuzzy_match - it2->fuzzy_match)
147 return (it1->fuzzy_match - it2->fuzzy_match);
149 return strcasecmp(it1->label, it2->label);
153 _cb_sort_date(const void *data1, const void *data2)
155 const Evry_Item_File *it1 = data1;
156 const Evry_Item_File *it2 = data2;
158 return it2->modified - it1->modified;
162 _item_free(Evry_Item *it)
166 IF_RELEASE(file->url);
167 IF_RELEASE(file->path);
168 IF_RELEASE(file->mime);
174 _scan_func(void *data, Ecore_Thread *thread)
178 Eina_File_Direct_Info *info;
179 Evry_Item_File *file;
181 if (!(ls = eina_file_stat_ls(d->directory)))
184 EINA_ITERATOR_FOREACH(ls, info)
186 if ((d->plugin->show_hidden) != (*(info->path + info->name_start) == '.'))
189 file = EVRY_ITEM_NEW(Evry_Item_File, d->plugin, NULL, NULL, _item_free);
190 file->path = strdup(info->path);
191 EVRY_ITEM(file)->label = strdup(info->path + info->name_start);
192 EVRY_ITEM(file)->browseable = (info->type == EINA_FILE_DIR);
194 d->files = eina_list_append(d->files, file);
195 /* TODO dont append files in thread, run mime scan
196 * simultaneously. ecore_thread_feedback(thread, file); */
198 if (ecore_thread_check(thread))
202 eina_iterator_free(ls);
206 _scan_mime_func(void *data, Ecore_Thread *thread)
209 Evry_Item_File *file;
213 EINA_LIST_FOREACH(d->files, l, file)
215 if (ecore_thread_check(thread))
218 if ((file->mime = efreet_mime_type_get(file->path)))
220 if (!strncmp(file->mime, "inode/", 6) &&
221 ecore_file_is_dir(file->path))
222 EVRY_ITEM(file)->browseable = EINA_TRUE;
225 file->mime = _mime_unknown;
227 if (cnt++ > MAX_ITEMS * d->run_cnt) break;
232 _files_filter(Plugin *p)
238 unsigned int len = p->input ? strlen(p->input) : 0;
240 EVRY_PLUGIN_ITEMS_CLEAR(p);
242 if (!p->command && p->min_query)
246 if (len < p->min_query)
250 EINA_LIST_FOREACH(p->files, l, it)
252 if (cnt >= MAX_SHOWN) break;
254 if (p->dirs_only && !it->browseable)
257 if (len && (match = evry->fuzzy_match(it->label, p->input)))
259 it->fuzzy_match = match;
262 EVRY_PLUGIN_ITEM_APPEND(p, it);
269 EVRY_PLUGIN_ITEM_APPEND(p, it);
277 _scan_cancel_func(void *data, Ecore_Thread *thread __UNUSED__)
280 Plugin *p = d->plugin;
281 Evry_Item_File *file;
283 EINA_LIST_FREE(p->files, file)
284 EVRY_ITEM_FREE(file);
286 EINA_LIST_FREE(d->files, file)
288 if (file->base.label) free((char *)(file->base.label));
289 if (file->path) free((char *)file->path);
303 _cache_mime_get(History_Types *ht, Evry_Item_File *file)
309 if ((he = eina_hash_find(ht->types, file->path)))
311 EINA_LIST_FOREACH(he->items, l, hi)
317 file->mime = hi->data;
320 EVRY_ITEM(file)->hi = hi;
327 _cache_dir_add(Eina_List *files)
334 EINA_LIST_REVERSE_FOREACH(files, l, item)
336 GET_FILE(file, item);
339 (hi = evry->history_item_add(item, NULL, NULL)))
341 hi->last_used = SIX_DAYS_AGO;
342 hi->usage = MIN_USAGE * (double) cnt++;
343 hi->data = eina_stringshare_ref(file->mime);
346 else if (item->hi && (item->hi->count == 1) &&
347 (item->hi->last_used < SIX_DAYS_AGO))
349 item->hi->last_used = SIX_DAYS_AGO;
350 item->hi->usage = MIN_USAGE * (double) cnt++;
356 _file_add(Plugin *p, Evry_Item *item)
358 GET_FILE(file, item);
360 char *filename = (char *)item->label;
361 char *path = (char *) file->path;
363 file->path = eina_stringshare_add(path);
364 file->mime = eina_stringshare_ref(file->mime);
366 item->label = eina_stringshare_add(filename);
367 item->id = eina_stringshare_ref(file->path);
368 item->context = eina_stringshare_ref(file->mime);
370 evry->util_file_detail_set(file);
372 p->files = eina_list_append(p->files, file);
379 _scan_end_func(void *data, Ecore_Thread *thread __UNUSED__)
382 Plugin *p = d->plugin;
384 Evry_Item_File *file;
386 History_Types *ht = NULL;
388 if (_conf->cache_dirs)
389 ht = evry->history_types_get(EVRY_TYPE_FILE);
391 if (!d->run_cnt) /* _scan_func finished */
393 EINA_LIST_FOREACH_SAFE(d->files, l, ll, item)
395 GET_FILE(file, item);
397 if (item->browseable)
398 file->mime = _mime_dir;
400 _cache_mime_get(ht, file);
404 d->files = eina_list_remove_list(d->files, l);
409 /* sort files by name for mimetypes scan */
411 d->files = eina_list_sort(d->files, -1, _cb_sort);
413 else /* _scan_mime_func finished */
415 EINA_LIST_FREE(d->files, file)
417 if (!file->mime) break;
418 _file_add(p, (Evry_Item*) file);
422 if (d->files) /* scan mimetypes */
425 p->thread = ecore_thread_run(_scan_mime_func,
427 _scan_cancel_func, d);
429 /* wait for first mime scan to finish */
430 if (d->run_cnt == 1) return;
432 else /* finished all file/mime scan */
438 if (_conf->cache_dirs && !(p->command == CMD_SHOW_HIDDEN))
439 _cache_dir_add(p->files);
442 p->files = eina_list_sort(p->files, -1, _cb_sort);
446 EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD);
450 _dir_watcher(void *data, Ecore_File_Monitor *em __UNUSED__, Ecore_File_Event event, const char *path)
453 Evry_Item_File *file;
459 case ECORE_FILE_EVENT_DELETED_SELF:
460 EINA_LIST_FREE(p->files, file)
461 evry->item_free(EVRY_ITEM(file));
464 case ECORE_FILE_EVENT_CREATED_DIRECTORY:
465 case ECORE_FILE_EVENT_CREATED_FILE:
466 label = ecore_file_file_get(path);
468 file = EVRY_ITEM_NEW(Evry_Item_File, p, label, NULL, _item_free);
469 file->path = eina_stringshare_add(path);
471 if (event == ECORE_FILE_EVENT_CREATED_DIRECTORY)
472 file->mime = eina_stringshare_ref(_mime_dir);
475 p->files = eina_list_append(p->files, file);
479 case ECORE_FILE_EVENT_DELETED_FILE:
480 case ECORE_FILE_EVENT_DELETED_DIRECTORY:
481 label = eina_stringshare_add(path);
483 EINA_LIST_FOREACH_SAFE(p->files, l, ll, file)
485 if (file->path != label) continue;
487 p->files = eina_list_remove_list(p->files, l);
489 EVRY_ITEM_FREE(file);
492 eina_stringshare_del(label);
501 EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD);
505 _read_directory(Plugin *p)
507 Data *d = E_NEW(Data, 1);
509 d->directory = strdup(p->directory);
512 p->thread = ecore_thread_run(_scan_func, _scan_end_func, _scan_cancel_func, d);
515 ecore_file_monitor_del(p->dir_mon);
517 p->dir_mon = ecore_file_monitor_add(p->directory, _dir_watcher, p);
521 _browse(Evry_Plugin *plugin, const Evry_Item *it)
525 if (!it || !(CHECK_TYPE(it, EVRY_TYPE_FILE)))
530 if (!evry->file_path_get(file) ||
531 !ecore_file_is_dir(file->path))
534 EVRY_PLUGIN_INSTANCE(p, plugin);
536 p->directory = eina_stringshare_add(file->path);
537 p->parent = EINA_TRUE;
541 return EVRY_PLUGIN(p);
545 _begin(Evry_Plugin *plugin, const Evry_Item *it)
551 const char *dir = NULL;
553 if ((CHECK_TYPE(it, EVRY_TYPE_FILE)) ||
554 (CHECK_SUBTYPE(it, EVRY_TYPE_FILE)))
558 if (!evry->file_path_get(file))
561 if (!ecore_file_is_dir(file->path))
563 char *tmp = ecore_file_dir_get(file->path);
564 dir = eina_stringshare_add(tmp);
569 dir = eina_stringshare_add(file->path);
575 if (!CHECK_TYPE(it, EVRY_TYPE_ACTION))
580 dir = eina_stringshare_add(e_user_homedir_get());
582 EVRY_PLUGIN_INSTANCE(p, plugin);
584 p->parent = EINA_FALSE;
588 return EVRY_PLUGIN(p);
592 /* provide subject */
593 EVRY_PLUGIN_INSTANCE(p, plugin);
594 p->parent = EINA_FALSE;
595 p->directory = eina_stringshare_add(e_user_homedir_get());
596 p->min_query = plugin->config->min_query;
599 return EVRY_PLUGIN(p);
606 _folder_item_add(Plugin *p, const char *path, int prio)
608 Evry_Item_File *file;
610 file = EVRY_ITEM_NEW(Evry_Item_File, p, path, NULL, _item_free);
611 file->path = eina_stringshare_add(path);
612 file->mime = eina_stringshare_ref(_mime_dir);
613 EVRY_ITEM(file)->browseable = EINA_TRUE;
614 EVRY_ITEM(file)->priority = prio;
615 EVRY_ITEM(file)->usage = -1;
616 p->files = eina_list_append(p->files, file);
617 EVRY_PLUGIN_ITEM_APPEND(p, file);
621 _free_files(Plugin *p)
623 Evry_Item_File *file;
625 EVRY_PLUGIN_ITEMS_CLEAR(p);
628 ecore_thread_cancel(p->thread);
631 EINA_LIST_FREE(p->files, file)
632 EVRY_ITEM_FREE(file);
635 ecore_file_monitor_del(p->dir_mon);
640 _finish(Evry_Plugin *plugin)
642 GET_PLUGIN(p, plugin);
644 IF_RELEASE(p->input);
645 IF_RELEASE(p->directory);
649 ecore_thread_cancel(p->thread);
661 _fetch(Evry_Plugin *plugin, const char *input)
663 GET_PLUGIN(p, plugin);
664 unsigned int len = (input ? strlen(input) : 0);
667 EVRY_PLUGIN_ITEMS_CLEAR(p);
669 IF_RELEASE(p->input);
671 if (!p->parent && input && !strncmp(input, "/", 1))
675 if (p->command != CMD_SHOW_ROOT)
679 IF_RELEASE(p->directory);
683 p->directory = eina_stringshare_add(path);
688 p->directory = eina_stringshare_add("/");
693 p->command = CMD_SHOW_ROOT;
697 int len = strlen(p->directory);
698 len = (len == 1) ? len : len+1;
700 p->input = eina_stringshare_add(input + len);
702 else if (p->directory && input && !strncmp(input, "..", 2))
704 if (p->command != CMD_SHOW_PARENT)
710 if (strncmp(p->directory, "/", 1))
715 strncpy(buf, p->directory, PATH_MAX);
717 _folder_item_add(p, p->directory, prio++);
719 while (strlen(buf) > 1)
721 buf[PATH_MAX - 1] = 0;
723 _folder_item_add(p, dir, prio++);
724 strncpy(buf, dir, PATH_MAX);
727 p->command = CMD_SHOW_PARENT;
731 else if (p->directory && input && !strncmp(input, ".", 1))
733 if (p->command != CMD_SHOW_HIDDEN)
737 p->show_hidden = EINA_TRUE;
740 p->command = CMD_SHOW_HIDDEN;
744 p->input = eina_stringshare_add(input);
748 /* clear command items */
751 if (p->command == CMD_SHOW_ROOT)
753 IF_RELEASE(p->directory);
754 p->directory = eina_stringshare_add(e_user_homedir_get());
757 p->command = CMD_NONE;
758 p->show_hidden = EINA_FALSE;
763 if (input && !p->command)
764 p->input = eina_stringshare_add(input);
766 if ((p->command) || (!p->min_query) || (len >= p->min_query))
769 return !!(EVRY_PLUGIN(p)->items);
772 /***************************************************************************/
776 _cb_sort_recent(const void *data1, const void *data2)
778 const Evry_Item *it1 = data1;
779 const Evry_Item *it2 = data2;
781 if (it1->browseable && !it2->browseable)
784 if (!it1->browseable && it2->browseable)
787 if (it1->hi && it2->hi)
788 return (it1->hi->last_used > it2->hi->last_used ? -1 : 1);
790 if (it1->fuzzy_match && it2->fuzzy_match)
791 if (it1->fuzzy_match - it2->fuzzy_match)
792 return (it1->fuzzy_match - it2->fuzzy_match);
794 return strcasecmp(it1->label, it2->label);
798 _recentf_files_filter(Plugin *p)
803 Eina_List *l, *new = NULL;
805 EVRY_PLUGIN_ITEMS_CLEAR(p);
807 EINA_LIST_FOREACH(p->files, l, it)
809 if (p->dirs_only && !it->browseable)
812 if (it->fuzzy_match <= 0)
814 if ((match = evry->fuzzy_match(it->label, p->input)) ||
815 (match = evry->fuzzy_match(EVRY_FILE(it)->path, p->input)))
816 it->fuzzy_match = match;
820 DBG("check match %d %s", it->fuzzy_match, it->label);
823 if (_conf->show_recent || it->fuzzy_match)
827 new = eina_list_append(new, it);
831 new = eina_list_sort(new, -1, _cb_sort_recent);
833 EINA_LIST_FREE(new, it)
835 if (cnt++ < MAX_SHOWN)
836 EVRY_PLUGIN_ITEM_APPEND(p, it);
844 /* use thread only to not block ui for ecore_file_exists ... */
847 _recentf_func(void *data)
851 Evry_Item_File *file;
853 EINA_LIST_FOREACH(d->files, l, file)
855 if ((!evry->file_path_get(file)) ||
856 (!ecore_file_exists(file->path)))
858 EVRY_ITEM(file)->hi->last_used -= ONE_DAY;
859 EVRY_ITEM(file)->hi = NULL;
865 _recentf_cancel_func(void *data)
868 Plugin *p = d->plugin;
869 Evry_Item_File *file;
871 EINA_LIST_FREE(d->files, file)
873 EVRY_ITEM_FREE(file);
883 _recentf_end_func(void *data)
886 Plugin *p = d->plugin;
889 EINA_LIST_FREE(d->files, it)
902 it->hi->data = eina_stringshare_ref(file->mime);
904 p->files = eina_list_append(p->files, it);
907 _recentf_files_filter(p);
909 EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD);
917 _recentf_items_add_cb(const Eina_Hash *hash __UNUSED__, const void *key, void *data, void *fdata)
919 History_Entry *he = data;
920 History_Item *hi = NULL, *hi2;
922 Evry_Item_File *file;
923 double last_used = 0.0;
925 Plugin *p = d->plugin;
930 EINA_LIST_FOREACH(he->items, l, hi2)
931 if (hi2->last_used > last_used)
933 last_used = hi2->last_used;
942 DBG("clear %s", (char *)key);
944 /* transient marks them for deletion */
958 if (!_conf->search_cache)
960 if ((hi->count == 1) && (hi->last_used < SIX_DAYS_AGO))
964 path = (const char *) key;
966 if (!(label = ecore_file_file_get(path)))
969 path = eina_stringshare_add(path);
971 EINA_LIST_FOREACH(p->files, ll, file)
973 if (file->path == path)
975 eina_stringshare_del(path);
976 EVRY_ITEM(file)->fuzzy_match = -1;
981 /* searching subdirs */
984 /* dont show recent files from same dir */
985 int len = strlen(p->directory);
986 char *end = strrchr(path, '/');
987 if (strncmp(path, p->directory, len) ||
990 /* DBG("not in dir %s", path); */
991 eina_stringshare_del(path);
996 if (!(match = evry->fuzzy_match(label, p->input)) &&
997 !(match = evry->fuzzy_match(path, p->input)))
999 eina_stringshare_del(path);
1003 file = EVRY_ITEM_NEW(Evry_Item_File, p, label, NULL, _item_free);
1007 file->mime = eina_stringshare_add(hi->data);
1009 EVRY_ITEM(file)->hi = hi;
1010 EVRY_ITEM(file)->fuzzy_match = match;
1011 EVRY_ITEM(file)->id = eina_stringshare_ref(file->path);
1016 hi->data = eina_stringshare_ref(file->mime);
1018 d->files = eina_list_append(d->files, file);
1020 if (eina_list_count(d->files) > 100)
1026 static Evry_Plugin *
1027 _recentf_browse(Evry_Plugin *plugin, const Evry_Item *it)
1031 if (!it || !CHECK_TYPE(it, EVRY_TYPE_FILE))
1036 if (!evry->file_path_get(file) ||
1037 !ecore_file_is_dir(file->path))
1040 EVRY_PLUGIN_INSTANCE(p, plugin);
1041 p->directory = eina_stringshare_add(file->path);
1042 p->parent = EINA_TRUE;
1044 return EVRY_PLUGIN(p);
1047 static Evry_Plugin *
1048 _recentf_begin(Evry_Plugin *plugin, const Evry_Item *it)
1052 if (it && !CHECK_TYPE(it, EVRY_TYPE_ACTION))
1055 EVRY_PLUGIN_INSTANCE(p, plugin);
1056 p->parent = EINA_FALSE;
1060 /* provide object */
1064 /* provide subject */
1065 p->min_query = plugin->config->min_query;
1069 History_Types *ht = evry->history_types_get(EVRY_TYPE_FILE);
1071 eina_hash_foreach(ht->types, _recentf_items_add_cb, p);
1073 clear_cache = EINA_FALSE;
1077 return EVRY_PLUGIN(p);
1081 _recentf_fetch(Evry_Plugin *plugin, const char *input)
1083 GET_PLUGIN(p, plugin);
1084 Evry_Item_File *file;
1086 int len = (input ? strlen(input) : 0);
1088 IF_RELEASE(p->input);
1091 * ecore_thread_cancel(p->thread);
1092 * p->thread = NULL; */
1094 if (input && isspace(input[len - 1]))
1095 return !!(plugin->items);
1097 if (len >= plugin->config->min_query)
1100 p->input = eina_stringshare_add(input);
1102 if ((ht = evry->history_types_get(EVRY_TYPE_FILE)))
1104 Data *d = E_NEW(Data, 1);
1106 eina_hash_foreach(ht->types, _recentf_items_add_cb, d);
1107 EINA_LIST_FREE(d->files, file)
1108 p->files = eina_list_append(p->files, file);
1111 _recentf_files_filter(p);
1113 /* _recentf_end_func(d);
1114 * p->thread = NULL; */
1115 /* p->thread = ecore_thread_run(_recentf_func, _recentf_end_func,
1116 * _recentf_cancel_func, d); */
1118 return !!(plugin->items);
1121 EVRY_PLUGIN_ITEMS_CLEAR(p);
1126 /***************************************************************************/
1130 _open_folder_check(Evry_Action *act __UNUSED__, const Evry_Item *it)
1132 return (it->browseable && e_action_find("fileman"));
1136 _open_folder_action(Evry_Action *act)
1142 if (!(action = e_action_find("fileman")))
1145 GET_FILE(file, act->it1.item);
1147 if (!(evry->file_path_get(file)))
1150 m = e_manager_list();
1152 if (!IS_BROWSEABLE(file))
1154 dir = ecore_file_dir_get(file->path);
1156 action->func.go(E_OBJECT(m->data), dir);
1161 action->func.go(E_OBJECT(m->data), file->path);
1168 _file_trash_action(Evry_Action *act)
1172 int force = (EVRY_ITEM_DATA_INT_GET(act) == ACT_DELETE);
1174 GET_FILE(file, act->it1.item);
1176 if (!(evry->file_url_get(file)))
1179 euri = efreet_uri_decode(file->url);
1183 ok = efreet_trash_delete_uri(euri, force);
1184 efreet_uri_free(euri);
1191 _file_copy_action(Evry_Action *act)
1193 GET_FILE(src, act->it1.item);
1194 GET_FILE(dst, act->it2.item);
1199 if (!(evry->file_path_get(src)))
1202 if (!(evry->file_path_get(dst)))
1205 if (!ecore_file_is_dir(dst->path))
1206 ddst = ecore_file_dir_get(dst->path);
1208 ddst = strdup(dst->path);
1212 snprintf(buf, sizeof(buf), "%s/%s", ddst, ecore_file_file_get(src->path));
1215 DBG(" %s -> %s\n", src->path, buf);
1217 if (EVRY_ITEM_DATA_INT_GET(act) == ACT_COPY)
1219 return ecore_file_cp(src->path, buf);
1221 else if (EVRY_ITEM_DATA_INT_GET(act) == ACT_MOVE)
1223 return ecore_file_mv(src->path, buf);
1230 _sort_by_date(Plugin *p)
1233 Evry_Item_File *file;
1236 EINA_LIST_FOREACH(p->files, l, file)
1241 if (lstat(file->path, &s) == 0)
1242 file->modified = s.st_mtime;
1244 EVRY_ITEM(file)->usage = -1;
1247 p->files = eina_list_sort(p->files, -1, _cb_sort_date);
1250 EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD);
1254 _sort_by_name(Plugin *p)
1259 EINA_LIST_FOREACH(p->files, l, it)
1262 p->files = eina_list_sort(p->files, -1, _cb_sort);
1265 EVRY_PLUGIN_UPDATE(p, EVRY_UPDATE_ADD);
1270 _file_sort_action(Evry_Action *act)
1272 GET_PLUGIN(p, act->it1.item);
1275 if (EVRY_ITEM_DATA_INT_GET(act) == ACT_SORT_DATE)
1288 _cb_key_down(Evry_Plugin *plugin, const Ecore_Event_Key *ev)
1290 GET_PLUGIN(p, plugin);
1292 if (!strcmp(ev->key, "F1"))
1297 if (!strcmp(ev->key, "F2"))
1308 _plugins_init(const Evry_API *api)
1310 Evry_Action *act, *act_sort_date, *act_sort_name;
1314 if (evry_module->active)
1319 if (!evry->api_version_check(EVRY_API_VERSION))
1322 _mime_dir = eina_stringshare_add("inode/directory");
1323 _mime_mount = eina_stringshare_add("inode/mountpoint");
1324 _mime_unknown = eina_stringshare_add("unknown");
1326 #define ACTION_NEW(_name, _type2, _icon, _act, _check, _register) \
1327 act = EVRY_ACTION_NEW(_name, EVRY_TYPE_FILE, _type2, _icon, _act, _check); \
1328 if (_register) evry->action_register(act, prio++); \
1329 _actions = eina_list_append(_actions, act); \
1331 ACTION_NEW(N_("Copy To ..."), EVRY_TYPE_FILE, "go-next",
1332 _file_copy_action, NULL, 1);
1333 act->it2.subtype = EVRY_TYPE_DIR;
1334 EVRY_ITEM_DATA_INT_SET(act, ACT_COPY);
1336 ACTION_NEW(N_("Move To ..."), EVRY_TYPE_FILE, "go-next",
1337 _file_copy_action, NULL, 1);
1338 act->it2.subtype = EVRY_TYPE_DIR;
1339 EVRY_ITEM_DATA_INT_SET(act, ACT_MOVE);
1341 ACTION_NEW(N_("Move to Trash"), 0, "user-trash",
1342 _file_trash_action, NULL, 1);
1343 EVRY_ITEM_DATA_INT_SET(act, ACT_TRASH);
1345 ACTION_NEW(N_("Open Folder (EFM)"), 0, "folder-open",
1346 _open_folder_action, _open_folder_check, 1);
1347 act->remember_context = EINA_TRUE;
1349 ACTION_NEW(N_("Sort by Date"), 0, "go-up",
1350 _file_sort_action, NULL, 0);
1351 EVRY_ITEM_DATA_INT_SET(act, ACT_SORT_DATE);
1352 act_sort_date = act;
1354 ACTION_NEW(N_("Sort by Name"), 0, "go-up",
1355 _file_sort_action, NULL, 0);
1356 EVRY_ITEM_DATA_INT_SET(act, ACT_SORT_NAME);
1357 act_sort_name = act;
1361 #define PLUGIN_NEW(_name, _icon, _begin, _finish, _fetch, _browse) \
1362 p = EVRY_PLUGIN_NEW(Evry_Plugin, _name, _icon, EVRY_TYPE_FILE, \
1363 _begin, _finish, _fetch, NULL); \
1364 p->browse = &_browse; \
1365 p->config_path = "extensions/everything-files"; \
1366 _plugins = eina_list_append(_plugins, p); \
1369 PLUGIN_NEW(N_("Files"), _module_icon, _begin, _finish, _fetch, _browse);
1370 p->input_type = EVRY_TYPE_FILE;
1371 p->cb_key_down = &_cb_key_down;
1372 p->actions = eina_list_append(p->actions, act_sort_date);
1373 p->actions = eina_list_append(p->actions, act_sort_name);
1374 if (evry->plugin_register(p, EVRY_PLUGIN_SUBJECT, 2))
1375 p->config->min_query = 1;
1378 PLUGIN_NEW(N_("Files"), _module_icon, _begin, _finish, _fetch, _browse);
1379 p->cb_key_down = &_cb_key_down;
1380 p->actions = eina_list_append(p->actions, act_sort_date);
1381 p->actions = eina_list_append(p->actions, act_sort_name);
1382 evry->plugin_register(p, EVRY_PLUGIN_OBJECT, 2);
1384 if (_conf->show_recent || _conf->search_recent)
1386 PLUGIN_NEW(N_("Recent Files"), _module_icon,
1387 _recentf_begin, _finish, _recentf_fetch, _recentf_browse);
1389 if (evry->plugin_register(p, EVRY_PLUGIN_SUBJECT, 3))
1391 p->config->top_level = EINA_FALSE;
1392 p->config->min_query = 3;
1395 PLUGIN_NEW(N_("Recent Files"), _module_icon,
1396 _recentf_begin, _finish, _recentf_fetch, _recentf_browse);
1398 if (evry->plugin_register(p, EVRY_PLUGIN_OBJECT, 3))
1400 p->config->top_level = EINA_FALSE;
1401 p->config->min_query = 3;
1411 _plugins_shutdown(void)
1416 if (!evry_module->active)
1419 eina_stringshare_del(_mime_dir);
1420 eina_stringshare_del(_mime_mount);
1421 eina_stringshare_del(_mime_unknown);
1423 EINA_LIST_FREE(_plugins, p)
1426 eina_list_free(p->actions);
1427 EVRY_PLUGIN_FREE(p);
1430 EINA_LIST_FREE(_actions, act)
1431 evry->action_free(act);
1433 evry_module->active = EINA_FALSE;
1437 /***************************************************************************/
1439 static E_Config_DD *conf_edd = NULL;
1441 struct _E_Config_Dialog_Data
1450 static void *_create_data(E_Config_Dialog *cfd);
1451 static void _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
1452 static void _fill_data(E_Config_Dialog_Data *cfdata);
1453 static Evas_Object *_basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
1454 static int _basic_apply(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
1456 static E_Config_Dialog *
1457 _conf_dialog(E_Container *con, const char *params __UNUSED__)
1459 E_Config_Dialog *cfd = NULL;
1460 E_Config_Dialog_View *v = NULL;
1462 if (e_config_dialog_find("everything-files", "extensions/everything-files")) return NULL;
1464 v = E_NEW(E_Config_Dialog_View, 1);
1465 if (!v) return NULL;
1467 v->create_cfdata = _create_data;
1468 v->free_cfdata = _free_data;
1469 v->basic.create_widgets = _basic_create;
1470 v->basic.apply_cfdata = _basic_apply;
1472 cfd = e_config_dialog_new(con, _("Everything Files"), "everything-files",
1473 "extensions/everything-files", _module_icon, 0, v, NULL);
1480 _clear_cache_cb(void *data __UNUSED__, void *data2 __UNUSED__)
1482 clear_cache = EINA_TRUE;
1485 static Evas_Object *
1486 _basic_create(E_Config_Dialog *cfd __UNUSED__, Evas *evas, E_Config_Dialog_Data *cfdata)
1488 Evas_Object *o = NULL, *of = NULL, *ow = NULL;
1490 o = e_widget_list_add(evas, 0, 0);
1492 of = e_widget_framelist_add(evas, _("General"), 0);
1493 e_widget_framelist_content_align_set(of, 0.0, 0.0);
1495 /* ow = e_widget_check_add(evas, _("Show home directory"),
1496 * &(cfdata->show_homedir));
1497 * e_widget_framelist_object_append(of, ow); */
1499 ow = e_widget_check_add(evas, _("Show recent files"),
1500 &(cfdata->show_recent));
1501 e_widget_framelist_object_append(of, ow);
1503 ow = e_widget_check_add(evas, _("Search recent files"),
1504 &(cfdata->search_recent));
1505 e_widget_framelist_object_append(of, ow);
1507 ow = e_widget_check_add(evas, _("Search cached files"),
1508 &(cfdata->search_cache));
1509 e_widget_framelist_object_append(of, ow);
1511 ow = e_widget_check_add(evas, _("Cache visited directories"),
1512 &(cfdata->cache_dirs));
1513 e_widget_framelist_object_append(of, ow);
1515 ow = e_widget_button_add(evas, _("Clear cache"), NULL,
1518 e_widget_framelist_object_append(of, ow);
1521 e_widget_list_object_append(o, of, 1, 1, 0.5);
1526 _create_data(E_Config_Dialog *cfd __UNUSED__)
1528 E_Config_Dialog_Data *cfdata = NULL;
1530 cfdata = E_NEW(E_Config_Dialog_Data, 1);
1536 _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
1543 _fill_data(E_Config_Dialog_Data *cfdata)
1545 #define C(_name) cfdata->_name = _conf->_name;
1555 _basic_apply(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
1557 #define C(_name) _conf->_name = cfdata->_name;
1565 e_config_domain_save("module.everything-files", conf_edd, _conf);
1566 e_config_save_queue();
1573 _conf = E_NEW(Module_Config, 1);
1574 _conf->version = (MOD_CONFIG_FILE_EPOCH << 16);
1576 #define IFMODCFG(v) if ((_conf->version & 0xffff) < v) {
1577 #define IFMODCFGEND }
1579 /* setup defaults */
1581 _conf->show_recent = 0;
1582 _conf->show_homedir = 1;
1583 _conf->search_recent = 1;
1584 _conf->cache_dirs = 0;
1585 _conf->search_cache = 0;
1588 _conf->version = MOD_CONFIG_FILE_VERSION;
1598 _conf_init(E_Module *m)
1602 snprintf(title, sizeof(title), "%s: %s", _("Everything Plugin"), _("Files"));
1604 e_configure_registry_item_add("launcher/everything-files", 110, title,
1605 NULL, _module_icon, _conf_dialog);
1607 conf_edd = E_CONFIG_DD_NEW("Module_Config", Module_Config);
1611 #define T Module_Config
1613 E_CONFIG_VAL(D, T, version, INT);
1614 E_CONFIG_VAL(D, T, show_homedir, UCHAR);
1615 E_CONFIG_VAL(D, T, show_recent, UCHAR);
1616 E_CONFIG_VAL(D, T, search_recent, UCHAR);
1617 E_CONFIG_VAL(D, T, search_cache, UCHAR);
1618 E_CONFIG_VAL(D, T, cache_dirs, UCHAR);
1622 _conf = e_config_domain_load("module.everything-files", conf_edd);
1624 if (_conf && !e_util_module_config_check
1625 (_("Everything Files"), _conf->version,
1626 MOD_CONFIG_FILE_EPOCH, MOD_CONFIG_FILE_VERSION))
1629 if (!_conf) _conf_new();
1635 _conf_shutdown(void)
1637 e_configure_registry_item_del("launcher/everything-files");
1640 E_CONFIG_DD_FREE(conf_edd);
1643 /***************************************************************************/
1646 evry_plug_files_init(E_Module *m)
1650 EVRY_MODULE_NEW(evry_module, evry, _plugins_init, _plugins_shutdown);
1656 evry_plug_files_shutdown(void)
1658 EVRY_MODULE_FREE(evry_module);
1664 evry_plug_files_save(void)
1666 e_config_domain_save("module.everything-files", conf_edd, _conf);