00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "config.h"
00032
00033 #include <stdlib.h>
00034
00035 #include "ctb_log.h"
00036 #include "ctb_actions.h"
00037 #include "filetypes.h"
00038 #include "i18n.h"
00039 #include "ipc.h"
00040 #include "shortcut.h"
00041 #include "fileview.h"
00042
00043 static void set_special_viewmode(const filelist_entry_t *item,
00044 ViewMode mode)
00045 {
00046 fileview_stop_update_display();
00047 filemodel_set_viewmode2(mode);
00048 fileview_dir_down(item->directory_path->str, item->filename->str);
00049 }
00050
00051
00052 static void handle_special_item(const filelist_entry_t *item)
00053 {
00054 const gchar *filename = item->filename->str;
00055 if (strcmp(filename, SPECIAL_BOOKS) == 0) {
00056 set_special_viewmode(item, BOOKS_VIEW);
00057 } else if (strcmp(filename, SPECIAL_IMAGES) == 0) {
00058 set_special_viewmode(item, IMAGES_VIEW);
00059 } else if (strcmp(filename, SPECIAL_NEWS) == 0) {
00060 set_special_viewmode(item, NEWS_VIEW);
00061 } else if (strcmp(filename, SPECIAL_DIR) == 0) {
00062 set_special_viewmode(item, DIR_VIEW);
00063 } else if (strcmp(filename, SPECIAL_SHORTCUTS) == 0) {
00064 set_special_viewmode(item, SHORTCUT_VIEW);
00065 } else if (strcmp(filename, SPECIAL_NOTES) == 0) {
00066 set_special_viewmode(item, NOTES_VIEW);
00067 } else if (strcmp(filename, SPECIAL_SETTINGS) == 0) {
00068 set_special_viewmode(item, SETTINGS_VIEW);
00069 } else if (strcmp(filename, SPECIAL_HELP) == 0) {
00070 set_special_viewmode(item, HELP_VIEW);
00071 } else if (strcmp(filename, SPECIAL_PERSONAL) == 0) {
00072 set_special_viewmode(item, PERSONAL_VIEW);
00073 } else if (strcmp(filename, SPECIAL_RECENT) == 0) {
00074 set_special_viewmode(item, RECENT_VIEW);
00075 } else if (strcmp(filename, SPECIAL_UPDIR) == 0) {
00076 fileview_stop_update_display();
00077 fileview_dir_up();
00078 } else if (strcmp(filename, SPECIAL_SEARCH) == 0) {
00079 fileview_show_search_dialog();
00080 } else {
00081 ERRORPRINTF("unknown special entry '%s'", filename);
00082 g_assert(0);
00083 }
00084 }
00085
00086
00087
00088 static int activate_shortcut_to_web_location ( const filelist_entry_t *fileinfo,
00089 const char* url)
00090 {
00091 g_assert(url && url[0]);
00092
00093 LOGPRINTF( "entry: filename [%s] url [%s]", fileinfo->filename->str, url);
00094
00095 const gchar *filename_display = fileinfo->filename_display->str;
00096 gchar *ret_message = NULL;
00097 gint errcode = ipc_sys_open_url(url, filename_display, NULL, &ret_message);
00098
00099 if ( errcode > 0 )
00100 {
00101 gchar *error_msg = NULL;
00102 ERRORPRINTF("cannot open url, url [%s], errcode %d [%s]", url, errcode, ret_message);
00103 switch (errcode)
00104 {
00105 case 1:
00106 default:
00107 error_msg = g_strdup_printf(
00108 _("The webpage '%s' cannot be opened."), url);
00109 show_error_dialog(error_msg);
00110 break;
00111 case 4:
00112 error_msg = g_strdup_printf(
00113 _("The webpage '%s' cannot be opened."), url);
00114 show_error_dialog(error_msg);
00115 break;
00116 case 2:
00117 case 3:
00118 break;
00119 }
00120 g_free(error_msg);
00121 }
00122
00123 g_free(ret_message);
00124 return ER_OK;
00125 }
00126
00127
00128 static int activate_shortcut_to_application(const filelist_entry_t *fileinfo, const char* cmdline)
00129 {
00130 const gchar *filename_display = fileinfo->filename_display->str;
00131 const gchar *directory = fileinfo->directory_path->str;
00132
00133 gchar *ret_message = NULL;
00134 gint errcode = ipc_sys_start_task(cmdline, directory, filename_display, NULL, &ret_message);
00135 if (errcode > 0) {
00136 if (ret_message && ret_message[0] != '\0') {
00137 ERRORPRINTF("cannot launch viewer, cmd_line [%s], errcode %d [%s]", cmdline, errcode, ret_message);
00138 show_error_dialog(ret_message);
00139 } else {
00140 gchar* error_msg = NULL;
00141 switch (errcode)
00142 {
00143 case 1:
00144 default:
00145 error_msg = g_strdup_printf(
00146 _("The '%s' application cannot be opened.\n"
00147 "Possibly the application is already open. Close it first and try again."),
00148 filename_display );
00149 show_error_dialog(error_msg);
00150 break;
00151 case 4:
00152 error_msg = g_strdup_printf(_("'%s' cannot be opened."), filename_display);
00153 show_error_dialog(error_msg);
00154 break;
00155 case 2:
00156 case 3:
00157 break;
00158 }
00159 g_free(error_msg);
00160 }
00161 return ER_FAIL;
00162 }
00163 return ER_OK;
00164 }
00165
00166
00167 static int activate_shortcut (const filelist_entry_t *fileinfo)
00168 {
00169 shortcut_t *shortcut = NULL;
00170 int ret = parse_shortcut_file(fileinfo->directory_path->str,
00171 fileinfo->filename->str, &shortcut);
00172 if (ret == ER_NOT_FOUND) {
00173 gchar* error_msg = g_strdup_printf(
00174 _("%s appears to no longer exist.\n"
00175 "Try connecting and ejecting the device from the computer."),
00176 fileinfo->filename_display->str);
00177 show_error_dialog(error_msg);
00178 g_free(error_msg);
00179 return ret;
00180 }
00181 if (ret != ER_OK) return ret;
00182
00183 switch (shortcut->type)
00184 {
00185 case SHORTCUT_TO_FILE:
00186 {
00187 filelist_entry_t *fileinfo_target = filelist_entry_new();
00188 fileinfo_target->filename = g_string_new(shortcut->details.file.filename);
00189 fileinfo_target->filename_display = g_string_new( shortcut->name );
00190 fileinfo_target->directory_path = g_string_new(shortcut->details.file.directory);
00191 fileinfo_target->filetype = g_string_new( g_extension_pointer(shortcut->details.file.filename));
00192 fileinfo_target->is_directory = FALSE;
00193 ret = activate_item(fileinfo_target);
00194 filelist_entry_free(fileinfo_target);
00195 break;
00196 }
00197 case SHORTCUT_TO_FOLDER:
00198 {
00199 if (shortcut->details.folder.directory == NULL) {
00200 ret = ER_NOT_FOUND;
00201 break;
00202 }
00203 fileview_stop_update_display();
00204 char fullname[512];
00205 sprintf(fullname, "%s/%s", shortcut->details.folder.directory,
00206 shortcut->details.folder.filename);
00207 fileview_dir_down(fullname, fileinfo->filename->str);
00208 ret = ER_OK;
00209 break;
00210 }
00211 case SHORTCUT_TO_APPLICATION:
00212 ret = activate_shortcut_to_application(fileinfo, shortcut->details.application.command_line);
00213 break;
00214
00215 case SHORTCUT_TO_WEB_LOCATION:
00216 ret = activate_shortcut_to_web_location(fileinfo, shortcut->details.web.url);
00217 break;
00218 default:
00219
00220 ret = ER_FAIL;
00221 }
00222
00223 shortcut_free(shortcut);
00224 return ret;
00225 }
00226
00227
00228
00229 int activate_item (const filelist_entry_t *item)
00230 {
00231 g_assert(item);
00232 g_assert(item->directory_path && item->directory_path->str);
00233 g_assert(item->filename && item->filename->str );
00234
00235 const gchar *filetype = item->filetype->str;
00236 if (strcmp(filetype, SPECIAL_ITEM_NAME) == 0) {
00237 handle_special_item(item);
00238 return ER_OK;
00239 }
00240
00241 const gchar *filename = item->filename->str;
00242 const gchar *directory = item->directory_path->str;
00243 if (item->is_directory)
00244 {
00245 fileview_stop_update_display();
00246 char fullname[512];
00247 sprintf(fullname, "%s/%s", directory, filename);
00248 fileview_dir_down(fullname, filename);
00249 return ER_OK;
00250 }
00251
00252 if (is_shortcut_file_extension(filetype))
00253 {
00254 return activate_shortcut(item);
00255 }
00256
00257
00258 const gchar *viewer_cmd = get_viewer_from_file_extension(filetype);
00259 if (viewer_cmd == NULL)
00260 {
00261 gchar *error_msg = g_strdup_printf( _("'%s' cannot be opened; the format is unknown."),
00262 filename);
00263 show_error_dialog(error_msg);
00264 g_free(error_msg);
00265 return ER_FAIL;
00266 }
00267
00268 gchar *cmd_line = g_strdup_printf("%s \"%s/%s\"", viewer_cmd, directory, filename);
00269 gchar *ret_message = NULL;
00270 gint errcode = ipc_sys_start_task(cmd_line, directory,
00271 item->filename_display->str, NULL, &ret_message);
00272 if (errcode > 0 && ret_message && ret_message[0] != '\0')
00273 {
00274 ERRORPRINTF("cannot launch viewer, cmd_line [%s], errcode %d [%s]", cmd_line, errcode, ret_message);
00275 show_error_dialog(ret_message);
00276 }
00277 #if MACHINE_IS_DR800S || MACHINE_IS_DR800SG || MACHINE_IS_DR800SW
00278 else if (errcode == 0) filemodel_update_last_read(item);
00279 #endif
00280
00281 g_free(ret_message);
00282 g_free(cmd_line);
00283 return ER_OK;
00284 }
00285
00286
00287 static void delete_item_from_db(erMetadb db, const filelist_entry_t *item)
00288 {
00289 g_assert(db);
00290 if (item->is_directory) {
00291 ermetadb_global_remove_folder(db, item->directory_path->str, item->filename->str);
00292 } else {
00293 ermetadb_global_remove_file(db, item->directory_path->str, item->filename->str);
00294 }
00295 }
00296
00297
00298 int delete_item(const filelist_entry_t *item)
00299 {
00300 g_assert(item);
00301 g_assert(item->filename && item->filename->str );
00302 g_assert(item->filetype && item->filetype->str );
00303 g_assert(item->directory_path && item->directory_path->str );
00304
00305 const gchar *filename = item->filename->str;
00306 const gchar *filetype = item->filetype->str;
00307
00308 LOGPRINTF( "entry: filename [%s] dirpath [%s]", filename, item->directory_path->str);
00309
00310
00311 gchar *filepath = g_strdup_printf("%s/%s", item->directory_path->str, filename);
00312
00313 const gchar *viewer_cmd = get_viewer_from_file_extension(filetype);
00314 if (viewer_cmd)
00315 {
00316 gchar *cmd_line = g_strdup_printf("%s \"%s\"", viewer_cmd, filepath);
00317 ipc_sys_stop_task(cmd_line);
00318 g_free(cmd_line);
00319 }
00320
00321
00322 const char *argv[10];
00323 unsigned int argc = 0;
00324 argv[argc++] = "rm";
00325 argv[argc++] = "-fr";
00326 argv[argc++] = filepath;
00327 argv[argc++] = NULL;
00328 g_assert(argc < sizeof(argv)/sizeof(argv[0]));
00329 gint stat;
00330 GError *err = NULL;
00331 gboolean ok = g_spawn_sync( NULL,
00332 (char**)argv,
00333 NULL,
00334 G_SPAWN_SEARCH_PATH,
00335 NULL,
00336 NULL,
00337 NULL,
00338 NULL,
00339 &stat,
00340 &err );
00341 g_free(filepath);
00342 if (!ok)
00343 {
00344 ERRORPRINTF("g_spawn_sync error [%s] on delete [%s/%s]",
00345 err->message, item->directory_path->str, filename);
00346 g_clear_error(&err);
00347 return ER_FAIL;
00348 }
00349
00350 delete_item_from_db(filemodel_get_database(), item);
00351 return ER_OK;
00352 }
00353
00354
00355 static gboolean shortcut_allowed(const filelist_entry_t *fileinfo)
00356 {
00357
00358 if (strcmp(fileinfo->filetype->str, SPECIAL_ITEM_NAME) == 0) return FALSE;
00359
00360
00361 if (is_shortcut_file_extension(fileinfo->filetype->str)) return FALSE;
00362
00363
00364 if (strcmp(fileinfo->filename->str, "new") == 0) return FALSE;
00365
00366 return TRUE;
00367 }
00368
00369
00370 int create_shortcut_item (const filelist_entry_t *item)
00371 {
00372 g_assert(item);
00373 g_assert(item->filename && item->filename->str );
00374 g_assert(item->filename_display && item->filename_display->str);
00375 g_assert(item->filetype && item->filetype->str );
00376 g_assert(item->directory_path && item->directory_path->str );
00377
00378 if (!shortcut_allowed(item)) {
00379 gchar *error_msg = g_strdup_printf(_("A shortcut cannot be created for this item"));
00380 show_error_dialog(error_msg);
00381 g_free(error_msg);
00382 return ER_FORBIDDEN;
00383 }
00384
00385 const gchar *mountpoint = ipc_get_media();
00386 char shortcut_dir[256];
00387 sprintf(shortcut_dir, "%s/%s", mountpoint, DIR_SHORTCUTS);
00388
00389
00390 g_mkdir_with_parents (shortcut_dir, 644);
00391
00392
00393 const gchar *target_dir = item->directory_path->str;
00394 const gchar *target_file = item->filename->str;
00395 const gchar *target_display = item->filename_display->str;
00396 GString *shortcut_file = g_string_new("");
00397 int ret = create_shortcut_file(target_dir, target_file, target_display, shortcut_dir, shortcut_file);
00398 if (ret != ER_OK) {
00399 ERRORPRINTF("cannot create shortcut for %s/%s", target_dir, target_file);
00400 g_string_free(shortcut_file, TRUE);
00401 return ret;
00402 }
00403
00404
00405 erMetadb db = filemodel_get_database();
00406 gint64 now = time(NULL);
00407 char subtitle[512];
00408
00409 snprintf(subtitle, 512, "%s/%s", target_dir + strlen(mountpoint), target_file);
00410 subtitle[sizeof(subtitle)-1] = 0;
00411 char* cp = subtitle;
00412 if (subtitle[0] == '/') cp++;
00413 ret = ermetadb_global_add_file(db, shortcut_dir, shortcut_file->str, 0, now, target_display, cp, "");
00414 if (ret != ER_OK) {
00415 ERRORPRINTF("cannot add %s/%s to metadb", shortcut_dir, shortcut_file->str);
00416 }
00417
00418 g_string_free(shortcut_file, TRUE);
00419 return ret;
00420 }
00421