From 7c79cf41e26e1e170331f2d6c6968bfafc9fde0c Mon Sep 17 00:00:00 2001 From: Thomas Bernard Date: Wed, 4 Apr 2018 19:11:21 +0200 Subject: [PATCH] Add "Set Rel" for directory bookmarks see http://pulkomandy.tk/projects/GrafX2/ticket/45 It is disabled under AmigaOS, AROS and MorphOS --- src/filesel.c | 48 ++++++++++++++++++++++++++++++++++++---------- src/io.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/io.h | 4 ++++ 3 files changed, 95 insertions(+), 10 deletions(-) diff --git a/src/filesel.c b/src/filesel.c index 43715d95..2bb2572e 100644 --- a/src/filesel.c +++ b/src/filesel.c @@ -1170,7 +1170,7 @@ short Compute_click_offset_in_fileselector(void) return computed_offset; } -void Display_bookmark(T_Dropdown_button * Button, int bookmark_number) +static void Display_bookmark(T_Dropdown_button * Button, int bookmark_number) { if (Config.Bookmark_directory[bookmark_number]) { @@ -1182,11 +1182,6 @@ void Display_bookmark(T_Dropdown_button * Button, int bookmark_number) Window_rectangle(Button->Pos_X+3+10+label_size*8,Button->Pos_Y+2,(8-label_size)*8,8,MC_Light); // Menu apparait sur clic droit Button->Active_button=RIGHT_SIDE; - // item actifs - Window_dropdown_clear_items(Button); - Window_dropdown_add_item(Button,0,"Set"); - Window_dropdown_add_item(Button,1,"Rename"); - Window_dropdown_add_item(Button,2,"Clear"); } else { @@ -1194,9 +1189,17 @@ void Display_bookmark(T_Dropdown_button * Button, int bookmark_number) Print_in_window(Button->Pos_X+3+10,Button->Pos_Y+2,"--------",MC_Dark,MC_Light); // Menu apparait sur clic droit ou gauche Button->Active_button=RIGHT_SIDE|LEFT_SIDE; - // item actifs - Window_dropdown_clear_items(Button); - Window_dropdown_add_item(Button,0,"Set"); + } + // item actifs + Window_dropdown_clear_items(Button); + Window_dropdown_add_item(Button,0,"Set"); +#if !(defined(__amigaos4__) || defined(__AROS__) || defined(__MORPHOS__) || defined(__amigaos__)) + Window_dropdown_add_item(Button,3,"Set Rel"); +#endif + if (Config.Bookmark_directory[bookmark_number]) + { + Window_dropdown_add_item(Button,1,"Rename"); + Window_dropdown_add_item(Button,2,"Clear"); } } @@ -1728,7 +1731,7 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context for (temp=0;tempPos_X+3,bookmark_dropdown[temp]->Pos_Y+2,ICON_STAR); Display_bookmark(bookmark_dropdown[temp],temp); } @@ -2133,6 +2136,7 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context { // Bookmark char * directory_name; + const char * rel_path; load_from_clipboard = 0; switch(Window_attribute2) @@ -2196,6 +2200,30 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context Display_bookmark(bookmark_dropdown[clicked_button-10],clicked_button-10); } break; + case 3: // Set Rel + rel_path = Calculate_relative_path(Data_directory, Selector->Directory); + if (rel_path != NULL) + { + // Erase old bookmark + free(Config.Bookmark_directory[clicked_button-10]); + Config.Bookmark_directory[clicked_button-10] = NULL; + + Config.Bookmark_directory[clicked_button-10] = strdup(rel_path); + directory_name=Find_last_separator(Selector->Directory); + if (directory_name && directory_name[1]!='\0') + directory_name++; + else + directory_name=Selector->Directory; + temp=strlen(directory_name); + strncpy(Config.Bookmark_label[clicked_button-10],directory_name,8); + if (temp>8) + { + Config.Bookmark_label[clicked_button-10][7]=ELLIPSIS_CHARACTER; + Config.Bookmark_label[clicked_button-10][8]='\0'; + } + Display_bookmark(bookmark_dropdown[clicked_button-10],clicked_button-10); + } + break; } } break; diff --git a/src/io.c b/src/io.c index 23637af1..27c1de00 100644 --- a/src/io.c +++ b/src/io.c @@ -918,3 +918,56 @@ int Remove_directory(const char * path) return rmdir(path); #endif } + +/// +/// Calculate relative path +const char * Calculate_relative_path(const char * ref_path, const char * path) +{ + char real_ref_path[MAX_PATH_CHARACTERS]; + static char rel_path[MAX_PATH_CHARACTERS]; + int last_separator = -1; + int i; + int separator_count = 0; + + if (ref_path == NULL || path == NULL) + return NULL; + if (Realpath(ref_path, real_ref_path) == NULL) + { + strncpy(real_ref_path, ref_path, MAX_PATH_CHARACTERS); + real_ref_path[MAX_PATH_CHARACTERS-1] = '\0'; + } +#if defined(WIN32) || defined(__MINT__) + if ((real_ref_path[1] == ':') && (real_ref_path[0] | 32) != (path[0] | 32)) + return NULL; // path on different volumes, not possible +#endif + // look for common path parts + for (i = 0; real_ref_path[i] == path[i] && path[i] != '\0'; i++) + { + if (path[i] == PATH_SEPARATOR[0]) + last_separator = i; +#if defined(WIN32) + else if(path[i] == '/') + last_separator = i; +#endif + } + if (real_ref_path[i] == '\0' && path[i] == PATH_SEPARATOR[0]) + { + snprintf(rel_path, MAX_PATH_CHARACTERS, ".%s", path + i); // path is under ref_path + return rel_path; + } + if (real_ref_path[i] == '\0' && path[i] == '\0') + return "."; // path are identical + if (last_separator <= 0) + return path; // no common part found return absolute path + // count the number of path separators in the reference path + for (i = last_separator; real_ref_path[i] != '\0'; i++) + if (real_ref_path[i] == PATH_SEPARATOR[0]) + separator_count++; + i = 0; + // construct the relative path + while(separator_count-- > 0) + i += snprintf(rel_path + i, MAX_PATH_CHARACTERS - i, "..%s", PATH_SEPARATOR); + strncpy(rel_path + i, path + last_separator + 1, MAX_PATH_CHARACTERS - i); + rel_path[MAX_PATH_CHARACTERS -1] = '\0'; + return rel_path; +} diff --git a/src/io.h b/src/io.h index 7c1a77c3..a960ef7a 100644 --- a/src/io.h +++ b/src/io.h @@ -195,5 +195,9 @@ int Remove_path(const char * path); /// Remove the directory int Remove_directory(const char * path); +/// +/// Calculate relative path +const char * Calculate_relative_path(const char * ref_path, const char * path); + /** @}*/ #endif