Browse Source

Merge pull request #1154 from thinkyhead/sd_sorting

SD Sort and Buffer
alexborro 10 years ago
parent
commit
4297bcc89f

+ 1
- 0
Marlin/Configuration_adv.h View File

292
 #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers?
292
 #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers?
293
 #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
293
 #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
294
 
294
 
295
+//#define SDCARD_SORT_ALPHA // Sort SD file listings in ASCII order. Find additional options in cardreader.h
295
 #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order.
296
 #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order.
296
 // 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.
297
 // 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.
297
 // using:
298
 // using:

+ 3
- 1
Marlin/SdFatConfig.h View File

111
 /**
111
 /**
112
  * Defines for long (vfat) filenames
112
  * Defines for long (vfat) filenames
113
  */
113
  */
114
+/** Number of UTF-16 characters per entry */
115
+#define FILENAME_LENGTH 13
114
 /** Number of VFAT entries used. Every entry has 13 UTF-16 characters */
116
 /** Number of VFAT entries used. Every entry has 13 UTF-16 characters */
115
 #define MAX_VFAT_ENTRIES (2)
117
 #define MAX_VFAT_ENTRIES (2)
116
 /** Total size of the buffer used to store the long filenames */
118
 /** Total size of the buffer used to store the long filenames */
117
-#define LONG_FILENAME_LENGTH (13*MAX_VFAT_ENTRIES+1)
119
+#define LONG_FILENAME_LENGTH (FILENAME_LENGTH*MAX_VFAT_ENTRIES+1)
118
 #endif  // SdFatConfig_h
120
 #endif  // SdFatConfig_h
119
 
121
 
120
 
122
 

+ 186
- 33
Marlin/cardreader.cpp View File

11
 
11
 
12
 CardReader::CardReader()
12
 CardReader::CardReader()
13
 {
13
 {
14
+  #ifdef SDCARD_SORT_ALPHA
15
+   sort_count = 0;
16
+  #endif
14
    filesize = 0;
17
    filesize = 0;
15
    sdpos = 0;
18
    sdpos = 0;
16
    sdprinting = false;
19
    sdprinting = false;
33
   autostart_atmillis=millis()+5000;
36
   autostart_atmillis=millis()+5000;
34
 }
37
 }
35
 
38
 
36
-char *createFilename(char *buffer,const dir_t &p) //buffer>12characters
39
+char *createFilename(char *buffer, const dir_t &p) //buffer>12characters
37
 {
40
 {
38
   char *pos=buffer;
41
   char *pos=buffer;
39
-  for (uint8_t i = 0; i < 11; i++) 
40
-  {
41
-    if (p.name[i] == ' ')continue;
42
-    if (i == 8) 
43
-    {
44
-      *pos++='.';
45
-    }
46
-    *pos++=p.name[i];
42
+  for (uint8_t i = 0; i < 11; i++) {
43
+    if (p.name[i] == ' ') continue;
44
+    if (i == 8) *pos++ = '.';
45
+    *pos++ = p.name[i];
47
   }
46
   }
48
-  *pos++=0;
47
+  *pos++ = 0;
49
   return buffer;
48
   return buffer;
50
 }
49
 }
51
 
50
 
53
 void  CardReader::lsDive(const char *prepend,SdFile parent)
52
 void  CardReader::lsDive(const char *prepend,SdFile parent)
54
 {
53
 {
55
   dir_t p;
54
   dir_t p;
56
- uint8_t cnt=0;
55
+  uint8_t cnt=0;
57
  
56
  
58
   while (parent.readDir(p, longFilename) > 0)
57
   while (parent.readDir(p, longFilename) > 0)
59
   {
58
   {
60
     if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint
59
     if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint
61
     {
60
     {
62
 
61
 
63
-      char path[13*2];
64
-      char lfilename[13];
62
+      char path[FILENAME_LENGTH*2];
63
+      char lfilename[FILENAME_LENGTH];
65
       createFilename(lfilename,p);
64
       createFilename(lfilename,p);
66
       
65
       
67
       path[0]=0;
66
       path[0]=0;
87
       }
86
       }
88
       lsDive(path,dir);
87
       lsDive(path,dir);
89
       //close done automatically by destructor of SdFile
88
       //close done automatically by destructor of SdFile
90
-
91
-      
92
     }
89
     }
93
     else
90
     else
94
     {
91
     {
101
         if ( p.name[1] != '.')
98
         if ( p.name[1] != '.')
102
         continue;
99
         continue;
103
       }
100
       }
104
-      
101
+
105
       if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
102
       if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
106
       filenameIsDir=DIR_IS_SUBDIR(&p);
103
       filenameIsDir=DIR_IS_SUBDIR(&p);
107
-      
108
-      
104
+
109
       if(!filenameIsDir)
105
       if(!filenameIsDir)
110
       {
106
       {
111
         if(p.name[8]!='G') continue;
107
         if(p.name[8]!='G') continue;
124
       } 
120
       } 
125
       else if(lsAction==LS_GetFilename)
121
       else if(lsAction==LS_GetFilename)
126
       {
122
       {
127
-        if(cnt==nrFiles)
128
-          return;
123
+        if (cnt == nrFiles) return;
129
         cnt++;
124
         cnt++;
130
-        
131
       }
125
       }
132
     }
126
     }
133
   }
127
   }
136
 void CardReader::ls() 
130
 void CardReader::ls() 
137
 {
131
 {
138
   lsAction=LS_SerialPrint;
132
   lsAction=LS_SerialPrint;
139
-  if(lsAction==LS_Count)
140
-  nrFiles=0;
141
-
142
   root.rewind();
133
   root.rewind();
143
   lsDive("",root);
134
   lsDive("",root);
144
 }
135
 }
177
   }
168
   }
178
   workDir=root;
169
   workDir=root;
179
   curDir=&root;
170
   curDir=&root;
171
+  #ifdef SDCARD_SORT_ALPHA
172
+    presort();
173
+  #endif
180
   /*
174
   /*
181
   if(!workDir.openRoot(&volume))
175
   if(!workDir.openRoot(&volume))
182
   {
176
   {
193
     SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL);
187
     SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL);
194
   }*/
188
   }*/
195
   workDir=root;
189
   workDir=root;
196
-  
197
   curDir=&workDir;
190
   curDir=&workDir;
191
+  #ifdef SDCARD_SORT_ALPHA
192
+    presort();
193
+  #endif
198
 }
194
 }
199
 void CardReader::release()
195
 void CardReader::release()
200
 {
196
 {
207
   if(cardOK)
203
   if(cardOK)
208
   {
204
   {
209
     sdprinting = true;
205
     sdprinting = true;
206
+    flush_presort();
210
   }
207
   }
211
 }
208
 }
212
 
209
 
235
     while(*t!=0 && cnt< MAXPATHNAMELENGTH) 
232
     while(*t!=0 && cnt< MAXPATHNAMELENGTH) 
236
     {t++;cnt++;}  //crawl counter forward.
233
     {t++;cnt++;}  //crawl counter forward.
237
   }
234
   }
238
-  if(cnt<MAXPATHNAMELENGTH-13)
235
+  if(cnt<MAXPATHNAMELENGTH-FILENAME_LENGTH)
239
     file.getFilename(t);
236
     file.getFilename(t);
240
   else
237
   else
241
     t[0]=0;
238
     t[0]=0;
305
       //SERIAL_ECHO("end  :");SERIAL_ECHOLN((int)(dirname_end-name));
302
       //SERIAL_ECHO("end  :");SERIAL_ECHOLN((int)(dirname_end-name));
306
       if(dirname_end>0 && dirname_end>dirname_start)
303
       if(dirname_end>0 && dirname_end>dirname_start)
307
       {
304
       {
308
-        char subdirname[13];
305
+        char subdirname[FILENAME_LENGTH];
309
         strncpy(subdirname, dirname_start, dirname_end-dirname_start);
306
         strncpy(subdirname, dirname_start, dirname_end-dirname_start);
310
         subdirname[dirname_end-dirname_start]=0;
307
         subdirname[dirname_end-dirname_start]=0;
311
         SERIAL_ECHOLN(subdirname);
308
         SERIAL_ECHOLN(subdirname);
401
       //SERIAL_ECHO("end  :");SERIAL_ECHOLN((int)(dirname_end-name));
398
       //SERIAL_ECHO("end  :");SERIAL_ECHOLN((int)(dirname_end-name));
402
       if(dirname_end>0 && dirname_end>dirname_start)
399
       if(dirname_end>0 && dirname_end>dirname_start)
403
       {
400
       {
404
-        char subdirname[13];
401
+        char subdirname[FILENAME_LENGTH];
405
         strncpy(subdirname, dirname_start, dirname_end-dirname_start);
402
         strncpy(subdirname, dirname_start, dirname_end-dirname_start);
406
         subdirname[dirname_end-dirname_start]=0;
403
         subdirname[dirname_end-dirname_start]=0;
407
         SERIAL_ECHOLN(subdirname);
404
         SERIAL_ECHOLN(subdirname);
439
       SERIAL_PROTOCOLPGM("File deleted:");
436
       SERIAL_PROTOCOLPGM("File deleted:");
440
       SERIAL_PROTOCOLLN(fname);
437
       SERIAL_PROTOCOLLN(fname);
441
       sdpos = 0;
438
       sdpos = 0;
439
+      #ifdef SDCARD_SORT_ALPHA
440
+        presort();
441
+      #endif
442
     }
442
     }
443
     else
443
     else
444
     {
444
     {
552
   
552
   
553
 }
553
 }
554
 
554
 
555
-void CardReader::getfilename(const uint8_t nr)
555
+void CardReader::getfilename(const uint16_t nr)
556
 {
556
 {
557
+  #if defined(SDCARD_SORT_ALPHA) && SORT_USES_RAM && SORT_USES_MORE_RAM
558
+    if (nr < sort_count) {
559
+      strcpy(filename, sortshort[nr]);
560
+      strcpy(longFilename, sortnames[nr]);
561
+      filenameIsDir = isDir[nr];
562
+      return;
563
+    }
564
+  #endif
557
   curDir=&workDir;
565
   curDir=&workDir;
558
   lsAction=LS_GetFilename;
566
   lsAction=LS_GetFilename;
559
   nrFiles=nr;
567
   nrFiles=nr;
560
   curDir->rewind();
568
   curDir->rewind();
561
   lsDive("",*curDir);
569
   lsDive("",*curDir);
562
-  
563
 }
570
 }
564
 
571
 
565
 uint16_t CardReader::getnrfilenames()
572
 uint16_t CardReader::getnrfilenames()
577
 {
584
 {
578
   SdFile newfile;
585
   SdFile newfile;
579
   SdFile *parent=&root;
586
   SdFile *parent=&root;
580
-  
587
+
581
   if(workDir.isOpen())
588
   if(workDir.isOpen())
582
     parent=&workDir;
589
     parent=&workDir;
583
   
590
   
595
       workDirParents[0]=*parent;
602
       workDirParents[0]=*parent;
596
     }
603
     }
597
     workDir=newfile;
604
     workDir=newfile;
605
+    #ifdef SDCARD_SORT_ALPHA
606
+      presort();
607
+    #endif
598
   }
608
   }
599
 }
609
 }
600
 
610
 
601
 void CardReader::updir()
611
 void CardReader::updir()
602
 {
612
 {
603
-  if(workDirDepth > 0)
613
+  if (workDirDepth > 0)
604
   {
614
   {
605
     --workDirDepth;
615
     --workDirDepth;
606
     workDir = workDirParents[0];
616
     workDir = workDirParents[0];
607
-    int d;
608
     for (int d = 0; d < workDirDepth; d++)
617
     for (int d = 0; d < workDirDepth; d++)
609
       workDirParents[d] = workDirParents[d+1];
618
       workDirParents[d] = workDirParents[d+1];
619
+    #ifdef SDCARD_SORT_ALPHA
620
+      presort();
621
+    #endif
622
+  }
623
+}
624
+
625
+#ifdef SDCARD_SORT_ALPHA
626
+
627
+/**
628
+ * Get the name of a file in the current directory by sort-index
629
+ */
630
+void CardReader::getfilename_sorted(const uint16_t nr) {
631
+  getfilename(nr < sort_count ? sort_order[nr] : nr);
632
+}
633
+
634
+/**
635
+ * Read all the files and produce a sort key
636
+ *
637
+ * We can do this in 3 ways...
638
+ *  - Minimal RAM: Read two filenames at a time sorting along...
639
+ *  - Some RAM: Buffer the directory and return filenames from RAM
640
+ *  - Some RAM: Buffer the directory just for this sort
641
+ */
642
+void CardReader::presort()
643
+{
644
+  flush_presort();
645
+
646
+  uint16_t fileCnt = getnrfilenames();
647
+  if (fileCnt > 0) {
648
+
649
+    if (fileCnt > SORT_LIMIT) fileCnt = SORT_LIMIT;
650
+
651
+    #if SORT_USES_RAM
652
+      #if SORT_USES_MORE_RAM
653
+        sortshort = (char**)calloc(fileCnt, sizeof(char*));
654
+        sortnames = (char**)calloc(fileCnt, sizeof(char*));
655
+      #else
656
+        char *sortnames[fileCnt];
657
+      #endif
658
+    #else
659
+      char name1[LONG_FILENAME_LENGTH+1];
660
+    #endif
661
+
662
+    #if FOLDER_SORTING != 0
663
+      #if SORT_USES_RAM && SORT_USES_MORE_RAM
664
+        isDir = (uint8_t*)calloc(fileCnt, sizeof(uint8_t));
665
+      #else
666
+        uint8_t isDir[fileCnt];
667
+      #endif
668
+    #endif
669
+
670
+    sort_order = new uint8_t[fileCnt];
671
+
672
+    if (fileCnt > 1) {
673
+
674
+      // Init sort order. If using RAM then read all filenames now.
675
+      for (uint16_t i=0; i<fileCnt; i++) {
676
+        sort_order[i] = i;
677
+        #if SORT_USES_RAM
678
+          getfilename(i);
679
+          sortnames[i] = strdup(longFilename[0] ? longFilename : filename);
680
+          #if SORT_USES_MORE_RAM
681
+            sortshort[i] = strdup(filename);
682
+          #endif
683
+          // char out[30];
684
+          // sprintf_P(out, PSTR("---- %i %s %s"), i, filenameIsDir ? "D" : " ", sortnames[i]);
685
+          // SERIAL_ECHOLN(out);
686
+          #if FOLDER_SORTING != 0
687
+            isDir[i] = filenameIsDir;
688
+          #endif
689
+        #endif
690
+      }
691
+
692
+      // Bubble Sort
693
+      for (uint16_t i=fileCnt; --i;) {
694
+        bool cmp, didSwap = false;
695
+        for (uint16_t j=0; j<i; ++j) {
696
+          uint16_t s1 = j, s2 = j+1, o1 = sort_order[s1], o2 = sort_order[s2];
697
+          #if SORT_USES_RAM
698
+            #if FOLDER_SORTING != 0
699
+              cmp = (isDir[o1] == isDir[o2]) ? (strcasecmp(sortnames[o1], sortnames[o2]) > 0) : isDir[FOLDER_SORTING > 0 ? o1 : o2];
700
+            #else
701
+              cmp = strcasecmp(sortnames[o1], sortnames[o2]) > 0;
702
+            #endif
703
+          #else
704
+            getfilename(o1);
705
+            strcpy(name1, longFilename[0] ? longFilename : filename);
706
+            #if FOLDER_SORTING != 0
707
+              bool dir1 = filenameIsDir;
708
+            #endif
709
+            getfilename(o2);
710
+            char *name2 = longFilename[0] ? longFilename : filename;
711
+            #if FOLDER_SORTING != 0
712
+              cmp = (dir1 == filenameIsDir) ? (strcasecmp(name1, name2) > 0) : (FOLDER_SORTING > 0 ? dir1 : !dir1);
713
+            #else
714
+              cmp = strcasecmp(name1, name2) > 0;
715
+            #endif
716
+          #endif
717
+          if (cmp) {
718
+            sort_order[s1] = o2;
719
+            sort_order[s2] = o1;
720
+            didSwap = true;
721
+          }
722
+        }
723
+        if (!didSwap) break;
724
+      }
725
+
726
+      #if SORT_USES_RAM && !SORT_USES_MORE_RAM
727
+        for (uint16_t i=0; i<fileCnt; ++i) free(sortnames[i]);
728
+      #endif
729
+    }
730
+    else {
731
+      sort_order[0] = 0;
732
+      #if SORT_USES_RAM && SORT_USES_MORE_RAM
733
+        sortnames = (char**)malloc(sizeof(char*));
734
+        sortshort = (char**)malloc(sizeof(char*));
735
+        isDir = (uint8_t*)malloc(sizeof(uint8_t));
736
+        getfilename(0);
737
+        sortnames[0] = strdup(longFilename[0] ? longFilename : filename);
738
+        sortshort[0] = strdup(filename);
739
+        isDir[0] = filenameIsDir;
740
+      #endif
741
+    }
742
+
743
+    sort_count = fileCnt;
744
+  }
745
+}
746
+
747
+void CardReader::flush_presort() {
748
+  if (sort_count > 0) {
749
+    #if SORT_USES_RAM && SORT_USES_MORE_RAM
750
+      for (uint8_t i=0; i<sort_count; ++i) {
751
+        free(sortshort[i]);
752
+        free(sortnames[i]);
753
+      }
754
+      free(sortshort);
755
+      free(sortnames);
756
+    #endif
757
+    delete sort_order;
758
+    sort_count = 0;
610
   }
759
   }
611
 }
760
 }
612
 
761
 
762
+#endif // SDCARD_SORT_ALPHA
613
 
763
 
614
 void CardReader::printingHasFinished()
764
 void CardReader::printingHasFinished()
615
 {
765
 {
633
           enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND));
783
           enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND));
634
       }
784
       }
635
       autotempShutdown();
785
       autotempShutdown();
786
+      #ifdef SDCARD_SORT_ALPHA
787
+        presort();
788
+      #endif
636
     }
789
     }
637
 }
790
 }
638
 #endif //SDSUPPORT
791
 #endif //SDSUPPORT

+ 29
- 7
Marlin/cardreader.h View File

3
 
3
 
4
 #ifdef SDSUPPORT
4
 #ifdef SDSUPPORT
5
 
5
 
6
-#define MAX_DIR_DEPTH 10
6
+#define MAX_DIR_DEPTH 10          // Maximum folder depth
7
+
8
+#ifdef SDCARD_SORT_ALPHA
9
+  #define SORT_USES_RAM false      // Buffer while sorting, else re-read from SD
10
+  #define SORT_USES_MORE_RAM false // Always keep the directory in RAM
11
+  #define SORT_LIMIT 256           // Maximum number of sorted items
12
+  #define FOLDER_SORTING -1        // -1=above  0=none  1=below
13
+#endif
7
 
14
 
8
 #include "SdFile.h"
15
 #include "SdFile.h"
9
 enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename};
16
 enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename};
28
   void getStatus();
35
   void getStatus();
29
   void printingHasFinished();
36
   void printingHasFinished();
30
 
37
 
31
-  void getfilename(const uint8_t nr);
38
+  void getfilename(const uint16_t nr);
32
   uint16_t getnrfilenames();
39
   uint16_t getnrfilenames();
33
   
40
   
34
   void getAbsFilename(char *t);
41
   void getAbsFilename(char *t);
39
   void updir();
46
   void updir();
40
   void setroot();
47
   void setroot();
41
 
48
 
49
+#ifdef SDCARD_SORT_ALPHA
50
+  void presort();
51
+  void flush_presort();
52
+  void getfilename_sorted(const uint16_t nr);
53
+#endif
54
+
42
 
55
 
43
   FORCE_INLINE bool isFileOpen() { return file.isOpen(); }
56
   FORCE_INLINE bool isFileOpen() { return file.isOpen(); }
44
   FORCE_INLINE bool eof() { return sdpos>=filesize ;};
57
   FORCE_INLINE bool eof() { return sdpos>=filesize ;};
50
 public:
63
 public:
51
   bool saving;
64
   bool saving;
52
   bool logging;
65
   bool logging;
53
-  bool sdprinting ;  
54
-  bool cardOK ;
55
-  char filename[13];
66
+  bool sdprinting;
67
+  bool cardOK;
68
+  char filename[FILENAME_LENGTH];
56
   char longFilename[LONG_FILENAME_LENGTH];
69
   char longFilename[LONG_FILENAME_LENGTH];
57
   bool filenameIsDir;
70
   bool filenameIsDir;
58
   int lastnr; //last number of the autostart;
71
   int lastnr; //last number of the autostart;
59
 private:
72
 private:
60
   SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH];
73
   SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH];
61
   uint16_t workDirDepth;
74
   uint16_t workDirDepth;
75
+#ifdef SDCARD_SORT_ALPHA
76
+  uint16_t sort_count;
77
+  uint8_t *sort_order;
78
+  #if SORT_USES_MORE_RAM
79
+    char **sortshort;
80
+    char **sortnames;
81
+    uint8_t *isDir;
82
+  #endif
83
+#endif
62
   Sd2Card card;
84
   Sd2Card card;
63
   SdVolume volume;
85
   SdVolume volume;
64
   SdFile file;
86
   SdFile file;
65
   #define SD_PROCEDURE_DEPTH 1
87
   #define SD_PROCEDURE_DEPTH 1
66
-  #define MAXPATHNAMELENGTH (13*MAX_DIR_DEPTH+MAX_DIR_DEPTH+1)
88
+  #define MAXPATHNAMELENGTH (FILENAME_LENGTH*MAX_DIR_DEPTH+MAX_DIR_DEPTH+1)
67
   uint8_t file_subcall_ctr;
89
   uint8_t file_subcall_ctr;
68
   uint32_t filespos[SD_PROCEDURE_DEPTH];
90
   uint32_t filespos[SD_PROCEDURE_DEPTH];
69
   char filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH];
91
   char filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH];
75
   bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware.
97
   bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware.
76
   
98
   
77
   LsAction lsAction; //stored for recursion.
99
   LsAction lsAction; //stored for recursion.
78
-  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.
100
+  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.
79
   char* diveDirName;
101
   char* diveDirName;
80
   void lsDive(const char *prepend,SdFile parent);
102
   void lsDive(const char *prepend,SdFile parent);
81
 };
103
 };

+ 1
- 0
Marlin/example_configurations/SCARA/Configuration_adv.h View File

295
 #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers?
295
 #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers?
296
 #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
296
 #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
297
 
297
 
298
+//#define SDCARD_SORT_ALPHA // Sort SD file listings in ASCII order. Find additional options in cardreader.h
298
 #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order.
299
 #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order.
299
 // 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.
300
 // 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.
300
 // using:
301
 // using:

+ 1
- 0
Marlin/example_configurations/delta/Configuration_adv.h View File

287
 #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers?
287
 #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers?
288
 #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
288
 #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
289
 
289
 
290
+//#define SDCARD_SORT_ALPHA // Sort SD file listings in ASCII order. Find additional options in cardreader.h
290
 #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the filesystem block order. 
291
 #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the filesystem block order. 
291
 // 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.
292
 // 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.
292
 // using:
293
 // using:

+ 1
- 0
Marlin/example_configurations/makibox/Configuration_adv.h View File

291
 #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers?
291
 #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers?
292
 #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
292
 #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
293
 
293
 
294
+//#define SDCARD_SORT_ALPHA // Sort SD file listings in ASCII order. Find additional options in cardreader.h
294
 #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order.
295
 #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order.
295
 // 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.
296
 // 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.
296
 // using:
297
 // using:

+ 18
- 11
Marlin/ultralcd.cpp View File

993
     card.getWorkDirName();
993
     card.getWorkDirName();
994
     if(card.filename[0]=='/')
994
     if(card.filename[0]=='/')
995
     {
995
     {
996
-#if SDCARDDETECT == -1
996
+      #if SDCARDDETECT == -1
997
         MENU_ITEM(function, LCD_STR_REFRESH MSG_REFRESH, lcd_sd_refresh);
997
         MENU_ITEM(function, LCD_STR_REFRESH MSG_REFRESH, lcd_sd_refresh);
998
-#endif
998
+      #endif
999
     }else{
999
     }else{
1000
         MENU_ITEM(function, LCD_STR_FOLDER "..", lcd_sd_updir);
1000
         MENU_ITEM(function, LCD_STR_FOLDER "..", lcd_sd_updir);
1001
     }
1001
     }
1004
     {
1004
     {
1005
         if (_menuItemNr == _lineNr)
1005
         if (_menuItemNr == _lineNr)
1006
         {
1006
         {
1007
-            #ifndef SDCARD_RATHERRECENTFIRST
1008
-              card.getfilename(i);
1007
+            #if defined(SDCARD_RATHERRECENTFIRST) && !defined(SDCARD_SORT_ALPHA)
1008
+              int nr = fileCnt-1-i;
1009
             #else
1009
             #else
1010
-              card.getfilename(fileCnt-1-i);
1010
+              int nr = i;
1011
             #endif
1011
             #endif
1012
-            if (card.filenameIsDir)
1013
-            {
1014
-                MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename);
1015
-            }else{
1016
-                MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename);
1012
+
1013
+            #ifdef SDCARD_SORT_ALPHA
1014
+              card.getfilename_sorted(nr);
1015
+            #else
1016
+              card.getfilename(nr);
1017
+            #endif
1018
+
1019
+            if (card.filenameIsDir) {
1020
+              MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename);
1021
+            }
1022
+            else {
1023
+              MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename);
1017
             }
1024
             }
1018
         }else{
1025
         }else{
1019
             MENU_ITEM_DUMMY();
1026
             MENU_ITEM_DUMMY();
1219
   #endif // SR_LCD_2W_NL
1226
   #endif // SR_LCD_2W_NL
1220
 #endif//!NEWPANEL
1227
 #endif//!NEWPANEL
1221
 
1228
 
1222
-#if defined (SDSUPPORT) && defined(SDCARDDETECT) && (SDCARDDETECT > 0)
1229
+#if defined(SDSUPPORT) && defined(SDCARDDETECT) && (SDCARDDETECT > 0)
1223
     pinMode(SDCARDDETECT,INPUT);
1230
     pinMode(SDCARDDETECT,INPUT);
1224
     WRITE(SDCARDDETECT, HIGH);
1231
     WRITE(SDCARDDETECT, HIGH);
1225
     lcd_oldcardstatus = IS_SD_INSERTED;
1232
     lcd_oldcardstatus = IS_SD_INSERTED;

Loading…
Cancel
Save