using Sunfish.Config;
namespace Sunfish.WinForms;
/// <summary>
/// Alta o edicion de un share con el aspecto de la 2.0: estrecho y vertical, etiqueta encima de
/// cada campo, los obligatorios en amarillo claro y el aviso en un recuadro amarillo.
/// </summary>
internal sealed class ShareDialog : Form
{
private static readonly Color MandatoryBack = Color.FromArgb(255, 252, 220);
private const int FieldWidth = 260;
private readonly SunfishConfig _config;
private readonly string? _originalName;
private readonly TextBox _name = new() { Width = FieldWidth - 70, BackColor = MandatoryBack };
private readonly CheckBox _enabled = new() { AutoSize = true, Margin = new Padding(8, 4, 0, 0) };
private readonly TextBox _location = new() { Width = FieldWidth, BackColor = MandatoryBack };
private readonly TextBox _path = new() { Width = FieldWidth - 30, BackColor = MandatoryBack };
private readonly TextBox _index = new() { Width = FieldWidth };
private readonly CheckBox _listing = new() { AutoSize = true };
private readonly CheckBox _upload = new() { AutoSize = true };
private readonly CheckBox _overwrite = new() { AutoSize = true };
private readonly CheckBox _rename = new() { AutoSize = true };
private readonly CheckBox _delete = new() { AutoSize = true };
private readonly CheckBox _zip = new() { AutoSize = true };
private readonly CheckedListBox _users = new() { Width = FieldWidth, Height = 64, CheckOnClick = true, IntegralHeight = false };
private readonly Label _warning = new()
{
AutoSize = true, MaximumSize = new Size(FieldWidth, 0), BackColor = Color.FromArgb(240, 230, 160),
BorderStyle = BorderStyle.FixedSingle, Padding = new Padding(3), Margin = new Padding(3, 8, 3, 3),
};
public ShareConfig Result { get; }
public ShareDialog(ShareConfig share, SunfishConfig config, string? originalName)
{
Result = share;
_config = config;
_originalName = originalName;
SuspendLayout();
AutoScaleDimensions = new SizeF(96F, 96F);
AutoScaleMode = AutoScaleMode.Dpi;
Text = originalName is null ? Texts.NewShare : Texts.EditShareTitle(originalName);
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = MinimizeBox = false;
ShowInTaskbar = false;
StartPosition = FormStartPosition.CenterParent;
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
Padding = new Padding(8, 6, 8, 8);
_enabled.Text = Texts.Active;
_listing.Text = Strings.OptListing;
_upload.Text = Strings.OptUpload;
_overwrite.Text = Strings.OptOverwrite;
_rename.Text = Strings.OptRename;
_delete.Text = Strings.OptDelete;
_zip.Text = Strings.OptZip;
_name.Text = share.Name;
_location.Text = share.Location;
_path.Text = share.Path;
_index.Text = share.Index;
_enabled.Checked = share.Enabled;
_listing.Checked = share.Listing;
_upload.Checked = share.Upload;
_overwrite.Checked = share.Overwrite;
_rename.Checked = share.Rename;
_delete.Checked = share.Delete;
_zip.Checked = share.Zip;
foreach (var user in config.Users)
_users.Items.Add(user.Name, share.Users.Contains(user.Name, StringComparer.OrdinalIgnoreCase));
var browse = new Button { Text = "...", Size = new Size(26, _path.Height + 2), Margin = new Padding(2, 2, 0, 0), UseVisualStyleBackColor = true };
browse.Click += (_, _) => Browse();
// El formulario se ajusta al contenido: el panel va en la esquina del relleno (Padding solo
// lo respetan los controles acoplados) y el relleno derecho/inferior lo anade AutoSize.
var main = new FlowLayoutPanel
{
FlowDirection = FlowDirection.TopDown, AutoSize = true, WrapContents = false,
Location = new Point(Padding.Left, Padding.Top), Margin = new Padding(0),
};
main.Controls.Add(Caption(Strings.FieldName));
main.Controls.Add(Row(_name, _enabled));
main.Controls.Add(Caption(Strings.FieldLocation));
main.Controls.Add(_location);
main.Controls.Add(Caption(Strings.FieldPath));
main.Controls.Add(Row(_path, browse));
main.Controls.Add(Caption(Strings.FieldIndex));
main.Controls.Add(_index);
main.Controls.Add(new Panel { Height = 6, Width = 1 });
foreach (var check in new[] { _listing, _upload, _overwrite, _rename, _delete, _zip })
{
check.Margin = new Padding(14, 2, 3, 2);
main.Controls.Add(check);
}
if (config.Users.Count > 0)
{
main.Controls.Add(Caption(Texts.AllowedUsers));
main.Controls.Add(_users);
}
main.Controls.Add(_warning);
var ok = new Button { Text = Texts.Ok, Size = new Size(80, 25), UseVisualStyleBackColor = true };
ok.Click += (_, _) => Accept();
var cancel = new Button { Text = Texts.Cancel, Size = new Size(80, 25), DialogResult = DialogResult.Cancel, UseVisualStyleBackColor = true };
var buttons = new FlowLayoutPanel { FlowDirection = FlowDirection.RightToLeft, Width = FieldWidth + 6, Height = 25, Margin = new Padding(0, 10, 0, 0) };
ok.Margin = new Padding(3, 0, 3, 0);
cancel.Margin = new Padding(3, 0, 3, 0);
buttons.Controls.AddRange([cancel, ok]);
main.Controls.Add(buttons);
AcceptButton = ok;
CancelButton = cancel;
Controls.Add(main);
ResumeLayout(false);
PerformLayout();
_upload.CheckedChanged += (_, _) => UpdateWarning();
_listing.CheckedChanged += (_, _) => UpdateWarning();
UpdateWarning();
}
private static Label Caption(string text) =>
new() { Text = text + ":", AutoSize = true, Margin = new Padding(3, 6, 3, 1) };
private static FlowLayoutPanel Row(params Control[] controls)
{
var row = new FlowLayoutPanel { AutoSize = true, WrapContents = false, Margin = new Padding(0) };
row.Controls.AddRange(controls);
return row;
}
private void Browse()
{
using var picker = new FolderBrowserDialog { SelectedPath = _path.Text, UseDescriptionForTitle = true, Description = Strings.FieldPath };
if (picker.ShowDialog(this) != DialogResult.OK)
return;
_path.Text = picker.SelectedPath;
if (_name.Text.Length == 0)
{
_name.Text = ShareSettings.SuggestName(_config, Path.GetFileName(Path.TrimEndingDirectorySeparator(picker.SelectedPath)));
_location.Text = ShareSettings.SuggestLocation(_config, _name.Text);
}
}
private void UpdateWarning()
{
bool show = _upload.Checked && _listing.Checked;
_warning.Text = show ? Strings.WarnUploadListing : "";
_warning.Visible = show;
}
private void Accept()
{
var s = Result;
s.Name = _name.Text.Trim();
s.Location = _location.Text.Trim();
s.Path = _path.Text.Trim();
s.Index = _index.Text.Trim();
s.Enabled = _enabled.Checked;
s.Listing = _listing.Checked;
s.Upload = _upload.Checked;
s.Overwrite = _overwrite.Checked;
s.Rename = _rename.Checked;
s.Delete = _delete.Checked;
s.Zip = _zip.Checked;
if (_config.Users.Count > 0)
s.Users = _users.CheckedItems.Cast<string>().ToList();
if (ShareSettings.Validate(_config, s, _originalName) is { } problem)
{
MessageBox.Show(this, problem, Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
DialogResult = DialogResult.OK;
}
}