1 /**
2  * Dialog module.
3  *
4  * License:
5  *     MIT. See LICENSE for full details.
6  */
7 module tkd.window.dialog.filedialog;
8 
9 /**
10  * Imports.
11  */
12 import std.regex;
13 import std.string;
14 import tkd.window.dialog.dialog;
15 import tkd.window.window;
16 
17 /**
18  * Pops up a dialog box for the user to select a color.
19  *
20  * See_Also:
21  *     $(LINK2 ./dialog.html, tkd.dialog.dialog) $(BR)
22  */
23 abstract class FileDialog : Dialog
24 {
25 	/*
26 	 * The default extension for the file.
27 	 */
28 	protected string _defaultExtension;
29 
30 	/*
31 	 * A list of allowed file types.
32 	 */
33 	protected string[] _fileTypes;
34 
35 	/*
36 	 * The initial directory to start in the dialog.
37 	 */
38 	protected string _initialDirectory;
39 
40 	/*
41 	 * The initial file to use in the dialog.
42 	 */
43 	protected string _initialFile;
44 
45 	/*
46 	 * A variable to hold the state of the selected file type.
47 	 */
48 	protected string _typeVariable;
49 
50 	/**
51 	 * Construct the dialog.
52 	 *
53 	 * Params:
54 	 *     parent = The parent window of the dialog.
55 	 *     title = The title of the dialog.
56 	 */
57 	this(Window parent, string title)
58 	{
59 		this._typeVariable = format("variable-%s", this.generateHash("%s%s", this._elementId, this.id));
60 		super(parent, title);
61 	}
62 
63 	/**
64 	 * Construct the dialog.
65 	 *
66 	 * Params:
67 	 *     title = The title of the dialog.
68 	 */
69 	this(string title)
70 	{
71 		this(null, title);
72 	}
73 
74 	/**
75 	 * Set the default extension.
76 	 *
77 	 * Params:
78 	 *     extension = The default extension.
79 	 *
80 	 * Returns:
81 	 *     This dialog to aid method chaining.
82 	 */
83 	public auto setDefaultExtension(this T)(string extension)
84 	{
85 		this._defaultExtension = extension;
86 
87 		return cast(T) this;
88 	}
89 
90 	/**
91 	 * Add an allowed file type. If a filetype combobox exists in the file 
92 	 * dialog on the particular platform, this adds entries to it. When the 
93 	 * user choose a filetype in the combobox, only the files of that type are 
94 	 * listed. If no types are added or if the filetypes combobox is not 
95 	 * supported by the particular platform then all files are listed 
96 	 * regardless of their types.
97 	 *
98 	 * Filetypes must be added in the correct format, i.e. all fields are 
99 	 * enclosed within curly braces and separated by a space. Extensions must 
100 	 * contain a dot. The format is described below in which the carats 
101 	 * indicate essential required space.
102 	 * ----
103 	 * {{Description} {.ext1 .ext2 .ext3 ...}}
104 	 *               ^      ^     ^     ^
105 	 * ----
106 	 *
107 	 * Params:
108 	 *     fileType = The file type to add.
109 	 *
110 	 * Returns:
111 	 *     This dialog to aid method chaining.
112 	 */
113 	public auto addFileType(this T)(string fileType)
114 	{
115 		assert(!std.regex.match(fileType, r"^\{\{.*?\} \{.*?\}\}$").empty,
116 				"File type must take the form of '{{Description} {.ext1 .ext2 .ext3 ...}}'. Braces and spaces are important!");
117 
118 		this._fileTypes ~= fileType;
119 
120 		return cast(T) this;
121 	}
122 
123 	/**
124 	 * Set the initial directory in the dialog.
125 	 *
126 	 * Params:
127 	 *     directory = The initial directory.
128 	 *
129 	 * Returns:
130 	 *     This dialog to aid method chaining.
131 	 */
132 	public auto setInitialDirectory(this T)(string directory)
133 	{
134 		this._initialDirectory = directory;
135 
136 		return cast(T) this;
137 	}
138 
139 	/**
140 	 * Set the initial file in the dialog.
141 	 *
142 	 * Params:
143 	 *     file = The initial file.
144 	 *
145 	 * Returns:
146 	 *     This dialog to aid method chaining.
147 	 */
148 	public auto setInitialFile(this T)(string file)
149 	{
150 		this._initialFile = file;
151 
152 		return cast(T) this;
153 	}
154 }