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;
252 nativeDecorations = true;
254 minClientSize = { 500, 300 };
257 property FileDialogType type
259 get { return style; }
262 int numTypes = sizeTypes / sizeof(FileType);
263 int rightOffset = (value != selectDir && numTypes > 0) ? 48 : 16;
267 if(value == selectDir)
270 filter.visible = false;
271 filterLabel.visible = false;
273 type.visible = false;
274 typeLabel.visible = false;
277 open.isDefault = true;
280 ok.id = DialogResult::ok;
282 ok.isDefault = false;
287 filter.visible = true;
288 filterLabel.visible = true;
291 type.visible = numTypes != 0;
292 typeLabel.visible = numTypes != 0;
294 open.visible = false;
295 open.isDefault = false;
302 ok.anchor = { right = 10, bottom = 32 + rightOffset - 1 };
305 cancel.anchor = { right = 10, bottom = rightOffset - 1 };
307 listBox.anchor = { left = 8, right = 8, top = 40, bottom = 64 + rightOffset };
308 fileName.anchor = { left = 96, bottom = 32 + rightOffset, right = 104 };
309 fileNameLabel.anchor = { left = 8, bottom = 35 + rightOffset };
311 listBox.multiSelect = value == multiOpen;
312 fileName.text = (value == selectDir) ? "Directory:" : "File Name:";
316 // Stuff currently in config moving to FileDialog:
317 property char * filePath { set { strcpy(filePath, value); } get { return (char *)filePath; } };
318 property char * currentDirectory
322 GetWorkingDir(currentDirectory, MAX_DIRECTORY);
323 PathCat(currentDirectory, value);
324 FileFixCase(currentDirectory);
326 get { return (char *)currentDirectory; }
328 property FileFilter * filters { set { filters = value; } get { return filters; } };
329 property FileType * types { set { types = value; } get { return types; } };
331 // Replace with Array system
332 property int sizeFilters
336 int numFilters = value / sizeof(FileFilter);
341 // File Extension Filter
343 // filter.AddField(null);
346 for(c = 0; c<numFilters; c++)
348 DataRow row = filter.AddString(filters[c].name);
353 filter.AddString("All files");
355 if(fileFilter >= numFilters) fileFilter = 0;
356 filter.currentRow = filter.FindRow(fileFilter);
358 get { return sizeFilters; }
360 property int sizeTypes
364 int numTypes = value / sizeof(FileType);
365 int rightOffset = (numTypes > 0) ? 48 : 16;
370 filter.anchor = { left = 96, right = 104, bottom = rightOffset };
371 filterLabel.anchor = { left = 8, bottom = 3 + rightOffset };
373 if(style != selectDir)
376 type.visible = numTypes ? true : false;
377 typeLabel.visible = numTypes ? true : false;
380 ok.anchor = { right = 10, bottom = 32 + rightOffset - 1 };
383 cancel.anchor = { right = 10, bottom = rightOffset - 1 };
386 listBox.anchor = { left = 8, right = 8, top = 40, bottom = 64 + rightOffset };
387 fileName.anchor = { left = 96, bottom = 32 + rightOffset, right = 104 };
388 fileNameLabel.anchor = { left = 8, bottom = 35 + rightOffset };
396 // type.AddField(null);
399 for(c = 0; c<numTypes; c++)
401 DataRow row = type.AddString(types[c].name);
405 if(fileType >= numTypes) fileType = 0;
407 type.currentRow = type.FindRow(fileType);
410 get { return sizeTypes; }
413 property int filter { set { fileFilter = value; } get { return fileFilter; } };
414 property int fileType { set { fileType = value; } get { return fileType; } };
415 property bool mayNotExist { set { mayNotExist = value; } get { return mayNotExist; } };
418 property int numSelections { get { return numSelections; } };
419 property char ** multiFilePaths { get { return multiFilePaths; } };
426 lookIn.AddField(lookInField);
427 listBox.AddField(nameField);
428 listBox.AddField(typeField);
429 listBox.AddField(sizeField);
431 filter.currentRow = filter.AddString("All files");
433 GetWorkingDir(currentDirectory, MAX_DIRECTORY);
434 FileFixCase(currentDirectory);
437 for(c = 0; c<FileNameType::enumSize; c++)
439 icons[c] = BitmapResource { iconNames[c], alphaBlend = true };
440 AddResource(icons[c]);
446 delete customFilter.extensions;
450 for(c = 0; c<numSelections; c++)
451 delete multiFilePaths[c];
452 delete multiFilePaths;
459 char tmpDir[MAX_FILENAME];
462 FileListing listing { "/" };
467 // Fill the path dropbox
470 row = lookIn.AddRow();
473 fileName.name = rootName;
477 fileName.type = computer;
478 row.SetData(null, fileName);
479 lookIn.currentRow = row;
483 while(listing.Find())
485 row = lookIn.AddRow();
487 fileName.name = listing.name;
488 fileName.type = drive;
489 if(listing.stats.attribs.isCDROM) fileName.type = cdrom;
490 if(listing.stats.attribs.isRemote) fileName.type = netDrive;
491 if(listing.stats.attribs.isRemovable)
493 if(listing.name[0] == 'A' || listing.name[0] == 'B')
494 fileName.type = floppy;
496 fileName.type = removable;
500 row.SetData(null, fileName);
503 if(listing.name[0] == currentDirectory[0] &&
504 listing.name[1] == currentDirectory[1])
507 for(c = start; currentDirectory[c]; )
511 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
512 for(;(ch = currentDirectory[c]) && (ch != '/' && ch != '\\'); c++)
514 if(len < MAX_FILENAME)
517 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
522 row = lookIn.AddRow();
523 fileName.name = tmpDir;
524 fileName.type = ch ? folder : folderOpen;
526 row.SetData(null, fileName);
529 lookIn.currentRow = row;
533 lookIn.currentRow = row;
538 row = lookIn.AddRow();
539 fileName.name = msNetwork;
540 fileName.type = network;
542 row.SetData(null, fileName);
543 if(!strcmp(currentDirectory, "\\\\"))
544 lookIn.currentRow = row;
547 if(currentDirectory[0] == '\\' && currentDirectory[1] == '\\')
549 for(c = 2; currentDirectory[c]; )
553 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
554 for(;(ch = currentDirectory[c]) && (ch != '/' && ch != '\\'); c++)
556 if(len < MAX_FILENAME)
559 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
564 row = lookIn.AddRow();
565 fileName.name = tmpDir;
567 if(fileName.indent == 1)
568 fileName.type = server;
569 else if(fileName.indent == 2)
570 fileName.type = share;
572 fileName.type = ch ? folder : folderOpen;
573 row.SetData(null, fileName);
576 lookIn.currentRow = row;
579 lookIn.currentRow = row;
585 // flag = false : Get Name From Edit Box, flag = true : Get Name From List Box
586 void GetNameFromListBox(bool flag)
591 if(style == multiOpen)
592 okDisabled = listBox.numSelections == 0;
594 okDisabled = listBox.currentRow == null;
595 if(okDisabled) flag = false;
598 okDisabled = !fileName || !fileName.line.text[0];
600 getNameFromListBox = flag;
601 ok.disabled = okDisabled;
602 open.disabled = okDisabled;
607 FileListing listing { currentDirectory };
612 if(sizeFilters < sizeof(FileFilter) && !fileFilter)
613 listing.extensions = null;
614 else if(filters && fileFilter < sizeFilters / (int)sizeof(FileFilter))
615 listing.extensions = filters[fileFilter].extensions;
617 listing.extensions = customFilter.extensions;
622 while(listing.Find())
624 if(style != selectDir || (listing.stats.attribs.isDirectory))
626 row = listBox.AddRow();
628 fileName.name = listing.name;
629 if(listing.stats.attribs.isDirectory)
631 fileName.type = (listing.stats.attribs.isDrive) ? drive : folder;
632 if(listing.stats.attribs.isServer) fileName.type = server;
633 if(listing.stats.attribs.isShare) fileName.type = share;
634 if(listing.stats.attribs.isCDROM) fileName.type = cdrom;
635 if(listing.stats.attribs.isRemote) fileName.type = netDrive;
636 if(listing.stats.attribs.isRemovable)
638 if(listing.name[0] == 'A' || listing.name[0] == 'B')
639 fileName.type = floppy;
641 fileName.type = removable;
643 row.SetData(nameField, fileName);
644 row.SetData(typeField, null);
648 char extension[MAX_EXTENSION];
650 GetExtension(fileName.name, extension);
651 fileName.type = FileNameType::SelectByExtension(extension);
653 row.SetData(nameField, fileName);
654 row.SetData(typeField, extension);
655 row.SetData(sizeField, listing.stats.size);
661 if(sortOrder && sortField != nameField)
662 listBox.Sort(nameField, 1);
663 listBox.Sort(sortField, sortOrder);
665 GetNameFromListBox(activeChild == listBox);
668 if(!strcmp(currentDirectory, "/"))
671 row = listBox.AddRow();
672 fileName.name = msNetwork;
673 fileName.type = network;
675 row.SetData(nameField, fileName);
676 row.SetData(typeField, null);
678 goUp.disabled = true;
681 goUp.disabled = false;
685 listBox.typingTimeout = 0.5;
689 bool GetNamesFromRow(DataRow row, char ** selectedFileName)
693 if(style == multiOpen)
696 listBox.GetMultiSelection(selection);
702 // First allocate enough memory
703 for(item = selection.first; item; item = item.next)
706 fileName = row.GetData(nameField);
708 if(!strcmp(currentDirectory, "/"))
710 if(!strcmp(fileName->name, msNetwork))
717 totalLen += strlen(fileName->name);
718 if(item != selection.first)
721 if(selection.count > 1) totalLen += 2;
722 *selectedFileName = new char[totalLen + 1];
723 (*selectedFileName)[0] = '\0';
725 // Then build the string
726 for(item = selection.first; item; item = item.next)
729 fileName = row.GetData(nameField);
730 if(item != selection.first) strcat(*selectedFileName, " ");
731 if(selection.count > 1) strcat(*selectedFileName, "\"");
733 if(!strcmp(currentDirectory, "/"))
736 if(!strcmp(fileName->name, msNetwork))
737 strcpy(name, "\\\\");
740 name[0] = fileName->name[0];
741 name[1] = fileName->name[1];
744 strcat(*selectedFileName, name);
748 strcat(*selectedFileName, fileName->name);
749 if(selection.count > 1) strcat(*selectedFileName, "\"");
751 selection.Free(null);
757 fileName = row.GetData(nameField);
761 if(!strcmp(currentDirectory, "/"))
763 *selectedFileName = new char[3];
764 if(!strcmp(fileName->name, msNetwork))
765 strcpy(*selectedFileName, "\\\\");
768 (*selectedFileName)[0] = fileName->name[0];
769 (*selectedFileName)[1] = fileName->name[1];
770 (*selectedFileName)[2] = '\0';
776 *selectedFileName = new char[strlen(fileName->name) + 1];
777 strcpy(*selectedFileName, fileName->name);
785 bool SelectFile(char * fileName, FileDialogSelectFrom from, bool isOK)
789 char * wildcardPointer = strstr(fileName, "*");
793 if(style != selectDir)
795 int numFilters = sizeFilters / sizeof(FileFilter);
796 int numExtensions = 0;
797 char * pointer = wildcardPointer;
801 // Count the number of extensions in requested filter
804 if(pointer[1] == '.' && pointer[2])
808 pointer = strstr(pointer, "*");
812 // Try to match the extension(s) to an existing filter
816 char extension[MAX_EXTENSION], compared[MAX_EXTENSION];
817 for(filter = 0; filter<numFilters; filter++)
819 if(filters[filter].extensions)
824 for(c = 0; filters[filter].extensions[c];)
826 bool matched = false;
829 for(;(ch = filters[filter].extensions[c]) && !IS_ALUNDER(ch); c++);
830 for(;(ch = filters[filter].extensions[c]) && IS_ALUNDER(ch); c++)
831 compared[len++] = ch;
832 compared[len] = '\0';
834 for(d = 0; wildcardPointer[d]; )
837 for(;(ch = wildcardPointer[d]) && !IS_ALUNDER(ch); d++);
838 for(;(ch = wildcardPointer[d]) && IS_ALUNDER(ch); d++)
840 if(len < MAX_EXTENSION)
841 extension[len++] = ch;
843 extension[len] = '\0';
845 if(!strcmpi(extension, compared))
860 if(numMatched == numExtensions)
866 else if(!strcmp(wildcardPointer, "*") || strstr(wildcardPointer, "*.*"))
873 // Only have *.* to check for
874 else if(!strcmp(wildcardPointer, "*") || strstr(wildcardPointer, "*.*"))
877 // If we can't match it, use the custom extension
878 if(this.fileFilter == -1)
880 char extension[MAX_EXTENSION];
882 char * name = new char[numExtensions * (4 + MAX_EXTENSION)];
884 delete customFilter.extensions;
886 if(!strcmp(wildcardPointer, "*") || strstr(wildcardPointer, "*.*"))
888 strcpy(name, "All Files");
889 customFilter.extensions = null;
893 customFilter.extensions = new char[numExtensions * (2 + MAX_EXTENSION)];
894 customFilter.extensions[0] = '\0';
898 for(c = 0; wildcardPointer[c]; )
902 for(;(ch = wildcardPointer[c]) && !IS_ALUNDER(ch); c++);
903 for(;(ch = wildcardPointer[c]) && IS_ALUNDER(ch); c++)
905 if(len < MAX_EXTENSION)
906 extension[len++] = ch;
908 extension[len] = '\0';
913 strcat(customFilter.extensions, ", ");
916 strcat(name, extension);
918 strcat(customFilter.extensions, ".");
920 strcat(customFilter.extensions, extension);
928 customFilterRow = filter.AddRow();
929 customFilterRow.tag = numFilters + 1;
932 customFilterRow.SetData(null, name);
934 fileFilter = numFilters + 1;
939 filter.currentRow = filter.FindRow(fileFilter);
943 *wildcardPointer = '\0';
946 if(style == multiOpen)
950 bool needQuotes = strchr(fileName, '\"') != null;
951 char currentFileName[MAX_LOCATION], * curFileName = currentFileName;
953 OldList selections { };
954 OldLink selection = null;
966 (*curFileName) = '\0';
968 selection = OldLink { data = new char[strlen(currentFileName)+1] };
969 strcpy(selection.data, currentFileName);
970 selections.Add(selection);
972 curFileName = currentFileName;
977 if(needQuotes && !quoted)
980 *(curFileName++) = ch;
986 multiFilePaths = new char *[selections.count];
988 for(selection = selections.first; selection; selection = selection.next)
990 char * fileName = selection.data;
993 strcpy(currentFileName, currentDirectory);
994 if(PathCat(currentFileName, fileName))
996 FileFixCase(currentFileName);
997 exists = FileExists(currentFileName);
998 if(exists.isDirectory)
1000 strcpy(currentDirectory, currentFileName);
1004 else if(exists || mayNotExist)
1006 char ** path = &multiFilePaths[numSelections++];
1007 *path = new char[strlen(currentFileName)+1];
1008 strcpy(*path, currentFileName);
1012 if(exists && result && from == fromListBox) // From List Box
1014 char pathName[MAX_LOCATION];
1015 GetLastDirectory(this.fileName.line.text, pathName);
1016 this.fileName.Clear();
1017 if(!exists.isDirectory)
1018 this.fileName.PutS(pathName);
1023 selections.Free(OldLink::Free);
1028 for(c = 0; c<numSelections; c++)
1029 if(multiFilePaths[c])
1030 delete multiFilePaths[c];
1031 delete multiFilePaths;
1037 strcpy(filePath, currentDirectory);
1038 if(PathCat(filePath, fileName))
1040 FileFixCase(filePath);
1041 exists = FileExists(filePath);
1042 if(exists.isDirectory && (style != selectDir || !isOK))
1044 strcpy(currentDirectory, filePath);
1050 // *** SAVING ONLY ****
1053 if(fileType >= 0 && fileType < sizeTypes)
1055 FileType type = types[fileType];
1056 if(type.forceExtension && type.typeExtension)
1058 char extension[MAX_EXTENSION];
1059 GetExtension(filePath, extension);
1060 if(type.forceExtension == always || !extension[0])
1062 ChangeExtension(filePath, type.typeExtension, filePath);
1063 exists = FileExists(filePath);
1067 if(!exists || MessageBox { master = this, type = yesNo, text = "File Already Exists", contents = "Replace existing file?" }.Modal() == yes)
1070 else if(exists || mayNotExist)
1072 if(style != selectDir ||
1073 (strcmp(filePath, "\\\\") &&
1074 strcmp(filePath, "\\\\") &&
1075 !(exists.isServer)))
1078 // *** DIRECTORY SELECTION ONLY ****
1079 else if(isOK && style == selectDir &&
1080 MessageBox { this, type = yesNo, text = "Directory doesn't exist", contents = "Create directory?" }.Modal() == yes)
1082 if(MakeDir(filePath))
1087 if(exists && result && from == fromListBox) // From List Box
1089 char pathName[MAX_LOCATION];
1090 GetLastDirectory(this.fileName.line.text, pathName);
1091 this.fileName.Clear();
1092 if(!exists.isDirectory)
1093 this.fileName.PutS(pathName);
1098 if(!exists && result && from == fromDropBox) // drive Drop Box
1104 Destroy(DialogResult::ok);
1113 for(c = 0; c<numSelections; c++)
1114 delete multiFilePaths[c];
1115 delete multiFilePaths;
1121 // Fix up config input directory
1122 char fileName[MAX_FILENAME];
1123 #if defined(__WIN32__)
1124 char * dirOccur = SearchString(filePath, 0, currentDirectory, false, false);
1126 char * dirOccur = strstr(filePath, currentDirectory);
1130 dirOccur += strlen(currentDirectory);
1131 for(;*dirOccur && (*dirOccur == '/' || *dirOccur == '\\'); dirOccur++);
1132 strcpy(fileName, dirOccur);
1135 strcpy(fileName, filePath);
1137 this.fileName.Clear();
1138 this.fileName.PutS(fileName);
1141 GetNameFromListBox(false);
1143 fileName.Activate();
1147 FileDialogType style;
1148 FileFilter customFilter;
1149 DataRow customFilterRow;
1150 bool getNameFromListBox;
1151 BitmapResource icons[FileNameType];
1153 char currentDirectory[MAX_DIRECTORY];
1154 char filePath[MAX_LOCATION];
1155 FileFilter * filters;
1159 int fileFilter, fileType;
1162 char ** multiFilePaths;
1165 // ListBox Configuration
1166 DataField sortField;
1169 // File Extension Filter
1172 this, text = "Filter:", anchor = { left = 96, right = 104, bottom = 16 }, hotKey = altR;
1174 bool NotifySelect(DropBox control, DataRow row, Modifiers mods)
1176 fileFilter = row ? row.tag : 0;
1184 this, inactive = true, anchor = { left = 8, bottom = 3 + 16 }, labeledWindow = filter
1190 this, text = "As Type:", visible = false, anchor = { left = 96, right = 104, bottom = 16 }, hotKey = altT;
1192 bool NotifySelect(DropBox control, DataRow row, Modifiers mods)
1194 char * selectedFileName = null;
1195 fileType = row ? row.tag : 0;
1196 if(style == save && types && types[fileType].typeExtension)
1198 if(getNameFromListBox)
1200 if(GetNamesFromRow(listBox.currentRow, &selectedFileName))
1205 char * fileName = this.fileName.line.text;
1206 //selectedFileName = new char[strlen(fileName)+1]; // Room to change extension???
1207 selectedFileName = new char[MAX_FILENAME];
1208 strcpy(selectedFileName, fileName);
1210 ChangeExtension(selectedFileName, types[fileType].typeExtension, selectedFileName);
1211 fileName.Select(null,0,0, null,0,0);
1212 fileName.PutS(selectedFileName);
1213 GetNameFromListBox(false);
1215 delete selectedFileName;
1222 this, inactive = true, visible = false, anchor = { left = 8, bottom = 19 }, labeledWindow = type;
1228 this, isDefault = true, text = "OK", anchor = { right = 10, bottom = 32 + 16 - 1 }, size = { 80 };
1230 bool NotifyClicked(Button control, int x, int y, Modifiers mods)
1233 char * selectedFileName = null;
1234 if(getNameFromListBox)
1236 GetNamesFromRow(listBox.currentRow, &selectedFileName);
1237 result = SelectFile(selectedFileName, fromEditBox, control.id == DialogResult::ok);
1238 if(result && style == selectDir)
1243 char * fileName = this.fileName.line.text;
1244 selectedFileName = new char[strlen(fileName)+1];
1245 strcpy(selectedFileName, fileName);
1246 result = SelectFile(selectedFileName, fromListBox, control.id == DialogResult::ok);
1247 if(result && style == selectDir)
1248 this.fileName.Activate();
1250 delete selectedFileName;
1255 // Open Button (SelectDir only)
1258 this, visible = false, text = "Open", hotKey = altO, anchor = { right = 100, bottom = 16 - 1 }, size = { 80 };
1259 NotifyClicked = ok.NotifyClicked;
1265 this, text = "Cancel", anchor = { right = 10, bottom = 16 - 1 }, size = { 80 }, hotKey = escape;
1266 bool NotifyClicked(Button control, int x, int y, Modifiers mods)
1268 Destroy(DialogResult::cancel);
1276 this, text = "Look in:", anchor = { left = 81, top = 8, right = 109 }, hotKey = altL, maxShown = 12;
1278 bool OnKeyHit(Key key, unichar ch)
1280 if(key == wheelDown || key == wheelUp)
1282 ((FileDialog)master).listBox.KeyMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnKeyHit, key, ch);
1288 bool NotifySelect(DropBox control, DataRow row, Modifiers mods)
1292 FileName * fileName = row.GetData(null);
1293 char name[MAX_LOCATION] = "/";
1297 if(!strcmp(fileName->name, msNetwork) ||
1298 (currentDirectory[0] == '\\' &&
1299 currentDirectory[1] == '\\' &&
1300 strcmp(fileName->name, rootName) &&
1301 (!fileName->name[0] || fileName->name[1] != ':')))
1303 strcpy(name, "\\\\");
1308 if(fileName->indent > 1)
1310 name[0] = currentDirectory[0];
1316 else if(fileName->indent == 1)
1318 name[0] = fileName->name[0];
1326 if(indent < fileName->indent)
1328 for(; currentDirectory[c]; )
1332 char directory[MAX_FILENAME];
1333 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
1334 for(;(ch = currentDirectory[c]) && (ch != '/' && ch != '\\'); c++)
1336 if(len < MAX_FILENAME)
1337 directory[len++] = ch;
1339 for(;(ch = currentDirectory[c]) && (ch == '/' || ch == '\\'); c++);
1340 directory[len] = '\0';
1342 if(indent >= fileName->indent) break;
1343 PathCat(name, directory);
1348 SelectFile(name, fromDropBox, false);
1354 DataField lookInField { dataType = "FileName", userData = this };
1358 this, position = { 10, 11 }, labeledWindow = lookIn;
1364 this, borderStyle = deep, hasVertScroll = true, hasHorzScroll = true,
1365 anchor = { left = 8, right = 8, top = 40, bottom = 64 + 16 },
1366 hasHeader = true, moveFields = true, resizable = true, sortable = true;
1368 bool NotifySelect(ListBox control, DataRow row, Modifiers mods)
1370 GetNameFromListBox(true);
1374 bool NotifyDoubleClick(ListBox control, int x, int y, Modifiers mods)
1377 char * selectedFileName = null;
1378 if(GetNamesFromRow(control.currentRow, &selectedFileName))
1380 result = SelectFile(selectedFileName, fromEditBox, false);
1382 delete selectedFileName;
1386 bool NotifyKeyDown(ListBox control, DataRow row, Key key, unichar ch)
1388 if(key == backSpace)
1390 if(strcmp(currentDirectory, "/"))
1391 goUp.NotifyClicked(this, goUp, 0,0, key.modifiers);
1396 bool NotifySort(ListBox control, DataField field, Modifiers mods)
1399 sortOrder = field.sortOrder;
1403 bool NotifyActivate(Window control, bool active, Window previous)
1406 GetNameFromListBox(true);
1411 DataField nameField { header = "Name", dataType = "FileName", width = 304, userData = this }; // editable = true
1412 DataField typeField { header = "Type", dataType = /*"String"*/ "char *", width = 40 };
1413 DataField sizeField { header = "Size", dataType = "FileSize", width = 96, alignment = right };
1418 this, inactive = true, anchor = { right = 79, top = 8 }, size = { 24, 24 },
1419 bitmap = { "<:ecere>actions/goUp.png", alphaBlend = true };
1422 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1425 notRoot = StripLastDirectory(currentDirectory, currentDirectory);
1427 strcpy(currentDirectory, "/");
1433 Button createDirectory
1435 this, inactive = true, anchor = { right = 51, top = 8 }, size = { 24, 24 },
1436 bitmap = { "<:ecere>actions/folderNew.png", alphaBlend = true };
1437 symbol = 30; // what the heck is that?
1439 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1441 if(CreateDirectoryDialog { master = this, parent = parent, currentDirectory = currentDirectory }.Modal() == ok )
1447 // File name editbox
1450 this, text = "File Name:", anchor = { left = 96, bottom = 32 + 16, right = 104 }, size.h = 20, hotKey = altF;
1452 bool NotifyActivate(Window control, bool active, Window previous)
1456 char * selectedFileName = null;
1458 if(getNameFromListBox)
1460 DataRow row = listBox.currentRow;
1463 if(GetNamesFromRow(row, &selectedFileName))
1466 fileName.PutS(selectedFileName);
1467 fileName.Select(null,0,0, null,0,0);
1469 GetNameFromListBox(false);
1472 delete selectedFileName;
1473 editText = fileName.contents;
1474 ok.disabled = !editText || !editText[0];
1479 void NotifyUpdate(EditBox control)
1481 GetNameFromListBox(false);
1487 this, inactive = true, anchor = { left = 8, bottom = 35 + 16 };
1488 labeledWindow = fileName;
1492 public class CreateDirectoryDialog : Window
1494 background = activeBorder;
1495 minClientSize = Size { 240, 100 };
1498 text = "Create Directory";
1502 property char * currentDirectory
1506 GetWorkingDir(currentDirectory, MAX_DIRECTORY); // is this necessary?
1507 PathCat(currentDirectory, value);
1508 FileFixCase(currentDirectory);
1510 get { return (char *)currentDirectory; }
1515 char currentDirectory[MAX_DIRECTORY];
1517 CreateDirectoryDialog()
1521 GetWorkingDir(currentDirectory, MAX_DIRECTORY);
1522 FileFixCase(currentDirectory);
1525 ~CreateDirectoryDialog()
1531 newDirectoryName.SelectAll();
1537 parent = this, isDefault = true, position = { 70, 60 }, size = { 60 }, text = "OK";
1538 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1540 if(newDirectoryName.contents && newDirectoryName.contents[0])
1542 char newDirPath[MAX_DIRECTORY];
1543 strcpy(newDirPath, currentDirectory);
1544 PathCat(newDirPath, newDirectoryName.contents);
1545 if(!FileExists(newDirPath).isDirectory)
1547 MakeDir(newDirPath);
1548 Destroy(DialogResult::ok);
1551 MessageBox { master = this, parent = parent, type = ok, text = "Create Directory Error", contents = "Directory already exists." }.Modal();
1554 MessageBox { master = this, parent = parent, type = ok, text = "Create Directory Error", contents = "Please enter a name." }.Modal();
1561 parent = this, position = { 140, 60 }, size = { 60 }, hotKey = escape, text = "Cancel";
1562 NotifyClicked = ButtonCloseDialog;
1565 EditBox newDirectoryName
1567 this, textHorzScroll = true, anchor = { left = 10, right = 10, top = 30 }, size = { 250 };
1568 hotKey = altN, text = "Name";
1569 contents = "New Directory";
1571 Label { this, position = { 10, 10 }, labeledWindow = newDirectoryName };