From 04761c79c4b5d911274a541ff389f9852423375d Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Sat, 2 Apr 2011 17:43:16 +0000 Subject: [PATCH] Unbroke the file selector (was listing only hidden files instead of non-hidden). Lua: can browse the whole filesystem now git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1761 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- src/buttons.c | 4 +- src/engine.c | 12 ++++- src/engine.h | 2 +- src/factory.c | 126 ++++++++++++++++++++++++++------------------------ src/filesel.c | 20 ++++---- src/io.c | 75 ++++++++++++++++++++++++++++-- src/io.h | 4 +- src/struct.h | 3 +- 8 files changed, 163 insertions(+), 83 deletions(-) diff --git a/src/buttons.c b/src/buttons.c index 0ab8c362..d53a8b60 100644 --- a/src/buttons.c +++ b/src/buttons.c @@ -1307,7 +1307,7 @@ void Button_Skins(void) // Scroller for the fileselector (file_scroller = Window_set_scroller_button(155, FILESEL_Y - 1, 82, Skin_files_list.Nb_elements, 10, 0)), // 3 - Draw_one_skin_name); // 4 + Draw_one_skin_name, 2); // 4 skin_list->Cursor_position = Find_file_in_fileselector(&Skin_files_list, Config.Skin_file); @@ -4835,7 +4835,7 @@ void Button_Text(void) Window_set_normal_button(54,160,60,14,"Cancel",0,1,KEY_ESC); // 12 // List of fonts - font_list = Window_set_list_button(font_list_button, font_scroller, Draw_one_font_name); // 13 + font_list = Window_set_list_button(font_list_button, font_scroller, Draw_one_font_name, 2); // 13 // Restore its settings from last passage in screen font_list->List_start = list_start; font_list->Cursor_position = cursor_position; diff --git a/src/engine.c b/src/engine.c index e140c9a1..717232fd 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2184,7 +2184,7 @@ void Window_dropdown_clear_items(T_Dropdown_button * dropdown) // - entry_button is the textual area where the list values will be printed. // - scroller is a scroller button attached to it -T_List_button * Window_set_list_button(T_Special_button * entry_button, T_Scroller_button * scroller, Func_draw_list_item draw_list_item) +T_List_button * Window_set_list_button(T_Special_button * entry_button, T_Scroller_button * scroller, Func_draw_list_item draw_list_item, byte color_index) { T_List_button *temp; @@ -2195,6 +2195,7 @@ T_List_button * Window_set_list_button(T_Special_button * entry_button, T_Scroll temp->Entry_button = entry_button; temp->Scroller = scroller; temp->Draw_list_item = draw_list_item; + temp->Color_index = color_index; temp->Next=Window_list_button_list; Window_list_button_list=temp; @@ -2216,12 +2217,19 @@ void Window_redraw_list(T_List_button * list) // Remaining rectangle under list i=list->Scroller->Nb_visibles-list->Scroller->Nb_elements; if (i>0) + { + byte color; + color = list->Color_index == 0 ? MC_Black : + (list->Color_index == 1 ? MC_Dark : + (list->Color_index == 2 ? MC_Light : MC_White)); + Window_rectangle( list->Entry_button->Pos_X, list->Entry_button->Pos_Y+list->Scroller->Nb_elements*8, list->Entry_button->Width, i*8, - MC_Light); + color); + } } //----------------------- Ouverture d'un pop-up ----------------------- diff --git a/src/engine.h b/src/engine.h index d9f16861..fb577db2 100644 --- a/src/engine.h +++ b/src/engine.h @@ -98,7 +98,7 @@ void Window_dropdown_clear_items(T_Dropdown_button * dropdown); T_Dropdown_choice * Dropdown_activate(T_Dropdown_button *button, short off_x, short off_y); T_List_button * Window_set_list_button(T_Special_button * entry_button, - T_Scroller_button * scroller, Func_draw_list_item draw_list_item); + T_Scroller_button * scroller, Func_draw_list_item draw_list_item, byte color_index); void Window_redraw_list(T_List_button * list); byte Window_click_in_rectangle(short start_x, short start_y, short end_x, short end_y); diff --git a/src/factory.c b/src/factory.c index de18f4c9..a3cab720 100644 --- a/src/factory.c +++ b/src/factory.c @@ -1268,15 +1268,23 @@ void Draw_script_name(word x, word y, word index, byte highlighted) current_item = Get_item_by_index(&Scripts_selector, index); - if (current_item->Type==1) // Directories + if (current_item->Type==0) // Files { - fg=(highlighted)?MC_Black:MC_Dark; - bg=(highlighted)?MC_Dark:MC_Light; + fg=(highlighted)?MC_White:MC_Light; + bg=(highlighted)?MC_Dark:MC_Black; } - else // Files + else if (current_item->Type==1) // Directories { - fg=MC_Black; - bg=(highlighted)?MC_Dark:MC_Light; + fg=(highlighted)?MC_Light:MC_Dark; + bg=(highlighted)?MC_Dark:MC_Black; + } + else // Drives + { + fg=(highlighted)?MC_Light:MC_Dark; + bg=(highlighted)?MC_Dark:MC_Black; + + Window_display_icon_sprite(x,y,current_item->Icon); + x+=8; } Print_in_window(x, y, current_item->Short_name, fg,bg); @@ -1426,30 +1434,36 @@ void Run_script(const char *script_subdirectory, const char *script_filename) lua_State* L; const char* message; byte old_cursor_shape=Cursor_shape; - char scriptdir[MAX_PATH_CHARACTERS]; - - strcpy(scriptdir, Data_directory); - strcat(scriptdir, "scripts/"); + char buf[MAX_PATH_CHARACTERS]; // Some scripts are slow Cursor_shape=CURSOR_SHAPE_HOURGLASS; Display_cursor(); Flush_update(); - chdir(scriptdir); - if (script_subdirectory && script_subdirectory[0]!='\0') { - sprintf(Last_run_script, "%s%s%s", script_subdirectory, PATH_SEPARATOR, script_filename); + strcpy(Last_run_script, script_subdirectory); + Append_path(Last_run_script, script_filename, NULL); } else { strcpy(Last_run_script, script_filename); } + // This chdir is for the script's sake. Grafx2 itself will (try to) + // not rely on what is the system's current directory. + Extract_path(buf,Last_run_script); + chdir(buf); L = lua_open(); - putenv("LUA_PATH=libs\\?.lua"); + + strcpy(buf, "LUA_PATH="); + strcat(buf, Data_directory); + Append_path(buf+9, "scripts", NULL); + Append_path(buf+9, "libs", NULL); + Append_path(buf+9, "?.lua", NULL); + putenv(buf); // writing and reading pixels lua_register(L,"putbrushpixel",L_PutBrushPixel); @@ -1687,24 +1701,34 @@ void Set_script_shortcut(T_Fileselector_item * script_item) void Button_Brush_Factory(void) { static char selected_file[MAX_PATH_CHARACTERS]=""; - static char sub_directory[MAX_PATH_CHARACTERS]=""; + static char sub_directory[MAX_PATH_CHARACTERS]="!"; short clicked_button; T_List_button* scriptlist; T_Scroller_button* scriptscroll; T_Special_button* scriptarea; - char scriptdir[MAX_PATH_CHARACTERS]; T_Fileselector_item *item; int last_selected_item=-1; + + if (sub_directory[0]=='!') + { + // Default directory + Realpath(Data_directory, sub_directory); + Append_path(sub_directory, "scripts", NULL); + } + // Reinitialize the list Free_fileselector_list(&Scripts_selector); - strcpy(scriptdir, Data_directory); - strcat(scriptdir, "scripts/"); - strcat(scriptdir, sub_directory); - if (sub_directory[0]!='\0') + if (sub_directory[0]=='\0') + { + Read_list_of_drives(&Scripts_selector,NAME_WIDTH+1); + } + else + { Add_element_to_list(&Scripts_selector, PARENT_DIR, Format_filename(PARENT_DIR, NAME_WIDTH+1, 1), 1, ICON_NONE); - // Add each found file to the list - For_each_directory_entry(scriptdir, Add_script); + // Add each found file to the list + For_each_directory_entry(sub_directory, Add_script); + } // Sort it Sort_list_of_files(&Scripts_selector); // @@ -1715,11 +1739,11 @@ void Button_Brush_Factory(void) Window_display_frame_in(6, FILESEL_Y - 2, NAME_WIDTH*8+4, 84); // File selector // Fileselector - scriptarea=Window_set_special_button(8, FILESEL_Y + 1, NAME_WIDTH*8, 80); // 2 + scriptarea=Window_set_special_button(8, FILESEL_Y + 0, NAME_WIDTH*8, 80); // 2 // Scroller for the fileselector scriptscroll = Window_set_scroller_button(NAME_WIDTH*8+14, FILESEL_Y - 1, 82, Scripts_selector.Nb_elements,10, 0); // 3 - scriptlist = Window_set_list_button(scriptarea,scriptscroll,Draw_script_name); // 4 + scriptlist = Window_set_list_button(scriptarea,scriptscroll,Draw_script_name, 0); // 4 Window_set_normal_button(10, 149, 67, 14, "Run", 0, 1, SDLK_RETURN); // 5 @@ -1811,55 +1835,37 @@ void Button_Brush_Factory(void) if (item->Type==0) // File { - strcpy(selected_file, sub_directory); - strcat(selected_file, item->Full_name); + strcpy(selected_file, item->Full_name); break; } - else if (item->Type==1) // Directory + else if (item->Type==1 || item->Type==2) // Directory { - if (!strcmp(item->Full_name,PARENT_DIR)) + if (item->Type==2) { - // Going up one directory - long len; - char * slash_pos; - - // Remove trailing slash - len=strlen(sub_directory); - if (len && !strcmp(sub_directory+len-1,PATH_SEPARATOR)) - sub_directory[len-1]='\0'; - - slash_pos=Find_last_slash(sub_directory); - if (slash_pos) - { - strcpy(selected_file, slash_pos+1); - *slash_pos='\0'; - } - else - { - strcpy(selected_file, sub_directory); - sub_directory[0]='\0'; - } + // Selecting one drive root + strcpy(selected_file, PARENT_DIR); + strcat(sub_directory, item->Full_name); } else { - // Going down one directory - strcpy(selected_file, PARENT_DIR); - - strcat(sub_directory, item->Full_name); - strcat(sub_directory, PATH_SEPARATOR); + // Going down one or up by one directory + Append_path(sub_directory, item->Full_name, selected_file); } // No break: going back up to beginning of loop // Reinitialize the list Free_fileselector_list(&Scripts_selector); - strcpy(scriptdir, Data_directory); - strcat(scriptdir, "scripts/"); - strcat(scriptdir, sub_directory); - if (sub_directory[0]!='\0') + if (sub_directory[0]=='\0') + { + Read_list_of_drives(&Scripts_selector,NAME_WIDTH+1); + } + else + { Add_element_to_list(&Scripts_selector, PARENT_DIR, Format_filename(PARENT_DIR, NAME_WIDTH+1, 1), 1, ICON_NONE); - // Add each found file to the list - For_each_directory_entry(scriptdir, Add_script); + // Add each found file to the list + For_each_directory_entry(sub_directory, Add_script); + } // Sort it Sort_list_of_files(&Scripts_selector); // @@ -1876,7 +1882,7 @@ void Button_Brush_Factory(void) if (clicked_button == 5) // Run the script { - Run_script("", selected_file); + Run_script(sub_directory, selected_file); } else { diff --git a/src/filesel.c b/src/filesel.c index 117a8ab3..756064f7 100644 --- a/src/filesel.c +++ b/src/filesel.c @@ -388,7 +388,7 @@ void Read_list_of_files(T_Fileselector *list, byte selected_format) (!strcmp(entry->d_name, PARENT_DIR) || // ou qu'il n'est pas caché Config.Show_hidden_directories || - !File_is_hidden(entry->d_name))) + !File_is_hidden(entry->d_name, entry->d_name))) { // On rajoute le répertoire à la liste Add_element_to_list(list, entry->d_name, Format_filename(entry->d_name, 19, 1), 1, ICON_NONE); @@ -396,7 +396,7 @@ void Read_list_of_files(T_Fileselector *list, byte selected_format) } else if (S_ISREG(Infos_enreg.st_mode) && //Il s'agit d'un fichier (Config.Show_hidden_files || //Il n'est pas caché - File_is_hidden(entry->d_name))) + !File_is_hidden(entry->d_name, entry->d_name))) { const char * ext = filter; while (ext!=NULL) @@ -474,7 +474,7 @@ void bstrtostr( BSTR in, STRPTR out, TEXT max ) #endif // -- Lecture d'une liste de lecteurs / volumes ----------------------------- -void Read_list_of_drives(T_Fileselector *list) +void Read_list_of_drives(T_Fileselector *list, byte name_length) { // Empty the current content of fileselector: @@ -495,7 +495,7 @@ void Read_list_of_drives(T_Fileselector *list) { bstrtostr( dl->dol_Name, tmp, 254 ); strcat( tmp, ":" ); - Add_element_to_list(list, tmp, Format_filename(tmp, 19, 2), 2, ICON_NONE ); + Add_element_to_list(list, tmp, Format_filename(tmp, name_length, 2), 2, ICON_NONE ); list->Nb_directories++; } UnLockDosList( LDF_VOLUMES | LDF_READ ); @@ -539,7 +539,7 @@ void Read_list_of_drives(T_Fileselector *list) break; } drive_name[0]='A'+bit_index; - Add_element_to_list(list, drive_name, Format_filename(drive_name,18,2), 2, icon); + Add_element_to_list(list, drive_name, Format_filename(drive_name,name_length-1,2), 2, icon); list->Nb_directories++; drive_index++; } @@ -556,7 +556,7 @@ void Read_list_of_drives(T_Fileselector *list) if ( (1 << bit_index) & drive_bits ) { drive_name[0]='A'+bit_index; - Add_element_to_list(list, drive_name,Format_filename(drive_name,19,2),2,ICON_NONE); + Add_element_to_list(list, drive_name,Format_filename(drive_name,name_length,2),2,ICON_NONE); list->Nb_directories++; drive_index++; } @@ -578,11 +578,11 @@ void Read_list_of_drives(T_Fileselector *list) #else char * home_dir = getenv("HOME"); #endif - Add_element_to_list(list, "/", Format_filename("/",19,2), 2, ICON_NONE); + Add_element_to_list(list, "/", Format_filename("/",name_length,2), 2, ICON_NONE); list->Nb_directories++; if(home_dir) { - Add_element_to_list(list, home_dir, Format_filename(home_dir, 19, 2), 2, ICON_NONE); + Add_element_to_list(list, home_dir, Format_filename(home_dir, name_length, 2), 2, ICON_NONE); list->Nb_directories++; } @@ -592,7 +592,7 @@ void Read_list_of_drives(T_Fileselector *list) { if(mount_points_list->me_dummy == 0 && strcmp(mount_points_list->me_mountdir,"/") && strcmp(mount_points_list->me_mountdir,"/home")) { - Add_element_to_list(list, mount_points_list->me_mountdir, Format_filename(mount_points_list->me_mountdir, 19, 2), 2, ICON_NONE); + Add_element_to_list(list, mount_points_list->me_mountdir, Format_filename(mount_points_list->me_mountdir, name_length, 2), 2, ICON_NONE); list->Nb_directories++; } next = mount_points_list -> me_next; @@ -1704,7 +1704,7 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context) Main_fileselector_position=0; Main_fileselector_offset=0; // Affichage des premiers fichiers visibles: - Read_list_of_drives(&Filelist); + Read_list_of_drives(&Filelist,19); Sort_list_of_files(&Filelist); Prepare_and_display_filelist(Main_fileselector_position,Main_fileselector_offset,file_scroller); Display_cursor(); diff --git a/src/io.c b/src/io.c index 81cf19c0..c28155ed 100644 --- a/src/io.c +++ b/src/io.c @@ -200,6 +200,67 @@ void Extract_path(char *dest, const char *source) strcat(dest, PATH_SEPARATOR); } +/// +/// Appends a file or directory name to an existing directory name. +/// As a special case, when the new item is equal to PARENT_DIR, this +/// will remove the rightmost directory name. +/// reverse_path is optional, if it's non-null, the function will +/// write there : +/// - if filename is ".." : The name of eliminated directory/file +/// - else: ".." +void Append_path(char *path, const char *filename, char *reverse_path) +{ + // Parent + if (!strcmp(filename, PARENT_DIR)) + { + // Going up one directory + long len; + char * slash_pos; + + // Remove trailing slash + len=strlen(path); + if (len && !strcmp(path+len-1,PATH_SEPARATOR)) + path[len-1]='\0'; + + slash_pos=Find_last_slash(path); + if (slash_pos) + { + if (reverse_path) + strcpy(reverse_path, slash_pos+1); + *slash_pos='\0'; + } + else + { + if (reverse_path) + strcpy(reverse_path, path); + path[0]='\0'; + } + #if defined(__WIN32__) + // Roots of drives need a pending antislash + if (path[0]!='\0' && path[1]==':' && path[2]=='\0') + { + strcat(path, PATH_SEPARATOR); + } + #endif + } + else + // Sub-directory + { + long len; + // Add trailing slash if needed + len=strlen(path); + if (len && strcmp(path+len-1,PATH_SEPARATOR)) + { + strcpy(path+len, PATH_SEPARATOR); + len+=strlen(PATH_SEPARATOR); + } + strcat(path, filename); + + if (reverse_path) + strcpy(reverse_path, PARENT_DIR); + } +} + int File_exists(char * fname) // Détermine si un file passé en paramètre existe ou non dans le // répertoire courant. @@ -244,16 +305,20 @@ int Directory_exists(char * directory) #define FILE_IS_HIDDEN_ATTRIBUTE #endif /// Check if a file or directory is hidden. -int File_is_hidden(FILE_IS_HIDDEN_ATTRIBUTE const char *fname) +int File_is_hidden(FILE_IS_HIDDEN_ATTRIBUTE const char *fname, const char *full_name) { #if defined(__amigaos4__) || defined(__AROS__) || defined(__MORPHOS__) || defined(__amigaos__) || defined(__MINT__) // False (unable to determine, or irrrelevent for platform) return 0; #elif defined(__WIN32__) - unsigned long att = GetFileAttributesA(fname); + unsigned long att; + if (full_name!=NULL) + att = GetFileAttributesA(full_name); + else + att = GetFileAttributesA(fname); if (att==INVALID_FILE_ATTRIBUTES) return 0; - return att&FILE_ATTRIBUTE_HIDDEN?1:0; + return (att&FILE_ATTRIBUTE_HIDDEN)?1:0; #else return fname[0]=='.'; #endif @@ -314,7 +379,7 @@ void For_each_directory_entry(const char * directory_name, void Callback(const c char full_filename[MAX_PATH_CHARACTERS]; int filename_position; strcpy(full_filename, directory_name); - current_directory=opendir(directory_name); + current_directory=opendir(full_filename); if(current_directory == NULL) return; // Répertoire invalide ... filename_position = strlen(full_filename); if (filename_position==0 || strcmp(full_filename+filename_position-1,PATH_SEPARATOR)) @@ -331,7 +396,7 @@ void For_each_directory_entry(const char * directory_name, void Callback(const c full_filename, S_ISREG(Infos_enreg.st_mode), S_ISDIR(Infos_enreg.st_mode), - File_is_hidden(entry->d_name)); + File_is_hidden(entry->d_name, full_filename)); } closedir(current_directory); } diff --git a/src/io.h b/src/io.h index 15419df2..1c9c52b8 100644 --- a/src/io.h +++ b/src/io.h @@ -90,8 +90,8 @@ int File_exists(char * fname); /// Returns true if a directory passed as a parameter exists in the current directory. int Directory_exists(char * directory); -/// Check if a file or directory is hidden. -int File_is_hidden(const char *fname); +/// Check if a file or directory is hidden. Full name (with directories) is optional. +int File_is_hidden(const char *fname, const char *full_name); /// Scans a directory, calls Callback for each file in it, void For_each_file(const char * directory_name, void Callback(const char *)); diff --git a/src/struct.h b/src/struct.h index 62422bd0..d4f06b82 100644 --- a/src/struct.h +++ b/src/struct.h @@ -215,7 +215,8 @@ typedef struct T_List_button T_Special_button * Entry_button; ///< Pointer to the associated selection control. T_Scroller_button * Scroller; ///< Pointer to the associated scroller - Func_draw_list_item Draw_list_item; ///< + Func_draw_list_item Draw_list_item; ///< Function to call for each item to draw its line + byte Color_index; ///< Background color: From 0->MC_Black to 3->MC_White struct T_List_button * Next; ///< Pointer to the next list button of current window. } T_List_button;