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;
285 get { return bits.preview; }
287 property bool columnsCompareStyle { set { bits.columnsCompareStyle = value; } get { return bits.columnsCompareStyle; } };
288 property bool textFileLinesStyle { set { bits.textFileLinesStyle = value; } get { return bits.textFileLinesStyle; } };
290 property FileSystemNode node
298 if(!list.currentRow.tag)
300 return (FileSystemNode)list.currentRow.tag;
306 void Select(FileSystemNode node)
310 node.EnsureVisible(false);
311 list.SelectRow(node.row);
315 void SelectMultipleByPath(Array<String> paths)
318 bool firstRow = false;
319 Map<String, bool> map { };
322 for(row = list.firstRow; row; row = row.next)
324 FileSystemNode node = (FileSystemNode)row.tag;
336 row.selected = false;
341 FileSystemNode SelectLocation(const char * location)
345 char step[MAX_LOCATION];
347 //StringArray steps { growingFactor = 4 };
348 Array<String> steps { };
349 FileSystemNode result = null;
350 FileSystemNode node = null;
352 temp = CopyString(location);
355 GetLastDirectory(temp, step);
356 StripLastDirectory(temp, temp);
357 steps.Add(CopyString(step));
360 for(c = steps.count - 1; c >= 0; c--)
362 //char * t = steps[c];
363 node = Find(steps[c], node);
381 FileSystemNode Find(const char * name, FileSystemNode parent)
383 FileSystemNode node = null;
384 FileSystemNode result = null;
385 if(!parent/* && !strcmp(name, "/")*/)
388 for(row = list.firstRow; row; row = row.next)
390 node = (FileSystemNode)row.tag;
391 if(node.name && !fstrcmp(node.name, name))
400 FileSystemNode start = parent ? parent : root;
401 if(!start.bits.loaded || !start.bits.childrenLoaded)
403 for(node = start.children.first; node; node = node.next)
404 if(node.name && !fstrcmp(node.name, name))
422 bool MenuOpen(MenuItem selection, Modifiers mods)
428 bool MenuReplaceListItemByContainingDir(MenuItem selection, Modifiers mods)
431 //FileSystemBoxSelection selection = this.selection.Copy(); // TOFIX compiler bug -- FileSystemBox.c -- ../libede/src/FileSystemBox.ec:420:49: error: ‘selection’ redeclared as different kind of symbol
432 FileSystemBoxSelection sel = this.selection.Copy();
433 FileSystemNode node = sel.node;
434 char newPath[MAX_LOCATION];
435 StripLastDirectory(node.path, newPath);
436 //node.path = newPath;
438 //if(node && node.type.isFolder && bits.navigateFolders)
439 // property::path = node.path;
444 bool MenuReplaceListItemByChild(MenuItem selection, Modifiers mods)
447 //FileSystemBoxSelection selection = this.selection.Copy(); // TOFIX compiler bug -- FileSystemBox.c -- ../libede/src/FileSystemBox.ec:420:49: error: ‘selection’ redeclared as different kind of symbol
448 FileSystemBoxSelection sel = this.selection.Copy();
449 FileSystemNode node = sel.node;
450 char newPath[MAX_LOCATION];
451 StripLastDirectory(node.path, newPath);
452 //node.path = newPath;
454 //if(node && node.type.isFolder && bits.navigateFolders)
455 // property::path = node.path;
461 FileSystemBoxBits bits;
465 Array<String> comparedPaths;
467 BitmapResource fileIcons[_FileType];
468 BitmapResource compIcons[countOfCompIconNames]; // todo: fix this limitation
471 //BitmapArray bitmaps { growingFactor = 16 };
475 char wd[MAX_LOCATION];
476 GetWorkingDir(wd, sizeof(wd));
480 InitCompIcons(); // todo: these icons should not be initialize, they should be set
481 // or at least initalized when the comparison listing is requested
482 // and we know how many paths are being compared.
483 list.AddField(nameField);
484 bits.autoLoad = true;
485 //iteratorClass = class(FileSystemIterator);
492 comparedPaths.Free();
493 delete comparedPaths;
501 list.background = background;
507 for(c = 0; c < _FileType::enumSize; c++)
509 fileIcons[c] = BitmapResource { fileIconNames[c], alphaBlend = true };
510 AddResource(fileIcons[c]);
517 for(c = 0; c < countOfCompIconNames; c++)
519 compIcons[c] = BitmapResource { compIconNames[c], alphaBlend = true };
520 AddResource(compIcons[c]);
524 DataField nameField { header = "Name", dataType = "FileSystemNode", width = 240, userData = this, freeData = false/*, editable = true*/; };
525 DataField pathField { header = "Location", dataType = /*"String"*/ "char *", width = 300, freeData = true };
526 DataField typeField { header = "Type", dataType = /*"String"*/ "char *", width = 40, freeData = false };
527 DataField sizeField { header = "Size", dataType = "FileSize", width = 96, alignment = right, freeData = false };
528 DataField modifiedField { header = "Modified", dataType = "SecSince1970", width = 96, alignment = right, freeData = false };
536 char wd[MAX_LOCATION];
537 GetWorkingDir(wd, sizeof(wd));
550 hasHorzScroll = true;
551 hasVertScroll = true;
552 fullRowSelect = false;
554 alwaysHighLight = true;
556 anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
558 // WHY is this not working ?
559 /*void OnResize(int width, int height)
561 if(vertScroll.visible)
562 nameField.width = width - vertScroll.size.w;
564 nameField.width = width;
567 bool NotifyCollapse(ListBox listBox, DataRow row, bool collapsed)
571 FileSystemNode node = (FileSystemNode)row.tag;
572 FileSystemNode child;
576 for(child = node.children.last; child; child = node.children.last)
578 listBox.DeleteRow(child.row);
582 node.childrenLoaded = false;
587 if(!node.bits.loaded || !node.bits.childrenLoaded)
590 //list.Sort(nameField, 1);
593 for(child = node.children.first; child && child.next; child = child.next);
595 child.EnsureVisible(false);
601 bool NotifyRightClick(ListBox listBox, int x, int y, Modifiers mods)
603 DataRow row = listBox.currentRow;
606 FileSystemNode node = (FileSystemNode)row.tag;
613 NotifyNodeMenu(master, this, menu, selection);
618 text = PrintString("Open ", node.name);
619 MenuItem { menu, text, o, NotifySelect = MenuOpen, disabled = false }; //delete text;
621 if(node.bits.isListItem/* && TODO: unless node is at root location*/)
623 MenuDivider { menu };
624 MenuItem { menu, "Replace by Parent\tCtrl+R", r, NotifySelect = MenuReplaceListItemByContainingDir, disabled = false };
626 else if(bits.mode == list)
628 MenuDivider { menu };
629 MenuItem { menu, "Replace List Item\tCtrl+R", r, NotifySelect = MenuReplaceListItemByChild, disabled = false };
631 MenuDivider { menu };
632 MenuItem { menu, "Cut\tCtrl+X", t, NotifySelect = null, disabled = false };
633 MenuItem { menu, "Copy\tCtrl+C", c, NotifySelect = null, disabled = false };
634 MenuItem { menu, "Paste\tCtrl+V", p, NotifySelect = null, disabled = false /*!clipboard*/ };
635 MenuItem { menu, "Delete\tDel", d, NotifySelect = null, disabled = false };
636 //MenuDivider { menu };
641 master = this, menu = menu,
643 x + clientStart.x + absPosition.x - guiApp.desktop.position.x,
644 y + clientStart.y + absPosition.y - guiApp.desktop.position.y }
652 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
657 selection.nodes.Free();
658 list.GetMultiSelection(rows);
659 for(item = rows.first; item; item = item.next)
661 DataRow row = item.data;
662 FileSystemNode node = (FileSystemNode)row.tag;
663 selection.nodes.Add(node);
668 selection.node = (FileSystemNode)row.tag;
670 selection.node = null;
672 if(selection.node && bits.preview)
675 FileSystemNode node = selection.node;
679 if(node && node.type == pictureFile)
682 bitmap.Load(node.path, null, displaySystem);
686 bitmaps = BitmapArray { };
687 for(pos = 0; pos < selectedItems.count; pos++)
690 selItem = (ExplorerFileItem)selectedItems._[pos];
691 bitmap.Load(selItem.path, null, displaySystem);
692 //bitmaps.Add(bitmap);
694 if(node && node.type == pictureFile)
697 bitmap.Load(node.path, null, displaySystem);
701 //NotifyItemSelect(master, view, item, selectedItems);
704 NotifyNodeSelect(listBox.parent.master, this, selection);
708 bool NotifyEditing(ListBox listBox, DataRow row)
712 //FileSystemNode node = (FileSystemNode)row.tag;
717 bool NotifyEdited(ListBox listBox, DataRow row)
721 //FileSystemNode node = (FileSystemNode)row.tag;
726 bool NotifyEditDone(ListBox listBox, DataRow row)
730 //FileSystemNode node = (FileSystemNode)row.tag;
735 bool NotifyDoubleClick(ListBox listBox, int x, int y, Modifiers mods)
737 bool result = !(selection.node && selection.node.type.isFolder && bits.navigateFolders);
742 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
744 //bool result = false;
745 if((SmartKey)key == enter)
746 /*result = */OpenNode();
748 else if((SmartKey)key == f2)
749 /*result = */RenameNode();
751 else if((SmartKey)key == f2)
753 FileSystemNode node = selection.node;
754 node.row.Edit(nameField);
778 anchor = Anchor { top = 0, right = 0, bottom = 0 };
780 void OnRedraw(Surface surface)
782 FileSystemBox fsb = (FileSystemBox)parent;
785 int wBmp = fsb.bitmap.width;
786 int hBmp = fsb.bitmap.height;
787 int wWnd = fsb.show.clientSize.w;
788 int hWnd = fsb.show.clientSize.h;
790 //int wList = 0;//fsb.list.size.w + fsb.split.size.w;
792 //float scale = Min((float)(wWnd - 10) / wBmp, (float)(hWnd - 10) / hBmp);
794 //int wDraw = (int)(wBmp * scale);
795 //int hDraw = (int)(hBmp * scale);
798 surface.Filter(fsb.bitmap, (wWnd - wDraw) / 2, (hWnd - hDraw) / 2, 0, 0, wDraw, hDraw, wBmp, hBmp);
800 // Until Filter / Stretch works with X
801 surface.Blit(fsb.bitmap, (wWnd - wBmp) / 2, (hWnd - hBmp) / 2, 0, 0, wBmp, hBmp);
806 surface.SetForeground(white);
807 surface.Area(0, 0, fsb.clientSize.w - 1, fsb.clientSize.h - 1);
815 FileSystemBoxSelection sel = this.selection.Copy();
816 //FileSystemNode node = selection.node;
817 for(node : sel.nodes)
820 if(node && node.type.isFolder && bits.navigateFolders)
821 property::path = node.path;
822 if(NotifyNodeOpen(this.master, this, sel) && !result)
833 //FileSystemBoxSelection selection = this.selection.Copy();
834 FileSystemNode node = selection.node;
835 //if(node && node.type.isFolder && bits.navigateFolders)
836 // property::path = node.path;
837 // ------------------------------------------- working here ---------------------------
839 /*result = NotifyNodeRename(this.master, this, node);
842 if(RenameFile(oldn, newn))
852 Menu editMenu { menu, "Edit", e };
855 editMenu, "Cut\tCtrl+X", t, disabled = true;
857 bool NotifySelect(MenuItem selection, Modifiers mods)
863 MenuItem itemEditCopy
865 editMenu, "Copy\tCtrl+C", c, disabled = true;
867 bool NotifySelect(MenuItem selection, Modifiers mods)
873 MenuItem itemEditPaste
875 editMenu, "Paste\tCtrl+V", p;
877 bool NotifySelect(MenuItem selection, Modifiers mods)
883 MenuItem itemEditDelete
885 editMenu, "Delete\tDel", d, disabled = true;
887 bool NotifySelect(MenuItem selection, Modifiers mods)
894 // WHY is this crashing ?
895 /*void OnResize(int width, int height)
897 if(this && nameField)
898 nameField.width = width - 80;
901 void ChangeViewType()
905 list.resizable = bits.details || bits.pathColumn;
906 list.moveFields = bits.details || bits.pathColumn;
907 list.hasHeader = bits.details || bits.pathColumn;
908 list.AddField(nameField);
910 list.AddField(pathField);
913 list.AddField(typeField);
914 list.AddField(sizeField);
915 list.AddField(modifiedField);
922 // this is crashing in for designer when details = true // can't save the file, always yields a crash
923 /*if(list && created)
926 list.AddField(nameField);
929 list.AddField(typeField);
930 list.AddField(sizeField);
934 if(comparedPaths && !bits.treeBranches)
938 FileAttribs pathAttribs = FileExists(path);
941 if(pathAttribs.isDirectory)
943 if(bits.treeBranches)
953 else if(pathAttribs.isFile) // we assume this is a file list
955 File f = FileOpen(path, read);
958 if(bits.treeBranches)
965 MessageBoxTodo($"unable to open file list");
968 MessageBoxTodo($"path is not a directory nor is it a file");
971 MessageBoxTodo($"path does not exist");
973 list.Sort(nameField, 1);
976 void LoadTreeDirectory()
978 bool isRoot = !strcmp(path, "/");
979 char name[MAX_LOCATION];
980 //FileSystemNode parent;
981 //FileSystemNode node;
982 //FileListing listing { path, extensions = extensions };
985 GetLastDirectory(path, name);
990 GetWorkingDir(startPath, sizeof(startPath));
992 strcpy(path, startPath);*/
993 bits.mode = directory;
1001 root = FileSystemNode { bits.loaded = true, bits.childrenLoaded = true };
1002 AddTreeNode(root, true, false, false, null);
1003 while(listing.Find())
1005 int len = strlen(listing.name);
1006 char info[MAX_LOCATION];
1007 char name[MAX_LOCATION];
1008 if(listing.stats.attribs.isDrive &&
1009 len > 3 && !strncmp(&listing.name[1], ": [", 3))
1011 strncpy(name, listing.name, 2);
1013 strncpy(info, &listing.name[4], len - 5);
1018 strcpy(name, listing.name);
1027 false, bits.previewPictures, false,
1030 parent.info = info; //CopyString(info);
1031 parent.bits.loaded = true;
1034 !listing.stats.attribs.isDirectory,
1036 listing.stats.attribs.isDirectory,
1038 if(!listing.stats.attribs.isDirectory)
1039 parent.bits.childrenLoaded = true;
1042 node = FileSystemNode { name = msNetwork, type = network };
1043 AddTreeNode(node, false, false, true, null);
1044 node.row.collapsed = true;
1050 FileGetStats(path, stats);
1051 root = MakeFileSystemNode(stats, name, path, false, bits.previewPictures, false, displaySystem);
1052 AddTreeNode(root, false, false, true, null);
1058 root.type = computer;
1059 root.label = rootName;
1062 list.Sort(nameField, 1);
1063 list.SelectRow(root.row);
1066 void LoadListDirectory()
1068 FileListing listing { path, extensions = extensions };
1070 bits.mode = directory;
1071 while(listing.Find())
1072 ProcessListItem(listing.name, listing.path, listing.stats, false);
1075 void LoadListFileList(File f)
1079 while(f.GetLine(line, 65536))
1082 char name[MAX_FILENAME];
1083 FileGetStats(line, stats);
1084 GetLastDirectory(line, name);
1085 ProcessListItem(name, line, stats, true);
1089 void LoadTreeFileList(File f)
1093 while(f.GetLine(line, 65536))
1096 char name[MAX_FILENAME];
1097 FileSystemNode node;
1098 FileGetStats(line, stats);
1099 GetLastDirectory(line, name);
1100 node = ProcessTreeItem(name, line, stats, node);
1104 void LoadListIterator()
1106 FileSystemIterator iterator = eInstance_New(iteratorClass);
1109 iterator.owner = this;
1110 iterator.OnObject = ListIterator_OnObject;
1111 //iterator.OnLeavingDirectory = ListIterator_OnLeavingDirectory;
1112 NotifyIteratorInit(master, this, iterator);
1113 iterator.Iterate(path, true);
1118 bool ListIterator_OnObject(const char * name, const char * path, FileStats stats, bool isRootObject)
1120 ProcessListItem(name, path, stats, false);
1124 //void ListIterator_OnLeavingDirectory(char * path) { }
1126 void ProcessListItem(const char * name, const char * path, FileStats stats, bool isListItem)
1128 if((!bits.foldersOnly && !bits.filesOnly) || (bits.foldersOnly && stats.attribs.isDirectory) || (bits.filesOnly && stats.attribs.isFile))
1130 FileSystemNode node = MakeFileSystemNode(stats, name, path, false, bits.previewPictures, isListItem, displaySystem);
1135 FileSystemNode ProcessTreeItem(char * name, char * path, FileStats stats, FileSystemNode parent)
1137 FileSystemNode node = MakeFileSystemNode(stats, name, path, false, bits.previewPictures, true, displaySystem);
1138 AddTreeNode(parent, false, false, true, null);
1139 //LoadTreeNode(node);
1143 void LoadTreeNode(FileSystemNode node)
1145 if(!node.bits.loaded)
1147 char path[MAX_LOCATION];
1150 FileListing listing { path, extensions = extensions };
1151 if(node.children.count == 1)
1152 DeleteNode(node.children.first);
1154 while(listing.Find())
1157 FileSystemNode child = null;
1158 if(!listing.stats.attribs.isRemovable && ((!bits.foldersOnly && !bits.filesOnly) ||
1159 (bits.foldersOnly && listing.stats.attribs.isDirectory) ||
1160 (bits.filesOnly && listing.stats.attribs.isFile)))
1161 child = MakeAndAddToTreeFileSystemNodeFromFileListing(listing, node);
1163 NodeChildLoad(child, node);
1169 node.bits.childrenLoaded = true;
1170 node.bits.loaded = true;
1171 node.row.SortSubRows(false);
1173 else if(!node.bits.childrenLoaded)
1175 FileSystemNode child;
1176 if(node.children.first)
1178 for(child = node.children.first; child; child = child.next)
1180 if(!child.bits.loaded)
1181 LoadTreeNode(child);
1182 else if(!child.bits.childrenLoaded)
1183 NodeChildLoad(child, node);
1185 node.bits.childrenLoaded = true;
1186 node.row.SortSubRows(false);
1191 void NodeChildLoad(FileSystemNode parent, FileSystemNode node)
1193 char path[MAX_LOCATION];
1194 parent.GetPath(path);
1195 if(bits.textFileLinesStyle && FileExists(path).isFile)
1202 FileListing listing { path, extensions = extensions };
1203 while(listing.Find())
1206 FileSystemNode child = null;
1207 if((!bits.foldersOnly && !bits.filesOnly) ||
1208 (bits.foldersOnly && listing.stats.attribs.isDirectory) ||
1209 (bits.filesOnly && listing.stats.attribs.isFile))
1210 child = MakeAndAddToTreeFileSystemNodeFromFileListing(listing, parent);
1224 parent.bits.childrenLoaded = true;
1227 void LoadComparedList()
1229 int c/*, cmp*/ /*, smallest*/, icon;//, equalCount;
1230 int count = comparedPaths ? comparedPaths.count : 0;
1231 //bool allDone = false;
1234 char path[MAX_LOCATION];
1235 //Array<ComparisonState> states { };
1236 //Array<FileListing> listings { };
1237 //Array<int> equals { };
1238 //Array<MapNode<String, int>> mapNodes { };
1240 //Array<Map<String, int>> lists { };
1241 //Map<int, bool> equals{ };
1244 MapNode<String, /*Map<int, */Array<int>> na;
1245 //MapNode<int, int> nb;
1246 Map<String, /*Map<int, */Array<int>> names { };
1247 //Map<String, Array<bool>> names { };
1248 //Map<String, bool[16]> names { }; // does not seem to be working
1249 //Map<String, BoolArrayInt> names { };
1251 for(c = 0; c < comparedPaths.count; c++)
1253 FileListing listing { comparedPaths[c], extensions = extensions };
1254 while(listing.Find())
1256 /*Map<int, int>*/Array<int> m = names[listing.name];
1259 names[listing.name] = m;
1260 /*/m[c] = */m.Add(c);
1263 /* // compiles and should work but better solution?
1264 for(c = 0; c < comparedPaths.count; c++)
1266 FileListing listing { comparedPaths[c], extensions = extensions };
1267 while(listing.Find())
1269 Array<bool> a = names[listing.name];
1272 names[listing.name] = a;
1277 /* // does not seem to be working
1278 for(c = 0; c < comparedPaths.count; c++)
1280 FileListing listing { comparedPaths[c], extensions = extensions };
1281 while(listing.Find())
1283 names[listing.name][c] = true;
1288 if(comparedPaths.count > 0)
1290 FileListing listing { comparedPaths[0], extensions = extensions };
1291 while(listing.Find())
1293 // should be able to just do names[listing.name]._0 = true;
1294 BoolArrayInt bai = names[listing.name];
1296 names[listing.name] = bai;
1299 if(comparedPaths.count > 1)
1301 FileListing listing { comparedPaths[1], extensions = extensions };
1302 while(listing.Find())
1304 // should be able to just do names[listing.name]._1 = true;
1305 BoolArrayInt bai = names[listing.name];
1307 names[listing.name] = bai;
1315 for(dirPath : comparedPaths)
1318 if(FileExists(dirPath).isDirectory)
1320 FileListing listing { dirPath, extensions = extensions };
1321 //MapNode<String, int> mn;
1322 Map<String, int> list { };
1323 //states.Add(listing.Find() == true ? matching : endOfListing);
1324 while(listing.Find())
1325 list[listing.name] = 0;
1326 //for(mn = ; mn; mn = mn.next)
1327 //mn = list.root.minimum;
1328 mapNodes.Add(/-*mn*-/list.root.minimum);
1330 //PrintLn(dirPath, " -- .Find() -- ", states[states.count-1] == matching ? listing.name : "endOfListing*");
1331 //listings.Add(listing);
1334 MapNode<String, int> mn;
1335 PrintLn("------------- DIR LISTING FOR ", dirPath);
1336 for(mn = list.root.minimum; mn; mn = mn.next)
1345 for(na = names.root.minimum; na; na = na.next)
1347 /*Map<int, */Array<int> equals = na.value;
1348 //MapNode<int, int> nb;
1354 for(c = 1; c < count; c++)
1356 //if(states[c] == endOfListing) continue;
1357 if(!mapNodes[c]) continue;
1358 // todo: use better comparison method
1359 // it should compare file type (dir/file) before
1360 // comparing file name.
1361 // should also provide alternative methods
1362 // of comparison including ones that consider
1363 // date changes as differences of some kind.
1364 // pethaps a OnCompare(a, b) to allow implementation
1365 // of custom methods of comparison.
1366 // note: this (or these) method(s) depend on files
1367 // being listed in sorted order by FileListing.
1368 // different comparison methods should have
1369 // appropriatly different sorting in FileListing.
1371 //cmp = strcmp(listings[smallest].name, listings[c].name);
1372 cmp = fstrcmp(mapNodes[smallest].key, mapNodes[c].key);
1373 PrintLn("COMPARING - ", mapNodes[smallest].key, " and ", mapNodes[c].key);
1386 if(equals.count == count) // all are equal, no diff icon
1391 else if(equals.count == count-1) // all are equal but one, not-sign icon for singled out missing
1395 for(nb = equals.root.minimum, i = 0; nb; nb = nb.next, i++)
1399 for(i = 0; i < equals.count; i++)
1408 if(i == equals.count)
1412 else if(equals.count == 1) // only one is present, all others missing, present-sign for singled out present
1414 //icon = equals.root.minimum.key+1;
1425 if(equals.count == count) // all are equal, no diff icon
1427 else if(count/2 - equals.count < 0) // more than half are equal, use not-sign icons for all missing
1429 else // less than half are equal, use present-sign icons for all present
1433 /*if((!bits.foldersOnly && !bits.filesOnly) ||
1434 (bits.foldersOnly && listings[smallest].stats.attribs.isDirectory) ||
1435 (bits.filesOnly && listings[smallest].stats.attribs.isFile))*/
1436 strcpy(path, comparedPaths[/*smallest*/equals[0]]);
1437 PathCat(path, /*mapNodes[smallest].key*/na.key);
1438 FileGetStats(path, stats);
1439 if((!bits.foldersOnly && !bits.filesOnly) ||
1440 (bits.foldersOnly && stats.attribs.isDirectory) ||
1441 (bits.filesOnly && stats.attribs.isFile))
1443 FileSystemNode node =
1444 MakeComparedFileSystemNode(
1446 /*mapNodes[smallest].key*/na.key,
1448 false, bits.previewPictures,
1456 mapNodes[equal] = mapNodes[equal].next;
1457 //states[equal] = listings[equal].Find() == true ? matching : endOfListing;
1458 //PrintLn(comparedPaths[equal], " -- .Find() -- ", states[equal] == matching ? listings[equal].name : "endOfListing*");
1461 //for(c = 0; c < count && states[c] == endOfListing; c++);
1462 for(c = 0; c < count && !mapNodes[c]; c++);
1467 list.Sort(nameField, 1);
1470 void AddNode(FileSystemNode node)
1472 DataRow row = list.AddRow();
1473 row.tag = (intptr)node;
1476 row.SetData(nameField, node);
1479 char path[MAX_LOCATION];
1480 StripLastDirectory(node.path, path);
1481 row.SetData(pathField, CopyString(path));
1485 if(node.type.isFile)
1487 row.SetData(typeField, node.extension);
1488 row.SetData(sizeField, /*(void *)*/node.stats.size);
1490 row.SetData(modifiedField, node.stats.modified);
1494 FileSystemNode MakeAndAddToTreeFileSystemNodeFromFileListing(FileListing listing, FileSystemNode parent)
1496 FileSystemNode result = null;
1497 /*if((!bits.foldersOnly && !bits.filesOnly) ||
1498 (bits.foldersOnly && listing.stats.attribs.isDirectory) ||
1499 (bits.filesOnly && listing.stats.attribs.isFile))*/
1500 /*if(!listing.stats.attribs.isRemovable && ((!bits.foldersOnly && !bits.filesOnly) ||
1501 (bits.foldersOnly && listing.stats.attribs.isDirectory) ||
1502 (bits.filesOnly && listing.stats.attribs.isFile)))*/
1504 bool textFileLinesStyle = false;
1505 const char * test = listing.name;
1508 result = MakeFileSystemNode(listing.stats, listing.name, listing.path, false, bits.previewPictures, false, displaySystem);
1512 if(bits.textFileLinesStyle)
1514 char ext[MAX_LOCATION];
1515 GetExtension(listing.name, ext);
1516 if(!strcmpi(ext, "txt") || !strcmpi(ext, "text"))
1517 textFileLinesStyle = true;
1519 //AddTreeNode(result, true, false, textFileLinesStyle, parent);
1520 AddTreeNode(result, !textFileLinesStyle && listing.stats.attribs.isFile, false, !listing.stats.attribs.isFile || textFileLinesStyle, parent);
1529 FileSystemNode node,
1531 bool childrenLoaded,
1533 FileSystemNode addTo)
1535 DataRow row = (addTo && addTo.row) ? addTo.row.AddRow() : list.AddRow();
1538 node.parent = addTo;
1539 node.indent = addTo.indent + 1;
1540 addTo.children.Add(node);
1542 row.tag = (intptr)node;
1544 row.SetData(null, node);
1547 char path[MAX_LOCATION];
1548 StripLastDirectory(node.path, path);
1549 row.SetData(pathField, CopyString(path));
1553 if(node.type.isFile)
1555 row.SetData(typeField, node.extension);
1556 row.SetData(sizeField, /*(void *)*/node.stats.size);
1558 row.SetData(modifiedField, node.stats.modified);
1561 node.bits.loaded = loaded;
1562 node.bits.childrenLoaded = childrenLoaded;
1564 //AddTreeNode(FileSystemNode { }, false, false, node); // why would this create a compile error?
1565 AddTreeNode(FileSystemNode { type = none, name = "Loader" }, false, false, false, node);
1567 if(node.indent > 0 || bits.mode == list)
1568 row.collapsed = true;
1569 else if(node.type == folder)
1570 node.type = folderOpen;
1573 void DeleteNode(FileSystemNode node)
1575 FileSystemNode child;
1578 for(; (child = node.children.first); )
1581 list.DeleteRow(node.row);
1588 enum ComparisonState { endOfListing, matching };
1592 class ExplorerView : FileSystemBox
1595 hasHorzScroll = false;
1596 hasVertScroll = false;
1598 virtual void Load(FileSystemNode parent);
1599 virtual void Refresh();
1601 virtual void LaunchNotifyItemSelect(Window master, ExplorerView view, ExplorerFileItem item, ExplorerFileItemArray selectedItems)
1603 view.NotifyItemSelect(master, view, item, selectedItems);
1606 virtual bool Window::NotifyItemSelect(ExplorerView view, ExplorerFileItem item, ExplorerFileItemArray selectedItems);
1607 virtual bool Window::NotifyItemOpen(ExplorerView view, ExplorerFileItem item);
1611 master = master, parent = this;
1614 hasHorzScroll = true;
1615 hasVertScroll = true;
1618 fullRowSelect = false;
1621 anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
1623 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
1625 ExplorerView view = (ExplorerView)listBox.parent;
1626 if(listBox.currentRow)
1629 ExplorerFileItemArray selectedItems { growingFactor = 16 };
1630 for(listRow = listBox.firstRow; listRow; listRow = listRow.next)
1631 if(listRow.selected)
1632 selectedItems.Add((ExplorerFileItem)listRow.tag);
1633 //view.NotifyItemSelect(listBox.parent.master, view, (ExplorerFileItem)listBox.currentRow.tag);
1634 view.LaunchNotifyItemSelect(listBox.parent.master, view, (ExplorerFileItem)listBox.currentRow.tag, selectedItems);
1639 bool NotifyDoubleClick(ListBox listBox, int x, int y, Modifiers mods)
1641 ExplorerView view = (ExplorerView)listBox.parent;
1642 view.NotifyItemOpen(listBox.parent.master, view, (ExplorerFileItem)listBox.currentRow.tag);
1646 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
1648 if((SmartKey)key == enter)
1650 ExplorerView view = (ExplorerView)listBox.parent;
1651 view.NotifyItemOpen(listBox.parent.master, view, (ExplorerFileItem)listBox.currentRow.tag);
1664 class ExplorerViewList : ExplorerView
1667 FileSystemNode location;
1671 DataField nameField { header = "Name", dataType = "ExplorerFileItem", width = 304, editable = true, userData = this };
1673 ExplorerViewDetails()
1675 list.AddField(nameField);
1683 void Load(FileSystemNode location)
1685 char path[MAX_LOCATION];
1686 this.location = location;
1687 location.GetPath(path);
1689 FileListing listing { path };
1691 ExplorerFileItem item;
1696 while(listing.Find())
1698 item = MakeFileItem(listing.stats.attribs, listing.name, listing.path, previewPictures, displaySystem);
1700 row = list.AddRow();
1701 row.tag = (int)item;
1702 row.SetData(nameField, item);
1704 list.Sort(nameField, 1);
1711 class ExplorerViewDetails : ExplorerView
1713 list.hasHeader = true;
1714 list.moveFields = true;
1715 list.resizable = true;
1716 list.sortable = true;
1718 FileSystemNode location;
1722 DataField nameField { header = "Name", dataType = "ExplorerFileItem", width = 304, editable = true, userData = this };
1723 DataField typeField { header = "Type", dataType = /-*"String"*-/ "char *", width = 40 };
1724 DataField sizeField { header = "Size", dataType = "FileSize", width = 96, alignment = right };
1726 ExplorerViewDetails()
1728 list.AddField(nameField);
1729 list.AddField(typeField);
1730 list.AddField(sizeField);
1738 void Load(FileSystemNode location)
1740 char path[MAX_LOCATION];
1741 this.location = location;
1742 location.GetPath(path);
1744 FileListing listing { path };
1746 ExplorerFileItem item;
1751 while(listing.Find())
1753 item = MakeFileItem(listing.stats.attribs, listing.name, listing.path, previewPictures, displaySystem);
1755 row = list.AddRow();
1756 row.tag = (int)item;
1757 row.SetData(nameField, item);
1758 row.SetData(typeField, CopyString(item.extension));
1759 row.SetData(sizeField, (uint)listing.stats.size);
1761 list.Sort(nameField, 1);
1768 class ExplorerViewIcons : ExplorerView
1771 FileSystemNode location;
1775 DataField nameField { header = "Name", dataType = "ExplorerFileItem", width = 304, editable = true, userData = this };
1777 ExplorerViewDetails()
1779 list.AddField(nameField);
1787 void Load(FileSystemNode location)
1789 char path[MAX_LOCATION];
1790 this.location = location;
1791 location.GetPath(path);
1793 FileListing listing { path };
1795 ExplorerFileItem item;
1800 while(listing.Find())
1802 item = MakeFileItem(listing.stats.attribs, listing.name, listing.path, previewPictures, displaySystem);
1804 row = list.AddRow();
1805 row.tag = (int)item;
1806 row.SetData(nameField, item);
1808 list.Sort(nameField, 1);
1815 class ExplorerViewCards : ExplorerView
1818 FileSystemNode location;
1822 DataField nameField { header = "Name", dataType = "ExplorerFileItem", width = 304, editable = true, userData = this };
1824 ExplorerViewDetails()
1826 list.AddField(nameField);
1834 void Load(FileSystemNode location)
1836 char path[MAX_LOCATION];
1837 this.location = location;
1838 location.GetPath(path);
1840 FileListing listing { path };
1842 ExplorerFileItem item;
1847 while(listing.Find())
1849 item = MakeFileItem(listing.stats.attribs, listing.name, listing.path, previewPictures, displaySystem);
1851 row = list.AddRow();
1852 row.tag = (int)item;
1853 row.SetData(nameField, item);
1855 list.Sort(nameField, 1);
1862 public class BitmapArray : RedjArray
1864 type = class(Bitmap);
1867 Bitmap * Add(Bitmap bitmap)
1874 Bitmap * AddBefore(uint position, Bitmap bitmap)
1876 Insert(position, 1);
1877 _[position] = bitmap;
1878 return &_[position];
1883 for(c = 0; c < _count; c++)
1895 class ExplorerViewShowcase : ExplorerView
1897 list.anchor = Anchor { left = 0, top = 0, bottom = 0 };
1898 list.size = Size { w = 200 };
1900 FileSystemNode location;
1904 DataField nameField { header = "Name", dataType = "ExplorerFileItem", width = 180, editable = true, userData = this };
1907 BitmapArray bitmaps { growingFactor = 16 };
1913 anchor = Anchor { top = 0, right = 0, bottom = 0 };
1915 void OnRedraw(Surface surface)
1917 ExplorerViewShowcase view = (ExplorerViewShowcase)parent;
1920 int wBmp = view.bitmap.width;
1921 int hBmp = view.bitmap.height;
1922 int wWnd = clientSize.w;
1923 int hWnd = clientSize.h;
1925 int wList = view.list.size.w + view.split.size.w;
1927 float scale = Min((float)(wWnd - 10) / wBmp, (float)(hWnd - 10) / hBmp);
1929 int wDraw = (int)(wBmp * scale);
1930 int hDraw = (int)(hBmp * scale);
1933 surface.Filter(view.bitmap, (wWnd - wDraw) / 2, (hWnd - hDraw) / 2, 0, 0, wDraw, hDraw, wBmp, hBmp);
1935 // Until Filter / Stretch works with X
1936 surface.Blit(view.bitmap, (wWnd - wDraw) / 2, (hWnd - hDraw) / 2, 0, 0, wDraw, hDraw);
1941 surface.SetForeground(white);
1942 surface.Area(0, 0, view.clientSize.w - 1, view.clientSize.h - 1);
1956 ExplorerViewDetails()
1958 list.AddField(nameField);
1961 void LaunchNotifyItemSelect(Window master, ExplorerViewShowcase view, ExplorerFileItem item, ExplorerFileItemArray selectedItems)
1964 ExplorerFileItem selItem;
1968 if(item && item.type == pictureFile)
1970 view.bitmap = Bitmap { };
1971 view.bitmap.Load(item.path, null, displaySystem);
1974 view.bitmaps.Clear();
1975 view.bitmaps = BitmapArray { };
1976 for(pos = 0; pos < selectedItems.count; pos++)
1979 selItem = (ExplorerFileItem)selectedItems._[pos];
1980 bitmap.Load(selItem.path, null, displaySystem);
1981 //view.bitmaps.Add(bitmap);
1983 if(item && item.type == pictureFile)
1985 view.bitmap = Bitmap { };
1986 view.bitmap.Load(item.path, null, displaySystem);
1989 view.show.Update(null);
1990 view.NotifyItemSelect(master, view, item, selectedItems);
1998 void Load(FileSystemNode location)
2000 char path[MAX_LOCATION];
2001 this.location = location;
2002 location.GetPath(path);
2004 FileListing listing { path };
2006 ExplorerFileItem item;
2011 while(listing.Find())
2013 item = MakeFileItem(listing.stats.attribs, listing.name, listing.path, previewPictures, displaySystem);
2015 row = list.AddRow();
2016 row.tag = (int)item;
2017 row.SetData(nameField, item);
2019 list.Sort(nameField, 1);
2026 class ExplorerTree : FileSystemBox
2028 hasHorzScroll = false;
2029 hasVertScroll = false;
2035 DataField nameField { dataType = "FileSystemNode", width = 240, userData = this };
2037 FileSystemNode root;
2038 FileSystemNode selection;
2040 virtual bool Window::NotifyNodeSelect(ExplorerTree tree, FileSystemNode node);
2042 property FileSystemNode node
2048 if(!tree.currentRow)
2050 if(!tree.currentRow.tag)
2052 return (FileSystemNode)tree.currentRow.tag;
2056 void Select(FileSystemNode node)
2060 node.EnsureVisible(false);
2061 tree.SelectRow(node.row);
2065 FileSystemNode Find(const char * name, FileSystemNode parent)
2067 FileSystemNode node;
2068 FileSystemNode start = parent ? parent : root;
2069 if(!start.loaded || !start.childrenLoaded)
2070 LoadTreeNode(start, tree);
2071 for(node = start.children.first; node; node = node.next)
2072 if(node.name && !strcmpi(node.name, name))
2079 master = master, parent = this;
2082 hasHorzScroll = true;
2083 hasVertScroll = true;
2084 fullRowSelect = false;
2086 collapseControl = true;
2087 rootCollapseButton = true;
2089 anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
2091 // WHY is this not working ?
2092 /-*void OnResize(int width, int height)
2094 if(vertScroll.visible)
2095 nameField.width = width - vertScroll.size.w;
2097 nameField.width = width;
2100 bool NotifyCollapse(ListBox listBox, DataRow row, bool collapsed)
2104 FileSystemNode node = (FileSystemNode)row.tag;
2105 FileSystemNode child;
2109 for(child = node.children.last; child; child = node.children.last)
2111 listBox.DeleteRow(child.row);
2115 node.childrenLoaded = false;
2120 if(!node.loaded || !node.childrenLoaded)
2121 LoadTreeNode(node, tree);
2122 for(child = node.children.first; child && child.next; child = child.next);
2124 child.EnsureVisible(false);
2130 bool NotifyRightClick(ListBox listBox, int x, int y, Modifiers mods)
2132 DataRow row = listBox.currentRow;
2135 FileSystemNode node = (FileSystemNode)row.tag;
2141 MenuItem { menu, "Cut\tCtrl+X", t, NotifySelect = null, disabled = false };
2142 MenuItem { menu, "Copy\tCtrl+C", c, NotifySelect = null, disabled = false };
2143 MenuItem { menu, "Paste\tCtrl+V", p, NotifySelect = null, disabled = false /-*!clipboard*-/ };
2144 MenuItem { menu, "Delete\tDel", d, NotifySelect = null, disabled = false };
2145 //MenuDivider { menu };
2149 master = this, menu = menu,
2151 x + clientStart.x + absPosition.x - guiApp.desktop.position.x,
2152 y + clientStart.y + absPosition.y - guiApp.desktop.position.y }
2160 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
2164 FileSystemNode node = (FileSystemNode)row.tag;
2165 NotifyNodeSelect(listBox.parent.master, this, node);
2171 bool NotifyEditing(ListBox listBox, DataRow row)
2175 FileSystemNode node = (FileSystemNode)row.tag;
2180 bool NotifyEdited(ListBox listBox, DataRow row)
2184 FileSystemNode node = (FileSystemNode)row.tag;
2189 bool NotifyEditDone(ListBox listBox, DataRow row)
2193 FileSystemNode node = (FileSystemNode)row.tag;
2200 Menu editMenu { menu, "Edit", e };
2201 MenuItem itemEditCut
2203 editMenu, "Cut\tCtrl+X", t, disabled = true;
2205 bool NotifySelect(MenuItem selection, Modifiers mods)
2211 MenuItem itemEditCopy
2213 editMenu, "Copy\tCtrl+C", c, disabled = true;
2215 bool NotifySelect(MenuItem selection, Modifiers mods)
2221 MenuItem itemEditPaste
2223 editMenu, "Paste\tCtrl+V", p;
2225 bool NotifySelect(MenuItem selection, Modifiers mods)
2231 MenuItem itemEditDelete
2233 editMenu, "Delete\tDel", d, disabled = true;
2235 bool NotifySelect(MenuItem selection, Modifiers mods)
2242 // WHY is this crashing ?
2243 /-*void OnResize(int width, int height)
2245 if(this && nameField)
2246 nameField.width = width - 80;
2251 tree.AddField(nameField);
2256 FileSystemNode parent;
2257 FileSystemNode node;
2258 FileListing listing { "/" };
2262 root = FileSystemNode { type = computer, loaded = true, childrenLoaded = true };
2264 root.name = rootName;
2268 AddTreeNode(root, true, false, false, null, tree);
2270 // How can this make sense for linux?
2272 while(listing.Find())
2274 int len = strlen(listing.name);
2275 char info[MAX_LOCATION];
2276 char name[MAX_LOCATION];
2277 if(listing.stats.attribs.isDrive &&
2278 len > 3 && !strncmp(&listing.name[1], ": [", 3))
2280 strncpy(name, listing.name, 2);
2282 strncpy(info, &listing.name[4], len - 5);
2287 strcpy(name, listing.name);
2291 parent = MakeFileSystemNode(listing.stats, name);
2293 parent.info = CopyString(info);
2294 parent.loaded = true;
2295 AddTreeNode(parent, !listing.stats.attribs.isDirectory, false, listing.stats.attribs.isDirectory, root, tree);
2296 if(!listing.stats.attribs.isDirectory)
2297 parent.childrenLoaded = true;
2300 node = FileSystemNode { name = msNetwork, type = network };
2301 AddTreeNode(node, false, false, true, null, tree);
2302 node.row.collapsed = true;
2303 tree.Sort(nameField, 1);
2304 tree.SelectRow(root.row);
2309 public class ClipBoardFiles
2323 int size = SelSize();
2326 // Try to allocate memory
2327 ClipBoard clipBoard { };
2328 if(clipBoard.Allocate(size+1))
2330 GetSel(clipBoard.memory, true);
2343 ClipBoard clipBoard { };
2344 if(clipBoard.Load())
2345 PutS(clipBoard.memory);
2356 SetViewToCursor(true);
2362 Private Type DROPFILES
2368 For iCounter = 0 To filelist.ListCount - 1
2369 If filelist.Selected(iCounter) = True Then
2370 strFiles = strFiles & FixPath(filelist.Path) & filelist.List(iCounter) & vbNullChar
2373 'all selected items are now put in strFiles
2375 hGlobal = GlobalAlloc(GHND, Len(DF) + Len(strFiles)) 'put all files to a exclusive number
2376 If hGlobal Then 'if the globalalloc worked
2377 lpGlobal = GlobalLock(hGlobal) 'lock the hGlobal
2378 DF.pFiles = Len(DF) 'set the size of the files
2380 Call CopyMem(ByVal lpGlobal, DF, Len(DF)) 'copy df to the lpglobal
2381 Call CopyMem(ByVal (lpGlobal + Len(DF)), ByVal strFiles, Len(strFiles)) 'copy strfiles to lpglobal
2382 Call GlobalUnlock(hGlobal) 'unlock hglobal again
2384 SetClipboardData CF_HDROP, hGlobal 'put files to the clipboard
2387 bool SaveFile(const char * filePath)
2393 public class FileTreeNodeBSArray : ArrayBinarySorted
2395 type = class(FileSystemNode);
2397 FileSystemNode * const _;
2398 BSloc Add(FileSystemNode item)
2400 BSloc result = Find(item);
2403 Insert(result.pos, 1);
2404 _[result.pos] = item;
2408 BSloc Remove(FileSystemNode item)
2416 public class FileTreeNodeArray : RedjArray
2418 type = class(FileSystemNode);
2420 FileSystemNode * const _;
2421 FileSystemNode * Add(FileSystemNode item)
2428 FileSystemNode * AddBefore(uint position, FileSystemNode item)
2430 Insert(position, 1);
2432 return &_[position];
2438 public class ExplorerFileItem : struct
2449 void OnDisplay(Surface surface, int x, int y, int width, FileSystemBox control, Alignment alignment, DataDisplayFlags displayFlags)
2451 int indentSize = (displayFlags.dropBox) ? 0 : 10;
2454 char label[MAX_FILENAME];
2456 //float scale = Min((float)clientSize.w / (float)bitmap.width, (float)clientSize.h / (float)bitmap.height);
2457 int w = 16; //(int)(bitmap.width * scale);
2458 int h = 16; //(int)(bitmap.height * scale);
2462 icon = control.fileIcons[type].bitmap;
2465 if(type == folder || type == folderOpen)
2466 surface.SetForeground(red); //Color { 170, 170, 0 } // REDJ What is that color?
2469 textOffset = indent * indentSize + (icon ? (icon.width + 6) : 0);
2472 sprintf(label, "%s [%s]", name, info);
2474 strcpy(label, name);
2475 len = strlen(label);
2477 surface.WriteTextDots
2478 (alignment, x + textOffset, y + 2, width - textOffset, label, len);
2479 if(type == pictureFile && control.previewPictures && bitmap)
2482 //surface.Filter(bitmap, (clientSize.w - w) / 2,(clientSize.h - h) / 2, 0,0, w, h, bitmap.width, bitmap.height);
2483 surface.Filter(bitmap, x + indent * indentSize + 2, y, 0, 0, w, h, bitmap.width, bitmap.height);
2485 // Until Filter / Stretch works with X
2486 //surface.Blit(bitmap, (clientSize.w - bitmap.width) / 2,(clientSize.h - bitmap.height) / 2, 0,0, bitmap.width, bitmap.height);
2487 surface.blend = true;
2488 surface.Blit(bitmap, x + indent * indentSize + 2, y,0,0, w, h);
2494 surface.Blit(icon, x + indent * indentSize + 2, y,0,0, icon.width, icon.height);
2497 int OnCompare(ExplorerFileItem b)
2500 if(type == b.type || (type < folder && b.type < folder) || (type >= drive))
2501 result = strcmpi(name, b.name);
2504 if(type == folder && b.type < folder) result = -1;
2505 else if(type < folder && b.type == folder) result = 1;
2510 void OnCopy(ExplorerFileItem newData)
2512 type = newData.type;
2513 indent = newData.indent;
2516 int len = strlen(newData.name) + 1;
2517 name = new char[len];
2518 CopyBytes(name, newData.name, len);
2522 bool OnGetDataFromString(char * string)
2524 int len = strlen(string) + 1;
2525 name = new char[len];
2526 CopyBytes(name, string, len);
2540 char * OnGetString(char * string, void * fieldData, bool * needClass)
2546 public class ExplorerFileItemArray : RedjArray
2548 type = class(ExplorerFileItem);
2550 ExplorerFileItem * const _;
2551 ExplorerFileItem * Add(ExplorerFileItem item)
2558 ExplorerFileItem * AddBefore(uint position, ExplorerFileItem item)
2560 Insert(position, 1);
2562 return &_[position];
2567 for(c = 0; c < _count; c++)
2577 ExplorerFileItem MakeFileItem(const FileAttribs attribs, const char * fileName, const char * filePath, const bool previewPicture, const DisplaySystem displaySystem)
2579 int len = strlen(fileName);
2580 char info[MAX_LOCATION];
2581 char name[MAX_LOCATION];
2582 char extension[MAX_EXTENSION];
2584 ExplorerFileItem item { };
2586 //if(stats.attribs.isFile) // -- should work now
2587 if(attribs.isDirectory)
2591 item.type = (attribs.isDrive) ? drive : folder;
2592 if(attribs.isServer)
2598 if(attribs.isRemote)
2599 item.type = netDrive;
2600 if(attribs.isRemovable)
2602 if(fileName[0] == 'A' || fileName[0] == 'B')
2605 item.type = removable;
2610 GetExtension(fileName, extension);
2611 //strupr(extension);
2614 item.type = _FileType::SelectByExtension(extension);
2617 if(attribs.isDrive &&
2618 len > 3 && !strncmp(&fileName[1], ": [", 3))
2620 strncpy(name, fileName, 2);
2622 strncpy(info, &fileName[4], len - 5);
2627 strcpy(name, fileName);
2631 item.path = CopyString(filePath);
2632 item.name = CopyString(name);
2634 item.info = CopyString(info);
2635 item.extension = CopyString(extension);
2637 if(item.type == pictureFile && previewPicture)
2639 item.bitmap = Bitmap { };
2640 item.bitmap.Load(filePath, null, displaySystem);
2648 public class FileSystemBoxSelection
2651 FileSystemNode node;
2652 Array<FileSystemNode> nodes { };
2655 FileSystemBoxSelection Copy()
2657 FileSystemBoxSelection copy { node = node };
2660 copy.nodes.Add(node);
2666 ~FileSystemBoxSelection()
2672 class FileSystemNodeBits
2674 bool loaded:1, childrenLoaded:1, isListItem:1;
2677 public class FileSystemNode
2681 FileSystemNodeBits bits;
2694 /* LinkElement<FileSystemNode> link;
2695 FileSystemNode parent;
2697 FileSystemNodeType type;
2701 FileSystemNode prev, next;
2705 property bool isListItem { set { bits.isListItem = value; } get { return bits.isListItem; } };
2707 property const char * path
2709 set { delete path; if(value && value[0]) path = CopyString(value); }
2710 get { return path; } isset { return path && path[0]; }
2712 property const char * name
2714 set { delete name; if(value && value[0]) name = CopyString(value); }
2715 get { return name; } isset { return name && name[0]; }
2717 property char * extension
2719 set { delete extension; if(value && value[0]) extension = CopyString(value); }
2720 get { return extension; } isset { return extension && extension[0]; }
2722 property const char * label
2724 set { delete label; if(value && value[0]) label = CopyString(value); }
2725 get { return label; } isset { return label && label[0]; }
2727 property const char * info
2729 set { delete info; if(value && value[0]) info = CopyString(value); }
2730 get { return info; } isset { return info && info[0]; }
2736 FileSystemNode parent;
2744 Array<int> exists; // would use (see) BoolArrayInt to pack this into an int if could be accessed as an array
2746 void GetPath(String outputPath)
2749 strcpy(outputPath, path);
2754 strcpy(outputPath, name);
2755 for(up = parent; up; up = up.parent)
2757 char temp[MAX_LOCATION];
2758 strcpy(temp, up.name);
2759 PathCat(temp, outputPath);
2760 strcpy(outputPath, temp);
2764 strcpy(outputPath, name ? name : "");
2767 bool IsChildOf(FileSystemNode node)
2769 FileSystemNode test;
2770 for(test = parent; test; test = test.parent)
2776 void DuplicateChildren(bool recursive, bool forceExpanded, FileSystemNode addTo, FileSystemBox fsb)
2780 FileSystemNode child;
2782 for(child = children.first; child; child = child.next)
2784 FileSystemNode copy { };
2785 copy.name = child.name; //CopyString(child.name);
2786 copy.type = child.type;
2787 fsb.AddTreeNode(copy, child.bits.loaded, false, false, addTo);
2789 copy.row.collapsed = false;
2791 child.DuplicateChildren(recursive, forceExpanded, copy, fsb);
2796 void EnsureVisible(bool expand)
2799 parent.EnsureVisible(true);
2801 row.collapsed = false;
2802 // TODO: row.EnsureVisible(); // making the row visible by scrolling
2812 FileSystemNode child;
2813 for(; (child = children.first); )
2816 children.Delete(child);
2830 parent.children.Delete(this);
2833 void OnDisplay(Surface surface, int x, int y, int width, FileSystemBox fsb, Alignment alignment, DataDisplayFlags displayFlags)
2835 //int indentSize = (displayFlags.dropBox) ? 0 : 10;
2842 char text[MAX_LOCATION];
2852 comp = fsb.comparedPaths && fsb.comparedPaths.count > 1;
2854 icon = fsb.fileIcons[type].bitmap;
2855 alt = bits.isListItem ? path : name;
2856 if(comp && !fsb.bits.columnsCompareStyle && cmpIcon)
2859 diffIcon = Bitmap { };
2860 diffIcon.AllocateDD(
2861 surface.display.displaySystem,
2862 fsb.compIcons[cmpIcon].bitmap.width,
2863 fsb.compIcons[cmpIcon].bitmap.height);
2864 if(fsb.compIcons[cmpIcon].bitmap)
2865 diffIcon.Copy(fsb.compIcons[cmpIcon].bitmap);
2867 diffIcon = fsb.compIcons[cmpIcon-1].bitmap;
2868 notIcon = fsb.compIcons[countOfCompIconNames-1].bitmap;
2870 //xStart = indent * indent + x + (icon ? (icon.width + 5) : 0);
2871 xStart = x + (icon ? (icon.width + 5) : 0) + (comp ? 18*(fsb.bits.columnsCompareStyle ? fsb.comparedPaths.count : 1) : 0);
2877 sprintf(text, "%s [%s]", label ? label : alt, info);
2879 strcpy(text, label ? label : alt); //"%d-%d/%s", stats.inode, stats.nlink
2880 //sprintf(text, "%d-%d/%s", stats.inode, stats.nlink, label ? label : alt);
2885 if(type == folder || type == folderOpen)
2886 surface.SetForeground(yellow);
2890 //textOffset = indent * indentSize + (icon ? (icon.width + 4) : 0);
2892 surface.SetForeground(displayFlags.selected ? fsb.selectionText : fsb.foreground);
2893 surface.TextOpacity(false);
2894 surface.TextExtent(text, len, &w, &h);
2897 // Draw the current row stipple
2898 if(displayFlags.selected)
2899 //surface.Area(xStart - 1, y, xStart - 1, y + h - 1);
2900 //surface.Area(xStart + w - 1, y, xStart + w + 1, y + h - 1);
2901 surface.Area(xStart - 3, y, xStart + w + 1, y + h - 1);
2902 //surface.WriteTextDots(alignment, x + textOffset, y + 2, width - textOffset, alt, strlen(alt));
2903 surface.WriteTextDots(alignment, xStart, y + 2, width, text, len);
2905 if(!guiApp.textMode)
2907 if(displayFlags.current)
2909 if(displayFlags.active)
2911 surface.LineStipple(0x5555);
2912 if(displayFlags.selected)
2913 surface.SetForeground(0xFFFFFF80);
2915 surface.SetForeground(black);
2919 surface.SetForeground(selectionColor);
2921 surface.Rectangle(xStart - 3, y, xStart + w + 1, y + h - 1);
2922 surface.LineStipple(0);
2927 if(!fsb.bits.columnsCompareStyle && diffIcon)
2930 h = diffIcon.height;
2931 /*if(cmpNot && notIcon)
2933 Surface s = diffIcon.GetSurface(0,0, {w,h});
2934 s.SetForeground(white);
2935 s.Blit(notIcon, x,y, 0,0, w,h);
2938 surface.SetForeground(white);
2939 surface.Blit(diffIcon, x,y, 0,0, w,h);
2940 if(cmpNot && notIcon)
2941 surface.Blit(notIcon, x,y, 0,0, w,h);
2945 else if(fsb.bits.columnsCompareStyle && exists && exists.count)
2948 for(c = d = 0; c < fsb.comparedPaths.count; c++)
2950 if(d == exists.count || exists[d] != c)
2954 diffIcon = fsb.compIcons[c].bitmap;
2958 h = diffIcon.height;
2959 surface.SetForeground(white);
2960 surface.Blit(diffIcon, x,y, 0,0, w,h);
2967 for(c = d = 0; c < exists.count; c++)
2972 x+=18*(exists[c]-d);
2976 diffIcon = fsb.compIcons[exists[c]].bitmap;
2980 h = diffIcon.height;
2981 surface.SetForeground(white);
2982 surface.Blit(diffIcon, x,y, 0,0, w,h);
2988 if(exists.count < fsb.comparedPaths.count && exists[exists.count-1] != d)
2990 x+=18*(exists[exists.count-1]-d);
2994 else if(fsb.bits.columnsCompareStyle)
2996 x+=18*fsb.comparedPaths.count;
3004 if(type == pictureFile && fsb.previewPictures && bitmap)
3006 surface.SetForeground(white);
3007 surface.blend = true;
3009 //surface.Filter(bitmap, (clientSize.w - w) / 2,(clientSize.h - h) / 2, 0,0, w, h, bitmap.width, bitmap.height);
3010 //surface.Filter(bitmap, x + indent/* * indentSize*/ + 2, y, 0, 0, w, h, bitmap.width, bitmap.height);
3011 surface.Filter(bitmap, x,y,0,0, w, h, bitmap.width, bitmap.height);
3013 // Until Filter / Stretch works with X
3014 //surface.Blit(bitmap, (clientSize.w - bitmap.width) / 2,(clientSize.h - bitmap.height) / 2, 0,0, bitmap.width, bitmap.height);
3015 // surface.blend = true;
3016 //surface.Blit(bitmap, x + indent/* * indentSize*/ + 2, y,0,0, w, h);
3017 //surface.Blit(bitmap, x,y,0,0, bitmap.width, bitmap.height);
3024 //surface.blend = true;
3025 //surface.alphaWrite = blend;
3026 surface.SetForeground(white);
3027 //surface.Blit(icon, x + indent * indentSize, y,0,0, icon.width, icon.height);
3028 surface.Blit(icon, x,y, 0,0, w,h);
3033 Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
3037 dataBox, anchor = { 0, 0, 0, 0 };
3039 //borderStyle = contour;
3041 //background = white;
3045 //dataBox.borderStyle = none;
3046 dataBox.borderStyle = contour;
3047 dataBox.background = white;
3048 //dataBox.opacity = 0.0f;
3053 bool OnSaveEdit(EditBox editBox, void * object)
3055 bool changed = false;
3056 if(editBox.modifiedDocument)
3059 // how the heck did this work for PathBox? :S
3061 //changed = _class._vTbl[__ecereVMethodID_class_OnGetDataFromString](_class, &this, editBox.contents);
3063 //if(strcmp(editBox.contents, this.name))
3066 //changed = NotifyNodeRename(this.master, this, node);
3068 if(changed && RenameFile(name, editBox.contents))
3070 name = editBox.contents;
3082 int OnCompare(FileSystemNode b)
3085 FileSystemNode a = this;
3086 if(a.type == b.type || (a.type < folder && b.type < folder) || (a.type >= drive))
3088 if(!a.name || !b.name)
3089 PrintLn("error: FileSystemNode::OnCompare -- null-named node");
3090 result = strcmpi(a.name, b.name);
3094 if(a.type == folder && b.type < folder) result = -1;
3095 else if(a.type < folder && b.type == folder) result = 1;
3102 //int OnCompare(FileSystemNode b)
3105 //FileSystemNode a = this;
3106 //if(a.parent < b.parent) result = -1;
3107 //else if(a.parent > b.parent) result = 1;
3109 //result = fstrcmp(a.name, b.name);
3114 bool OnGetDataFromString(const char * string)
3117 if(string && *string)
3119 int len = strlen(string) + 1;
3120 name = new char[len];
3121 CopyBytes(name, string, len);
3128 const char * OnGetString(char * tempString, void * unused /*FileSystemToolWindow fileSysToolWnd*/, bool * needClass)
3130 return name ? name : "";
3134 /*FileSystemNode MakeFileSystemNode(const FileStats stats, const char * name)
3136 FileSystemNode node { stats = stats };
3137 node.name = CopyString(name);
3140 if(stats.attribs.isDirectory)
3142 node.type = (stats.attribs.isDrive) ? drive : folder;
3143 if(stats.attribs.isServer) node.type = server;
3144 if(stats.attribs.isShare) node.type = share;
3145 if(stats.attribs.isCDROM) node.type = cdrom;
3146 if(stats.attribs.isRemote) node.type = netDrive;
3147 if(stats.attribs.isRemovable)
3149 if(name[0] == 'A' || name[0] == 'B')
3152 node.type = removable;
3157 char extension[MAX_EXTENSION];
3158 GetExtension(node.name, extension);
3159 node.type = _FileType::SelectByExtension(extension);
3164 FileSystemNode MakeFileSystemNode(
3165 const FileStats stats,
3168 const bool pathAddName,
3169 const bool previewPicture,
3170 const bool isListItem,
3171 /*const */DisplaySystem displaySystem)
3173 int len = strlen(name);
3174 char info[MAX_LOCATION];
3175 char name2[MAX_LOCATION];
3176 char extension[MAX_EXTENSION];
3178 FileSystemNode node { stats = stats };
3182 char o[MAX_LOCATION];
3183 //char r[MAX_LOCATION];
3184 //StripLastDirectory(path, o);
3185 GetLastDirectory(path, o);
3186 if(fstrcmp(name, o))
3187 //if(!FileExists(path))
3190 //if(stats.attribs.isFile) // TODO fix this in ecere -- WTH -- this has been fixed :/
3191 if(stats.attribs.isDirectory)
3193 extension[0] = '\0';
3195 node.type = (stats.attribs.isDrive) ? drive : folder;
3196 if(stats.attribs.isServer) node.type = server;
3197 if(stats.attribs.isShare) node.type = share;
3198 if(stats.attribs.isCDROM) node.type = cdrom;
3199 if(stats.attribs.isRemote) node.type = netDrive;
3200 if(stats.attribs.isRemovable)
3202 if(name[0] == 'A' || name[0] == 'B')
3205 node.type = removable;
3210 GetExtension(name, extension);
3213 node.type = _FileType::SelectByExtension(extension);
3216 if(stats.attribs.isDrive &&
3217 len > 3 && !strncmp(&name[1], ": [", 3))
3219 strncpy(name2, name, 2);
3221 strncpy(info, &name[4], len - 5);
3226 strcpy(name2, name);
3232 //bool isFile = stats.attribs.isFile;
3233 //bool isFolder = stats.attribs.isDirectory;
3234 char full[MAX_LOCATION];
3236 PathCat(full, name);
3237 node.path = full; //CopyString(full);
3240 node.path = path; //CopyString(path);
3241 node.name = name2; //CopyString(name2);
3243 node.info = info; //CopyString(info);
3244 node.extension = extension; //CopyString(extension);
3246 if(node.type == pictureFile && previewPicture)
3248 node.bitmap = Bitmap { alphaBlend = true };
3249 node.bitmap.Load(path, null, displaySystem);
3253 node.bits.isListItem = true;
3258 FileSystemNode MakeComparedFileSystemNode(
3259 const FileStats stats,
3262 const bool pathAddName,
3263 const bool previewPicture,
3266 /*const */Array<int> exists,
3267 /*const */DisplaySystem displaySystem)
3269 FileSystemNode node = MakeFileSystemNode(stats, name, path, pathAddName, previewPicture, false, displaySystem);
3272 node.cmpIcon = cmpIcon;
3273 node.cmpNot = cmpNot;
3274 node.exists = exists;
3279 #if 0 // could we do this?
3280 class BoolArrayInt : int
3282 // packing 32 bools in one int exposing them as an array
3283 bool [32]:1; // the :1 specifies the size of each element
3284 // byte [4]:8; // packing 4 bytes in an int exposing them as an arrat
3286 // allowing you to access each 32 bits with the following notation:
3293 for(c = 0; c < 32; c++)
3294 a[c] = SomFunction(...);
3297 class BoolArrayInt : int