// C Source File // Created 15/02/2004; 16:37:40 #include "mkhibliba.h" /** * Explore a folder * This function is recursive : add every files and folder to the handles, and the explore the * folders found * * @param h_folder : the handle of the table of the folders * @param namefold : the name of the folder explored * @param h the handle wich will contain every HSym (updated by this function) * @param h_level the handle wich will contain every h_MenuLevel (updated by this function) * @param nb the number of found entries (updated by this function) * @param current_level : the current level of the exploration * @param fct_filter : the function which filters the files to include or not * * @return FALSE in case of memory error, else TRUE */ BOOL exploreVAT(HANDLE h_folder, const unsigned char * namefold, HANDLE * h, HANDLE * h_level, short * nb, short current_level, h_FilterVAT fct_filter) { short size = 3; short size_level = 3; short nb_level; short nb_item; HSym * tabhsym; HSym hsym; h_MenuLevel * tablevel; //variable for the research SYM_ENTRY * SymPtr; unsigned char namesubfolder[10]; short i,j; *nb = 0; *h = HeapAlloc(size*sizeof(HSym)); if (*h == H_NULL) { return FALSE; } nb_level = 0; *h_level = HeapAlloc(size_level * sizeof(h_MenuLevel)); if (*h_level == H_NULL) { HeapFree(*h); return FALSE; } //search every file in this folder i = hl_addHANDLE(h, nb, &size, sizeof(HSym)); j = hl_addHANDLE(h_level, &nb_level, &size_level, sizeof(h_MenuLevel)); if (i==NOK || j==NOK) { error: HeapFree(*h); HeapFree(*h_level); return FALSE; } SymPtr=SymFindFirst(SYMSTR(namefold), FO_SINGLE_FOLDER | FO_SKIP_TEMPS); while (SymPtr != NULL) { hsym=MakeHSym(h_folder, SymPtr); if (fct_filter==NULL || fct_filter(hsym)) { ((h_MenuLevel *)HeapDeref(*h_level))[i] = (h_MenuLevel) { .hide = 0, .draw = 1, .level = current_level }; ((HSym *)HeapDeref(*h))[i] = hsym; i = hl_addHANDLE(h, nb, &size, sizeof(HSym)); j = hl_addHANDLE(h_level, &nb_level, &size_level, sizeof(h_MenuLevel)); if (i==NOK || j==NOK) { goto error; } } SymPtr = SymFindNext(); } nb_item = --(*nb); //search in every sub-folder for (j = 0; j < nb_item; j++) { HANDLE h_subfolder; HANDLE h_subfolder_level; short nb_subfolder; SymPtr = DerefSym(((HSym *)HeapDeref(*h))[*nb - (nb_item - j)]); if (SymPtr->flags.bits.folder) { //it's a folder SymCpy0(namesubfolder, SymPtr->name); //get every files in the folder if (!exploreVAT(SymPtr->handle, namesubfolder, &h_subfolder, &h_subfolder_level, &nb_subfolder, current_level + 1, fct_filter)) goto error; //we have to add every entries of the subfolder's handle to the actual handle //first resize : if (!h_resizeHANDLE(h, *nb + nb_subfolder, &size, nb, sizeof(HSym))) { error2: HeapFree(h_subfolder); HeapFree(h_subfolder_level); goto error; } if (!h_resizeHANDLE(h_level, *nb + nb_subfolder, &size_level, &nb_level, sizeof(h_MenuLevel))) { goto error2; } //then move : the entries must be ordered tabhsym = HeapDeref(*h); tablevel = HeapDeref(*h_level); for (i = *nb - 1; i > *nb - (nb_item - j); i--) { //move the following entries tabhsym[i + nb_subfolder] = tabhsym[i]; tablevel[i + nb_subfolder] = tablevel[i]; } //finaly, copy memcpy(&(tabhsym[*nb - (nb_item - j - 1)]), HeapDeref(h_subfolder), sizeof(HSym) * nb_subfolder); memcpy(&(tablevel[*nb - (nb_item - j - 1)]), HeapDeref(h_subfolder_level), sizeof(h_MenuLevel) * nb_subfolder); (*nb) += nb_subfolder; //and free the subfolder handles HeapFree(h_subfolder); HeapFree(h_subfolder_level); } }// next entry return TRUE; } /** * Create a h_Menu which will describe the VAT files and folders * This function will explore the VAT, make a list of every files that match * the specified filter, and then prepare a menu with the list of files. The * list of files are stored in allocated HANDLES (h and h_level parameters). * So after using the menu, the HANDLE have to be free * * @param hmenu the menu to fill in * @param font the font to use for the menu * @param pos_x the x position of the menu * @param pos_y the y position of the menu * @param width the width of the frame of the menu * @param nb_draw the number maximum of drawn entries in the menu * @param h the handle wich will contain every HSym (updated by this function) * @param h_level the handle wich will contain every h_MenuLevel (updated by this function) * @param fct_filter the function to filter the files to include or not * @param fct_draw the function to draw the entries of the menu * * @return FALSE in case of memeory error, else TRUE */ BOOL h_initMenuVAT(h_Menu * hmenu, h_Font * font, short pos_x, short pos_y, short width, short nb_draw, HANDLE * h, HANDLE * h_level, h_FilterVAT fct_filter, h_FctDrawMenu fct_draw) { short nb = 0; BOOL ok; FolderOp(NULL,FOP_ALL_FOLDERS | FOP_LOCK); //lock every folder table ok = exploreVAT(SymFindHome(SYMSTR("main")).folder, "\x7F", h, h_level, &nb, 0, fct_filter); FolderOp(NULL,FOP_ALL_FOLDERS | FOP_UNLOCK); //unlock every folder table if (!ok) { return FALSE; } *hmenu = (h_Menu) { .nb = nb, .size_item = 0, .tab = HLock(*h), .level_tab = HLock(*h_level), .font = font, .pos_x = pos_x, .pos_y = pos_y, .width = width, .nb_draw = nb_draw, .fct_draw = fct_draw, .draw_scrollbar = TRUE }; return TRUE; } /** * A filter function for the creation of a VAT Menu. This function will filter * every file which can be open by HibLib. * * @see h_FilterVAT */ BOOL h_hibfilterVAT(HSym hsym) { SYM_ENTRY * SymPtr = DerefSym(hsym); if (SymPtr->flags.bits.folder) { return TRUE; } switch (h_getFileType(HeapDeref(SymPtr->handle))) { case CUSTOM_TAG + HTXT_TAG: case TEXT_TAG: case PIC_TAG: case STR_TAG: return TRUE; } return FALSE; }