1 module easyd.gtk.dialogs;
2 
3 // (C) 2014-2019 by Matthias Rossmy
4 // This file is distributed under the "Fair Use License v2"
5 
6 import easyd.string;
7 import easyd.gtk.base;
8 import easyd.gtk.widgets;
9 import std.string;
10 
11 import gtk.Dialog;
12 import gtk.Window;
13 import gtk.Label;
14 import gtk.CheckButton;
15 import gtk.ToggleButton;
16 import gtk.FileChooserDialog;
17 import gtk.FileFilter;
18 
19 struct Dialog
20 {
21 	BindingSet bindings;
22 	gtk.Dialog.Dialog gtkDlg;
23 	GridLayout layout;
24 	int row = 0;
25 
26 	this(Window parent, string title="", string[] buttonsText = ["OK"/*.tr*/,"Cancel"/*.tr*/], int[] responses = [1,2])
27 	{
28 		gtkDlg = new gtk.Dialog.Dialog(title, parent, DialogFlags.MODAL | DialogFlags.DESTROY_WITH_PARENT, buttonsText, cast(GtkResponseType[]) responses);
29 		layout = new GridLayout;
30 		layout.margin = 5;
31 		layout.spacing=5;
32 		gtkDlg.getContentArea.packEnd(layout,true,true,0);
33 	}
34 
35 	~this()
36 	{
37 		if(gtkDlg !is null) gtkDlg.destroy();
38 	}
39 
40 	T add(T)(T widget)
41 	{
42 		widget.setHexpand(1);
43 		layout.attach(widget,0,row++,2,1);
44 		return widget;
45 	}
46 
47 	void add(string label)
48 	{
49 		auto l = new Label(label);
50 		l.setAlignment(0,0.5);
51 		layout.attach(l,0,row++,2,1);
52 	}
53 	
54 	T add(T)(string label, T widget)
55 	{
56 		auto l = new Label(label);
57 		l.setAlignment(0,0.5);
58 		layout.attach(l,0,row++,1,1);
59 		return layout.addRightOf(l,widget,1,1,true);
60 	}
61 	
62 	void add(T,TData)(ref TData data, string label, T widget)
63 	{
64 		bindings.add(data,add(label,widget));
65 	}
66 	
67 	int runAndGetButtonID(int okId=1)
68 	{
69 		bindings.load;
70 		gtkDlg.showAll;
71 		int result = cast(int)(gtkDlg.run);
72 		gtkDlg.hide;
73 		if(result==okId) bindings.apply;
74 		return result;
75 	}
76 	
77 	bool run(int okId=1)
78 	{
79 		return runAndGetButtonID(okId)==okId;
80 	}
81 
82 	void return1()
83 	{
84 		gtkDlg.response(cast(GtkResponseType)1);
85 	}
86 }
87 
88 void showMessage(Window parent, string s, MessageType t = MessageType.INFO)
89 {
90 	showMessage(parent,"",s,t);
91 }
92 
93 void showMessage(Window parent, string title, string s, MessageType t = MessageType.INFO)
94 {
95 	auto d = Dialog(parent,title,[t==MessageType.ERROR? "Close"/*.tr*/ : "OK"/*.tr*/],[1]);
96 	d.add(s);
97 	if(title.length>0) d.gtkDlg.setDefaultSize(200,1);
98 	d.run;
99 }
100 
101 bool confirm(Window parent, string question)
102 {
103 	return confirm(parent,"",question);
104 }
105 
106 bool confirm(Window parent, string title, string question)
107 {
108 	auto d = Dialog(parent,title,["Yes"/*.tr*/,"No"/*.tr*/],[1,2]);
109 	d.add(question);
110 	return d.run==1;
111 }
112 
113 bool stringDlg(Window parent, out string result, string title="", string text="", bool password=false)
114 {
115 	auto d = new Dialog(parent,title);
116 	
117 	if(text.length>0) d.add(text);
118 	
119 	auto l = new LineEdit;
120 	l.onPressEnter ~= &d.return1;
121 	d.add(l);
122 	
123 	if(password)
124 	{
125 		l.setVisibility(false);
126 		struct StringDlgController
127 		{
128 			CheckButton cb;
129 			this(LineEdit l)
130 			{
131 				cb = new CheckButton("Show password"/*.tr*/);
132 				cb.addOnToggled(&cbClick);
133 			}
134 			void cbClick(ToggleButton t)
135 			{
136 				l.setVisibility(cb.getActive);
137 			}
138 		}
139 		auto c=StringDlgController(l);
140 		d.add(c.cb);
141 	}
142 	
143 	if(d.run==1)
144 	{
145 		result = l.getText;
146 		return true;
147 	}
148 	else
149 	{
150 		return false;
151 	}
152 }
153 
154 bool fileDlg(Window parent, ref string result, string filters="*", FileChooserAction action=FileChooserAction.OPEN)
155 {
156 	auto fc= new FileChooserDialog("", parent, action);
157 
158 	auto fl = filters.split;
159 	if(action==FileChooserAction.OPEN)
160 	{
161 		auto ff = new FileFilter;
162 		ff.setName(filters);
163 		foreach(f;fl)
164 		{
165 			ff.addPattern(f);
166 		}
167 		fc.addFilter(ff);
168 	}
169 	else
170 	{
171 		foreach(f;fl)
172 		{
173 			auto ff = new FileFilter;
174 			ff.setName(f);
175 			ff.addPattern(f);
176 			fc.addFilter(ff);
177 		}
178 	}
179 
180 	fc.selectFilename(result);
181 
182 	bool ok = fc.run() == ResponseType.OK;
183 	if (ok) 
184 	{
185 		result = fc.getFilename;
186 		string f = fc.getFilter.getName;
187 		if(f.startsWith("*") && f.countChar('*')==1 && !result.endsWith(f.subStr(1))) result ~= f.subStr(1);
188 	}
189 	fc.destroy();
190 	return ok;
191 }