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 minClientSize = { 500, 300 };
254 property FileDialogType type
256 get { return style; }
259 int numTypes = sizeTypes / sizeof(FileType);
260 int rightOffset = (value != selectDir && numTypes > 0) ? 48 : 16;
264 if(value == selectDir)
267 filter.visible = false;
268 filterLabel.visible = false;
270 type.visible = false;
271 typeLabel.visible = false;
274 open.isDefault = true;
277 ok.id = DialogResult::ok;
279 ok.isDefault = false;
284 filter.visible = true;
285 filterLabel.visible = true;
288 type.visible = numTypes != 0;
289 typeLabel.visible = numTypes != 0;
291 open.visible = false;
292 open.isDefault = false;
299 ok.anchor = { right = 10, bottom = 32 + rightOffset - 1 };
302 cancel.anchor = { right = 10, bottom = rightOffset - 1 };
304 listBox.anchor = { left = 8, right = 8, top = 40, bottom = 64 + rightOffset };
305 fileName.anchor = { left = 96, bottom = 32 + rightOffset, right = 104 };
306 fileNameLabel.anchor = { left = 8, bottom = 35 + rightOffset };
308 listBox.multiSelect = value == multiOpen;
309 fileName.text = (value == selectDir) ? "Directory:" : "File Name:";
313 // Stuff currently in config moving to FileDialog:
314 property char * filePath { set { strcpy(filePath, value); } get { return (char *)filePath; } };
315 property char * currentDirectory
319 GetWorkingDir(currentDirectory, MAX_DIRECTORY);
320 PathCat(currentDirectory, value);
321 FileFixCase(currentDirectory);
323 get { return (char *)currentDirectory; }
325 property FileFilter * filters { set { filters = value; } get { return filters; } };
326 property FileType * types { set { types = value; } get { return types; } };
328 // Replace with Array system
329 property int sizeFilters
333 int numFilters = value / sizeof(FileFilter);
338 // File Extension Filter
340 // filter.AddField(null);
343 for(c = 0; c<numFilters; c++)
345 DataRow row = filter.AddString(filters[c].name);
350 filter.AddString("All files");
352 if(fileFilter >= numFilters) fileFilter = 0;
353 filter.currentRow = filter.FindRow(fileFilter);
355 get { return sizeFilters; }
357 property int sizeTypes
361 int numTypes = value / sizeof(FileType);
362 int rightOffset = (numTypes > 0) ? 48 : 16;
367 filter.anchor = { left = 96, right = 104, bottom = rightOffset };
368 filterLabel.anchor = { left = 8, bottom = 3 + rightOffset };
370 if(style != selectDir)
373 type.visible = numTypes ? true : false;
374 typeLabel.visible = numTypes ? true : false;
377 ok.anchor = { right = 10, bottom = 32 + rightOffset - 1 };
380 cancel.anchor = { right = 10, bottom = rightOffset - 1 };
383 listBox.anchor = { left = 8, right = 8, top = 40, bottom = 64 + rightOffset };
384 fileName.anchor = { left = 96, bottom = 32 + rightOffset, right = 104 };
385 fileNameLabel.anchor = { left = 8, bottom = 35 + rightOffset };
393 // type.AddField(null);
396 for(c = 0; c<numTypes; c++)
398 DataRow row = type.AddString(types[c].name);
402 if(fileType >= numTypes) fileType = 0;
404 type.currentRow = type.FindRow(fileType);
407 get { return sizeTypes; }
410 property int filter { set { fileFilter = value; } get { return fileFilter; } };
411 property int fileType { set { fileType = value; } get { return fileType; } };
412 property bool mayNotExist { set { mayNotExist = value; } get { return mayNotExist; } };
415 property int numSelections { get { return numSelections; } };
416 property char ** multiFilePaths { get { return multiFilePaths; } };
423 lookIn.AddField(lookInField);
424 listBox.AddField(nameField);
425 listBox.AddField(typeField);
426 listBox.AddField(sizeField);
428 filter.currentRow = filter.AddString("All files");
430 GetWorkingDir(currentDirectory, MAX_DIRECTORY);
431 FileFixCase(currentDirectory);
434 for(c = 0; c<FileNameType::enumSize; c++)
436 icons[c] = BitmapResource { iconNames[c], alphaBlend = true };
437 AddResource(icons[c]);
443 delete customFilter.extensions;
447 for(c = 0; c<numSelections; c++)
448 delete multiFilePaths[c];
449 delete multiFilePaths;
456 char tmpDir[MAX_FILENAME];
459 FileListing listing { "/" };
464 // Fill the path dropbox
467 row = lookIn.AddRow();
470 fileName.name = rootName;
474 fileName.type = computer;
475 row.SetData(null, fileName);
476 lookIn.currentRow = row;
480 while(listing.Find())
482 row = lookIn.AddRow();
484 fileName.name = listing.name;
485 fileName.type = drive;
486 if(listing.stats.attribs.isCDROM) fileName.type = cdrom;
487 if(listing.stats.attribs.isRemote) fileName.type = netDrive;
488 if(listing.stats.attribs.isRemovable)
490 if(listing.name[0] == 'A' || listing.name[0] == 'B')
491 fileName.type = floppy;
493 fileName.type = removable;
497 row.SetData(null, fileName);
500 if(listing.name[0] == currentDirectory[0] &&
501 listing.name[1] == currentDirectory[1])
504 for(c = start; currentDirectory[c]; )
508 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
509 for(;(ch = currentDirectory[c]) && (ch != '/' && ch != '\\'); c++)
511 if(len < MAX_FILENAME)
514 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
519 row = lookIn.AddRow();
520 fileName.name = tmpDir;
521 fileName.type = ch ? folder : folderOpen;
523 row.SetData(null, fileName);
526 lookIn.currentRow = row;
530 lookIn.currentRow = row;
535 row = lookIn.AddRow();
536 fileName.name = msNetwork;
537 fileName.type = network;
539 row.SetData(null, fileName);
540 if(!strcmp(currentDirectory, "\\\\"))
541 lookIn.currentRow = row;
544 if(currentDirectory[0] == '\\' && currentDirectory[1] == '\\')
546 for(c = 2; currentDirectory[c]; )
550 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
551 for(;(ch = currentDirectory[c]) && (ch != '/' && ch != '\\'); c++)
553 if(len < MAX_FILENAME)
556 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
561 row = lookIn.AddRow();
562 fileName.name = tmpDir;
564 if(fileName.indent == 1)
565 fileName.type = server;
566 else if(fileName.indent == 2)
567 fileName.type = share;
569 fileName.type = ch ? folder : folderOpen;
570 row.SetData(null, fileName);
573 lookIn.currentRow = row;
576 lookIn.currentRow = row;
582 // flag = false : Get Name From Edit Box, flag = true : Get Name From List Box
583 void GetNameFromListBox(bool flag)
588 if(style == multiOpen)
589 okDisabled = listBox.numSelections == 0;
591 okDisabled = listBox.currentRow == null;
592 if(okDisabled) flag = false;
595 okDisabled = !fileName || !fileName.line.text[0];
597 getNameFromListBox = flag;
598 ok.disabled = okDisabled;
599 open.disabled = okDisabled;
604 FileListing listing { currentDirectory };
609 if(sizeFilters < sizeof(FileFilter) && !fileFilter)
610 listing.extensions = null;
611 else if(filters && fileFilter < sizeFilters / (int)sizeof(FileFilter))
612 listing.extensions = filters[fileFilter].extensions;
614 listing.extensions = customFilter.extensions;
619 while(listing.Find())
621 if(style != selectDir || (listing.stats.attribs.isDirectory))
623 row = listBox.AddRow();
625 fileName.name = listing.name;
626 if(listing.stats.attribs.isDirectory)
628 fileName.type = (listing.stats.attribs.isDrive) ? drive : folder;
629 if(listing.stats.attribs.isServer) fileName.type = server;
630 if(listing.stats.attribs.isShare) fileName.type = share;
631 if(listing.stats.attribs.isCDROM) fileName.type = cdrom;
632 if(listing.stats.attribs.isRemote) fileName.type = netDrive;
633 if(listing.stats.attribs.isRemovable)
635 if(listing.name[0] == 'A' || listing.name[0] == 'B')
636 fileName.type = floppy;
638 fileName.type = removable;
640 row.SetData(nameField, fileName);
641 row.SetData(typeField, null);
645 char extension[MAX_EXTENSION];
647 GetExtension(fileName.name, extension);
648 fileName.type = FileNameType::SelectByExtension(extension);
650 row.SetData(nameField, fileName);
651 row.SetData(typeField, extension);
652 row.SetData(sizeField, listing.stats.size);
658 if(sortOrder && sortField != nameField)
659 listBox.Sort(nameField, 1);
660 listBox.Sort(sortField, sortOrder);
662 GetNameFromListBox(activeChild == listBox);
665 if(!strcmp(currentDirectory, "/"))
668 row = listBox.AddRow();
669 fileName.name = msNetwork;
670 fileName.type = network;
672 row.SetData(nameField, fileName);
673 row.SetData(typeField, null);
675 goUp.disabled = true;
678 goUp.disabled = false;
682 listBox.typingTimeout = 0.5;
686 bool GetNamesFromRow(DataRow row, char ** selectedFileName)
690 if(style == multiOpen)
693 listBox.GetMultiSelection(selection);
699 // First allocate enough memory
700 for(item = selection.first; item; item = item.next)
703 fileName = row.GetData(nameField);
705 if(!strcmp(currentDirectory, "/"))
707 if(!strcmp(fileName->name, msNetwork))
714 totalLen += strlen(fileName->name);
715 if(item != selection.first)
718 if(selection.count > 1) totalLen += 2;
719 *selectedFileName = new char[totalLen + 1];
720 (*selectedFileName)[0] = '\0';
722 // Then build the string
723 for(item = selection.first; item; item = item.next)
726 fileName = row.GetData(nameField);
727 if(item != selection.first) strcat(*selectedFileName, " ");
728 if(selection.count > 1) strcat(*selectedFileName, "\"");
730 if(!strcmp(currentDirectory, "/"))
733 if(!strcmp(fileName->name, msNetwork))
734 strcpy(name, "\\\\");
737 name[0] = fileName->name[0];
738 name[1] = fileName->name[1];
741 strcat(*selectedFileName, name);
745 strcat(*selectedFileName, fileName->name);
746 if(selection.count > 1) strcat(*selectedFileName, "\"");
748 selection.Free(null);
754 fileName = row.GetData(nameField);
758 if(!strcmp(currentDirectory, "/"))
760 *selectedFileName = new char[3];
761 if(!strcmp(fileName->name, msNetwork))
762 strcpy(*selectedFileName, "\\\\");
765 (*selectedFileName)[0] = fileName->name[0];
766 (*selectedFileName)[1] = fileName->name[1];
767 (*selectedFileName)[2] = '\0';
773 *selectedFileName = new char[strlen(fileName->name) + 1];
774 strcpy(*selectedFileName, fileName->name);
782 bool SelectFile(char * fileName, FileDialogSelectFrom from, bool isOK)
786 char * wildcardPointer = strstr(fileName, "*");
790 if(style != selectDir)
792 int numFilters = sizeFilters / sizeof(FileFilter);
793 int numExtensions = 0;
794 char * pointer = wildcardPointer;
798 // Count the number of extensions in requested filter
801 if(pointer[1] == '.' && pointer[2])
805 pointer = strstr(pointer, "*");
809 // Try to match the extension(s) to an existing filter
813 char extension[MAX_EXTENSION], compared[MAX_EXTENSION];
814 for(filter = 0; filter<numFilters; filter++)
816 if(filters[filter].extensions)
821 for(c = 0; filters[filter].extensions[c];)
823 bool matched = false;
826 for(;(ch = filters[filter].extensions[c]) && !IS_ALUNDER(ch); c++);
827 for(;(ch = filters[filter].extensions[c]) && IS_ALUNDER(ch); c++)
828 compared[len++] = ch;
829 compared[len] = '\0';
831 for(d = 0; wildcardPointer[d]; )
834 for(;(ch = wildcardPointer[d]) && !IS_ALUNDER(ch); d++);
835 for(;(ch = wildcardPointer[d]) && IS_ALUNDER(ch); d++)
837 if(len < MAX_EXTENSION)
838 extension[len++] = ch;
840 extension[len] = '\0';
842 if(!strcmpi(extension, compared))
857 if(numMatched == numExtensions)
863 else if(!strcmp(wildcardPointer, "*") || strstr(wildcardPointer, "*.*"))
870 // Only have *.* to check for
871 else if(!strcmp(wildcardPointer, "*") || strstr(wildcardPointer, "*.*"))
874 // If we can't match it, use the custom extension
875 if(this.fileFilter == -1)
877 char extension[MAX_EXTENSION];
879 char * name = new char[numExtensions * (4 + MAX_EXTENSION)];
881 delete customFilter.extensions;
883 if(!strcmp(wildcardPointer, "*") || strstr(wildcardPointer, "*.*"))
885 strcpy(name, "All Files");
886 customFilter.extensions = null;
890 customFilter.extensions = new char[numExtensions * (2 + MAX_EXTENSION)];
891 customFilter.extensions[0] = '\0';
895 for(c = 0; wildcardPointer[c]; )
899 for(;(ch = wildcardPointer[c]) && !IS_ALUNDER(ch); c++);
900 for(;(ch = wildcardPointer[c]) && IS_ALUNDER(ch); c++)
902 if(len < MAX_EXTENSION)
903 extension[len++] = ch;
905 extension[len] = '\0';
910 strcat(customFilter.extensions, ", ");
913 strcat(name, extension);
915 strcat(customFilter.extensions, ".");
917 strcat(customFilter.extensions, extension);
925 customFilterRow = filter.AddRow();
926 customFilterRow.tag = numFilters + 1;
929 customFilterRow.SetData(null, name);
931 fileFilter = numFilters + 1;
936 filter.currentRow = filter.FindRow(fileFilter);
940 *wildcardPointer = '\0';
943 if(style == multiOpen)
947 bool needQuotes = strchr(fileName, '\"') != null;
948 char currentFileName[MAX_LOCATION], * curFileName = currentFileName;
950 OldList selections { };
951 OldLink selection = null;
963 (*curFileName) = '\0';
965 selection = OldLink { data = new char[strlen(currentFileName)+1] };
966 strcpy(selection.data, currentFileName);
967 selections.Add(selection);
969 curFileName = currentFileName;
974 if(needQuotes && !quoted)
977 *(curFileName++) = ch;
983 multiFilePaths = new char *[selections.count];
985 for(selection = selections.first; selection; selection = selection.next)
987 char * fileName = selection.data;
990 strcpy(currentFileName, currentDirectory);
991 if(PathCat(currentFileName, fileName))
993 FileFixCase(currentFileName);
994 exists = FileExists(currentFileName);
995 if(exists.isDirectory)
997 strcpy(currentDirectory, currentFileName);
1001 else if(exists || mayNotExist)
1003 char ** path = &multiFilePaths[numSelections++];
1004 *path = new char[strlen(currentFileName)+1];
1005 strcpy(*path, currentFileName);
1009 if(exists && result && from == fromListBox) // From List Box
1011 char pathName[MAX_LOCATION];
1012 GetLastDirectory(this.fileName.line.text, pathName);
1013 this.fileName.Clear();
1014 if(!exists.isDirectory)
1015 this.fileName.PutS(pathName);
1020 selections.Free(OldLink::Free);
1025 for(c = 0; c<numSelections; c++)
1026 if(multiFilePaths[c])
1027 delete multiFilePaths[c];
1028 delete multiFilePaths;
1034 strcpy(filePath, currentDirectory);
1035 if(PathCat(filePath, fileName))
1037 FileFixCase(filePath);
1038 exists = FileExists(filePath);
1039 if(exists.isDirectory && (style != selectDir || !isOK))
1041 strcpy(currentDirectory, filePath);
1047 // *** SAVING ONLY ****
1050 if(fileType >= 0 && fileType < sizeTypes)
1052 FileType type = types[fileType];
1053 if(type.forceExtension && type.typeExtension)
1055 char extension[MAX_EXTENSION];
1056 GetExtension(filePath, extension);
1057 if(type.forceExtension == always || !extension[0])
1059 ChangeExtension(filePath, type.typeExtension, filePath);
1060 exists = FileExists(filePath);
1064 if(!exists || MessageBox { master = this, type = yesNo, text = "File Already Exists", contents = "Replace existing file?" }.Modal() == yes)
1067 else if(exists || mayNotExist)
1069 if(style != selectDir ||
1070 (strcmp(filePath, "\\\\") &&
1071 strcmp(filePath, "\\\\") &&
1072 !(exists.isServer)))
1075 // *** DIRECTORY SELECTION ONLY ****
1076 else if(isOK && style == selectDir &&
1077 MessageBox { this, type = yesNo, text = "Directory doesn't exist", contents = "Create directory?" }.Modal() == yes)
1079 if(MakeDir(filePath))
1084 if(exists && result && from == fromListBox) // From List Box
1086 char pathName[MAX_LOCATION];
1087 GetLastDirectory(this.fileName.line.text, pathName);
1088 this.fileName.Clear();
1089 if(!exists.isDirectory)
1090 this.fileName.PutS(pathName);
1095 if(!exists && result && from == fromDropBox) // drive Drop Box
1101 Destroy(DialogResult::ok);
1110 for(c = 0; c<numSelections; c++)
1111 delete multiFilePaths[c];
1112 delete multiFilePaths;
1118 // Fix up config input directory
1119 char fileName[MAX_FILENAME];
1120 #if defined(__WIN32__)
1121 char * dirOccur = SearchString(filePath, 0, currentDirectory, false, false);
1123 char * dirOccur = strstr(filePath, currentDirectory);
1127 dirOccur += strlen(currentDirectory);
1128 for(;*dirOccur && (*dirOccur == '/' || *dirOccur == '\\'); dirOccur++);
1129 strcpy(fileName, dirOccur);
1132 strcpy(fileName, filePath);
1134 this.fileName.Clear();
1135 this.fileName.PutS(fileName);
1138 GetNameFromListBox(false);
1140 fileName.Activate();
1144 FileDialogType style;
1145 FileFilter customFilter;
1146 DataRow customFilterRow;
1147 bool getNameFromListBox;
1148 BitmapResource icons[FileNameType];
1150 char currentDirectory[MAX_DIRECTORY];
1151 char filePath[MAX_LOCATION];
1152 FileFilter * filters;
1156 int fileFilter, fileType;
1159 char ** multiFilePaths;
1162 // ListBox Configuration
1163 DataField sortField;
1166 // File Extension Filter
1169 this, text = "Filter:", anchor = { left = 96, right = 104, bottom = 16 }, hotKey = altR;
1171 bool NotifySelect(DropBox control, DataRow row, Modifiers mods)
1173 fileFilter = row ? row.tag : 0;
1181 this, inactive = true, anchor = { left = 8, bottom = 3 + 16 }, labeledWindow = filter
1187 this, text = "As Type:", visible = false, anchor = { left = 96, right = 104, bottom = 16 }, hotKey = altT;
1189 bool NotifySelect(DropBox control, DataRow row, Modifiers mods)
1191 char * selectedFileName = null;
1192 fileType = row ? row.tag : 0;
1193 if(style == save && types && types[fileType].typeExtension)
1195 if(getNameFromListBox)
1197 if(GetNamesFromRow(listBox.currentRow, &selectedFileName))
1202 char * fileName = this.fileName.line.text;
1203 //selectedFileName = new char[strlen(fileName)+1]; // Room to change extension???
1204 selectedFileName = new char[MAX_FILENAME];
1205 strcpy(selectedFileName, fileName);
1207 ChangeExtension(selectedFileName, types[fileType].typeExtension, selectedFileName);
1208 fileName.Select(null,0,0, null,0,0);
1209 fileName.PutS(selectedFileName);
1210 GetNameFromListBox(false);
1212 delete selectedFileName;
1219 this, inactive = true, visible = false, anchor = { left = 8, bottom = 19 }, labeledWindow = type;
1225 this, isDefault = true, text = "OK", anchor = { right = 10, bottom = 32 + 16 - 1 }, size = { 80 };
1227 bool NotifyClicked(Button control, int x, int y, Modifiers mods)
1230 char * selectedFileName = null;
1231 if(getNameFromListBox)
1233 GetNamesFromRow(listBox.currentRow, &selectedFileName);
1234 result = SelectFile(selectedFileName, fromEditBox, control.id == DialogResult::ok);
1235 if(result && style == selectDir)
1240 char * fileName = this.fileName.line.text;
1241 selectedFileName = new char[strlen(fileName)+1];
1242 strcpy(selectedFileName, fileName);
1243 result = SelectFile(selectedFileName, fromListBox, control.id == DialogResult::ok);
1244 if(result && style == selectDir)
1245 this.fileName.Activate();
1247 delete selectedFileName;
1252 // Open Button (SelectDir only)
1255 this, visible = false, text = "Open", hotKey = altO, anchor = { right = 100, bottom = 16 - 1 }, size = { 80 };
1256 NotifyClicked = ok.NotifyClicked;
1262 this, text = "Cancel", anchor = { right = 10, bottom = 16 - 1 }, size = { 80 }, hotKey = escape;
1263 bool NotifyClicked(Button control, int x, int y, Modifiers mods)
1265 Destroy(DialogResult::cancel);
1273 this, text = "Look in:", anchor = { left = 81, top = 8, right = 109 }, hotKey = altL, maxShown = 12;
1275 bool OnKeyHit(Key key, unichar ch)
1277 if(key == wheelDown || key == wheelUp)
1279 ((FileDialog)master).listBox.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit, key, ch);
1285 bool NotifySelect(DropBox control, DataRow row, Modifiers mods)
1289 FileName * fileName = row.GetData(null);
1290 char name[MAX_LOCATION] = "/";
1294 if(!strcmp(fileName->name, msNetwork) ||
1295 (currentDirectory[0] == '\\' &&
1296 currentDirectory[1] == '\\' &&
1297 strcmp(fileName->name, rootName) &&
1298 (!fileName->name[0] || fileName->name[1] != ':')))
1300 strcpy(name, "\\\\");
1305 if(fileName->indent > 1)
1307 name[0] = currentDirectory[0];
1313 else if(fileName->indent == 1)
1315 name[0] = fileName->name[0];
1323 if(indent < fileName->indent)
1325 for(; currentDirectory[c]; )
1329 char directory[MAX_FILENAME];
1330 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
1331 for(;(ch = currentDirectory[c]) && (ch != '/' && ch != '\\'); c++)
1333 if(len < MAX_FILENAME)
1334 directory[len++] = ch;
1336 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
1337 directory[len] = '\0';
1339 if(indent >= fileName->indent) break;
1340 PathCat(name, directory);
1345 SelectFile(name, fromDropBox, false);
1351 DataField lookInField { dataType = "FileName", userData = this };
1355 this, position = { 10, 11 }, labeledWindow = lookIn;
1361 this, borderStyle = deep, hasVertScroll = true, hasHorzScroll = true,
1362 anchor = { left = 8, right = 8, top = 40, bottom = 64 + 16 },
1363 hasHeader = true, moveFields = true, resizable = true, sortable = true;
1365 bool NotifySelect(ListBox control, DataRow row, Modifiers mods)
1367 GetNameFromListBox(true);
1371 bool NotifyDoubleClick(ListBox control, int x, int y, Modifiers mods)
1374 char * selectedFileName = null;
1375 if(GetNamesFromRow(control.currentRow, &selectedFileName))
1377 result = SelectFile(selectedFileName, fromEditBox, false);
1379 delete selectedFileName;
1383 bool NotifyKeyDown(ListBox control, DataRow row, Key key, unichar ch)
1385 if(key == backSpace)
1387 if(strcmp(currentDirectory, "/"))
1388 goUp.NotifyClicked(this, goUp, 0,0, key.modifiers);
1393 bool NotifySort(ListBox control, DataField field, Modifiers mods)
1396 sortOrder = field.sortOrder;
1400 bool NotifyActivate(Window control, bool active, Window previous)
1403 GetNameFromListBox(true);
1408 DataField nameField { header = "Name", dataType = "FileName", width = 304, userData = this }; // editable = true
1409 DataField typeField { header = "Type", dataType = /*"String"*/ "char *", width = 40 };
1410 DataField sizeField { header = "Size", dataType = "FileSize", width = 96, alignment = right };
1415 this, inactive = true, anchor = { right = 79, top = 8 }, size = { 24, 24 },
1416 bitmap = { "<:ecere>actions/goUp.png", alphaBlend = true };
1419 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1422 notRoot = StripLastDirectory(currentDirectory, currentDirectory);
1424 strcpy(currentDirectory, "/");
1430 Button createDirectory
1432 this, inactive = true, anchor = { right = 51, top = 8 }, size = { 24, 24 },
1433 bitmap = { "<:ecere>actions/folderNew.png", alphaBlend = true };
1434 symbol = 30; // what the heck is that?
1436 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1438 if(CreateDirectoryDialog { master = this, parent = parent, currentDirectory = currentDirectory }.Modal() == ok )
1444 // File name editbox
1447 this, text = "File Name:", anchor = { left = 96, bottom = 32 + 16, right = 104 }, size.h = 20, hotKey = altF;
1449 bool NotifyActivate(Window control, bool active, Window previous)
1453 char * selectedFileName = null;
1455 if(getNameFromListBox)
1457 DataRow row = listBox.currentRow;
1460 if(GetNamesFromRow(row, &selectedFileName))
1463 fileName.PutS(selectedFileName);
1464 fileName.Select(null,0,0, null,0,0);
1466 GetNameFromListBox(false);
1469 delete selectedFileName;
1470 editText = fileName.contents;
1471 ok.disabled = !editText || !editText[0];
1476 void NotifyUpdate(EditBox control)
1478 GetNameFromListBox(false);
1484 this, inactive = true, anchor = { left = 8, bottom = 35 + 16 };
1485 labeledWindow = fileName;
1489 public class CreateDirectoryDialog : Window
1491 background = activeBorder;
1492 minClientSize = Size { 240, 100 };
1495 text = "Create Directory";
1499 property char * currentDirectory
1503 GetWorkingDir(currentDirectory, MAX_DIRECTORY); // is this necessary?
1504 PathCat(currentDirectory, value);
1505 FileFixCase(currentDirectory);
1507 get { return (char *)currentDirectory; }
1512 char currentDirectory[MAX_DIRECTORY];
1514 CreateDirectoryDialog()
1518 GetWorkingDir(currentDirectory, MAX_DIRECTORY);
1519 FileFixCase(currentDirectory);
1522 ~CreateDirectoryDialog()
1528 newDirectoryName.SelectAll();
1534 parent = this, isDefault = true, position = { 70, 60 }, size = { 60 }, text = "OK";
1535 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1537 if(newDirectoryName.contents && newDirectoryName.contents[0])
1539 char newDirPath[MAX_DIRECTORY];
1540 strcpy(newDirPath, currentDirectory);
1541 PathCat(newDirPath, newDirectoryName.contents);
1542 if(!FileExists(newDirPath).isDirectory)
1544 MakeDir(newDirPath);
1545 Destroy(DialogResult::ok);
1548 MessageBox { master = this, parent = parent, type = ok, text = "Create Directory Error", contents = "Directory already exists." }.Modal();
1551 MessageBox { master = this, parent = parent, type = ok, text = "Create Directory Error", contents = "Please enter a name." }.Modal();
1558 parent = this, position = { 140, 60 }, size = { 60 }, hotKey = escape, text = "Cancel";
1559 NotifyClicked = ButtonCloseDialog;
1562 EditBox newDirectoryName
1564 this, textHorzScroll = true, anchor = { left = 10, right = 10, top = 30 }, size = { 250 };
1565 hotKey = altN, text = "Name";
1566 contents = "New Directory";
1568 Label { this, position = { 10, 10 }, labeledWindow = newDirectoryName };