1 namespace gui::dialogs;
4 static char * rootName = "Entire Computer";
5 static char * msNetwork = "Microsoft Windows Network";
10 #define IS_ALUNDER(ch) ((ch) == '_' || isalnum((ch)))
13 extern int __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit;
16 static char * iconNames[] =
18 "<:ecere>places/folder.png",
19 "<:ecere>status/folderOpen.png",
20 "<:ecere>devices/computer.png",
21 "<:ecere>devices/driveHardDisk.png",
22 "<:ecere>places/driveRemote.png",
23 "<:ecere>devices/mediaOptical.png",
24 "<:ecere>devices/driveRemovableMedia.png",
25 "<:ecere>devices/mediaFloppy.png",
26 "<:ecere>places/networkWorkgroup.png",
27 "<:ecere>places/networkServer.png",
28 "<:ecere>places/folderRemote.png",
30 "<:ecere>mimeTypes/file.png", /*normalFile*/
31 "<:ecere>mimeTypes/textEcereWorkspace.png", /*ewsFile*/
32 "<:ecere>mimeTypes/textEcereProject.png", /*epjFile*/
33 "<:ecere>mimeTypes/textEcereSource.png", /*ecFile*/
34 "<:ecere>mimeTypes/textEcereHeader.png", /*ehFile*/
35 "<:ecere>mimeTypes/textCSource.png", /*cFile*/
36 "<:ecere>mimeTypes/textCHeader.png", /*hFile*/
37 "<:ecere>mimeTypes/textC++Source.png", /*cppFile*/
38 "<:ecere>mimeTypes/textC++Header.png", /*hppFile*/
39 "<:ecere>mimeTypes/text.png", /*textFile*/
40 "<:ecere>mimeTypes/textHyperTextMarkup.png", /*webFile*/
41 "<:ecere>mimeTypes/image.png", /*pictureFile*/
42 "<:ecere>status/audioVolumeHigh.png", /*soundFile*/
43 "<:ecere>mimeTypes/package.png", /*archiveFile*/
44 "<:ecere>mimeTypes/packageSoftware.png", /*packageFile*/
45 "<:ecere>mimeTypes/packageOpticalDisc.png" /*opticalMediaImageFile*/
48 public enum FileNameType // Had to be private, since icons member of FileDialog is also private... (Static members? Not for a while...)
50 folder, folderOpen, computer,
51 drive, netDrive, cdrom, removable, floppy, network, server, share, // these are sort equal
53 normalFile, ewsFile, epjFile, ecFile, ehFile, cFile, hFile, cppFile, hppFile,
54 textFile, webFile, pictureFile, soundFile,
55 archiveFile, packageFile, opticalMediaImageFile; /* these (all previous) are sort equal */
61 this = SelectByExtension(value);
64 public property bool isFolderType
66 get { return this >= folder && this <= share; }
69 public property bool isFileType
71 get { return this >= normalFile && this <= opticalMediaImageFile; }
74 FileNameType ::SelectByExtension(char * extension)
76 if(!strcmpi(extension, "ews"))
78 else if(!strcmpi(extension, "epj"))
80 else if(!strcmpi(extension, "ec"))
82 else if(!strcmpi(extension, "eh"))
84 else if(!strcmpi(extension, "cpp") ||
85 !strcmpi(extension, "cc") || !strcmpi(extension, "cxx"))
87 else if(!strcmpi(extension, "hpp") ||
88 !strcmpi(extension, "hh") || !strcmpi(extension, "hxx"))
90 else if(!strcmpi(extension, "c"))
92 else if(!strcmpi(extension, "h"))
94 else if(!strcmpi(extension, "txt") || !strcmpi(extension, "text") ||
95 !strcmpi(extension, "nfo") || !strcmpi(extension, "info"))
97 else if(!strcmpi(extension, "htm") || !strcmpi(extension, "html") ||
98 !strcmpi(extension, "css") || !strcmpi(extension, "php") ||
99 !strcmpi(extension, "js"))
101 else if(!strcmpi(extension, "bmp") || !strcmpi(extension, "pcx") ||
102 !strcmpi(extension, "jpg") || !strcmpi(extension, "jpeg") ||
103 !strcmpi(extension, "gif") || !strcmpi(extension, "png") ||
104 !strcmpi(extension, "ico"))
106 else if(!strcmpi(extension, "wav") || !strcmpi(extension, "mp3") ||
107 !strcmpi(extension, "ogg") || !strcmpi(extension, "snd"))
109 else if(!strcmpi(extension, "ear") || !strcmpi(extension, "7z") ||
110 !strcmpi(extension, "rar") || !strcmpi(extension, "zip") ||
111 !strcmpi(extension, "gz") || !strcmpi(extension, "bz2") ||
112 !strcmpi(extension, "tar") || !strcmpi(extension, "arj") ||
113 !strcmpi(extension, "lza") || !strcmpi(extension, "lzh") ||
114 !strcmpi(extension, "cpio") || !strcmpi(extension, "z"))
116 else if(!strcmpi(extension, "cab") || !strcmpi(extension, "deb") ||
117 !strcmpi(extension, "rpm"))
119 else if(!strcmpi(extension, "iso") || !strcmpi(extension, "mds") ||
120 !strcmpi(extension, "cue") || !strcmpi(extension, "bin") ||
121 !strcmpi(extension, "ccd") || !strcmpi(extension, "bwt") ||
122 !strcmpi(extension, "cdi") || !strcmpi(extension, "nrg"))
123 return opticalMediaImageFile;
128 public enum FileDialogType { open, save, selectDir, multiOpen };
129 public struct FileFilter
131 char * name, * extensions;
133 bool ValidateFileName(char * name)
135 if(strcmp(name, "..") && strcmp(name, ".") && strcmp(name, ""))
137 if(extensions) // && !stats.attribs.isDirectory)
139 char extension[MAX_EXTENSION], compared[MAX_EXTENSION];
142 GetExtension(name, extension);
143 for(c = 0; extensions[c];)
147 for(;(ch = extensions[c]) && !IS_ALUNDER(ch); c++);
148 for(;(ch = extensions[c]) && IS_ALUNDER(ch); c++)
149 compared[len++] = ch;
150 compared[len] = '\0';
152 if(!strcmpi(extension, compared))
162 public enum FileForceExtension { never, always, whenNoneGiven };
163 public struct FileType
165 char * name, * typeExtension;
166 FileForceExtension forceExtension;
169 static enum FileDialogSelectFrom { fromEditBox, fromListBox, fromDropBox };
171 public struct FileName
177 void OnDisplay(Surface surface, int x, int y, int width, FileDialog fileDialog, Alignment alignment, DataDisplayFlags displayFlags)
179 int indentSize = (displayFlags.dropBox) ? 0 : 10;
182 Bitmap icon = fileDialog.icons[type].bitmap;
183 if(!icon && type > normalFile)
184 icon = fileDialog.icons[normalFile].bitmap;
187 if(type == folder || type == folderOpen)
188 surface.SetForeground(red); //Color { 170, 170, 0 } // REDJ What is that color?
191 textOffset = indent * indentSize + (icon ? (icon.width + 4) : 0);
193 surface.WriteTextDots
194 (alignment, x + textOffset, y + 2, width - textOffset, name, strlen(name));
196 surface.Blit(icon, x + indent * indentSize, y,0,0, icon.width, icon.height);
199 int OnCompare(FileName b)
202 if(type == b.type || (type >= normalFile && b.type >= normalFile) || (type >= drive && type <= share))
203 result = strcmpi(name, b.name);
206 if(type == folder && b.type >= normalFile) result = -1;
207 else if(type >= normalFile && b.type == folder) result = 1;
212 void OnCopy(FileName newData)
215 indent = newData.indent;
218 int len = strlen(newData.name) + 1;
219 name = new char[len];
220 CopyBytes(name, newData.name, len);
224 bool OnGetDataFromString(char * string)
226 int len = strlen(string) + 1;
227 name = new char[len];
228 CopyBytes(name, string, len);
237 char * OnGetString(char * string, void * fieldData, bool * needClass)
243 public class FileDialog : Window
245 text = "Select a file...";
246 background = activeBorder;
248 borderStyle = sizable;
251 nativeDecorations = true;
252 minClientSize = { 500, 300 };
255 property FileDialogType type
257 get { return style; }
260 int numTypes = sizeTypes / sizeof(FileType);
261 int rightOffset = (value != selectDir && numTypes > 0) ? 48 : 16;
265 if(value == selectDir)
268 filter.visible = false;
269 filterLabel.visible = false;
271 type.visible = false;
272 typeLabel.visible = false;
275 open.isDefault = true;
278 ok.id = DialogResult::ok;
280 ok.isDefault = false;
285 filter.visible = true;
286 filterLabel.visible = true;
289 type.visible = numTypes != 0;
290 typeLabel.visible = numTypes != 0;
292 open.visible = false;
293 open.isDefault = false;
300 ok.anchor = { right = 10, bottom = 32 + rightOffset - 1 };
303 cancel.anchor = { right = 10, bottom = rightOffset - 1 };
305 listBox.anchor = { left = 8, right = 8, top = 40, bottom = 64 + rightOffset };
306 fileName.anchor = { left = 96, bottom = 32 + rightOffset, right = 104 };
307 fileNameLabel.anchor = { left = 8, bottom = 35 + rightOffset };
309 listBox.multiSelect = value == multiOpen;
310 fileName.text = (value == selectDir) ? "Directory:" : "File Name:";
314 // Stuff currently in config moving to FileDialog:
315 property char * filePath { set { strcpy(filePath, value); } get { return (char *)filePath; } };
316 property char * currentDirectory
320 GetWorkingDir(currentDirectory, MAX_DIRECTORY);
321 PathCat(currentDirectory, value);
322 FileFixCase(currentDirectory);
324 get { return (char *)currentDirectory; }
326 property FileFilter * filters { set { filters = value; } get { return filters; } };
327 property FileType * types { set { types = value; } get { return types; } };
329 // Replace with Array system
330 property int sizeFilters
334 int numFilters = value / sizeof(FileFilter);
339 // File Extension Filter
341 // filter.AddField(null);
344 for(c = 0; c<numFilters; c++)
346 DataRow row = filter.AddString(filters[c].name);
351 filter.AddString("All files");
353 if(fileFilter >= numFilters) fileFilter = 0;
354 filter.currentRow = filter.FindRow(fileFilter);
356 get { return sizeFilters; }
358 property int sizeTypes
362 int numTypes = value / sizeof(FileType);
363 int rightOffset = (numTypes > 0) ? 48 : 16;
368 filter.anchor = { left = 96, right = 104, bottom = rightOffset };
369 filterLabel.anchor = { left = 8, bottom = 3 + rightOffset };
371 if(style != selectDir)
374 type.visible = numTypes ? true : false;
375 typeLabel.visible = numTypes ? true : false;
378 ok.anchor = { right = 10, bottom = 32 + rightOffset - 1 };
381 cancel.anchor = { right = 10, bottom = rightOffset - 1 };
384 listBox.anchor = { left = 8, right = 8, top = 40, bottom = 64 + rightOffset };
385 fileName.anchor = { left = 96, bottom = 32 + rightOffset, right = 104 };
386 fileNameLabel.anchor = { left = 8, bottom = 35 + rightOffset };
394 // type.AddField(null);
397 for(c = 0; c<numTypes; c++)
399 DataRow row = type.AddString(types[c].name);
403 if(fileType >= numTypes) fileType = 0;
405 type.currentRow = type.FindRow(fileType);
408 get { return sizeTypes; }
411 property int filter { set { fileFilter = value; } get { return fileFilter; } };
412 property int fileType { set { fileType = value; } get { return fileType; } };
413 property bool mayNotExist { set { mayNotExist = value; } get { return mayNotExist; } };
416 property int numSelections { get { return numSelections; } };
417 property char ** multiFilePaths { get { return multiFilePaths; } };
424 lookIn.AddField(lookInField);
425 listBox.AddField(nameField);
426 listBox.AddField(typeField);
427 listBox.AddField(sizeField);
429 filter.currentRow = filter.AddString("All files");
431 GetWorkingDir(currentDirectory, MAX_DIRECTORY);
432 FileFixCase(currentDirectory);
435 for(c = 0; c<FileNameType::enumSize; c++)
437 icons[c] = BitmapResource { iconNames[c], alphaBlend = true };
438 AddResource(icons[c]);
444 delete customFilter.extensions;
448 for(c = 0; c<numSelections; c++)
449 delete multiFilePaths[c];
450 delete multiFilePaths;
457 char tmpDir[MAX_FILENAME];
460 FileListing listing { "/" };
465 // Fill the path dropbox
468 row = lookIn.AddRow();
471 fileName.name = rootName;
475 fileName.type = computer;
476 row.SetData(null, fileName);
477 lookIn.currentRow = row;
481 while(listing.Find())
483 row = lookIn.AddRow();
485 fileName.name = listing.name;
486 fileName.type = drive;
487 if(listing.stats.attribs.isCDROM) fileName.type = cdrom;
488 if(listing.stats.attribs.isRemote) fileName.type = netDrive;
489 if(listing.stats.attribs.isRemovable)
491 if(listing.name[0] == 'A' || listing.name[0] == 'B')
492 fileName.type = floppy;
494 fileName.type = removable;
498 row.SetData(null, fileName);
501 if(listing.name[0] == currentDirectory[0] &&
502 listing.name[1] == currentDirectory[1])
505 for(c = start; currentDirectory[c]; )
509 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
510 for(;(ch = currentDirectory[c]) && (ch != '/' && ch != '\\'); c++)
512 if(len < MAX_FILENAME)
515 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
520 row = lookIn.AddRow();
521 fileName.name = tmpDir;
522 fileName.type = ch ? folder : folderOpen;
524 row.SetData(null, fileName);
527 lookIn.currentRow = row;
531 lookIn.currentRow = row;
536 row = lookIn.AddRow();
537 fileName.name = msNetwork;
538 fileName.type = network;
540 row.SetData(null, fileName);
541 if(!strcmp(currentDirectory, "\\\\"))
542 lookIn.currentRow = row;
545 if(currentDirectory[0] == '\\' && currentDirectory[1] == '\\')
547 for(c = 2; currentDirectory[c]; )
551 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
552 for(;(ch = currentDirectory[c]) && (ch != '/' && ch != '\\'); c++)
554 if(len < MAX_FILENAME)
557 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
562 row = lookIn.AddRow();
563 fileName.name = tmpDir;
565 if(fileName.indent == 1)
566 fileName.type = server;
567 else if(fileName.indent == 2)
568 fileName.type = share;
570 fileName.type = ch ? folder : folderOpen;
571 row.SetData(null, fileName);
574 lookIn.currentRow = row;
577 lookIn.currentRow = row;
583 // flag = false : Get Name From Edit Box, flag = true : Get Name From List Box
584 void GetNameFromListBox(bool flag)
589 if(style == multiOpen)
590 okDisabled = listBox.numSelections == 0;
592 okDisabled = listBox.currentRow == null;
593 if(okDisabled) flag = false;
596 okDisabled = !fileName || !fileName.line.text[0];
598 getNameFromListBox = flag;
599 ok.disabled = okDisabled;
600 open.disabled = okDisabled;
605 FileListing listing { currentDirectory };
610 if(sizeFilters < sizeof(FileFilter) && !fileFilter)
611 listing.extensions = null;
612 else if(filters && fileFilter < sizeFilters / (int)sizeof(FileFilter))
613 listing.extensions = filters[fileFilter].extensions;
615 listing.extensions = customFilter.extensions;
620 while(listing.Find())
622 if(style != selectDir || (listing.stats.attribs.isDirectory))
624 row = listBox.AddRow();
626 fileName.name = listing.name;
627 if(listing.stats.attribs.isDirectory)
629 fileName.type = (listing.stats.attribs.isDrive) ? drive : folder;
630 if(listing.stats.attribs.isServer) fileName.type = server;
631 if(listing.stats.attribs.isShare) fileName.type = share;
632 if(listing.stats.attribs.isCDROM) fileName.type = cdrom;
633 if(listing.stats.attribs.isRemote) fileName.type = netDrive;
634 if(listing.stats.attribs.isRemovable)
636 if(listing.name[0] == 'A' || listing.name[0] == 'B')
637 fileName.type = floppy;
639 fileName.type = removable;
641 row.SetData(nameField, fileName);
642 row.SetData(typeField, null);
646 char extension[MAX_EXTENSION];
648 GetExtension(fileName.name, extension);
649 fileName.type = FileNameType::SelectByExtension(extension);
651 row.SetData(nameField, fileName);
652 row.SetData(typeField, extension);
653 row.SetData(sizeField, listing.stats.size);
659 if(sortOrder && sortField != nameField)
660 listBox.Sort(nameField, 1);
661 listBox.Sort(sortField, sortOrder);
663 GetNameFromListBox(activeChild == listBox);
666 if(!strcmp(currentDirectory, "/"))
669 row = listBox.AddRow();
670 fileName.name = msNetwork;
671 fileName.type = network;
673 row.SetData(nameField, fileName);
674 row.SetData(typeField, null);
676 goUp.disabled = true;
679 goUp.disabled = false;
683 listBox.typingTimeout = 0.5;
687 bool GetNamesFromRow(DataRow row, char ** selectedFileName)
691 if(style == multiOpen)
694 listBox.GetMultiSelection(selection);
700 // First allocate enough memory
701 for(item = selection.first; item; item = item.next)
704 fileName = row.GetData(nameField);
706 if(!strcmp(currentDirectory, "/"))
708 if(!strcmp(fileName->name, msNetwork))
715 totalLen += strlen(fileName->name);
716 if(item != selection.first)
719 if(selection.count > 1) totalLen += 2;
720 *selectedFileName = new char[totalLen + 1];
721 (*selectedFileName)[0] = '\0';
723 // Then build the string
724 for(item = selection.first; item; item = item.next)
727 fileName = row.GetData(nameField);
728 if(item != selection.first) strcat(*selectedFileName, " ");
729 if(selection.count > 1) strcat(*selectedFileName, "\"");
731 if(!strcmp(currentDirectory, "/"))
734 if(!strcmp(fileName->name, msNetwork))
735 strcpy(name, "\\\\");
738 name[0] = fileName->name[0];
739 name[1] = fileName->name[1];
742 strcat(*selectedFileName, name);
746 strcat(*selectedFileName, fileName->name);
747 if(selection.count > 1) strcat(*selectedFileName, "\"");
749 selection.Free(null);
755 fileName = row.GetData(nameField);
759 if(!strcmp(currentDirectory, "/"))
761 *selectedFileName = new char[3];
762 if(!strcmp(fileName->name, msNetwork))
763 strcpy(*selectedFileName, "\\\\");
766 (*selectedFileName)[0] = fileName->name[0];
767 (*selectedFileName)[1] = fileName->name[1];
768 (*selectedFileName)[2] = '\0';
774 *selectedFileName = new char[strlen(fileName->name) + 1];
775 strcpy(*selectedFileName, fileName->name);
783 bool SelectFile(char * fileName, FileDialogSelectFrom from, bool isOK)
787 char * wildcardPointer = strstr(fileName, "*");
791 if(style != selectDir)
793 int numFilters = sizeFilters / sizeof(FileFilter);
794 int numExtensions = 0;
795 char * pointer = wildcardPointer;
799 // Count the number of extensions in requested filter
802 if(pointer[1] == '.' && pointer[2])
806 pointer = strstr(pointer, "*");
810 // Try to match the extension(s) to an existing filter
814 char extension[MAX_EXTENSION], compared[MAX_EXTENSION];
815 for(filter = 0; filter<numFilters; filter++)
817 if(filters[filter].extensions)
822 for(c = 0; filters[filter].extensions[c];)
824 bool matched = false;
827 for(;(ch = filters[filter].extensions[c]) && !IS_ALUNDER(ch); c++);
828 for(;(ch = filters[filter].extensions[c]) && IS_ALUNDER(ch); c++)
829 compared[len++] = ch;
830 compared[len] = '\0';
832 for(d = 0; wildcardPointer[d]; )
835 for(;(ch = wildcardPointer[d]) && !IS_ALUNDER(ch); d++);
836 for(;(ch = wildcardPointer[d]) && IS_ALUNDER(ch); d++)
838 if(len < MAX_EXTENSION)
839 extension[len++] = ch;
841 extension[len] = '\0';
843 if(!strcmpi(extension, compared))
858 if(numMatched == numExtensions)
864 else if(!strcmp(wildcardPointer, "*") || strstr(wildcardPointer, "*.*"))
871 // Only have *.* to check for
872 else if(!strcmp(wildcardPointer, "*") || strstr(wildcardPointer, "*.*"))
875 // If we can't match it, use the custom extension
876 if(this.fileFilter == -1)
878 char extension[MAX_EXTENSION];
880 char * name = new char[numExtensions * (4 + MAX_EXTENSION)];
882 delete customFilter.extensions;
884 if(!strcmp(wildcardPointer, "*") || strstr(wildcardPointer, "*.*"))
886 strcpy(name, "All Files");
887 customFilter.extensions = null;
891 customFilter.extensions = new char[numExtensions * (2 + MAX_EXTENSION)];
892 customFilter.extensions[0] = '\0';
896 for(c = 0; wildcardPointer[c]; )
900 for(;(ch = wildcardPointer[c]) && !IS_ALUNDER(ch); c++);
901 for(;(ch = wildcardPointer[c]) && IS_ALUNDER(ch); c++)
903 if(len < MAX_EXTENSION)
904 extension[len++] = ch;
906 extension[len] = '\0';
911 strcat(customFilter.extensions, ", ");
914 strcat(name, extension);
916 strcat(customFilter.extensions, ".");
918 strcat(customFilter.extensions, extension);
926 customFilterRow = filter.AddRow();
927 customFilterRow.tag = numFilters + 1;
930 customFilterRow.SetData(null, name);
932 fileFilter = numFilters + 1;
937 filter.currentRow = filter.FindRow(fileFilter);
941 *wildcardPointer = '\0';
944 if(style == multiOpen)
948 bool needQuotes = strchr(fileName, '\"') != null;
949 char currentFileName[MAX_LOCATION], * curFileName = currentFileName;
951 OldList selections { };
952 OldLink selection = null;
964 (*curFileName) = '\0';
966 selection = OldLink { data = new char[strlen(currentFileName)+1] };
967 strcpy(selection.data, currentFileName);
968 selections.Add(selection);
970 curFileName = currentFileName;
975 if(needQuotes && !quoted)
978 *(curFileName++) = ch;
984 multiFilePaths = new char *[selections.count];
986 for(selection = selections.first; selection; selection = selection.next)
988 char * fileName = selection.data;
991 strcpy(currentFileName, currentDirectory);
992 if(PathCat(currentFileName, fileName))
994 FileFixCase(currentFileName);
995 exists = FileExists(currentFileName);
996 if(exists.isDirectory)
998 strcpy(currentDirectory, currentFileName);
1002 else if(exists || mayNotExist)
1004 char ** path = &multiFilePaths[numSelections++];
1005 *path = new char[strlen(currentFileName)+1];
1006 strcpy(*path, currentFileName);
1010 if(exists && result && from == fromListBox) // From List Box
1012 char pathName[MAX_LOCATION];
1013 GetLastDirectory(this.fileName.line.text, pathName);
1014 this.fileName.Clear();
1015 if(!exists.isDirectory)
1016 this.fileName.PutS(pathName);
1021 selections.Free(OldLink::Free);
1026 for(c = 0; c<numSelections; c++)
1027 if(multiFilePaths[c])
1028 delete multiFilePaths[c];
1029 delete multiFilePaths;
1035 strcpy(filePath, currentDirectory);
1036 if(PathCat(filePath, fileName))
1038 FileFixCase(filePath);
1039 exists = FileExists(filePath);
1040 if(exists.isDirectory && (style != selectDir || !isOK))
1042 strcpy(currentDirectory, filePath);
1048 // *** SAVING ONLY ****
1051 if(fileType >= 0 && fileType < sizeTypes)
1053 FileType type = types[fileType];
1054 if(type.forceExtension && type.typeExtension)
1056 char extension[MAX_EXTENSION];
1057 GetExtension(filePath, extension);
1058 if(type.forceExtension == always || !extension[0])
1060 ChangeExtension(filePath, type.typeExtension, filePath);
1061 exists = FileExists(filePath);
1065 if(!exists || MessageBox { master = this, type = yesNo, text = "File Already Exists", contents = "Replace existing file?" }.Modal() == yes)
1068 else if(exists || mayNotExist)
1070 if(style != selectDir ||
1071 (strcmp(filePath, "\\\\") &&
1072 strcmp(filePath, "\\\\") &&
1073 !(exists.isServer)))
1076 // *** DIRECTORY SELECTION ONLY ****
1077 else if(isOK && style == selectDir &&
1078 MessageBox { this, type = yesNo, text = "Directory doesn't exist", contents = "Create directory?" }.Modal() == yes)
1080 if(MakeDir(filePath))
1085 if(exists && result && from == fromListBox) // From List Box
1087 char pathName[MAX_LOCATION];
1088 GetLastDirectory(this.fileName.line.text, pathName);
1089 this.fileName.Clear();
1090 if(!exists.isDirectory)
1091 this.fileName.PutS(pathName);
1096 if(!exists && result && from == fromDropBox) // drive Drop Box
1102 Destroy(DialogResult::ok);
1111 for(c = 0; c<numSelections; c++)
1112 delete multiFilePaths[c];
1113 delete multiFilePaths;
1119 // Fix up config input directory
1120 char fileName[MAX_FILENAME];
1121 #if defined(__WIN32__)
1122 char * dirOccur = SearchString(filePath, 0, currentDirectory, false, false);
1124 char * dirOccur = strstr(filePath, currentDirectory);
1128 dirOccur += strlen(currentDirectory);
1129 for(;*dirOccur && (*dirOccur == '/' || *dirOccur == '\\'); dirOccur++);
1130 strcpy(fileName, dirOccur);
1133 strcpy(fileName, filePath);
1135 this.fileName.Clear();
1136 this.fileName.PutS(fileName);
1139 GetNameFromListBox(false);
1141 fileName.Activate();
1145 FileDialogType style;
1146 FileFilter customFilter;
1147 DataRow customFilterRow;
1148 bool getNameFromListBox;
1149 BitmapResource icons[FileNameType];
1151 char currentDirectory[MAX_DIRECTORY];
1152 char filePath[MAX_LOCATION];
1153 FileFilter * filters;
1157 int fileFilter, fileType;
1160 char ** multiFilePaths;
1163 // ListBox Configuration
1164 DataField sortField;
1167 // File Extension Filter
1170 this, text = "Filter:", anchor = { left = 96, right = 104, bottom = 16 }, hotKey = altR;
1172 bool NotifySelect(DropBox control, DataRow row, Modifiers mods)
1174 fileFilter = row ? row.tag : 0;
1182 this, inactive = true, anchor = { left = 8, bottom = 3 + 16 }, labeledWindow = filter
1188 this, text = "As Type:", visible = false, anchor = { left = 96, right = 104, bottom = 16 }, hotKey = altT;
1190 bool NotifySelect(DropBox control, DataRow row, Modifiers mods)
1192 char * selectedFileName = null;
1193 fileType = row ? row.tag : 0;
1194 if(style == save && types && types[fileType].typeExtension)
1196 if(getNameFromListBox)
1198 if(GetNamesFromRow(listBox.currentRow, &selectedFileName))
1203 char * fileName = this.fileName.line.text;
1204 //selectedFileName = new char[strlen(fileName)+1]; // Room to change extension???
1205 selectedFileName = new char[MAX_FILENAME];
1206 strcpy(selectedFileName, fileName);
1208 ChangeExtension(selectedFileName, types[fileType].typeExtension, selectedFileName);
1209 fileName.Select(null,0,0, null,0,0);
1210 fileName.PutS(selectedFileName);
1211 GetNameFromListBox(false);
1213 delete selectedFileName;
1220 this, inactive = true, visible = false, anchor = { left = 8, bottom = 19 }, labeledWindow = type;
1226 this, isDefault = true, text = "OK", anchor = { right = 10, bottom = 32 + 16 - 1 }, size = { 80 };
1228 bool NotifyClicked(Button control, int x, int y, Modifiers mods)
1231 char * selectedFileName = null;
1232 if(getNameFromListBox)
1234 GetNamesFromRow(listBox.currentRow, &selectedFileName);
1235 result = SelectFile(selectedFileName, fromEditBox, control.id == DialogResult::ok);
1236 if(result && style == selectDir)
1241 char * fileName = this.fileName.line.text;
1242 selectedFileName = new char[strlen(fileName)+1];
1243 strcpy(selectedFileName, fileName);
1244 result = SelectFile(selectedFileName, fromListBox, control.id == DialogResult::ok);
1245 if(result && style == selectDir)
1246 this.fileName.Activate();
1248 delete selectedFileName;
1253 // Open Button (SelectDir only)
1256 this, visible = false, text = "Open", hotKey = altO, anchor = { right = 100, bottom = 16 - 1 }, size = { 80 };
1257 NotifyClicked = ok.NotifyClicked;
1263 this, text = "Cancel", anchor = { right = 10, bottom = 16 - 1 }, size = { 80 }, hotKey = escape;
1264 bool NotifyClicked(Button control, int x, int y, Modifiers mods)
1266 Destroy(DialogResult::cancel);
1274 this, text = "Look in:", anchor = { left = 81, top = 8, right = 109 }, hotKey = altL, maxShown = 12;
1276 bool OnKeyHit(Key key, unichar ch)
1278 if(key == wheelDown || key == wheelUp)
1280 ((FileDialog)master).listBox.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit, key, ch);
1286 bool NotifySelect(DropBox control, DataRow row, Modifiers mods)
1290 FileName * fileName = row.GetData(null);
1291 char name[MAX_LOCATION] = "/";
1295 if(!strcmp(fileName->name, msNetwork) ||
1296 (currentDirectory[0] == '\\' &&
1297 currentDirectory[1] == '\\' &&
1298 strcmp(fileName->name, rootName) &&
1299 (!fileName->name[0] || fileName->name[1] != ':')))
1301 strcpy(name, "\\\\");
1306 if(fileName->indent > 1)
1308 name[0] = currentDirectory[0];
1314 else if(fileName->indent == 1)
1316 name[0] = fileName->name[0];
1324 if(indent < fileName->indent)
1326 for(; currentDirectory[c]; )
1330 char directory[MAX_FILENAME];
1331 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
1332 for(;(ch = currentDirectory[c]) && (ch != '/' && ch != '\\'); c++)
1334 if(len < MAX_FILENAME)
1335 directory[len++] = ch;
1337 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
1338 directory[len] = '\0';
1340 if(indent >= fileName->indent) break;
1341 PathCat(name, directory);
1346 SelectFile(name, fromDropBox, false);
1352 DataField lookInField { dataType = "FileName", userData = this };
1356 this, position = { 10, 11 }, labeledWindow = lookIn;
1362 this, borderStyle = deep, hasVertScroll = true, hasHorzScroll = true,
1363 anchor = { left = 8, right = 8, top = 40, bottom = 64 + 16 },
1364 hasHeader = true, moveFields = true, resizable = true, sortable = true;
1366 bool NotifySelect(ListBox control, DataRow row, Modifiers mods)
1368 GetNameFromListBox(true);
1372 bool NotifyDoubleClick(ListBox control, int x, int y, Modifiers mods)
1375 char * selectedFileName = null;
1376 if(GetNamesFromRow(control.currentRow, &selectedFileName))
1378 result = SelectFile(selectedFileName, fromEditBox, false);
1380 delete selectedFileName;
1384 bool NotifyKeyDown(ListBox control, DataRow row, Key key, unichar ch)
1386 if(key == backSpace)
1388 if(strcmp(currentDirectory, "/"))
1389 goUp.NotifyClicked(this, goUp, 0,0, key.modifiers);
1394 bool NotifySort(ListBox control, DataField field, Modifiers mods)
1397 sortOrder = field.sortOrder;
1401 bool NotifyActivate(Window control, bool active, Window previous)
1404 GetNameFromListBox(true);
1409 DataField nameField { header = "Name", dataType = "FileName", width = 304, userData = this }; // editable = true
1410 DataField typeField { header = "Type", dataType = /*"String"*/ "char *", width = 40 };
1411 DataField sizeField { header = "Size", dataType = "FileSize", width = 96, alignment = right };
1416 this, inactive = true, anchor = { right = 79, top = 8 }, size = { 24, 24 },
1417 bitmap = { "<:ecere>actions/goUp.png", alphaBlend = true };
1420 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1423 notRoot = StripLastDirectory(currentDirectory, currentDirectory);
1425 strcpy(currentDirectory, "/");
1431 Button createDirectory
1433 this, inactive = true, anchor = { right = 51, top = 8 }, size = { 24, 24 },
1434 bitmap = { "<:ecere>actions/folderNew.png", alphaBlend = true };
1435 symbol = 30; // what the heck is that?
1437 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1439 if(CreateDirectoryDialog { master = this, parent = parent, currentDirectory = currentDirectory }.Modal() == ok )
1445 // File name editbox
1448 this, text = "File Name:", anchor = { left = 96, bottom = 32 + 16, right = 104 }, size.h = 20, hotKey = altF;
1450 bool NotifyActivate(Window control, bool active, Window previous)
1454 char * selectedFileName = null;
1456 if(getNameFromListBox)
1458 DataRow row = listBox.currentRow;
1461 if(GetNamesFromRow(row, &selectedFileName))
1464 fileName.PutS(selectedFileName);
1465 fileName.Select(null,0,0, null,0,0);
1467 GetNameFromListBox(false);
1470 delete selectedFileName;
1471 editText = fileName.contents;
1472 ok.disabled = !editText || !editText[0];
1477 void NotifyUpdate(EditBox control)
1479 GetNameFromListBox(false);
1485 this, inactive = true, anchor = { left = 8, bottom = 35 + 16 };
1486 labeledWindow = fileName;
1490 public class CreateDirectoryDialog : Window
1492 background = activeBorder;
1493 minClientSize = Size { 240, 100 };
1496 text = "Create Directory";
1500 property char * currentDirectory
1504 GetWorkingDir(currentDirectory, MAX_DIRECTORY); // is this necessary?
1505 PathCat(currentDirectory, value);
1506 FileFixCase(currentDirectory);
1508 get { return (char *)currentDirectory; }
1513 char currentDirectory[MAX_DIRECTORY];
1515 CreateDirectoryDialog()
1519 GetWorkingDir(currentDirectory, MAX_DIRECTORY);
1520 FileFixCase(currentDirectory);
1523 ~CreateDirectoryDialog()
1529 newDirectoryName.SelectAll();
1535 parent = this, isDefault = true, position = { 70, 60 }, size = { 60 }, text = "OK";
1536 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1538 if(newDirectoryName.contents && newDirectoryName.contents[0])
1540 char newDirPath[MAX_DIRECTORY];
1541 strcpy(newDirPath, currentDirectory);
1542 PathCat(newDirPath, newDirectoryName.contents);
1543 if(!FileExists(newDirPath).isDirectory)
1545 MakeDir(newDirPath);
1546 Destroy(DialogResult::ok);
1549 MessageBox { master = this, parent = parent, type = ok, text = "Create Directory Error", contents = "Directory already exists." }.Modal();
1552 MessageBox { master = this, parent = parent, type = ok, text = "Create Directory Error", contents = "Please enter a name." }.Modal();
1559 parent = this, position = { 140, 60 }, size = { 60 }, hotKey = escape, text = "Cancel";
1560 NotifyClicked = ButtonCloseDialog;
1563 EditBox newDirectoryName
1565 this, textHorzScroll = true, anchor = { left = 10, right = 10, top = 30 }, size = { 250 };
1566 hotKey = altN, text = "Name";
1567 contents = "New Directory";
1569 Label { this, position = { 10, 10 }, labeledWindow = newDirectoryName };