| @@ -292,6 +292,7 @@ | |||||||
| #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers? | #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers? | ||||||
| #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. | #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. | ||||||
|  |  | ||||||
|  | //#define SDCARD_SORT_ALPHA // Sort SD file listings in ASCII order. Find additional options in cardreader.h | ||||||
| #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order. | #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order. | ||||||
| // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. | // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. | ||||||
| // using: | // using: | ||||||
|   | |||||||
| @@ -111,10 +111,12 @@ uint8_t const SOFT_SPI_SCK_PIN = 13; | |||||||
| /** | /** | ||||||
|  * Defines for long (vfat) filenames |  * Defines for long (vfat) filenames | ||||||
|  */ |  */ | ||||||
|  | /** Number of UTF-16 characters per entry */ | ||||||
|  | #define FILENAME_LENGTH 13 | ||||||
| /** Number of VFAT entries used. Every entry has 13 UTF-16 characters */ | /** Number of VFAT entries used. Every entry has 13 UTF-16 characters */ | ||||||
| #define MAX_VFAT_ENTRIES (2) | #define MAX_VFAT_ENTRIES (2) | ||||||
| /** Total size of the buffer used to store the long filenames */ | /** Total size of the buffer used to store the long filenames */ | ||||||
| #define LONG_FILENAME_LENGTH (13*MAX_VFAT_ENTRIES+1) | #define LONG_FILENAME_LENGTH (FILENAME_LENGTH*MAX_VFAT_ENTRIES+1) | ||||||
| #endif  // SdFatConfig_h | #endif  // SdFatConfig_h | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,6 +11,9 @@ | |||||||
|  |  | ||||||
| CardReader::CardReader() | CardReader::CardReader() | ||||||
| { | { | ||||||
|  |   #ifdef SDCARD_SORT_ALPHA | ||||||
|  |    sort_count = 0; | ||||||
|  |   #endif | ||||||
|    filesize = 0; |    filesize = 0; | ||||||
|    sdpos = 0; |    sdpos = 0; | ||||||
|    sdprinting = false; |    sdprinting = false; | ||||||
| @@ -36,13 +39,9 @@ CardReader::CardReader() | |||||||
| char *createFilename(char *buffer, const dir_t &p) //buffer>12characters | char *createFilename(char *buffer, const dir_t &p) //buffer>12characters | ||||||
| { | { | ||||||
|   char *pos=buffer; |   char *pos=buffer; | ||||||
|   for (uint8_t i = 0; i < 11; i++)  |   for (uint8_t i = 0; i < 11; i++) { | ||||||
|   { |  | ||||||
|     if (p.name[i] == ' ') continue; |     if (p.name[i] == ' ') continue; | ||||||
|     if (i == 8)  |     if (i == 8) *pos++ = '.'; | ||||||
|     { |  | ||||||
|       *pos++='.'; |  | ||||||
|     } |  | ||||||
|     *pos++ = p.name[i]; |     *pos++ = p.name[i]; | ||||||
|   } |   } | ||||||
|   *pos++ = 0; |   *pos++ = 0; | ||||||
| @@ -60,8 +59,8 @@ void  CardReader::lsDive(const char *prepend,SdFile parent) | |||||||
|     if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint |     if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint | ||||||
|     { |     { | ||||||
|  |  | ||||||
|       char path[13*2]; |       char path[FILENAME_LENGTH*2]; | ||||||
|       char lfilename[13]; |       char lfilename[FILENAME_LENGTH]; | ||||||
|       createFilename(lfilename,p); |       createFilename(lfilename,p); | ||||||
|        |        | ||||||
|       path[0]=0; |       path[0]=0; | ||||||
| @@ -87,8 +86,6 @@ void  CardReader::lsDive(const char *prepend,SdFile parent) | |||||||
|       } |       } | ||||||
|       lsDive(path,dir); |       lsDive(path,dir); | ||||||
|       //close done automatically by destructor of SdFile |       //close done automatically by destructor of SdFile | ||||||
|  |  | ||||||
|        |  | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
| @@ -105,7 +102,6 @@ void  CardReader::lsDive(const char *prepend,SdFile parent) | |||||||
|       if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue; |       if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue; | ||||||
|       filenameIsDir=DIR_IS_SUBDIR(&p); |       filenameIsDir=DIR_IS_SUBDIR(&p); | ||||||
|  |  | ||||||
|        |  | ||||||
|       if(!filenameIsDir) |       if(!filenameIsDir) | ||||||
|       { |       { | ||||||
|         if(p.name[8]!='G') continue; |         if(p.name[8]!='G') continue; | ||||||
| @@ -124,10 +120,8 @@ void  CardReader::lsDive(const char *prepend,SdFile parent) | |||||||
|       }  |       }  | ||||||
|       else if(lsAction==LS_GetFilename) |       else if(lsAction==LS_GetFilename) | ||||||
|       { |       { | ||||||
|         if(cnt==nrFiles) |         if (cnt == nrFiles) return; | ||||||
|           return; |  | ||||||
|         cnt++; |         cnt++; | ||||||
|          |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -136,9 +130,6 @@ void  CardReader::lsDive(const char *prepend,SdFile parent) | |||||||
| void CardReader::ls()  | void CardReader::ls()  | ||||||
| { | { | ||||||
|   lsAction=LS_SerialPrint; |   lsAction=LS_SerialPrint; | ||||||
|   if(lsAction==LS_Count) |  | ||||||
|   nrFiles=0; |  | ||||||
|  |  | ||||||
|   root.rewind(); |   root.rewind(); | ||||||
|   lsDive("",root); |   lsDive("",root); | ||||||
| } | } | ||||||
| @@ -177,6 +168,9 @@ void CardReader::initsd() | |||||||
|   } |   } | ||||||
|   workDir=root; |   workDir=root; | ||||||
|   curDir=&root; |   curDir=&root; | ||||||
|  |   #ifdef SDCARD_SORT_ALPHA | ||||||
|  |     presort(); | ||||||
|  |   #endif | ||||||
|   /* |   /* | ||||||
|   if(!workDir.openRoot(&volume)) |   if(!workDir.openRoot(&volume)) | ||||||
|   { |   { | ||||||
| @@ -193,8 +187,10 @@ void CardReader::setroot() | |||||||
|     SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL); |     SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL); | ||||||
|   }*/ |   }*/ | ||||||
|   workDir=root; |   workDir=root; | ||||||
|    |  | ||||||
|   curDir=&workDir; |   curDir=&workDir; | ||||||
|  |   #ifdef SDCARD_SORT_ALPHA | ||||||
|  |     presort(); | ||||||
|  |   #endif | ||||||
| } | } | ||||||
| void CardReader::release() | void CardReader::release() | ||||||
| { | { | ||||||
| @@ -207,6 +203,7 @@ void CardReader::startFileprint() | |||||||
|   if(cardOK) |   if(cardOK) | ||||||
|   { |   { | ||||||
|     sdprinting = true; |     sdprinting = true; | ||||||
|  |     flush_presort(); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -235,7 +232,7 @@ void CardReader::getAbsFilename(char *t) | |||||||
|     while(*t!=0 && cnt< MAXPATHNAMELENGTH)  |     while(*t!=0 && cnt< MAXPATHNAMELENGTH)  | ||||||
|     {t++;cnt++;}  //crawl counter forward. |     {t++;cnt++;}  //crawl counter forward. | ||||||
|   } |   } | ||||||
|   if(cnt<MAXPATHNAMELENGTH-13) |   if(cnt<MAXPATHNAMELENGTH-FILENAME_LENGTH) | ||||||
|     file.getFilename(t); |     file.getFilename(t); | ||||||
|   else |   else | ||||||
|     t[0]=0; |     t[0]=0; | ||||||
| @@ -305,7 +302,7 @@ void CardReader::openFile(char* name,bool read, bool replace_current/*=true*/) | |||||||
|       //SERIAL_ECHO("end  :");SERIAL_ECHOLN((int)(dirname_end-name)); |       //SERIAL_ECHO("end  :");SERIAL_ECHOLN((int)(dirname_end-name)); | ||||||
|       if(dirname_end>0 && dirname_end>dirname_start) |       if(dirname_end>0 && dirname_end>dirname_start) | ||||||
|       { |       { | ||||||
|         char subdirname[13]; |         char subdirname[FILENAME_LENGTH]; | ||||||
|         strncpy(subdirname, dirname_start, dirname_end-dirname_start); |         strncpy(subdirname, dirname_start, dirname_end-dirname_start); | ||||||
|         subdirname[dirname_end-dirname_start]=0; |         subdirname[dirname_end-dirname_start]=0; | ||||||
|         SERIAL_ECHOLN(subdirname); |         SERIAL_ECHOLN(subdirname); | ||||||
| @@ -401,7 +398,7 @@ void CardReader::removeFile(char* name) | |||||||
|       //SERIAL_ECHO("end  :");SERIAL_ECHOLN((int)(dirname_end-name)); |       //SERIAL_ECHO("end  :");SERIAL_ECHOLN((int)(dirname_end-name)); | ||||||
|       if(dirname_end>0 && dirname_end>dirname_start) |       if(dirname_end>0 && dirname_end>dirname_start) | ||||||
|       { |       { | ||||||
|         char subdirname[13]; |         char subdirname[FILENAME_LENGTH]; | ||||||
|         strncpy(subdirname, dirname_start, dirname_end-dirname_start); |         strncpy(subdirname, dirname_start, dirname_end-dirname_start); | ||||||
|         subdirname[dirname_end-dirname_start]=0; |         subdirname[dirname_end-dirname_start]=0; | ||||||
|         SERIAL_ECHOLN(subdirname); |         SERIAL_ECHOLN(subdirname); | ||||||
| @@ -439,6 +436,9 @@ void CardReader::removeFile(char* name) | |||||||
|       SERIAL_PROTOCOLPGM("File deleted:"); |       SERIAL_PROTOCOLPGM("File deleted:"); | ||||||
|       SERIAL_PROTOCOLLN(fname); |       SERIAL_PROTOCOLLN(fname); | ||||||
|       sdpos = 0; |       sdpos = 0; | ||||||
|  |       #ifdef SDCARD_SORT_ALPHA | ||||||
|  |         presort(); | ||||||
|  |       #endif | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
| @@ -552,14 +552,21 @@ void CardReader::closefile(bool store_location) | |||||||
|    |    | ||||||
| } | } | ||||||
|  |  | ||||||
| void CardReader::getfilename(const uint8_t nr) | void CardReader::getfilename(const uint16_t nr) | ||||||
| { | { | ||||||
|  |   #if defined(SDCARD_SORT_ALPHA) && SORT_USES_RAM && SORT_USES_MORE_RAM | ||||||
|  |     if (nr < sort_count) { | ||||||
|  |       strcpy(filename, sortshort[nr]); | ||||||
|  |       strcpy(longFilename, sortnames[nr]); | ||||||
|  |       filenameIsDir = isDir[nr]; | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |   #endif | ||||||
|   curDir=&workDir; |   curDir=&workDir; | ||||||
|   lsAction=LS_GetFilename; |   lsAction=LS_GetFilename; | ||||||
|   nrFiles=nr; |   nrFiles=nr; | ||||||
|   curDir->rewind(); |   curDir->rewind(); | ||||||
|   lsDive("",*curDir); |   lsDive("",*curDir); | ||||||
|    |  | ||||||
| } | } | ||||||
|  |  | ||||||
| uint16_t CardReader::getnrfilenames() | uint16_t CardReader::getnrfilenames() | ||||||
| @@ -595,6 +602,9 @@ void CardReader::chdir(const char * relpath) | |||||||
|       workDirParents[0]=*parent; |       workDirParents[0]=*parent; | ||||||
|     } |     } | ||||||
|     workDir=newfile; |     workDir=newfile; | ||||||
|  |     #ifdef SDCARD_SORT_ALPHA | ||||||
|  |       presort(); | ||||||
|  |     #endif | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -604,12 +614,152 @@ void CardReader::updir() | |||||||
|   { |   { | ||||||
|     --workDirDepth; |     --workDirDepth; | ||||||
|     workDir = workDirParents[0]; |     workDir = workDirParents[0]; | ||||||
|     int d; |  | ||||||
|     for (int d = 0; d < workDirDepth; d++) |     for (int d = 0; d < workDirDepth; d++) | ||||||
|       workDirParents[d] = workDirParents[d+1]; |       workDirParents[d] = workDirParents[d+1]; | ||||||
|  |     #ifdef SDCARD_SORT_ALPHA | ||||||
|  |       presort(); | ||||||
|  |     #endif | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #ifdef SDCARD_SORT_ALPHA | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Get the name of a file in the current directory by sort-index | ||||||
|  |  */ | ||||||
|  | void CardReader::getfilename_sorted(const uint16_t nr) { | ||||||
|  |   getfilename(nr < sort_count ? sort_order[nr] : nr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Read all the files and produce a sort key | ||||||
|  |  * | ||||||
|  |  * We can do this in 3 ways... | ||||||
|  |  *  - Minimal RAM: Read two filenames at a time sorting along... | ||||||
|  |  *  - Some RAM: Buffer the directory and return filenames from RAM | ||||||
|  |  *  - Some RAM: Buffer the directory just for this sort | ||||||
|  |  */ | ||||||
|  | void CardReader::presort() | ||||||
|  | { | ||||||
|  |   flush_presort(); | ||||||
|  |  | ||||||
|  |   uint16_t fileCnt = getnrfilenames(); | ||||||
|  |   if (fileCnt > 0) { | ||||||
|  |  | ||||||
|  |     if (fileCnt > SORT_LIMIT) fileCnt = SORT_LIMIT; | ||||||
|  |  | ||||||
|  |     #if SORT_USES_RAM | ||||||
|  |       #if SORT_USES_MORE_RAM | ||||||
|  |         sortshort = (char**)calloc(fileCnt, sizeof(char*)); | ||||||
|  |         sortnames = (char**)calloc(fileCnt, sizeof(char*)); | ||||||
|  |       #else | ||||||
|  |         char *sortnames[fileCnt]; | ||||||
|  |       #endif | ||||||
|  |     #else | ||||||
|  |       char name1[LONG_FILENAME_LENGTH+1]; | ||||||
|  |     #endif | ||||||
|  |  | ||||||
|  |     #if FOLDER_SORTING != 0 | ||||||
|  |       #if SORT_USES_RAM && SORT_USES_MORE_RAM | ||||||
|  |         isDir = (uint8_t*)calloc(fileCnt, sizeof(uint8_t)); | ||||||
|  |       #else | ||||||
|  |         uint8_t isDir[fileCnt]; | ||||||
|  |       #endif | ||||||
|  |     #endif | ||||||
|  |  | ||||||
|  |     sort_order = new uint8_t[fileCnt]; | ||||||
|  |  | ||||||
|  |     if (fileCnt > 1) { | ||||||
|  |  | ||||||
|  |       // Init sort order. If using RAM then read all filenames now. | ||||||
|  |       for (uint16_t i=0; i<fileCnt; i++) { | ||||||
|  |         sort_order[i] = i; | ||||||
|  |         #if SORT_USES_RAM | ||||||
|  |           getfilename(i); | ||||||
|  |           sortnames[i] = strdup(longFilename[0] ? longFilename : filename); | ||||||
|  |           #if SORT_USES_MORE_RAM | ||||||
|  |             sortshort[i] = strdup(filename); | ||||||
|  |           #endif | ||||||
|  |           // char out[30]; | ||||||
|  |           // sprintf_P(out, PSTR("---- %i %s %s"), i, filenameIsDir ? "D" : " ", sortnames[i]); | ||||||
|  |           // SERIAL_ECHOLN(out); | ||||||
|  |           #if FOLDER_SORTING != 0 | ||||||
|  |             isDir[i] = filenameIsDir; | ||||||
|  |           #endif | ||||||
|  |         #endif | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       // Bubble Sort | ||||||
|  |       for (uint16_t i=fileCnt; --i;) { | ||||||
|  |         bool cmp, didSwap = false; | ||||||
|  |         for (uint16_t j=0; j<i; ++j) { | ||||||
|  |           uint16_t s1 = j, s2 = j+1, o1 = sort_order[s1], o2 = sort_order[s2]; | ||||||
|  |           #if SORT_USES_RAM | ||||||
|  |             #if FOLDER_SORTING != 0 | ||||||
|  |               cmp = (isDir[o1] == isDir[o2]) ? (strcasecmp(sortnames[o1], sortnames[o2]) > 0) : isDir[FOLDER_SORTING > 0 ? o1 : o2]; | ||||||
|  |             #else | ||||||
|  |               cmp = strcasecmp(sortnames[o1], sortnames[o2]) > 0; | ||||||
|  |             #endif | ||||||
|  |           #else | ||||||
|  |             getfilename(o1); | ||||||
|  |             strcpy(name1, longFilename[0] ? longFilename : filename); | ||||||
|  |             #if FOLDER_SORTING != 0 | ||||||
|  |               bool dir1 = filenameIsDir; | ||||||
|  |             #endif | ||||||
|  |             getfilename(o2); | ||||||
|  |             char *name2 = longFilename[0] ? longFilename : filename; | ||||||
|  |             #if FOLDER_SORTING != 0 | ||||||
|  |               cmp = (dir1 == filenameIsDir) ? (strcasecmp(name1, name2) > 0) : (FOLDER_SORTING > 0 ? dir1 : !dir1); | ||||||
|  |             #else | ||||||
|  |               cmp = strcasecmp(name1, name2) > 0; | ||||||
|  |             #endif | ||||||
|  |           #endif | ||||||
|  |           if (cmp) { | ||||||
|  |             sort_order[s1] = o2; | ||||||
|  |             sort_order[s2] = o1; | ||||||
|  |             didSwap = true; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         if (!didSwap) break; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       #if SORT_USES_RAM && !SORT_USES_MORE_RAM | ||||||
|  |         for (uint16_t i=0; i<fileCnt; ++i) free(sortnames[i]); | ||||||
|  |       #endif | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       sort_order[0] = 0; | ||||||
|  |       #if SORT_USES_RAM && SORT_USES_MORE_RAM | ||||||
|  |         sortnames = (char**)malloc(sizeof(char*)); | ||||||
|  |         sortshort = (char**)malloc(sizeof(char*)); | ||||||
|  |         isDir = (uint8_t*)malloc(sizeof(uint8_t)); | ||||||
|  |         getfilename(0); | ||||||
|  |         sortnames[0] = strdup(longFilename[0] ? longFilename : filename); | ||||||
|  |         sortshort[0] = strdup(filename); | ||||||
|  |         isDir[0] = filenameIsDir; | ||||||
|  |       #endif | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     sort_count = fileCnt; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void CardReader::flush_presort() { | ||||||
|  |   if (sort_count > 0) { | ||||||
|  |     #if SORT_USES_RAM && SORT_USES_MORE_RAM | ||||||
|  |       for (uint8_t i=0; i<sort_count; ++i) { | ||||||
|  |         free(sortshort[i]); | ||||||
|  |         free(sortnames[i]); | ||||||
|  |       } | ||||||
|  |       free(sortshort); | ||||||
|  |       free(sortnames); | ||||||
|  |     #endif | ||||||
|  |     delete sort_order; | ||||||
|  |     sort_count = 0; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif // SDCARD_SORT_ALPHA | ||||||
|  |  | ||||||
| void CardReader::printingHasFinished() | void CardReader::printingHasFinished() | ||||||
| { | { | ||||||
| @@ -633,6 +783,9 @@ void CardReader::printingHasFinished() | |||||||
|           enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND)); |           enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND)); | ||||||
|       } |       } | ||||||
|       autotempShutdown(); |       autotempShutdown(); | ||||||
|  |       #ifdef SDCARD_SORT_ALPHA | ||||||
|  |         presort(); | ||||||
|  |       #endif | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif //SDSUPPORT | #endif //SDSUPPORT | ||||||
|   | |||||||
| @@ -3,7 +3,14 @@ | |||||||
|  |  | ||||||
| #ifdef SDSUPPORT | #ifdef SDSUPPORT | ||||||
|  |  | ||||||
| #define MAX_DIR_DEPTH 10 | #define MAX_DIR_DEPTH 10          // Maximum folder depth | ||||||
|  |  | ||||||
|  | #ifdef SDCARD_SORT_ALPHA | ||||||
|  |   #define SORT_USES_RAM false      // Buffer while sorting, else re-read from SD | ||||||
|  |   #define SORT_USES_MORE_RAM false // Always keep the directory in RAM | ||||||
|  |   #define SORT_LIMIT 256           // Maximum number of sorted items | ||||||
|  |   #define FOLDER_SORTING -1        // -1=above  0=none  1=below | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include "SdFile.h" | #include "SdFile.h" | ||||||
| enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename}; | enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename}; | ||||||
| @@ -28,7 +35,7 @@ public: | |||||||
|   void getStatus(); |   void getStatus(); | ||||||
|   void printingHasFinished(); |   void printingHasFinished(); | ||||||
|  |  | ||||||
|   void getfilename(const uint8_t nr); |   void getfilename(const uint16_t nr); | ||||||
|   uint16_t getnrfilenames(); |   uint16_t getnrfilenames(); | ||||||
|    |    | ||||||
|   void getAbsFilename(char *t); |   void getAbsFilename(char *t); | ||||||
| @@ -39,6 +46,12 @@ public: | |||||||
|   void updir(); |   void updir(); | ||||||
|   void setroot(); |   void setroot(); | ||||||
|  |  | ||||||
|  | #ifdef SDCARD_SORT_ALPHA | ||||||
|  |   void presort(); | ||||||
|  |   void flush_presort(); | ||||||
|  |   void getfilename_sorted(const uint16_t nr); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|   FORCE_INLINE bool isFileOpen() { return file.isOpen(); } |   FORCE_INLINE bool isFileOpen() { return file.isOpen(); } | ||||||
|   FORCE_INLINE bool eof() { return sdpos>=filesize ;}; |   FORCE_INLINE bool eof() { return sdpos>=filesize ;}; | ||||||
| @@ -52,18 +65,27 @@ public: | |||||||
|   bool logging; |   bool logging; | ||||||
|   bool sdprinting; |   bool sdprinting; | ||||||
|   bool cardOK; |   bool cardOK; | ||||||
|   char filename[13]; |   char filename[FILENAME_LENGTH]; | ||||||
|   char longFilename[LONG_FILENAME_LENGTH]; |   char longFilename[LONG_FILENAME_LENGTH]; | ||||||
|   bool filenameIsDir; |   bool filenameIsDir; | ||||||
|   int lastnr; //last number of the autostart; |   int lastnr; //last number of the autostart; | ||||||
| private: | private: | ||||||
|   SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH]; |   SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH]; | ||||||
|   uint16_t workDirDepth; |   uint16_t workDirDepth; | ||||||
|  | #ifdef SDCARD_SORT_ALPHA | ||||||
|  |   uint16_t sort_count; | ||||||
|  |   uint8_t *sort_order; | ||||||
|  |   #if SORT_USES_MORE_RAM | ||||||
|  |     char **sortshort; | ||||||
|  |     char **sortnames; | ||||||
|  |     uint8_t *isDir; | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|   Sd2Card card; |   Sd2Card card; | ||||||
|   SdVolume volume; |   SdVolume volume; | ||||||
|   SdFile file; |   SdFile file; | ||||||
|   #define SD_PROCEDURE_DEPTH 1 |   #define SD_PROCEDURE_DEPTH 1 | ||||||
|   #define MAXPATHNAMELENGTH (13*MAX_DIR_DEPTH+MAX_DIR_DEPTH+1) |   #define MAXPATHNAMELENGTH (FILENAME_LENGTH*MAX_DIR_DEPTH+MAX_DIR_DEPTH+1) | ||||||
|   uint8_t file_subcall_ctr; |   uint8_t file_subcall_ctr; | ||||||
|   uint32_t filespos[SD_PROCEDURE_DEPTH]; |   uint32_t filespos[SD_PROCEDURE_DEPTH]; | ||||||
|   char filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH]; |   char filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH]; | ||||||
| @@ -75,7 +97,7 @@ private: | |||||||
|   bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware. |   bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware. | ||||||
|    |    | ||||||
|   LsAction lsAction; //stored for recursion. |   LsAction lsAction; //stored for recursion. | ||||||
|   int16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory. |   uint16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory. | ||||||
|   char* diveDirName; |   char* diveDirName; | ||||||
|   void lsDive(const char *prepend,SdFile parent); |   void lsDive(const char *prepend,SdFile parent); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -295,6 +295,7 @@ | |||||||
| #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers? | #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers? | ||||||
| #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. | #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. | ||||||
|  |  | ||||||
|  | //#define SDCARD_SORT_ALPHA // Sort SD file listings in ASCII order. Find additional options in cardreader.h | ||||||
| #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order. | #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order. | ||||||
| // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. | // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. | ||||||
| // using: | // using: | ||||||
|   | |||||||
| @@ -287,6 +287,7 @@ | |||||||
| #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers? | #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers? | ||||||
| #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. | #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. | ||||||
|  |  | ||||||
|  | //#define SDCARD_SORT_ALPHA // Sort SD file listings in ASCII order. Find additional options in cardreader.h | ||||||
| #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the filesystem block order.  | #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the filesystem block order.  | ||||||
| // if a file is deleted, it frees a block. hence, the order is not purely cronological. To still have auto0.g accessible, there is again the option to do that. | // if a file is deleted, it frees a block. hence, the order is not purely cronological. To still have auto0.g accessible, there is again the option to do that. | ||||||
| // using: | // using: | ||||||
|   | |||||||
| @@ -291,6 +291,7 @@ | |||||||
| #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers? | #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers? | ||||||
| #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. | #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. | ||||||
|  |  | ||||||
|  | //#define SDCARD_SORT_ALPHA // Sort SD file listings in ASCII order. Find additional options in cardreader.h | ||||||
| #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order. | #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order. | ||||||
| // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. | // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. | ||||||
| // using: | // using: | ||||||
|   | |||||||
| @@ -1004,15 +1004,22 @@ void lcd_sdcard_menu() | |||||||
|     { |     { | ||||||
|         if (_menuItemNr == _lineNr) |         if (_menuItemNr == _lineNr) | ||||||
|         { |         { | ||||||
|             #ifndef SDCARD_RATHERRECENTFIRST |             #if defined(SDCARD_RATHERRECENTFIRST) && !defined(SDCARD_SORT_ALPHA) | ||||||
|               card.getfilename(i); |               int nr = fileCnt-1-i; | ||||||
|             #else |             #else | ||||||
|               card.getfilename(fileCnt-1-i); |               int nr = i; | ||||||
|             #endif |             #endif | ||||||
|             if (card.filenameIsDir) |  | ||||||
|             { |             #ifdef SDCARD_SORT_ALPHA | ||||||
|  |               card.getfilename_sorted(nr); | ||||||
|  |             #else | ||||||
|  |               card.getfilename(nr); | ||||||
|  |             #endif | ||||||
|  |  | ||||||
|  |             if (card.filenameIsDir) { | ||||||
|               MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename); |               MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename); | ||||||
|             }else{ |             } | ||||||
|  |             else { | ||||||
|               MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename); |               MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename); | ||||||
|             } |             } | ||||||
|         }else{ |         }else{ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user