2 import "FileSystemCache"
5 static char * rootName = "Entire Computer";
6 static const char * msNetwork = "Microsoft Windows Network";
8 static const char * rootName = "File System";
12 define guiApp = (GuiApplication)((__thisModule).application);
13 define selectionColor = guiApp.currentSkin.selectionColor; //Color { 10, 36, 106 };
15 void MessageBoxTodo(const char * message)
17 PrintLn("MessageBoxTodo(char * message) -- ", message);
18 MessageBox { type = ok, text = "MessageBoxTodo(char * message)", contents = message }.Modal();
21 static const char * fileIconNames[] =
23 "<:ecere>mimeTypes/file.png", /* none */
25 "<:ecere>mimeTypes/file.png", /* normalFile */
26 "<:ecere>mimeTypes/textEcereWorkspace.png", /* ewsFile */
27 "<:ecere>mimeTypes/textEcereProject.png", /* epjFile */
28 "<:ecere>mimeTypes/textEcereSource.png", /* ecFile */
29 "<:ecere>mimeTypes/textEcereHeader.png", /* ehFile */
30 "<:ecere>mimeTypes/textCSource.png", /* cFile */
31 "<:ecere>mimeTypes/textCHeader.png", /* hFile */
32 "<:ecere>mimeTypes/textC++Source.png", /* cppFile */
33 "<:ecere>mimeTypes/textC++Header.png", /* hppFile */
34 "<:ecere>mimeTypes/text.png", /* textFile */
35 "<:ecere>mimeTypes/textHyperTextMarkup.png", /* webFile */
36 "<:ecere>mimeTypes/image.png", /* pictureFile */
37 "<:ecere>status/audioVolumeHigh.png", /* soundFile */
38 "<:ecere>mimeTypes/package.png", /* archiveFile */
39 "<:ecere>mimeTypes/packageSoftware.png", /* packageFile */
40 "<:ecere>mimeTypes/packageOpticalDisc.png", /* opticalMediaImageFile */
42 "<:ecere>places/folder.png", /* folder */
43 "<:ecere>status/folderOpen.png", /* folderOpen */
44 "<:ecere>devices/computer.png", /* computer */
45 "<:ecere>devices/driveHardDisk.png", /* drive */
46 "<:ecere>places/driveRemote.png", /* netDrive */
47 "<:ecere>devices/mediaOptical.png", /* cdrom */
48 "<:ecere>devices/driveRemovableMedia.png", /* removable */
49 "<:ecere>devices/mediaFloppy.png", /* floppy */
50 "<:ecere>places/networkWorkgroup.png", /* network */
51 "<:ecere>places/networkServer.png", /* server */
52 "<:ecere>places/folderRemote.png", /* share */
54 "<:ecere>mimeTypes/package.png", /* treeLoader */
55 "<:ecere>places/startHere.png", /* lineNumbers */
60 define countOfCompIconNames = 6;
61 static const char * compIconNames[] =
70 "<:ede>devices/media-optical.png",
71 "<:ede>devices/media-flash.png",
72 "<:ede>places/network-server.png",
73 "<:ede>places/folder-saved-search.png",
74 "<:ede>places/user-home.png",
75 "<:ede>emblem-not.png",
83 normalFile, ewsFile, epjFile, ecFile, ehFile, cFile, hFile, cppFile, hppFile,
84 textFile, webFile, pictureFile, soundFile,
85 archiveFile, packageFile, opticalMediaImageFile, /* these (all previous) are sort equal */
87 folder, folderOpen, computer,
88 drive, netDrive, cdrom, removable, floppy, network, server, share, // these are sort equal
98 this = SelectByExtension(value);
102 public property bool isFolder
104 get { return this >= folder && this <= share; }
107 public property bool isFile
109 get { return this >= normalFile && this <= opticalMediaImageFile; }
112 _FileType ::SelectByExtension(char * extension)
114 if(!strcmpi(extension, "ews"))
116 else if(!strcmpi(extension, "epj"))
118 else if(!strcmpi(extension, "ec"))
120 else if(!strcmpi(extension, "eh"))
122 else if(!strcmpi(extension, "cpp") ||
123 !strcmpi(extension, "cc") || !strcmpi(extension, "cxx"))
125 else if(!strcmpi(extension, "hpp") ||
126 !strcmpi(extension, "hh") || !strcmpi(extension, "hxx"))
128 else if(!strcmpi(extension, "c"))
130 else if(!strcmpi(extension, "h"))
132 else if(!strcmpi(extension, "txt") || !strcmpi(extension, "text") ||
133 !strcmpi(extension, "nfo") || !strcmpi(extension, "info"))
135 else if(!strcmpi(extension, "htm") || !strcmpi(extension, "html") ||
136 !strcmpi(extension, "css") || !strcmpi(extension, "php") ||
137 !strcmpi(extension, "js"))
139 else if(!strcmpi(extension, "bmp") || !strcmpi(extension, "pcx") ||
140 !strcmpi(extension, "jpg") || !strcmpi(extension, "jpeg") ||
141 !strcmpi(extension, "gif") || !strcmpi(extension, "png") ||
142 !strcmpi(extension, "ico"))
144 else if(!strcmpi(extension, "wav") || !strcmpi(extension, "mp3") ||
145 !strcmpi(extension, "ogg") || !strcmpi(extension, "snd"))
147 else if(!strcmpi(extension, "ear") || !strcmpi(extension, "7z") ||
148 !strcmpi(extension, "rar") || !strcmpi(extension, "zip") ||
149 !strcmpi(extension, "gz") || !strcmpi(extension, "bz2") ||
150 !strcmpi(extension, "tar") || !strcmpi(extension, "arj") ||
151 !strcmpi(extension, "lza") || !strcmpi(extension, "lzh") ||
152 !strcmpi(extension, "cpio") || !strcmpi(extension, "z"))
154 else if(!strcmpi(extension, "cab") || !strcmpi(extension, "deb") ||
155 !strcmpi(extension, "rpm"))
157 else if(!strcmpi(extension, "iso") || !strcmpi(extension, "mds") ||
158 !strcmpi(extension, "cue") || !strcmpi(extension, "bin") ||
159 !strcmpi(extension, "ccd") || !strcmpi(extension, "bwt") ||
160 !strcmpi(extension, "cdi") || !strcmpi(extension, "nrg"))
161 return opticalMediaImageFile;
166 public enum FileSystemBoxMode { directory, list };
168 class FileSystemBoxBits
170 bool foldersOnly:1, filesOnly:1, details:1, pathColumn:1, treeBranches:1, previewPictures:1, navigateFolders:1, autoLoad:1;
172 bool columnsCompareStyle:1;
173 //bool header:1, freeSelect:1, fullRowSelect:1, multiSelect:1, autoScroll:1, alwaysHL : 1, moveRows:1, resizable:1;
174 //bool moveFields:1, clearHeader:1, alwaysEdit:1, collapse:1, treeBranch:1, rootCollapse:1, heightSet:1;
175 //bool sortable:1, noDragging:1, fillLastField:1, expandOnAdd:1;
176 bool textFileLinesStyle:1;
178 FileSystemBoxMode mode:2;
181 public class FileSystemBox : Window // should we not derive from ListBox instead?
182 // I say we should, but we can't right now...
183 // because ListBox (inside ecere library) is
184 // not exposing enough internal machinery...
185 // could we not have a different private and
186 // public mechanism when deriving a class than
187 // we do when simply instanciating a class?
189 this stuff from the listbox would be nicely exposed...
190 fullRowSelect = false;
192 collapseControl = true;
193 rootCollapseButton = true;
198 hasHorzScroll = false;
199 hasVertScroll = false;
205 FileSystemBoxSelection selection { };
207 subclass(InterfaceFileSystemIterator) iteratorClass;
208 FileSystemCache cache;
210 virtual bool Window::NotifyNodeSelect(FileSystemBox box, FileSystemBoxSelection selection);
211 //virtual bool Window::NotifyNodeNavigate(FileSystemBox box, FileSystemNode node);
212 virtual bool Window::NotifyNodeOpen(FileSystemBox box, FileSystemBoxSelection selection);
213 virtual bool Window::NotifyNodeMenu(FileSystemBox box, Menu menu, FileSystemBoxSelection selection);
214 virtual bool Window::NotifyIteratorInit(FileSystemBox box, FileSystemIterator fileSystemIterator);
216 property const char * path
221 if(value && value[0])
222 path = CopyString(value);
224 locationBox.path = value;
229 //isset { return path && path[0]; }
232 property Array<String> comparedPaths
238 comparedPaths.Free();
239 delete comparedPaths;
241 if(value && value.count)
242 comparedPaths = value;
244 locationBox.path = value[0];
248 get { return comparedPaths; }
249 //isset { return comparedPaths && comparedPaths.count; }
252 property FileSystemBoxMode mode { set { bits.mode = value; } get { return bits.mode; } };
253 property bool foldersOnly { set { bits.foldersOnly = value; bits.filesOnly = !value; } get { return bits.foldersOnly; } };
254 property bool filesOnly { set { bits.filesOnly = value; bits.foldersOnly = !value; } get { return bits.filesOnly; } };
255 property bool previewPictures { set { bits.previewPictures = value; } get { return bits.previewPictures; } };
256 property char * extensions { set { delete extensions; if(value && value[0]) extensions = CopyString(value); } get { return extensions; } }
257 property bool details { set { bits.details = value; ChangeViewType(); } get { return bits.details; } };
258 property bool pathColumn { set { bits.pathColumn = value; ChangeViewType(); } get { return bits.pathColumn; } };
259 property bool treeBranches
263 bits.treeBranches = value;
264 list.treeBranches = value;
265 list.collapseControl = value;
266 list.rootCollapseButton = value;
268 get { return bits.treeBranches; }
270 property Color selectionColor { set { list.selectionColor = value; } get { return list.selectionColor; }/* isset { return selectionColor ? true : false; }*/ };
271 property Color selectionText { set { list.selectionText = value; } get { return list.selectionText; }/* isset { return selectionText ? true : false; }*/ };
272 property bool navigateFolders { set { bits.navigateFolders = value; bits.filesOnly = !value; } get { return bits.navigateFolders; } };
273 property bool multiSelect { set { list.multiSelect = value; } get { return list.multiSelect; } };
274 property bool autoLoad { set { bits.autoLoad = value; } get { return bits.autoLoad; } };
275 property bool hasHeader { set { list.hasHeader = value; } get { return list.hasHeader; } };
276 property bool preview
280 bits.preview = value;
281 split.leftPane = value ? list : null;
282 split.visible = value;
283 show.visible = value;
287 list.anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
290 get { return bits.preview; }
292 property bool columnsCompareStyle { set { bits.columnsCompareStyle = value; } get { return bits.columnsCompareStyle; } };
293 property bool textFileLinesStyle { set { bits.textFileLinesStyle = value; } get { return bits.textFileLinesStyle; } };
295 property FileSystemNode node
303 if(!list.currentRow.tag)
305 return (FileSystemNode)list.currentRow.tag;
311 void Select(FileSystemNode node)
315 node.EnsureVisible(false);
316 list.SelectRow(node.row);
320 void SelectMultipleByPath(Array<String> paths)
323 bool firstRow = false;
324 Map<String, bool> map { };
327 for(row = list.firstRow; row; row = row.next)
329 FileSystemNode node = (FileSystemNode)row.tag;
341 row.selected = false;
346 FileSystemNode SelectLocation(const char * location)
350 char step[MAX_LOCATION];
352 //StringArray steps { growingFactor = 4 };
353 Array<String> steps { };
354 FileSystemNode result = null;
355 FileSystemNode node = null;
357 temp = CopyString(location);
360 GetLastDirectory(temp, step);
361 StripLastDirectory(temp, temp);
362 steps.Add(CopyString(step));
365 for(c = steps.count - 1; c >= 0; c--)
367 //char * t = steps[c];
368 node = Find(steps[c], node);
386 FileSystemNode Find(const char * name, FileSystemNode parent)
388 FileSystemNode node = null;
389 FileSystemNode result = null;
390 if(!parent/* && !strcmp(name, "/")*/)
393 for(row = list.firstRow; row; row = row.next)
395 node = (FileSystemNode)row.tag;
396 if(node.name && !fstrcmp(node.name, name))
405 FileSystemNode start = parent ? parent : root;
406 if(!start.bits.loaded || !start.bits.childrenLoaded)
408 for(node = start.children.first; node; node = node.next)
409 if(node.name && !fstrcmp(node.name, name))
427 bool MenuOpen(MenuItem selection, Modifiers mods)
433 bool MenuReplaceListItemByContainingDir(MenuItem selection, Modifiers mods)
436 //FileSystemBoxSelection selection = this.selection.Copy(); // TOFIX compiler bug -- FileSystemBox.c -- ../libede/src/FileSystemBox.ec:420:49: error: ‘selection’ redeclared as different kind of symbol
437 FileSystemBoxSelection sel = this.selection.Copy();
438 FileSystemNode node = sel.node;
439 char newPath[MAX_LOCATION];
440 StripLastDirectory(node.path, newPath);
441 //node.path = newPath;
443 //if(node && node.type.isFolder && bits.navigateFolders)
444 // property::path = node.path;
449 bool MenuReplaceListItemByChild(MenuItem selection, Modifiers mods)
452 //FileSystemBoxSelection selection = this.selection.Copy(); // TOFIX compiler bug -- FileSystemBox.c -- ../libede/src/FileSystemBox.ec:420:49: error: ‘selection’ redeclared as different kind of symbol
453 FileSystemBoxSelection sel = this.selection.Copy();
454 FileSystemNode node = sel.node;
455 char newPath[MAX_LOCATION];
456 StripLastDirectory(node.path, newPath);
457 //node.path = newPath;
459 //if(node && node.type.isFolder && bits.navigateFolders)
460 // property::path = node.path;
466 FileSystemBoxBits bits;
470 Array<String> comparedPaths;
472 BitmapResource fileIcons[_FileType];
473 BitmapResource compIcons[countOfCompIconNames]; // todo: fix this limitation
476 //BitmapArray bitmaps { growingFactor = 16 };
480 char wd[MAX_LOCATION];
481 GetWorkingDir(wd, sizeof(wd));
485 InitCompIcons(); // todo: these icons should not be initialize, they should be set
486 // or at least initalized when the comparison listing is requested
487 // and we know how many paths are being compared.
488 list.AddField(nameField);
489 bits.autoLoad = true;
490 //iteratorClass = class(FileSystemIterator);
497 comparedPaths.Free();
498 delete comparedPaths;
506 list.background = background;
512 for(c = 0; c < _FileType::enumSize; c++)
514 fileIcons[c] = BitmapResource { fileIconNames[c], alphaBlend = true };
515 AddResource(fileIcons[c]);
522 for(c = 0; c < countOfCompIconNames; c++)
524 compIcons[c] = BitmapResource { compIconNames[c], alphaBlend = true };
525 AddResource(compIcons[c]);
529 DataField nameField { header = "Name", dataType = "FileSystemNode", width = 240, userData = this, freeData = false/*, editable = true*/; };
530 DataField pathField { header = "Location", dataType = /*"String"*/ "char *", width = 300, freeData = true };
531 DataField typeField { header = "Type", dataType = /*"String"*/ "char *", width = 40, freeData = false };
532 DataField sizeField { header = "Size", dataType = "FileSize", width = 96, alignment = right, freeData = false };
533 DataField modifiedField { header = "Modified", dataType = "SecSince1970", width = 96, alignment = right, freeData = false };
541 char wd[MAX_LOCATION];
542 GetWorkingDir(wd, sizeof(wd));
555 hasHorzScroll = true;
556 hasVertScroll = true;
557 fullRowSelect = false;
559 alwaysHighLight = true;
561 anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
563 // WHY is this not working ?
564 /*void OnResize(int width, int height)
566 if(vertScroll.visible)
567 nameField.width = width - vertScroll.size.w;
569 nameField.width = width;
572 bool NotifyCollapse(ListBox listBox, DataRow row, bool collapsed)
576 FileSystemNode node = (FileSystemNode)row.tag;
577 FileSystemNode child;
581 for(child = node.children.last; child; child = node.children.last)
583 listBox.DeleteRow(child.row);
587 node.childrenLoaded = false;
592 if(!node.bits.loaded || !node.bits.childrenLoaded)
595 //list.Sort(nameField, 1);
598 for(child = node.children.first; child && child.next; child = child.next);
600 child.EnsureVisible(false);
606 bool NotifyRightClick(ListBox listBox, int x, int y, Modifiers mods)
608 DataRow row = listBox.currentRow;
611 FileSystemNode node = (FileSystemNode)row.tag;
618 NotifyNodeMenu(master, this, menu, selection);
623 text = PrintString("Open ", node.name);
624 MenuItem { menu, text, o, NotifySelect = MenuOpen, disabled = false }; //delete text;
626 if(node.bits.isListItem/* && TODO: unless node is at root location*/)
628 MenuDivider { menu };
629 MenuItem { menu, "Replace by Parent\tCtrl+R", r, NotifySelect = MenuReplaceListItemByContainingDir, disabled = false };
631 else if(bits.mode == list)
633 MenuDivider { menu };
634 MenuItem { menu, "Replace List Item\tCtrl+R", r, NotifySelect = MenuReplaceListItemByChild, disabled = false };
636 MenuDivider { menu };
637 MenuItem { menu, "Cut\tCtrl+X", t, NotifySelect = null, disabled = false };
638 MenuItem { menu, "Copy\tCtrl+C", c, NotifySelect = null, disabled = false };
639 MenuItem { menu, "Paste\tCtrl+V", p, NotifySelect = null, disabled = false /*!clipboard*/ };
640 MenuItem { menu, "Delete\tDel", d, NotifySelect = null, disabled = false };
641 //MenuDivider { menu };
646 master = this, menu = menu,
648 x + clientStart.x + absPosition.x - guiApp.desktop.position.x,
649 y + clientStart.y + absPosition.y - guiApp.desktop.position.y }
657 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
662 selection.nodes.Free();
663 list.GetMultiSelection(rows);
664 for(item = rows.first; item; item = item.next)
666 DataRow row = item.data;
667 FileSystemNode node = (FileSystemNode)row.tag;
668 selection.nodes.Add(node);
673 selection.node = (FileSystemNode)row.tag;
675 selection.node = null;
677 if(selection.node && bits.preview)
680 FileSystemNode node = selection.node;
684 if(node && node.type == pictureFile)
687 bitmap.Load(node.path, null, displaySystem);
691 bitmaps = BitmapArray { };
692 for(pos = 0; pos < selectedItems.count; pos++)
695 selItem = (ExplorerFileItem)selectedItems._[pos];
696 bitmap.Load(selItem.path, null, displaySystem);
697 //bitmaps.Add(bitmap);
699 if(node && node.type == pictureFile)
702 bitmap.Load(node.path, null, displaySystem);
706 //NotifyItemSelect(master, view, item, selectedItems);
709 NotifyNodeSelect(listBox.parent.master, this, selection);
713 bool NotifyEditing(ListBox listBox, DataRow row)
717 //FileSystemNode node = (FileSystemNode)row.tag;
722 bool NotifyEdited(ListBox listBox, DataRow row)
726 //FileSystemNode node = (FileSystemNode)row.tag;
731 bool NotifyEditDone(ListBox listBox, DataRow row)
735 //FileSystemNode node = (FileSystemNode)row.tag;
740 bool NotifyDoubleClick(ListBox listBox, int x, int y, Modifiers mods)
742 bool result = !(selection.node && selection.node.type.isFolder && bits.navigateFolders);
747 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
749 //bool result = false;
750 if((SmartKey)key == enter)
751 /*result = */OpenNode();
753 else if((SmartKey)key == f2)
754 /*result = */RenameNode();
756 else if((SmartKey)key == f2)
758 FileSystemNode node = selection.node;
759 node.row.Edit(nameField);
783 anchor = Anchor { top = 0, right = 0, bottom = 0 };
785 void OnRedraw(Surface surface)
787 FileSystemBox fsb = (FileSystemBox)parent;
790 int wBmp = fsb.bitmap.width;
791 int hBmp = fsb.bitmap.height;
792 int wWnd = fsb.show.clientSize.w;
793 int hWnd = fsb.show.clientSize.h;
795 //int wList = 0;//fsb.list.size.w + fsb.split.size.w;
797 //float scale = Min((float)(wWnd - 10) / wBmp, (float)(hWnd - 10) / hBmp);
799 //int wDraw = (int)(wBmp * scale);
800 //int hDraw = (int)(hBmp * scale);
803 surface.Filter(fsb.bitmap, (wWnd - wDraw) / 2, (hWnd - hDraw) / 2, 0, 0, wDraw, hDraw, wBmp, hBmp);
805 // Until Filter / Stretch works with X
806 surface.Blit(fsb.bitmap, (wWnd - wBmp) / 2, (hWnd - hBmp) / 2, 0, 0, wBmp, hBmp);
811 surface.SetForeground(white);
812 surface.Area(0, 0, fsb.clientSize.w - 1, fsb.clientSize.h - 1);
820 FileSystemBoxSelection sel = this.selection.Copy();
821 //FileSystemNode node = selection.node;
822 for(node : sel.nodes)
825 if(node && node.type.isFolder && bits.navigateFolders)
826 property::path = node.path;
827 if(NotifyNodeOpen(this.master, this, sel) && !result)
838 //FileSystemBoxSelection selection = this.selection.Copy();
839 FileSystemNode node = selection.node;
840 //if(node && node.type.isFolder && bits.navigateFolders)
841 // property::path = node.path;
842 // ------------------------------------------- working here ---------------------------
844 /*result = NotifyNodeRename(this.master, this, node);
847 if(RenameFile(oldn, newn))
857 Menu editMenu { menu, "Edit", e };
860 editMenu, "Cut\tCtrl+X", t, disabled = true;
862 bool NotifySelect(MenuItem selection, Modifiers mods)
868 MenuItem itemEditCopy
870 editMenu, "Copy\tCtrl+C", c, disabled = true;
872 bool NotifySelect(MenuItem selection, Modifiers mods)
878 MenuItem itemEditPaste
880 editMenu, "Paste\tCtrl+V", p;
882 bool NotifySelect(MenuItem selection, Modifiers mods)
888 MenuItem itemEditDelete
890 editMenu, "Delete\tDel", d, disabled = true;
892 bool NotifySelect(MenuItem selection, Modifiers mods)
899 // WHY is this crashing ?
900 /*void OnResize(int width, int height)
902 if(this && nameField)
903 nameField.width = width - 80;
906 void ChangeViewType()
910 list.resizable = bits.details || bits.pathColumn;
911 list.moveFields = bits.details || bits.pathColumn;
912 list.hasHeader = bits.details || bits.pathColumn;
913 list.AddField(nameField);
915 list.AddField(pathField);
918 list.AddField(typeField);
919 list.AddField(sizeField);
920 list.AddField(modifiedField);
927 // this is crashing in for designer when details = true // can't save the file, always yields a crash
928 /*if(list && created)
931 list.AddField(nameField);
934 list.AddField(typeField);
935 list.AddField(sizeField);
939 if(comparedPaths && !bits.treeBranches)
943 FileAttribs pathAttribs = FileExists(path);
946 if(pathAttribs.isDirectory)
948 if(bits.treeBranches)
958 else if(pathAttribs.isFile) // we assume this is a file list
960 File f = FileOpen(path, read);
963 if(bits.treeBranches)
970 MessageBoxTodo($"unable to open file list");
973 MessageBoxTodo($"path is not a directory nor is it a file");
976 MessageBoxTodo($"path does not exist");
978 list.Sort(nameField, 1);
981 void LoadTreeDirectory()
983 bool isRoot = !strcmp(path, "/");
984 char name[MAX_LOCATION];
985 //FileSystemNode parent;
986 //FileSystemNode node;
987 //FileListing listing { path, extensions = extensions };
990 GetLastDirectory(path, name);
995 GetWorkingDir(startPath, sizeof(startPath));
997 strcpy(path, startPath);*/
998 bits.mode = directory;
1006 root = FileSystemNode { bits.loaded = true, bits.childrenLoaded = true };
1007 AddTreeNode(root, true, false, false, null);
1008 while(listing.Find())
1010 int len = strlen(listing.name);
1011 char info[MAX_LOCATION];
1012 char name[MAX_LOCATION];
1013 if(listing.stats.attribs.isDrive &&
1014 len > 3 && !strncmp(&listing.name[1], ": [", 3))
1016 strncpy(name, listing.name, 2);
1018 strncpy(info, &listing.name[4], len - 5);
1023 strcpy(name, listing.name);
1032 false, bits.previewPictures, false,
1035 parent.info = info; //CopyString(info);
1036 parent.bits.loaded = true;
1039 !listing.stats.attribs.isDirectory,
1041 listing.stats.attribs.isDirectory,
1043 if(!listing.stats.attribs.isDirectory)
1044 parent.bits.childrenLoaded = true;
1047 node = FileSystemNode { name = msNetwork, type = network };
1048 AddTreeNode(node, false, false, true, null);
1049 node.row.collapsed = true;
1055 FileGetStats(path, stats);
1056 root = MakeFileSystemNode(stats, name, path, false, bits.previewPictures, false, displaySystem);
1057 AddTreeNode(root, false, false, true, null);
1063 root.type = computer;
1064 root.label = rootName;
1067 list.Sort(nameField, 1);
1068 list.SelectRow(root.row);
1071 void LoadListDirectory()
1073 FileListing listing { path, extensions = extensions };
1075 bits.mode = directory;
1076 while(listing.Find())
1077 ProcessListItem(listing.name, listing.path, listing.stats, false);
1080 void LoadListFileList(File f)
1084 while(f.GetLine(line, 65536))
1087 char name[MAX_FILENAME];
1088 FileGetStats(line, stats);
1089 GetLastDirectory(line, name);
1090 ProcessListItem(name, line, stats, true);
1094 void LoadTreeFileList(File f)
1098 while(f.GetLine(line, 65536))
1101 char name[MAX_FILENAME];
1102 FileSystemNode node;
1103 FileGetStats(line, stats);
1104 GetLastDirectory(line, name);
1105 node = ProcessTreeItem(name, line, stats, node);
1109 void LoadListIterator()
1111 FileSystemIterator iterator = eInstance_New(iteratorClass);
1114 iterator.owner = this;
1115 iterator.OnObject = ListIterator_OnObject;
1116 //iterator.OnLeavingDirectory = ListIterator_OnLeavingDirectory;
1117 NotifyIteratorInit(master, this, iterator);
1118 iterator.Iterate(path, true);
1123 bool ListIterator_OnObject(const char * name, const char * path, FileStats stats, bool isRootObject)
1125 ProcessListItem(name, path, stats, false);
1129 //void ListIterator_OnLeavingDirectory(char * path) { }
1131 void ProcessListItem(const char * name, const char * path, FileStats stats, bool isListItem)
1133 if((!bits.foldersOnly && !bits.filesOnly) || (bits.foldersOnly && stats.attribs.isDirectory) || (bits.filesOnly && stats.attribs.isFile))
1135 FileSystemNode node = MakeFileSystemNode(stats, name, path, false, bits.previewPictures, isListItem, displaySystem);
1140 FileSystemNode ProcessTreeItem(char * name, char * path, FileStats stats, FileSystemNode parent)
1142 FileSystemNode node = MakeFileSystemNode(stats, name, path, false, bits.previewPictures, true, displaySystem);
1143 AddTreeNode(parent, false, false, true, null);
1144 //LoadTreeNode(node);
1148 void LoadTreeNode(FileSystemNode node)
1150 if(!node.bits.loaded)
1152 char path[MAX_LOCATION];
1155 FileListing listing { path, extensions = extensions };
1156 if(node.children.count == 1)
1157 DeleteNode(node.children.first);
1159 while(listing.Find())
1162 FileSystemNode child = null;
1163 if(!listing.stats.attribs.isRemovable && ((!bits.foldersOnly && !bits.filesOnly) ||
1164 (bits.foldersOnly && listing.stats.attribs.isDirectory) ||
1165 (bits.filesOnly && listing.stats.attribs.isFile)))
1166 child = MakeAndAddToTreeFileSystemNodeFromFileListing(listing, node);
1168 NodeChildLoad(child, node);
1174 node.bits.childrenLoaded = true;
1175 node.bits.loaded = true;
1176 node.row.SortSubRows(false);
1178 else if(!node.bits.childrenLoaded)
1180 FileSystemNode child;
1181 if(node.children.first)
1183 for(child = node.children.first; child; child = child.next)
1185 if(!child.bits.loaded)
1186 LoadTreeNode(child);
1187 else if(!child.bits.childrenLoaded)
1188 NodeChildLoad(child, node);
1190 node.bits.childrenLoaded = true;
1191 node.row.SortSubRows(false);
1196 void NodeChildLoad(FileSystemNode parent, FileSystemNode node)
1198 char path[MAX_LOCATION];
1199 parent.GetPath(path);
1200 if(bits.textFileLinesStyle && FileExists(path).isFile)
1207 FileListing listing { path, extensions = extensions };
1208 while(listing.Find())
1211 FileSystemNode child = null;
1212 if((!bits.foldersOnly && !bits.filesOnly) ||
1213 (bits.foldersOnly && listing.stats.attribs.isDirectory) ||
1214 (bits.filesOnly && listing.stats.attribs.isFile))
1215 child = MakeAndAddToTreeFileSystemNodeFromFileListing(listing, parent);
1229 parent.bits.childrenLoaded = true;
1232 void LoadComparedList()
1234 int c/*, cmp*/ /*, smallest*/, icon;//, equalCount;
1235 int count = comparedPaths ? comparedPaths.count : 0;
1236 //bool allDone = false;
1239 char path[MAX_LOCATION];
1240 //Array<ComparisonState> states { };
1241 //Array<FileListing> listings { };
1242 //Array<int> equals { };
1243 //Array<MapNode<String, int>> mapNodes { };
1245 //Array<Map<String, int>> lists { };
1246 //Map<int, bool> equals{ };
1249 MapNode<String, /*Map<int, */Array<int>> na;
1250 //MapNode<int, int> nb;
1251 Map<String, /*Map<int, */Array<int>> names { };
1252 //Map<String, Array<bool>> names { };
1253 //Map<String, bool[16]> names { }; // does not seem to be working
1254 //Map<String, BoolArrayInt> names { };
1256 for(c = 0; c < comparedPaths.count; c++)
1258 FileListing listing { comparedPaths[c], extensions = extensions };
1259 while(listing.Find())
1261 /*Map<int, int>*/Array<int> m = names[listing.name];
1264 names[listing.name] = m;
1265 /*/m[c] = */m.Add(c);
1268 /* // compiles and should work but better solution?
1269 for(c = 0; c < comparedPaths.count; c++)
1271 FileListing listing { comparedPaths[c], extensions = extensions };
1272 while(listing.Find())
1274 Array<bool> a = names[listing.name];
1277 names[listing.name] = a;
1282 /* // does not seem to be working
1283 for(c = 0; c < comparedPaths.count; c++)
1285 FileListing listing { comparedPaths[c], extensions = extensions };
1286 while(listing.Find())
1288 names[listing.name][c] = true;
1293 if(comparedPaths.count > 0)
1295 FileListing listing { comparedPaths[0], extensions = extensions };
1296 while(listing.Find())
1298 // should be able to just do names[listing.name]._0 = true;
1299 BoolArrayInt bai = names[listing.name];
1301 names[listing.name] = bai;
1304 if(comparedPaths.count > 1)
1306 FileListing listing { comparedPaths[1], extensions = extensions };
1307 while(listing.Find())
1309 // should be able to just do names[listing.name]._1 = true;
1310 BoolArrayInt bai = names[listing.name];
1312 names[listing.name] = bai;
1320 for(dirPath : comparedPaths)
1323 if(FileExists(dirPath).isDirectory)
1325 FileListing listing { dirPath, extensions = extensions };
1326 //MapNode<String, int> mn;
1327 Map<String, int> list { };
1328 //states.Add(listing.Find() == true ? matching : endOfListing);
1329 while(listing.Find())
1330 list[listing.name] = 0;
1331 //for(mn = ; mn; mn = mn.next)
1332 //mn = list.root.minimum;
1333 mapNodes.Add(/-*mn*-/list.root.minimum);
1335 //PrintLn(dirPath, " -- .Find() -- ", states[states.count-1] == matching ? listing.name : "endOfListing*");
1336 //listings.Add(listing);
1339 MapNode<String, int> mn;
1340 PrintLn("------------- DIR LISTING FOR ", dirPath);
1341 for(mn = list.root.minimum; mn; mn = mn.next)
1350 for(na = names.root.minimum; na; na = na.next)
1352 /*Map<int, */Array<int> equals = na.value;
1353 //MapNode<int, int> nb;
1359 for(c = 1; c < count; c++)
1361 //if(states[c] == endOfListing) continue;
1362 if(!mapNodes[c]) continue;
1363 // todo: use better comparison method
1364 // it should compare file type (dir/file) before
1365 // comparing file name.
1366 // should also provide alternative methods
1367 // of comparison including ones that consider
1368 // date changes as differences of some kind.
1369 // pethaps a OnCompare(a, b) to allow implementation
1370 // of custom methods of comparison.
1371 // note: this (or these) method(s) depend on files
1372 // being listed in sorted order by FileListing.
1373 // different comparison methods should have
1374 // appropriatly different sorting in FileListing.
1376 //cmp = strcmp(listings[smallest].name, listings[c].name);
1377 cmp = fstrcmp(mapNodes[smallest].key, mapNodes[c].key);
1378 PrintLn("COMPARING - ", mapNodes[smallest].key, " and ", mapNodes[c].key);
1391 if(equals.count == count) // all are equal, no diff icon
1396 else if(equals.count == count-1) // all are equal but one, not-sign icon for singled out missing
1400 for(nb = equals.root.minimum, i = 0; nb; nb = nb.next, i++)
1404 for(i = 0; i < equals.count; i++)
1413 if(i == equals.count)
1417 else if(equals.count == 1) // only one is present, all others missing, present-sign for singled out present
1419 //icon = equals.root.minimum.key+1;
1430 if(equals.count == count) // all are equal, no diff icon
1432 else if(count/2 - equals.count < 0) // more than half are equal, use not-sign icons for all missing
1434 else // less than half are equal, use present-sign icons for all present
1438 /*if((!bits.foldersOnly && !bits.filesOnly) ||
1439 (bits.foldersOnly && listings[smallest].stats.attribs.isDirectory) ||
1440 (bits.filesOnly && listings[smallest].stats.attribs.isFile))*/
1441 strcpy(path, comparedPaths[/*smallest*/equals[0]]);
1442 PathCat(path, /*mapNodes[smallest].key*/na.key);
1443 FileGetStats(path, stats);
1444 if((!bits.foldersOnly && !bits.filesOnly) ||
1445 (bits.foldersOnly && stats.attribs.isDirectory) ||
1446 (bits.filesOnly && stats.attribs.isFile))
1448 FileSystemNode node =
1449 MakeComparedFileSystemNode(
1451 /*mapNodes[smallest].key*/na.key,
1453 false, bits.previewPictures,
1461 mapNodes[equal] = mapNodes[equal].next;
1462 //states[equal] = listings[equal].Find() == true ? matching : endOfListing;
1463 //PrintLn(comparedPaths[equal], " -- .Find() -- ", states[equal] == matching ? listings[equal].name : "endOfListing*");
1466 //for(c = 0; c < count && states[c] == endOfListing; c++);
1467 for(c = 0; c < count && !mapNodes[c]; c++);
1472 list.Sort(nameField, 1);
1475 void AddNode(FileSystemNode node)
1477 DataRow row = list.AddRow();
1478 row.tag = (intptr)node;
1481 row.SetData(nameField, node);
1484 char path[MAX_LOCATION];
1485 StripLastDirectory(node.path, path);
1486 row.SetData(pathField, CopyString(path));
1490 if(node.type.isFile)
1492 row.SetData(typeField, node.extension);
1493 row.SetData(sizeField, /*(void *)*/node.stats.size);
1495 row.SetData(modifiedField, node.stats.modified);
1499 FileSystemNode MakeAndAddToTreeFileSystemNodeFromFileListing(FileListing listing, FileSystemNode parent)
1501 FileSystemNode result = null;
1502 /*if((!bits.foldersOnly && !bits.filesOnly) ||
1503 (bits.foldersOnly && listing.stats.attribs.isDirectory) ||
1504 (bits.filesOnly && listing.stats.attribs.isFile))*/
1505 /*if(!listing.stats.attribs.isRemovable && ((!bits.foldersOnly && !bits.filesOnly) ||
1506 (bits.foldersOnly && listing.stats.attribs.isDirectory) ||
1507 (bits.filesOnly && listing.stats.attribs.isFile)))*/
1509 bool textFileLinesStyle = false;
1510 const char * test = listing.name;
1513 result = MakeFileSystemNode(listing.stats, listing.name, listing.path, false, bits.previewPictures, false, displaySystem);
1517 if(bits.textFileLinesStyle)
1519 char ext[MAX_LOCATION];
1520 GetExtension(listing.name, ext);
1521 if(!strcmpi(ext, "txt") || !strcmpi(ext, "text"))
1522 textFileLinesStyle = true;
1524 //AddTreeNode(result, true, false, textFileLinesStyle, parent);
1525 AddTreeNode(result, !textFileLinesStyle && listing.stats.attribs.isFile, false, !listing.stats.attribs.isFile || textFileLinesStyle, parent);
1534 FileSystemNode node,
1536 bool childrenLoaded,
1538 FileSystemNode addTo)
1540 DataRow row = (addTo && addTo.row) ? addTo.row.AddRow() : list.AddRow();
1543 node.parent = addTo;
1544 node.indent = addTo.indent + 1;
1545 addTo.children.Add(node);
1547 row.tag = (intptr)node;
1549 row.SetData(null, node);
1552 char path[MAX_LOCATION];
1553 StripLastDirectory(node.path, path);
1554 row.SetData(pathField, CopyString(path));
1558 if(node.type.isFile)
1560 row.SetData(typeField, node.extension);
1561 row.SetData(sizeField, /*(void *)*/node.stats.size);
1563 row.SetData(modifiedField, node.stats.modified);
1566 node.bits.loaded = loaded;
1567 node.bits.childrenLoaded = childrenLoaded;
1569 //AddTreeNode(FileSystemNode { }, false, false, node); // why would this create a compile error?
1570 AddTreeNode(FileSystemNode { type = none, name = "Loader" }, false, false, false, node);
1572 if(node.indent > 0 || bits.mode == list)
1573 row.collapsed = true;
1574 else if(node.type == folder)
1575 node.type = folderOpen;
1578 void DeleteNode(FileSystemNode node)
1580 FileSystemNode child;
1583 for(; (child = node.children.first); )
1586 list.DeleteRow(node.row);
1593 enum ComparisonState { endOfListing, matching };
1597 class ExplorerView : FileSystemBox
1600 hasHorzScroll = false;
1601 hasVertScroll = false;
1603 virtual void Load(FileSystemNode parent);
1604 virtual void Refresh();
1606 virtual void LaunchNotifyItemSelect(Window master, ExplorerView view, ExplorerFileItem item, ExplorerFileItemArray selectedItems)
1608 view.NotifyItemSelect(master, view, item, selectedItems);
1611 virtual bool Window::NotifyItemSelect(ExplorerView view, ExplorerFileItem item, ExplorerFileItemArray selectedItems);
1612 virtual bool Window::NotifyItemOpen(ExplorerView view, ExplorerFileItem item);
1616 master = master, parent = this;
1619 hasHorzScroll = true;
1620 hasVertScroll = true;
1623 fullRowSelect = false;
1626 anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
1628 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
1630 ExplorerView view = (ExplorerView)listBox.parent;
1631 if(listBox.currentRow)
1634 ExplorerFileItemArray selectedItems { growingFactor = 16 };
1635 for(listRow = listBox.firstRow; listRow; listRow = listRow.next)
1636 if(listRow.selected)
1637 selectedItems.Add((ExplorerFileItem)listRow.tag);
1638 //view.NotifyItemSelect(listBox.parent.master, view, (ExplorerFileItem)listBox.currentRow.tag);
1639 view.LaunchNotifyItemSelect(listBox.parent.master, view, (ExplorerFileItem)listBox.currentRow.tag, selectedItems);
1644 bool NotifyDoubleClick(ListBox listBox, int x, int y, Modifiers mods)
1646 ExplorerView view = (ExplorerView)listBox.parent;
1647 view.NotifyItemOpen(listBox.parent.master, view, (ExplorerFileItem)listBox.currentRow.tag);
1651 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
1653 if((SmartKey)key == enter)
1655 ExplorerView view = (ExplorerView)listBox.parent;
1656 view.NotifyItemOpen(listBox.parent.master, view, (ExplorerFileItem)listBox.currentRow.tag);
1669 class ExplorerViewList : ExplorerView
1672 FileSystemNode location;
1676 DataField nameField { header = "Name", dataType = "ExplorerFileItem", width = 304, editable = true, userData = this };
1678 ExplorerViewDetails()
1680 list.AddField(nameField);
1688 void Load(FileSystemNode location)
1690 char path[MAX_LOCATION];
1691 this.location = location;
1692 location.GetPath(path);
1694 FileListing listing { path };
1696 ExplorerFileItem item;
1701 while(listing.Find())
1703 item = MakeFileItem(listing.stats.attribs, listing.name, listing.path, previewPictures, displaySystem);
1705 row = list.AddRow();
1706 row.tag = (int)item;
1707 row.SetData(nameField, item);
1709 list.Sort(nameField, 1);
1716 class ExplorerViewDetails : ExplorerView
1718 list.hasHeader = true;
1719 list.moveFields = true;
1720 list.resizable = true;
1721 list.sortable = true;
1723 FileSystemNode location;
1727 DataField nameField { header = "Name", dataType = "ExplorerFileItem", width = 304, editable = true, userData = this };
1728 DataField typeField { header = "Type", dataType = /-*"String"*-/ "char *", width = 40 };
1729 DataField sizeField { header = "Size", dataType = "FileSize", width = 96, alignment = right };
1731 ExplorerViewDetails()
1733 list.AddField(nameField);
1734 list.AddField(typeField);
1735 list.AddField(sizeField);
1743 void Load(FileSystemNode location)
1745 char path[MAX_LOCATION];
1746 this.location = location;
1747 location.GetPath(path);
1749 FileListing listing { path };
1751 ExplorerFileItem item;
1756 while(listing.Find())
1758 item = MakeFileItem(listing.stats.attribs, listing.name, listing.path, previewPictures, displaySystem);
1760 row = list.AddRow();
1761 row.tag = (int)item;
1762 row.SetData(nameField, item);
1763 row.SetData(typeField, CopyString(item.extension));
1764 row.SetData(sizeField, (uint)listing.stats.size);
1766 list.Sort(nameField, 1);
1773 class ExplorerViewIcons : ExplorerView
1776 FileSystemNode location;
1780 DataField nameField { header = "Name", dataType = "ExplorerFileItem", width = 304, editable = true, userData = this };
1782 ExplorerViewDetails()
1784 list.AddField(nameField);
1792 void Load(FileSystemNode location)
1794 char path[MAX_LOCATION];
1795 this.location = location;
1796 location.GetPath(path);
1798 FileListing listing { path };
1800 ExplorerFileItem item;
1805 while(listing.Find())
1807 item = MakeFileItem(listing.stats.attribs, listing.name, listing.path, previewPictures, displaySystem);
1809 row = list.AddRow();
1810 row.tag = (int)item;
1811 row.SetData(nameField, item);
1813 list.Sort(nameField, 1);
1820 class ExplorerViewCards : ExplorerView
1823 FileSystemNode location;
1827 DataField nameField { header = "Name", dataType = "ExplorerFileItem", width = 304, editable = true, userData = this };
1829 ExplorerViewDetails()
1831 list.AddField(nameField);
1839 void Load(FileSystemNode location)
1841 char path[MAX_LOCATION];
1842 this.location = location;
1843 location.GetPath(path);
1845 FileListing listing { path };
1847 ExplorerFileItem item;
1852 while(listing.Find())
1854 item = MakeFileItem(listing.stats.attribs, listing.name, listing.path, previewPictures, displaySystem);
1856 row = list.AddRow();
1857 row.tag = (int)item;
1858 row.SetData(nameField, item);
1860 list.Sort(nameField, 1);
1867 public class BitmapArray : RedjArray
1869 type = class(Bitmap);
1872 Bitmap * Add(Bitmap bitmap)
1879 Bitmap * AddBefore(uint position, Bitmap bitmap)
1881 Insert(position, 1);
1882 _[position] = bitmap;
1883 return &_[position];
1888 for(c = 0; c < _count; c++)
1900 class ExplorerViewShowcase : ExplorerView
1902 list.anchor = Anchor { left = 0, top = 0, bottom = 0 };
1903 list.size = Size { w = 200 };
1905 FileSystemNode location;
1909 DataField nameField { header = "Name", dataType = "ExplorerFileItem", width = 180, editable = true, userData = this };
1912 BitmapArray bitmaps { growingFactor = 16 };
1918 anchor = Anchor { top = 0, right = 0, bottom = 0 };
1920 void OnRedraw(Surface surface)
1922 ExplorerViewShowcase view = (ExplorerViewShowcase)parent;
1925 int wBmp = view.bitmap.width;
1926 int hBmp = view.bitmap.height;
1927 int wWnd = clientSize.w;
1928 int hWnd = clientSize.h;
1930 int wList = view.list.size.w + view.split.size.w;
1932 float scale = Min((float)(wWnd - 10) / wBmp, (float)(hWnd - 10) / hBmp);
1934 int wDraw = (int)(wBmp * scale);
1935 int hDraw = (int)(hBmp * scale);
1938 surface.Filter(view.bitmap, (wWnd - wDraw) / 2, (hWnd - hDraw) / 2, 0, 0, wDraw, hDraw, wBmp, hBmp);
1940 // Until Filter / Stretch works with X
1941 surface.Blit(view.bitmap, (wWnd - wDraw) / 2, (hWnd - hDraw) / 2, 0, 0, wDraw, hDraw);
1946 surface.SetForeground(white);
1947 surface.Area(0, 0, view.clientSize.w - 1, view.clientSize.h - 1);
1961 ExplorerViewDetails()
1963 list.AddField(nameField);
1966 void LaunchNotifyItemSelect(Window master, ExplorerViewShowcase view, ExplorerFileItem item, ExplorerFileItemArray selectedItems)
1969 ExplorerFileItem selItem;
1973 if(item && item.type == pictureFile)
1975 view.bitmap = Bitmap { };
1976 view.bitmap.Load(item.path, null, displaySystem);
1979 view.bitmaps.Clear();
1980 view.bitmaps = BitmapArray { };
1981 for(pos = 0; pos < selectedItems.count; pos++)
1984 selItem = (ExplorerFileItem)selectedItems._[pos];
1985 bitmap.Load(selItem.path, null, displaySystem);
1986 //view.bitmaps.Add(bitmap);
1988 if(item && item.type == pictureFile)
1990 view.bitmap = Bitmap { };
1991 view.bitmap.Load(item.path, null, displaySystem);
1994 view.show.Update(null);
1995 view.NotifyItemSelect(master, view, item, selectedItems);
2003 void Load(FileSystemNode location)
2005 char path[MAX_LOCATION];
2006 this.location = location;
2007 location.GetPath(path);
2009 FileListing listing { path };
2011 ExplorerFileItem item;
2016 while(listing.Find())
2018 item = MakeFileItem(listing.stats.attribs, listing.name, listing.path, previewPictures, displaySystem);
2020 row = list.AddRow();
2021 row.tag = (int)item;
2022 row.SetData(nameField, item);
2024 list.Sort(nameField, 1);
2031 class ExplorerTree : FileSystemBox
2033 hasHorzScroll = false;
2034 hasVertScroll = false;
2040 DataField nameField { dataType = "FileSystemNode", width = 240, userData = this };
2042 FileSystemNode root;
2043 FileSystemNode selection;
2045 virtual bool Window::NotifyNodeSelect(ExplorerTree tree, FileSystemNode node);
2047 property FileSystemNode node
2053 if(!tree.currentRow)
2055 if(!tree.currentRow.tag)
2057 return (FileSystemNode)tree.currentRow.tag;
2061 void Select(FileSystemNode node)
2065 node.EnsureVisible(false);
2066 tree.SelectRow(node.row);
2070 FileSystemNode Find(const char * name, FileSystemNode parent)
2072 FileSystemNode node;
2073 FileSystemNode start = parent ? parent : root;
2074 if(!start.loaded || !start.childrenLoaded)
2075 LoadTreeNode(start, tree);
2076 for(node = start.children.first; node; node = node.next)
2077 if(node.name && !strcmpi(node.name, name))
2084 master = master, parent = this;
2087 hasHorzScroll = true;
2088 hasVertScroll = true;
2089 fullRowSelect = false;
2091 collapseControl = true;
2092 rootCollapseButton = true;
2094 anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
2096 // WHY is this not working ?
2097 /-*void OnResize(int width, int height)
2099 if(vertScroll.visible)
2100 nameField.width = width - vertScroll.size.w;
2102 nameField.width = width;
2105 bool NotifyCollapse(ListBox listBox, DataRow row, bool collapsed)
2109 FileSystemNode node = (FileSystemNode)row.tag;
2110 FileSystemNode child;
2114 for(child = node.children.last; child; child = node.children.last)
2116 listBox.DeleteRow(child.row);
2120 node.childrenLoaded = false;
2125 if(!node.loaded || !node.childrenLoaded)
2126 LoadTreeNode(node, tree);
2127 for(child = node.children.first; child && child.next; child = child.next);
2129 child.EnsureVisible(false);
2135 bool NotifyRightClick(ListBox listBox, int x, int y, Modifiers mods)
2137 DataRow row = listBox.currentRow;
2140 FileSystemNode node = (FileSystemNode)row.tag;
2146 MenuItem { menu, "Cut\tCtrl+X", t, NotifySelect = null, disabled = false };
2147 MenuItem { menu, "Copy\tCtrl+C", c, NotifySelect = null, disabled = false };
2148 MenuItem { menu, "Paste\tCtrl+V", p, NotifySelect = null, disabled = false /-*!clipboard*-/ };
2149 MenuItem { menu, "Delete\tDel", d, NotifySelect = null, disabled = false };
2150 //MenuDivider { menu };
2154 master = this, menu = menu,
2156 x + clientStart.x + absPosition.x - guiApp.desktop.position.x,
2157 y + clientStart.y + absPosition.y - guiApp.desktop.position.y }
2165 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
2169 FileSystemNode node = (FileSystemNode)row.tag;
2170 NotifyNodeSelect(listBox.parent.master, this, node);
2176 bool NotifyEditing(ListBox listBox, DataRow row)
2180 FileSystemNode node = (FileSystemNode)row.tag;
2185 bool NotifyEdited(ListBox listBox, DataRow row)
2189 FileSystemNode node = (FileSystemNode)row.tag;
2194 bool NotifyEditDone(ListBox listBox, DataRow row)
2198 FileSystemNode node = (FileSystemNode)row.tag;
2205 Menu editMenu { menu, "Edit", e };
2206 MenuItem itemEditCut
2208 editMenu, "Cut\tCtrl+X", t, disabled = true;
2210 bool NotifySelect(MenuItem selection, Modifiers mods)
2216 MenuItem itemEditCopy
2218 editMenu, "Copy\tCtrl+C", c, disabled = true;
2220 bool NotifySelect(MenuItem selection, Modifiers mods)
2226 MenuItem itemEditPaste
2228 editMenu, "Paste\tCtrl+V", p;
2230 bool NotifySelect(MenuItem selection, Modifiers mods)
2236 MenuItem itemEditDelete
2238 editMenu, "Delete\tDel", d, disabled = true;
2240 bool NotifySelect(MenuItem selection, Modifiers mods)
2247 // WHY is this crashing ?
2248 /-*void OnResize(int width, int height)
2250 if(this && nameField)
2251 nameField.width = width - 80;
2256 tree.AddField(nameField);
2261 FileSystemNode parent;
2262 FileSystemNode node;
2263 FileListing listing { "/" };
2267 root = FileSystemNode { type = computer, loaded = true, childrenLoaded = true };
2269 root.name = rootName;
2273 AddTreeNode(root, true, false, false, null, tree);
2275 // How can this make sense for linux?
2277 while(listing.Find())
2279 int len = strlen(listing.name);
2280 char info[MAX_LOCATION];
2281 char name[MAX_LOCATION];
2282 if(listing.stats.attribs.isDrive &&
2283 len > 3 && !strncmp(&listing.name[1], ": [", 3))
2285 strncpy(name, listing.name, 2);
2287 strncpy(info, &listing.name[4], len - 5);
2292 strcpy(name, listing.name);
2296 parent = MakeFileSystemNode(listing.stats, name);
2298 parent.info = CopyString(info);
2299 parent.loaded = true;
2300 AddTreeNode(parent, !listing.stats.attribs.isDirectory, false, listing.stats.attribs.isDirectory, root, tree);
2301 if(!listing.stats.attribs.isDirectory)
2302 parent.childrenLoaded = true;
2305 node = FileSystemNode { name = msNetwork, type = network };
2306 AddTreeNode(node, false, false, true, null, tree);
2307 node.row.collapsed = true;
2308 tree.Sort(nameField, 1);
2309 tree.SelectRow(root.row);
2314 public class ClipBoardFiles
2328 int size = SelSize();
2331 // Try to allocate memory
2332 ClipBoard clipBoard { };
2333 if(clipBoard.Allocate(size+1))
2335 GetSel(clipBoard.memory, true);
2348 ClipBoard clipBoard { };
2349 if(clipBoard.Load())
2350 PutS(clipBoard.memory);
2361 SetViewToCursor(true);
2367 Private Type DROPFILES
2373 For iCounter = 0 To filelist.ListCount - 1
2374 If filelist.Selected(iCounter) = True Then
2375 strFiles = strFiles & FixPath(filelist.Path) & filelist.List(iCounter) & vbNullChar
2378 'all selected items are now put in strFiles
2380 hGlobal = GlobalAlloc(GHND, Len(DF) + Len(strFiles)) 'put all files to a exclusive number
2381 If hGlobal Then 'if the globalalloc worked
2382 lpGlobal = GlobalLock(hGlobal) 'lock the hGlobal
2383 DF.pFiles = Len(DF) 'set the size of the files
2385 Call CopyMem(ByVal lpGlobal, DF, Len(DF)) 'copy df to the lpglobal
2386 Call CopyMem(ByVal (lpGlobal + Len(DF)), ByVal strFiles, Len(strFiles)) 'copy strfiles to lpglobal
2387 Call GlobalUnlock(hGlobal) 'unlock hglobal again
2389 SetClipboardData CF_HDROP, hGlobal 'put files to the clipboard
2392 bool SaveFile(const char * filePath)
2398 public class FileTreeNodeBSArray : ArrayBinarySorted
2400 type = class(FileSystemNode);
2402 FileSystemNode * const _;
2403 BSloc Add(FileSystemNode item)
2405 BSloc result = Find(item);
2408 Insert(result.pos, 1);
2409 _[result.pos] = item;
2413 BSloc Remove(FileSystemNode item)
2421 public class FileTreeNodeArray : RedjArray
2423 type = class(FileSystemNode);
2425 FileSystemNode * const _;
2426 FileSystemNode * Add(FileSystemNode item)
2433 FileSystemNode * AddBefore(uint position, FileSystemNode item)
2435 Insert(position, 1);
2437 return &_[position];
2443 public class ExplorerFileItem : struct
2454 void OnDisplay(Surface surface, int x, int y, int width, FileSystemBox control, Alignment alignment, DataDisplayFlags displayFlags)
2456 int indentSize = (displayFlags.dropBox) ? 0 : 10;
2459 char label[MAX_FILENAME];
2461 //float scale = Min((float)clientSize.w / (float)bitmap.width, (float)clientSize.h / (float)bitmap.height);
2462 int w = 16; //(int)(bitmap.width * scale);
2463 int h = 16; //(int)(bitmap.height * scale);
2467 icon = control.fileIcons[type].bitmap;
2470 if(type == folder || type == folderOpen)
2471 surface.SetForeground(red); //Color { 170, 170, 0 } // REDJ What is that color?
2474 textOffset = indent * indentSize + (icon ? (icon.width + 6) : 0);
2477 sprintf(label, "%s [%s]", name, info);
2479 strcpy(label, name);
2480 len = strlen(label);
2482 surface.WriteTextDots
2483 (alignment, x + textOffset, y + 2, width - textOffset, label, len);
2484 if(type == pictureFile && control.previewPictures && bitmap)
2487 //surface.Filter(bitmap, (clientSize.w - w) / 2,(clientSize.h - h) / 2, 0,0, w, h, bitmap.width, bitmap.height);
2488 surface.Filter(bitmap, x + indent * indentSize + 2, y, 0, 0, w, h, bitmap.width, bitmap.height);
2490 // Until Filter / Stretch works with X
2491 //surface.Blit(bitmap, (clientSize.w - bitmap.width) / 2,(clientSize.h - bitmap.height) / 2, 0,0, bitmap.width, bitmap.height);
2492 surface.blend = true;
2493 surface.Blit(bitmap, x + indent * indentSize + 2, y,0,0, w, h);
2499 surface.Blit(icon, x + indent * indentSize + 2, y,0,0, icon.width, icon.height);
2502 int OnCompare(ExplorerFileItem b)
2505 if(type == b.type || (type < folder && b.type < folder) || (type >= drive))
2506 result = strcmpi(name, b.name);
2509 if(type == folder && b.type < folder) result = -1;
2510 else if(type < folder && b.type == folder) result = 1;
2515 void OnCopy(ExplorerFileItem newData)
2517 type = newData.type;
2518 indent = newData.indent;
2521 int len = strlen(newData.name) + 1;
2522 name = new char[len];
2523 CopyBytes(name, newData.name, len);
2527 bool OnGetDataFromString(char * string)
2529 int len = strlen(string) + 1;
2530 name = new char[len];
2531 CopyBytes(name, string, len);
2545 char * OnGetString(char * string, void * fieldData, bool * needClass)
2551 public class ExplorerFileItemArray : RedjArray
2553 type = class(ExplorerFileItem);
2555 ExplorerFileItem * const _;
2556 ExplorerFileItem * Add(ExplorerFileItem item)
2563 ExplorerFileItem * AddBefore(uint position, ExplorerFileItem item)
2565 Insert(position, 1);
2567 return &_[position];
2572 for(c = 0; c < _count; c++)
2582 ExplorerFileItem MakeFileItem(const FileAttribs attribs, const char * fileName, const char * filePath, const bool previewPicture, const DisplaySystem displaySystem)
2584 int len = strlen(fileName);
2585 char info[MAX_LOCATION];
2586 char name[MAX_LOCATION];
2587 char extension[MAX_EXTENSION];
2589 ExplorerFileItem item { };
2591 //if(stats.attribs.isFile) // -- should work now
2592 if(attribs.isDirectory)
2596 item.type = (attribs.isDrive) ? drive : folder;
2597 if(attribs.isServer)
2603 if(attribs.isRemote)
2604 item.type = netDrive;
2605 if(attribs.isRemovable)
2607 if(fileName[0] == 'A' || fileName[0] == 'B')
2610 item.type = removable;
2615 GetExtension(fileName, extension);
2616 //strupr(extension);
2619 item.type = _FileType::SelectByExtension(extension);
2622 if(attribs.isDrive &&
2623 len > 3 && !strncmp(&fileName[1], ": [", 3))
2625 strncpy(name, fileName, 2);
2627 strncpy(info, &fileName[4], len - 5);
2632 strcpy(name, fileName);
2636 item.path = CopyString(filePath);
2637 item.name = CopyString(name);
2639 item.info = CopyString(info);
2640 item.extension = CopyString(extension);
2642 if(item.type == pictureFile && previewPicture)
2644 item.bitmap = Bitmap { };
2645 item.bitmap.Load(filePath, null, displaySystem);
2653 public class FileSystemBoxSelection
2656 FileSystemNode node;
2657 Array<FileSystemNode> nodes { };
2660 FileSystemBoxSelection Copy()
2662 FileSystemBoxSelection copy { node = node };
2665 copy.nodes.Add(node);
2671 ~FileSystemBoxSelection()
2677 class FileSystemNodeBits
2679 bool loaded:1, childrenLoaded:1, isListItem:1;
2682 public class FileSystemNode
2686 FileSystemNodeBits bits;
2699 /* LinkElement<FileSystemNode> link;
2700 FileSystemNode parent;
2702 FileSystemNodeType type;
2706 FileSystemNode prev, next;
2710 property bool isListItem { set { bits.isListItem = value; } get { return bits.isListItem; } };
2712 property const char * path
2714 set { delete path; if(value && value[0]) path = CopyString(value); }
2715 get { return path; } isset { return path && path[0]; }
2717 property const char * name
2719 set { delete name; if(value && value[0]) name = CopyString(value); }
2720 get { return name; } isset { return name && name[0]; }
2722 property char * extension
2724 set { delete extension; if(value && value[0]) extension = CopyString(value); }
2725 get { return extension; } isset { return extension && extension[0]; }
2727 property const char * label
2729 set { delete label; if(value && value[0]) label = CopyString(value); }
2730 get { return label; } isset { return label && label[0]; }
2732 property const char * info
2734 set { delete info; if(value && value[0]) info = CopyString(value); }
2735 get { return info; } isset { return info && info[0]; }
2741 FileSystemNode parent;
2749 Array<int> exists; // would use (see) BoolArrayInt to pack this into an int if could be accessed as an array
2751 void GetPath(String outputPath)
2754 strcpy(outputPath, path);
2759 strcpy(outputPath, name);
2760 for(up = parent; up; up = up.parent)
2762 char temp[MAX_LOCATION];
2763 strcpy(temp, up.name);
2764 PathCat(temp, outputPath);
2765 strcpy(outputPath, temp);
2769 strcpy(outputPath, name ? name : "");
2772 bool IsChildOf(FileSystemNode node)
2774 FileSystemNode test;
2775 for(test = parent; test; test = test.parent)
2781 void DuplicateChildren(bool recursive, bool forceExpanded, FileSystemNode addTo, FileSystemBox fsb)
2785 FileSystemNode child;
2787 for(child = children.first; child; child = child.next)
2789 FileSystemNode copy { };
2790 copy.name = child.name; //CopyString(child.name);
2791 copy.type = child.type;
2792 fsb.AddTreeNode(copy, child.bits.loaded, false, false, addTo);
2794 copy.row.collapsed = false;
2796 child.DuplicateChildren(recursive, forceExpanded, copy, fsb);
2801 void EnsureVisible(bool expand)
2804 parent.EnsureVisible(true);
2806 row.collapsed = false;
2807 // TODO: row.EnsureVisible(); // making the row visible by scrolling
2817 FileSystemNode child;
2818 for(; (child = children.first); )
2821 children.Delete(child);
2835 parent.children.Delete(this);
2838 void OnDisplay(Surface surface, int x, int y, int width, FileSystemBox fsb, Alignment alignment, DataDisplayFlags displayFlags)
2840 //int indentSize = (displayFlags.dropBox) ? 0 : 10;
2847 char text[MAX_LOCATION];
2857 comp = fsb.comparedPaths && fsb.comparedPaths.count > 1;
2859 icon = fsb.fileIcons[type].bitmap;
2860 alt = bits.isListItem ? path : name;
2861 if(comp && !fsb.bits.columnsCompareStyle && cmpIcon)
2864 diffIcon = Bitmap { };
2865 diffIcon.AllocateDD(
2866 surface.display.displaySystem,
2867 fsb.compIcons[cmpIcon].bitmap.width,
2868 fsb.compIcons[cmpIcon].bitmap.height);
2869 if(fsb.compIcons[cmpIcon].bitmap)
2870 diffIcon.Copy(fsb.compIcons[cmpIcon].bitmap);
2872 diffIcon = fsb.compIcons[cmpIcon-1].bitmap;
2873 notIcon = fsb.compIcons[countOfCompIconNames-1].bitmap;
2875 //xStart = indent * indent + x + (icon ? (icon.width + 5) : 0);
2876 xStart = x + (icon ? (icon.width + 5) : 0) + (comp ? 18*(fsb.bits.columnsCompareStyle ? fsb.comparedPaths.count : 1) : 0);
2882 sprintf(text, "%s [%s]", label ? label : alt, info);
2884 strcpy(text, label ? label : alt); //"%d-%d/%s", stats.inode, stats.nlink
2885 //sprintf(text, "%d-%d/%s", stats.inode, stats.nlink, label ? label : alt);
2890 if(type == folder || type == folderOpen)
2891 surface.SetForeground(yellow);
2895 //textOffset = indent * indentSize + (icon ? (icon.width + 4) : 0);
2897 surface.SetForeground(displayFlags.selected ? fsb.selectionText : fsb.foreground);
2898 surface.TextOpacity(false);
2899 surface.TextExtent(text, len, &w, &h);
2902 // Draw the current row stipple
2903 if(displayFlags.selected)
2904 //surface.Area(xStart - 1, y, xStart - 1, y + h - 1);
2905 //surface.Area(xStart + w - 1, y, xStart + w + 1, y + h - 1);
2906 surface.Area(xStart - 3, y, xStart + w + 1, y + h - 1);
2907 //surface.WriteTextDots(alignment, x + textOffset, y + 2, width - textOffset, alt, strlen(alt));
2908 surface.WriteTextDots(alignment, xStart, y + 2, width, text, len);
2910 if(!guiApp.textMode)
2912 if(displayFlags.current)
2914 if(displayFlags.active)
2916 surface.LineStipple(0x5555);
2917 if(displayFlags.selected)
2918 surface.SetForeground(0xFFFFFF80);
2920 surface.SetForeground(black);
2924 surface.SetForeground(selectionColor);
2926 surface.Rectangle(xStart - 3, y, xStart + w + 1, y + h - 1);
2927 surface.LineStipple(0);
2932 if(!fsb.bits.columnsCompareStyle && diffIcon)
2935 h = diffIcon.height;
2936 /*if(cmpNot && notIcon)
2938 Surface s = diffIcon.GetSurface(0,0, {w,h});
2939 s.SetForeground(white);
2940 s.Blit(notIcon, x,y, 0,0, w,h);
2943 surface.SetForeground(white);
2944 surface.Blit(diffIcon, x,y, 0,0, w,h);
2945 if(cmpNot && notIcon)
2946 surface.Blit(notIcon, x,y, 0,0, w,h);
2950 else if(fsb.bits.columnsCompareStyle && exists && exists.count)
2953 for(c = d = 0; c < fsb.comparedPaths.count; c++)
2955 if(d == exists.count || exists[d] != c)
2959 diffIcon = fsb.compIcons[c].bitmap;
2963 h = diffIcon.height;
2964 surface.SetForeground(white);
2965 surface.Blit(diffIcon, x,y, 0,0, w,h);
2972 for(c = d = 0; c < exists.count; c++)
2977 x+=18*(exists[c]-d);
2981 diffIcon = fsb.compIcons[exists[c]].bitmap;
2985 h = diffIcon.height;
2986 surface.SetForeground(white);
2987 surface.Blit(diffIcon, x,y, 0,0, w,h);
2993 if(exists.count < fsb.comparedPaths.count && exists[exists.count-1] != d)
2995 x+=18*(exists[exists.count-1]-d);
2999 else if(fsb.bits.columnsCompareStyle)
3001 x+=18*fsb.comparedPaths.count;
3009 if(type == pictureFile && fsb.previewPictures && bitmap)
3011 surface.SetForeground(white);
3012 surface.blend = true;
3014 //surface.Filter(bitmap, (clientSize.w - w) / 2,(clientSize.h - h) / 2, 0,0, w, h, bitmap.width, bitmap.height);
3015 //surface.Filter(bitmap, x + indent/* * indentSize*/ + 2, y, 0, 0, w, h, bitmap.width, bitmap.height);
3016 surface.Filter(bitmap, x,y,0,0, w, h, bitmap.width, bitmap.height);
3018 // Until Filter / Stretch works with X
3019 //surface.Blit(bitmap, (clientSize.w - bitmap.width) / 2,(clientSize.h - bitmap.height) / 2, 0,0, bitmap.width, bitmap.height);
3020 // surface.blend = true;
3021 //surface.Blit(bitmap, x + indent/* * indentSize*/ + 2, y,0,0, w, h);
3022 //surface.Blit(bitmap, x,y,0,0, bitmap.width, bitmap.height);
3029 //surface.blend = true;
3030 //surface.alphaWrite = blend;
3031 surface.SetForeground(white);
3032 //surface.Blit(icon, x + indent * indentSize, y,0,0, icon.width, icon.height);
3033 surface.Blit(icon, x,y, 0,0, w,h);
3038 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
3042 dataBox, anchor = { 0, 0, 0, 0 };
3044 //borderStyle = contour;
3046 //background = white;
3050 //dataBox.borderStyle = none;
3051 dataBox.borderStyle = contour;
3052 dataBox.background = white;
3053 //dataBox.opacity = 0.0f;
3058 bool OnSaveEdit(EditBox editBox, void * object)
3060 bool changed = false;
3061 if(editBox.modifiedDocument)
3064 // how the heck did this work for PathBox? :S
3066 //changed = _class._vTbl[__ecereVMethodID_class_OnGetDataFromString](_class, &this, editBox.contents);
3068 //if(strcmp(editBox.contents, this.name))
3071 //changed = NotifyNodeRename(this.master, this, node);
3073 if(changed && RenameFile(name, editBox.contents))
3075 name = editBox.contents;
3087 int OnCompare(FileSystemNode b)
3090 FileSystemNode a = this;
3091 if(a.type == b.type || (a.type < folder && b.type < folder) || (a.type >= drive))
3093 if(!a.name || !b.name)
3094 PrintLn("error: FileSystemNode::OnCompare -- null-named node");
3095 result = strcmpi(a.name, b.name);
3099 if(a.type == folder && b.type < folder) result = -1;
3100 else if(a.type < folder && b.type == folder) result = 1;
3107 //int OnCompare(FileSystemNode b)
3110 //FileSystemNode a = this;
3111 //if(a.parent < b.parent) result = -1;
3112 //else if(a.parent > b.parent) result = 1;
3114 //result = fstrcmp(a.name, b.name);
3119 bool OnGetDataFromString(const char * string)
3122 if(string && *string)
3124 int len = strlen(string) + 1;
3125 name = new char[len];
3126 CopyBytes(name, string, len);
3133 const char * OnGetString(char * tempString, void * unused /*FileSystemToolWindow fileSysToolWnd*/, bool * needClass)
3135 return name ? name : "";
3139 /*FileSystemNode MakeFileSystemNode(const FileStats stats, const char * name)
3141 FileSystemNode node { stats = stats };
3142 node.name = CopyString(name);
3145 if(stats.attribs.isDirectory)
3147 node.type = (stats.attribs.isDrive) ? drive : folder;
3148 if(stats.attribs.isServer) node.type = server;
3149 if(stats.attribs.isShare) node.type = share;
3150 if(stats.attribs.isCDROM) node.type = cdrom;
3151 if(stats.attribs.isRemote) node.type = netDrive;
3152 if(stats.attribs.isRemovable)
3154 if(name[0] == 'A' || name[0] == 'B')
3157 node.type = removable;
3162 char extension[MAX_EXTENSION];
3163 GetExtension(node.name, extension);
3164 node.type = _FileType::SelectByExtension(extension);
3169 FileSystemNode MakeFileSystemNode(
3170 const FileStats stats,
3173 const bool pathAddName,
3174 const bool previewPicture,
3175 const bool isListItem,
3176 /*const */DisplaySystem displaySystem)
3178 int len = strlen(name);
3179 char info[MAX_LOCATION];
3180 char name2[MAX_LOCATION];
3181 char extension[MAX_EXTENSION];
3183 FileSystemNode node { stats = stats };
3187 char o[MAX_LOCATION];
3188 //char r[MAX_LOCATION];
3189 //StripLastDirectory(path, o);
3190 GetLastDirectory(path, o);
3191 if(fstrcmp(name, o))
3192 //if(!FileExists(path))
3195 //if(stats.attribs.isFile) // TODO fix this in ecere -- WTH -- this has been fixed :/
3196 if(stats.attribs.isDirectory)
3198 extension[0] = '\0';
3200 node.type = (stats.attribs.isDrive) ? drive : folder;
3201 if(stats.attribs.isServer) node.type = server;
3202 if(stats.attribs.isShare) node.type = share;
3203 if(stats.attribs.isCDROM) node.type = cdrom;
3204 if(stats.attribs.isRemote) node.type = netDrive;
3205 if(stats.attribs.isRemovable)
3207 if(name[0] == 'A' || name[0] == 'B')
3210 node.type = removable;
3215 GetExtension(name, extension);
3218 node.type = _FileType::SelectByExtension(extension);
3221 if(stats.attribs.isDrive &&
3222 len > 3 && !strncmp(&name[1], ": [", 3))
3224 strncpy(name2, name, 2);
3226 strncpy(info, &name[4], len - 5);
3231 strcpy(name2, name);
3237 //bool isFile = stats.attribs.isFile;
3238 //bool isFolder = stats.attribs.isDirectory;
3239 char full[MAX_LOCATION];
3241 PathCat(full, name);
3242 node.path = full; //CopyString(full);
3245 node.path = path; //CopyString(path);
3246 node.name = name2; //CopyString(name2);
3248 node.info = info; //CopyString(info);
3249 node.extension = extension; //CopyString(extension);
3251 if(node.type == pictureFile && previewPicture)
3253 node.bitmap = Bitmap { alphaBlend = true };
3254 node.bitmap.Load(path, null, displaySystem);
3258 node.bits.isListItem = true;
3263 FileSystemNode MakeComparedFileSystemNode(
3264 const FileStats stats,
3267 const bool pathAddName,
3268 const bool previewPicture,
3271 /*const */Array<int> exists,
3272 /*const */DisplaySystem displaySystem)
3274 FileSystemNode node = MakeFileSystemNode(stats, name, path, pathAddName, previewPicture, false, displaySystem);
3277 node.cmpIcon = cmpIcon;
3278 node.cmpNot = cmpNot;
3279 node.exists = exists;
3284 #if 0 // could we do this?
3285 class BoolArrayInt : int
3287 // packing 32 bools in one int exposing them as an array
3288 bool [32]:1; // the :1 specifies the size of each element
3289 // byte [4]:8; // packing 4 bytes in an int exposing them as an arrat
3291 // allowing you to access each 32 bits with the following notation:
3298 for(c = 0; c < 32; c++)
3299 a[c] = SomFunction(...);
3302 class BoolArrayInt : int