ACC SHELL
/**
* File:
* include/mail/ui.ycp
*
* Package:
* Configuration of mail
*
* Summary:
* User interface functions.
*
* Authors:
* Martin Vidner <mvidner@suse.cz>
*
* $Id: ui.ycp 61601 2010-04-07 12:52:02Z varkoly $
*
* All user interface functions.
*
*/
{
textdomain "mail";
import "Wizard";
import "Progress";
import "Mode";
import "Mail";
import "MailAliases";
import "Hostname";
import "CWMFirewallInterfaces";
import "Popup";
import "Label";
import "Sequencer";
import "Package";
include "mail/helps.ycp";
include "mail/wj.ycp";
/**
* Read settings dialog
* @return `abort or `next
*/
define symbol ReadDialog () ``{
Wizard::SetScreenShotName ("mail-0-read");
// Set help text
Wizard::RestoreHelp (ReadDialogHelp ());
// A callback function for abort
block<boolean> callback = ``{
return UI::PollInput () == `abort;
};
// Read the configuration
boolean was_ok = true;
if (Mode::screen_shot())
{
Mail::Fake ();
// make it possible to snap this dialog
sleep (3000);
UI::PollInput ();
}
else
{
was_ok = Mail::Read ( callback );
}
// TODO FIXME possibly handle the abort
if (was_ok)
{
if (! Mail::CreateConfig ())
{
string setting = "MAIL_CREATE_CONFIG";
// Translators: continue/cancel dialog
// %1 is a sysconfig variable name
was_ok = Popup::ContinueCancel (sformat (_("The setting %1 is turned off. You have
probably modified the configuration files directly.
If you continue, it will be turned on and
SuSEconfig will overwrite manual changes.
"), setting));
}
}
else
{
if (Mail::mta == `other)
{
// After text freeze, but
// a) either something is very broken -> user must know
// b) user installed a different MTA -> knowledgeable enough to
// ba) never see this message anyway
// bb) read English
// TODO: look at exim and mention it in the popup
// Translators: error popup
Popup::Error (_("YaST can only configure Postfix and Sendmail,
but neither of them is installed."));
}
}
Wizard::RestoreScreenShotName ();
return ( was_ok? `next : `abort );
}
/**
* Confirmation dialog before saving and installing needed packages
* @return `back or `next
*/
define symbol ConfirmDialog () ``{
// not to be displayed, #37554.
// but ProbePackages still has to be called.
// continue-cancel popup
string message1 = _("The configuration will be written now.\n");
string message2 = Mail::ProbePackages ();
// return Popup::ContinueCancel (message1 + message2) ? `next : `back;
return `next;
}
/**
* Write settings dialog
* @return `abort or `next
*/
define symbol WriteDialog () ``{
if (Mode::screen_shot())
{
y2milestone ("Screenshot mode - skipping Write");
return `next;
}
// Install packages if needed.
// Cannot do it in Write, autoinstall does it differently.
if (size (Mail::install_packages) > 0 || size (Mail::remove_packages) > 0)
{
Package::DoInstallAndRemove (Mail::install_packages, Mail::remove_packages);
}
// Set help text
Wizard::RestoreHelp (WriteDialogHelp ());
// A callback function for abort
block<boolean> callback = ``{
return UI::PollInput () == `abort;
};
// Read the configuration
boolean was_ok = Mail::Write ( callback);
// TODO FIXME possibly handle the abort
return ( was_ok? `next : `abort );
}
/**
* MTA selection dialog
* (only for autoinstallation, otherwise probed in Mail::Read)
* @return `abort or `next
*/
define symbol MtaSelectionDialog () ``{
Wizard::SetScreenShotName ("mail-0-mta");
symbol mta = Mail::mta;
// for now. TODO: disable Next if none selected
if (mta != `sendmail && mta != `postfix)
{
mta = `postfix;
}
// Translators: dialog caption
// Mailer: Sendmail or Postfix
string caption = _("Mail transfer agent");
term contents =
`Frame (
// Translators: frame label
// Mailer: Sendmail or Postfix
_("Mail transfer agent"),
`RadioButtonGroup (
`id (`mtag),
`HSquash (
`VBox (
`HSpacing (23), // qt bug workaround, #23979
`VSpacing (0.2),
// MTA name does not need translation
`Left (`RadioButton (`id (`sendmail), `opt(`autoShortcut), "Sendmail", mta == `sendmail)),
// MTA name does not need translation
`Left (`RadioButton (`id (`postfix), `opt(`autoShortcut), "Postfix", mta == `postfix)),
`VSpacing (0.2)
)
)
)
);
Wizard::SetContentsButtons (caption, contents, MtaSelectionDialogHelp (), Label::BackButton (), Label::NextButton ());
any ret = nil;
while (true)
{
ret = UI::UserInput ();
if (ret == `cancel)
{
ret = `abort;
}
if (ret == `back || ret == `next ||
(ret == `abort && Popup::ReallyAbort (Mail::touched)))
{
break;
}
}
if (ret == `next)
{
mta = (symbol) UI::QueryWidget (`id (`mtag), `CurrentButton);
Mail::Touch (Mail::mta != mta);
Mail::mta = mta;
}
Wizard::RestoreScreenShotName ();
return (symbol) ret;
}
/**
* A command line argument can override what is read from SCR.
* Used when starting mail from lan/modem.
*/
symbol preselect_connection_type = nil;
/**
* D1
* @return `back, `abort, `next or `none
*/
define symbol ConnectionTypeDialog () ``{
Wizard::SetScreenShotName ("mail-1-conntype");
list widgets = [];
symbol ct = Mail::connection_type;
if (preselect_connection_type != nil)
{
ct = preselect_connection_type;
}
// Translators: dialog caption
string caption = _("General Settings");
term contents =
`Frame (
// Translators: frame label
_("Connection type"),
RadioButtonVBox (
`ctg,
[
// Translators: radio button label
`RadioButton (`id (`permanent), `opt (`notify), _("&Permanent"), ct == `permanent),
// Translators: radio button label
`RadioButton (`id (`dialup), `opt (`notify), _("&Dial-up"), ct == `dialup),
// Translators: radio button label
`RadioButton (`id (`none), `opt (`notify), _("No &connection"), ct == `none),
// Translators: radio button label
`RadioButton (`id (`nodaemon), `opt (`notify), _("Do not start Postfix as Daemon"), ct == `nodaemon),
]
)
);
boolean amavis_allowed = Mail::amavis_allowed;
term amavis_t = nil;
if (amavis_allowed)
{
amavis_t = `Left (WJ_MakeWidget (`use_amavis));
widgets = add (widgets, `use_amavis);
}
else
{
amavis_t = `Empty (`id (`use_amavis));
}
contents = `HSquash (
`VBox (
contents,
`VSpacing (1),
amavis_t
)
);
Wizard::SetContentsButtons (caption, contents,
WJ_MakeHelp (
prepend (widgets,
ConnectionTypeDialogHelp ())),
Label::BackButton (), Label::NextButton ());
any ret = nil;
while (true)
{
ct = (symbol) UI::QueryWidget (`id (`ctg), `CurrentButton);
if (ct == `permanent || ct == `dialup)
{
UI::ChangeWidget (`id (`use_amavis), `Enabled, true);
Wizard::RestoreNextButton();
//argh, slow
//Wizard::RestoreNextButton ();
}
else if (ct == `nodaemon)
{
UI::ChangeWidget (`id (`use_amavis), `Value, false);
UI::ChangeWidget (`id (`use_amavis), `Enabled, false);
}
else if (ct == `none)
{
UI::ChangeWidget (`id (`use_amavis), `Value, false);
UI::ChangeWidget (`id (`use_amavis), `Enabled, false);
Wizard::SetNextButton(`next, Label::FinishButton() );
}
ret = UI::UserInput ();
if (ret == `cancel)
{
ret = `abort;
}
if (ret == `back ||
(ret == `abort && Popup::ReallyAbort (Mail::touched)))
{
break;
}
else if (ret == `next)
{
if (WJ_Validate (widgets))
{
break;
}
}
}
if (ret == `next)
{
WJ_Set (widgets);
ct = (symbol) UI::QueryWidget (`id (`ctg), `CurrentButton);
Mail::Touch (Mail::connection_type != ct);
Mail::connection_type = ct;
ret = (ct == `none)? `none: ret;
}
// avoid overriding the choice the user has made
preselect_connection_type = nil;
Wizard::RestoreScreenShotName ();
return (symbol) ret;
}
/**
* D2
* @return `back, `abort, `next or `outgoing_details
*/
define symbol OutgoingDialog () ``{
Wizard::SetScreenShotName ("mail-21-outgoing");
boolean TLSnone = ( Mail::smtp_use_TLS == "no" );
boolean TLSuse = ( Mail::smtp_use_TLS == "yes" );
boolean TLSmust = ( Mail::smtp_use_TLS == "must" );
// what buttons can be used to leave this dialog
//(except the std wizarding ones)
list<symbol> buttons = [];
list<symbol> widgets = [
`outgoing_mail_server,
];
// Translators: dialog caption
string caption = _("Outgoing Mail");
term o_contents =
`VSquash (
`VBox (
WJ_MakeWidget (`outgoing_mail_server),
// TLS
`Label (_("The server use &TLS")),
`RadioButtonGroup(`id(`TLS),
`HBox(
`Left(`RadioButton(`id("no"), _("No"), TLSnone)),
`Left(`RadioButton(`id("yes"), _("Use"), TLSuse)),
`Left(`RadioButton(`id("must"), _("Enforce"),TLSmust))
)
),
// Translators: button
// TODO ...
`PushButton (`id(`outgoing_details), _("&Masquerading")),
// Translators: button
// TODO ...
`PushButton (`id(`outgoing_auth_opts), _("&Authentication"))
)
);
buttons = add (buttons, `outgoing_details);
buttons = add (buttons, `outgoing_auth_opts);
// frame label
term o_frame = `Frame (_("Outgoing Mail"), o_contents);
term contents = `HSquash ( `VBox (
`VStretch (),
o_frame,
`VStretch ()
));
string help = ""; //TODO
Wizard::SetContentsButtons (
caption, contents, WJ_MakeHelp (widgets),
Label::BackButton (),
Label::NextButton ());
symbol ret = nil;
while (true)
{
ret = (symbol) UI::UserInput ();
if (ret == `cancel)
{
ret = `abort;
}
if (ret == `back ||
(ret == `abort && Popup::ReallyAbort (Mail::touched)))
{
break;
}
else if (ret == `next || contains (buttons, ret))
{
// input validation
// For consistency, all querywidgets are done here
if (WJ_Validate (widgets))
{
// all checks OK, break the input loop
break;
}
}
}
if (ret == `next || contains (buttons, ret))
{
Mail::smtp_use_TLS = (string)UI::QueryWidget (`id (`TLS), `Value);
WJ_Set (widgets);
}
Wizard::RestoreScreenShotName ();
return (symbol) ret;
}
/**
* D2
* @return `back, `abort, `next or `outgoing_details
*/
define symbol IncomingDialog () ``{
Wizard::SetScreenShotName ("mail-22-incoming");
list<any> buttons = [];
// watch out, fm_widgets are not part of widgets
// because of special validation requirements
list<symbol> widgets = [
`listen_remote,
];
// firewall widget using CWM
map<string, any> fw_settings = $[
"services": [ "smtp" ],
"display_details": true,
];
map<string,any> fw_cwm_widget = CWMFirewallInterfaces::CreateOpenFirewallWidget (fw_settings);
// Translators: dialog caption
string caption = _("Incoming Mail");
term i_contents = `VBox ();
i_contents = add (i_contents, `Left (WJ_MakeWidget (`listen_remote)));
i_contents = add (i_contents, fw_cwm_widget["custom_widget"]:`Empty ());
list<symbol> fm_widgets = [];
if (true) // always embed the first account
{
// Edit the first fetchmail item here.
// Copy it into the edit buffer.
fetchmail_item = Mail::fetchmail[0]:$[];
fm_widgets = [
`fm_server,
`fm_protocol,
`fm_remote_user,
`fm_password,
`fm_local_user,
];
term fm_contents = `VBox (
`HSpacing (40), // prevent fm_password being squashed in curses
`HBox (
WJ_MakeWidget (`fm_server),
`HSpacing (1),
WJ_MakeWidget (`fm_protocol)
),
`HBox (
WJ_MakeWidget (`fm_remote_user),
`HSpacing (1),
WJ_MakeWidget (`fm_password)
),
`HBox (
`Bottom (WJ_MakeWidget (`fm_local_user)),
`HSpacing (1),
// pushbutton
`Bottom (`PushButton (`id (`downloading), `opt (`key_F7), _("&Details...")))
),
`HBox (
`Left(`ComboBox (`id (`fm_start),_("Start &fetchmail"),["manual","daemon"]))
)
);
// frame label: mail downloading (fetchmail)
term fm_frame = `Frame (_("&Downloading"), fm_contents);
i_contents = add (i_contents,
`HBox (
`HSpacing (1),
fm_frame,
`HSpacing (1)
)
);
}
i_contents = add (i_contents, WJ_MakeWidget (`root_alias));
widgets = add (widgets, `root_alias);
if (Mail::mta == `postfix)
{
i_contents = add (i_contents, WJ_MakeWidget (`delivery_mode));
widgets = add (widgets, `delivery_mode);
}
i_contents = add (
i_contents,
// menu button: details of incoming mail
`HBox (
// pushbutton
`PushButton (`id (`aliases), _("&Aliases...")),
// pushbutton
`PushButton (`id (`virtual), _("&Virtual domains..."))
)
);
buttons = flatten ([buttons, [`downloading, `aliases, `virtual]]);
// frame label
// term i_frame = `Frame (_("Incoming Mail"), i_contents);
term contents = `HSquash ( `VBox (
`VStretch (),
i_contents,
`VStretch ()
));
string help = ""; //TODO
Wizard::SetContentsButtons (
caption, contents, WJ_MakeHelp (widgets) + fw_cwm_widget["help"]:"",
Label::BackButton (),
Label::FinishButton ());
// set combo boxes to proper values
WJ_GetWidget (`fm_protocol);
WJ_GetWidget (`fm_local_user);
WJ_GetWidget (`delivery_mode);
// initialize the widget (set the current value)
CWMFirewallInterfaces::OpenFirewallInit (fw_cwm_widget, "");
UI::ChangeWidget(`id(`fm_start),`Value, Mail::fetchmail_mode);
// nothing entered in the dowloading items - don't save them
boolean fm_empty = true;
map event = nil;
any ret = nil;
while (true)
{
event = UI::WaitForEvent ();
ret = event["ID"]:nil;
if (ret == `cancel)
{
ret = `abort;
}
// handle the events, enable/disable the button, show the popup if button clicked
CWMFirewallInterfaces::OpenFirewallHandle (fw_cwm_widget, "", event);
if (ret == `back ||
(ret == `abort && Popup::ReallyAbort (Mail::touched)))
{
break;
}
else if (ret == `next || contains (buttons, ret))
{
Mail::fetchmail_mode = (string) UI::QueryWidget(`id (`fm_start), `Value);
// input validation
// For consistency, all querywidgets are done here
if (WJ_Validate (widgets))
{
fm_empty =
UI::QueryWidget(`id (`fm_server), `Value) == "" &&
UI::QueryWidget(`id (`fm_remote_user), `Value) == "" &&
UI::QueryWidget(`id (`fm_password), `Value) == "" &&
UI::QueryWidget(`id (`fm_local_user), `Value) == "";
if (fm_empty || WJ_Validate (fm_widgets))
{
// all checks OK, break the input loop
break;
}
}
}
}
if (ret == `next || contains (buttons, ret))
{
WJ_Set (widgets);
// grab current settings, store them to SuSEFirewall::
CWMFirewallInterfaces::OpenFirewallStore (fw_cwm_widget, "", event);
if (!fm_empty)
{
WJ_Set (fm_widgets);
// CHECK: aliasing is not harmful here
Mail::fetchmail[0] = fetchmail_item;
// -------------- fix of bug #29919:
// -------------- propose local domains when fetchmail is used:
if (Mail::fetchmail != [] && Mail::local_domains == [] &&
Mail::mta == `postfix)
{
list<string> ld = [ "\\$myhostname",
"localhost.\\$mydomain",
"\\$mydomain" ];
// popup text
// %1: variable name (eg. POSTFIX_LOCALDOMAINS)
// %2: file name (eg. /etc/sysconfig/postfix)
// %3: value (about 50 characters)
if (Popup::YesNo (sformat (_("To be able to deliver mail to your local MTA,
the value of %1 in %2 will be set to
\"%3\"."), "POSTFIX_LOCALDOMAINS", "/etc/sysconfig/postfix", mergestring (ld, ", "))))
{
Mail::local_domains = ld;
}
}
}
}
Wizard::RestoreScreenShotName ();
return (symbol) ret;
}
/**
* (taken from y2c_users ui.ycp)
* @param username a string
* @return Whether a string contains only valid user name characters
*/
define boolean check_username (string username) ``{
//DUH, auth_dialogs.ycp, users.ycp and Users.ycp have conflicing definitions!
string valid_logname_chars = "0123456789abcdefghijklmnopqrstuvwxyz-_";
string firstchar = substring (username, 0, 1);
return username != "" &&
( (firstchar >= "a" && firstchar <= "z" ) || firstchar == "_" ) &&
findfirstnotof (username, valid_logname_chars) == nil;
}
/**
* (taken from y2c_users ui.ycp)
* @return Describe a valid username
*/
define string valid_username () ``{
// There is a check whether the information from the UI is
// correct and complete. The login name may contain only
// certain characters and must begin with a letter.
// Already in Translation Memory
return _("The user login may contain only
lower case letters, digits, \"-\" and \"_\"
and must begin with a letter or \"_\".
Please try again.
");
}
/**
* See RFC 2822, 3.4
* But for now, no-spaces@valid_domainname
* @param address an address to check
* @return valid?
*/
define boolean check_mail_address (string address) ``{
list<string> parts = splitstring (address, "@");
if (size (parts) != 2)
{
return false;
}
return check_mail_local_part (parts[0]:"")
&& Hostname::CheckDomain (parts[1]:"");
}
/**
* D2.1.1
* Used for adding and editing a user masquerading entry.
* @param defaultv $["user": "address":] or just $[]
* @param existing current masqueading list
* @return $["comment": "", "user": "address":] or $[] on cancel
*/
define map MasqueradeUserPopup (map defaultv, list<map> existing) ``{
string user = defaultv["user"]:"";
string address = defaultv["address"]:"";
list<string> forbidden = maplist (map e, existing, ``( e["user"]:"" ));
term contents =
`HBox(
`HSpacing(1),
`VBox(
`VSpacing(0.2),
// Translators: popup dialog heading
`Heading (_("Sender address rewriting")),
Mode::config () ?
// Translators: text entry label
`Left (`TextEntry (`id (`user), _("&Local user"), user)) :
`Left (`ComboBox (`id (`user), `opt (`editable, `hstretch), _("&Local user"), GetLocalUsers ())),
// Translators: text entry label
`Left (`TextEntry (`id (`address), _("&Display as"), address)),
`VSpacing(0.2),
`HBox(`PushButton(`id(`ok), `opt(`default, `key_F10), Label::OKButton()),
`PushButton(`id(`cancel), `opt (`key_F9), Label::CancelButton())),
`VSpacing(0.2)
),
`HSpacing(1)
);
UI::OpenDialog (`opt(`decorated), contents);
UI::ChangeWidget (`id (`user), `Value, user);
UI::SetFocus (`id (`user));
any ret = nil;
while (true)
{
ret = UI::UserInput ();
if (ret == `cancel)
{
break;
}
else if (ret == `ok)
{
// Input validation
user = (string) UI::QueryWidget (`id (`user), `Value);
address = (string) UI::QueryWidget (`id (`address), `Value);
if (!check_username (user))
{
UI::SetFocus (`id (`user));
Popup::Error (valid_username ());
}
else if (contains (forbidden, user))
{
UI::SetFocus (`id (`user));
// Translators: error message
Popup::Error (_("The address for this user is already defined."));
}
else if (!check_mail_address (address))
{
// string valid_mail_address
// no-spaces@valid_domainname
UI::SetFocus (`id (`address));
// error popup
Popup::Error (_("The mail address format is incorrect."));
}
else
{
// all checks OK, break the input loop
break;
}
}
}
UI::CloseDialog ();
return (ret == `ok)? $["comment": "", "user": user, "address": address] : $[];
}
/**
* D2.1
* @return `back, `abort or `next
*/
define symbol OutgoingDetailsDialog () ``{
Wizard::SetScreenShotName ("mail-2o-outgoing-details");
string mod = listToString (Mail::masquerade_other_domains);
list<string> lmod = [];
list<map> mu = Mail::masquerade_users;
// Translators: dialog caption
string caption = _("Masquerading");
term contents =
`VBox (
`VSpacing (0.2),
`RadioButtonGroup (
`id (`mdg),
`VBox (
`VSpacing (0.2),
WJ_MakeWidget (`from_header),
`VSpacing (0.2),
WJ_MakeWidget (`local_domains),
`VSpacing (0.2),
`Left (`RadioButton (
`id (`masqlocal),
// Translators: radio button label
_("Masquerade &local domains"),
mod == "")),
// `HBox (
// `HSpacing (2),
// `TextEntry (`id (`masqdomains), `opt (`disabled), _("That is"), ld)
//// `Left (`Label (`opt (`outputField, `hstretch), ld))
// ),
// Translators: radio button label
`Left (`RadioButton (`id (`masqothers), _("Ma&squerade other domains"), mod != "")),
`HBox (
`HSpacing (2),
// Translators: text entry label
`TextEntry (`id (`masqdomains), `opt (`notify), _("Do&mains to masquerade"), mod)
)
)
),
`VSpacing (1),
`Table (
`id (`tab),
`opt (`notify, `immediate),
// Translators: table column headings
`header (_("Local user"),
// Translators: table column headings
_("Display as")),
makeItems (mu, ["user", "address"])
),
/*
`HBox (
`HWeight (1, `ComboBox (`id (`user), `opt (`editable), _("Local user"),
["holly", "jane", "tarzan"])),
`HWeight (2, `TextEntry (`id (`address), _("Display as"), "holly@red.dwarf"))
),
*/
`HBox(
// Translators: button
`PushButton(`id(`add), `opt (`key_F3), _("A&dd")),
// Translators: button
`PushButton(`id(`edit), `opt (`key_F4), _("&Edit")),
// Translators: button
`PushButton(`id(`delete), `opt (`key_F5), _("Dele&te"))
),
`VSpacing (1)
);
string help = WJ_MakeHelp ( [`from_header, `local_domains ]) +
MasqueradingDialogHelp ();
Wizard::SetContentsButtons (caption, contents, help , Label::BackButton (), Label::OKButton ());
symbol ret = nil;
edit_touched = false;
while (true)
{
boolean any_items = UI::QueryWidget (`id (`tab), `CurrentItem) != nil;
UI::ChangeWidget (`id (`edit), `Enabled, any_items);
UI::ChangeWidget (`id (`delete), `Enabled, any_items);
// Kludge, because a `Table still does not have a shortcut.
// watch out, a textentry sends UI too
if (ret != `masqdomains)
{
UI::SetFocus (`id (`tab));
}
ret = (symbol) UI::UserInput ();
if (ret == `cancel)
{
ret = `abort;
}
if (ret == `masqdomains)
{
UI::ChangeWidget (`id (`mdg), `CurrentButton, `masqothers);
}
else if (contains ([`add, `edit, `delete], ret))
{
mu = EditTable ((symbol)ret, mu, ["user", "address"],
MasqueradeUserPopup, `tab);
}
else if ((ret == `abort
&& Popup::ReallyAbort (Mail::touched || edit_touched))
|| ret == `back)
{
break;
}
else if (ret == `next)
{
// Input validation
// For consistency, all querywidgets are done here.
// The table contents is maintained and validated
// at the EditTable call.
symbol rb = (symbol) UI::QueryWidget (`id (`mdg), `CurrentButton);
if (rb == `masqothers)
{
mod = (string) UI::QueryWidget (`id (`masqdomains), `Value);
lmod = stringToList (mod);
}
else
{
lmod = [];
}
if (! Validate_from_header (`from_header))
{
y2debug ("nothing");
}
else if (! Validate_local_domains (`local_domains))
{
y2debug ("nothing, already done");
}
else if (find (string s, lmod, ``(! Hostname::CheckDomain (s))) != nil)
{
UI::SetFocus (`id (`masqdomains));
// Translators: error popup
// Already in Translation Memory
string msg = _("The domain name is incorrect");
// TODO: describe a valid domain name
Popup::Error (msg);
}
else
{
// all checks OK, break the input loop
break;
}
}
}
if (ret == `next)
{
// all querywidgets are already done by the validation part
Set_from_header (`from_header);
Set_local_domains (`local_domains);
Mail::Touch (Mail::masquerade_other_domains != lmod);
Mail::masquerade_other_domains = lmod;
Mail::Touch (Mail::masquerade_users != mu);
Mail::masquerade_users = mu;
}
Wizard::RestoreScreenShotName ();
return (symbol) ret;
}
/**
* D2.2
* Outgoing server authentification
* @return `back, `abort or `next
*/
define symbol OutgoingAuthOptions() ``{
Wizard::SetScreenShotName ("mail-2o-outgoing-authentication");
//string mod = listToString (Mail::masquerade_other_domains);
//list<string> lmod = [];
//list<map> mu = Mail::masquerade_users;
// Translators: dialog caption
string caption = _("Outgoing Server Authentication");
term contents =
`VBox(
`HBox(
`HWeight(1,
`Empty()
),
`HWeight(3,
`VBox(
// text entry
`TextEntry(`id(`server), _("Outgoing &Server")),
// text entry
`TextEntry(`id(`user), _("&User name")),
// password entry
`Password( `id(`passw), _("&Password"))
)
),
`HWeight(1,
`Empty()
)
)
);
//);
Wizard::SetContentsButtons (caption, contents, AuthenticationDialogHelp (), Label::BackButton (), Label::OKButton ());
any ret = nil;
map config = Mail::smtp_auth[0]:$[];
if (config == $[]) {
config = add(config, "server", Mail::outgoing_mail_server);
config = add(config, "user", "");
config = add(config, "password", "");
}
UI::ChangeWidget(`id(`server), `Value, config["server"]:"");
UI::ChangeWidget(`id(`user), `Value, config["user"]:"");
UI::ChangeWidget(`id(`passw), `Value, config["password"]:"");
while (true)
{
ret = UI::UserInput ();
if (ret == `cancel)
{
ret = `abort;
}
if ((ret == `abort && Popup::ReallyAbort (Mail::touched))
|| ret == `back)
{
break;
}
else if (ret == `next)
{
string server = (string) UI::QueryWidget (`id (`server), `Value);
string user = (string) UI::QueryWidget (`id (`user), `Value);
string password = (string) UI::QueryWidget (`id (`passw), `Value);
if (server == "" && user == "" && password == "")
{
// wants to delete it, ok
config = $[];
break;
}
else
{
config["server"] = server;
config["user"] = user;
config["password"] = password;
}
// validity checks: reuse fetchmail widgets
if (Validate_outgoing_mail_server (`server) &&
Validate_fm_remote_user (`user))
{
break;
}
}
}
if (ret == `next)
{
// all querywidgets are already done by the validation part
Mail::Touch (Mail::smtp_auth[0]:$[] != config);
Mail::smtp_auth[0] = config;
// removing? had to add it first so that there is something to remove.
if (config == $[])
{
Mail::smtp_auth = remove (Mail::smtp_auth, 0);
}
else
{
// #158220
Mail::Touch (Mail::outgoing_mail_server != config["server"]:"");
Mail::outgoing_mail_server = config["server"]:"";
}
}
Wizard::RestoreScreenShotName ();
return (symbol)ret;
}
/**
* D3.1
* @param defaultv $[server:, protocol:, remote_user:, local_user:, password:, ...]
* @param existing unused
* @return edited data (with no other fields) or $[] on cancel
*/
define map FetchmailPopup (map defaultv, list<map> existing) ``{
fetchmail_item = defaultv;
fetchmail_item_touched = false;
list<symbol> widgets = [
`fm_server,
`fm_protocol,
`fm_remote_user,
`fm_password,
`fm_local_user,
];
term contents =
`HBox(
`HSpacing(1),
`VBox(
`VSpacing(0.2),
// Translators: popup dialog heading
`Heading (_("Mail downloading")),
`Left (WJ_MakeWidget (`fm_server)),
`Left (WJ_MakeWidget (`fm_protocol)),
`Left (WJ_MakeWidget (`fm_remote_user)),
`Left (WJ_MakeWidget (`fm_password)),
`Left (WJ_MakeWidget (`fm_local_user)),
`VSpacing(0.2),
`HBox(`PushButton(`id(`ok), `opt(`default, `key_F10), Label::OKButton()),
`PushButton(`id(`cancel), `opt (`key_F9), Label::CancelButton())),
`VSpacing(0.2)
),
`HSpacing(1)
);
UI::OpenDialog (`opt(`decorated), contents);
// set combo boxes to proper values
WJ_GetWidget (`fm_protocol);
WJ_GetWidget (`fm_local_user);
UI::SetFocus (`id (`fm_server));
any ret = nil;
while (true)
{
ret = UI::UserInput ();
if (ret == `cancel)
{
break;
}
else if (ret == `ok)
{
// Input validation
if (WJ_Validate (widgets))
{
// all checks OK, break the input loop
break;
}
}
}
WJ_Set (widgets); // TODO hope it is ok to mess it up
UI::CloseDialog ();
return (ret == `ok)? fetchmail_item : $[];
}
/**
* D3
* @return `back, `abort or `next
*/
define symbol DownloadingDialog () ``{
Wizard::SetScreenShotName ("mail-2ia-download");
//List of maps: $[server:, protocol:, remote_user:, local_user:, password:]
list<map> fm = Mail::fetchmail;
// Translators: dialog caption
string caption = _("Mail downloading");
term contents =
`VBox (
`VSpacing (0.2),
/*
* no time to implement this :-(
* #22903
`Frame (
// Translators: frame label
// When should Fetchmail run
// Fetchmail is a program name, do not translate
_("Run Fetchmail"),
RadioButtonVBox (
`run_fm_g,
[
// Translators: radio button label
`RadioButton (`id (`run_fm_man), _("&Manually"), true), // TODO fake
// Translators: radio button label
`RadioButton (`id (`run_fm_ppp), _("For &dial-up network connections"), false),
// Translators: radio button label
`RadioButton (`id (`run_fm_net), _("For &all network connections"), false),
]
)
),
`VSpacing (0.5),
*/
`Table (
`id (`tab),
`opt (`notify, `immediate),
// Translators: table column headings
`header (_("Server"),
// Translators: table column headings
_("Protocol"),
// Translators: table column headings
_("User"),
// Translators: table column headings
_("Local user")),
makeItems (fm, ["server", "protocol", "remote_user", "local_user"])
),
`HBox(
// Translators: button
`PushButton(`id(`add), `opt (`key_F3), _("A&dd")),
// Translators: button
`PushButton(`id(`edit), `opt (`key_F4), _("&Edit")),
// Translators: button
`PushButton(`id(`delete), `opt (`key_F5), _("De&lete"))
),
`VSpacing (0.2)
);
Wizard::SetContentsButtons (caption, contents, DownloadingDialogHelp (), Label::BackButton (), Label::OKButton ());
UI::ChangeWidget (`id (`edit), `Enabled, false);
UI::ChangeWidget (`id (`delete), `Enabled, false);
symbol ret = nil;
edit_touched = false;
while (true)
{
boolean any_items = UI::QueryWidget (`id (`tab), `CurrentItem) != nil;
UI::ChangeWidget (`id (`edit), `Enabled, any_items);
UI::ChangeWidget (`id (`delete), `Enabled, any_items);
// Kludge, because a `Table still does not have a shortcut.
UI::SetFocus (`id (`tab));
ret = (symbol) UI::UserInput ();
if (ret == `cancel)
{
ret = `abort;
}
if (contains ([`add, `edit, `delete], ret))
{
fm = EditTable (ret, fm,
["server", "protocol", "remote_user", "local_user"],
FetchmailPopup, `tab);
}
else if ((ret == `abort
&& Popup::ReallyAbort (Mail::touched || edit_touched))
|| ret == `next || ret == `back)
{
break;
}
}
if (ret == `next)
{
Mail::Touch (Mail::fetchmail != fm);
Mail::fetchmail = fm;
}
Wizard::RestoreScreenShotName ();
return ret;
}
/**
* D1.1.1, 1.2.1
* Used for adding and editing an alias/virtual domain entry.
* @param defaultv $["alias": "destinations": ?comment] or just $[]
* @param existing current entry list
* @return $["comment": ""?, "alias": "destinations":] or $[] on cancel
*/
define map AliasPopup (map defaultv, list<map> existing) ``{
string alias = defaultv["alias"]:"";
string destinations = defaultv["destinations"]:"";
list<string> forbidden = maplist (map e, existing, ``( e["alias"]:"" ));
term contents =
`HBox(
`HSpacing(1),
`VBox(
`VSpacing(0.2),
// Translators: popup dialog heading
`Heading (_("Incoming mail redirection")),
// Translators: text entry label
`Left (`TextEntry (`id (`alias), _("&Alias"), alias)),
// Translators: text entry label
`Left (`TextEntry (`id (`destinations), _("&Destinations"), destinations)),
`VSpacing(0.2),
`HBox(`PushButton(`id(`ok), `opt(`default, `key_F10), Label::OKButton()),
`PushButton(`id(`cancel), `opt (`key_F9), Label::CancelButton())),
`VSpacing(0.2)
),
`HSpacing(1)
);
UI::OpenDialog (`opt(`decorated), contents);
UI::SetFocus (`id (`alias));
any ret = nil;
while (true)
{
ret = UI::UserInput ();
if (ret == `cancel)
{
break;
}
else if (ret == `ok)
{
// Input validation
alias = (string) UI::QueryWidget (`id (`alias), `Value);
destinations = (string)UI::QueryWidget (`id (`destinations),`Value);
// TODO: this only works because check_mail_local part is too
// permissive. Virtusertable aliases may contain @ so it is not
// a local part and the check will need to be improved.
// (But a postfix-style virtual domain will have an @-less entry.)
if (!check_mail_local_part (alias))
{
UI::SetFocus (`id (`alias));
// Translators: error message
Popup::Message (_("The alias format is incorrect."));
}
else if (contains (forbidden, alias))
{
UI::SetFocus (`id (`alias));
// Translators: error message
Popup::Message (_("The destinations for this alias are already defined."));
}
else
{
// all checks OK, break the input loop
break;
}
}
}
UI::CloseDialog ();
return (ret == `ok)? $["comment": "", "alias": alias, "destinations": destinations] : $[];
}
/**
* D1.1
* @return `back, `abort or `next
*/
define symbol AliasesDialog () ``{
Wizard::SetScreenShotName ("mail-2ib-aliases");
list<map> aliases = MailAliases::MergeRootAlias (MailAliases::aliases);
// Translators: dialog caption
string caption = _("Aliases");
term contents =
`VBox (
`VSpacing (0.2),
`Table (
`id (`tab),
`opt (`notify, `immediate),
// Translators: table column headings
`header (_("Alias"),
// Translators: table column headings
_("Destinations")),
makeItems (aliases, ["alias", "destinations"])
),
`Left( `HBox(
// Translators: button
`PushButton(`id(`add), `opt (`key_F3), _("A&dd")),
// Translators: button
`PushButton(`id(`edit), `opt (`key_F4), _("&Edit")),
// Translators: button
`PushButton(`id(`delete), `opt (`key_F5), _("De&lete"))
)),
`VSpacing (0.2)
);
Wizard::SetContentsButtons (caption, contents, AliasesDialogHelp (), Label::BackButton (), Label::OKButton ());
any ret = nil;
edit_touched = false;
while (true)
{
boolean any_items = UI::QueryWidget (`id (`tab), `CurrentItem) != nil;
UI::ChangeWidget (`id (`edit), `Enabled, any_items);
UI::ChangeWidget (`id (`delete), `Enabled, any_items);
// Kludge, because a `Table still does not have a shortcut.
UI::SetFocus (`id (`tab));
ret = UI::UserInput ();
symbol ret_sym = nil;
if (is(ret,symbol))
{
ret_sym = (symbol) ret;
}
if (ret == `cancel)
{
ret = `abort;
}
if (contains ([`add, `edit, `delete], ret_sym))
{
aliases = EditTable((symbol)ret, aliases, ["alias", "destinations"],
AliasPopup, `tab);
}
else if (ret == "man_aliases")
{
y2milestone ("TODO: man aliases");
}
else if ((ret == `abort
&& Popup::ReallyAbort (Mail::touched || edit_touched))
|| ret == `next || ret == `back)
{
break;
}
}
if (ret == `next)
{
Mail::Touch (edit_touched);
MailAliases::aliases = aliases;
MailAliases::FilterRootAlias ();
}
Wizard::RestoreScreenShotName ();
return (symbol) ret;
}
/**
* D1.2
* @return `back, `abort or `next
*/
define symbol VirtualDialog () ``{
Wizard::SetScreenShotName ("mail-2ic-virtdomains");
list<map> vu = Mail::virtual_users;
// Translators: dialog caption
string caption = _("Virtual domains");
term contents =
`VBox (
`VSpacing (0.2),
`Table (
`id (`tab),
`opt (`notify, `immediate),
// Translators: table column headings
`header (_("Alias"),
// Translators: table column headings
_("Destinations")),
makeItems (vu, ["alias", "destinations"])
),
`Left(`HBox(
// Translators: button
`PushButton(`id(`add), `opt (`key_F3), _("A&dd")),
// Translators: button
`PushButton(`id(`edit), `opt (`key_F4), _("&Edit")),
// Translators: button
`PushButton(`id(`delete), `opt (`key_F5), _("De&lete"))
)),
`VSpacing (0.2)
);
Wizard::SetContentsButtons (caption, contents, VirtualDialogHelp (), Label::BackButton (), Label::OKButton ());
UI::ChangeWidget (`id (`edit), `Enabled, false);
UI::ChangeWidget (`id (`delete), `Enabled, false);
symbol ret = nil;
edit_touched = false;
while (true)
{
boolean any_items = UI::QueryWidget (`id (`tab), `CurrentItem) != nil;
UI::ChangeWidget (`id (`edit), `Enabled, any_items);
UI::ChangeWidget (`id (`delete), `Enabled, any_items);
// Kludge, because a `Table still does not have a shortcut.
UI::SetFocus (`id (`tab));
ret = (symbol) UI::UserInput ();
if (ret == `cancel)
{
ret = `abort;
}
if (contains ([`add, `edit, `delete], ret))
{
vu = EditTable((symbol)ret, vu, ["alias", "destinations"],
AliasPopup, `tab);
}
else if ((ret == `abort
&& Popup::ReallyAbort (Mail::touched || edit_touched))
|| ret == `next || ret == `back)
{
break;
}
}
if (ret == `next)
{
Mail::Touch (Mail::virtual_users != vu);
Mail::virtual_users = vu;;
}
Wizard::RestoreScreenShotName ();
return (symbol) ret;
}
/**
* A Wizard Sequencer helper
* @return `next
*/
define symbol JustNext () ``{
return `next;
}
map dialogs = $[
"read" : [ ``( ReadDialog () ), true ],
"confirm" : [ ``( ConfirmDialog () ), true],
"write" : [ ``( WriteDialog () ), true ],
"mta": ``( MtaSelectionDialog () ),
"connection_type": ``( ConnectionTypeDialog () ),
"outgoing": ``( OutgoingDialog () ),
"incoming": ``( IncomingDialog () ),
"outgoing-details": ``( OutgoingDetailsDialog () ),
"outgoing-auth": ``( OutgoingAuthOptions () ),
"downloading": ``( DownloadingDialog () ),
"aliases": ``( AliasesDialog () ),
"virtual": ``( VirtualDialog () ),
"common-next": [ ``( JustNext () ), true ],
];
map common_sequence = $[
//"ws_start" : must be defined in an overriding sequence
"connection_type" :
$[
`abort : `abort,
`next : "outgoing",
`none : "common-next",
],
"outgoing" :
$[
`abort : `abort,
`outgoing_details : "outgoing-details",
`outgoing_auth_opts : "outgoing-auth",
`next : "incoming",
],
"incoming" :
$[
`abort : `abort,
`downloading : "downloading",
`aliases : "aliases",
`virtual : "virtual",
`next : "common-next",
],
"outgoing-details" :
$[
`abort : `abort,
`next : "outgoing",
],
"outgoing-auth" :
$[
`abort : `abort,
`next : "outgoing",
],
"downloading" :
$[
`abort : `abort,
`next : "incoming",
],
"aliases" :
$[
`abort : `abort,
`next : "incoming",
],
"virtual" :
$[
`abort : `abort,
`next : "incoming",
],
"common-next" :
$[
`next : `next,
],
];
/**
* Whole configuration of mail
* @return `back, `abort or `next
*/
define symbol MailSequence () ``{
map sequence = $[
"ws_start" : "read",
"read" :
$[
`abort : `abort,
`next : "connection_type",
],
// common_sequence here
// override
"common-next" :
$[
`next : "confirm",
],
"confirm" :
$[
`next : "write"
],
"write" : $[
`abort : `abort,
`next : `next
]
];
Wizard::CreateDialog ();
Wizard::SetDesktopIcon("mail");
// the second map must override the first!
sequence = union (common_sequence, sequence);
any ret = Sequencer::Run (dialogs, sequence);
UI::CloseDialog ();
return (symbol) ret;
}
/**
* Whole configuration of mail but without reading and writing.
* MTA is selected first.
* For use with autoinstallation.
* @return `back, `abort or `next
*/
define symbol MailAutoSequence () ``{
map sequence = $[
"ws_start": "mta",
"mta":
$[
`abort : `abort,
`next : "connection_type",
],
// common_sequence here
];
// Translators: dialog caption
string caption = _("Mail configuration");
// label
term contents = `Label (_("Initializing..."));
Wizard::CreateDialog ();
Wizard::SetDesktopIcon("mail");
Wizard::SetContentsButtons ( caption,
contents,
"",
Label::BackButton (),
Label::NextButton ());
// the second map must override the first!
sequence = union (common_sequence, sequence);
any ret = Sequencer::Run (dialogs, sequence);
UI::CloseDialog ();
return (symbol) ret;
}
}
ACC SHELL 2018