1 /** 2 * Dialog module. 3 * 4 * License: 5 * MIT. See LICENSE for full details. 6 */ 7 module tkd.window.dialog.openfiledialog; 8 9 /** 10 * Imports. 11 */ 12 import std.array; 13 import std.regex; 14 import tkd.window.dialog.filedialog; 15 import tkd.window.window; 16 17 /** 18 * Pops up a dialog box for the user to open a file. 19 * 20 * Example: 21 * --- 22 * auto dialog = new OpenFileDialog("Open a file") 23 * .setMultiSelection(false) 24 * .setDefaultExtension(".txt") 25 * .addFileType("{{All files} {*}}") 26 * .addFileType("{{Text files} {.txt}}") 27 * .setInitialDirectory("~") 28 * .setInitialFile("file.txt") 29 * .show(); 30 * 31 * string fileToOpen = dialog.getResult(); 32 * --- 33 * 34 * Result: 35 * The full path of the file selected. 36 * 37 * See_Also: 38 * $(LINK2 ./filedialog.html, tkd.dialog.filedialog) $(BR) 39 */ 40 class OpenFileDialog : FileDialog 41 { 42 /* 43 * Allows the user to choose multiple files from the Open dialog. 44 */ 45 protected bool _selectMultiple; 46 47 /** 48 * Construct the dialog. 49 * 50 * Params: 51 * parent = The parent window of the dialog. 52 * title = The title of the dialog. 53 */ 54 this(Window parent, string title = "Open") 55 { 56 super(parent, title); 57 } 58 59 /** 60 * Construct the dialog. 61 * 62 * Params: 63 * title = The title of the dialog. 64 */ 65 this(string title = "Open") 66 { 67 this(null, title); 68 } 69 70 /** 71 * Set whether to enable mutli-selection. 72 * 73 * Params: 74 * enable = Enables multi-selections. 75 * 76 * Returns: 77 * This dialog to aid method chaining. 78 */ 79 public auto setMultiSelection(this T)(bool enable) 80 { 81 this._selectMultiple = enable; 82 83 return cast(T) this; 84 } 85 86 /** 87 * Show the dialog. 88 * 89 * Returns: 90 * This dialog to aid method chaining. 91 */ 92 public auto show(this T)() 93 { 94 if (this._parent) 95 { 96 // String concatentation is used here to avoid the character escaping done on args. 97 this._tk.eval("tk_getOpenFile -parent %s -title {%s} -multiple %s -defaultextension {%s} -filetypes {" ~ this._fileTypes.join(" ") ~ "} -initialdir {%s} -initialfile {%s} -typevariable %s", this._parent.id, this._title, this._selectMultiple, this._defaultExtension, this._initialDirectory, this._initialFile, this._typeVariable); 98 } 99 else 100 { 101 // String concatentation is used here to avoid the character escaping done on args. 102 this._tk.eval("tk_getOpenFile -title {%s} -multiple %s -defaultextension {%s} -filetypes {" ~ this._fileTypes.join(" ") ~ "} -initialdir {%s} -initialfile {%s} -typevariable %s", this._title, this._selectMultiple, this._defaultExtension, this._initialDirectory, this._initialFile, this._typeVariable); 103 } 104 105 string result = this._tk.getResult!(string); 106 107 if (match(result, r"^bad window path name").empty) 108 { 109 if (this._selectMultiple) 110 { 111 auto regexResult = matchAll(result, r"\{.*?\}"); 112 result = result.replaceAll(regex(r"\{.*?\}"), ""); 113 this._results ~= result.split(); 114 115 foreach (match; regexResult) 116 { 117 this._results ~= match.hit; 118 } 119 120 this.removeBracesFromResults; 121 } 122 else 123 { 124 this._results = [result]; 125 } 126 } 127 128 return cast(T) this; 129 } 130 131 /** 132 * Get multiple dialog results. 133 * 134 * Returns: 135 * The multiple results of the dialog. 136 */ 137 public string[] getResults() 138 { 139 assert(this._selectMultiple, "You need to set multi-selection on to retrieve more than one result."); 140 141 return this._results; 142 } 143 }