MODULE IMAPGUI;
IMPORT
Streams, Strings, KernelLog, Classes := TFClasses, Kernel, Modules, IMAPClient, IMAPUtilities,
WMComponents, WMStandardComponents, WMWindowManager, WMRectangles, WMEditors, WMDialogs, Raster,
WMGrids, WMStringGrids, WMGraphics, WMPopups, WMTrees, WMMessages, WMRestorable, Texts, UTF8Strings, Files,
XML, XMLScanner, XMLParser, RMSMTP;
CONST
WindowTitle = "MailClient";
CR = 0DX; LF = 0AX;
DEBUG = FALSE;
REFRESHTIME = 1000 * 2;
VAR
nofWindows: LONGINT;
TYPE
String = Strings.String;
KillerMsg = OBJECT
END KillerMsg;
LoadWindow = OBJECT (WMComponents.FormWindow)
VAR
offline: WMStandardComponents.Checkbox;
filename: WMEditors.Editor;
load, cancel: WMStandardComponents.Button;
ready, valid: BOOLEAN;
PROCEDURE &New*;
VAR
vc : WMComponents.VisualComponent;
BEGIN
IncCount();
ready := FALSE;
valid := FALSE;
vc := CreateForm();
Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), FALSE);
SetContent(vc);
SetTitle(Strings.NewString("Load Account File"));
WMWindowManager.DefaultAddWindow(SELF);
END New;
PROCEDURE CreateForm() : WMComponents.VisualComponent;
VAR
ret, panel : WMStandardComponents.Panel;
label : WMStandardComponents.Label;
BEGIN
NEW(ret); ret.bounds.SetExtents(400, 200); ret.fillColor.Set(LONGINT(0CCCCCCFFH));
NEW(label); label.bounds.SetHeight(25); label.alignment.Set(WMComponents.AlignTop);
label.caption.SetAOC("Please give the path of the file that contains the account data: ");
label.bearing.Set(WMRectangles.MakeRect(10,10,10,10));
ret.AddContent(label);
NEW(filename); filename.bounds.SetHeight(25); filename.alignment.Set(WMComponents.AlignTop);
filename.multiLine.Set(FALSE); filename.fillColor.Set(LONGINT(0FFFFFFFFH)); filename.tv.showBorder.Set(TRUE);
filename.bearing.Set(WMRectangles.MakeRect(10,10,10,10));
ret.AddContent(filename);
NEW(panel);
panel.bounds.SetHeight(20); panel.alignment.Set(WMComponents.AlignTop);
ret.AddContent(panel);
NEW(label); label.bounds.SetWidth(150); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Open the account offline? ");
label.bearing.Set(WMRectangles.MakeRect(10,0,10,0));
panel.AddContent(label);
NEW(offline); offline.bounds.SetWidth(20); offline.alignment.Set(WMComponents.AlignLeft);
panel.AddContent(offline);
NEW(panel);
panel.bounds.SetHeight(20); panel.alignment.Set(WMComponents.AlignBottom);
ret.AddContent(panel);
NEW(load);
load.bounds.SetWidth(100); load.alignment.Set(WMComponents.AlignRight);
load.caption.SetAOC("Load"); load.onClick.Add(LoadHandler);
panel.AddContent(load);
NEW(cancel);
cancel.bounds.SetWidth(100); cancel.alignment.Set(WMComponents.AlignRight);
cancel.caption.SetAOC("Cancel"); cancel.onClick.Add(CancelHandler);
panel.AddContent(cancel);
RETURN ret;
END CreateForm;
PROCEDURE Close;
BEGIN
Close^();
DecCount();
END Close;
PROCEDURE Handle(VAR x: WMMessages.Message);
BEGIN
IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) & (x.ext IS KillerMsg) THEN
Close();
ELSE
Handle^(x);
END;
END Handle;
PROCEDURE LoadHandler(sender, data: ANY);
BEGIN {EXCLUSIVE}
ready := TRUE;
valid := TRUE;
END LoadHandler;
PROCEDURE GetAnswer(VAR file: String; VAR b: BOOLEAN);
VAR
i: LONGINT;
BEGIN
BEGIN {EXCLUSIVE}
AWAIT(ready);
IF valid THEN
IMAPUtilities.TextToStr(filename.text, file);
ELSE
file := NIL;
END;
i := offline.state.Get();
b := (i = 1);
END;
Close^;
END GetAnswer;
PROCEDURE CancelHandler(sender, data: ANY);
BEGIN
BEGIN {EXCLUSIVE}
ready := TRUE;
END;
Close();
END CancelHandler;
END LoadWindow;
SaveWindow = OBJECT (WMComponents.FormWindow)
VAR
filename: WMEditors.Editor;
save, cancel: WMStandardComponents.Button;
ready, valid: BOOLEAN;
PROCEDURE &New*;
VAR
vc : WMComponents.VisualComponent;
BEGIN
IncCount();
ready := FALSE;
valid := FALSE;
vc := CreateForm();
Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), FALSE);
SetContent(vc);
SetTitle(Strings.NewString("Save Account As"));
WMWindowManager.DefaultAddWindow(SELF);
END New;
PROCEDURE CreateForm() : WMComponents.VisualComponent;
VAR
ret, panel : WMStandardComponents.Panel;
label : WMStandardComponents.Label;
BEGIN
NEW(ret); ret.bounds.SetExtents(400, 200); ret.fillColor.Set(LONGINT(0CCCCCCFFH));
NEW(label); label.bounds.SetHeight(25); label.alignment.Set(WMComponents.AlignTop);
label.caption.SetAOC("Please give the name of the file that should be saved: ");
label.bearing.Set(WMRectangles.MakeRect(10,10,10,10));
ret.AddContent(label);
NEW(filename); filename.bounds.SetHeight(25); filename.alignment.Set(WMComponents.AlignTop);
filename.multiLine.Set(FALSE); filename.fillColor.Set(LONGINT(0FFFFFFFFH)); filename.tv.showBorder.Set(TRUE);
filename.bearing.Set(WMRectangles.MakeRect(10,10,10,10));
ret.AddContent(filename);
NEW(panel);
panel.bounds.SetHeight(20); panel.alignment.Set(WMComponents.AlignBottom);
ret.AddContent(panel);
NEW(save);
save.bounds.SetWidth(100); save.alignment.Set(WMComponents.AlignRight);
save.caption.SetAOC("Save"); save.onClick.Add(SaveHandler);
panel.AddContent(save);
NEW(cancel);
cancel.bounds.SetWidth(100); cancel.alignment.Set(WMComponents.AlignRight);
cancel.caption.SetAOC("Cancel"); cancel.onClick.Add(CancelHandler);
panel.AddContent(cancel);
RETURN ret;
END CreateForm;
PROCEDURE Close;
BEGIN
Close^();
DecCount();
END Close;
PROCEDURE Handle(VAR x: WMMessages.Message);
BEGIN
IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) & (x.ext IS KillerMsg) THEN
Close();
ELSE
Handle^(x);
END;
END Handle;
PROCEDURE SaveHandler(sender, data: ANY);
BEGIN {EXCLUSIVE}
ready := TRUE;
valid := TRUE;
END SaveHandler;
PROCEDURE GetAnswer(VAR file: String);
BEGIN
BEGIN {EXCLUSIVE}
AWAIT(ready);
IF valid THEN
IMAPUtilities.TextToStr(filename.text, file);
ELSE
file := NIL;
END;
END;
Close^;
END GetAnswer;
PROCEDURE CancelHandler(sender, data: ANY);
BEGIN
BEGIN {EXCLUSIVE}
ready := TRUE;
END;
Close();
END CancelHandler;
END SaveWindow;
MessageWindow = OBJECT (WMComponents.FormWindow)
VAR
topToolbar, statusbar, headerPanel, messagePanel: WMStandardComponents.Panel;
statusLabel: WMStandardComponents.Label;
send, reply, saveDraft: WMStandardComponents.Button;
from, to, cc, subject, date: WMEditors.Editor;
messageField: WMEditors.Editor;
message: IMAPClient.Message;
window: Window;
folder: IMAPClient.Folder;
PROCEDURE &New*(win: Window);
VAR vc : WMComponents.VisualComponent;
BEGIN
IncCount();
window := win;
IF win # NIL THEN
folder := win.client.currentFolder;
END;
vc := CreateForm();
Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), FALSE);
SetContent(vc);
SetTitle(Strings.NewString("Message Window"));
from.hScrollbar.visible.Set(FALSE);
to.hScrollbar.visible.Set(FALSE);
cc.hScrollbar.visible.Set(FALSE);
WMWindowManager.DefaultAddWindow(SELF);
END New;
PROCEDURE CreateForm() : WMComponents.VisualComponent;
VAR
panel : WMStandardComponents.Panel;
p: WMStandardComponents.Panel;
label : WMStandardComponents.Label;
BEGIN
NEW(panel); panel.bounds.SetExtents(800, 600); panel.fillColor.Set(LONGINT(0CCCCCCFFH));
NEW(topToolbar); topToolbar.bounds.SetHeight(40); topToolbar.alignment.Set(WMComponents.AlignTop);
panel.AddContent(topToolbar);
NEW(send);
send.caption.SetAOC("Send");
send.bounds.SetWidth(120);
send.bearing.Set(WMRectangles.MakeRect(10,10,10,10));
send.alignment.Set(WMComponents.AlignLeft);
send.onClick.Add(ButtonHandler);
topToolbar.AddContent(send);
NEW(reply);
reply.caption.SetAOC("Change Fields to answer");
reply.bounds.SetWidth(140);
reply.bearing.Set(WMRectangles.MakeRect(10,10,10,10));
reply.alignment.Set(WMComponents.AlignLeft);
reply.onClick.Add(ButtonHandler);
topToolbar.AddContent(reply);
NEW(saveDraft);
saveDraft.caption.SetAOC("Save in draft folder");
saveDraft.bounds.SetWidth(120);
saveDraft.bearing.Set(WMRectangles.MakeRect(10,10,10,10));
saveDraft.alignment.Set(WMComponents.AlignLeft);
saveDraft.onClick.Add(ButtonHandler);
topToolbar.AddContent(saveDraft);
NEW(statusbar); statusbar.bounds.SetHeight(20); statusbar.alignment.Set(WMComponents.AlignBottom);
panel.AddContent(statusbar);
NEW(statusLabel); statusLabel.bounds.SetWidth(800); statusLabel.alignment.Set(WMComponents.AlignLeft);
statusLabel.textColor.Set(0000000FFH);
statusLabel.SetCaption("Status: loading ...");
statusbar.AddContent(statusLabel);
NEW(headerPanel); headerPanel.alignment.Set(WMComponents.AlignTop);
headerPanel.bounds.SetHeight(150);
headerPanel.fillColor.Set(LONGINT(0FFFFFFFFH));
panel.AddContent(headerPanel);
NEW(p);
p.alignment.Set(WMComponents.AlignTop);
p.bounds.SetHeight(32);
NEW(label);
label.alignment.Set(WMComponents.AlignLeft);
label.bounds.SetWidth(60);
label.SetCaption(" FROM: ");
p.AddContent(label);
NEW(from);
from.alignment.Set(WMComponents.AlignClient);
from.tv.showBorder.Set(TRUE);
from.hScrollbar.visible.Set(FALSE);
p.AddContent(from);
headerPanel.AddContent(p);
NEW(p);
p.alignment.Set(WMComponents.AlignTop);
p.bounds.SetHeight(32);
NEW(label);
label.alignment.Set(WMComponents.AlignLeft);
label.bounds.SetWidth(60);
label.SetCaption(" TO: ");
p.AddContent(label);
NEW(to);
to.alignment.Set(WMComponents.AlignClient);
to.tv.showBorder.Set(TRUE);
to.hScrollbar.visible.Set(FALSE);
p.AddContent(to);
headerPanel.AddContent(p);
NEW(p);
p.alignment.Set(WMComponents.AlignTop);
p.bounds.SetHeight(32);
NEW(label);
label.alignment.Set(WMComponents.AlignLeft);
label.bounds.SetWidth(60);
label.SetCaption(" CC: ");
p.AddContent(label);
NEW(cc);
cc.alignment.Set(WMComponents.AlignClient);
cc.tv.showBorder.Set(TRUE);
cc.hScrollbar.visible.Set(FALSE);
p.AddContent(cc);
headerPanel.AddContent(p);
NEW(p);
p.alignment.Set(WMComponents.AlignTop);
p.bounds.SetHeight(25);
NEW(label);
label.alignment.Set(WMComponents.AlignLeft);
label.bounds.SetWidth(60);
label.SetCaption(" SUBJECT: ");
p.AddContent(label);
NEW(subject);
subject.alignment.Set(WMComponents.AlignClient);
subject.multiLine.Set(FALSE);
subject.tv.showBorder.Set(TRUE);
p.AddContent(subject);
headerPanel.AddContent(p);
NEW(p);
p.alignment.Set(WMComponents.AlignTop);
p.bounds.SetHeight(25);
NEW(label);
label.alignment.Set(WMComponents.AlignLeft);
label.bounds.SetWidth(60);
label.SetCaption(" DATE: ");
p.AddContent(label);
NEW(date);
date.alignment.Set(WMComponents.AlignClient);
date.multiLine.Set(FALSE);
date.tv.showBorder.Set(TRUE);
p.AddContent(date);
headerPanel.AddContent(p);
NEW(messagePanel); messagePanel.alignment.Set(WMComponents.AlignClient);
NEW(messageField);
messageField.alignment.Set(WMComponents.AlignClient);
messageField.tv.showBorder.Set(TRUE);
messageField.SetAsString("");
messagePanel.AddContent(messageField);
messagePanel.fillColor.Set(LONGINT(0FFFFFFFFH));
messageField.hScrollbar.visible.Set(FALSE);
panel.AddContent(messagePanel);
RETURN panel;
END CreateForm;
PROCEDURE Close;
BEGIN
Close^();
DecCount();
END Close;
PROCEDURE Handle(VAR x: WMMessages.Message);
BEGIN
IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) & (x.ext IS KillerMsg) THEN
Close();
ELSE
Handle^(x);
END;
END Handle;
PROCEDURE ButtonHandler*(sender, data: ANY);
BEGIN
IF sender = send THEN
Send();
ELSIF sender = reply THEN
Reply();
ELSIF sender = saveDraft THEN
SaveDraft();
ELSE
OutputError("An Unknown Button was pressed");
END;
END ButtonHandler;
PROCEDURE Reply;
VAR
string: Strings.String;
buffer: Strings.Buffer;
w: Streams.Writer;
r: LONGINT;
header: IMAPClient.HeaderElement;
BEGIN
header := message.header;
IMAPUtilities.TextToStr(subject.text, string);
NEW(buffer, 16);
w := buffer.GetWriter();
w.String("Re: ");
w.String(string^);
string := buffer.GetString();
IMAPUtilities.SetEditorText(subject, string);
IF header.from # NIL THEN
IMAPUtilities.AddressesToString(header.from, string);
IMAPUtilities.SetEditorText(to, string);
ELSE
string := Strings.NewString("");
END;
NEW(buffer, 16);
w := buffer.GetWriter();
w.Char(CR); w.Char(LF); w.Char(CR); w.Char(LF);
w.String(string^);
w.String(" wrote:"); w.Char(CR); w.Char(LF); w.Char(CR); w.Char(LF);
IMAPUtilities.TextToStr(messageField.text, string);
w.String(string^);
string := buffer.GetString();
IMAPUtilities.SetEditorText(messageField, string);
IF window # NIL THEN
string := Strings.NewString(window.client.preferences.From^);
IMAPUtilities.SetEditorText(from, string);
IF window.client.currentFolder # folder THEN
buffer.Clear();
w.String("The current Folder of your Mail Client is not equal to the Folder this Message is stored in. ");
w.String("So the Answered Flag will not be updated. ");
w.String("If you want the Answered Flag to be updated change to the Folder this Message is stored in and click Yes. ");
w.String("Otherwise click No.");
string := buffer.GetString();
r := WMDialogs.ResYes;
WHILE (r = WMDialogs.ResYes) & (window.client.currentFolder # folder) DO
r := WMDialogs.Confirmation(WindowTitle,string^);
END;
IF (r = WMDialogs.ResYes) & (window.client.currentFolder = folder) THEN
r := window.client.SetAnsweredFlag(message);
END;
ELSE
r := window.client.SetAnsweredFlag(message);
END;
END;
END Reply;
PROCEDURE Send;
VAR
server, thisHost: ARRAY 1000 OF CHAR;
preferences: IMAPClient.AccountPreferences;
r: LONGINT;
msg, caption: String;
buttons: SET;
header: IMAPClient.HeaderElement;
newMessage: IMAPClient.Message;
BEGIN
NEW(header);
NEW(newMessage);
newMessage.header := header;
message := newMessage;
BuildMessage();
IF window # NIL THEN
preferences := window.client.preferences;
IMAPUtilities.StringCopy(preferences.SMTPServer^, 0, IMAPUtilities.StringLength(preferences.SMTPServer^), server);
IMAPUtilities.StringCopy(preferences.SMTPThisHost^, 0, IMAPUtilities.StringLength(preferences.SMTPThisHost^), thisHost);
ELSE
server := "";
thisHost := "";
END;
statusLabel.caption.SetAOC("Status: Preparing...");
IF WMDialogs.QueryString("Enter SMTP-Server:", server) = WMDialogs.ResOk THEN
IF WMDialogs.QueryString("Enter Name of this host", thisHost) = WMDialogs.ResOk THEN
statusLabel.caption.SetAOC("Status: Sending...");
statusLabel.caption.SetAOC("Status: Finished");
IF r = RMSMTP.OK THEN
buttons := {WMDialogs.ResYes, WMDialogs.ResNo};
caption := Strings.NewString("Send was successful");
msg := Strings.NewString("Send was successful. Do you want to close the MessageWindow now?");
IF window # NIL THEN
window.client.abort := TRUE;
r := window.client.SaveSentMessage(message);
window.client.abort := FALSE;
END
ELSE
buttons := {WMDialogs.ResOk};
caption := Strings.NewString("Send was NOT successful");
msg := Strings.NewString("Send was NOT successful.");
END;
r := WMDialogs.Message(WMDialogs.TInformation, caption^, msg^, buttons);
IF r = WMDialogs.ResYes THEN
Close^;
END;
END;
END;
statusLabel.caption.SetAOC("Status: Finished");
END Send;
PROCEDURE SaveDraft;
VAR
path: String;
r: LONGINT;
BEGIN
path := window.client.preferences.DraftFolder;
IF path^ = "" THEN
OutputError("No Draft Folder specified in Preferences");
RETURN;
END;
BuildMessage();
r := window.client.AppendMessage(message, path);
END SaveDraft;
PROCEDURE BuildMessage;
VAR
string: String;
addresses: Classes.List;
BEGIN
NEW(message);
NEW(message.header);
IMAPUtilities.TextToStr(from.text, string);
IF Strings.Length(string^) > 0 THEN
IMAPUtilities.ParseAddresses(string, addresses);
message.header.from := addresses;
END;
IMAPUtilities.TextToStr(to.text, string);
IF Strings.Length(string^) > 0 THEN
IMAPUtilities.ParseAddresses(string, addresses);
message.header.to := addresses;
END;
IMAPUtilities.TextToStr(cc.text, string);
IF Strings.Length(string^) > 0 THEN
IMAPUtilities.ParseAddresses(string, addresses);
message.header.cc := addresses;
END;
IMAPUtilities.TextToStr(subject.text, string);
message.header.subject := Strings.NewString(string^);
message.header.date := IMAPUtilities.getRFC822Date();
IMAPUtilities.TextToStr(messageField.text, string);
message.message := string;
END BuildMessage;
PROCEDURE NewMessage*;
VAR
header: IMAPClient.HeaderElement;
string: String;
BEGIN
NEW(message);
NEW(header);
message.header := header;
IF window # NIL THEN
string := Strings.NewString(window.client.preferences.From^);
IMAPUtilities.SetEditorText(from, string);
END;
statusLabel.caption.SetAOC("Status: Ready");
from.hScrollbar.visible.Set(FALSE);
to.hScrollbar.visible.Set(FALSE);
cc.hScrollbar.visible.Set(FALSE);
messageField.hScrollbar.visible.Set(FALSE);
END NewMessage;
PROCEDURE DisplayMessage*(message: IMAPClient.Message);
VAR
string, string2: String;
header: IMAPClient.HeaderElement;
i: LONGINT;
text: Texts.Text;
BEGIN
SELF.message := message;
from.hScrollbar.visible.Set(FALSE);
to.hScrollbar.visible.Set(FALSE);
cc.hScrollbar.visible.Set(FALSE);
messageField.hScrollbar.visible.Set(FALSE);
header := message.header;
IF header.from # NIL THEN
IMAPUtilities.AddressesToString(header.from, string);
IMAPUtilities.replaceEncodedHeaderWord(string^);
IMAPUtilities.SetEditorText(from, string);
END;
IF header.to # NIL THEN
IMAPUtilities.AddressesToString(header.to, string);
IMAPUtilities.replaceEncodedHeaderWord(string^);
IMAPUtilities.SetEditorText(to, string);
END;
IF header.cc # NIL THEN
IMAPUtilities.AddressesToString(header.cc, string);
IMAPUtilities.replaceEncodedHeaderWord(string^);
IMAPUtilities.SetEditorText(cc, string);
END;
IF header.subject # NIL THEN
string := IMAPUtilities.NewString(header.subject^);
IMAPUtilities.replaceEncodedHeaderWord(string^);
IMAPUtilities.SetEditorText(subject, string);
END;
IF header.date # NIL THEN
string := IMAPUtilities.NewString(header.date^);
IMAPUtilities.replaceEncodedHeaderWord(string^);
IMAPUtilities.SetEditorText(date, string);
END;
IF message.bodystructure # NIL THEN
Strings.UpperCase(message.bodystructure.type);
Strings.UpperCase(message.bodystructure.subtype);
Strings.UpperCase(message.bodystructure.encoding);
Strings.UpperCase(message.bodystructure.charset);
IF DEBUG THEN
KernelLog.String("Type: "); KernelLog.String(message.bodystructure.type); KernelLog.Ln();
KernelLog.String("SubType: "); KernelLog.String(message.bodystructure.subtype); KernelLog.Ln();
KernelLog.String("Encoding: "); KernelLog.String(message.bodystructure.encoding); KernelLog.Ln();
KernelLog.String("Charset: "); KernelLog.String(message.bodystructure.charset); KernelLog.Ln();
END;
IF (message.bodystructure.type = "TEXT") & (message.bodystructure.subtype = "PLAIN") THEN
IF message.message # NIL THEN
IF message.bodystructure.encoding = "BASE64" THEN
string := IMAPUtilities.decodeBase64(message.message^);
ELSIF message.bodystructure.encoding = "QUOTED-PRINTABLE" THEN
string := IMAPUtilities.decodeQuotedPrintable(message.message^);
ELSE
string := Strings.NewString(message.message^);
END;
NEW(text);
IF message.bodystructure.charset = "UTF-8" THEN
IMAPUtilities.StrToText(text, 0, string^);
ELSIF message.bodystructure.charset = "ISO-8859-1" THEN
i := IMAPUtilities.StringLength(string^);
NEW(string2, 6*i + 1);
UTF8Strings.ASCIItoUTF8(string^, string2^);
IMAPUtilities.StrToText(text, 0, string2^);
ELSE
i := IMAPUtilities.StringLength(string^);
NEW(string2, 6*i + 1);
UTF8Strings.ASCIItoUTF8(string^, string2^);
IMAPUtilities.StrToText(text, 0, string2^);
END;
messageField.SetText(text);
statusLabel.SetCaption("Status: Finished");
ELSE
messageField.SetAsString("Message can not be loaded!");
statusLabel.SetCaption("Finished");
END;
ELSE
NEW(text);
IMAPUtilities.StrToText(text, 0, message.message^);
messageField.SetText(text);
statusLabel.SetCaption("Message is not of type TEXT/PLAIN");
END;
ELSE
IF message.message = NIL THEN
OutputError("The body of this message is not available. Maybe your are offline and don't have the body in your local storage");
ELSE
NEW(text);
IMAPUtilities.StrToText(text, 0, message.message^);
messageField.SetText(text);
statusLabel.SetCaption("The Bodystructure for this message is not available. TEXT/PLAIN is assumed.");
END;
END;
from.hScrollbar.visible.Set(FALSE);
to.hScrollbar.visible.Set(FALSE);
cc.hScrollbar.visible.Set(FALSE);
END DisplayMessage;
END MessageWindow;
SearchWindow = OBJECT (WMComponents.FormWindow)
VAR
answered, unanswered, deleted, undeleted, draft, undraft, flagged, unflagged, seen, unseen, recent, old: WMStandardComponents.Checkbox;
subject, text, from, minSize, maxSize: WMEditors.Editor;
search, cancel: WMStandardComponents.Button;
before, on, after: WMStandardComponents.Checkbox;
day, month, year: WMEditors.Editor;
utf8: WMStandardComponents.Checkbox;
status: WMStandardComponents.Label;
w: Window;
PROCEDURE &New*(win: Window);
VAR
vc : WMComponents.VisualComponent;
BEGIN
IncCount();
w := win;
vc := CreateForm();
Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), FALSE);
SetContent(vc);
SetTitle(Strings.NewString("Search Window"));
WMWindowManager.DefaultAddWindow(SELF);
END New;
PROCEDURE CreateForm() : WMComponents.VisualComponent;
VAR
panel : WMStandardComponents.Panel;
label: WMStandardComponents.Label;
p: WMStandardComponents.Panel;
BEGIN
NEW(panel); panel.bounds.SetExtents(600, 400); panel.fillColor.Set(LONGINT(0CCCCCCFFH));
NEW(p);
p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Answered: ");
p.AddContent(label);
NEW(answered); answered.bounds.SetWidth(20); answered.alignment.Set(WMComponents.AlignLeft);
p.AddContent(answered);
NEW(label); label.bounds.SetWidth(50); label.alignment.Set(WMComponents.AlignLeft);
p.AddContent(label);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Unanswered: ");
p.AddContent(label);
NEW(unanswered); unanswered.bounds.SetWidth(20); unanswered.alignment.Set(WMComponents.AlignLeft);
p.AddContent(unanswered);
NEW(p);
p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Deleted: ");
p.AddContent(label);
NEW(deleted); deleted.bounds.SetWidth(20); deleted.alignment.Set(WMComponents.AlignLeft);
p.AddContent(deleted);
NEW(label); label.bounds.SetWidth(50); label.alignment.Set(WMComponents.AlignLeft);
p.AddContent(label);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Undeleted: ");
p.AddContent(label);
NEW(undeleted); undeleted.bounds.SetWidth(20); undeleted.alignment.Set(WMComponents.AlignLeft);
p.AddContent(undeleted);
NEW(p);
p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Draft: ");
p.AddContent(label);
NEW(draft); draft.bounds.SetWidth(20); draft.alignment.Set(WMComponents.AlignLeft);
p.AddContent(draft);
NEW(label); label.bounds.SetWidth(50); label.alignment.Set(WMComponents.AlignLeft);
p.AddContent(label);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Undraft: ");
p.AddContent(label);
NEW(undraft); undraft.bounds.SetWidth(20); undraft.alignment.Set(WMComponents.AlignLeft);
p.AddContent(undraft);
NEW(p);
p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Flagged: ");
p.AddContent(label);
NEW(flagged); flagged.bounds.SetWidth(20); flagged.alignment.Set(WMComponents.AlignLeft);
p.AddContent(flagged);
NEW(label); label.bounds.SetWidth(50); label.alignment.Set(WMComponents.AlignLeft);
p.AddContent(label);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Unflagged: ");
p.AddContent(label);
NEW(unflagged); unflagged.bounds.SetWidth(20); unflagged.alignment.Set(WMComponents.AlignLeft);
p.AddContent(unflagged);
NEW(p);
p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Seen: ");
p.AddContent(label);
NEW(seen); seen.bounds.SetWidth(20); seen.alignment.Set(WMComponents.AlignLeft);
p.AddContent(seen);
NEW(label); label.bounds.SetWidth(50); label.alignment.Set(WMComponents.AlignLeft);
p.AddContent(label);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Unseen: ");
p.AddContent(label);
NEW(unseen); unseen.bounds.SetWidth(20); unseen.alignment.Set(WMComponents.AlignLeft);
p.AddContent(unseen);
NEW(p);
p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Recent: ");
p.AddContent(label);
NEW(recent); recent.bounds.SetWidth(20); recent.alignment.Set(WMComponents.AlignLeft);
p.AddContent(recent);
NEW(label); label.bounds.SetWidth(50); label.alignment.Set(WMComponents.AlignLeft);
p.AddContent(label);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Old: ");
p.AddContent(label);
NEW(old); old.bounds.SetWidth(20); old.alignment.Set(WMComponents.AlignLeft);
p.AddContent(old);
NEW(p);
p.bounds.SetHeight(25); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Subject: ");
p.AddContent(label);
NEW(subject); subject.bounds.SetWidth(300); subject.alignment.Set(WMComponents.AlignClient);
subject.multiLine.Set(FALSE); subject.fillColor.Set(LONGINT(0FFFFFFFFH)); subject.tv.showBorder.Set(TRUE);
p.AddContent(subject);
NEW(p);
p.bounds.SetHeight(25); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("From: ");
p.AddContent(label);
NEW(from); from.bounds.SetWidth(300); from.alignment.Set(WMComponents.AlignClient);
from.multiLine.Set(FALSE); from.fillColor.Set(LONGINT(0FFFFFFFFH)); from.tv.showBorder.Set(TRUE);
p.AddContent(from);
NEW(p);
p.bounds.SetHeight(25); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Body-Text: ");
p.AddContent(label);
NEW(text); text.bounds.SetWidth(300); text.alignment.Set(WMComponents.AlignClient);
text.multiLine.Set(FALSE); text.fillColor.Set(LONGINT(0FFFFFFFFH)); text.tv.showBorder.Set(TRUE);
p.AddContent(text);
NEW(p);
p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Min Size: ");
p.AddContent(label);
NEW(minSize); minSize.bounds.SetWidth(100); minSize.alignment.Set(WMComponents.AlignLeft);
minSize.multiLine.Set(FALSE); minSize.fillColor.Set(LONGINT(0FFFFFFFFH)); minSize.tv.showBorder.Set(TRUE);
p.AddContent(minSize);
NEW(label); label.bounds.SetWidth(50); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC(" ");
p.AddContent(label);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Max Size: ");
p.AddContent(label);
NEW(maxSize); maxSize.bounds.SetWidth(100); maxSize.alignment.Set(WMComponents.AlignLeft);
maxSize.multiLine.Set(FALSE); maxSize.fillColor.Set(LONGINT(0FFFFFFFFH)); maxSize.tv.showBorder.Set(TRUE);
p.AddContent(maxSize);
NEW(p);
p.bounds.SetHeight(15); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(p);
p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Before: ");
p.AddContent(label);
NEW(before); before.bounds.SetWidth(20); before.alignment.Set(WMComponents.AlignLeft);
p.AddContent(before);
NEW(p);
p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("On: ");
p.AddContent(label);
NEW(on); on.bounds.SetWidth(20); on.alignment.Set(WMComponents.AlignLeft);
p.AddContent(on);
NEW(label); label.bounds.SetWidth(50); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC(" ");
p.AddContent(label);
NEW(label); label.bounds.SetWidth(50); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Date: ");
p.AddContent(label);
NEW(label); label.bounds.SetWidth(50); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Day: ");
p.AddContent(label);
NEW(day); day.bounds.SetWidth(50); day.alignment.Set(WMComponents.AlignLeft);
day.multiLine.Set(FALSE); day.fillColor.Set(LONGINT(0FFFFFFFFH)); day.tv.showBorder.Set(TRUE);
p.AddContent(day);
NEW(label); label.bounds.SetWidth(50); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Month: ");
p.AddContent(label);
NEW(month); month.bounds.SetWidth(50); month.alignment.Set(WMComponents.AlignLeft);
month.multiLine.Set(FALSE); month.fillColor.Set(LONGINT(0FFFFFFFFH)); month.tv.showBorder.Set(TRUE);
p.AddContent(month);
NEW(label); label.bounds.SetWidth(50); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Year: ");
p.AddContent(label);
NEW(year); year.bounds.SetWidth(50); year.alignment.Set(WMComponents.AlignLeft);
year.multiLine.Set(FALSE); year.fillColor.Set(LONGINT(0FFFFFFFFH)); year.tv.showBorder.Set(TRUE);
p.AddContent(year);
NEW(p);
p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("After: ");
p.AddContent(label);
NEW(after); after.bounds.SetWidth(20); after.alignment.Set(WMComponents.AlignLeft);
p.AddContent(after);
NEW(p);
p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(label); label.bounds.SetWidth(200); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Try UTF-8 charset for search strings: ");
p.AddContent(label);
NEW(utf8); utf8.bounds.SetWidth(20); utf8.alignment.Set(WMComponents.AlignLeft);
p.AddContent(utf8);
NEW(p);
p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignBottom);
p.bearing.Set(WMRectangles.MakeRect(5,2,5,2));
panel.AddContent(p);
NEW(search);
search.bounds.SetWidth(100); search.alignment.Set(WMComponents.AlignRight);
search.caption.SetAOC("Search"); search.onClick.Add(SearchHandler);
p.AddContent(search);
NEW(cancel);
cancel.bounds.SetWidth(100); cancel.alignment.Set(WMComponents.AlignRight);
cancel.caption.SetAOC("Cancel"); cancel.onClick.Add(CancelHandler);
p.AddContent(cancel);
NEW(status); status.bounds.SetWidth(400); status.alignment.Set(WMComponents.AlignLeft);
status.caption.SetAOC("Status: Ready");
p.AddContent(status);
RETURN panel;
END CreateForm;
PROCEDURE Close;
BEGIN
Close^();
DecCount();
END Close;
PROCEDURE Handle(VAR x: WMMessages.Message);
BEGIN
IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) & (x.ext IS KillerMsg) THEN
Close();
ELSE
Handle^(x);
END;
END Handle;
PROCEDURE SearchHandler(sender, data: ANY);
VAR
buffer, dateBuffer: Strings.Buffer;
string, dateString: String;
writer, dateWriter: Streams.Writer;
i, dateCount: LONGINT;
monthString: ARRAY 37 OF CHAR;
valid: BOOLEAN;
errorString: ARRAY 65 OF CHAR;
BEGIN
valid := TRUE;
NEW(buffer, 16);
writer := buffer.GetWriter();
i := utf8.state.Get();
IF i = 1 THEN writer.String("CHARSET UTF-8 "); END;
i := answered.state.Get();
IF i = 1 THEN writer.String("ANSWERED "); END;
i := unanswered.state.Get();
IF i = 1 THEN writer.String("UNANSWERED ") END;
i := deleted.state.Get();
IF i = 1 THEN writer.String("DELETED ") END;
i := undeleted.state.Get();
IF i = 1 THEN writer.String("UNDELETED ") END;
i := draft.state.Get();
IF i = 1 THEN writer.String("DRAFT ") END;
i := undraft.state.Get();
IF i = 1 THEN writer.String("UNDRAFT ") END;
i := flagged.state.Get();
IF i = 1 THEN writer.String("FLAGGED ") END;
i := unflagged.state.Get();
IF i = 1 THEN writer.String("UNFLAGGED ") END;
i := seen.state.Get();
IF i = 1 THEN writer.String("SEEN ") END;
i := unseen.state.Get();
IF i = 1 THEN writer.String("UNSEEN ") END;
i := recent.state.Get();
IF i = 1 THEN writer.String("RECENT ") END;
i := old.state.Get();
IF i = 1 THEN writer.String("OLD ") END;
IMAPUtilities.TextToStr(subject.text, string);
IF IMAPUtilities.StringLength(string^) > 0 THEN
IMAPUtilities.MakeQuotedString(string);
writer.String("SUBJECT ");
writer.String(string^);
writer.String(" ");
END;
IMAPUtilities.TextToStr(from.text, string);
IF IMAPUtilities.StringLength(string^) > 0 THEN
IMAPUtilities.MakeQuotedString(string);
writer.String("FROM ");
writer.String(string^);
writer.String(" ");
END;
IMAPUtilities.TextToStr(text.text, string);
IF IMAPUtilities.StringLength(string^) > 0 THEN
IMAPUtilities.MakeQuotedString(string);
writer.String("BODY ");
writer.String(string^);
writer.String(" ");
END;
IMAPUtilities.TextToStr(minSize.text, string);
IF IMAPUtilities.StringLength(string^) > 0 THEN
Strings.StrToInt(string^, i);
Strings.IntToStr(i-1, string^);
writer.String("LARGER ");
writer.String(string^);
writer.String(" ");
END;
IMAPUtilities.TextToStr(maxSize.text, string);
IF IMAPUtilities.StringLength(string^) > 0 THEN
Strings.StrToInt(string^,i);
Strings.IntToStr(i+1, string^);
writer.String("SMALLER ");
writer.String(string^);
writer.String(" ");
END;
dateCount := 0;
i := before.state.Get();
IF i = 1 THEN INC(dateCount); END;
i := on.state.Get();
IF i = 1 THEN INC(dateCount); END;
i := after.state.Get();
IF i = 1 THEN INC(dateCount); END;
IF dateCount = 3 THEN
ELSE
IF dateCount = 2 THEN
writer.String("OR ");
END;
NEW(dateBuffer, 16);
dateWriter := dateBuffer.GetWriter();
IMAPUtilities.TextToStr(day.text, string);
IF IMAPUtilities.StringLength(string^) > 0 THEN
Strings.StrToInt(string^,i);
IF (i < 1) OR (i > 31) THEN
valid := FALSE;
COPY("Day should be between 1 and 31", errorString);
END;
Strings.IntToStr(i, string^);
dateWriter.String(string^);
dateWriter.String("-");
END;
IMAPUtilities.TextToStr(month.text, string);
IF IMAPUtilities.StringLength(string^) > 0 THEN
Strings.StrToInt(string^,i);
IF (i < 1) OR (i > 12) THEN
valid := FALSE;
COPY("Month should be between 1 and 12", errorString);
ELSE
COPY("JanFebMarAprMayJunJulAugSepOctNovDec", monthString);
IMAPUtilities.StringCopy(monthString, (3*i)-3, 3, string^);
dateWriter.String(string^);
dateWriter.String("-");
END;
END;
IMAPUtilities.TextToStr(year.text, string);
IF IMAPUtilities.StringLength(string^) > 0 THEN
Strings.StrToInt(string^,i);
Strings.IntToStr(i, string^);
IF IMAPUtilities.StringLength(string^) # 4 THEN
valid := FALSE;
COPY("Year should consist of 4 digits", errorString);
END;
dateWriter.String(string^);
END;
dateString := dateBuffer.GetString();
i := before.state.Get();
IF i = 1 THEN
writer.String("BEFORE ");
writer.String(dateString^);
writer.String(" ");
END;
i := on.state.Get();
IF i = 1 THEN
writer.String("ON ");
writer.String(dateString^);
writer.String(" ");
END;
i := after.state.Get();
IF i = 1 THEN
writer.String("SINCE ");
writer.String(dateString^);
writer.String(" ");
END;
END;
IF valid THEN
string := buffer.GetString();
Strings.TrimRight(string^, " ");
IF DEBUG THEN KernelLog.String("Performing search..."); END;
status.caption.SetAOC("Status: Performing search...");
i := w.client.Search(string^);
IF i < 0 THEN
status.caption.SetAOC("Status: Searching Not Successful");
ELSE
NEW(buffer,16);
writer := buffer.GetWriter();
writer.String("Status: Finished. ");
NEW(string, 20);
Strings.IntToStr(i, string^);
writer.String(string^);
writer.String(" messages found.");
string := buffer.GetString();
status.caption.SetAOC(string^);
IF DEBUG THEN KernelLog.String("Search finished. "); KernelLog.Int(i,0); KernelLog.String(" messages found"); KernelLog.Ln(); END;
w.messageGrid.SetTopPosition(0,0,TRUE);
w.timer.Wakeup();
END;
ELSE
NEW(buffer,16);
writer := buffer.GetWriter();
writer.String("Status: Invalid Input: ");
writer.String(errorString);
string := buffer.GetString();
status.caption.SetAOC(string^);
OutputError(errorString);
END;
END SearchHandler;
PROCEDURE CancelHandler(sender, data: ANY);
VAR
BEGIN
Close^;
END CancelHandler;
END SearchWindow;
PreferencesWindow = OBJECT (WMComponents.FormWindow)
VAR
SMTPServer, SMTPThisHost, SentFolder, DraftFolder, TrashBin, From: WMEditors.Editor;
ExpungeOnFolderChange, ExpungeOnDelete, UseDragNDropAsMove, ExpungeOnMove, UseATrashBin: WMStandardComponents.Checkbox;
ok, cancel: WMStandardComponents.Button;
window: Window;
oldPreferences: IMAPClient.AccountPreferences;
PROCEDURE &New*(win: Window);
VAR
vc : WMComponents.VisualComponent;
BEGIN
IncCount();
window := win;
IF window.client # NIL THEN
oldPreferences := window.client.preferences;
ELSE
NEW(oldPreferences);
END;
vc := CreateForm();
Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), FALSE);
SetContent(vc);
SetTitle(Strings.NewString("Preferences"));
WMWindowManager.DefaultAddWindow(SELF);
END New;
PROCEDURE CreateForm() : WMComponents.VisualComponent;
VAR
panel : WMStandardComponents.Panel;
label: WMStandardComponents.Label;
p: WMStandardComponents.Panel;
rect: WMRectangles.Rectangle;
BEGIN
NEW(panel); panel.bounds.SetExtents(500, 400); panel.fillColor.Set(LONGINT(0CCCCCCFFH));
rect := WMRectangles.MakeRect(5, 2, 5, 2);
NEW(p); p.bounds.SetHeight(25); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(rect);
NEW(label); label.bounds.SetWidth(200); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("IMAP server name: ");
p.AddContent(label);
NEW(label); label.alignment.Set(WMComponents.AlignClient);
label.caption.Set(window.client.preferences.IMAPServer);
p.AddContent(label);
panel.AddContent(p);
NEW(p); p.bounds.SetHeight(25); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(rect);
NEW(label); label.bounds.SetWidth(200); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("IMAP user name: ");
p.AddContent(label);
NEW(label); label.alignment.Set(WMComponents.AlignClient);
label.caption.Set(window.client.preferences.UserName);
p.AddContent(label);
panel.AddContent(p);
NEW(p); p.bounds.SetHeight(25); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(rect);
NEW(label); label.bounds.SetWidth(200); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("SMTP server name: ");
p.AddContent(label);
NEW(SMTPServer); SMTPServer.alignment.Set(WMComponents.AlignClient);
SMTPServer.multiLine.Set(FALSE); SMTPServer.fillColor.Set(LONGINT(0FFFFFFFFH)); SMTPServer.tv.showBorder.Set(TRUE);
SMTPServer.SetAsString(oldPreferences.SMTPServer^);
p.AddContent(SMTPServer);
panel.AddContent(p);
NEW(p); p.bounds.SetHeight(25); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(rect);
NEW(label); label.bounds.SetWidth(200); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Name of this host(for SMTP): ");
p.AddContent(label);
NEW(SMTPThisHost); SMTPThisHost.alignment.Set(WMComponents.AlignClient);
SMTPThisHost.multiLine.Set(FALSE); SMTPThisHost.fillColor.Set(LONGINT(0FFFFFFFFH)); SMTPThisHost.tv.showBorder.Set(TRUE);
SMTPThisHost.SetAsString(oldPreferences.SMTPThisHost^);
p.AddContent(SMTPThisHost);
panel.AddContent(p);
NEW(p); p.bounds.SetHeight(25); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(rect);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Sent Folder: ");
p.AddContent(label);
NEW(SentFolder); SentFolder.alignment.Set(WMComponents.AlignClient);
SentFolder.multiLine.Set(FALSE); SentFolder.fillColor.Set(LONGINT(0FFFFFFFFH)); SentFolder.tv.showBorder.Set(TRUE);
SentFolder.SetAsString(oldPreferences.SentFolder^);
p.AddContent(SentFolder);
panel.AddContent(p);
NEW(p); p.bounds.SetHeight(25); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(rect);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Draft Folder: ");
p.AddContent(label);
NEW(DraftFolder); DraftFolder.alignment.Set(WMComponents.AlignClient);
DraftFolder.multiLine.Set(FALSE); DraftFolder.fillColor.Set(LONGINT(0FFFFFFFFH)); DraftFolder.tv.showBorder.Set(TRUE);
DraftFolder.SetAsString(oldPreferences.DraftFolder^);
p.AddContent(DraftFolder);
panel.AddContent(p);
NEW(p); p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(rect);
NEW(label); label.bounds.SetWidth(200); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Use A Trash Bin: ");
p.AddContent(label);
NEW(UseATrashBin); UseATrashBin.bounds.SetWidth(20); UseATrashBin.alignment.Set(WMComponents.AlignLeft);
IF oldPreferences.UseATrashBin THEN
UseATrashBin.state.Set(1);
ELSE
UseATrashBin.state.Set(0);
END;
p.AddContent(UseATrashBin);
panel.AddContent(p);
NEW(p); p.bounds.SetHeight(25); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(rect);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Trash Bin: ");
p.AddContent(label);
NEW(TrashBin); TrashBin.alignment.Set(WMComponents.AlignClient);
TrashBin.multiLine.Set(FALSE); TrashBin.fillColor.Set(LONGINT(0FFFFFFFFH)); TrashBin.tv.showBorder.Set(TRUE);
TrashBin.SetAsString(oldPreferences.TrashBin^);
p.AddContent(TrashBin);
panel.AddContent(p);
NEW(p); p.bounds.SetHeight(25); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(rect);
NEW(label); label.bounds.SetWidth(100); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("From Field: ");
p.AddContent(label);
NEW(From); From.alignment.Set(WMComponents.AlignClient);
From.multiLine.Set(FALSE); From.fillColor.Set(LONGINT(0FFFFFFFFH)); From.tv.showBorder.Set(TRUE);
From.SetAsString(oldPreferences.From^);
p.AddContent(From);
panel.AddContent(p);
NEW(p); p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(rect);
NEW(label); label.bounds.SetWidth(200); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Expunge On Folder Change: ");
p.AddContent(label);
NEW(ExpungeOnFolderChange); ExpungeOnFolderChange.bounds.SetWidth(20); ExpungeOnFolderChange.alignment.Set(WMComponents.AlignLeft);
IF oldPreferences.ExpungeOnFolderChange THEN
ExpungeOnFolderChange.state.Set(1);
ELSE
ExpungeOnFolderChange.state.Set(0);
END;
p.AddContent(ExpungeOnFolderChange);
panel.AddContent(p);
NEW(p); p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(rect);
NEW(label); label.bounds.SetWidth(200); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Expunge On Delete: ");
p.AddContent(label);
NEW(ExpungeOnDelete); ExpungeOnDelete.bounds.SetWidth(20); ExpungeOnDelete.alignment.Set(WMComponents.AlignLeft);
IF oldPreferences.ExpungeOnDelete THEN
ExpungeOnDelete.state.Set(1);
ELSE
ExpungeOnDelete.state.Set(0);
END;
p.AddContent(ExpungeOnDelete);
panel.AddContent(p);
NEW(p); p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(rect);
NEW(label); label.bounds.SetWidth(200); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Use Drag'n'Drop as Move: ");
p.AddContent(label);
NEW(UseDragNDropAsMove); UseDragNDropAsMove.bounds.SetWidth(20); UseDragNDropAsMove.alignment.Set(WMComponents.AlignLeft);
IF oldPreferences.UseDragNDropAsMove THEN
UseDragNDropAsMove.state.Set(1);
ELSE
UseDragNDropAsMove.state.Set(0);
END;
p.AddContent(UseDragNDropAsMove);
panel.AddContent(p);
NEW(p); p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignTop);
p.bearing.Set(rect);
NEW(label); label.bounds.SetWidth(200); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Expunge On Move: ");
p.AddContent(label);
NEW(ExpungeOnMove); ExpungeOnMove.bounds.SetWidth(20); ExpungeOnMove.alignment.Set(WMComponents.AlignLeft);
IF oldPreferences.ExpungeOnMove THEN
ExpungeOnMove.state.Set(1);
ELSE
ExpungeOnMove.state.Set(0);
END;
p.AddContent(ExpungeOnMove);
panel.AddContent(p);
NEW(p); p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignBottom);
NEW(ok);
ok.bounds.SetWidth(100); ok.alignment.Set(WMComponents.AlignRight);
ok.caption.SetAOC("OK"); ok.onClick.Add(OKHandler);
p.AddContent(ok);
NEW(cancel);
cancel.bounds.SetWidth(100); cancel.alignment.Set(WMComponents.AlignRight);
cancel.caption.SetAOC("Cancel"); cancel.onClick.Add(CancelHandler);
p.AddContent(cancel);
panel.AddContent(p);
RETURN panel;
END CreateForm;
PROCEDURE Close;
BEGIN
Close^();
DecCount();
END Close;
PROCEDURE Handle(VAR x: WMMessages.Message);
BEGIN
IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) & (x.ext IS KillerMsg) THEN
Close();
ELSE
Handle^(x);
END;
END Handle;
PROCEDURE OKHandler(sender, data: ANY);
VAR
i: LONGINT;
string: String;
preferences: IMAPClient.AccountPreferences;
BEGIN
IF window # NIL THEN
preferences := window.client.preferences;
IMAPUtilities.TextToStr(SMTPServer.text, string);
window.client.preferences.SMTPServer := string;
IMAPUtilities.TextToStr(SMTPThisHost.text, string);
preferences.SMTPThisHost := string;
IMAPUtilities.TextToStr(SentFolder.text, string);
preferences.SentFolder := string;
IMAPUtilities.TextToStr(DraftFolder.text, string);
preferences.DraftFolder := string;
IMAPUtilities.TextToStr(TrashBin.text, string);
preferences.TrashBin := string;
IMAPUtilities.TextToStr(From.text, string);
preferences.From := string;
i := ExpungeOnFolderChange.state.Get();
preferences.ExpungeOnFolderChange := (i=1);
i := ExpungeOnDelete.state.Get();
preferences.ExpungeOnDelete := (i=1);
i := UseDragNDropAsMove.state.Get();
preferences.UseDragNDropAsMove := (i=1);
i := ExpungeOnMove.state.Get();
preferences.ExpungeOnMove := (i=1);
i := UseATrashBin.state.Get();
preferences.UseATrashBin := (i=1);
ELSE
OutputError("Updating Preferences not possible, because Client is not initialized");
END;
Close^();
END OKHandler;
PROCEDURE CancelHandler(sender, data: ANY);
BEGIN
Close^;
END CancelHandler;
END PreferencesWindow;
Window = OBJECT (WMComponents.FormWindow)
VAR
topToolbar, messagePanel : WMStandardComponents.Panel;
statusLabel, currentFolderLabel, currentMessagesLabel: WMStandardComponents.Label;
connect, disconnect, reload, abort, search, save, load, new, expunge, preferences, download, switchToOffline, switchToOnline: WMStandardComponents.Button;
messageGrid : WMStringGrids.StringGrid;
folderTree: WMTrees.TreeView;
tree: WMTrees.Tree;
colWidths : WMGrids.Spacings;
address: WMEditors.Editor;
popup: WMPopups.Popup;
px, py : LONGINT;
IconRead, IconAnswered, IconUnread, IconDeleted: WMGraphics.Image;
copyTarget: IMAPClient.Folder;
client: IMAPClient.Client;
timer: Kernel.Timer;
updateFlag: BOOLEAN;
active: BOOLEAN;
PROCEDURE &New*(c: WMRestorable.Context);
VAR vc : WMComponents.VisualComponent; panel : WMStandardComponents.Panel;
BEGIN
NEW(client, RefreshDisplay, OutputError);
vc := CreateForm();
Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), FALSE);
SetContent(vc);
SetTitle(Strings.NewString(WindowTitle));
SetIcon(WMGraphics.LoadImage("WMIcons.tar://IMAPGUI.png", TRUE));
active := TRUE;
updateFlag := FALSE;
copyTarget := NIL;
IconRead := WMGraphics.LoadImage("IMAPIcons.tar://IMAPIconRead.png", FALSE);
IconAnswered := WMGraphics.LoadImage("IMAPIcons.tar://IMAPIconAnswered.png", FALSE);
IconUnread := WMGraphics.LoadImage("IMAPIcons.tar://IMAPIconUnread.png", FALSE);
IconDeleted := WMGraphics.LoadImage("IMAPIcons.tar://IMAPIconDeleted.png", FALSE);
IF DEBUG THEN KernelLog.String("Window initialisiert"); KernelLog.Ln(); END;
IncCount();
IF c # NIL THEN
WMRestorable.AddByContext(SELF, c);
Resized(GetWidth(), GetHeight());
ELSE
WMWindowManager.DefaultAddWindow(SELF);
END;
END New;
PROCEDURE Resized(width, height : LONGINT);
BEGIN
Resized^(width, height);
ResizeGrid;
END Resized;
PROCEDURE ResizeGrid;
BEGIN
IF LEN(colWidths) = 4 THEN
NEW(colWidths, 4);
colWidths[0] := (messageGrid.bounds.GetWidth() DIV 8)*2;
colWidths[1] := (messageGrid.bounds.GetWidth() DIV 8)*3;
colWidths[2] := messageGrid.bounds.GetWidth() DIV 4;
colWidths[3] := messageGrid.bounds.GetWidth() DIV 8;
ELSE
NEW(colWidths, 1);
colWidths[0] := messageGrid.bounds.GetWidth();
END;
messageGrid.SetColSpacings(colWidths);
END ResizeGrid;
PROCEDURE CreateForm() : WMComponents.VisualComponent;
VAR
panel : WMStandardComponents.Panel;
label : WMStandardComponents.Label;
p: WMStandardComponents.Panel;
rect: WMRectangles.Rectangle;
root: WMTrees.TreeNode;
BEGIN
rect := WMRectangles.MakeRect(2,3,0,3);
NEW(panel); panel.bounds.SetExtents(1024, 768); panel.fillColor.Set(WMGraphics.White);
NEW(topToolbar); topToolbar.bounds.SetHeight(78); topToolbar.alignment.Set(WMComponents.AlignTop);
topToolbar.fillColor.Set(LONGINT(0CCCCCCFFH));
panel.AddContent(topToolbar);
NEW(p); p.bounds.SetHeight(26); p.alignment.Set(WMComponents.AlignTop);
topToolbar.AddContent(p);
NEW(label); label.bounds.SetWidth(40); label.alignment.Set(WMComponents.AlignLeft);
label.caption.SetAOC("Host: "); label.textColor.Set(0000000FFH); label.bearing.Set(rect); p.AddContent(label);
NEW(address); address.bounds.SetWidth(160); address.alignment.Set(WMComponents.AlignLeft);
address.multiLine.Set(FALSE); address.fillColor.Set(LONGINT(0FFFFFFFFH)); address.bearing.Set(rect); address.tv.showBorder.Set(TRUE);
address.tv.borders.Set(WMRectangles.MakeRect(3,3,1,1));
address.onEnter.Add(ButtonHandler);
p.AddContent(address);
IMAPUtilities.SetEditorText(address, client.preferences.IMAPServer);
NEW(connect); connect.bounds.SetWidth(100); connect.alignment.Set(WMComponents.AlignLeft);
connect.caption.SetAOC("Connect"); connect.bearing.Set(rect); connect.onClick.Add(ButtonHandler);
p.AddContent(connect);
NEW(disconnect); disconnect.bounds.SetWidth(100); disconnect.alignment.Set(WMComponents.AlignLeft);
disconnect.caption.SetAOC("Disconnect"); disconnect.bearing.Set(rect); disconnect.onClick.Add(ButtonHandler);
p.AddContent(disconnect);
NEW(save); save.bounds.SetWidth(100); save.alignment.Set(WMComponents.AlignLeft);
save.caption.SetAOC("Save Account"); save.bearing.Set(rect); save.onClick.Add(ButtonHandler);
p.AddContent(save);
NEW(load); load.bounds.SetWidth(100); load.alignment.Set(WMComponents.AlignLeft);
load.caption.SetAOC("Load Account"); load.bearing.Set(rect); load.onClick.Add(ButtonHandler);
p.AddContent(load);
NEW(switchToOffline); switchToOffline.bounds.SetWidth(100); switchToOffline.alignment.Set(WMComponents.AlignLeft);
switchToOffline.caption.SetAOC("Switch To Offline"); switchToOffline.bearing.Set(rect); switchToOffline.onClick.Add(ButtonHandler);
p.AddContent(switchToOffline);
NEW(switchToOnline); switchToOnline.bounds.SetWidth(100); switchToOnline.alignment.Set(WMComponents.AlignLeft);
switchToOnline.caption.SetAOC("Switch To Online"); switchToOnline.bearing.Set(rect); switchToOnline.onClick.Add(ButtonHandler);
p.AddContent(switchToOnline);
NEW(preferences); preferences.bounds.SetWidth(100); preferences.alignment.Set(WMComponents.AlignLeft);
preferences.caption.SetAOC("Preferences"); preferences.bearing.Set(rect); preferences.onClick.Add(ButtonHandler);
p.AddContent(preferences);
NEW(p); p.bounds.SetHeight(26); p.alignment.Set(WMComponents.AlignTop);
topToolbar.AddContent(p);
NEW(new); new.bounds.SetWidth(100); new.alignment.Set(WMComponents.AlignLeft);
new.caption.SetAOC("Send new"); new.bearing.Set(rect);new.onClick.Add(ButtonHandler);
p.AddContent(new);
NEW(reload); reload.bounds.SetWidth(100); reload.alignment.Set(WMComponents.AlignLeft);
reload.caption.SetAOC("Reload"); reload.bearing.Set(rect); reload.onClick.Add(ButtonHandler);
p.AddContent(reload);
NEW(abort); abort.bounds.SetWidth(100); abort.alignment.Set(WMComponents.AlignLeft);
abort.caption.SetAOC("Abort"); abort.bearing.Set(rect); abort.onClick.Add(ButtonHandler);
p.AddContent(abort);
NEW(search); search.bounds.SetWidth(100); search.alignment.Set(WMComponents.AlignLeft);
search.caption.SetAOC("Search"); search.bearing.Set(rect); search.onClick.Add(ButtonHandler);
p.AddContent(search);
NEW(expunge); expunge.bounds.SetWidth(100); expunge.alignment.Set(WMComponents.AlignLeft);
expunge.caption.SetAOC("Expunge"); expunge.bearing.Set(rect); expunge.onClick.Add(ButtonHandler);
p.AddContent(expunge);
NEW(download); download.bounds.SetWidth(100); download.alignment.Set(WMComponents.AlignLeft);
download.caption.SetAOC("Load all messages"); download.bearing.Set(rect); download.onClick.Add(ButtonHandler);
p.AddContent(download);
NEW(p);
p.bounds.SetHeight(26); p.alignment.Set(WMComponents.AlignTop);
topToolbar.AddContent(p);
NEW(currentMessagesLabel);
currentMessagesLabel.bounds.SetWidth(200);
currentMessagesLabel.alignment.Set(WMComponents.AlignLeft);
currentMessagesLabel.fillColor.Set(LONGINT(0CCCCCCFFH));
currentMessagesLabel.caption.SetAOC("Current Messages: 0 ");
currentMessagesLabel.bearing.Set(rect);
p.AddContent(currentMessagesLabel);
NEW(currentFolderLabel);
currentFolderLabel.alignment.Set(WMComponents.AlignClient);
currentFolderLabel.fillColor.Set(LONGINT(0CCCCCCFFH));
currentFolderLabel.caption.SetAOC("Current Folder: ");
currentFolderLabel.bearing.Set(rect);
p.AddContent(currentFolderLabel);
NEW(p);
p.bounds.SetHeight(20); p.alignment.Set(WMComponents.AlignBottom);
p.fillColor.Set(LONGINT(0CCCCCCFFH));
panel.AddContent(p);
NEW(statusLabel);
statusLabel.bounds.SetHeight(20);
statusLabel.alignment.Set(WMComponents.AlignTop);
statusLabel.bearing.Set(WMRectangles.MakeRect(3,0,0,0));
statusLabel.textColor.Set(0000000FFH);
statusLabel.SetCaption("Status: disconnected");
p.AddContent(statusLabel);
NEW(folderTree);
folderTree.bounds.SetWidth(200);
folderTree.alignment.Set(WMComponents.AlignLeft);
folderTree.bearing.Set(WMRectangles.MakeRect(3,3,0,0));
folderTree.fillColor.Set(WMGraphics.White);
folderTree.onClickNode.Add(ChangeFolder);
folderTree.SetExtContextMenuHandler(FolderContextMenu);
folderTree.SetExtDragDroppedHandler(MessagesDragDropped);
tree := folderTree.GetTree();
tree.Acquire();
NEW(root);
tree.SetRoot(root);
tree.SetNodeCaption(root, Strings.NewString("Folders"));
tree.Release();
panel.AddContent(folderTree);
NEW(messagePanel);
messagePanel.alignment.Set(WMComponents.AlignClient);
messagePanel.bounds.SetWidth(824);
messagePanel.fillColor.Set(LONGINT(0CCCCCCFFH));
panel.AddContent(messagePanel);
NEW(messageGrid);
messageGrid.alignment.Set(WMComponents.AlignClient);
messageGrid.bounds.SetWidth(824);
messageGrid.onClickSelected.Add(DisplayMessage);
messageGrid.SetExtContextMenuHandler(MessageContextMenu);
messageGrid.onStartDrag.Add(MessagesStartDrag);
messageGrid.fillColor.Set(WMGraphics.White);
NEW(colWidths, 1);
colWidths[0] := messageGrid.bounds.GetWidth();
messageGrid.model.Acquire;
messageGrid.SetColSpacings(colWidths);
messageGrid.model.SetNofCols(1);
messageGrid.model.SetNofRows(1);
messageGrid.fixedRows.Set(1);
messageGrid.clFixed.Set(LONGINT(0C0C0C0FFH));
messageGrid.model.SetCellText(0, 0, Strings.NewString(""));
messageGrid.SetSelectionMode(WMGrids.GridSelectRows);
messageGrid.showScrollX.Set(FALSE);
messageGrid.alwaysShowScrollX.Set(FALSE);
messageGrid.alwaysShowScrollY.Set(FALSE);
messageGrid.model.Release;
messagePanel.AddContent(messageGrid);
RETURN panel;
END CreateForm;
PROCEDURE ButtonHandler(sender, data: ANY);
BEGIN
IF sender = address THEN
Connect();
ELSIF sender = connect THEN
Connect();
ELSIF sender = disconnect THEN
Disconnect();
ELSIF sender = search THEN
Search();
ELSIF sender = reload THEN
Reload();
ELSIF sender = abort THEN
Abort();
ELSIF sender = save THEN
Save();
ELSIF sender = load THEN
Load();
ELSIF sender = new THEN
NewSend();
ELSIF sender = expunge THEN
Expunge();
ELSIF sender = preferences THEN
SetPreferences();
ELSIF sender = download THEN
DownloadAllMessages();
ELSIF sender = switchToOffline THEN
SwitchToOffline();
ELSIF sender = switchToOnline THEN
SwitchToOnline();
ELSE
OutputError("An Unknown Button was pressed");
END;
END ButtonHandler;
PROCEDURE DisplayMessage(sender, data: ANY);
VAR
message: IMAPClient.Message;
mw: MessageWindow;
i: LONGINT;
BEGIN
IF (data # NIL) & (data IS IMAPClient.Message) THEN
message := data(IMAPClient.Message);
IF (message.message = NIL) & (client.status = IMAPClient.ONLINE) THEN
client.abort := TRUE;
i := client.FetchMessage(message);
client.abort := FALSE;
client.timer.Wakeup();
END;
IF DEBUG THEN KernelLog.String("Display Message "); KernelLog.Int(i,0); KernelLog.Ln(); END;
NEW(mw, SELF);
mw.DisplayMessage(message);
ELSE
OutputError("Display Message NOT possible because your selection was invalid");
END;
END DisplayMessage;
PROCEDURE ChangeFolder(sender, data: ANY);
VAR
folder: IMAPClient.Folder;
treeNode: WMTrees.TreeNode;
p: ANY;
i: LONGINT;
BEGIN
IF (data # NIL) & (data IS WMTrees.TreeNode) THEN
treeNode := data(WMTrees.TreeNode);
p := tree.GetNodeData(treeNode);
IF p = NIL THEN RETURN; END;
folder := p(IMAPClient.Folder);
IF DEBUG THEN KernelLog.String("Change Folder: folder name: "); KernelLog.String(folder.name^); KernelLog.Ln(); END;
client.userAbort := FALSE;
client.abort := TRUE;
i := client.SelectFolder(folder);
client.abort := FALSE;
client.timer.Wakeup();
client.applySearchFilter := FALSE;
END;
messageGrid.Acquire;
messageGrid.SetTopPosition(0,0,TRUE);
messageGrid.Release;
RefreshDisplay();
END ChangeFolder;
PROCEDURE FolderContextMenu(sender : ANY; x, y: LONGINT);
VAR
p: ANY;
folder: IMAPClient.Folder;
selected: WMTrees.TreeNode;
BEGIN
selected := folderTree.GetNodeAtPos(x,y);
tree.Acquire;
p := tree.GetNodeData(selected);
IF p # NIL THEN
folder := p(IMAPClient.Folder);
IF DEBUG THEN KernelLog.String("Folder Name: "); KernelLog.String(folder.name^); KernelLog.Ln(); END;
NEW(popup);
popup.AddParButton("Create Sub-Folder", CreateDir, folder);
popup.AddParButton("Rename", RenameDir, folder);
popup.AddParButton("Delete", DeleteDir, folder);
popup.AddParButton("Select as Copy-Target", TargetDir, folder);
popup.AddParButton("Select as Sent Folder", SentFolder, folder);
popup.AddParButton("Select as Draft Folder", DraftFolder, folder);
popup.AddParButton("Select as Trash Bin", TrashBin, folder);
folderTree.ToWMCoordinates(x, y, px, py);
popup.Popup(px, py);
ELSE
IF DEBUG THEN KernelLog.String("No Folder Selected"); KernelLog.Ln(); END;
END;
tree.Release;
END FolderContextMenu;
PROCEDURE CreateDir(sender, data: ANY);
VAR
name : ARRAY 128 OF CHAR;
folder: IMAPClient.Folder;
r: LONGINT;
BEGIN
IF (data # NIL) & (data IS IMAPClient.Folder) THEN
folder := data(IMAPClient.Folder);
COPY("NewFolder", name);
IF WMDialogs.QueryString("Create Folder: ", name) = WMDialogs.ResOk THEN
IF DEBUG THEN KernelLog.String("Creating Folder: "); KernelLog.String(name); KernelLog.Ln; END;
client.abort := TRUE;
r := client.Create(folder, name);
client.abort := FALSE;
RefreshDisplay();
END;
END;
END CreateDir;
PROCEDURE RenameDir(sender, data: ANY);
VAR
folder: IMAPClient.Folder;
name : ARRAY 128 OF CHAR;
r: LONGINT;
BEGIN
IF (data # NIL) & (data IS IMAPClient.Folder) THEN
folder := data(IMAPClient.Folder);
COPY("NewName", name);
IF WMDialogs.QueryString("Rename Folder: ", name) = WMDialogs.ResOk THEN
IF DEBUG THEN KernelLog.String("Renaming Folder: "); KernelLog.String(folder.name^); KernelLog.String(" to "); KernelLog.String(name); KernelLog.Ln; END;
client.abort := TRUE;
r := client.Rename(folder, name);
client.abort := FALSE;
client.timer.Wakeup();
RefreshDisplay();
END
END;
END RenameDir;
PROCEDURE DeleteDir(sender, data: ANY);
VAR
folder: IMAPClient.Folder;
r: LONGINT;
buffer: Strings.Buffer;
w: Streams.Writer;
string: String;
BEGIN
IF (data # NIL) & (data IS IMAPClient.Folder) THEN
folder := data(IMAPClient.Folder);
NEW(buffer, 16);
w := buffer.GetWriter();
w.String("Do you want to delete the folder: ");
w.String(folder.name^);
string := buffer.GetString();
r := WMDialogs.Confirmation("Confirm deleting folder", string^);
IF r = WMDialogs.ResYes THEN
client.abort := TRUE;
r := client.Delete(folder);
client.abort := FALSE;
client.timer.Wakeup();
END;
END;
RefreshDisplay();
END DeleteDir;
PROCEDURE TargetDir(sender, data: ANY);
VAR
path: String;
BEGIN
IF (data # NIL) & (data IS IMAPClient.Folder) THEN
copyTarget := data(IMAPClient.Folder);
path := copyTarget.GetPath();
IF DEBUG THEN KernelLog.String("Copy-Target selected: "); KernelLog.String(path^); KernelLog.Ln(); END;
ELSE
IF DEBUG THEN KernelLog.String("No Copy-Target selected."); KernelLog.Ln(); END;
END;
END TargetDir;
PROCEDURE SentFolder(sender, data: ANY);
VAR
path: String;
folder: IMAPClient.Folder;
BEGIN
IF (data # NIL) & (data IS IMAPClient.Folder) THEN
folder := data(IMAPClient.Folder);
path := folder.GetPath();
client.preferences.SentFolder := path;
IF DEBUG THEN KernelLog.String("Sent Folder selected: "); KernelLog.String(path^); KernelLog.Ln(); END;
ELSE
IF DEBUG THEN KernelLog.String("No Sent Folder selected."); KernelLog.Ln(); END;
END;
END SentFolder;
PROCEDURE DraftFolder(sender, data: ANY);
VAR
path: String;
folder: IMAPClient.Folder;
BEGIN
IF (data # NIL) & (data IS IMAPClient.Folder) THEN
folder := data(IMAPClient.Folder);
path := folder.GetPath();
client.preferences.DraftFolder := path;
IF DEBUG THEN KernelLog.String("Draft Folder selected: "); KernelLog.String(path^); KernelLog.Ln(); END;
ELSE
IF DEBUG THEN KernelLog.String("No Draft Folder selected."); KernelLog.Ln(); END;
END;
END DraftFolder;
PROCEDURE TrashBin(sender, data: ANY);
VAR
path: String;
folder: IMAPClient.Folder;
BEGIN
IF (data # NIL) & (data IS IMAPClient.Folder) THEN
folder := data(IMAPClient.Folder);
path := folder.GetPath();
client.preferences.TrashBin := path;
client.preferences.UseATrashBin := TRUE;
IF DEBUG THEN KernelLog.String("Trash Bin selected: "); KernelLog.String(path^); KernelLog.Ln(); END;
ELSE
IF DEBUG THEN KernelLog.String("No Trash Bin selected."); KernelLog.Ln(); END;
END;
END TrashBin;
PROCEDURE MessagesDragDropped(x, y : LONGINT; dragInfo : WMWindowManager.DragInfo; VAR handled : BOOLEAN);
VAR
selected: WMTrees.TreeNode;
p: ANY;
folder: IMAPClient.Folder;
list: Classes.List;
i, r: LONGINT;
message: IMAPClient.Message;
successful: BOOLEAN;
path: String;
BEGIN
handled := TRUE;
IF DEBUG THEN KernelLog.String("MessagesDragDropped"); KernelLog.Ln(); END;
selected := folderTree.GetNodeAtPos(x,y);
tree.Acquire;
p := tree.GetNodeData(selected);
tree.Release;
IF p # NIL THEN
folder := p(IMAPClient.Folder);
IF DEBUG THEN KernelLog.String("Folder Name: "); KernelLog.String(folder.name^); KernelLog.Ln(); END;
ELSE
IF DEBUG THEN KernelLog.String("Folder NIL: "); KernelLog.Ln(); END;
END;
p := dragInfo.data;
IF p IS Classes.List THEN
IF DEBUG THEN KernelLog.String("Classes.List"); KernelLog.Ln(); END;
list := p(Classes.List);
i := 0;
client.abort := TRUE;
successful := TRUE;
WHILE i < list.GetCount() DO
p := list.GetItem(i);
message := p(IMAPClient.Message);
path := folder.GetPath();
r := client.CopyMessage(message, path);
IF (r = IMAPClient.OK) & client.preferences.UseDragNDropAsMove THEN
r := client.DeleteMessage(message, client.preferences.ExpungeOnMove);
ELSE
successful := FALSE;
END;
INC(i);
END;
IF successful & client.preferences.ExpungeOnMove THEN
r := client.Expunge();
END;
client.abort := FALSE;
client.timer.Wakeup();
ELSE
IF DEBUG THEN KernelLog.String("Not Classes.List "); KernelLog.Ln(); END;
END;
END MessagesDragDropped;
PROCEDURE MessagesStartDrag(sender,data: ANY);
VAR
list: Classes.List;
img : WMGraphics.Image;
c : WMGraphics.BufferCanvas;
top, i: LONGINT;
p: ANY;
message: IMAPClient.Message;
BEGIN
IF DEBUG THEN KernelLog.String("In MessageStartDrag"); KernelLog.Ln(); END;
list := GetMessageSelection();
NEW(img); Raster.Create(img, 100, 200, Raster.BGRA8888);
NEW(c, img);
c.SetColor(LONGINT(0FFFF00FFH));
top := 0;
FOR i := 0 TO list.GetCount() - 1 DO
c.Fill(WMRectangles.MakeRect(0, top, 100, top + 25), 0FF80H, WMGraphics.ModeCopy);
p := list.GetItem(i);
message := p(IMAPClient.Message);
c.DrawString(3, top + 20, message.header.subject^);
INC(top, 25)
END;
IF messageGrid.StartDrag(list, img, 0,0,DragArrivedList, NIL) THEN
IF DEBUG THEN KernelLog.String("DraggingStarted"); KernelLog.Ln(); END;
ELSE
IF DEBUG THEN KernelLog.String("Drag could not be started"); KernelLog.Ln(); END;
END;
END MessagesStartDrag;
PROCEDURE DragArrivedList(sender, data : ANY);
BEGIN
IF DEBUG THEN KernelLog.String("DragArrivedList"); KernelLog.Ln(); END;
IF sender = tree THEN
KernelLog.String("TREE"); KernelLog.Ln();
ELSE
KernelLog.String("Unknown"); KernelLog.Ln();
END;
IF data IS Classes.List THEN
KernelLog.String("data vom Type List"); KernelLog.Ln();
ELSE
KernelLog.String("data nicht vom Type List"); KernelLog.Ln();
END;
END DragArrivedList;
PROCEDURE MessageContextMenu(sender : ANY; x, y: LONGINT);
VAR
list: Classes.List;
BEGIN
px := x; py := y;
NEW(popup);
list := GetMessageSelection();
IF list.GetCount() > 0 THEN
popup.AddParButton("Copy to Target", CopyMessages, list);
popup.AddParButton("Delete", DeleteMessages, list);
popup.AddParButton("Restore", RestoreMessages, list);
END;
messageGrid.ToWMCoordinates(x, y, px, py);
popup.Popup(px, py);
END MessageContextMenu;
PROCEDURE GetMessageSelection() : Classes.List;
VAR selection : Classes.List;
l, t, r, b, NofSel, i : LONGINT;
p : ANY;
message: IMAPClient.Message;
BEGIN
messageGrid.model.Acquire;
messageGrid.GetSelection(l, t, r, b);
NofSel:= b- t + 1;
IF NofSel > 0 THEN
NEW(selection);
i := t;
WHILE i <= b DO
p := messageGrid.model.GetCellData(0, i);
IF (p # NIL) & (p IS IMAPClient.Message) THEN
message := p(IMAPClient.Message);
selection.Add(message);
END;
INC(i);
END;
END;
messageGrid.model.Release;
RETURN selection
END GetMessageSelection;
PROCEDURE CopyMessages(sender, data: ANY);
VAR
list: Classes.List;
i, r: LONGINT;
p: ANY;
message: IMAPClient.Message;
path: String;
BEGIN
IF copyTarget # NIL THEN
list := data(Classes.List);
i := 0;
client.abort := TRUE;
WHILE i < list.GetCount() DO
p := list.GetItem(i);
message := p(IMAPClient.Message);
path := copyTarget.GetPath();
r := client.CopyMessage(message, path);
INC(i);
END;
client.abort := FALSE;
client.timer.Wakeup();
ELSE
OutputError("Copy NOT possible because there is no copy Target selected");
END;
END CopyMessages;
PROCEDURE DeleteMessages(sender, data: ANY);
VAR
list: Classes.List;
i, r: LONGINT;
p: ANY;
message: IMAPClient.Message;
BEGIN
list := data(Classes.List);
IF list # NIL THEN
i := 0;
client.abort := TRUE;
IF DEBUG THEN KernelLog.String("Delete "); KernelLog.Int(list.GetCount(),0); KernelLog.String(" messages."); KernelLog.Ln(); END;
WHILE i < list.GetCount() DO
p := list.GetItem(i);
message := p(IMAPClient.Message);
IF (client.preferences.UseATrashBin) THEN
r := client.MoveMessageToTrashBin(message);
ELSE
r := client.DeleteMessage(message, client.preferences.ExpungeOnDelete);
END;
INC(i);
END;
client.abort := FALSE;
client.timer.Wakeup();
END;
END DeleteMessages;
PROCEDURE RestoreMessages(sender, data: ANY);
VAR
list: Classes.List;
i, r: LONGINT;
p: ANY;
message: IMAPClient.Message;
BEGIN
list := data(Classes.List);
IF list # NIL THEN
i := 0;
client.abort := TRUE;
IF DEBUG THEN KernelLog.String("Restore "); KernelLog.Int(list.GetCount(),0); KernelLog.String(" messages."); KernelLog.Ln(); END;
WHILE i < list.GetCount() DO
p := list.GetItem(i);
message := p(IMAPClient.Message);
r := client.RestoreMessage(message);
INC(i);
END;
client.abort := FALSE;
client.timer.Wakeup();
END;
END RestoreMessages;
PROCEDURE Connect;
VAR user, pass: ARRAY 1000 OF CHAR;
host: String;
r: LONGINT;
BEGIN
IMAPUtilities.TextToStr(address.text, host);
IF (host^ = "") THEN
OutputError("Server not specified");
RETURN;
END;
IMAPUtilities.StringCopy(client.preferences.UserName^, 0, IMAPUtilities.StringLength(client.preferences.UserName^), user);
IF WMDialogs.QueryString("Enter Username:", user) = WMDialogs.ResOk THEN
IF WMDialogs.QueryPassword("Enter Password", pass) = WMDialogs.ResOk THEN
Disconnect();
r := client.Connect(host^, user, pass);
END;
END;
END Connect;
PROCEDURE Disconnect;
BEGIN
client.abort := TRUE;
client.Disconnect();
client.abort := FALSE;
END Disconnect;
PROCEDURE Reload;
BEGIN
client.applySearchFilter := FALSE;
client.userAbort := FALSE;
client.abort := FALSE;
client.timer.Wakeup();
END Reload;
PROCEDURE Abort;
BEGIN
client.userAbort := TRUE;
client.abort := TRUE;
END Abort;
PROCEDURE Search;
VAR
sw: SearchWindow;
BEGIN
IF (client.status # IMAPClient.OK) & (client.status # IMAPClient.OFFLINE) THEN
OutputError("Search not applicable because Client not connected.");
RETURN;
END;
IF client.currentFolder.Noselect THEN
OutputError("Search not applicable because Client not in Selected State.");
RETURN;
END;
NEW(sw, SELF);
END Search;
PROCEDURE Save;
VAR
sw: SaveWindow;
filename: String;
doc: XML.Document;
file: Files.File;
fw: Files.Writer;
r: LONGINT;
BEGIN
IF (client.status # IMAPClient.ONLINE) & (client.status # IMAPClient.OFFLINE) THEN
OutputError("Save is not applicable because you are disconnected");
RETURN;
END;
NEW(sw);
sw.GetAnswer(filename);
IF filename = NIL THEN
RETURN;
END;
r := client.Save(doc);
IF DEBUG THEN KernelLog.String("Save finished"); KernelLog.Ln(); END;
file := Files.New(filename^);
IF file # NIL THEN
Files.OpenWriter(fw, file, 0);
doc.Write(fw, NIL, 0);
fw.Update();
Files.Register(file);
IF DEBUG THEN KernelLog.String("Writing File successful"); KernelLog.Ln(); END;
ELSE
OutputError("Writing File failed");
END;
END Save;
PROCEDURE NewSend;
VAR
mw: MessageWindow;
BEGIN
NEW(mw, SELF);
mw.NewMessage();
END NewSend;
PROCEDURE Expunge;
VAR
r: LONGINT;
BEGIN
IF client.status = IMAPClient.ONLINE THEN
r := WMDialogs.Confirmation("Confirm Expunge", "Do you really want to expunge the deleted Messages?");
IF r = WMDialogs.ResYes THEN
r := client.Expunge();
END;
END;
END Expunge;
PROCEDURE DownloadAllMessages;
BEGIN
IF client.status # IMAPClient.ONLINE THEN
OutputError("The client is not online");
RETURN;
END;
client.abort := FALSE;
client.userAbort := FALSE;
client.Task := IMAPClient.TLoadAllMessages;
client.timer.Wakeup();
END DownloadAllMessages;
PROCEDURE SwitchToOffline;
BEGIN
client.SwitchToOffline();
END SwitchToOffline;
PROCEDURE SwitchToOnline;
VAR
pass: ARRAY 1000 OF CHAR;
BEGIN
IF DEBUG THEN KernelLog.String("GUI: switch to online"); KernelLog.Ln(); END;
IF WMDialogs.QueryPassword("Enter Password", pass) = WMDialogs.ResOk THEN
client.SwitchToOnline(pass);
END;
END SwitchToOnline;
PROCEDURE Load;
VAR
lw: LoadWindow;
filename: String;
offline: BOOLEAN;
file: Files.File;
fr: Files.Reader;
string: String;
r: LONGINT;
scanner: XMLScanner.Scanner;
parser: XMLParser.Parser;
document: XML.Document;
element: XML.Element;
server, user: String;
pass: ARRAY 1000 OF CHAR;
BEGIN
NEW(lw);
lw.GetAnswer(filename, offline);
IF filename # NIL THEN
IF DEBUG THEN KernelLog.String("start loading"); KernelLog.Ln(); END;
Disconnect();
file := Files.Old(filename^);
IF file # NIL THEN
IF DEBUG THEN KernelLog.String("start scanning and parsing..."); KernelLog.Ln(); END;
Files.OpenReader(fr, file, 0);
NEW(scanner, fr);
NEW(parser, scanner);
document := parser.Parse();
element := document.GetRoot();
string := element.GetName();
IF string^ # "account" THEN
OutputError("The file is not compatible it doesn't start with the account tag");
RETURN;
END;
IF offline THEN
Disconnect();
r := client.Load(document);
RefreshDisplay();
ELSE
IF WMDialogs.QueryPassword("Enter Password", pass) = WMDialogs.ResOk THEN
Disconnect();
r := client.Load(document);
IF r = IMAPClient.OK THEN
server := client.preferences.IMAPServer;
user := client.preferences.UserName;
r := client.Connect(server^, user^, pass);
IF DEBUG THEN KernelLog.String("CONNECT RETURN = "); KernelLog.Int(r,0); KernelLog.Ln(); END;
IMAPUtilities.SetEditorText(address, server);
END;
RefreshDisplay();
END;
END;
ELSE
OutputError("Reading the file failed.");
END;
END;
END Load;
PROCEDURE SetPreferences;
VAR
pw: PreferencesWindow;
BEGIN
NEW(pw, SELF);
END SetPreferences;
PROCEDURE Handle(VAR x: WMMessages.Message);
BEGIN
IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) THEN
IF(x.ext IS KillerMsg) THEN
Close();
ELSIF (x.ext IS WMRestorable.Storage) THEN
x.ext(WMRestorable.Storage).Add("Window", "IMAPGUI.Restore", SELF, NIL);
ELSE
Handle^(x);
END;
ELSE
Handle^(x);
END;
END Handle;
PROCEDURE Close;
BEGIN
client.abort := TRUE;
client.Close();
active := FALSE;
timer.Wakeup();
Close^;
DecCount();
END Close;
PROCEDURE DisplayCurrentFolder;
BEGIN
UpdateFolders();
UpdateMessages();
UpdateStatusLabels();
END DisplayCurrentFolder;
PROCEDURE UpdateStatusLabels;
VAR
status, currentWork, nofMessages: LONGINT;
buffer: Strings.Buffer;
w: Streams.Writer;
string: String;
BEGIN
NEW(buffer, 16);
w := buffer.GetWriter();
w.String("Current Folder: ");
IF IMAPUtilities.StringLength(client.currentFolder.path^) # 0 THEN
w.String(client.currentFolder.path^);
w.Char(client.currentFolder.hierarchyDelimiter);
END;
w.String(client.currentFolder.name^);
string := buffer.GetString();
currentFolderLabel.caption.SetAOC(string^);
NEW(buffer, 16);
w := buffer.GetWriter();
w.String("Current Messages: ");
messageGrid.model.Acquire;
nofMessages := messageGrid.model.GetNofRows() - 1;
IF client.currentFolder.Noselect THEN
nofMessages := 0;
END;
w.Int(nofMessages, 0);
messageGrid.model.Release;
string := buffer.GetString();
currentMessagesLabel.caption.SetAOC(string^);
status := client.status;
currentWork := client.currentWork;
NEW(buffer, 16);
w := buffer.GetWriter();
w.String("Status: ");
IF client.status = IMAPClient.ONLINE THEN
w.String("online. ");
ELSIF client.status = IMAPClient.OFFLINE THEN
w.String("offline. ");
ELSE
w.String("disconnected. ");
END;
IF (status = IMAPClient.ONLINE) OR (status = IMAPClient.OFFLINE) THEN
w.String("Current Work: ");
IF currentWork = IMAPClient.CWFINISHED THEN
w.String("Finished");
ELSIF currentWork = IMAPClient.CWCONNECTING THEN
w.String("Connecting...");
ELSIF currentWork = IMAPClient.CWLOADING THEN
w.String("Loading...");
ELSIF currentWork = IMAPClient.CWCREATING THEN
w.String("Creating Mailbox...");
ELSIF currentWork = IMAPClient.CWRENAMING THEN
w.String("Renaming Mailbox...");
ELSIF currentWork = IMAPClient.CWDELETINGFOLDER THEN
w.String("Deleting Mailbox...");
ELSIF currentWork = IMAPClient.CWSEARCHING THEN
w.String("Searching...");
ELSIF currentWork = IMAPClient.CWCOPYING THEN
w.String("Copying Message...");
ELSIF currentWork = IMAPClient.CWDELETINGMESSAGE THEN
w.String("Deleting Message...");
ELSIF currentWork = IMAPClient.CWAPPENDING THEN
w.String("Saving Message...");
ELSIF currentWork = IMAPClient.CWCLOSING THEN
w.String("Closing Client...");
ELSIF currentWork = IMAPClient.CWSAVINGACCOUNT THEN
w.String("Saving Account...");
ELSIF currentWork = IMAPClient.CWLOADINGACCOUNT THEN
w.String("Loading Account...");
ELSIF currentWork = IMAPClient.CWPOLLING THEN
w.String("Polling...");
ELSIF currentWork = IMAPClient.CWEXPUNGING THEN
w.String("Expunging...");
ELSIF currentWork = IMAPClient.CWRESTORING THEN
w.String("Restoring...");
END;
END;
string := buffer.GetString();
statusLabel.caption.SetAOC(string^);
END UpdateStatusLabels;
PROCEDURE UpdateFolders;
VAR
root: WMTrees.TreeNode;
i: LONGINT;
p: ANY;
folder: IMAPClient.Folder;
state: SET;
PROCEDURE UpdateSub(parent: WMTrees.TreeNode; folder:IMAPClient.Folder);
VAR
node, child: WMTrees.TreeNode;
i: LONGINT;
sub: ANY;
subFolder: IMAPClient.Folder;
childData: ANY;
childFolder: IMAPClient.Folder;
present: BOOLEAN;
name: String;
BEGIN
present := FALSE;
child := tree.GetChildren(parent);
WHILE (child # NIL) & (present = FALSE) DO
childData := tree.GetNodeData(child);
childFolder := childData(IMAPClient.Folder);
IF childFolder = folder THEN
present := TRUE;
node := child;
END;
child := tree.GetNextSibling(child);
END;
IF present = FALSE THEN
NEW(node);
tree.AddChildNode(parent, node);
name := IMAPUtilities.NewString(folder.name^);
IMAPUtilities.replaceEncodedFolderName(name);
tree.SetNodeCaption(node, name);
tree.SetNodeData(node, folder);
END;
i := 0;
WHILE i < folder.children.GetCount() DO
sub := folder.children.GetItem(i);
subFolder := sub(IMAPClient.Folder);
UpdateSub(node, subFolder);
INC(i);
END;
RemoveOldSubNodes(node);
END UpdateSub;
PROCEDURE RemoveOldSubNodes(node: WMTrees.TreeNode);
VAR
child, nextSibling: WMTrees.TreeNode;
childFolder: IMAPClient.Folder;
p: ANY;
folder: IMAPClient.Folder;
subFolders: Classes.List;
subFolder: IMAPClient.Folder;
i: LONGINT;
found: BOOLEAN;
BEGIN
p := tree.GetNodeData(node);
folder := p(IMAPClient.Folder);
subFolders:= folder.children;
child := tree.GetChildren(node);
WHILE child # NIL DO
p := tree.GetNodeData(child);
childFolder := p(IMAPClient.Folder);
found := FALSE;
i := 0;
WHILE (i < subFolders.GetCount()) & ~found DO
p := subFolders.GetItem(i);
subFolder := p(IMAPClient.Folder);
IF subFolder = childFolder THEN
found := TRUE;
END;
INC(i);
END;
nextSibling := tree.GetNextSibling(child);
IF ~found THEN
tree.RemoveNode(child);
END;
child := nextSibling;
END;
END RemoveOldSubNodes;
BEGIN
tree.Acquire();
root := tree.GetRoot();
tree.SetNodeData(root, client.mailboxContent);
state := {WMTrees.NodeAlwaysExpanded};
tree.SetNodeState(root, state);
i := 0;
WHILE i < client.mailboxContent.children.GetCount() DO
p := client.mailboxContent.children.GetItem(i);
folder := p(IMAPClient.Folder);
UpdateSub(root, folder);
INC(i);
END;
RemoveOldSubNodes(root);
tree.Release();
END UpdateFolders;
PROCEDURE UpdateMessages;
VAR
i, count: LONGINT;
message: IMAPClient.Message;
messageP: ANY;
header: IMAPClient.HeaderElement;
list: Classes.List;
address: IMAPUtilities.Address;
addressP: ANY;
buffer: Strings.Buffer;
w: Streams.Writer;
string: String;
bResizeGrid: BOOLEAN;
sortedList: Classes.SortedList;
PROCEDURE Display(row: LONGINT; message: IMAPClient.Message);
BEGIN
IF message.header # NIL THEN
list := message.header.from;
IF list # NIL THEN
IF list.GetCount() > 0 THEN
addressP := list.GetItem(0);
address := addressP(IMAPUtilities.Address);
IF address.realName^ # "" THEN
IMAPUtilities.replaceEncodedHeaderWord(address.realName^);
string := IMAPUtilities.NewString(address.realName^);
ELSE
NEW(buffer, 16);
w := buffer.GetWriter();
w.String("<");
w.String(address.namePart^);
w.String("@");
w.String(address.domainPart^);
w.String(">");
string := buffer.GetString();
END;
ELSE
string := Strings.NewString("");
END;
ELSE
string := Strings.NewString("");
END;
messageGrid.model.SetCellText(0, row+1, string);
IF message.flags.deleted THEN
messageGrid.model.SetCellImage(0, row+1, IconDeleted);
ELSE
IF ~message.flags.seen THEN
messageGrid.model.SetCellImage(0, row+1, IconUnread);
ELSE
IF message.flags.answered THEN
messageGrid.model.SetCellImage(0, row+1, IconAnswered);
ELSE
messageGrid.model.SetCellImage(0, row+1, IconRead);
END;
END;
END;
messageGrid.model.SetCellData(0, row+1, message);
IF message.header.subject # NIL THEN
IMAPUtilities.replaceEncodedHeaderWord(message.header.subject^);
string := Strings.NewString(message.header.subject^);
messageGrid.model.SetCellText(1, row+1, string);
messageGrid.model.SetCellData(1, row+1, message);
END;
IF message.internalDate # NIL THEN
messageGrid.model.SetCellText(2, row+1, Strings.NewString(message.internalDate^));
messageGrid.model.SetCellData(2, row+1, message);
END;
NEW(buffer, 16);
w := buffer.GetWriter();
w.Int(message.size,0);
string := buffer.GetString();
messageGrid.model.SetCellText(3, row+1, string);
messageGrid.model.SetCellData(3, row+1, message);
END;
END Display;
BEGIN
bResizeGrid := FALSE;
IF client.currentFolder.Noselect THEN
messageGrid.model.Acquire;
IF messageGrid.model.GetNofCols() # 1 THEN
bResizeGrid := TRUE;
NEW(colWidths, 1);
messageGrid.model.SetNofRows(2);
messageGrid.model.SetNofCols(1);
messageGrid.model.SetCellText(0, 0, Strings.NewString(""));
messageGrid.model.SetCellData(0, 0, NIL);
messageGrid.model.SetCellImage(0, 1, NIL);
messageGrid.model.SetCellText(0, 1, Strings.NewString("This Mailbox is not selectable and does not contain any mail."));
messageGrid.model.SetCellData(0, 1, NIL);
END;
messageGrid.model.Release;
ELSE
messageGrid.model.Acquire;
IF messageGrid.model.GetNofCols() # 4 THEN
bResizeGrid := TRUE;
NEW(colWidths, 4);
messageGrid.model.SetNofCols(4);
messageGrid.model.SetNofRows(1);
messageGrid.model.SetCellText(0, 0, Strings.NewString("From"));
messageGrid.model.SetCellData(0, 0, NIL);
messageGrid.model.SetCellText(1, 0, Strings.NewString("Subject"));
messageGrid.model.SetCellData(1, 0, NIL);
messageGrid.model.SetCellText(2, 0, Strings.NewString("Date"));
messageGrid.model.SetCellData(2, 0, NIL);
messageGrid.model.SetCellText(3, 0, Strings.NewString("Size"));
messageGrid.model.SetCellData(3, 0, NIL);
messageGrid.bounds.SetHeight(messageGrid.bounds.GetHeight()-20);
END;
messageGrid.model.Release;
NEW(sortedList, IMAPClient.OldestFirst);
IF client.applySearchFilter = TRUE THEN
i := LEN(client.searchResult) -1;
WHILE i >= 0 DO
messageP := client.currentFolder.messages.GetItem(client.searchResult[i]);
message := messageP(IMAPClient.Message);
sortedList.Add(message);
DEC(i);
END;
ELSE
i := client.currentFolder.messages.GetCount() - 1;
WHILE i >= 0 DO
messageP := client.currentFolder.messages.GetItem(i);
message := messageP(IMAPClient.Message);
sortedList.Add(message);
DEC(i);
END;
END;
i := 0;
count := 0;
messageGrid.model.Acquire;
IF sortedList.GetCount() = 0 THEN
bResizeGrid := TRUE;
messageGrid.model.SetNofRows(1);
IF DEBUG THEN KernelLog.String("keine Nachrichten"); KernelLog.Ln(); END;
END;
WHILE i < sortedList.GetCount() DO
messageP := sortedList.GetItem(i);
message := messageP(IMAPClient.Message);
header := message.header;
IF (header # NIL) THEN
messageGrid.model.SetNofRows(count + 2);
Display(count, message);
INC(count);
END;
INC(i);
END;
messageGrid.model.Release;
END;
IF bResizeGrid THEN ResizeGrid(); END;
END UpdateMessages;
PROCEDURE RefreshDisplay;
BEGIN
updateFlag := TRUE;
timer.Wakeup();
END RefreshDisplay;
BEGIN {ACTIVE} (* keepalive *)
NEW(timer);
WHILE active DO
timer.Sleep(REFRESHTIME);
IF DEBUG THEN KernelLog.String("+"); END;
IF (client.status = IMAPClient.DISCONNECTED) OR (client.status = IMAPClient.DEAD) THEN
UpdateFolders();
messageGrid.model.Acquire;
NEW(colWidths, 1);
colWidths[0] := messageGrid.bounds.GetWidth();
messageGrid.SetColSpacings(colWidths);
messageGrid.model.SetNofRows(1);
messageGrid.model.SetNofCols(1);
messageGrid.model.SetCellText(0, 0, Strings.NewString(""));
messageGrid.model.Release;
UpdateStatusLabels();
ELSE
WHILE updateFlag DO
IF DEBUG THEN KernelLog.Ln(); END;
updateFlag := FALSE;
DisplayCurrentFolder();
END;
END;
END (* WHILE *);
IF DEBUG THEN KernelLog.String("Window Activity finished-------------------------------------------------------------------"); KernelLog.Ln(); END;
END Window;
PROCEDURE OutputError(CONST error: ARRAY OF CHAR);
BEGIN
WMDialogs.Error(WindowTitle, error);
END OutputError;
PROCEDURE Open*;
VAR w: Window;
BEGIN
NEW(w, NIL);
END Open;
PROCEDURE Restore*(context : WMRestorable.Context);
VAR w : Window;
BEGIN
NEW(w, context);
END Restore;
PROCEDURE IncCount;
BEGIN {EXCLUSIVE}
INC(nofWindows);
END IncCount;
PROCEDURE DecCount;
BEGIN {EXCLUSIVE}
DEC(nofWindows);
END DecCount;
PROCEDURE Cleanup;
VAR
die: KillerMsg;
msg: WMMessages.Message;
m: WMWindowManager.WindowManager;
BEGIN {EXCLUSIVE}
NEW(die);
msg.ext := die;
msg.msgType := WMMessages.MsgExt;
m := WMWindowManager.GetDefaultManager();
m.Broadcast(msg);
AWAIT(nofWindows = 0);
END Cleanup;
BEGIN
Modules.InstallTermHandler(Cleanup);
END IMAPGUI.
IMAPGUI.Open ~
AosTools.FreeDownTo IMAPUtilities~