1 /** 2 * Dialog module. 3 * 4 * License: 5 * MIT. See LICENSE for full details. 6 */ 7 module tkd.window.dialog.messagedialog; 8 9 /** 10 * Imports. 11 */ 12 import std.conv; 13 import std.regex; 14 import tkd.window.dialog.dialog; 15 import tkd.window.window; 16 17 /** 18 * Pops up a dialog box with a user defined message and buttons. 19 * 20 * Example: 21 * --- 22 * auto dialog = new MessageDialog("Save file?") 23 * .setIcon(MessageDialogIcon.question) 24 * .setMessage("Do you want to save this file?") 25 * .setType(MessageDialogType.okcancel) 26 * .show(); 27 * 28 * string buttonClicked = dialog.getResult(); 29 * --- 30 * 31 * Result: 32 * The symbolic name of the button pressed. 33 * 34 * See_Also: 35 * $(LINK2 ./dialog.html, tkd.dialog.dialog) $(BR) 36 */ 37 class MessageDialog : Dialog 38 { 39 /** 40 * The symbolic name of the default button for this message window ('ok', 41 * 'cancel', and so on). 42 */ 43 private string _defaultButton; 44 45 /** 46 * Specifies an auxiliary message to the main message. 47 */ 48 private string _detailMessage; 49 50 /** 51 * Specifies an icon to display. 52 */ 53 private string _icon = MessageDialogIcon.info; 54 55 /** 56 * Specifies the message to display in this message box. 57 */ 58 private string _message; 59 60 /** 61 * Arranges for a predefined set of buttons to be displayed. 62 */ 63 private string _type = MessageDialogType.ok; 64 65 /** 66 * Construct the dialog. 67 * 68 * Params: 69 * parent = The parent window of the dialog. 70 * title = The title of the dialog. 71 */ 72 this(Window parent, string title = "Information") 73 { 74 super(parent, title); 75 } 76 77 /** 78 * Construct the dialog. 79 * 80 * Params: 81 * title = The title of the dialog. 82 */ 83 this(string title = "Information") 84 { 85 this(null, title); 86 } 87 88 /** 89 * Set the default button. 90 * 91 * Params: 92 * button = The default button to use. 93 * 94 * Returns: 95 * This dialog to aid method chaining. 96 * 97 * See_Also: 98 * $(LINK2 ./messagedialog.html#MessageDialogButton, tkd.dialog.messagedialog.MessageDialogButton) $(BR) 99 */ 100 public auto setDefaultButton(this T)(string button) 101 { 102 this._defaultButton = button; 103 104 return cast(T) this; 105 } 106 107 /** 108 * Set the detail message. The message detail will be presented beneath the 109 * main message and, where supported by the OS, in a less emphasized font 110 * than the main message. 111 * 112 * Params: 113 * message = The detail message. 114 * 115 * Returns: 116 * This dialog to aid method chaining. 117 */ 118 public auto setDetailMessage(this T)(string message) 119 { 120 this._detailMessage = message; 121 122 return cast(T) this; 123 } 124 125 /** 126 * Set the preset dialog icon. It must be one of the following: error, 127 * info, question or warning. 128 * 129 * Params: 130 * icon = The preset dialog icon. 131 * 132 * Returns: 133 * This dialog to aid method chaining. 134 * 135 * See_Also: 136 * $(LINK2 ./messagedialog.html#MessageDialogIcon, tkd.dialog.messagedialog.MessageDialogIcon) $(BR) 137 */ 138 public auto setIcon(this T)(string icon) 139 { 140 this._icon = icon; 141 142 return cast(T) this; 143 } 144 145 /** 146 * Set the main message to display in the message dialog. 147 * 148 * Params: 149 * message = The message. 150 * 151 * Returns: 152 * This dialog to aid method chaining. 153 */ 154 public auto setMessage(this T)(string message) 155 { 156 this._message = message; 157 158 return cast(T) this; 159 } 160 161 /** 162 * Set the message dialog type. Arranges for a predefined set of buttons to 163 * be displayed. 164 * 165 * Params: 166 * type = The type of the message dialog. 167 * 168 * Returns: 169 * This dialog to aid method chaining. 170 * 171 * See_Also: 172 * $(LINK2 ./messagedialog.html#MessageDialogType, tkd.dialog.messagedialog.MessageDialogType) $(BR) 173 */ 174 public auto setType(this T)(string type) 175 { 176 this._type = type; 177 178 return cast(T) this; 179 } 180 181 /** 182 * Check the default button and if not set, set it. 183 */ 184 private void checkDefaultButton() 185 { 186 if (!this._defaultButton) 187 { 188 switch(this._type) 189 { 190 case MessageDialogType.abortretryignore: 191 this._defaultButton = MessageDialogButton.abort; 192 break; 193 194 case MessageDialogType.retrycancel: 195 this._defaultButton = MessageDialogButton.retry; 196 break; 197 198 case MessageDialogType.yesno: 199 case MessageDialogType.yesnocancel: 200 this._defaultButton = MessageDialogButton.yes; 201 break; 202 203 default: 204 this._defaultButton = MessageDialogButton.ok; 205 break; 206 } 207 } 208 } 209 210 /** 211 * Show the dialog. 212 * 213 * Returns: 214 * This dialog to aid method chaining. 215 */ 216 public auto show(this T)() 217 { 218 this.checkDefaultButton(); 219 220 // String concatenation is used to build the script here instead of 221 // using format specifiers to enable supporting input which includes 222 // Tcl/Tk reserved characters and elements that could be construed as 223 // format specifiers. 224 string script; 225 226 if (this._parent) 227 { 228 script = text( 229 `tk_messageBox -parent `, this._parent.id, 230 ` -title {`, this._title, `}`, 231 ` -default {`, this._defaultButton, `}`, 232 ` -detail {`, this._detailMessage, `}`, 233 ` -icon {`, this._icon, `}`, 234 ` -message {`, this._message, `}`, 235 ` -type {`, this._type, `}` 236 ); 237 } 238 else 239 { 240 script = text( 241 `tk_messageBox -title {`, this._title, `}`, 242 ` -default {`, this._defaultButton, `}`, 243 ` -detail {`, this._detailMessage, `}`, 244 ` -icon {`, this._icon, `}`, 245 ` -message {`, this._message, `}`, 246 ` -type {`, this._type, `}` 247 ); 248 } 249 250 this._tk.eval(script); 251 this._results = [this._tk.getResult!(string)]; 252 253 return cast(T) this; 254 } 255 } 256 257 /** 258 * Symbolic names for message dialog buttons. 259 */ 260 enum MessageDialogButton : string 261 { 262 abort = "abort", /// The 'abort' button. 263 cancel = "cancel", /// The 'cancel' button. 264 ignore = "ignore", /// The 'ignore' button. 265 no = "no", /// The 'no' button. 266 ok = "ok", /// The 'ok' button. 267 retry = "retry", /// The 'retry' button. 268 yes = "yes", /// The 'yes' button. 269 } 270 271 /** 272 * Preset icons used for the message dialog. 273 */ 274 enum MessageDialogIcon : string 275 { 276 error = "error", /// An error icon. 277 info = "info", /// An information icon 278 question = "question", /// A question icon. 279 warning = "warning", /// A warning icon. 280 } 281 282 /** 283 * Arranges for a predefined set of buttons to be displayed. The following 284 * values are possible for predefinedType: 285 */ 286 enum MessageDialogType : string 287 { 288 abortretryignore = "abortretryignore", /// Displays three buttons whose symbolic names are abort, retry and ignore. 289 ok = "ok", /// Displays one button whose symbolic name is ok. 290 okcancel = "okcancel", /// Displays two buttons whose symbolic names are ok and cancel. 291 retrycancel = "retrycancel", /// Displays two buttons whose symbolic names are retry and cancel. 292 yesno = "yesno", /// Displays two buttons whose symbolic names are yes and no. 293 yesnocancel = "yesnocancel", /// Displays three buttons whose symbolic names are yes, no and cancel. 294 }