1 /**
2  * Dialog module.
3  *
4  * License:
5  *     MIT. See LICENSE for full details.
6  */
7 module tkd.window.dialog.directorydialog;
8 
9 /**
10  * Imports.
11  */
12 import std.regex;
13 import tkd.window.dialog.dialog;
14 import tkd.window.window;
15 
16 /**
17  * Pops up a dialog box for the user to select a directory.
18  *
19  * Example:
20  * ---
21  * auto dialog = new DirectoryDialog("Select a directory")
22  * .setInitialDirectory("~")
23  * .setDirectoryMustExist(true)
24  * .show();
25  *
26  * string directory = dialog.getResult();
27  * ---
28  *
29  * Result:
30  *     The full path of the directory selected.
31  *
32  * See_Also:
33  *     $(LINK2 ./dialog.html, tkd.dialog.dialog) $(BR)
34  */
35 class DirectoryDialog : Dialog
36 {
37 	/**
38 	 * The initial directory to start in the dialog.
39 	 */
40 	private string _initialDirectory;
41 
42 	/**
43 	 * Whether or not the choosen directory must exist in the file system.
44 	 */
45 	private bool _directoryMustExist;
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 = "Directory")
55 	{
56 		super(parent, title);
57 
58 		// Fix to hide hidden files by default on Posix systems. This also
59 		// enables a checkbutton to show them again within the dialog.
60 		version (Posix)
61 		{
62 			this._tk.eval("catch {tk_getOpenFile foo bar}");
63 			this._tk.eval("set ::tk::dialog::file::showHiddenVar 0");
64 			this._tk.eval("set ::tk::dialog::file::showHiddenBtn 1");
65 		}
66 	}
67 
68 	/**
69 	 * Construct the dialog.
70 	 *
71 	 * Params:
72 	 *     title = The title of the dialog.
73 	 */
74 	this(string title = "Directory")
75 	{
76 		this(null, title);
77 	}
78 
79 	/**
80 	 * Set the initial directory in the dialog.
81 	 *
82 	 * Params:
83 	 *     directory = The initial directory.
84 	 *
85 	 * Returns:
86 	 *     This dialog to aid method chaining.
87 	 */
88 	public auto setInitialDirectory(this T)(string directory)
89 	{
90 		this._initialDirectory = directory;
91 
92 		return cast(T) this;
93 	}
94 
95 	/**
96 	 * Set if the directory must exist.
97 	 *
98 	 * Params:
99 	 *     mustExist = Determins if the directory must exist.
100 	 *
101 	 * Returns:
102 	 *     This dialog to aid method chaining.
103 	 */
104 	public auto setDirectoryMustExist(this T)(bool mustExist)
105 	{
106 		this._directoryMustExist = mustExist;
107 
108 		return cast(T) this;
109 	}
110 
111 	/**
112 	 * Show the dialog.
113 	 *
114 	 * Returns:
115 	 *     This dialog to aid method chaining.
116 	 */
117 	public auto show(this T)()
118 	{
119 		if (this._parent)
120 		{
121 			this._tk.eval("tk_chooseDirectory -parent %s -title {%s} -initialdir {%s} -mustexist %s", this._parent.id, this._title, this._initialDirectory, this._directoryMustExist);
122 		}
123 		else
124 		{
125 			this._tk.eval("tk_chooseDirectory -title {%s} -initialdir {%s} -mustexist %s", this._title, this._initialDirectory, this._directoryMustExist);
126 		}
127 
128 		string result = this._tk.getResult!(string);
129 
130 		if (match(result, r"^bad window path name").empty)
131 		{
132 			this._results = [result];
133 		}
134 
135 		return cast(T) this;
136 	}
137 }