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
;
41 // ////////////////////////////////////////////////////////////////////////// //
42 public class SelectPopBoxWindow
: SubWindow
{
43 SimpleListBoxWidget lb
;
45 void delegate (Account acc
) onSelected
;
47 this (Account defacc
) {
48 if (accounts
.length
> 0) {
52 lb
= new SimpleListBoxWidget(this);
53 bool accFound
= false;
55 foreach (immutable aidx
, Account acc
; accounts
) {
56 if (cast(Pop3Account
)acc
) {
57 import std
.format
: format
;
58 string s
= "%s <%s>".format(acc
.realname
, acc
.mail
);
59 lb
.appendItem(s
, acc
);
60 int w
= gxTextWidthUtf(s
)+2;
61 if (xwdt
< w
) xwdt
= w
;
63 lb
.curidx
= lb
.length
-1;
66 if (acc
is defaultAcc
) defAccIdx
= lb
.length
-1;
67 xhgt
+= gxTextHeightUtf
;
71 if (xhgt
== 0) { super(); return; }
72 if (xhgt
> VBufHeight
) xhgt
= VBufHeight
-decorationSizeY
;
74 if (!accFound
&& defAccIdx
>= 0) lb
.curidx
= defAccIdx
;
75 if (xwdt
> VBufWidth
-decorationSizeX
) xwdt
= VBufWidth
-decorationSizeX
;
77 super("Select Account", xwdt
+decorationSizeX
, xhgt
+decorationSizeY
);
81 lb
.onAction
= delegate (self
) {
82 if (auto acc
= cast(Account
)lb
.itemData(lb
.curidx
)) {
84 if (onSelected
!is null) onSelected(acc
); else vbwin
.beep();
96 override bool onKey (KeyEvent event
) {
98 if (event
== "Escape" || event
== "C-Q") { close(); return true; }
99 if (event
== "Enter") { lb
.onAction(lb
); return true; }
101 return super.onKey(event
);
106 // ////////////////////////////////////////////////////////////////////////// //
107 public class SelectAddressBookWindow
: SubWindow
{
108 SimpleListBoxWidget lb
;
110 void delegate (AddressBookEntry acc
) onSelected
;
112 this (const(char)[] prefix
) {
113 if (abook
.length
> 0) {
116 auto defae
= abookFindByNickFirst(prefix
);
117 if (defae
is null && prefix
.length
) {
118 auto mstx
= prefix
.lastIndexOf('<');
120 prefix
= prefix
[mstx
+1..$];
121 if (prefix
.length
&& prefix
[$-1] == '>') prefix
= prefix
[0..$-1];
123 defae
= abookFindByMailFirst(prefix
);
126 lb
= new SimpleListBoxWidget(this);
127 foreach (immutable aidx
, AddressBookEntry ae
; abook
) {
128 import std
.format
: format
;
130 if (ae
.realname
.length
) s
= ae
.realname
~" <"~ae
.mail
~">"; else s
= ae
.mail
;
131 lb
.appendItem(s
, ae
);
132 int w
= gxTextWidthUtf(s
)+2;
133 if (xwdt
< w
) xwdt
= w
;
134 if (ae
is defae
) lb
.curidx
= lb
.length
-1;
135 xhgt
+= gxTextHeightUtf
;
138 if (xhgt
== 0) { super(); return; }
139 if (xhgt
> VBufHeight
) xhgt
= VBufHeight
-decorationSizeY
;
141 if (xwdt
> VBufWidth
-decorationSizeX
) xwdt
= VBufWidth
-decorationSizeX
;
143 super("Select Recepient", xwdt
+decorationSizeX
, xhgt
+decorationSizeY
);
145 lb
.wh
= clientHeight
;
147 lb
.onAction
= delegate (self
) {
148 if (auto ae
= cast(AddressBookEntry
)lb
.itemData(lb
.curidx
)) {
150 if (onSelected
!is null) onSelected(ae
); else vbwin
.beep();
162 override bool onKey (KeyEvent event
) {
164 if (event
== "Escape" || event
== "C-Q") { close(); return true; }
165 if (event
== "Enter") { lb
.onAction(lb
); return true; }
167 return super.onKey(event
);
172 // ////////////////////////////////////////////////////////////////////////// //
173 public class PostWindow
: SubWindow
{
179 string references
; // of replyto article
184 import std
.algorithm
: max
;
186 int wanthgt
= VBufHeight
-42*2;
187 if (wanthgt
< 80) wanthgt
= 80;
188 int wantwdt
= VBufWidth
-64*2;
189 if (wantwdt
< 506) wantwdt
= 506;
190 super("Compose Mail", /*506*/wantwdt
, /*253*/wanthgt
);
191 //if (hasWindowClass(this)) return;
193 from
= new LineEditWidget(this, "From:");
194 to
= new LineEditWidget(this, "To:");
195 subj
= new LineEditWidget(this, "Subj:");
196 ed
= new EditorWidget(this);
200 int tw
= max(from
.titwdt
, to
.titwdt
, subj
.titwdt
);
206 to
.wy
= from
.wy
+from
.wh
+2;
207 subj
.wy
= to
.wy
+to
.wh
+2;
210 ed
.wy
= subj
.wy
+subj
.wh
+2;
211 ed
.ww
= gxClipRect
.width
;
212 ed
.wh
= gxClipRect
.height
-ed
.wy
;
217 override bool onKey (KeyEvent event
) {
219 if (event
== "Escape" && !ed
.editor
.textChanged
) { close(); return true; }
220 if (event
== "C-G" || event
== "C-C") {
221 if (ed
.editor
.textChanged
) {
222 auto qww
= new YesNoWindow("Close?", "Do you really want to close the editor?", true);
223 qww
.onYes
= () { close(); };
230 if (event
== "M-Tab" && activeWidget
is to
) {
231 auto ae
= abookFindByNick(to
.str);
232 //if (ae is null) ae = abookFindByMail(to.str);
234 if (ae
.realname
.length
) to
.str = ae
.realname
~" <"~ae
.mail
~">"; else to
.str = ae
.mail
;
240 if (event
== "C-Space" && activeWidget
is to
) {
241 auto wae
= new SelectAddressBookWindow(to
.str);
242 wae
.onSelected
= delegate (AddressBookEntry ae
) {
243 if (ae
.realname
.length
) to
.str = ae
.realname
~" <"~ae
.mail
~">"; else to
.str = ae
.mail
;
247 if ((event
== "C-Space") && activeWidget
is from
) {
248 if (cast(Pop3Account
)acc
) {
249 auto wacc
= new SelectPopBoxWindow(acc
);
250 wacc
.onSelected
= delegate (Account newacc
) {
252 from
.str = acc
.realname
~" <"~acc
.mail
~">";
257 if (event
== "C-Enter") {
258 static bool checkString (string s
) nothrow @trusted @nogc {
259 if (s
.length
== 0) return false;
260 if (s
.utflen
> 255) return false;
263 if (!checkString(subj
.str)) { vbwin
.beep(); return true; }
264 if (!checkString(to
.str)) { vbwin
.beep(); return true; }
265 if (ed
.editor
[].length
== 0) { vbwin
.beep(); return true; }
266 auto senddg
= delegate () {
267 // build reply article and add it to send queue
269 ed
.editor
.clearAndDisableUndo(); // so removing attaches will not add 'em to undo, lol
270 string
[] attnames
= ed
.extractAttaches();
271 if (attnames
) conwriteln("ATTACHES: ", attnames
);
272 // build article text
273 auto newart
= new Article();
274 newart
.markAsStandalone();
275 newart
.attachedFileNames
= attnames
;
277 //foreach (immutable idx; 0..lcount) newart.appendTextLine(ed.editor[idx]);
279 auto mtr
= ed
.editor
[];
280 if (mtr
.length
) newart
.appendTextRange(mtr
); else newart
.appendTextLine("no text");
282 // clear editor, so it free used memory
283 ed
.editor
.clearAndDisableUndo();
286 newart
.subj
= subj
.str;
287 //newart.inreplyto = replyto;
288 if (replyto
.length
) newart
.replaceHeader("In-Reply-To", replyto
);
289 if (references
.length
) newart
.replaceHeader("References", references
);
290 newart
.replaceHeader("To", encodeq(to
.str));
291 if (!acc
.addToSendQueue(fld, newart
)) { vbwin
.beep(); return; }
294 auto qww
= new YesNoWindow("Send?", "Do you really want to send the message?", true);
300 return super.onKey(event
);
305 // ////////////////////////////////////////////////////////////////////////// //
306 public class TitlerWindow
: SubWindow
{
307 LineEditWidget title
;
312 void delegate (string name
, string mail
, string folder
, string title
) onSelected
;
314 this (string aname
, string amail
, string afolder
, string atitle
) {
315 int xhgt
= gxTextHeightUtf
+2;
317 super("Title for "~aname
~" <"~amail
~">", 506, xhgt
+decorationSizeY
);
319 title
= new LineEditWidget(this, "Title:");
320 title
.wh
= clientWidth
;
329 override bool onKey (KeyEvent event
) {
331 if (event
== "Escape" || event
== "C-Q") { close(); return true; }
332 if (event
== "Enter") {
334 if (onSelected
!is null) onSelected(name
, mail
, folder
, title
.str);
338 return super.onKey(event
);
343 // ////////////////////////////////////////////////////////////////////////// //
344 public final class HintWindow
: SubWindow
{
345 private string mMessage
;
347 this (string amessage
) {
350 int xwdt
= gxTextWidthUtf(amessage
)+6;
351 int xhgt
= gxTextHeightUtf
+4;
352 super(null, 0, 0, xwdt
, xhgt
);
353 winx
= VBufWidth
-winw
;
359 override @property int decorationSizeX () const nothrow @safe @nogc { return 3*2; }
360 override @property int decorationSizeY () const nothrow @safe @nogc { return 2*2; }
362 override @property int clientOffsetX () const nothrow @safe @nogc { return 3; }
363 override @property int clientOffsetY () const nothrow @safe @nogc { return 2; }
365 @property void message (string v
) {
368 if (winx
== VBufWidth
-winw
) {
369 winw
= gxTextWidthUtf(v
)+6;
370 winx
= VBufWidth
-winw
;
372 winw
= gxTextWidthUtf(v
)+6;
373 if (winx
+winw
> VBufWidth
) winx
= VBufWidth
-winw
;
379 override void onPaint () {
383 gxDrawWindow(null, gxRGB
!(255, 255, 255), gxRGB
!(0, 0, 0), gxRGB
!(255, 255, 255), gxRGB
!(0, 0, 80));
384 gxClipRect
.shrinkBy(3, 2);
385 gxDrawTextUtf(x0
+3, y0
+2, mMessage
, gxRGB
!(155, 155, 155));
387 drawWindowMinimized();
391 override bool onKey (KeyEvent event
) {
395 override bool onMouse (MouseEvent event
) {
396 if (closed
) return false;
399 event
.mouse2xy(mx
, my
);
402 if (!isSubWinDragging
&& event
.type
== MouseEventType
.buttonPressed
&& event
.button
== MouseButton
.left
) {
403 if (mx
>= x0
&& my
>= y0
&& mx
< x0
+width
&& my
< (!mMinimized ? y0
+10 : height
)) {
404 startMouseDrag(event
);