From 22f5f68389b5f429aa201afd6ca429c190f3320a Mon Sep 17 00:00:00 2001 From: Rejean Loyer Date: Fri, 9 Sep 2011 21:13:54 -0400 Subject: [PATCH] introducing libede --- libede/ede.epj | 53 +++ libede/src/FileSystemBox.ec | 1059 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1112 insertions(+) create mode 100644 libede/ede.epj create mode 100644 libede/src/FileSystemBox.ec diff --git a/libede/ede.epj b/libede/ede.epj new file mode 100644 index 0000000..3129383 --- /dev/null +++ b/libede/ede.epj @@ -0,0 +1,53 @@ +{ + "Version" : 0.2, + "ModuleName" : "ede", + "Description" : "", + "License" : "", + "Options" : { + "Warnings" : "All", + "TargetType" : "SharedLibrary", + "TargetFileName" : "ede", + "TargetDirectory" : "obj/$(CONFIG).$(PLATFORM)", + "ObjectsDirectory" : "obj/$(CONFIG).$(PLATFORM)", + "Libraries" : [ + "ecere" + ] + }, + "Configurations" : [ + { + "Name" : "Debug", + "Options" : { + "Debug" : true, + "Optimization" : "None", + "PreprocessorDefinitions" : [ + "_DEBUG" + ] + } + }, + { + "Name" : "Release", + "Options" : { + "Debug" : false, + "Optimization" : "Speed" + } + } + ], + "Files" : [ + { + "Folder" : "src", + "Files" : [ + { + "FileName" : "FileSystemCache.ec", + "Options" : { + "ExcludeFromBuild" : true + } + }, + "FileSystemBox.ec" + ] + } + ], + "ResourcesPath" : "", + "Resources" : [ + + ] +} \ No newline at end of file diff --git a/libede/src/FileSystemBox.ec b/libede/src/FileSystemBox.ec new file mode 100644 index 0000000..b73a3d3 --- /dev/null +++ b/libede/src/FileSystemBox.ec @@ -0,0 +1,1059 @@ +public import "ecere" + +static char * fileIconNames[] = +{ + "<:ecere>mimeTypes/file.png", /* none */ + + "<:ecere>mimeTypes/file.png", /* normalFile */ + "<:ecere>mimeTypes/textEcereWorkspace.png", /* ewsFile */ + "<:ecere>mimeTypes/textEcereProject.png", /* epjFile */ + "<:ecere>mimeTypes/textEcereSource.png", /* ecFile */ + "<:ecere>mimeTypes/textEcereHeader.png", /* ehFile */ + "<:ecere>mimeTypes/textCSource.png", /* cFile */ + "<:ecere>mimeTypes/textCHeader.png", /* hFile */ + "<:ecere>mimeTypes/textC++Source.png", /* cppFile */ + "<:ecere>mimeTypes/textC++Header.png", /* hppFile */ + "<:ecere>mimeTypes/text.png", /* textFile */ + "<:ecere>mimeTypes/textHyperTextMarkup.png", /* webFile */ + "<:ecere>mimeTypes/image.png", /* pictureFile */ + "<:ecere>status/audioVolumeHigh.png", /* soundFile */ + "<:ecere>mimeTypes/package.png", /* archiveFile */ + "<:ecere>mimeTypes/packageSoftware.png", /* packageFile */ + "<:ecere>mimeTypes/packageOpticalDisc.png", /* opticalMediaImageFile */ + + "<:ecere>places/folder.png", /* folder */ + "<:ecere>status/folderOpen.png", /* folderOpen */ + "<:ecere>devices/computer.png", /* computer */ + "<:ecere>devices/driveHardDisk.png", /* drive */ + "<:ecere>places/driveRemote.png", /* netDrive */ + "<:ecere>devices/mediaOptical.png", /* cdrom */ + "<:ecere>devices/driveRemovableMedia.png", /* removable */ + "<:ecere>devices/mediaFloppy.png", /* floppy */ + "<:ecere>places/networkWorkgroup.png", /* network */ + "<:ecere>places/networkServer.png", /* server */ + "<:ecere>places/folderRemote.png", /* share */ + + "<:ecere>mimeTypes/package.png", /* treeLoader */ + "<:ecere>places/startHere.png", /* lineNumbers */ + + "" +}; + +//define guiApp = ((GuiApplication)__thisModule); +//define selectionColor = guiApp.currentSkin.selectionColor; //Color { 10, 36, 106 }; + +public enum __FileType +{ + none, + + normalFile, ewsFile, epjFile, ecFile, ehFile, cFile, hFile, cppFile, hppFile, + textFile, webFile, pictureFile, soundFile, + archiveFile, packageFile, opticalMediaImageFile, /* these (all previous) are sort equal */ + + folder, folderOpen, computer, + drive, netDrive, cdrom, removable, floppy, network, server, share, // these are sort equal + + // utilities + treeLoader, + lineNumbers; + + /*property char * + { + set + { + this = SelectByExtension(value); + } + }*/ + + public property bool isFolder + { + get { return this >= folder && this <= share; } + } + + public property bool isFile + { + get { return this >= normalFile && this <= opticalMediaImageFile; } + } + + __FileType ::SelectByExtension(char * extension) + { + if(!strcmpi(extension, "ews")) + return ewsFile; + else if(!strcmpi(extension, "epj")) + return epjFile; + else if(!strcmpi(extension, "ec")) + return ecFile; + else if(!strcmpi(extension, "eh")) + return ehFile; + else if(!strcmpi(extension, "cpp") || + !strcmpi(extension, "cc") || !strcmpi(extension, "cxx")) + return cppFile; + else if(!strcmpi(extension, "hpp") || + !strcmpi(extension, "hh") || !strcmpi(extension, "hxx")) + return hppFile; + else if(!strcmpi(extension, "c")) + return cFile; + else if(!strcmpi(extension, "h")) + return hFile; + else if(!strcmpi(extension, "txt") || !strcmpi(extension, "text") || + !strcmpi(extension, "nfo") || !strcmpi(extension, "info")) + return textFile; + else if(!strcmpi(extension, "htm") || !strcmpi(extension, "html") || + !strcmpi(extension, "css") || !strcmpi(extension, "php") || + !strcmpi(extension, "js")) + return webFile; + else if(!strcmpi(extension, "bmp") || !strcmpi(extension, "pcx") || + !strcmpi(extension, "jpg") || !strcmpi(extension, "jpeg") || + !strcmpi(extension, "gif") || !strcmpi(extension, "png") || + !strcmpi(extension, "ico")) + return pictureFile; + else if(!strcmpi(extension, "wav") || !strcmpi(extension, "mp3") || + !strcmpi(extension, "ogg") || !strcmpi(extension, "snd")) + return soundFile; + else if(!strcmpi(extension, "ear") || !strcmpi(extension, "7z") || + !strcmpi(extension, "rar") || !strcmpi(extension, "zip") || + !strcmpi(extension, "gz") || !strcmpi(extension, "bz2") || + !strcmpi(extension, "tar") || !strcmpi(extension, "arj") || + !strcmpi(extension, "lza") || !strcmpi(extension, "lzh") || + !strcmpi(extension, "cpio") || !strcmpi(extension, "z")) + return archiveFile; + else if(!strcmpi(extension, "cab") || !strcmpi(extension, "deb") || + !strcmpi(extension, "rpm")) + return packageFile; + else if(!strcmpi(extension, "iso") || !strcmpi(extension, "mds") || + !strcmpi(extension, "cue") || !strcmpi(extension, "bin") || + !strcmpi(extension, "ccd") || !strcmpi(extension, "bwt") || + !strcmpi(extension, "cdi") || !strcmpi(extension, "nrg")) + return opticalMediaImageFile; + return normalFile; + } +}; + +//public enum FileSystemNodeType { file, folder, system }; + +define guiApp = ((GuiApplication)__thisModule); // how to do this in a dll? +define selectionColor = guiApp.currentSkin.selectionColor; //Color { 10, 36, 106 }; + +public class FileSystemNode : struct // : struct +{ +public: + /*//LinkElement link; + FileSystemNode parent; + + FileSystemNodeType type; + + char * name;*/ + + FileSystemNode prev, next; + + bool loaded, childrenLoaded; + int indent; + char * path; + char * name; + char * extension; + char * info; + DataRow row; + OldList children; + __FileType type; + FileSystemNode parent; + + FileStats stats; + + Bitmap bitmap; + + void GetPath(String outputPath) + { + FileSystemNode up; + if(parent) + { + strcpy(outputPath, name); + for(up = parent; up; up = up.parent) + { + char temp[MAX_LOCATION]; + strcpy(temp, up.name); + PathCat(temp, outputPath); + strcpy(outputPath, temp); + } + } + else +#ifdef __WIN32__ + strcpy(outputPath, "/"); +#else + strcpy(outputPath, name); +#endif + + } + + bool IsChildOf(FileSystemNode node) + { + FileSystemNode test; + for(test = parent; test; test = test.parent) + if(test == node) + return true; + return false; + } + + void DuplicateChildren(bool recursive, bool forceExpanded, FileSystemNode addTo, FileSystemBox fsb) + { + if(children.first) + { + FileSystemNode child; + + for(child = children.first; child; child = child.next) + { + FileSystemNode copy { }; + copy.name = CopyString(child.name); + copy.type = child.type; + fsb.AddTreeNode(copy, child.loaded, false, addTo); + if(forceExpanded) + copy.row.collapsed = false; + if(recursive) + child.DuplicateChildren(recursive, forceExpanded, copy, fsb); + } + } + } + + void EnsureVisible(bool expand) + { + if(parent) + parent.EnsureVisible(true); + if(expand) + row.collapsed = false; + // TODO: row.EnsureVisible(); // making the row visible by scrolling + } + + void OnFree() + { + //delete name; + } + + void Free() + { + FileSystemNode child; + for(; (child = children.first); ) + { + child.Free(); + children.Delete(child); + } + //if(name) + delete name; + delete info; + } + + void Delete() + { + Free(); + if(parent) + parent.children.Delete(this); + } + + void OnDisplay(Surface surface, int x, int y, int width, FileSystemBox fsb, Alignment alignment, DataDisplayFlags displayFlags) + { + //int indentSize = (displayFlags.dropBox) ? 0 : 10; + int indent = 16; + int xStart; + int len; + int w, h; + //int textOffset; + char label[MAX_FILENAME]; + + Bitmap icon; + + if(!this) + return; + + icon = fsb.fileIcons[type].bitmap; + /*if(type == normalFile) + PrintLn("dd");*/ + //xStart = indent * indent + x + (icon ? (icon.width + 5) : 0); + xStart = x + (icon ? (icon.width + 5) : 0); + + if(!name) + return; + + if(info) + sprintf(label, "%s [%s]", name, info); + else + strcpy(label, name); + len = strlen(label); + + if(!icon) + { + if(type == folder || type == folderOpen) + surface.SetForeground(yellow); + //indentSize = 8; + indent = 8; + } + //textOffset = indent * indentSize + (icon ? (icon.width + 4) : 0); + + surface.TextOpacity(false); + surface.TextExtent(label, len, &w, &h); + h = Max(h, 16); + + // Draw the current row stipple + if(displayFlags.selected) + //surface.Area(xStart - 1, y, xStart - 1, y + h - 1); + //surface.Area(xStart + w - 1, y, xStart + w + 1, y + h - 1); + surface.Area(xStart - 3, y, xStart + w + 1, y + h - 1); + + //surface.WriteTextDots(alignment, x + textOffset, y + 2, width - textOffset, name, strlen(name)); + surface.WriteTextDots(alignment, xStart, y + 2, width, label, len); + + //if(!guiApp.textMode) -- how to do this in a dll? + { + if(displayFlags.current) + { + if(displayFlags.active) + { + surface.LineStipple(0x5555); + if(displayFlags.selected) + surface.SetForeground(0xFFFFFF80); + else + surface.SetForeground(black); + } + else + { + surface.SetForeground(selectionColor); + } + surface.Rectangle(xStart - 3, y, xStart + w + 1, y + h - 1); + surface.LineStipple(0); + } + + if(icon) + { + //surface.blend = true; + //surface.alphaWrite = blend; + surface.SetForeground(white); + //surface.Blit(icon, x + indent * indentSize, y,0,0, icon.width, icon.height); + surface.Blit(icon, x,y,0,0, icon.width, icon.height); + } + } + } + + int OnCompare(FileSystemNode b) + { + int result; + FileSystemNode a = this; + if(a.type == b.type || (a.type < folder && b.type < folder) || (a.type >= drive)) + result = strcmpi(a.name, b.name); + else + { + if(a.type == folder && b.type < folder) result = -1; + else if(a.type < folder && b.type == folder) result = 1; + else result = 0; + } + return result; + } + + /*int OnCompare(FileSystemNode b) + { + int result; + FileSystemNode a = this; + if(a.parent < b.parent) result = -1; + else if(a.parent > b.parent) result = 1; + else + result = fstrcmp(a.name, b.name); + return result; + }*/ + + char * OnGetString(char * tempString, FileSystemToolWindow fileSysToolWnd, bool * needClass) + { + return name ? name : ""; + } +} + +/*FileSystemNode MakeFileSystemNode(const FileStats stats, const char * name) +{ + FileSystemNode node { stats = stats }; + node.name = CopyString(name); + if(!node.name) + node.name = null; + if(stats.attribs.isDirectory) + { + node.type = (stats.attribs.isDrive) ? drive : folder; + if(stats.attribs.isServer) node.type = server; + if(stats.attribs.isShare) node.type = share; + if(stats.attribs.isCDROM) node.type = cdrom; + if(stats.attribs.isRemote) node.type = netDrive; + if(stats.attribs.isRemovable) + { + if(name[0] == 'A' || name[0] == 'B') + node.type = floppy; + else + node.type = removable; + } + } + else + { + char extension[MAX_EXTENSION]; + GetExtension(node.name, extension); + node.type = __FileType::SelectByExtension(extension); + } + return node; +}*/ +static FileSystemNode MakeFileSystemNode(const FileStats stats, const char * fileName, const char * filePath, const bool previewPicture, const DisplaySystem displaySystem) +{ + int len = strlen(fileName); + char info[MAX_LOCATION]; + char name[MAX_LOCATION]; + char extension[MAX_EXTENSION]; + + FileSystemNode node { stats = stats }; + + //if(stats.attribs.isFile) // TODO fix this in ecere + if(stats.attribs.isDirectory) + { + extension[0] = '\0'; + + node.type = (stats.attribs.isDrive) ? drive : folder; + if(stats.attribs.isServer) node.type = server; + if(stats.attribs.isShare) node.type = share; + if(stats.attribs.isCDROM) node.type = cdrom; + if(stats.attribs.isRemote) node.type = netDrive; + if(stats.attribs.isRemovable) + { + if(fileName[0] == 'A' || fileName[0] == 'B') + node.type = floppy; + else + node.type = removable; + } + } + else + { + GetExtension(fileName, extension); + strlwr(extension); + + node.type = __FileType::SelectByExtension(extension); + } + + if(stats.attribs.isDrive && + len > 3 && !strncmp(&fileName[1], ": [", 3)) + { + strncpy(name, fileName, 2); + name[2] = 0; + strncpy(info, &fileName[4], len - 5); + info[len - 5] = 0; + } + else + { + strcpy(name, fileName); + info[0] = 0; + } + + node.path = CopyString(filePath); + node.name = CopyString(name); + if(info[0]) + node.info = CopyString(info); + node.extension = CopyString(extension); + + if(node.type == pictureFile && previewPicture) + { + node.bitmap = Bitmap { }; + node.bitmap.Load(filePath, null, displaySystem); + } + + return node; +} + +class FileSystemBoxBits +{ + bool foldersOnly:1, details:1, treeBranches:1, previewPictures:1; + //bool header:1, freeSelect:1, fullRowSelect:1, multiSelect:1, autoScroll:1, alwaysHL : 1, moveRows:1, resizable:1; + //bool moveFields:1, clearHeader:1, alwaysEdit:1, collapse:1, treeBranch:1, rootCollapse:1, heightSet:1; + //bool sortable:1, noDragging:1, fillLastField:1, expandOnAdd:1; +}; + +public class FileSystemBox : Window // should we not derive from ListBox instead? +/* + this stuff from the listbox would be nicely exposed... + fullRowSelect = false; + treeBranches = true; + collapseControl = true; + rootCollapseButton = true; + sortable = true; +*/ +{ + borderStyle = deep; + hasHorzScroll = false; + hasVertScroll = false; + + menu = Menu { }; + +public: + FileSystemNode root; + FileSystemNode selection; + + virtual bool Window::NotifyNodeSelect(FileSystemBox box, FileSystemNode node); + + property char * path + { + set + { + delete path; + if(value && value[0]) + path = CopyString(value); + if(created) + Load(); + } + + get { return path; } + //isset { return path && path[0]; } + } + + property bool foldersOnly { set { bits.foldersOnly = value; } get { return bits.foldersOnly; } }; + property bool previewPictures { set { bits.previewPictures = value; } get { return bits.previewPictures; } }; + property char * extensions { set { delete extensions; if(value && value[0]) extensions = CopyString(value); } get { return extensions; } } + property bool details { set { bits.details = value; } get { return bits.details; } }; + property bool treeBranches + { + set + { + bits.treeBranches = value; + list.treeBranches = value; + list.collapseControl = value; + list.rootCollapseButton = value; + } + get { return bits.treeBranches; } + }; + + property FileSystemNode node + { + get + { + if(!list) + return null; + if(!list.currentRow) + return null; + if(!list.currentRow.tag) + return null; + return (FileSystemNode)list.currentRow.tag; + } + } + + void Select(FileSystemNode node) + { + if(node.row) + { + node.EnsureVisible(false); + list.SelectRow(node.row); + } + } + + FileSystemNode Find(const char * name, FileSystemNode parent) + { + FileSystemNode node; + FileSystemNode start = parent ? parent : root; + if(!start.loaded || !start.childrenLoaded) + LoadTreeNode(start); + for(node = start.children.first; node; node = node.next) + if(node.name && !strcmpi(node.name, name)) + return node; + return null; + } + +private: + FileSystemBoxBits bits; + + char * path; + char * extensions; + + BitmapResource fileIcons[__FileType]; + + FileSystemBox() + { + char wd[MAX_LOCATION]; + GetWorkingDir(wd, sizeof(wd)); + property::path = wd; + + InitFileIcons(); + list.AddField(nameField); + } + ~FileSystemBox() + { + delete extensions; + delete path; + } + void InitFileIcons() + { + __FileType c; + for(c = 0; c < __FileType::enumSize; c++) + { + fileIcons[c] = BitmapResource { fileIconNames[c], alphaBlend = true }; + AddResource(fileIcons[c]); + } + } + + DataField nameField { dataType = "FileSystemNode", width = 240, userData = this }; + DataField typeField { header = "Type", dataType = /*"String"*/ "char *", width = 40, freeData = false }; + DataField sizeField { header = "Size", dataType = "FileSize", width = 96, alignment = right }; + + bool OnPostCreate() + { + Load(); + return true; + } + + ListBox list + { + this; + + borderStyle = none; + hasHorzScroll = true; + hasVertScroll = true; + fullRowSelect = false; + sortable = true; + + anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 }; + + // WHY is this not working ? + /*void OnResize(int width, int height) + { + if(vertScroll.visible) + nameField.width = width - vertScroll.size.w; + else + nameField.width = width; + }*/ + + bool NotifyCollapse(ListBox listBox, DataRow row, bool collapsed) + { + if(row) + { + FileSystemNode node = (FileSystemNode)row.tag; + FileSystemNode child; + if(collapsed) + { + /* + for(child = node.children.last; child; child = node.children.last) + { + listBox.DeleteRow(child.row); + child.Free(); + delete child; + } + node.childrenLoaded = false; + */ + } + else + { + if(!node.loaded || !node.childrenLoaded) + { + LoadTreeNode(node); + //list.Sort(nameField, 1); + //node. + } + for(child = node.children.first; child && child.next; child = child.next); + if(child) + child.EnsureVisible(false); + } + } + return true; + } + + bool NotifyRightClick(ListBox listBox, int x, int y, Modifiers mods) + { + DataRow row = listBox.currentRow; + if(row) + { + FileSystemNode node = (FileSystemNode)row.tag; + if(node) + { + PopupMenu popup; + Menu menu { }; + + MenuItem { menu, "Cut\tCtrl+X", t, NotifySelect = null, disabled = false }; + MenuItem { menu, "Copy\tCtrl+C", c, NotifySelect = null, disabled = false }; + MenuItem { menu, "Paste\tCtrl+V", p, NotifySelect = null, disabled = false /*!clipboard*/ }; + MenuItem { menu, "Delete\tDel", d, NotifySelect = null, disabled = false }; + //MenuDivider { menu }; + + popup = PopupMenu + { + master = this, menu = menu, + position = { + x + clientStart.x + absPosition.x - guiApp.desktop.position.x, + y + clientStart.y + absPosition.y - guiApp.desktop.position.y } + }; + popup.Create(); + } + } + return true; + } + + bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods) + { + if(row) + { + FileSystemNode node = (FileSystemNode)row.tag; + NotifyNodeSelect(listBox.parent.master, this, node); + selection = node; + } + return true; + } + + bool NotifyEditing(ListBox listBox, DataRow row) + { + if(row) + { + FileSystemNode node = (FileSystemNode)row.tag; + } + return true; + } + + bool NotifyEdited(ListBox listBox, DataRow row) + { + if(row) + { + FileSystemNode node = (FileSystemNode)row.tag; + } + return true; + } + + bool NotifyEditDone(ListBox listBox, DataRow row) + { + if(row) + { + FileSystemNode node = (FileSystemNode)row.tag; + } + return true; + } + + }; + + // Edit Menu + Menu editMenu { menu, "Edit", e }; + MenuItem itemEditCut + { + editMenu, "Cut\tCtrl+X", t, disabled = true; + + bool NotifySelect(MenuItem selection, Modifiers mods) + { + //EditCut(); + return true; + } + }; + MenuItem itemEditCopy + { + editMenu, "Copy\tCtrl+C", c, disabled = true; + + bool NotifySelect(MenuItem selection, Modifiers mods) + { + //EditCopy(); + return true; + } + }; + MenuItem itemEditPaste + { + editMenu, "Paste\tCtrl+V", p; + + bool NotifySelect(MenuItem selection, Modifiers mods) + { + //EditPaste(); + return true; + } + }; + MenuItem itemEditDelete + { + editMenu, "Delete\tDel", d, disabled = true; + + bool NotifySelect(MenuItem selection, Modifiers mods) + { + //EditDelete(); + return true; + } + }; + + // WHY is this crashing ? + /*void OnResize(int width, int height) + { + if(this && nameField) + nameField.width = width - 80; + }*/ + + void Load() + { + // TODO: fix this! + // this is crashing in for designer when details = true // can't save the file, always yields a crash + /*if(list && created) + { + list.ClearFields(); + list.AddField(nameField); + if(bits.details) + { + list.AddField(typeField); + list.AddField(sizeField); + } + }*/ + if(bits.treeBranches) + LoadTree(); + else + LoadList(); + } + + void LoadList() + { + FileListing listing { path, extensions = extensions }; + + list.Clear(); + while(listing.Find()) + { + if(!bits.foldersOnly || listing.stats.attribs.isDirectory) + { + FileSystemNode node = MakeFileSystemNode(listing.stats, listing.name, listing.path, bits.previewPictures, displaySystem); + DataRow row = list.AddRow(); + row.tag = (int)node; + row.SetData(nameField, node); + if(bits.details) + { + row.SetData(typeField, node.extension); + row.SetData(sizeField, (void *)node.stats.size); + } + } + } + list.Sort(nameField, 1); + } + + void LoadTree() + { + //char startPath[MAX_LOCATION]; + FileSystemNode parent; + FileSystemNode node; + FileListing listing { path, extensions = extensions }; + + /*if(!path) + GetWorkingDir(startPath, sizeof(startPath)); + else + strcpy(path, startPath);*/ + + list.Clear(); + + delete root; + //root = FileSystemNode { type = computer, loaded = true, childrenLoaded = true }; + root = MakeFileSystemNode(FileStats { attribs = FileExists(path)}, path, path, bits.previewPictures, displaySystem); + #ifdef __WIN32__ + //root.name = rootName; + AddTreeNode(root, true, false, null, list); + #else + //root.name = "/"; + #endif + AddTreeNode(root, false, true, null); + + // How can this make sense for linux? + #ifdef __WIN32__ + while(listing.Find()) + { + int len = strlen(listing.name); + char info[MAX_LOCATION]; + char name[MAX_LOCATION]; + if(listing.stats.attribs.isDrive && + len > 3 && !strncmp(&listing.name[1], ": [", 3)) + { + strncpy(name, listing.name, 2); + name[2] = 0; + strncpy(info, &listing.name[4], len - 5); + info[len - 5] = 0; + } + else + { + strcpy(name, listing.name); + info[0] = 0; + } + + parent = MakeFileSystemNode(listing.stats, name); + if(info[0]) + parent.info = CopyString(info); + parent.loaded = true; + AddTreeNode(parent, !listing.stats.attribs.isDirectory, listing.stats.attribs.isDirectory, root, this); + if(!listing.stats.attribs.isDirectory) + parent.childrenLoaded = true; + } + + node = FileSystemNode { name = msNetwork, type = network }; + AddTreeNode(node, false, true, null, this); + node.row.collapsed = true; + Sort(nameField, 1); + SelectRow(root.row); + #endif + LoadTreeNode(root); + list.Sort(nameField, 1); + } + + void LoadTreeNode(FileSystemNode node) + { + if(!node.loaded) + { + char path[MAX_LOCATION]; + node.GetPath(path); + { + FileListing listing { path, extensions = extensions }; + if(node.children.count == 1) + DeleteNode(node.children.first); + + while(listing.Find()) + { + if(!bits.foldersOnly || listing.stats.attribs.isDirectory) + { + FileSystemNode child = MakeFileSystemNode(listing.stats, listing.name, listing.path, bits.previewPictures, displaySystem); + AddTreeNode(child, true, false, node); + NodeChildLoad(child, node); + } + } + } + node.childrenLoaded = true; + node.loaded = true; + node.row.SortSubRows(false); + } + else if(!node.childrenLoaded) + { + FileSystemNode child; + if(node.children.first) + { + for(child = node.children.first; child; child = child.next) + { + if(!child.loaded) + LoadTreeNode(child); + else if(!child.childrenLoaded) + NodeChildLoad(child, node); + } + node.childrenLoaded = true; + node.row.SortSubRows(false); + } + } + } + + void NodeChildLoad(FileSystemNode parent, FileSystemNode node) + { + char path[MAX_LOCATION]; + parent.GetPath(path); + { + bool added = false; + FileListing listing { path, extensions = extensions }; + while(listing.Find()) + { + if(!bits.foldersOnly || listing.stats.attribs.isDirectory) + { + FileSystemNode child = MakeFileSystemNode(listing.stats, listing.name, listing.path, bits.previewPictures, displaySystem); + AddTreeNode(child, true, false, parent); + added = true; + } + } + if(!added) + added = true; + } + //parent.childrenLoaded = true; + } + + void AddTreeNode(FileSystemNode node, bool loaded, bool addLoader, FileSystemNode addTo) + { + DataRow row = (addTo && addTo.row) ? addTo.row.AddRow() : list.AddRow(); + if(addTo) + { + node.parent = addTo; + node.indent = addTo.indent + 1; + addTo.children.Add(node); + } + row.tag = (int)node; + node.row = row; + row.SetData(null, node); + + node.loaded = loaded; + if(addLoader) + //AddTreeNode(FileSystemNode { }, false, false, node); // why would this create a compile error? + AddTreeNode(FileSystemNode { type = none }, false, false, node); + + if(node.indent > 0) + row.collapsed = true; + else if(node.type == folder) + node.type = folderOpen; + } + + void DeleteNode(FileSystemNode node) + { + FileSystemNode child; + for(; (child = node.children.first); ) + DeleteNode(child); + list.DeleteRow(node.row); + node.Delete(); + } +/* +public class ClipBoardFiles +{ + +public: + + property + +} + + // CLIPBOARD + void Copy() + { + if(this) + { + int size = SelSize(); + if(size) + { + // Try to allocate memory + ClipBoard clipBoard { }; + if(clipBoard.Allocate(size+1)) + { + GetSel(clipBoard.memory, true); + // Save clipboard + clipBoard.Save(); + } + delete clipBoard; + } + } + } + + void Paste() + { + if(this) + { + ClipBoard clipBoard { }; + if(clipBoard.Load()) + PutS(clipBoard.memory); + delete clipBoard; + } + } + + void Cut() + { + if(this) + { + Copy(); + DelSel(); + SetViewToCursor(true); + Modified(); + } + } + +Private Type DROPFILES + pFiles As Long + pt As POINTAPI + fNC As Long + fWide As Long +End Type +For iCounter = 0 To filelist.ListCount - 1 + If filelist.Selected(iCounter) = True Then + strFiles = strFiles & FixPath(filelist.Path) & filelist.List(iCounter) & vbNullChar + End If +Next +'all selected items are now put in strFiles + +hGlobal = GlobalAlloc(GHND, Len(DF) + Len(strFiles)) 'put all files to a exclusive number +If hGlobal Then 'if the globalalloc worked + lpGlobal = GlobalLock(hGlobal) 'lock the hGlobal + DF.pFiles = Len(DF) 'set the size of the files + + Call CopyMem(ByVal lpGlobal, DF, Len(DF)) 'copy df to the lpglobal + Call CopyMem(ByVal (lpGlobal + Len(DF)), ByVal strFiles, Len(strFiles)) 'copy strfiles to lpglobal + Call GlobalUnlock(hGlobal) 'unlock hglobal again + + SetClipboardData CF_HDROP, hGlobal 'put files to the clipboard +End If + + bool SaveFile(const char * filePath) + { + } +*/ + +} -- 1.8.3.1