2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module dialogs
/*is aliced*/;
22 import arsd
.simpledisplay
;
33 import chibackend
: DynStr
;
40 // ////////////////////////////////////////////////////////////////////////// //
41 public final class HintWindow
: SubWindow
{
42 private DynStr mMessage
;
44 this (const(char)[] amessage
) {
47 int xwdt
= gxTextWidthUtf(amessage
)+6;
48 int xhgt
= gxTextHeightUtf
+4;
49 super(null, 0, 0, xwdt
, xhgt
);
50 winx
= VBufWidth
-winw
;
56 override @property int decorationSizeX () const nothrow @safe @nogc { return 3*2; }
57 override @property int decorationSizeY () const nothrow @safe @nogc { return 2*2; }
59 override @property int clientOffsetX () const nothrow @safe @nogc { return 3; }
60 override @property int clientOffsetY () const nothrow @safe @nogc { return 2; }
62 @property void message (DynStr v
) {
65 if (winx
== VBufWidth
-winw
) {
66 winw
= gxTextWidthUtf(v
)+6;
67 winx
= VBufWidth
-winw
;
69 winw
= gxTextWidthUtf(v
)+6;
70 if (winx
+winw
> VBufWidth
) winx
= VBufWidth
-winw
;
76 override void onPaint () {
80 gxDrawWindow(null, gxRGB
!(255, 255, 255), gxRGB
!(0, 0, 0), gxRGB
!(255, 255, 255), gxRGB
!(0, 0, 80));
81 gxClipRect
.shrinkBy(3, 2);
82 gxDrawTextUtf(x0
+3, y0
+2, mMessage
, gxRGB
!(155, 155, 155));
84 drawWindowMinimized();
88 override bool onKey (KeyEvent event
) {
92 override bool onMouse (MouseEvent event
) {
93 if (closed
) return false;
96 event
.mouse2xy(mx
, my
);
99 if (!isSubWinDragging
&& event
.type
== MouseEventType
.buttonPressed
&& event
.button
== MouseButton
.left
) {
100 if (mx
>= x0
&& my
>= y0
&& mx
< x0
+width
&& my
< (!mMinimized ? y0
+10 : height
)) {
101 startMouseDrag(event
);
111 // ////////////////////////////////////////////////////////////////////////// //
113 public class SelectPopBoxWindow : SubWindow {
114 SimpleListBoxWidget lb;
116 void delegate (Account acc) onSelected;
118 this (Account defacc) {
119 if (accounts.length > 0) {
123 lb = new SimpleListBoxWidget(this);
124 bool accFound = false;
126 foreach (immutable aidx, Account acc; accounts) {
127 if (cast(Pop3Account)acc) {
128 import std.format : format;
129 string s = "%s <%s>".format(acc.realname, acc.mail);
130 lb.appendItem(s, acc);
131 int w = gxTextWidthUtf(s)+2;
132 if (xwdt < w) xwdt = w;
134 lb.curidx = lb.length-1;
137 if (acc is defaultAcc) defAccIdx = lb.length-1;
138 xhgt += gxTextHeightUtf;
142 if (xhgt == 0) { super(); return; }
143 if (xhgt > VBufHeight) xhgt = VBufHeight-decorationSizeY;
145 if (!accFound && defAccIdx >= 0) lb.curidx = defAccIdx;
146 if (xwdt > VBufWidth-decorationSizeX) xwdt = VBufWidth-decorationSizeX;
148 super("Select Account", xwdt+decorationSizeX, xhgt+decorationSizeY);
150 lb.wh = clientHeight;
152 lb.onAction = delegate (self) {
153 if (auto acc = cast(Account)lb.itemData(lb.curidx)) {
155 if (onSelected !is null) onSelected(acc); else vbwin.beep();
167 override bool onKey (KeyEvent event) {
169 if (event == "Escape" || event == "C-Q") { close(); return true; }
170 if (event == "Enter") { lb.onAction(lb); return true; }
172 return super.onKey(event);
178 // ////////////////////////////////////////////////////////////////////////// //
180 public class SelectAddressBookWindow : SubWindow {
181 SimpleListBoxWidget lb;
183 void delegate (AddressBookEntry acc) onSelected;
185 this (const(char)[] prefix) {
186 if (abook.length > 0) {
189 auto defae = abookFindByNickFirst(prefix);
190 if (defae is null && prefix.length) {
191 auto mstx = prefix.lastIndexOf('<');
193 prefix = prefix[mstx+1..$];
194 if (prefix.length && prefix[$-1] == '>') prefix = prefix[0..$-1];
196 defae = abookFindByMailFirst(prefix);
199 lb = new SimpleListBoxWidget(this);
200 foreach (immutable aidx, AddressBookEntry ae; abook) {
201 import std.format : format;
203 if (ae.realname.length) s = ae.realname~" <"~ae.mail~">"; else s = ae.mail;
204 lb.appendItem(s, ae);
205 int w = gxTextWidthUtf(s)+2;
206 if (xwdt < w) xwdt = w;
207 if (ae is defae) lb.curidx = lb.length-1;
208 xhgt += gxTextHeightUtf;
211 if (xhgt == 0) { super(); return; }
212 if (xhgt > VBufHeight) xhgt = VBufHeight-decorationSizeY;
214 if (xwdt > VBufWidth-decorationSizeX) xwdt = VBufWidth-decorationSizeX;
216 super("Select Recepient", xwdt+decorationSizeX, xhgt+decorationSizeY);
218 lb.wh = clientHeight;
220 lb.onAction = delegate (self) {
221 if (auto ae = cast(AddressBookEntry)lb.itemData(lb.curidx)) {
223 if (onSelected !is null) onSelected(ae); else vbwin.beep();
235 override bool onKey (KeyEvent event) {
237 if (event == "Escape" || event == "C-Q") { close(); return true; }
238 if (event == "Enter") { lb.onAction(lb); return true; }
240 return super.onKey(event);
246 // ////////////////////////////////////////////////////////////////////////// //
248 public class PostWindow : SubWindow {
254 string references; // of replyto article
259 import std.algorithm : max;
261 int wanthgt = VBufHeight-42*2;
262 if (wanthgt < 80) wanthgt = 80;
263 int wantwdt = VBufWidth-64*2;
264 if (wantwdt < 506) wantwdt = 506;
265 super("Compose Mail", /*506*/wantwdt, /*253*/wanthgt);
266 //if (hasWindowClass(this)) return;
268 from = new LineEditWidget(this, "From:");
269 to = new LineEditWidget(this, "To:");
270 subj = new LineEditWidget(this, "Subj:");
271 ed = new EditorWidget(this);
275 int tw = max(from.titwdt, to.titwdt, subj.titwdt);
281 to.wy = from.wy+from.wh+2;
282 subj.wy = to.wy+to.wh+2;
285 ed.wy = subj.wy+subj.wh+2;
286 ed.ww = gxClipRect.width;
287 ed.wh = gxClipRect.height-ed.wy;
292 override bool onKey (KeyEvent event) {
294 if (event == "Escape" && !ed.editor.textChanged) { close(); return true; }
295 if (event == "C-G" || event == "C-C") {
296 if (ed.editor.textChanged) {
297 auto qww = new YesNoWindow("Close?", "Do you really want to close the editor?", true);
298 qww.onYes = () { close(); };
305 if (event == "M-Tab" && activeWidget is to) {
306 auto ae = abookFindByNick(to.str);
307 //if (ae is null) ae = abookFindByMail(to.str);
309 if (ae.realname.length) to.str = ae.realname~" <"~ae.mail~">"; else to.str = ae.mail;
315 if (event == "C-Space" && activeWidget is to) {
316 auto wae = new SelectAddressBookWindow(to.str);
317 wae.onSelected = delegate (AddressBookEntry ae) {
318 if (ae.realname.length) to.str = ae.realname~" <"~ae.mail~">"; else to.str = ae.mail;
322 if ((event == "C-Space") && activeWidget is from) {
323 if (cast(Pop3Account)acc) {
324 auto wacc = new SelectPopBoxWindow(acc);
325 wacc.onSelected = delegate (Account newacc) {
327 from.str = acc.realname~" <"~acc.mail~">";
332 if (event == "C-Enter") {
333 static bool checkString (string s) nothrow @trusted @nogc {
334 if (s.length == 0) return false;
335 if (s.utflen > 255) return false;
338 if (!checkString(subj.str)) { vbwin.beep(); return true; }
339 if (!checkString(to.str)) { vbwin.beep(); return true; }
340 if (ed.editor[].length == 0) { vbwin.beep(); return true; }
341 auto senddg = delegate () {
342 // build reply article and add it to send queue
344 ed.editor.clearAndDisableUndo(); // so removing attaches will not add 'em to undo, lol
345 string[] attnames = ed.extractAttaches();
346 if (attnames) conwriteln("ATTACHES: ", attnames);
347 // build article text
348 auto newart = new Article();
349 newart.markAsStandalone();
350 newart.attachedFileNames = attnames;
352 //foreach (immutable idx; 0..lcount) newart.appendTextLine(ed.editor[idx]);
354 auto mtr = ed.editor[];
355 if (mtr.length) newart.appendTextRange(mtr); else newart.appendTextLine("no text");
357 // clear editor, so it free used memory
358 ed.editor.clearAndDisableUndo();
361 newart.subj = subj.str;
362 //newart.inreplyto = replyto;
363 if (replyto.length) newart.replaceHeader("In-Reply-To", replyto);
364 if (references.length) newart.replaceHeader("References", references);
365 newart.replaceHeader("To", encodeq(to.str));
366 if (!acc.addToSendQueue(fld, newart)) { vbwin.beep(); return; }
369 auto qww = new YesNoWindow("Send?", "Do you really want to send the message?", true);
375 return super.onKey(event);
381 // ////////////////////////////////////////////////////////////////////////// //
383 public class TitlerWindow : SubWindow {
384 LineEditWidget title;
389 void delegate (string name, string mail, string folder, string title) onSelected;
391 this (string aname, string amail, string afolder, string atitle) {
392 int xhgt = gxTextHeightUtf+2;
394 super("Title for "~aname~" <"~amail~">", 506, xhgt+decorationSizeY);
396 title = new LineEditWidget(this, "Title:");
397 title.wh = clientWidth;
406 override bool onKey (KeyEvent event) {
408 if (event == "Escape" || event == "C-Q") { close(); return true; }
409 if (event == "Enter") {
411 if (onSelected !is null) onSelected(name, mail, folder, title.str);
415 return super.onKey(event);