LukasRiedel

MA2017 FINAL

May 15th, 2017
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 239.90 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Net.Mail;
  5. using System.Windows.Forms;
  6.  
  7. namespace Mail_Agent_2017
  8. {
  9.     /// <summary>
  10.     /// Základní okno adresáře.
  11.     /// </summary>
  12.     public partial class AddressBookForm : Form
  13.     {
  14.         /// <summary>
  15.         /// Adresář kontaktů.
  16.         /// </summary>
  17.         public Adresar adresar;
  18.         internal List<JedenKontakt> ovladaciPrvky;
  19.         /// <summary>
  20.         /// Aktuální přihlášení.
  21.         /// </summary>
  22.         protected Prihlaseni aktualniPrihlaseni;
  23.  
  24.         /// <summary>
  25.         /// Konstruktor, který se nesmí nikdy zavolat. Máme ho zde kvůli polymorfismu, jinak by to nefungovalo.
  26.         /// </summary>
  27.         protected AddressBookForm() { }
  28.  
  29.         /// <summary>
  30.         /// Inicializace nejdůležitějších komponent pro toto okno.
  31.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení. Toto je zde kvůli odesílání e-mailů a nalezení správného adresáře.</param>
  32.         /// <param name="pridatDoEmailu">Rozhoduje, jaký druh adresáře zobrazí. Jestli ten editovací, nebo ten, který přidává kontakty do e-mailu.</param>
  33.         /// </summary>
  34.         public AddressBookForm(Prihlaseni aktualniPrihlaseni, bool pridatDoEmailu)
  35.         {
  36.             this.Icon = BarevnyMotiv.ikona;
  37.             InitializeComponent();
  38.             adresar = new Adresar(aktualniPrihlaseni);
  39.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  40.             ovladaciPrvky = new List<JedenKontakt>();
  41.  
  42.             // Vyřešíme takhle jednoduše, abychom nemuseli "složitě" upravovat designer.
  43.             if (pridatDoEmailu)
  44.             {
  45.                 this.VytvoritButton.Visible = false;
  46.                 this.ZavritButton.Text = "Připojit k e-mailu";
  47.             }
  48.  
  49.             for (int i = 0; i < adresar.seznamKontaktu.Count; i++)
  50.                 ovladaciPrvky.Add(new JedenKontakt(adresar.seznamKontaktu[i], i, this, pridatDoEmailu));
  51.         }
  52.  
  53.         /// <summary>
  54.         /// Vytvoří nový kontakt.
  55.         /// </summary>
  56.         internal virtual void VytvoritButton_Click(object sender, EventArgs e)
  57.         {
  58.             using (var form = new ContactForm(aktualniPrihlaseni))
  59.                 if (form.ShowDialog() == DialogResult.OK)
  60.                 {
  61.                     adresar.seznamKontaktu.Add(form.novyKontakt);
  62.                     ovladaciPrvky.Add(new JedenKontakt(adresar.seznamKontaktu[adresar.seznamKontaktu.Count - 1], adresar.seznamKontaktu.Count - 1, this, false));
  63.                 }
  64.         }
  65.  
  66.         /// <summary>
  67.         /// Odstraní daný kontakt z adresáře.
  68.         /// </summary>
  69.         /// <param name="kolikaty">Kolikátý kontakt v pořadí se má smazat.</param>
  70.         private void OdstranExistujiciKontakt(int kolikaty)
  71.         {
  72.             // Všechny kontakty pod tímto musíme posunout směrem nahoru.
  73.             ovladaciPrvky.GetRange(kolikaty + 1, ovladaciPrvky.Count - kolikaty - 1).ForEach(kontakt =>
  74.             {
  75.                 kontakt.JmenoKontaktLabel.Location = new System.Drawing.Point(52, kontakt.JmenoKontaktLabel.Location.Y - 38);
  76.                 kontakt.EmailKontaktLabel.Location = new System.Drawing.Point(230, kontakt.EmailKontaktLabel.Location.Y - 38);
  77.                 kontakt.DeleteButton.Location = new System.Drawing.Point(482, kontakt.DeleteButton.Location.Y - 38);
  78.                 kontakt.EditButton.Location = new System.Drawing.Point(449, kontakt.EditButton.Location.Y - 38);
  79.                 kontakt.InfoButton.Location = new System.Drawing.Point(416, kontakt.InfoButton.Location.Y - 38);
  80.                 kontakt.ObrazekKontaktPicturebox.Location = new System.Drawing.Point(3, kontakt.ObrazekKontaktPicturebox.Location.Y - 38);
  81.             });
  82.  
  83.             // Uvolnění resourců, aby prvky smazané kontakty nezůstaly na pozadí a nezabíraly tak zbytečně paměť.
  84.             ovladaciPrvky[kolikaty].Dispose();
  85.             adresar.seznamKontaktu.RemoveAt(kolikaty);
  86.         }
  87.  
  88.         /// <summary>
  89.         /// Zavře okno s kontakty.
  90.         /// </summary>
  91.         protected void ZavritButton_Click(object sender, EventArgs e)
  92.         {
  93.             this.DialogResult = DialogResult.OK;
  94.             this.Close();
  95.         }
  96.  
  97.         /// <summary>
  98.         /// Třída sloužící k inicializaci jednoho kontaktu v adresářovém okně - tedy inicializuje labely a tlačítka pro daný kontakt.
  99.         /// </summary>
  100.         internal class JedenKontakt : IDisposable
  101.         {
  102.             internal Kontakt kontakt;
  103.             private AddressBookForm okno;
  104.             private int kolikatyKontakt;
  105.  
  106.             internal System.Windows.Forms.Label EmailKontaktLabel;
  107.             internal System.Windows.Forms.PictureBox InfoButton;
  108.             internal System.Windows.Forms.PictureBox EditButton;
  109.             internal System.Windows.Forms.PictureBox DeleteButton;
  110.             internal System.Windows.Forms.PictureBox ObrazekKontaktPicturebox;
  111.             internal System.Windows.Forms.Label JmenoKontaktLabel;
  112.             internal System.Windows.Forms.CheckBox PridatKontaktCheckbox;
  113.  
  114.             internal ToolTip PridatDoEmailuToolTip;
  115.  
  116.             /// <summary>
  117.             /// Inicializace celého kontaktu.
  118.             /// </summary>
  119.             /// <param name="kontakt">Kontakt, který se má inicializovat.</param>
  120.             /// <param name="kolikatyKontakt">Určuje, o kolikátý kontakt v seznamu se jedná. Kvůli pozici tlačítek a tak.</param>
  121.             /// <param name="okno">Aktuální okno.</param>
  122.             /// <param name="pridatDoEmailu">Rozhoduje, jaký druh adresáře zobrazí. Jestli ten editovací, nebo ten, který přidává kontakty do e-mailu.</param>
  123.             internal JedenKontakt(Kontakt kontakt, int kolikatyKontakt, AddressBookForm okno, bool pridatDoEmailu)
  124.             {
  125.                 this.kontakt = kontakt;
  126.                 this.okno = okno;
  127.                 this.kolikatyKontakt = kolikatyKontakt;
  128.  
  129.                 #region Inicializace ovládacích prvků.
  130.                 this.JmenoKontaktLabel = new System.Windows.Forms.Label();
  131.                 this.EmailKontaktLabel = new System.Windows.Forms.Label();
  132.                 this.ObrazekKontaktPicturebox = new System.Windows.Forms.PictureBox();
  133.                
  134.                 ((System.ComponentModel.ISupportInitialize)(this.ObrazekKontaktPicturebox)).BeginInit();
  135.                 //
  136.                 // JmenoKontaktLabel
  137.                 //
  138.                 this.JmenoKontaktLabel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  139.                 this.JmenoKontaktLabel.Font = new System.Drawing.Font("Calibri", 10F);
  140.                 this.JmenoKontaktLabel.Location = new System.Drawing.Point(52, 38 * kolikatyKontakt);
  141.                 this.JmenoKontaktLabel.Name = "JmenoKontaktLabel";
  142.                 this.JmenoKontaktLabel.Size = new System.Drawing.Size(171, 32);
  143.                 this.JmenoKontaktLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
  144.                 //
  145.                 // EmailKontaktLabel
  146.                 //
  147.                 this.EmailKontaktLabel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  148.                 this.EmailKontaktLabel.Font = new System.Drawing.Font("Calibri Light", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
  149.                 this.EmailKontaktLabel.ForeColor = System.Drawing.SystemColors.Highlight;
  150.                 this.EmailKontaktLabel.Location = new System.Drawing.Point(230, 38 * kolikatyKontakt);
  151.                 this.EmailKontaktLabel.Name = "EmailKontaktLabel";
  152.                 this.EmailKontaktLabel.Size = new System.Drawing.Size(171, 32);
  153.                 this.EmailKontaktLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;                              
  154.                 //
  155.                 // ObrazekKontaktPicturebox
  156.                 //
  157.                 this.ObrazekKontaktPicturebox.Location = new System.Drawing.Point(3, 38 * kolikatyKontakt);
  158.                 this.ObrazekKontaktPicturebox.Name = "ObrazekKontaktPicturebox";
  159.                 this.ObrazekKontaktPicturebox.Size = new System.Drawing.Size(32, 32);
  160.                 this.ObrazekKontaktPicturebox.TabIndex = 18;
  161.                 this.ObrazekKontaktPicturebox.TabStop = false;
  162.                 this.ObrazekKontaktPicturebox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
  163.  
  164.                 ((System.ComponentModel.ISupportInitialize)(this.ObrazekKontaktPicturebox)).EndInit();
  165.  
  166.  
  167.                 okno.AdresarPanel.Controls.Add(this.ObrazekKontaktPicturebox);
  168.                 okno.AdresarPanel.Controls.Add(this.JmenoKontaktLabel);
  169.                 okno.AdresarPanel.Controls.Add(this.EmailKontaktLabel);
  170.  
  171.                 this.PridatKontaktCheckbox = new System.Windows.Forms.CheckBox();
  172.  
  173.                 if (pridatDoEmailu)
  174.                 {
  175.  
  176.                     //
  177.                     // PridatKontaktCheckbox
  178.                     //
  179.                     this.PridatKontaktCheckbox.AutoSize = true;
  180.                     this.PridatKontaktCheckbox.Location = new System.Drawing.Point(449, 11 + 38 * kolikatyKontakt);
  181.                     this.PridatKontaktCheckbox.Name = "PridatKontaktCheckbox";
  182.                     this.PridatKontaktCheckbox.Size = new System.Drawing.Size(16, 16);
  183.                     this.PridatKontaktCheckbox.TabIndex = kolikatyKontakt;
  184.                     this.PridatKontaktCheckbox.UseVisualStyleBackColor = true;
  185.  
  186.                     PridatDoEmailuToolTip = new ToolTip();
  187.                     PridatDoEmailuToolTip.UseFading = true;
  188.                     PridatDoEmailuToolTip.UseAnimation = true;
  189.                     PridatDoEmailuToolTip.ReshowDelay = 500;
  190.                     PridatDoEmailuToolTip.InitialDelay = 500;
  191.                     PridatDoEmailuToolTip.AutoPopDelay = 15000;
  192.                     PridatDoEmailuToolTip.ShowAlways = true;
  193.                     PridatDoEmailuToolTip.ToolTipIcon = ToolTipIcon.Info;
  194.                     PridatDoEmailuToolTip.SetToolTip(PridatKontaktCheckbox, "Připojí kontakt k e-mailu.");
  195.  
  196.                     ToolTip InfoToolTip = new ToolTip();
  197.                     InfoToolTip.UseFading = true;
  198.                     InfoToolTip.UseAnimation = true;
  199.                     InfoToolTip.ReshowDelay = 500;
  200.                     InfoToolTip.InitialDelay = 500;
  201.                     InfoToolTip.AutoPopDelay = 15000;
  202.                     InfoToolTip.ShowAlways = true;
  203.                     InfoToolTip.ToolTipIcon = ToolTipIcon.Info;
  204.                     InfoToolTip.SetToolTip(ObrazekKontaktPicturebox, "Zobrazit kontakt.");
  205.  
  206.                     ToolTip InfoToolTip2 = new ToolTip();
  207.                     InfoToolTip2.UseFading = true;
  208.                     InfoToolTip2.UseAnimation = true;
  209.                     InfoToolTip2.ReshowDelay = 500;
  210.                     InfoToolTip2.InitialDelay = 500;
  211.                     InfoToolTip2.AutoPopDelay = 15000;
  212.                     InfoToolTip2.ShowAlways = true;
  213.                     InfoToolTip2.ToolTipIcon = ToolTipIcon.Info;
  214.                     InfoToolTip2.SetToolTip(JmenoKontaktLabel, "Zobrazit kontakt.");
  215.  
  216.                     okno.AdresarPanel.Controls.Add(this.PridatKontaktCheckbox);
  217.  
  218.                     this.ObrazekKontaktPicturebox.Click += new System.EventHandler(this.InfoButton_Click);
  219.                     this.JmenoKontaktLabel.Click += new System.EventHandler(this.InfoButton_Click);
  220.  
  221.                     this.JmenoKontaktLabel.Cursor = Cursors.Hand;
  222.                     this.ObrazekKontaktPicturebox.Cursor = Cursors.Hand;
  223.  
  224.                     this.EmailKontaktLabel.ForeColor = this.JmenoKontaktLabel.ForeColor;
  225.                 }
  226.  
  227.                 else
  228.                 {
  229.                     this.DeleteButton = new System.Windows.Forms.PictureBox();
  230.                     this.EditButton = new System.Windows.Forms.PictureBox();
  231.                     this.InfoButton = new System.Windows.Forms.PictureBox();
  232.  
  233.                     ((System.ComponentModel.ISupportInitialize)(this.DeleteButton)).BeginInit();
  234.                     ((System.ComponentModel.ISupportInitialize)(this.EditButton)).BeginInit();
  235.                     ((System.ComponentModel.ISupportInitialize)(this.InfoButton)).BeginInit();
  236.  
  237.                     //
  238.                     // DeleteButton
  239.                     //
  240.                     this.DeleteButton.Image = global::Mail_Agent_2017.Properties.Resources.OdstranitSoubor;
  241.                     this.DeleteButton.Location = new System.Drawing.Point(482, 38 * kolikatyKontakt);
  242.                     this.DeleteButton.Name = "DeleteButton";
  243.                     this.DeleteButton.Padding = new System.Windows.Forms.Padding(4);
  244.                     this.DeleteButton.Size = new System.Drawing.Size(32, 32);
  245.                     this.DeleteButton.TabStop = false;
  246.                     this.DeleteButton.Cursor = Cursors.Hand;
  247.                     //
  248.                     // EditButton
  249.                     //
  250.                     this.EditButton.Image = global::Mail_Agent_2017.Properties.Resources.EditovatSoubor;
  251.                     this.EditButton.Location = new System.Drawing.Point(449, 38 * kolikatyKontakt);
  252.                     this.EditButton.Name = "EditButton";
  253.                     this.EditButton.Padding = new System.Windows.Forms.Padding(4);
  254.                     this.EditButton.Size = new System.Drawing.Size(32, 32);
  255.                     this.EditButton.TabStop = false;
  256.                     this.EditButton.Cursor = Cursors.Hand;
  257.                     //
  258.                     // InfoButton
  259.                     //
  260.                     this.InfoButton.Image = global::Mail_Agent_2017.Properties.Resources.InformaceOSouboru;
  261.                     this.InfoButton.Location = new System.Drawing.Point(416, 38 * kolikatyKontakt);
  262.                     this.InfoButton.Name = "InfoButton";
  263.                     this.InfoButton.Padding = new System.Windows.Forms.Padding(4);
  264.                     this.InfoButton.Size = new System.Drawing.Size(32, 32);
  265.                     this.InfoButton.TabStop = false;
  266.                     this.InfoButton.Cursor = Cursors.Hand;
  267.  
  268.                     ToolTip SendToolTip = new ToolTip();
  269.                     SendToolTip.UseFading = true;
  270.                     SendToolTip.UseAnimation = true;
  271.                     SendToolTip.ReshowDelay = 500;
  272.                     SendToolTip.InitialDelay = 500;
  273.                     SendToolTip.AutoPopDelay = 15000;
  274.                     SendToolTip.ShowAlways = true;
  275.                     SendToolTip.ToolTipIcon = ToolTipIcon.Info;
  276.                     SendToolTip.SetToolTip(EmailKontaktLabel, "Kliknutím odešlete e-mail na danou adresu.");
  277.  
  278.                     ToolTip InfoToolTip = new ToolTip();
  279.                     InfoToolTip.UseFading = true;
  280.                     InfoToolTip.UseAnimation = true;
  281.                     InfoToolTip.ReshowDelay = 500;
  282.                     InfoToolTip.InitialDelay = 500;
  283.                     InfoToolTip.AutoPopDelay = 15000;
  284.                     InfoToolTip.ShowAlways = true;
  285.                     InfoToolTip.ToolTipIcon = ToolTipIcon.Info;
  286.                     InfoToolTip.SetToolTip(InfoButton, "Zobrazit kontakt.");
  287.  
  288.                     ToolTip EditToolTip = new ToolTip();
  289.                     EditToolTip.UseFading = true;
  290.                     EditToolTip.UseAnimation = true;
  291.                     EditToolTip.ReshowDelay = 500;
  292.                     EditToolTip.InitialDelay = 500;
  293.                     EditToolTip.AutoPopDelay = 15000;
  294.                     EditToolTip.ShowAlways = true;
  295.                     EditToolTip.ToolTipIcon = ToolTipIcon.Info;
  296.                     EditToolTip.SetToolTip(EditButton, "Editovat kontakt.");
  297.  
  298.                     ToolTip DeleteToolTip = new ToolTip();
  299.                     DeleteToolTip.UseFading = true;
  300.                     DeleteToolTip.UseAnimation = true;
  301.                     DeleteToolTip.ReshowDelay = 500;
  302.                     DeleteToolTip.InitialDelay = 500;
  303.                     DeleteToolTip.AutoPopDelay = 15000;
  304.                     DeleteToolTip.ShowAlways = true;
  305.                     DeleteToolTip.ToolTipIcon = ToolTipIcon.Info;
  306.                     DeleteToolTip.SetToolTip(DeleteButton, "Smazat kontakt.");
  307.  
  308.                     this.InfoButton.Click += new System.EventHandler(this.InfoButton_Click);
  309.                     this.EditButton.Click += new System.EventHandler(this.EditButton_Click);
  310.                     this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click);
  311.                     this.EmailKontaktLabel.Click += new System.EventHandler(this.SendButton_Click);
  312.  
  313.                     okno.AdresarPanel.Controls.Add(this.EditButton);
  314.                     okno.AdresarPanel.Controls.Add(this.InfoButton);
  315.                     okno.AdresarPanel.Controls.Add(this.DeleteButton);                    
  316.  
  317.                     ((System.ComponentModel.ISupportInitialize)(this.DeleteButton)).EndInit();
  318.                     ((System.ComponentModel.ISupportInitialize)(this.EditButton)).EndInit();
  319.                     ((System.ComponentModel.ISupportInitialize)(this.InfoButton)).EndInit();
  320.  
  321.                     this.EmailKontaktLabel.Cursor = Cursors.Hand;
  322.                 }
  323.  
  324.                
  325.                 #endregion
  326.  
  327.                 JmenoKontaktLabel.Text = kontakt.Jmeno;
  328.                 EmailKontaktLabel.Text = kontakt.Email;
  329.  
  330.                 int pomer = Math.Max(kontakt.Fotografie.Width / 24, kontakt.Fotografie.Height / 24);
  331.                 ObrazekKontaktPicturebox.Image = new Bitmap(kontakt.Fotografie, new Size(kontakt.Fotografie.Width / pomer, kontakt.Fotografie.Height / pomer));
  332.  
  333.                 okno.Invalidate();
  334.             }
  335.  
  336.             /// <summary>
  337.             /// Zobrazí informace o kontaktu.
  338.             /// </summary>
  339.             private void InfoButton_Click(object sender, EventArgs e)
  340.             {
  341.                 new ContactForm(kontakt, true, okno.aktualniPrihlaseni).ShowDialog();
  342.             }
  343.  
  344.             /// <summary>
  345.             /// Otevře okno, které odešle danému kontaktu e-mail.
  346.             /// </summary>
  347.             private void SendButton_Click(object sender, EventArgs e)
  348.             {
  349.                 // Nejdřív uložíme adresář do souboru.
  350.                 okno.adresar.Ulozit();
  351.                 new SendForm(okno.aktualniPrihlaseni, ((Label)sender).Text).ShowDialog();
  352.             }
  353.  
  354.             /// <summary>
  355.             /// Upraví kontakt.
  356.             /// </summary>
  357.             private void EditButton_Click(object sender, EventArgs e)
  358.             {
  359.                 using (var form = new ContactForm(kontakt, false, okno.aktualniPrihlaseni))
  360.                     if (form.ShowDialog() == DialogResult.OK)
  361.                         kontakt = form.novyKontakt;
  362.  
  363.                 JmenoKontaktLabel.Text = kontakt.Jmeno;
  364.                 EmailKontaktLabel.Text = kontakt.Email;
  365.  
  366.                 int pomer = Math.Max(kontakt.Fotografie.Width / 24, kontakt.Fotografie.Height / 24);
  367.                 ObrazekKontaktPicturebox.Image = new Bitmap(kontakt.Fotografie, new Size(kontakt.Fotografie.Width / pomer, kontakt.Fotografie.Height / pomer));
  368.  
  369.                 okno.adresar.seznamKontaktu[kolikatyKontakt] = kontakt;
  370.                 okno.ovladaciPrvky[kolikatyKontakt] = this;
  371.             }
  372.  
  373.             /// <summary>
  374.             /// Odstraní kontakt.
  375.             /// </summary>
  376.             private void DeleteButton_Click(object sender, EventArgs e)
  377.             {
  378.                 if (MessageBox.Show("Opravdu chcete odstranit tento kontakt?", "Odstranit", MessageBoxButtons.YesNo) == DialogResult.Yes)
  379.                     okno.OdstranExistujiciKontakt((this.DeleteButton.Location.Y) / 38); // O kolikátý kontakt se jedná, poznáme podle jeho pozice.
  380.             }
  381.  
  382.             /// <summary>
  383.             /// Klasická implementace metody Dispose.
  384.             /// </summary>
  385.             public void Dispose()
  386.             {
  387.                 EmailKontaktLabel.Dispose();
  388.                 InfoButton.Dispose();
  389.                 EditButton.Dispose();
  390.                 DeleteButton.Dispose();
  391.                 ObrazekKontaktPicturebox.Dispose();
  392.                 JmenoKontaktLabel.Dispose();
  393.                 PridatKontaktCheckbox.Dispose();
  394.             }
  395.         }
  396.     }
  397. }
  398.  
  399. using System;
  400. using System.Collections.Generic;
  401. using System.ComponentModel;
  402. using System.Drawing;
  403. using System.IO;
  404. using System.Linq;
  405. using System.Text;
  406. using System.Threading.Tasks;
  407.  
  408. namespace Mail_Agent_2017
  409. {
  410.     interface IAdresarovaStruktura
  411.     {
  412.         void Ulozit();
  413.     }
  414.  
  415.     /// <summary>
  416.     /// Třída implementující adresář kontaktů.
  417.     /// </summary>
  418.     public class Adresar : IAdresarovaStruktura
  419.     {
  420.         /// <summary>
  421.         /// Seznam kontaktů v adresáři.
  422.         /// </summary>
  423.         public List<Kontakt> seznamKontaktu;
  424.         private Prihlaseni aktualniPrihlaseni;
  425.  
  426.         /// <summary>
  427.         /// Konstruktor načte všechny kontakty ze souboru kontaktů.
  428.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení zde máme proto, abychom věděli, čí adresář máme na disku hledat.</param>
  429.         /// </summary>
  430.         public Adresar(Prihlaseni aktualniPrihlaseni)
  431.         {
  432.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  433.             seznamKontaktu = new List<Kontakt>();
  434.  
  435.             Skupiny skupiny = new Skupiny(aktualniPrihlaseni);
  436.  
  437.             object soubor;
  438.  
  439.             if (!File.Exists(@aktualniPrihlaseni._email + ".contacts_info"))
  440.             {
  441.                 soubor = File.Create(aktualniPrihlaseni._email + ".contacts_info");
  442.                 ((FileStream)soubor).Close();
  443.             }
  444.  
  445.             soubor = new StreamReader(@aktualniPrihlaseni._email + ".contacts_info");
  446.  
  447.             // Zkusíme načíst kontakty ze souboru.
  448.             try
  449.             {
  450.                 while (!((StreamReader)soubor).EndOfStream)
  451.                 {
  452.                     var jedenKontakt = ((StreamReader)soubor).ReadLine().Split(';');
  453.                     seznamKontaktu.Add(new Kontakt(jedenKontakt[0], jedenKontakt[1], jedenKontakt[2], jedenKontakt[3], jedenKontakt[4], jedenKontakt[5], jedenKontakt[6],
  454.                         (skupiny.seznamSkupin.IndexOf(new Skupina { _nazev = jedenKontakt[7] }) == -1) ? "" : jedenKontakt[7], // Pokud skupina již neexistuje (byla smazána), nebudeme ji vypisovat.
  455.                         jedenKontakt[8]));
  456.                 }
  457.             }
  458.  
  459.             // Někde je chyba, vytvoříme nový adresář.
  460.             catch { seznamKontaktu = new List<Kontakt>(); }
  461.             finally { ((StreamReader)soubor).Close(); }
  462.         }
  463.  
  464.         /// <summary>
  465.         /// Uloží adresář z paměti do souboru.
  466.         /// </summary>
  467.         public void Ulozit()
  468.         {
  469.             StreamWriter soubor = new StreamWriter(@aktualniPrihlaseni._email + ".contacts_info");
  470.             foreach (Kontakt kontakt in seznamKontaktu)
  471.                 soubor.WriteLine(kontakt.UlozKontakt());
  472.             soubor.Close();
  473.         }
  474.     }
  475.  
  476.     /// <summary>
  477.     /// Třída uchovávající informace o kontaktu.
  478.     /// </summary>
  479.     public class Kontakt
  480.     {
  481.         private string _fotka;
  482.         private string _jmeno;
  483.         private string _firma;
  484.         private string _prezdivka;
  485.         private string _email;
  486.         private string _telefon;
  487.         private string _web;
  488.         internal string _skupina;
  489.         private string _poznamka;
  490.  
  491.         #region Definice vlastností jednotlivých parametrů.
  492.         // Všechno šifrujeme, abychom mohli údaje bezpečně uložit do souboru a nehrozilo zneužití údajů.
  493.  
  494.         /// <summary>
  495.         /// Fotografie daného kontaktu.
  496.         /// </summary>
  497.         public Bitmap Fotografie
  498.         {
  499.             get { return _fotka == null ? null : Sifrovani.StringToBitmap(_fotka); }
  500.             set { _fotka = Sifrovani.BitmapToString(value); }
  501.         }
  502.  
  503.         /// <summary>
  504.         /// Jméno daného kontaktu.
  505.         /// </summary>
  506.         public string Jmeno
  507.         {
  508.             get { return _jmeno == null ? null : Sifrovani.Decrypt(_jmeno); }
  509.             set { _jmeno = Sifrovani.Encrypt(value); }
  510.         }
  511.  
  512.         /// <summary>
  513.         /// Firma daného kontaktu.
  514.         /// </summary>
  515.         public string Firma
  516.         {
  517.             get { return _firma == null ? null : Sifrovani.Decrypt(_firma); }
  518.             set { _firma = Sifrovani.Encrypt(value); }
  519.         }
  520.  
  521.         /// <summary>
  522.         /// Přezdívka daného kontaktu.
  523.         /// </summary>
  524.         public string Prezdivka
  525.         {
  526.             get { return _prezdivka == null ? null : Sifrovani.Decrypt(_prezdivka); }
  527.             set { _prezdivka = Sifrovani.Encrypt(value); }
  528.         }
  529.  
  530.         /// <summary>
  531.         /// E-mail daného kontaktu.
  532.         /// </summary>
  533.         public string Email
  534.         {
  535.             get { return _email == null ? null : Sifrovani.Decrypt(_email); }
  536.             set { _email = Sifrovani.Encrypt(value); }
  537.         }
  538.  
  539.         /// <summary>
  540.         /// Telefon daného kontaktu.
  541.         /// </summary>
  542.         public string Telefon
  543.         {
  544.             get { return _telefon == null ? null : Sifrovani.Decrypt(_telefon); }
  545.             set { _telefon = Sifrovani.Encrypt(value); }
  546.         }
  547.  
  548.         /// <summary>
  549.         /// Web daného kontaktu.
  550.         /// </summary>
  551.         public string Web
  552.         {
  553.             get { return _web == null ? null : Sifrovani.Decrypt(_web); }
  554.             set { _web = Sifrovani.Encrypt(value); }
  555.         }
  556.  
  557.         /// <summary>
  558.         /// Skupina daného kontaktu.
  559.         /// </summary>
  560.         public string Skupina
  561.         {
  562.             get { return _skupina == null ? null : Sifrovani.Decrypt(_skupina); }
  563.             set { _skupina = Sifrovani.Encrypt(value); }
  564.         }
  565.  
  566.         /// <summary>
  567.         /// Poznámka daného kontaktu.
  568.         /// </summary>
  569.         public string Poznamka
  570.         {
  571.             get { return _poznamka == null ? null : Sifrovani.Decrypt(_poznamka); }
  572.             set { _poznamka = Sifrovani.Encrypt(value); }
  573.         }
  574.  
  575.         #endregion
  576.  
  577.         /// <summary>
  578.         /// Obyčejný konstruktor inicializující nový objekt třídy Kontakt.
  579.         /// </summary>
  580.         public Kontakt() { }
  581.  
  582.         /// <summary>
  583.         /// Tento konstruktor načítá zašifrované údaje přímo ze souboru.
  584.         /// </summary>
  585.         public Kontakt(string fotografie, string jmeno, string firma, string prezdivka, string email, string telefon, string web, string skupina, string poznamka)
  586.         {
  587.             this._fotka = fotografie;
  588.             this._jmeno = jmeno;
  589.             this._firma = firma;
  590.             this._prezdivka = prezdivka;
  591.             this._email = email;
  592.             this._telefon = telefon;
  593.             this._web = web;
  594.             this._skupina = skupina;
  595.             this._poznamka = poznamka;
  596.         }
  597.  
  598.         /// <summary>
  599.         /// Vytvoří záznam o kontaktu, který lze uložit do souboru.
  600.         /// </summary>
  601.         /// <returns>Šifrované údaje o kontaktu ve formátu, který se uloží do souboru.</returns>
  602.         internal string UlozKontakt()
  603.         {
  604.             return @_fotka + ";" + @_jmeno + ";" + @_firma + ";" + @_prezdivka + ";" + @_email + ";" + @_telefon + ";" + @_web + ";" + @_skupina + ";" + @_poznamka; // Zavináče ruší meta význam znaků, které se zde díky šifrování mohou objevit.
  605.         }
  606.     }
  607.  
  608.     /// <summary>
  609.     /// Třída implementující skupiny kontaktů.
  610.     /// </summary>
  611.     public class Skupiny : IAdresarovaStruktura
  612.     {
  613.         /// <summary>
  614.         /// Zde budeme uchovávat základní informace o skupinách.
  615.         /// </summary>
  616.         public List<Skupina> seznamSkupin;
  617.         private Prihlaseni aktualniPrihlaseni;
  618.  
  619.         /// <summary>
  620.         /// Konstruktor načte všechny skupiny ze souboru skupin. Tam máme uložená pouze základní informace, kontakty máme ke skupinám přiřazené pouze v adresáři.
  621.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení zde máme proto, abychom věděli, čí seznam skupin máme na disku hledat.</param>
  622.         /// </summary>
  623.         public Skupiny(Prihlaseni aktualniPrihlaseni)
  624.         {
  625.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  626.             seznamSkupin = new List<Skupina>();
  627.  
  628.             object soubor;
  629.  
  630.             if (!File.Exists(@aktualniPrihlaseni._email + ".groups_info"))
  631.             {
  632.                 soubor = File.Create(aktualniPrihlaseni._email + ".groups_info");
  633.                 ((FileStream)soubor).Close();
  634.             }
  635.  
  636.             soubor = new StreamReader(@aktualniPrihlaseni._email + ".groups_info");
  637.  
  638.             // Zkusíme načíst skupiny ze souboru.
  639.             try
  640.             {
  641.                 while (!((StreamReader)soubor).EndOfStream)
  642.                 {
  643.                     var jednaSkupina = ((StreamReader)soubor).ReadLine().Split(';');
  644.                     seznamSkupin.Add(new Skupina(jednaSkupina[0], jednaSkupina[1], jednaSkupina[2]));
  645.                 }
  646.             }
  647.  
  648.             // Někde je chyba, vytvoříme nový seznam skupin.
  649.             catch { seznamSkupin = new List<Skupina>(); }
  650.             finally { ((StreamReader)soubor).Close(); }
  651.         }
  652.  
  653.         /// <summary>
  654.         /// Uloží skupiny z paměti do souboru.
  655.         /// </summary>
  656.         public void Ulozit()
  657.         {
  658.             StreamWriter soubor = new StreamWriter(@aktualniPrihlaseni._email + ".groups_info");
  659.             foreach (Skupina skupina in seznamSkupin)
  660.                 soubor.WriteLine(skupina.UlozSkupinu());
  661.             soubor.Close();
  662.         }
  663.     }
  664.  
  665.     /// <summary>
  666.     /// Třída sdružující základní informace o jedné skupině.
  667.     /// </summary>
  668.     public class Skupina : IEquatable<Skupina>
  669.     {
  670.         private string _fotka;
  671.         internal string _nazev;
  672.         private string _poznamka;
  673.  
  674.         #region Definice vlastností jednotlivých parametrů.
  675.         // Všechno šifrujeme, abychom mohli údaje bezpečně uložit do souboru a nehrozilo zneužití údajů.
  676.  
  677.         /// <summary>
  678.         /// Obrázek dané skupiny.
  679.         /// </summary>
  680.         public Bitmap Fotografie
  681.         {
  682.             get { return _fotka == null ? null : Sifrovani.StringToBitmap(_fotka); }
  683.             set { _fotka = Sifrovani.BitmapToString(value); }
  684.         }
  685.  
  686.         /// <summary>
  687.         /// Název dané skupiny.
  688.         /// </summary>
  689.         public string Nazev
  690.         {
  691.             get { return _nazev == null ? null : Sifrovani.Decrypt(_nazev); }
  692.             set { _nazev = Sifrovani.Encrypt(value); }
  693.         }
  694.        
  695.  
  696.         /// <summary>
  697.         /// Poznámka dané skupiny.
  698.         /// </summary>
  699.         public string Poznamka
  700.         {
  701.             get { return _poznamka == null ? null : Sifrovani.Decrypt(_poznamka); }
  702.             set { _poznamka = Sifrovani.Encrypt(value); }
  703.         }
  704.  
  705.         #endregion
  706.  
  707.         /// <summary>
  708.         /// Obyčejný konstruktor inicializující nový objekt třídy Skupina.
  709.         /// </summary>
  710.         public Skupina() { }
  711.  
  712.         /// <summary>
  713.         /// Tento konstruktor načítá zašifrované údaje přímo ze souboru.
  714.         /// </summary>
  715.         public Skupina(string fotografie, string nazev, string poznamka)
  716.         {
  717.             this._fotka = fotografie;
  718.             this._nazev = nazev;
  719.             this._poznamka = poznamka;
  720.         }
  721.  
  722.         /// <summary>
  723.         /// Vytvoří záznam o skupině, který lze uložit do souboru.
  724.         /// </summary>
  725.         /// <returns>Šifrované údaje o skupině ve formátu, která se uloží do souboru.</returns>
  726.         internal string UlozSkupinu()
  727.         {
  728.             return @_fotka + ";" + @_nazev + ";" + @_poznamka; // Zavináče ruší meta význam znaků, které se zde díky šifrování mohou objevit.
  729.         }
  730.  
  731.         /// <summary>
  732.         /// Klaiscká implementace metody Equals.
  733.         /// </summary>
  734.         /// <param name="sCim">S čím se má porovnávat.</param>
  735.         /// <returns>True, pokud se názvy skupin shodují.</returns>
  736.         public bool Equals(Skupina sCim)
  737.         {
  738.             return sCim._nazev == _nazev;
  739.         }
  740.     }
  741. }
  742.  
  743.  
  744. using System;
  745. using System.Drawing;
  746. using System.Windows.Forms;
  747.  
  748. namespace Mail_Agent_2017
  749. {
  750.     /// <summary>
  751.     /// Okno, kde si uživatel nastavuje aplikaci.
  752.     /// </summary>
  753.     public partial class AppSettingsForm : Form
  754.     {
  755.         private Prihlaseni aktualniPrihlaseni;
  756.  
  757.         /// <summary>
  758.         /// Hlavní inicializace okna.
  759.         /// </summary>
  760.         public AppSettingsForm(Prihlaseni aktualniPrihlaseni)
  761.         {
  762.             this.Icon = BarevnyMotiv.ikona;
  763.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  764.             InitializeComponent();
  765.  
  766.             this.AktualizaceTextbox.Text = aktualniPrihlaseni.refresh.ToString();
  767.  
  768.             if (aktualniPrihlaseni.ImapPripojeni.Capabilities.Idle)
  769.             {
  770.                 this.AktualizaceTextbox.Enabled = false;
  771.                 this.InfoAktualizaceLabel.Visible = true;
  772.             }
  773.  
  774.             // Implementováno tímto způsobem, aby se daly snáz provádět změny v barevných motivech.
  775.             this.ModraButton.BackColor = (Color)BarevnyMotiv.NastavBarvyTlacitek(BarevnyMotiv.BarevnaPaleta.Modra);
  776.             this.CervenaButton.BackColor = (Color)BarevnyMotiv.NastavBarvyTlacitek(BarevnyMotiv.BarevnaPaleta.Cervena);
  777.             this.ZelenaButton.BackColor = (Color)BarevnyMotiv.NastavBarvyTlacitek(BarevnyMotiv.BarevnaPaleta.Zelena);
  778.             this.SedaButton.BackColor = (Color)BarevnyMotiv.NastavBarvyTlacitek(BarevnyMotiv.BarevnaPaleta.Seda);
  779.             this.CernaButton.BackColor = (Color)BarevnyMotiv.NastavBarvyTlacitek(BarevnyMotiv.BarevnaPaleta.Cerna);
  780.             this.ZlutaButton.BackColor = (Color)BarevnyMotiv.NastavBarvyTlacitek(BarevnyMotiv.BarevnaPaleta.Zluta);
  781.         }
  782.  
  783.         /// <summary>
  784.         /// Zavře okno.
  785.         /// </summary>
  786.         private void ZavritButton_Click(object sender, EventArgs e)
  787.         {
  788.             if (AktualizaceTextbox.Enabled && int.Parse(AktualizaceTextbox.Text) > 840 && int.Parse(AktualizaceTextbox.Text) < 120)
  789.             {
  790.                 MessageBox.Show("Interval automatické aktualizace musí být mezi 120 a 840 sekundami.");
  791.                 return;
  792.             }
  793.             aktualniPrihlaseni.refresh = int.Parse(AktualizaceTextbox.Text);
  794.             this.Close();
  795.         }
  796.  
  797.         /// <summary>
  798.         /// Obsluha tlačítek, které mění barevný motiv.
  799.         /// </summary>
  800.         private void NastavBarvu_Click(object sender, EventArgs e)
  801.         {
  802.             // Nastavujeme podle tab indexu tlačítka, který reprezentuje danou barvu. Celkem neobvyklé, ale funkční a jednoduché.
  803.             BarevnyMotiv.Barva = (BarevnyMotiv.BarevnaPaleta)Enum.ToObject(typeof(BarevnyMotiv.BarevnaPaleta), ((Button)sender).TabIndex);
  804.             this.ZavritButton.BackColor = BarevnyMotiv.barvaTlacitek;
  805.             this.Icon = BarevnyMotiv.ikona;
  806.             this.Invalidate();
  807.         }
  808.     }
  809. }
  810.  
  811.  
  812. using System;
  813. using System.Collections.Generic;
  814. using System.Linq;
  815. using System.Windows.Forms;
  816.  
  817. namespace Mail_Agent_2017
  818. {
  819.     /// <summary>
  820.     /// Toto okno se zobrazí, pokud chce uživatel přidat k e-mailu nějakou přílohu.
  821.     /// </summary>
  822.     public partial class AttachmentForm : Form
  823.     {
  824.         internal List<Priloha> seznamPriloh;
  825.  
  826.         /// <summary>
  827.         /// Inicializace nejdůležitějších komponent pro toto okno.
  828.         /// </summary>
  829.         public AttachmentForm()
  830.         {
  831.             this.Icon = BarevnyMotiv.ikona;
  832.             InitializeComponent();
  833.             seznamPriloh = new List<Priloha>();
  834.             InicializujNovouPrilohu(null);
  835.         }
  836.  
  837.         /// <summary>
  838.         /// Skryje toto okno.
  839.         /// </summary>
  840.         private void PridatButton_Click(object sender, EventArgs e)
  841.         {
  842.             this.Hide();
  843.         }
  844.  
  845.         /// <summary>
  846.         /// Inicializuje nové ovládací prvky, díky nim může uživatel přidat novou přílohu. Zároveň upravuje GUI.
  847.         /// </summary>
  848.         /// <param name="cesta">Cesta k souboru, v případě, že se jedná o již načtenou přílohu.</param>
  849.         public virtual void InicializujNovouPrilohu(object cesta)
  850.         {
  851.             try
  852.             {
  853.                 // Není vhodné posílat příliš mnoho souborů emailem. Navíc, kdybychom přidávali přílohy do nekonečna, dostali bychom se s GUI mimo obrazovku.
  854.                 if (seznamPriloh.Count == 10)
  855.                     throw new PrilisMnohoPrilohException("Byl dosažen maximální počet příloh u jednoho emailu.");
  856.  
  857.                 // Posune celé GUI.
  858.                 if (seznamPriloh.Count > 5)
  859.                 {
  860.                     this.ClientSize = new System.Drawing.Size(384, this.ClientSize.Height + 36);
  861.                     this.PridatButton.Location = new System.Drawing.Point(90, this.PridatButton.Location.Y + 36);
  862.                 }                    
  863.  
  864.                 // Přidáme ovládací prvky dané přílohy do seznamu, abychom k nim mohli snadno přistupovat.
  865.                
  866.                 this.seznamPriloh.Add((cesta == null) ? new Priloha(this, seznamPriloh.Count) : new Priloha(this, seznamPriloh.Count, cesta));
  867.             }
  868.             catch (Exception ex)
  869.             {
  870.                 if (ex is PrilisMnohoPrilohException)
  871.                     MessageBox.Show(ex.Message);
  872.             }      
  873.         }
  874.  
  875.         /// <summary>
  876.         /// Odstraní existující přílohu a to tak, že danou přílohu odebere ze seznamu příloh a celý seznam posune, také upravuje GUI.
  877.         /// </summary>
  878.         /// <param name="kolikataPriloha">Index přílohy, která se má odstranit.</param>
  879.         internal void OdstranExistujiciPrilohu(int kolikataPriloha)
  880.         {
  881.             // V každém případě danou přílohu odstraníme ze seznamu a všechny přílohy posuneme o jedno políčko směrem nahoru.
  882.             seznamPriloh.GetRange(kolikataPriloha + 1, seznamPriloh.Count - kolikataPriloha - 1).ForEach(priloha =>
  883.             {
  884.                 priloha.label.Location = new System.Drawing.Point(152, priloha.label.Location.Y - 36);
  885.                 priloha.tlacitko.Location = new System.Drawing.Point(16, priloha.tlacitko.Location.Y - 36);                
  886.             });
  887.            
  888.             // A pokud jsme kvůli přílohám zvětšovali okno, tak ho zase zmenšíme.
  889.             if (seznamPriloh.Count > 5)
  890.             {
  891.                 this.PridatButton.Location = new System.Drawing.Point(90, this.PridatButton.Location.Y - 36);
  892.                 this.ClientSize = new System.Drawing.Size(384, this.ClientSize.Height - 36);
  893.             }
  894.  
  895.             // Uvolnění resourců, aby prvky smazané přílohy nezůstaly na pozadí a nezabíraly tak zbytečně paměť.
  896.             seznamPriloh[kolikataPriloha].Dispose();
  897.             seznamPriloh.RemoveAt(kolikataPriloha);
  898.  
  899.             // Pokud jsme odebrali poslední přílohu, musíme přidat tlačítko na přidání nové.
  900.             if (seznamPriloh.Count == 9 && seznamPriloh.Last().label.Text != "...")
  901.                 InicializujNovouPrilohu(null);
  902.         }
  903.  
  904.         /// <summary>
  905.         /// Definice třídy příloh, každá příloha se skládá z trojice - tlačítko, label a OpenFileDialog objekt.
  906.         /// </summary>
  907.         internal class Priloha : IDisposable
  908.         {
  909.             public Button tlacitko;
  910.             public Label label;
  911.             public OpenFileDialog soubor;
  912.             internal ImapX.Attachment priloha;
  913.             protected AttachmentForm okno;
  914.  
  915.             /// <summary>
  916.             /// Zde probíhá inicializace ovládacích prvků.
  917.             /// </summary>
  918.             /// <param name="okno">Vzhledem k tomu, že se jedná o interní třídu ve třídě, tak nemůžeme použít this na vnější třídu. Vlastnosti okna musíme třídě předat jako parametr.</param>
  919.             /// <param name="kolikataPriloha">Určuje, o kolikátou přílohu se jedná a dle toho umisťuje ovládací prvky.</param>
  920.             public Priloha(AttachmentForm okno, int kolikataPriloha)
  921.             {
  922.                 this.okno = okno;
  923.                 this.tlacitko = new System.Windows.Forms.Button();
  924.                 this.label = new System.Windows.Forms.Label();
  925.                 this.soubor = new System.Windows.Forms.OpenFileDialog();
  926.  
  927.                 #region Inicializace ovládacích prvků
  928.                 okno.SuspendLayout();
  929.                
  930.                 // Inicializuje tlačítko
  931.                 this.tlacitko.BackColor = BarevnyMotiv.barvaTlacitek;
  932.                 this.tlacitko.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  933.                 this.tlacitko.Font = new System.Drawing.Font("Calibri", 11F, System.Drawing.FontStyle.Bold);
  934.                 this.tlacitko.ForeColor = System.Drawing.Color.White;
  935.                 this.tlacitko.Location = new System.Drawing.Point(16, 100 + kolikataPriloha * 36);
  936.                 this.tlacitko.Size = new System.Drawing.Size(130, 28);
  937.                 this.tlacitko.TabIndex = kolikataPriloha;
  938.                 this.tlacitko.Text = "Vybrat ze souboru";
  939.                 this.tlacitko.UseVisualStyleBackColor = false;
  940.                 this.tlacitko.Click += new EventHandler(this.OtevriSoubor);
  941.  
  942.                 // Inicializuje label
  943.                 this.label.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  944.                 this.label.Font = new System.Drawing.Font("Calibri", 12F);
  945.                 this.label.Location = new System.Drawing.Point(152, 100 + kolikataPriloha * 36);
  946.                 this.label.Size = new System.Drawing.Size(220, 28);
  947.                 this.label.Text = "...";
  948.                 this.label.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
  949.                 okno.ResumeLayout();
  950.                 #endregion
  951.  
  952.                 okno.Controls.Add(this.tlacitko);
  953.                 okno.Controls.Add(this.label);
  954.             }
  955.  
  956.             /// <summary>
  957.             /// Rozšířený konstruktor, pokud již příloha existuje a známe k ní cestu.
  958.             /// </summary>
  959.             /// <param name="okno">Vzhledem k tomu, že se jedná o interní třídu ve třídě, tak nemůžeme použít this na vnější třídu. Vlastnosti okna musíme třídě předat jako parametr.</param>
  960.             /// <param name="kolikataPriloha">Určuje, o kolikátou přílohu se jedná a dle toho umisťuje ovládací prvky.</param>
  961.             /// <param name="cesta">Cesta ve filesystému k dané příloze.</param>
  962.             public Priloha(AttachmentForm okno, int kolikataPriloha, object cesta) : this(okno, kolikataPriloha)
  963.             {
  964.                 string temp;
  965.                 this.tlacitko.Text = "Odstranit";
  966.                 this.priloha = ((ImapX.Attachment)cesta);
  967.                 this.tlacitko.Click -= new EventHandler(this.OtevriSoubor);
  968.                 this.tlacitko.Click += new EventHandler(this.OdstranPrilohu);
  969.  
  970.                 if (cesta is ImapX.Attachment)
  971.                 {
  972.                     try { ((ImapX.Attachment)cesta).Download(); }
  973.                     catch { }
  974.                    
  975.                     temp = ((ImapX.Attachment)cesta).FileName;
  976.                 }
  977.                    
  978.  
  979.                 else temp = cesta.ToString();
  980.  
  981.                 this.label.Text = "..\u005c" + temp.ToString().Split('\u005c').ToList().Last(); // V labelu zobrazíme pouze název souboru.
  982.             }
  983.  
  984.             /// <summary>
  985.             /// Obsluha tlačítka, které přidává přílohu.
  986.             /// </summary>
  987.             protected virtual void OtevriSoubor(object sender, EventArgs e)
  988.             {
  989.                 if (this.soubor.ShowDialog() == DialogResult.OK)
  990.                 {
  991.                     this.tlacitko.Text = "Odstranit";
  992.                     this.label.Text = "..\u005c" + this.soubor.FileName.ToString().Split('\u005c').ToList().Last(); // V labelu zobrazíme pouze název souboru.
  993.  
  994.                     // Tlačítko přidat měníme na tlačítko odstranit, musíme upravit obsluhy daného tlačítka.
  995.                     this.tlacitko.Click -= new EventHandler(this.OtevriSoubor);
  996.                     this.tlacitko.Click += new EventHandler(this.OdstranPrilohu);
  997.  
  998.                     // Přidáme možnost přidání nové přílohy.
  999.                     okno.InicializujNovouPrilohu(null);
  1000.                 }
  1001.             }
  1002.  
  1003.             /// <summary>
  1004.             /// Obsluha tlačítka, které odebírá přílohu.
  1005.             /// </summary>
  1006.             private void OdstranPrilohu(object sender, EventArgs e)
  1007.             {
  1008.                 if (MessageBox.Show("Opravdu chcete odstranit tuto přílohu?", "Odstranit", MessageBoxButtons.YesNo) == DialogResult.Yes)
  1009.                 {
  1010.                     this.tlacitko.Text = "Vybrat ze souboru";
  1011.                     this.label.Text = "...";
  1012.                     this.soubor = new System.Windows.Forms.OpenFileDialog();
  1013.  
  1014.                     // Tlačítko odstranit měníme na tlačítko přidat, musíme upravit obsluhy daného tlačítka.
  1015.                     this.tlacitko.Click -= new EventHandler(this.OdstranPrilohu);
  1016.                     this.tlacitko.Click += new EventHandler(this.OtevriSoubor);
  1017.  
  1018.                     okno.OdstranExistujiciPrilohu((this.label.Location.Y - 100) / 36); // O kolikátou přílohu se jedná, poznáme podle její pozice.
  1019.                 }
  1020.             }
  1021.  
  1022.             /// <summary>
  1023.             /// Klasická implementace metody Dispose.
  1024.             /// Disposuje všechny tři elementy tohoto objektu.
  1025.             /// </summary>
  1026.             public void Dispose()
  1027.             {
  1028.                 this.tlacitko.Dispose();
  1029.                 this.label.Dispose();
  1030.                 this.soubor.Dispose();
  1031.             }
  1032.         }        
  1033.     }
  1034. }
  1035.  
  1036. using System;
  1037. using System.Collections.Generic;
  1038. using System.IO;
  1039. using System.Linq;
  1040. using System.Text;
  1041.  
  1042. namespace Mail_Agent_2017
  1043. {
  1044.     /// <summary>
  1045.     /// Okno na vytváření konceptů.
  1046.     /// </summary>
  1047.     public class ConceptForm : SendForm
  1048.     {
  1049.         /// <summary>
  1050.         /// Konstruktor jen lehce pozmění GUI třídy SendForm.
  1051.         /// </summary>
  1052.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení.</param>
  1053.         public ConceptForm(Prihlaseni aktualniPrihlaseni) : base (aktualniPrihlaseni)
  1054.         {
  1055.             this.Name = "ConceptForm";
  1056.             this.Text = "Mail Agent 2017 - Nový koncept";
  1057.             PrilohyButton.Location = KonceptButton.Location;
  1058.             PrilohaLabel.Location = new System.Drawing.Point(PrilohyButton.Location.X + PrilohyButton.Size.Width + 15, PrilohaLabel.Location.Y);
  1059.             SendButton.Visible = false;
  1060.             KonceptButton.Location = SendButton.Location;
  1061.             KonceptButton.Size = SendButton.Size;
  1062.         }
  1063.     }
  1064. }
  1065.  
  1066. using System;
  1067. using System.Drawing;
  1068. using System.Windows.Forms;
  1069.  
  1070. namespace Mail_Agent_2017
  1071. {
  1072.     /// <summary>
  1073.     /// Okno na přidávání, zobrazení a editaci kontaktů.
  1074.     /// </summary>
  1075.     public partial class ContactForm : Form
  1076.     {
  1077.         /// <summary>
  1078.         /// Kontakt, který se v tomto formuláři vytvoří/edituje.
  1079.         /// </summary>
  1080.         public Kontakt novyKontakt;
  1081.  
  1082.         /// <summary>
  1083.         /// Aktuální přihlášení.
  1084.         /// </summary>
  1085.         protected Prihlaseni aktualniPrihlaseni;
  1086.  
  1087.         /// <summary>
  1088.         /// Konstruktor, který se nesmí nikdy zavolat. Máme ho zde kvůli polymorfismu, jinak by to nefungovalo.
  1089.         /// </summary>
  1090.         protected ContactForm() { }
  1091.  
  1092.         /// <summary>
  1093.         /// Základní inicializace nového kontaktu.
  1094.         /// </summary>
  1095.         public ContactForm(Prihlaseni aktualniPrihlaseni)
  1096.         {
  1097.             this.Icon = BarevnyMotiv.ikona;
  1098.             InitializeComponent();
  1099.             InitializeEditComponent();
  1100.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  1101.             novyKontakt = new Kontakt { Fotografie = (Bitmap)FotografiePicturebox.Image };
  1102.  
  1103.             SkupinaCombobox.Items.Add("");
  1104.             foreach (Skupina skupina in new Skupiny(aktualniPrihlaseni).seznamSkupin)
  1105.                 SkupinaCombobox.Items.Add(skupina.Nazev);
  1106.             this.SkupinaCombobox.SelectedIndex = 0;
  1107.  
  1108.             this.Text = "Mail Agent 2017 - Vytvořit kontakt";
  1109.             this.HlavniButton.Text = "Vytvořit kontakt";
  1110.         }
  1111.  
  1112.         /// <summary>
  1113.         /// Základní inicializace existujícího kontaktu.
  1114.         /// </summary>
  1115.         /// <param name="kontakt">Kontakt, který se bude editovat.</param>
  1116.         /// <param name="pouzeZobrazit">Rozhoduje, zdali se má zobrazit formulář, pomocí kterého lze kontakt editovat, nebo pouze zobrazit kontakt.</param>
  1117.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení.</param>
  1118.         public ContactForm(Kontakt kontakt, bool pouzeZobrazit, Prihlaseni aktualniPrihlaseni)
  1119.         {
  1120.             this.Icon = BarevnyMotiv.ikona;
  1121.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  1122.             InitializeComponent();
  1123.            
  1124.             if (pouzeZobrazit) // Pokud uživatel klikl na tlačítko "Pouze zobrazit", nedovolíme mu kontakt měnit.
  1125.             {
  1126.                 InitializeShowComponent();
  1127.                 FotografiePicturebox.Image = kontakt.Fotografie;
  1128.                 JmenoInputLabel.Text = kontakt.Jmeno;
  1129.                 FirmaInputLabel.Text = kontakt.Firma;
  1130.                 PrezdivkaInputLabel.Text = kontakt.Prezdivka;
  1131.                 EmailInputLabel.Text = kontakt.Email;
  1132.                 WebInputLabel.Text = kontakt.Web;
  1133.                 SkupinaInputLabel.Text = kontakt.Skupina;
  1134.                 PoznamkaInputLabel.Text = kontakt.Poznamka;
  1135.                 TelefonInputLabel.Text = kontakt.Telefon;
  1136.  
  1137.                 foreach (Skupina skupina in new Skupiny(aktualniPrihlaseni).seznamSkupin) if (skupina.Nazev == kontakt.Skupina)
  1138.                     SkupinaInputLabel.Text = kontakt.Skupina;
  1139.             }
  1140.  
  1141.             else // Jinak se jedná o možnost editace kontaktu. Toto je analogické jako tvorba nového kontaktu, akorát budou nějaké textboxy předvyplněné na základě údajů o kontaktu.
  1142.             {
  1143.                 InitializeEditComponent();
  1144.                 this.novyKontakt = kontakt;
  1145.  
  1146.                 EmailTextbox.Text = novyKontakt.Email;
  1147.                 FirmaTextbox.Text = novyKontakt.Firma;
  1148.                 JmenoTextbox.Text = novyKontakt.Jmeno;
  1149.                 PoznamkaTextbox.Text = novyKontakt.Poznamka;
  1150.                 PrezdivkaTextbox.Text = novyKontakt.Prezdivka;
  1151.                 WebTextbox.Text = novyKontakt.Web;
  1152.                 TelefonTextbox.Text = novyKontakt.Telefon;
  1153.                 FotografiePicturebox.Image = novyKontakt.Fotografie;
  1154.  
  1155.                 SkupinaCombobox.Items.Add(novyKontakt.Skupina);
  1156.                 if (novyKontakt.Skupina != "") SkupinaCombobox.Items.Add("");
  1157.  
  1158.                 foreach (Skupina skupina in new Skupiny(aktualniPrihlaseni).seznamSkupin) if (SkupinaCombobox.Items[0].ToString() != skupina.Nazev)
  1159.                     SkupinaCombobox.Items.Add(skupina.Nazev);
  1160.                 this.SkupinaCombobox.SelectedIndex = 0;
  1161.  
  1162.                 this.Text = "Mail Agent 2017 - Upravit kontakt";
  1163.                 this.HlavniButton.Text = "Upravit kontakt";
  1164.             }
  1165.         }
  1166.  
  1167.         /// <summary>
  1168.         /// Tlačítko, které dá uživateli možnost zvolit fotografii kontaktu.
  1169.         /// </summary>
  1170.         protected virtual void FotografieButton_Click(object sender, EventArgs e)
  1171.         {
  1172.             OpenFileDialog soubor = new OpenFileDialog();
  1173.             if (soubor.ShowDialog() == DialogResult.OK)
  1174.             {
  1175.                 Bitmap temp = new Bitmap(soubor.FileName);
  1176.  
  1177.                 // Nyní naškálujeme fotku na velikost maximálně 128x128.
  1178.                 try
  1179.                 {
  1180.                     int pomer = Math.Max(temp.Width / 128, temp.Height / 128);
  1181.                     novyKontakt.Fotografie = new Bitmap(temp, new Size(temp.Width / pomer, temp.Height / pomer));
  1182.                 }
  1183.                 catch (DivideByZeroException) { novyKontakt.Fotografie = temp; } // Pokud jsou rozměry menší než 128x128, vložíme fotku v plné velikosti.
  1184.                 finally { FotografiePicturebox.Image = novyKontakt.Fotografie;  }                
  1185.  
  1186.                 this.Invalidate();
  1187.             }
  1188.                
  1189.         }
  1190.  
  1191.         /// <summary>
  1192.         /// Tlačítko, které kontroluje chyby a přidává/vrací kontakt do adresáře, respektive vrací ho otcovskému oknu.
  1193.         /// </summary>
  1194.         protected virtual void PridatNeboEditovat_Click(object sender, EventArgs e)
  1195.         {
  1196.             try
  1197.             {
  1198.                 if (string.IsNullOrEmpty(JmenoTextbox.Text))
  1199.                     throw new ChybneZadaniException("Jméno musí být vyplněno.");
  1200.  
  1201.                 if (string.IsNullOrEmpty(EmailTextbox.Text))
  1202.                     throw new ChybneZadaniException("E-mail musí být vyplněn.");
  1203.  
  1204.                 if (!Utility.SpravnyFormatAdresy(EmailTextbox.Text))
  1205.                     throw new ChybneZadaniException("E-mailová adresa má nesprávný formát.");
  1206.             }
  1207.  
  1208.             catch (ChybneZadaniException ex)
  1209.             {
  1210.                 ChyboveOknoLabel.Show();
  1211.                 ChyboveOknoLabel.Text = ex.Message;
  1212.                 ZobrazeniChybyTimer.Enabled = true;
  1213.                 return;
  1214.             }
  1215.  
  1216.             novyKontakt.Email = EmailTextbox.Text;
  1217.             novyKontakt.Firma = FirmaTextbox.Text;
  1218.             novyKontakt.Jmeno = JmenoTextbox.Text;
  1219.             novyKontakt.Poznamka = PoznamkaTextbox.Text;
  1220.             novyKontakt.Prezdivka = PrezdivkaTextbox.Text;
  1221.             novyKontakt.Web = WebTextbox.Text;
  1222.             novyKontakt.Telefon = TelefonTextbox.Text;
  1223.             novyKontakt.Skupina = SkupinaCombobox.SelectedItem == null ? "" : SkupinaCombobox.SelectedItem.ToString();
  1224.  
  1225.             this.DialogResult = DialogResult.OK;
  1226.             this.Close();
  1227.         }
  1228.  
  1229.         /// <summary>
  1230.         /// Zavře okno s kontaktem.
  1231.         /// </summary>
  1232.         protected void Zavrit_Click(object sender, EventArgs e)
  1233.         {
  1234.             this.Close();
  1235.         }
  1236.  
  1237.         /// <summary>
  1238.         /// Otevře okno, které odešle danému kontaktu e-mail.
  1239.         /// </summary>
  1240.         private void SendButton_Click(object sender, EventArgs e)
  1241.         {
  1242.             new SendForm(aktualniPrihlaseni, ((Label)sender).Text).ShowDialog();
  1243.         }
  1244.  
  1245.         /// <summary>
  1246.         /// Po kliknutí na webový odkaz zobrazí webovou stránku tím stylem, že se otevře v defaultním webovém prohlížeči.
  1247.         /// </summary>
  1248.         private void ZobrazitWeb(object sender, EventArgs e)
  1249.         {
  1250.             if (MessageBox.Show("Aplikace se pokouší zobrazit webovou stránku. Chcete pokračovat?", "Zobrazit webovou stránku", MessageBoxButtons.YesNo) == DialogResult.Yes)
  1251.                 System.Diagnostics.Process.Start(((Label)sender).Text);
  1252.         }
  1253.  
  1254.         /// <summary>
  1255.         /// Skryje chybovou hlášku po uplynutí deseti sekund.
  1256.         /// </summary>
  1257.         protected void ZobrazeniChybyTimer_Tick(object sender, EventArgs e)
  1258.         {
  1259.             ZobrazeniChybyTimer.Enabled = false;
  1260.             ChyboveOknoLabel.Hide();
  1261.         }
  1262.  
  1263.     }
  1264. }
  1265.  
  1266.  
  1267. using System;
  1268. using System.Collections.Generic;
  1269. using System.IO;
  1270.  
  1271. namespace Mail_Agent_2017
  1272. {
  1273.     /// <summary>
  1274.     /// Třída seskupující informace o jednotlivých e-mail service providerech.
  1275.     /// Umožňuje uživateli jednodušší přihlášení ke své e-mailové schránce.
  1276.     /// V případě, že uživatel využívá ESP, který není v seznamu, tak se po prvním úspěšném přihlášení do tohoto seznamu zapíše.
  1277.     /// </summary>
  1278.     class ESP
  1279.     {
  1280.         private List<ESP_Zaznam> seznam;  
  1281.        
  1282.         /// <summary>
  1283.         /// Konstruktor načte údaje o všech ESP z tabulky, která je uložena v souboru.
  1284.         /// </summary>
  1285.         public ESP()
  1286.         {
  1287.             this.seznam = new List<ESP_Zaznam>();
  1288.             StreamReader esp_seznam = new StreamReader(".esp_info");
  1289.  
  1290.             while (!esp_seznam.EndOfStream)
  1291.             {
  1292.                 string[] zaznam = esp_seznam.ReadLine().Split(';');
  1293.                 seznam.Add(new ESP_Zaznam(zaznam[0], zaznam[1], int.Parse(zaznam[2]), bool.Parse(zaznam[3]),
  1294.                                           zaznam[4], int.Parse(zaznam[5]), bool.Parse(zaznam[6]), bool.Parse(zaznam[7])));
  1295.             }
  1296.  
  1297.             esp_seznam.Close();
  1298.         }
  1299.  
  1300.         /// <summary>
  1301.         /// Třída zahrnující informace o e-mail service providerovi.
  1302.         /// </summary>
  1303.         internal class ESP_Zaznam : IEquatable<ESP_Zaznam>
  1304.         {
  1305.             public string nazev;
  1306.             public string ImapServer;
  1307.             public int ImapPort;
  1308.             public bool ImapSsl;
  1309.             public string SmtpServer;
  1310.             public int SmtpPort;
  1311.             public bool SmtpSsl;
  1312.             public bool SmtpAuth;
  1313.  
  1314.             /// <summary>
  1315.             /// Klasický konstruktor, inicializuje celý objekt dle vstupních hodnot.
  1316.             /// </summary>
  1317.             public ESP_Zaznam(string nazev, string ImapServer, int ImapPort, bool ImapSsl, string SmtpServer, int SmtpPort, bool SmtpSsl, bool SmtpAuth)
  1318.             {
  1319.                 this.nazev = nazev;
  1320.                 this.ImapServer = ImapServer;
  1321.                 this.ImapPort = ImapPort;
  1322.                 this.ImapSsl = ImapSsl;
  1323.                 this.SmtpServer = SmtpServer;
  1324.                 this.SmtpPort = SmtpPort;
  1325.                 this.SmtpSsl = SmtpSsl;
  1326.                 this.SmtpAuth = SmtpAuth;
  1327.  
  1328.             }
  1329.  
  1330.             /// <summary>
  1331.             /// Klasická implementace metody Equals.
  1332.             /// </summary>
  1333.             public bool Equals(ESP_Zaznam zaznam)
  1334.             {
  1335.                 return this.nazev == zaznam.nazev;
  1336.             }
  1337.         }
  1338.  
  1339.         /// <summary>
  1340.         /// Metoda, která hledá ESP uživatele v tabulce známých ESP.
  1341.         /// </summary>
  1342.         /// <param name="nazev">E-mail service provider uživatele</param>
  1343.         /// <returns>E-mail service provider uživatele</returns>
  1344.         public ESP_Zaznam NajdiVhodnehoESP(string nazev)
  1345.         {
  1346.             foreach (ESP_Zaznam esp in seznam) if (esp.nazev == nazev)
  1347.                     return esp;
  1348.             return null;
  1349.         }
  1350.  
  1351.         /// <summary>
  1352.         /// Metoda, která přidává nový záznam o ESP do tabulky známých ESP.
  1353.         /// </summary>
  1354.         public void PridejZaznamOESP(string nazev, string ImapServer, int ImapPort, bool ImapSsl, string SmtpServer, int SmtpPort, bool SmtpSsl, bool SmtpAuth)
  1355.         {
  1356.             seznam.Add(new ESP_Zaznam(nazev, ImapServer, ImapPort, ImapSsl, SmtpServer, SmtpPort, SmtpSsl, SmtpAuth));
  1357.             TextWriter esp_seznam = new StreamWriter(".esp_info", true);
  1358.             esp_seznam.WriteLine("{0};{1};{2};{3};{4};{5};{6};{7}", nazev, ImapServer, ImapPort,
  1359.                                  ImapSsl, SmtpServer, SmtpPort, SmtpSsl, SmtpAuth);
  1360.             esp_seznam.Close();
  1361.         }
  1362.     }    
  1363. }
  1364.  
  1365. using System;
  1366. using System.Collections.Generic;
  1367. using System.Drawing;
  1368. using System.IO;
  1369. using System.Windows.Forms;
  1370.  
  1371. namespace Mail_Agent_2017
  1372. {
  1373.     /// <summary>
  1374.     /// Okno pro editaci složek.
  1375.     /// </summary>
  1376.     public partial class FolderForm : Form
  1377.     {
  1378.         private Prihlaseni aktualniPrihlaseni;
  1379.         internal List<string> slozky;
  1380.         private List<JednaSlozka> ovladaciPrvky;
  1381.  
  1382.         internal ImapX.Folder kamPresunout;
  1383.  
  1384.         /// <summary>
  1385.         /// Inicializace nejdůležitějších komponent pro toto okno.
  1386.         /// </summary>
  1387.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení.</param>
  1388.         /// <param name="presunout">Tento parametr se nastavuje, pokud chceme přesunout e-mail do nějaké existující složky.</param>
  1389.         public FolderForm(Prihlaseni aktualniPrihlaseni, bool presunout)
  1390.         {
  1391.             this.Icon = BarevnyMotiv.ikona;
  1392.             InitializeComponent();
  1393.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  1394.             ovladaciPrvky = new List<JednaSlozka>();
  1395.  
  1396.             // Pokud chceme e-mail přesunout, odebereme tlačítko na vytvoření nové složky. A také přidáme do seznamu klasické složky.
  1397.             if (presunout)
  1398.             {
  1399.                 this.VytvoritButton.Visible = false;
  1400.                 this.ZavritButton.Visible = false;
  1401.                 this.Size = new Size(this.Width + 68, this.Height - 35);
  1402.  
  1403.                 ovladaciPrvky.Add(new JednaSlozka("Doručená pošta", ovladaciPrvky.Count, this, true));
  1404.                 ovladaciPrvky.Add(new JednaSlozka("Označená pošta", ovladaciPrvky.Count, this, true));
  1405.                 ovladaciPrvky.Add(new JednaSlozka("Důležitá pošta", ovladaciPrvky.Count, this, true));
  1406.                 ovladaciPrvky.Add(new JednaSlozka("Odeslaná pošta", ovladaciPrvky.Count, this, true));
  1407.                 ovladaciPrvky.Add(new JednaSlozka("Koncepty", ovladaciPrvky.Count, this, true));
  1408.                 ovladaciPrvky.Add(new JednaSlozka("Nevyžádaná pošta", ovladaciPrvky.Count, this, true));
  1409.                 ovladaciPrvky.Add(new JednaSlozka("Koš", ovladaciPrvky.Count, this, true));
  1410.             }
  1411.  
  1412.             slozky = NacistSlozky();
  1413.  
  1414.             foreach (var slozka in slozky)
  1415.                 ovladaciPrvky.Add(new JednaSlozka(slozka, ovladaciPrvky.Count, this, presunout));
  1416.         }
  1417.        
  1418.  
  1419.         /// <summary>
  1420.         /// Vytvoří novou složku.
  1421.         /// </summary>
  1422.         private void VytvoritButton_Click(object sender, EventArgs e)
  1423.         {
  1424.             string nazev;
  1425.             try
  1426.             {
  1427.                 if ((nazev = new Prompt().ShowDialog("Zadejte název nové složky.", "Mail Agent 2017 - Vytvořit novou složku", 20)) == null)
  1428.                     throw new ChybneZadaniException();
  1429.             }
  1430.             catch
  1431.                 { return; }
  1432.  
  1433.             aktualniPrihlaseni.ImapPripojeni.Folders.Add(nazev);
  1434.             ovladaciPrvky.Add(new JednaSlozka(nazev, slozky.Count, this, false));
  1435.             slozky.Add(nazev);
  1436.         }
  1437.  
  1438.         /// <summary>
  1439.         /// Odstraní danou složku.
  1440.         /// </summary>
  1441.         /// <param name="kolikata">Kolikátá skupina v pořadí se má smazat.</param>
  1442.         private void OdstranSlozku(int kolikata)
  1443.         {
  1444.             // Všechny složky musíme posunout směrem nahoru.
  1445.             ovladaciPrvky.GetRange(kolikata + 1, ovladaciPrvky.Count - kolikata - 1).ForEach(slozka =>
  1446.             {
  1447.                 slozka.SlozkaLabel.Location = new System.Drawing.Point(slozka.SlozkaLabel.Location.X, slozka.SlozkaLabel.Location.Y - 38);
  1448.                 slozka.DeleteButton.Location = new System.Drawing.Point(slozka.DeleteButton.Location.X, slozka.DeleteButton.Location.Y - 38);
  1449.                 slozka.SlozkaPicturebox.Location = new System.Drawing.Point(slozka.SlozkaPicturebox.Location.X, slozka.SlozkaPicturebox.Location.Y - 38);
  1450.             });
  1451.  
  1452.             try { aktualniPrihlaseni.ImapPripojeni.Folders[ovladaciPrvky[kolikata].slozka].Remove(); }
  1453.             catch { }
  1454.  
  1455.             // Uvolnění resourců, aby prvky smazané složky nezůstaly na pozadí a nezabíraly tak zbytečně paměť.
  1456.             ovladaciPrvky[kolikata].Dispose();
  1457.             slozky.RemoveAt(kolikata);
  1458.             UlozitSlozky();
  1459.            
  1460.         }
  1461.  
  1462.         /// <summary>
  1463.         /// Načte údaje od složkách do paměti.
  1464.         /// </summary>
  1465.         /// <returns></returns>
  1466.         private List<string> NacistSlozky()
  1467.         {
  1468.             List<string> nacteneSlozky = new List<string>();
  1469.  
  1470.             object soubor;
  1471.  
  1472.             if (!File.Exists(@aktualniPrihlaseni._email + ".folders_info"))
  1473.             {
  1474.                 soubor = File.Create(@aktualniPrihlaseni._email + ".folders_info");
  1475.                 ((FileStream)soubor).Close();
  1476.             }
  1477.  
  1478.             soubor = new StreamReader(@aktualniPrihlaseni._email + ".folders_info");
  1479.  
  1480.             // Zkusíme načíst složky ze souboru.
  1481.             try
  1482.             {
  1483.                 while (!((StreamReader)soubor).EndOfStream)
  1484.                     nacteneSlozky.Add(Sifrovani.Decrypt(((StreamReader)soubor).ReadLine())); // U názvů složek to se šifrováním nebudeme přehánět. Budou zašifrované jen v souboru.
  1485.             }
  1486.  
  1487.             // Někde je chyba, vytvoříme nový adresář.
  1488.             catch { nacteneSlozky = new List<string>(); }
  1489.             finally { ((StreamReader)soubor).Close(); }
  1490.  
  1491.             return nacteneSlozky;
  1492.         }
  1493.  
  1494.         /// <summary>
  1495.         /// Uloží údaje o složkách do souboru.
  1496.         /// </summary>
  1497.         internal void UlozitSlozky()
  1498.         {
  1499.             StreamWriter soubor = new StreamWriter(@aktualniPrihlaseni._email + ".folders_info");
  1500.             foreach (var slozka in slozky) soubor.WriteLine(Sifrovani.Encrypt(slozka));
  1501.             soubor.Close();
  1502.         }
  1503.  
  1504.         /// <summary>
  1505.         /// Zavře okno se složkami.
  1506.         /// </summary>
  1507.         private void ZavritButton_Click(object sender, EventArgs e)
  1508.         {
  1509.             this.DialogResult = DialogResult.OK;
  1510.             this.Close();
  1511.         }
  1512.  
  1513.         /// <summary>
  1514.         /// Třída sloužící k inicializaci jedné složky v okně.
  1515.         /// </summary>
  1516.         internal class JednaSlozka : IDisposable
  1517.         {
  1518.             internal string slozka;
  1519.             private FolderForm okno;
  1520.             private int kolikataSlozka;
  1521.  
  1522.             internal System.Windows.Forms.Label SlozkaLabel;
  1523.             internal System.Windows.Forms.PictureBox DeleteButton;
  1524.             internal System.Windows.Forms.Button PresunoutButton;
  1525.             internal System.Windows.Forms.PictureBox SlozkaPicturebox;
  1526.  
  1527.             /// <summary>
  1528.             /// Inicializace celé složky..
  1529.             /// </summary>
  1530.             /// <param name="slozka">Složka, která se má inicializovat.</param>
  1531.             /// <param name="kolikataSlozka">Určuje, o kolikátou složku v seznamu se jedná. Kvůli pozici tlačítek a tak.</param>
  1532.             /// <param name="okno">Aktuální okno.</param>
  1533.             /// <param name="presunout">Určuje, v jakém smyslu se složka inicializuje.</param>
  1534.             internal JednaSlozka(string slozka, int kolikataSlozka, FolderForm okno, bool presunout)
  1535.             {
  1536.                 this.slozka = slozka;
  1537.                 this.okno = okno;
  1538.                 this.kolikataSlozka = kolikataSlozka;
  1539.  
  1540.                 #region Inicializace ovládacích prvků.
  1541.                 this.SlozkaLabel = new System.Windows.Forms.Label();
  1542.                 this.SlozkaPicturebox = new System.Windows.Forms.PictureBox();
  1543.                
  1544.                 ((System.ComponentModel.ISupportInitialize)(this.SlozkaPicturebox)).BeginInit();
  1545.                 this.SlozkaLabel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  1546.                 this.SlozkaLabel.Font = new System.Drawing.Font("Calibri", 10F);
  1547.                 this.SlozkaLabel.Location = new System.Drawing.Point(52, 38 * kolikataSlozka);
  1548.                 this.SlozkaLabel.Name = "SlozkaLabel";
  1549.                 this.SlozkaLabel.Size = new System.Drawing.Size(158, 32);
  1550.                 this.SlozkaLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;      
  1551.  
  1552.                 this.SlozkaPicturebox.Location = new System.Drawing.Point(3, 38 * kolikataSlozka);
  1553.                 this.SlozkaPicturebox.Name = "SlozkaPicturebox";
  1554.                 this.SlozkaPicturebox.Size = new System.Drawing.Size(32, 32);
  1555.                 this.SlozkaPicturebox.TabIndex = 18;
  1556.                 this.SlozkaPicturebox.TabStop = false;
  1557.                 this.SlozkaPicturebox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
  1558.  
  1559.                 SlozkaPicturebox.Image = global::Mail_Agent_2017.Properties.Resources.Slozka;
  1560.  
  1561.                 ((System.ComponentModel.ISupportInitialize)(this.SlozkaPicturebox)).EndInit();
  1562.  
  1563.                 if (presunout)
  1564.                 {
  1565.                     this.PresunoutButton = new System.Windows.Forms.Button();
  1566.  
  1567.                     this.PresunoutButton.BackColor = BarevnyMotiv.barvaTlacitek;
  1568.                     this.PresunoutButton.Location = new System.Drawing.Point(212, 38 * kolikataSlozka);
  1569.                     this.PresunoutButton.Name = slozka;
  1570.                     this.PresunoutButton.Text = "Přesunout";
  1571.                     this.PresunoutButton.Padding = new System.Windows.Forms.Padding(0);
  1572.                     this.PresunoutButton.Size = new System.Drawing.Size(100, 35);
  1573.                     this.PresunoutButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  1574.                     this.PresunoutButton.ForeColor = Color.White;
  1575.                     this.PresunoutButton.Font = new System.Drawing.Font("Calibri", 10F, System.Drawing.FontStyle.Regular);
  1576.                     this.PresunoutButton.TabStop = false;
  1577.  
  1578.                     ToolTip PresunoutTooltip = new ToolTip();
  1579.                     PresunoutTooltip.UseFading = true;
  1580.                     PresunoutTooltip.UseAnimation = true;
  1581.                     PresunoutTooltip.ReshowDelay = 500;
  1582.                     PresunoutTooltip.InitialDelay = 500;
  1583.                     PresunoutTooltip.AutoPopDelay = 15000;
  1584.                     PresunoutTooltip.ShowAlways = true;
  1585.                     PresunoutTooltip.ToolTipIcon = ToolTipIcon.Info;
  1586.                     PresunoutTooltip.SetToolTip(PresunoutButton, "Přesune e-mail do této složky.");
  1587.  
  1588.                     this.PresunoutButton.Click += new System.EventHandler(delegate (object sender, EventArgs e)
  1589.                     {
  1590.  
  1591.                         switch (((Button)sender).Name)
  1592.                         {
  1593.                             case "Doručená pošta": okno.kamPresunout = okno.aktualniPrihlaseni.ImapPripojeni.Folders.Inbox; break;
  1594.                             case "Označená pošta": okno.kamPresunout = okno.aktualniPrihlaseni.ImapPripojeni.Folders.Flagged; break;
  1595.                             case "Důležitá pošta": okno.kamPresunout = okno.aktualniPrihlaseni.ImapPripojeni.Folders.Important; break;
  1596.                             case "Odeslaná pošta": okno.kamPresunout = okno.aktualniPrihlaseni.ImapPripojeni.Folders.Sent; break;
  1597.                             case "Koncepty": okno.kamPresunout = okno.aktualniPrihlaseni.ImapPripojeni.Folders.Drafts; break;
  1598.                             case "Nevyžádaná pošta": okno.kamPresunout = okno.aktualniPrihlaseni.ImapPripojeni.Folders.Junk; break;
  1599.                             case "Koš": okno.kamPresunout = okno.aktualniPrihlaseni.ImapPripojeni.Folders.Trash; break;
  1600.                             default: okno.kamPresunout = okno.aktualniPrihlaseni.ImapPripojeni.Folders[((Button)sender).Name]; break; // Name proto, protože název složky máme trikově skryt v názvu tlačítka.
  1601.                         }
  1602.  
  1603.                         if (okno.kamPresunout == null) // Toto u gmailu nastat nemůže.
  1604.                         {
  1605.                             if (okno.aktualniPrihlaseni.ImapPripojeni.Folders[((Button)sender).Name] == null)
  1606.                                 okno.aktualniPrihlaseni.ImapPripojeni.Folders.Add(((Button)sender).Name);
  1607.                             okno.kamPresunout = okno.aktualniPrihlaseni.ImapPripojeni.Folders[((Button)sender).Name];
  1608.                         }
  1609.  
  1610.                         okno.DialogResult = DialogResult.OK;
  1611.                         okno.Close();
  1612.                     });
  1613.  
  1614.                     okno.SlozkyPanel.Controls.Add(this.PresunoutButton);
  1615.                 }
  1616.  
  1617.                 else
  1618.                 {
  1619.                     this.DeleteButton = new System.Windows.Forms.PictureBox();
  1620.  
  1621.                     ((System.ComponentModel.ISupportInitialize)(this.DeleteButton)).BeginInit();
  1622.  
  1623.                     this.DeleteButton.Image = global::Mail_Agent_2017.Properties.Resources.OdstranitSoubor;
  1624.                     this.DeleteButton.Location = new System.Drawing.Point(212, 38 * kolikataSlozka);
  1625.                     this.DeleteButton.Name = "DeleteButton";
  1626.                     this.DeleteButton.Padding = new System.Windows.Forms.Padding(4);
  1627.                     this.DeleteButton.Size = new System.Drawing.Size(32, 32);
  1628.                     this.DeleteButton.TabStop = false;
  1629.                     this.DeleteButton.Cursor = Cursors.Hand;
  1630.  
  1631.                     ToolTip DeleteToolTip = new ToolTip();
  1632.                     DeleteToolTip.UseFading = true;
  1633.                     DeleteToolTip.UseAnimation = true;
  1634.                     DeleteToolTip.ReshowDelay = 500;
  1635.                     DeleteToolTip.InitialDelay = 500;
  1636.                     DeleteToolTip.AutoPopDelay = 15000;
  1637.                     DeleteToolTip.ShowAlways = true;
  1638.                     DeleteToolTip.ToolTipIcon = ToolTipIcon.Info;
  1639.                     DeleteToolTip.SetToolTip(DeleteButton, "Smazat složku.");
  1640.  
  1641.                     this.DeleteButton.Click += new System.EventHandler(delegate (object sender, EventArgs e)
  1642.                     {
  1643.                         if (MessageBox.Show("Opravdu chcete odstranit tuto složku? Veškeré e-maily v ní budou vymazány.", "Odstranit", MessageBoxButtons.YesNo) == DialogResult.Yes)
  1644.                             okno.OdstranSlozku((this.DeleteButton.Location.Y) / 38); // O kolikátou složku se jedná, poznáme podle její pozice.
  1645.                     });
  1646.  
  1647.                     okno.SlozkyPanel.Controls.Add(this.DeleteButton);
  1648.  
  1649.                     ((System.ComponentModel.ISupportInitialize)(this.DeleteButton)).EndInit();
  1650.                 }
  1651.  
  1652.                 okno.SlozkyPanel.Controls.Add(this.SlozkaPicturebox);
  1653.                 okno.SlozkyPanel.Controls.Add(this.SlozkaLabel);
  1654.                 #endregion
  1655.  
  1656.                 SlozkaLabel.Text = slozka;
  1657.  
  1658.                 okno.Invalidate();
  1659.             }
  1660.            
  1661.  
  1662.             /// <summary>
  1663.             /// Klasická implementace metody Dispose.
  1664.             /// </summary>
  1665.             public void Dispose()
  1666.             {
  1667.                 SlozkaLabel.Dispose();
  1668.                 SlozkaPicturebox.Dispose();
  1669.                 DeleteButton.Dispose();
  1670.             }
  1671.         }
  1672.     }
  1673. }
  1674.  
  1675. using System;
  1676. using System.Collections.Generic;
  1677. using System.Drawing;
  1678. using System.Linq;
  1679. using System.Text;
  1680. using System.Threading.Tasks;
  1681. using System.Windows.Forms;
  1682.  
  1683. namespace Mail_Agent_2017
  1684. {
  1685.     /// <summary>
  1686.     /// Třída implementující okno seznamu skupin.
  1687.     /// Jedná se de facto o to stejné okno, jako je adresář, až na nějaké drobnosti.
  1688.     /// </summary>
  1689.     public class GroupBookForm : AddressBookForm
  1690.     {
  1691.         /// <summary>
  1692.         /// Adresář skupin.
  1693.         /// </summary>
  1694.         public Skupiny skupiny;
  1695.         new internal List<JednaSkupina> ovladaciPrvky;
  1696.  
  1697.         /// <summary>
  1698.         /// Inicializace nejdůležitějších komponent pro toto okno.
  1699.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení. Toto je zde kvůli nalezení správného adresáře.</param>
  1700.         /// <param name="pridatDoEmailu">Rozhoduje, jaký druh skupinového adresáře zobrazí. Jestli ten editovací, nebo ten, který přidává skupiny kontaktů do e-mailu.</param>
  1701.         /// </summary>
  1702.         public GroupBookForm(Prihlaseni aktualniPrihlaseni, bool pridatDoEmailu)
  1703.         {
  1704.             this.Icon = BarevnyMotiv.ikona;
  1705.             InitializeComponent();
  1706.  
  1707.             #region Úprava designeru otcovské třídy.
  1708.             this.VytvoritButton.Text = "Vytvořit novou skupinu";
  1709.             this.Name = "GroupBookForm";
  1710.             this.Text = "Mail Agent 2017 - Adresář skupin";
  1711.             this.JmenoLabel.Text = "Název skupiny";
  1712.             this.EmailLabel.Text = "Členové skupiny";
  1713.             #endregion
  1714.  
  1715.             skupiny = new Skupiny(aktualniPrihlaseni);
  1716.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  1717.             ovladaciPrvky = new List<JednaSkupina>();
  1718.  
  1719.             // Vyřešíme takhle jednoduše, abychom nemuseli "složitě" upravovat designer.
  1720.             if (pridatDoEmailu)
  1721.             {
  1722.                 this.VytvoritButton.Visible = false;
  1723.                 this.ZavritButton.Text = "Připojit k e-mailu";
  1724.             }
  1725.  
  1726.             for (int i = 0; i < skupiny.seznamSkupin.Count; i++)
  1727.                 ovladaciPrvky.Add(new JednaSkupina(skupiny.seznamSkupin[i], i, this, pridatDoEmailu));
  1728.         }
  1729.  
  1730.         /// <summary>
  1731.         /// Vytvoří novou skupinu.
  1732.         /// </summary>
  1733.         internal override void VytvoritButton_Click(object sender, EventArgs e)
  1734.         {
  1735.             using (var form = new GroupForm(aktualniPrihlaseni))
  1736.                 if (form.ShowDialog() == DialogResult.OK)
  1737.                 {
  1738.                     skupiny.seznamSkupin.Add(form.novaSkupina);
  1739.                     ovladaciPrvky.Add(new JednaSkupina(skupiny.seznamSkupin[skupiny.seznamSkupin.Count - 1], skupiny.seznamSkupin.Count - 1, this, false));
  1740.                     skupiny.Ulozit();
  1741.                 }
  1742.         }
  1743.  
  1744.         /// <summary>
  1745.         /// Odstraní danou skupinu z adresáře.
  1746.         /// </summary>
  1747.         /// <param name="kolikata">Kolikátá skupina v pořadí se má smazat.</param>
  1748.         private void OdstranExistujiciSkupinu(int kolikata)
  1749.         {
  1750.             // Všechny skupiny pod touto musíme posunout směrem nahoru.
  1751.             ovladaciPrvky.GetRange(kolikata + 1, ovladaciPrvky.Count - kolikata - 1).ForEach(skupina =>
  1752.             {
  1753.                 skupina.NazevSkupinaLabel.Location = new System.Drawing.Point(52, skupina.NazevSkupinaLabel.Location.Y - 38);
  1754.                 skupina.ClenoveSkupinaLabel.Location = new System.Drawing.Point(230, skupina.ClenoveSkupinaLabel.Location.Y - 38);
  1755.                 skupina.DeleteButton.Location = new System.Drawing.Point(482, skupina.DeleteButton.Location.Y - 38);
  1756.                 skupina.EditButton.Location = new System.Drawing.Point(449, skupina.EditButton.Location.Y - 38);
  1757.                 skupina.InfoButton.Location = new System.Drawing.Point(416, skupina.InfoButton.Location.Y - 38);
  1758.                 skupina.ObrazekSkupinaPicturebox.Location = new System.Drawing.Point(3, skupina.ObrazekSkupinaPicturebox.Location.Y - 38);
  1759.             });
  1760.  
  1761.             // Uvolnění resourců, aby prvky smazané skupiny nezůstaly na pozadí a nezabíraly tak zbytečně paměť.
  1762.             ovladaciPrvky[kolikata].Dispose();
  1763.             skupiny.seznamSkupin.RemoveAt(kolikata);
  1764.         }
  1765.  
  1766.         /// <summary>
  1767.         /// Třída sloužící k inicializaci jedné skupiny v adresářovém okně - tedy inicializuje labely a tlačítka pro daný skupina.
  1768.         /// </summary>
  1769.         internal class JednaSkupina : IDisposable
  1770.         {
  1771.             internal Skupina skupina;
  1772.             private GroupBookForm okno;
  1773.             private int kolikataSkupina;
  1774.  
  1775.             internal System.Windows.Forms.Label ClenoveSkupinaLabel;
  1776.             internal System.Windows.Forms.PictureBox InfoButton;
  1777.             internal System.Windows.Forms.PictureBox EditButton;
  1778.             internal System.Windows.Forms.PictureBox DeleteButton;
  1779.             internal System.Windows.Forms.PictureBox ObrazekSkupinaPicturebox;
  1780.             internal System.Windows.Forms.Label NazevSkupinaLabel;
  1781.             internal System.Windows.Forms.CheckBox PridatSkupinuCheckbox;
  1782.  
  1783.             /// <summary>
  1784.             /// Inicializace celé skupiny.
  1785.             /// </summary>
  1786.             /// <param name="skupina">Skupina, která se má inicializovat.</param>
  1787.             /// <param name="kolikataSkupina">Určuje, o kolikátou skupinu v seznamu se jedná. Kvůli pozici tlačítek a tak.</param>
  1788.             /// <param name="okno">Aktuální okno.</param>
  1789.             /// <param name="pridatDoEmailu">Rozhoduje, jaký druh skupinového adresáře zobrazí. Jestli ten editovací, nebo ten, který přidává kontakty do e-mailu.</param>
  1790.             internal JednaSkupina(Skupina skupina, int kolikataSkupina, GroupBookForm okno, bool pridatDoEmailu)
  1791.             {
  1792.                 this.skupina = skupina;
  1793.                 this.okno = okno;
  1794.                 this.kolikataSkupina = kolikataSkupina;
  1795.  
  1796.                 #region Inicializace ovládacích prvků.
  1797.                 this.NazevSkupinaLabel = new System.Windows.Forms.Label();
  1798.                 this.ClenoveSkupinaLabel = new System.Windows.Forms.Label();
  1799.                 this.ObrazekSkupinaPicturebox = new System.Windows.Forms.PictureBox();
  1800.  
  1801.                 ((System.ComponentModel.ISupportInitialize)(this.ObrazekSkupinaPicturebox)).BeginInit();
  1802.                 //
  1803.                 // NazevSkupinaLabel
  1804.                 //
  1805.                 this.NazevSkupinaLabel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  1806.                 this.NazevSkupinaLabel.Font = new System.Drawing.Font("Calibri", 10F);
  1807.                 this.NazevSkupinaLabel.Location = new System.Drawing.Point(52, 38 * kolikataSkupina);
  1808.                 this.NazevSkupinaLabel.Name = "NazevSkupinaLabel";
  1809.                 this.NazevSkupinaLabel.Size = new System.Drawing.Size(171, 32);
  1810.                 this.NazevSkupinaLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
  1811.                 //
  1812.                 // ClenoveSkupinaLabel
  1813.                 //
  1814.                 this.ClenoveSkupinaLabel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  1815.                 this.ClenoveSkupinaLabel.Font = new System.Drawing.Font("Calibri Light", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
  1816.                 this.ClenoveSkupinaLabel.Location = new System.Drawing.Point(230, 38 * kolikataSkupina);
  1817.                 this.ClenoveSkupinaLabel.Name = "ClenoveSkupinaLabel";
  1818.                 this.ClenoveSkupinaLabel.Size = new System.Drawing.Size(171, 32);
  1819.                 this.ClenoveSkupinaLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
  1820.                 //
  1821.                 // ObrazekSkupinaPicturebox
  1822.                 //
  1823.                 this.ObrazekSkupinaPicturebox.Location = new System.Drawing.Point(3, 38 * kolikataSkupina);
  1824.                 this.ObrazekSkupinaPicturebox.Name = "ObrazekSkupinaPicturebox";
  1825.                 this.ObrazekSkupinaPicturebox.Size = new System.Drawing.Size(32, 32);
  1826.                 this.ObrazekSkupinaPicturebox.TabIndex = 18;
  1827.                 this.ObrazekSkupinaPicturebox.TabStop = false;
  1828.                 this.ObrazekSkupinaPicturebox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
  1829.  
  1830.                 ((System.ComponentModel.ISupportInitialize)(this.ObrazekSkupinaPicturebox)).EndInit();
  1831.  
  1832.  
  1833.                 okno.AdresarPanel.Controls.Add(this.ObrazekSkupinaPicturebox);
  1834.                 okno.AdresarPanel.Controls.Add(this.NazevSkupinaLabel);
  1835.                 okno.AdresarPanel.Controls.Add(this.ClenoveSkupinaLabel);
  1836.  
  1837.                 this.PridatSkupinuCheckbox = new System.Windows.Forms.CheckBox();
  1838.  
  1839.                 if (pridatDoEmailu)
  1840.                 {
  1841.                     //
  1842.                     // PridatSkupinuCheckbox
  1843.                     //
  1844.                     this.PridatSkupinuCheckbox.AutoSize = true;
  1845.                     this.PridatSkupinuCheckbox.Location = new System.Drawing.Point(449, 11 + 38 * kolikataSkupina);
  1846.                     this.PridatSkupinuCheckbox.Name = "PridatSkupinuCheckbox";
  1847.                     this.PridatSkupinuCheckbox.Size = new System.Drawing.Size(16, 16);
  1848.                     this.PridatSkupinuCheckbox.TabIndex = kolikataSkupina;
  1849.                     this.PridatSkupinuCheckbox.UseVisualStyleBackColor = true;
  1850.  
  1851.                     ToolTip PridatDoEmailuToolTip = new ToolTip();
  1852.                     PridatDoEmailuToolTip.UseFading = true;
  1853.                     PridatDoEmailuToolTip.UseAnimation = true;
  1854.                     PridatDoEmailuToolTip.ReshowDelay = 500;
  1855.                     PridatDoEmailuToolTip.InitialDelay = 500;
  1856.                     PridatDoEmailuToolTip.AutoPopDelay = 15000;
  1857.                     PridatDoEmailuToolTip.ShowAlways = true;
  1858.                     PridatDoEmailuToolTip.ToolTipIcon = ToolTipIcon.Info;
  1859.                     PridatDoEmailuToolTip.SetToolTip(PridatSkupinuCheckbox, "Připojí skupinu kontaktů k e-mailu.");
  1860.  
  1861.                     ToolTip InfoToolTip = new ToolTip();
  1862.                     InfoToolTip.UseFading = true;
  1863.                     InfoToolTip.UseAnimation = true;
  1864.                     InfoToolTip.ReshowDelay = 500;
  1865.                     InfoToolTip.InitialDelay = 500;
  1866.                     InfoToolTip.AutoPopDelay = 15000;
  1867.                     InfoToolTip.ShowAlways = true;
  1868.                     InfoToolTip.ToolTipIcon = ToolTipIcon.Info;
  1869.                     InfoToolTip.SetToolTip(ObrazekSkupinaPicturebox, "Zobrazit skupinu.");
  1870.  
  1871.                     ToolTip InfoToolTip2 = new ToolTip();
  1872.                     InfoToolTip2.UseFading = true;
  1873.                     InfoToolTip2.UseAnimation = true;
  1874.                     InfoToolTip2.ReshowDelay = 500;
  1875.                     InfoToolTip2.InitialDelay = 500;
  1876.                     InfoToolTip2.AutoPopDelay = 15000;
  1877.                     InfoToolTip2.ShowAlways = true;
  1878.                     InfoToolTip2.ToolTipIcon = ToolTipIcon.Info;
  1879.                     InfoToolTip2.SetToolTip(NazevSkupinaLabel, "Zobrazit skupinu.");
  1880.  
  1881.                     okno.AdresarPanel.Controls.Add(this.PridatSkupinuCheckbox);
  1882.  
  1883.                     this.ObrazekSkupinaPicturebox.Click += new System.EventHandler(this.InfoButton_Click);
  1884.                     this.NazevSkupinaLabel.Click += new System.EventHandler(this.InfoButton_Click);
  1885.  
  1886.                     this.NazevSkupinaLabel.Cursor = Cursors.Hand;
  1887.                     this.ObrazekSkupinaPicturebox.Cursor = Cursors.Hand;
  1888.  
  1889.                     this.ClenoveSkupinaLabel.ForeColor = this.NazevSkupinaLabel.ForeColor;
  1890.                 }
  1891.  
  1892.                 else
  1893.                 {
  1894.                     this.DeleteButton = new System.Windows.Forms.PictureBox();
  1895.                     this.EditButton = new System.Windows.Forms.PictureBox();
  1896.                     this.InfoButton = new System.Windows.Forms.PictureBox();
  1897.  
  1898.                     ((System.ComponentModel.ISupportInitialize)(this.DeleteButton)).BeginInit();
  1899.                     ((System.ComponentModel.ISupportInitialize)(this.EditButton)).BeginInit();
  1900.                     ((System.ComponentModel.ISupportInitialize)(this.InfoButton)).BeginInit();
  1901.  
  1902.                     //
  1903.                     // DeleteButton
  1904.                     //
  1905.                     this.DeleteButton.Image = global::Mail_Agent_2017.Properties.Resources.OdstranitSoubor;
  1906.                     this.DeleteButton.Location = new System.Drawing.Point(482, 38 * kolikataSkupina);
  1907.                     this.DeleteButton.Name = "DeleteButton";
  1908.                     this.DeleteButton.Padding = new System.Windows.Forms.Padding(4);
  1909.                     this.DeleteButton.Size = new System.Drawing.Size(32, 32);
  1910.                     this.DeleteButton.TabStop = false;
  1911.                     this.DeleteButton.Cursor = Cursors.Hand;
  1912.                     //
  1913.                     // EditButton
  1914.                     //
  1915.                     this.EditButton.Image = global::Mail_Agent_2017.Properties.Resources.EditovatSoubor;
  1916.                     this.EditButton.Location = new System.Drawing.Point(449, 38 * kolikataSkupina);
  1917.                     this.EditButton.Name = "EditButton";
  1918.                     this.EditButton.Padding = new System.Windows.Forms.Padding(4);
  1919.                     this.EditButton.Size = new System.Drawing.Size(32, 32);
  1920.                     this.EditButton.TabStop = false;
  1921.                     this.EditButton.Cursor = Cursors.Hand;
  1922.                     //
  1923.                     // InfoButton
  1924.                     //
  1925.                     this.InfoButton.Image = global::Mail_Agent_2017.Properties.Resources.InformaceOSouboru;
  1926.                     this.InfoButton.Location = new System.Drawing.Point(416, 38 * kolikataSkupina);
  1927.                     this.InfoButton.Name = "InfoButton";
  1928.                     this.InfoButton.Padding = new System.Windows.Forms.Padding(4);
  1929.                     this.InfoButton.Size = new System.Drawing.Size(32, 32);
  1930.                     this.InfoButton.TabStop = false;
  1931.                     this.InfoButton.Cursor = Cursors.Hand;
  1932.  
  1933.                     ToolTip InfoToolTip = new ToolTip();
  1934.                     InfoToolTip.UseFading = true;
  1935.                     InfoToolTip.UseAnimation = true;
  1936.                     InfoToolTip.ReshowDelay = 500;
  1937.                     InfoToolTip.InitialDelay = 500;
  1938.                     InfoToolTip.AutoPopDelay = 15000;
  1939.                     InfoToolTip.ShowAlways = true;
  1940.                     InfoToolTip.ToolTipIcon = ToolTipIcon.Info;
  1941.                     InfoToolTip.SetToolTip(InfoButton, "Zobrazit skupinu.");
  1942.  
  1943.                     ToolTip EditToolTip = new ToolTip();
  1944.                     EditToolTip.UseFading = true;
  1945.                     EditToolTip.UseAnimation = true;
  1946.                     EditToolTip.ReshowDelay = 500;
  1947.                     EditToolTip.InitialDelay = 500;
  1948.                     EditToolTip.AutoPopDelay = 15000;
  1949.                     EditToolTip.ShowAlways = true;
  1950.                     EditToolTip.ToolTipIcon = ToolTipIcon.Info;
  1951.                     EditToolTip.SetToolTip(EditButton, "Editovat skupinu.");
  1952.  
  1953.                     ToolTip DeleteToolTip = new ToolTip();
  1954.                     DeleteToolTip.UseFading = true;
  1955.                     DeleteToolTip.UseAnimation = true;
  1956.                     DeleteToolTip.ReshowDelay = 500;
  1957.                     DeleteToolTip.InitialDelay = 500;
  1958.                     DeleteToolTip.AutoPopDelay = 15000;
  1959.                     DeleteToolTip.ShowAlways = true;
  1960.                     DeleteToolTip.ToolTipIcon = ToolTipIcon.Info;
  1961.                     DeleteToolTip.SetToolTip(DeleteButton, "Smazat skupinu.");
  1962.  
  1963.                     this.InfoButton.Click += new System.EventHandler(this.InfoButton_Click);
  1964.                     this.EditButton.Click += new System.EventHandler(this.EditButton_Click);
  1965.                     this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click);
  1966.  
  1967.                     okno.AdresarPanel.Controls.Add(this.EditButton);
  1968.                     okno.AdresarPanel.Controls.Add(this.InfoButton);
  1969.                     okno.AdresarPanel.Controls.Add(this.DeleteButton);
  1970.  
  1971.                     ((System.ComponentModel.ISupportInitialize)(this.DeleteButton)).EndInit();
  1972.                     ((System.ComponentModel.ISupportInitialize)(this.EditButton)).EndInit();
  1973.                     ((System.ComponentModel.ISupportInitialize)(this.InfoButton)).EndInit();
  1974.                 }
  1975.  
  1976.  
  1977.                 #endregion
  1978.  
  1979.                 NazevSkupinaLabel.Text = skupina.Nazev;
  1980.  
  1981.                 // Zde vypíšeme prvních pár kontaktů do kolonky členů.
  1982.  
  1983.                 List<Kontakt> clenoveSkupiny = Utility.VypisKontaktyVeSkupine(new Adresar(okno.aktualniPrihlaseni), skupina);
  1984.                 if (clenoveSkupiny.Count >= 2) ClenoveSkupinaLabel.Text = clenoveSkupiny[0].Jmeno + ", " + clenoveSkupiny[1].Jmeno + " ...";
  1985.                 else if (clenoveSkupiny.Count == 2) ClenoveSkupinaLabel.Text = clenoveSkupiny[0].Jmeno + ", " + clenoveSkupiny[1].Jmeno;
  1986.                 else if (clenoveSkupiny.Count == 1) ClenoveSkupinaLabel.Text = clenoveSkupiny[0].Jmeno;
  1987.                 else ClenoveSkupinaLabel.Text = "---";
  1988.  
  1989.                 int pomer = Math.Max(skupina.Fotografie.Width / 24, skupina.Fotografie.Height / 24);
  1990.                 ObrazekSkupinaPicturebox.Image = new Bitmap(skupina.Fotografie, new Size(skupina.Fotografie.Width / pomer, skupina.Fotografie.Height / pomer));
  1991.  
  1992.                 okno.Invalidate();
  1993.             }
  1994.  
  1995.             /// <summary>
  1996.             /// Zobrazí informace o skupině.
  1997.             /// </summary>
  1998.             private void InfoButton_Click(object sender, EventArgs e)
  1999.             {
  2000.                 new GroupForm(skupina, true, okno.aktualniPrihlaseni).ShowDialog();
  2001.             }
  2002.  
  2003.             /// <summary>
  2004.             /// Upraví skupinu.
  2005.             /// </summary>
  2006.             private void EditButton_Click(object sender, EventArgs e)
  2007.             {
  2008.                 using (var form = new GroupForm(skupina, false, okno.aktualniPrihlaseni))
  2009.                     if (form.ShowDialog() == DialogResult.OK)
  2010.                         skupina = form.novaSkupina;
  2011.  
  2012.                 okno.skupiny.Ulozit();
  2013.  
  2014.                 NazevSkupinaLabel.Text = skupina.Nazev;
  2015.  
  2016.                 List<Kontakt> clenoveSkupiny = Utility.VypisKontaktyVeSkupine(new Adresar(okno.aktualniPrihlaseni), skupina);
  2017.                 if (clenoveSkupiny.Count >= 2) ClenoveSkupinaLabel.Text = clenoveSkupiny[0].Jmeno + ", " + clenoveSkupiny[1].Jmeno + " ...";
  2018.                 else if (clenoveSkupiny.Count == 2) ClenoveSkupinaLabel.Text = clenoveSkupiny[0].Jmeno + ", " + clenoveSkupiny[1].Jmeno;
  2019.                 else if (clenoveSkupiny.Count == 1) ClenoveSkupinaLabel.Text = clenoveSkupiny[0].Jmeno;
  2020.                 else ClenoveSkupinaLabel.Text = "---";
  2021.  
  2022.                 int pomer = Math.Max(skupina.Fotografie.Width / 24, skupina.Fotografie.Height / 24);
  2023.                 ObrazekSkupinaPicturebox.Image = new Bitmap(skupina.Fotografie, new Size(skupina.Fotografie.Width / pomer, skupina.Fotografie.Height / pomer));
  2024.  
  2025.                 okno.skupiny.seznamSkupin[kolikataSkupina] = skupina;
  2026.                 okno.ovladaciPrvky[kolikataSkupina] = this;
  2027.             }
  2028.  
  2029.             /// <summary>
  2030.             /// Odstraní skupinu.
  2031.             /// </summary>
  2032.             private void DeleteButton_Click(object sender, EventArgs e)
  2033.             {
  2034.                 if (MessageBox.Show("Opravdu chcete odstranit tuto skupinu?", "Odstranit", MessageBoxButtons.YesNo) == DialogResult.Yes)
  2035.                     okno.OdstranExistujiciSkupinu((this.DeleteButton.Location.Y) / 38); // O kolikátou skupinu se jedná, poznáme podle její pozice.
  2036.                 okno.skupiny.Ulozit();
  2037.             }
  2038.  
  2039.             /// <summary>
  2040.             /// Klasická implementace metody Dispose.
  2041.             /// </summary>
  2042.             public void Dispose()
  2043.             {
  2044.                 ClenoveSkupinaLabel.Dispose();
  2045.                 InfoButton.Dispose();
  2046.                 EditButton.Dispose();
  2047.                 DeleteButton.Dispose();
  2048.                 ObrazekSkupinaPicturebox.Dispose();
  2049.                 NazevSkupinaLabel.Dispose();
  2050.                 PridatSkupinuCheckbox.Dispose();
  2051.             }
  2052.         }
  2053.     }
  2054. }
  2055.  
  2056.  
  2057. using System;
  2058. using System.Collections.Generic;
  2059. using System.Drawing;
  2060. using System.Linq;
  2061. using System.Text;
  2062. using System.Threading.Tasks;
  2063. using System.Windows.Forms;
  2064.  
  2065. namespace Mail_Agent_2017
  2066. {
  2067.     /// <summary>
  2068.     /// Okno na přidávání a editaci skupin, podobné tomu pro kontakty.
  2069.     /// </summary>
  2070.     class GroupForm : ContactForm
  2071.     {
  2072.         /// <summary>
  2073.         /// Skupina, která se vytváří/edituje.
  2074.         /// </summary>
  2075.         public Skupina novaSkupina;
  2076.  
  2077.  
  2078.         private Label ClenoveLabel;
  2079.         private Label ClenoveInputLabel;
  2080.         private Button ClenoveButton;
  2081.  
  2082.         /// <summary>
  2083.         /// Metoda upravující designer otcovské třídy.
  2084.         /// </summary>
  2085.         private void OverrideComponent()
  2086.         {
  2087.             this.SuspendLayout();
  2088.             this.Size = new Size(this.Width, this.Height - 165);
  2089.  
  2090.             this.PrezdivkaTextbox.Visible = false;
  2091.             this.FirmaInputLabel.Visible = false; this.FirmaLabel.Visible = false; this.FirmaTextbox.Visible = false;
  2092.             this.WebInputLabel.Visible = false; this.WebLabel.Visible = false; this.WebTextbox.Visible = false;
  2093.             this.EmailInputLabel.Visible = false; this.EmailLabel.Visible = false; this.EmailTextbox.Visible = false;
  2094.             this.TelefonInputLabel.Visible = false; this.TelefonLabel.Visible = false; this.TelefonTextbox.Visible = false;
  2095.             this.SkupinaCombobox.Visible = false; this.SkupinaInputLabel.Visible = false; this.SkupinaLabel.Visible = false;
  2096.  
  2097.             this.FotografiePicturebox.Image = global::Mail_Agent_2017.Properties.Resources.DefaultSkupinaFotografie;
  2098.             this.JmenoLabel.Text = "Název:";
  2099.  
  2100.             this.ClenoveLabel = PrezdivkaLabel;
  2101.             this.ClenoveLabel.Name = "ClenoveLabel";
  2102.             this.ClenoveLabel.Text = "Členové:";
  2103.  
  2104.             this.ClenoveInputLabel = PrezdivkaInputLabel;
  2105.             this.ClenoveInputLabel.Name = "ClenoveInputLabel";
  2106.  
  2107.             this.PoznamkaInputLabel.Location = new Point(PoznamkaInputLabel.Location.X, PoznamkaInputLabel.Location.Y - 165);
  2108.             this.PoznamkaLabel.Location = new Point(PoznamkaLabel.Location.X, PoznamkaLabel.Location.Y - 165);
  2109.             this.PoznamkaTextbox.Location = new Point(PoznamkaTextbox.Location.X, PoznamkaTextbox.Location.Y - 165);
  2110.  
  2111.             this.ChyboveOknoLabel.Location = new Point(ChyboveOknoLabel.Location.X, ChyboveOknoLabel.Location.Y - 165);
  2112.             this.HlavniButton.Location = new Point(HlavniButton.Location.X, HlavniButton.Location.Y - 165);
  2113.  
  2114.  
  2115.             this.ClenoveButton = new Button();
  2116.             this.ClenoveButton.Location = PrezdivkaTextbox.Location;
  2117.             this.ClenoveButton.Size = PrezdivkaTextbox.Size;
  2118.             this.ClenoveButton.Name = "ClenoveButton";
  2119.             this.ClenoveButton.Text = "Upravit";
  2120.             this.ClenoveButton.BackColor = BarevnyMotiv.barvaTlacitek;
  2121.             this.ClenoveButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  2122.             this.ClenoveButton.Font = new System.Drawing.Font("Calibri", 10F);
  2123.             this.ClenoveButton.ForeColor = System.Drawing.Color.White;
  2124.             this.ClenoveButton.UseVisualStyleBackColor = false;
  2125.  
  2126.  
  2127.  
  2128.             this.ClenoveButton.Click += new EventHandler(delegate (object sender, EventArgs e) // Otevře okno, které umožní přidat kontakty do skupiny.
  2129.             {
  2130.                 using (var form = new AddressBookForm(aktualniPrihlaseni, true) ) // Je to stejné okno jako to, pomocí kterého přidáváme kontakty do e-mailu. Jen lehce pozměníme GUI.
  2131.                 {
  2132.                     form.ZavritButton.Text = "Upravit členy skupiny";
  2133.                     foreach (AddressBookForm.JedenKontakt kontakt in form.ovladaciPrvky)
  2134.                     {
  2135.                         kontakt.PridatDoEmailuToolTip.SetToolTip(kontakt.PridatKontaktCheckbox, "Přidá kontakt do skupiny.");
  2136.                         if (kontakt.kontakt.Skupina == novaSkupina.Nazev) // Pokud již kontakt ve skupině je, zobrazí se zaškrtnutý checkbox. Kontakt můžeme ze skupiny odebrat odškrtnutím checkboxu.
  2137.                             kontakt.PridatKontaktCheckbox.Checked = true;
  2138.                         else if (!string.IsNullOrEmpty(kontakt.kontakt.Skupina)) // Pokud je v nějaké jiné skupině, nemůžeme ho přidat do této.
  2139.                             kontakt.PridatKontaktCheckbox.Enabled = false;
  2140.                     }
  2141.                     if (form.ShowDialog() == DialogResult.OK)
  2142.                         foreach (AddressBookForm.JedenKontakt kontakt in form.ovladaciPrvky)
  2143.                         {
  2144.                             if (kontakt.PridatKontaktCheckbox.Checked)
  2145.                                 kontakt.kontakt.Skupina = novaSkupina.Nazev;
  2146.                             else kontakt.kontakt._skupina = "";
  2147.                         }
  2148.                     form.adresar.Ulozit();
  2149.                 }
  2150.             });
  2151.  
  2152.             this.Controls.Add(ClenoveLabel);
  2153.             this.Controls.Add(ClenoveInputLabel);
  2154.             this.Controls.Add(ClenoveButton);
  2155.  
  2156.             this.ResumeLayout();
  2157.             this.Invalidate();
  2158.         }
  2159.  
  2160.  
  2161.         public GroupForm(Prihlaseni aktualniPrihlaseni)
  2162.         {
  2163.             this.Icon = BarevnyMotiv.ikona;
  2164.             InitializeComponent();
  2165.             InitializeEditComponent();
  2166.  
  2167.             OverrideComponent();
  2168.  
  2169.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  2170.             novaSkupina = new Skupina { Fotografie = (Bitmap)FotografiePicturebox.Image };
  2171.  
  2172.             this.Text = "Mail Agent 2017 - Vytvořit skupinu";
  2173.             this.HlavniButton.Text = "Vytvořit novou skupinu";
  2174.         }
  2175.  
  2176.         /// <summary>
  2177.         /// Základní inicializace existující skupiny.
  2178.         /// </summary>
  2179.         /// <param name="skupina">Skupina, která se bude editovat.</param>
  2180.         /// <param name="pouzeZobrazit">Rozhoduje, zdali se má zobrazit formulář, pomocí kterého lze kontakt editovat, nebo pouze zobrazit skupinu.</param>
  2181.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení.</param>
  2182.         public GroupForm(Skupina skupina, bool pouzeZobrazit, Prihlaseni aktualniPrihlaseni)
  2183.         {
  2184.             this.Icon = BarevnyMotiv.ikona;
  2185.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  2186.             InitializeComponent();
  2187.  
  2188.             if (pouzeZobrazit)
  2189.             {
  2190.                 InitializeShowComponent();
  2191.                 OverrideComponent();
  2192.                 FotografiePicturebox.Image = skupina.Fotografie;
  2193.                 JmenoInputLabel.Text = skupina.Nazev;
  2194.                 PoznamkaInputLabel.Text = skupina.Poznamka;
  2195.                 ClenoveButton.Visible = false;
  2196.  
  2197.                 // Zde vypíšeme prvních pár kontaktů do kolonky členů.
  2198.                 List<Kontakt> clenoveSkupiny = new List<Kontakt>();
  2199.                 foreach (Kontakt kontakt in new Adresar(aktualniPrihlaseni).seznamKontaktu)
  2200.                     if (kontakt.Skupina == skupina.Nazev)
  2201.                         clenoveSkupiny.Add(kontakt);
  2202.                 if (clenoveSkupiny.Count > 1) ClenoveInputLabel.Text = clenoveSkupiny[0].Jmeno + "...";
  2203.                 else if (clenoveSkupiny.Count == 1) ClenoveInputLabel.Text = clenoveSkupiny[0].Jmeno;
  2204.                 else ClenoveInputLabel.Text = "Tato skupina nemá žádné členy.";
  2205.  
  2206.                 this.Text = "Mail Agent 2017 - Zobrazit skupinu";
  2207.             }
  2208.  
  2209.             else
  2210.             {
  2211.                 InitializeEditComponent();
  2212.                 OverrideComponent();
  2213.                 this.novaSkupina = skupina;
  2214.                
  2215.                 JmenoTextbox.Text = novaSkupina.Nazev;
  2216.                 FotografiePicturebox.Image = novaSkupina.Fotografie;
  2217.                 ClenoveInputLabel.Visible = false;
  2218.  
  2219.                 this.Text = "Mail Agent 2017 - Upravit skupinu";
  2220.                 this.HlavniButton.Text = "Upravit skupinu";
  2221.             }
  2222.         }
  2223.  
  2224.         /// <summary>
  2225.         /// Tlačítko, které kontroluje chyby a přidává/vrací skupinu do adresáře, respektive vrací ji otcovskému oknu.
  2226.         /// </summary>
  2227.         protected override void PridatNeboEditovat_Click(object sender, EventArgs e)
  2228.         {
  2229.             try
  2230.             {
  2231.                 if (string.IsNullOrEmpty(JmenoTextbox.Text))
  2232.                     throw new ChybneZadaniException("Název musí být vyplněn.");
  2233.             }
  2234.  
  2235.             catch (ChybneZadaniException ex)
  2236.             {
  2237.                 ChyboveOknoLabel.Show();
  2238.                 ChyboveOknoLabel.Text = ex.Message;
  2239.                 ZobrazeniChybyTimer.Enabled = true;
  2240.                 return;
  2241.             }
  2242.  
  2243.             novaSkupina.Nazev = JmenoTextbox.Text;
  2244.             novaSkupina.Poznamka = PoznamkaTextbox.Text;
  2245.  
  2246.             this.DialogResult = DialogResult.OK;
  2247.             this.Close();
  2248.         }
  2249.  
  2250.         /// <summary>
  2251.         /// Tlačítko, které dá uživateli možnost zvolit obrázek skupiny.
  2252.         /// </summary>
  2253.         protected override void FotografieButton_Click(object sender, EventArgs e)
  2254.         {
  2255.             OpenFileDialog soubor = new OpenFileDialog();
  2256.             if (soubor.ShowDialog() == DialogResult.OK)
  2257.             {
  2258.                 Bitmap temp = new Bitmap(soubor.FileName);
  2259.  
  2260.                 // Nyní naškálujeme fotku na velikost maximálně 128x128.
  2261.                 try
  2262.                 {
  2263.                     int pomer = Math.Max(temp.Width / 128, temp.Height / 128);
  2264.                     novaSkupina.Fotografie = new Bitmap(temp, new Size(temp.Width / pomer, temp.Height / pomer));
  2265.                 }
  2266.                 catch (DivideByZeroException) { novaSkupina.Fotografie = temp; } // Pokud jsou rozměry menší než 128x128, vložíme fotku v plné velikosti.
  2267.                 finally { FotografiePicturebox.Image = novaSkupina.Fotografie; }
  2268.  
  2269.                 this.Invalidate();
  2270.             }
  2271.  
  2272.         }
  2273.     }
  2274. }
  2275.  
  2276.  
  2277. using System;
  2278. using System.Windows.Forms;
  2279.  
  2280. namespace Mail_Agent_2017
  2281. {
  2282.     /// <summary>
  2283.     /// Zobrazí náhled HTML kódu.
  2284.     /// </summary>
  2285.     public partial class HtmlPreviewForm : Form
  2286.     {
  2287.         /// <summary>
  2288.         /// Inicializace nejdůležitějších komponent pro toto okno.
  2289.         /// </summary>
  2290.         /// <param name="kod">HTML kód.</param>
  2291.         public HtmlPreviewForm(string kod)
  2292.         {
  2293.             this.Icon = BarevnyMotiv.ikona;
  2294.             InitializeComponent();
  2295.             HtmlPreviewWebbrowser.DocumentText = "<!DOCTYPE html><html><body style=\"font-family: Calibri;\">" + kod + "</body></html>";
  2296.         }
  2297.  
  2298.         /// <summary>
  2299.         /// Zavře okno s náhledem.
  2300.         /// </summary>
  2301.         private void ZavritButton_Click(object sender, EventArgs e)
  2302.         {
  2303.             this.Close();
  2304.         }
  2305.     }
  2306. }
  2307. using System;
  2308. using System.Collections.Generic;
  2309. using System.Windows.Forms;
  2310.  
  2311. namespace Mail_Agent_2017
  2312. {
  2313.     /// <summary>
  2314.     /// První přihlašovací okno.
  2315.     /// </summary>
  2316.     public partial class LoginForm1 : Form
  2317.     {
  2318.         Prihlaseni aktualniPrihlaseni;
  2319.         Stack<Form> PrihlasovaciProces;
  2320.  
  2321.         /// <summary>
  2322.         /// Inicializace nejdůležitějších komponent pro toto okno.
  2323.         /// </summary>
  2324.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení.</param>
  2325.         /// <param name="PrihlasovaciProces">Zásobník oken reprezentující přihlašovací proces.</param>
  2326.         public LoginForm1(Prihlaseni aktualniPrihlaseni, Stack<Form> PrihlasovaciProces)
  2327.         {
  2328.             this.Icon = BarevnyMotiv.ikona;
  2329.             InitializeComponent();
  2330.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  2331.             this.PrihlasovaciProces = PrihlasovaciProces;
  2332.             AdresaTextbox.Text = aktualniPrihlaseni.Email; // Toto je zde pro případ, kdyby se uživatel vracel do tohoto okna.
  2333.         }
  2334.  
  2335.         /// <summary>
  2336.         /// Metoda, která se spustí po kliknutí na tlačítko "Dále" na první přihlašovací obrazovce.
  2337.         /// Kotroluje, zdali má zadaná e-mailová adresa správný formát a v případě úspěchu odkáže uživatele na další přihlašovací obrazovku.
  2338.         /// </summary>
  2339.         private void DaleButton_Click(object sender, EventArgs e)
  2340.         {
  2341.            
  2342.             try
  2343.             {
  2344.                 if (!Utility.SpravnyFormatAdresy(AdresaTextbox.Text))
  2345.                     throw new ChybneZadaniException("E-mailová adresa má chybný formát.");
  2346.             }
  2347.  
  2348.             catch (Exception ex)
  2349.             {
  2350.                 ChyboveOknoLabel.Show();
  2351.                 ChyboveOknoLabel.Text = ex.Message;
  2352.                 ZobrazeniChybyTimer.Enabled = true;
  2353.                 return;
  2354.             }
  2355.  
  2356.             aktualniPrihlaseni.Email = AdresaTextbox.Text;
  2357.             PrihlasovaciProces.Push(new LoginForm2(aktualniPrihlaseni, PrihlasovaciProces));
  2358.             this.Close();
  2359.         }
  2360.  
  2361.         /// <summary>
  2362.         /// Skryje chybovou hlášku po uplynutí deseti sekund.
  2363.         /// </summary>
  2364.         private void ZobrazeniChybyTimer_Tick(object sender, EventArgs e)
  2365.         {
  2366.             ZobrazeniChybyTimer.Enabled = false;
  2367.             ChyboveOknoLabel.Hide();
  2368.         }
  2369.  
  2370.     }
  2371. }
  2372.  
  2373.  
  2374. using System;
  2375. using System.Collections.Generic;
  2376. using System.Drawing;
  2377. using System.Threading.Tasks;
  2378. using System.Windows.Forms;
  2379. using ImapX;
  2380. using System.Threading;
  2381.  
  2382. namespace Mail_Agent_2017
  2383. {
  2384.     /// <summary>
  2385.     /// Druhé přihlašovací okno.
  2386.     /// </summary>
  2387.     public partial class LoginForm2 : Form
  2388.     {
  2389.         Prihlaseni aktualniPrihlaseni;
  2390.         Stack<Form> PrihlasovaciProces;
  2391.         ESP seznamESP;
  2392.  
  2393.         /// <summary>
  2394.         /// Konstruktor se stará zejména o vyplnění údajů o známých ESP, upravuje dle toho UI.
  2395.         /// </summary>
  2396.         public LoginForm2(Prihlaseni aktualniPrihlaseni, Stack<Form> PrihlasovaciProces)
  2397.         {
  2398.             this.Icon = BarevnyMotiv.ikona;
  2399.             InitializeComponent();
  2400.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  2401.             this.PrihlasovaciProces = PrihlasovaciProces;
  2402.             this.EmailAddressTextbox.Text = aktualniPrihlaseni.Email;
  2403.             this.HesloTextbox.Text = aktualniPrihlaseni.Heslo;
  2404.             this.JmenoTextbox.Text = aktualniPrihlaseni.Jmeno;
  2405.             this.seznamESP = new ESP(); // Načtení tabulky známých ESP.
  2406.  
  2407.             // Aplikace zkontroluje, zdali se uživatelův ESP nenachází v tabulce známých ESP.
  2408.             if (seznamESP.NajdiVhodnehoESP(aktualniPrihlaseni.Email.Split('@')[1]) != null)
  2409.             {
  2410.                 OznameniLabel.Text = "Váš poskytovatel e-mailových služeb je nám známý. Některé údaje budou automaticky předvyplněny.";
  2411.  
  2412.                 UpravyCheckbox.Checked = false;
  2413.  
  2414.                 var aktualniESP = seznamESP.NajdiVhodnehoESP(aktualniPrihlaseni.Email.Split('@')[1]);
  2415.  
  2416.                 ImapServerTextbox.Text = aktualniESP.ImapServer;
  2417.                 ImapServerTextbox.Enabled = UpravyCheckbox.Checked;
  2418.  
  2419.                 ImapPortTextbox.Text = aktualniESP.ImapPort.ToString();
  2420.                 ImapPortTextbox.Enabled = UpravyCheckbox.Checked;
  2421.  
  2422.                 SmtpServerTextbox.Text = aktualniESP.SmtpServer;
  2423.                 SmtpServerTextbox.Enabled = UpravyCheckbox.Checked;
  2424.  
  2425.                 SmtpPortTextbox.Text = aktualniESP.SmtpPort.ToString();
  2426.                 SmtpPortTextbox.Enabled = UpravyCheckbox.Checked;
  2427.  
  2428.                 ImapSslCheckbox.Checked = aktualniESP.ImapSsl;
  2429.                 ImapSslCheckbox.Enabled = UpravyCheckbox.Checked;
  2430.  
  2431.                 SmtpSslCheckbox.Checked = aktualniESP.SmtpSsl;
  2432.                 SmtpSslCheckbox.Enabled = UpravyCheckbox.Checked;
  2433.  
  2434.                 SmtpAuthCheckbox.Checked = aktualniESP.SmtpAuth;
  2435.                 SmtpAuthCheckbox.Enabled = UpravyCheckbox.Checked;
  2436.             }
  2437.             else
  2438.             {
  2439.                 OznameniLabel.Text = "V případě nesnází se obraťte na Vašeho poskytovatele e-mailových služeb.";
  2440.                 UpravyCheckbox.Visible = false;
  2441.                 ZmenaLabel.Visible = false;
  2442.             }
  2443.         }
  2444.  
  2445.         /// <summary>
  2446.         /// Implementace tlačítka zpět - po stisknutí tlačítka se vrátí na předchozí přihlašovací okno.
  2447.         /// </summary>
  2448.         private void ZpetButton_Click(object sender, EventArgs e)
  2449.         {
  2450.             PrihlasovaciProces.Push(new LoginForm1(aktualniPrihlaseni, PrihlasovaciProces));
  2451.             this.Close();
  2452.         }
  2453.  
  2454.         /// <summary>
  2455.         /// Metoda starající se o navazování spojení se SMTP a IMAP servery.
  2456.         /// Rovněž hledá a kontroluje chyby, obeznamuje o nich uživatele.
  2457.         /// </summary>
  2458.         private async void DaleButton_Click(object sender, EventArgs e)
  2459.         {
  2460.             ZobrazeniChybyTimer.Enabled = false;
  2461.  
  2462.             aktualniPrihlaseni.Heslo = HesloTextbox.Text;
  2463.             aktualniPrihlaseni.Jmeno = JmenoTextbox.Text;
  2464.  
  2465.             // Zatímco budeme čekat na navázání spojení, uživateli se bude zobrazovat efekt blikajících teček při přihlašování.
  2466.             ChyboveOknoLabel.Text = "";
  2467.             NacitaniTimer.Enabled = true;
  2468.             ChyboveOknoLabel.ForeColor = Color.Black;
  2469.             ChyboveOknoLabel.Show();
  2470.  
  2471.             // Navazování spojení rozběhneme na novém pracovním vlákně jako asynchronní metodu.
  2472.             await Task.Run(() =>
  2473.             {
  2474.                 try
  2475.                 {
  2476.                     // Chyba: Nebyly vyplněny všechny údaje.
  2477.                     if (string.IsNullOrWhiteSpace(HesloTextbox.Text) || string.IsNullOrWhiteSpace(JmenoTextbox.Text) || string.IsNullOrWhiteSpace(ImapServerTextbox.Text) ||
  2478.                         string.IsNullOrWhiteSpace(ImapPortTextbox.Text) || string.IsNullOrWhiteSpace(SmtpServerTextbox.Text) || string.IsNullOrWhiteSpace(SmtpPortTextbox.Text))
  2479.                         throw new ChybneZadaniException("Nebyly vyplněny všechny údaje.");
  2480.  
  2481.                     // Chyba: Porty neobsahují číselné hodnoty.
  2482.                     if (!int.TryParse(ImapPortTextbox.Text, out int imap) || !int.TryParse(SmtpPortTextbox.Text, out int smtp))
  2483.                         throw new ChybneZadaniException("Porty byly vyplněny chybně.");
  2484.  
  2485.                     // Inicializace SMTP a IMAP spojení.
  2486.                     aktualniPrihlaseni.ImapPripojeni = new ImapClient(ImapServerTextbox.Text, int.Parse(ImapPortTextbox.Text), ImapSslCheckbox.Checked, ImapSslCheckbox.Checked);
  2487.                     aktualniPrihlaseni.SmtpPripojeni = Utility.SmtpConnect(SmtpServerTextbox.Text, int.Parse(SmtpPortTextbox.Text), SmtpSslCheckbox.Checked,
  2488.                                                                                      SmtpAuthCheckbox.Checked, aktualniPrihlaseni.Email, HesloTextbox.Text);
  2489.  
  2490.                     // Chyba: Nepodařilo se navázat spojení s IMAP serverem.
  2491.                     if (!aktualniPrihlaseni.ImapPripojeni.Connect())
  2492.                         throw new ImapConnectFailException("Chyba při navazování spojení s IMAP serverem.");
  2493.  
  2494.                     // Chyba: Špatná e-mailová adresa nebo heslo.
  2495.                     else if (!aktualniPrihlaseni.ImapPripojeni.Login(aktualniPrihlaseni.Email, aktualniPrihlaseni.Heslo))
  2496.                         throw new SpatneHesloException("Heslo a e-mailová adresa se neshodují.");
  2497.  
  2498.                     // Chyba: Nepodařilo se navázat spojení se SMTP serverem. Pro otestování spojení se SMTP serverem pošle testovací zprávu.
  2499.                     else if (aktualniPrihlaseni.SmtpPripojeni == null)
  2500.                         throw new SmtpConnectFailException("Chyba při navazování spojení se SMTP serverem.");
  2501.                 }
  2502.  
  2503.                 catch (Exception ex)
  2504.                 {
  2505.                     // Zkontrolujeme, jestli se jedná o výjimku vyvolanou námi.
  2506.                     if (ex is ChybneZadaniException || ex is SmtpConnectFailException || ex is ImapConnectFailException || ex is SpatneHesloException)
  2507.  
  2508.                         // Zobrazení chybové hlášky. Texty labelů (a všeobecně celé GUI) se můžou měnit pouze z UI vlákna, proto je to řešeno pomocí MethodInvokeru.                        
  2509.                         this.BeginInvoke(new MethodInvoker(delegate ()
  2510.                         {
  2511.                             // Zastavení blikajích teček
  2512.                             NacitaniTimer.Enabled = false;
  2513.                             ChyboveOknoLabel.Text = ex.Message; ChyboveOknoLabel.ForeColor = Color.Red;
  2514.                             ZobrazeniChybyTimer.Enabled = true;
  2515.                         }));
  2516.  
  2517.                     // Pokud se jedná o jinou výjimku, tak prostě nebudeme uživateli nic tajit a řekneme mu tím, jak neumíme programovat.
  2518.                     else MessageBox.Show(ex.Message);
  2519.                 }
  2520.  
  2521.                 finally
  2522.                 {
  2523.                     // Toto je zde pro efekt.
  2524.                     // Poznámka autora: Když už jsem si dal tu práci s programováním blikajících teček, tak ať jsou alespoň vidět i v případě, že je spojení navázáno rychle.
  2525.                     Thread.Sleep(2500);
  2526.                 }
  2527.             });
  2528.  
  2529.             // Výsledek z pracovního vlákna poznáme snadno, a to tak, že pouze v případě chyby se rozběhne tento timer.
  2530.             if (ZobrazeniChybyTimer.Enabled)
  2531.                 return;
  2532.  
  2533.             // Po úspěšném navázání spojení přidá záznam do tabulky známých ESP, pokud tam již není.
  2534.             if (seznamESP.NajdiVhodnehoESP(aktualniPrihlaseni.Email.Split('@')[1]) == null)
  2535.                 seznamESP.PridejZaznamOESP(aktualniPrihlaseni.Email.Split('@')[1], ImapServerTextbox.Text, int.Parse(ImapPortTextbox.Text), ImapSslCheckbox.Checked,
  2536.                                            SmtpServerTextbox.Text, int.Parse(SmtpPortTextbox.Text), SmtpSslCheckbox.Checked, SmtpAuthCheckbox.Checked);
  2537.  
  2538.             PrihlasovaciProces.Push(new LoginForm3(aktualniPrihlaseni, PrihlasovaciProces));
  2539.             this.Close();
  2540.         }
  2541.  
  2542.         /// <summary>
  2543.         /// Skryje chybovou hlášku po uplynutí deseti sekund.
  2544.         /// </summary>
  2545.         private void ZobrazeniChybyTimer_Tick(object sender, EventArgs e)
  2546.         {
  2547.             ZobrazeniChybyTimer.Enabled = false;
  2548.             ChyboveOknoLabel.Hide();
  2549.         }
  2550.        
  2551.         /// <summary>
  2552.         /// Metoda, která obsluhuje tlačítko, které povoluje změny předvyplněných údajů.
  2553.         /// </summary>
  2554.         private void ZmenaCB_CheckedChanged(object sender, EventArgs e)
  2555.         {
  2556.             ImapServerTextbox.Enabled = UpravyCheckbox.Checked;
  2557.             ImapPortTextbox.Enabled = UpravyCheckbox.Checked;
  2558.             SmtpServerTextbox.Enabled = UpravyCheckbox.Checked;
  2559.             SmtpPortTextbox.Enabled = UpravyCheckbox.Checked;
  2560.             ImapSslCheckbox.Enabled = UpravyCheckbox.Checked;
  2561.             SmtpSslCheckbox.Enabled = UpravyCheckbox.Checked;
  2562.             SmtpAuthCheckbox.Enabled = UpravyCheckbox.Checked;
  2563.         }
  2564.  
  2565.         /// <summary>
  2566.         /// Metoda pro efekt, zobrazuje efekt blikajících teček při přihlašování.
  2567.         /// </summary>
  2568.         private void NacitaniTimer_Tick(object sender, EventArgs e)
  2569.         {
  2570.             if (ChyboveOknoLabel.Text.Length >= 75 || ChyboveOknoLabel.Text.Length == 0)
  2571.                 ChyboveOknoLabel.Text = "Počkejte, prosím. Toto může chvíli trvat. Probíhá navazování komunikace ";
  2572.             else
  2573.                 ChyboveOknoLabel.Text += ".";
  2574.         }
  2575.     }
  2576. }
  2577.  
  2578. using System;
  2579. using System.Collections.Generic;
  2580. using System.Windows.Forms;
  2581.  
  2582. namespace Mail_Agent_2017
  2583. {
  2584.     /// <summary>
  2585.     /// Třetí přihlašovací okno.
  2586.     /// </summary>
  2587.     public partial class LoginForm3 : Form
  2588.     {
  2589.         Prihlaseni aktualniPrihlaseni;
  2590.         Stack<Form> PrihlasovaciProces;
  2591.  
  2592.         /// <summary>
  2593.         /// Inicializace nejdůležitějších komponent pro toto okno.
  2594.         /// </summary>
  2595.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení.</param>
  2596.         /// <param name="PrihlasovaciProces">Zásobník oken reprezentující přihlašovací proces.</param>
  2597.         public LoginForm3(Prihlaseni aktualniPrihlaseni, Stack<Form> PrihlasovaciProces)
  2598.         {
  2599.             this.Icon = BarevnyMotiv.ikona;
  2600.             InitializeComponent();
  2601.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  2602.             this.PrihlasovaciProces = PrihlasovaciProces;
  2603.  
  2604.             PopisLabel.Text = "Při této příležitosti Vám byla zaslána testovací zpráva.\n" +
  2605.                               "Nyní můžete vstoupit do aplikace a využívat všechny její funkce.\n\n" +
  2606.                               "Děkujeme Vám, " + aktualniPrihlaseni.Jmeno.Split(' ')[0] + ", že jste si vybral Mail Agent 2017.";
  2607.         }
  2608.  
  2609.         /// <summary>
  2610.         /// Implementace tlačítka zpět - po stisknutí tlačítka se vrátí na předchozí přihlašovací okno.
  2611.         /// </summary>
  2612.         private void ZpetButton_Click(object sender, EventArgs e)
  2613.         {
  2614.             PrihlasovaciProces.Push(new LoginForm2(aktualniPrihlaseni, PrihlasovaciProces));
  2615.             this.Close();
  2616.         }        
  2617.  
  2618.         /// <summary>
  2619.         /// Přesměruje uživatele do aplikace.
  2620.         /// </summary>
  2621.         private void DaleButton_Click(object sender, EventArgs e)
  2622.         {
  2623.             this.Close();
  2624.         }
  2625.     }
  2626. }
  2627.  
  2628.  
  2629. using System;
  2630. using System.Collections.Generic;
  2631. using System.ComponentModel;
  2632. using System.Data;
  2633. using System.Drawing;
  2634. using System.Linq;
  2635. using System.Text;
  2636. using System.Threading;
  2637. using System.Threading.Tasks;
  2638. using System.Windows.Forms;
  2639.  
  2640. namespace Mail_Agent_2017
  2641. {    
  2642.     /// <summary>
  2643.     /// Hlavní okno celé aplikace.
  2644.     /// </summary>
  2645.     public partial class MainForm : Form, IDisposable
  2646.     {
  2647.         [System.Runtime.InteropServices.DllImport("user32.dll")]
  2648.         private static extern bool ShowScrollBar(IntPtr panel, int velikost, bool zobrazit); // Tímto skryjeme horizontální scrollbar. Nevím sice proč, ale funguje to.
  2649.         /// <summary>
  2650.         /// Metoda se spustí při inicializaci okna. Pomocí API funkce pro scrollbar zakáže horizontální scrollbar pro panel složek.
  2651.         /// </summary>
  2652.         protected override void OnShown(EventArgs e)
  2653.         {
  2654.             ShowScrollBar(this.SlozkaPanel.Handle, 0, false);
  2655.             base.OnShown(e);
  2656.         }
  2657.  
  2658.  
  2659.         private Prihlaseni aktualniPrihlaseni;
  2660.         private object vybranaSlozka;
  2661.         private StazeneEmaily stazeneEmaily;
  2662.  
  2663.         // Toto zde máme z jednoduchého důvodu. Během stahování e-mailů nemůžeme nijak měnit GUI, neboť bychom tím mohli rozbít IMAP připojení, což by vedlo k vyvolání výjimky.
  2664.         // Každý event handler, který se zavolá, zkontroluje, jestli je tato hodnota nastavená na true. Pokud ano, obsluha dané události neproběhne.
  2665.         // Tento problém je zde proto, že navazování spojení probíhá na vedlejším vlákně. ImapX knihovna je stavěna tak, že v jednom okamžiku může být navázáno pouze jedno spojení.
  2666.         // Proměnnou nastavujeme v případě, kdy se nás tento problém týká.
  2667.         // Alternativní řešení, pro uživatele příjemnější, pro programátora mnohem obtížnější, je využití CancellationToken-u.
  2668.         internal bool pozastavSpousteniEventHandleru = false;
  2669.  
  2670.  
  2671.         /// <summary>
  2672.         /// Konstruktor se stará o hlavní inicializaci, popř. spouští přihlašovací proces...
  2673.         /// </summary>
  2674.         public MainForm()
  2675.         {
  2676.             this.Icon = BarevnyMotiv.ikona;
  2677.             this.aktualniPrihlaseni = new Prihlaseni();
  2678.             Utility.PrihlasovaciProces(ref aktualniPrihlaseni);
  2679.             InitializeComponent();
  2680.             VlastniSlozky(new FolderForm(aktualniPrihlaseni, false).slozky); // Vytvoříme tlačítka pro vlastní složky.
  2681.  
  2682.             this.Text = "Mail Agent 2017 - " + aktualniPrihlaseni.Email;
  2683.  
  2684.             // Po dokončení úprav přesunout do designeru.
  2685.             this.OdpovedetButton.BackColor = BarevnyMotiv.barvaTlacitek;
  2686.             this.SmazatButton.BackColor = BarevnyMotiv.barvaTlacitek;
  2687.             this.PreposlatButton.BackColor = BarevnyMotiv.barvaTlacitek;
  2688.             this.PresunoutButton.BackColor = BarevnyMotiv.barvaTlacitek;
  2689.             this.PrilohyButton.BackColor = BarevnyMotiv.barvaTlacitek;
  2690.             this.KonceptButton.BackColor = BarevnyMotiv.barvaTlacitek;
  2691.  
  2692.             this.EmailPanel.Scroll += new ScrollEventHandler(AktualizujPostu);
  2693.             this.EmailPanel.MouseWheel += new MouseEventHandler(MouseScroll);
  2694.  
  2695.             // Pokud server podporuje idle stav spojení, spustíme idle stav, který po každém přijatém e-mailu aktualizuje poštu.
  2696.             // Jinak bude aktualizovat v intervalu, který si nastavil uživatel.
  2697.             if (aktualniPrihlaseni.ImapPripojeni.Capabilities.Idle)
  2698.             {
  2699.                 aktualniPrihlaseni.ImapPripojeni.Folders.Inbox.StartIdling();
  2700.                 aktualniPrihlaseni.ImapPripojeni.OnNewMessagesArrived +=
  2701.                     new EventHandler<ImapX.IdleEventArgs>(delegate (object sender, ImapX.IdleEventArgs e) {
  2702.                         if (MessageBox.Show("Přišel Vám nový e-mail. Chcete ho zobrazit?", "Nový e-mail", MessageBoxButtons.YesNo) == DialogResult.Yes)
  2703.                             this.BeginInvoke(new MethodInvoker(delegate () { EmailPanel.VerticalScroll.Value = 0;
  2704.                         VyberSlozku(DorucenaPostaButton, null); }));
  2705.                         // Pro jistotu rozběhneme na UI vlákně. Nevím, jak funguje idlování knihoviny ImapX, a ani to není nikde napsané.
  2706.                     });
  2707.             }
  2708.             else
  2709.             {
  2710.                 // Toto je napsané velmi ošklivě. Jedním z důvodů je ten, že většina serverů podporuje idle stav. Ale do budoucna určitě upravit!
  2711.                 AktualizujTimer.Interval = aktualniPrihlaseni.refresh == 0 ? 840000 : aktualniPrihlaseni.refresh * 1000;
  2712.                 AktualizujTimer.Enabled = true;
  2713.                 AktualizujTimer.Tick += new EventHandler(delegate (object sender, EventArgs e) { EmailPanel.VerticalScroll.Value = 0; VyberSlozku(NajdiTlacitko(vybranaSlozka), null); });
  2714.             }
  2715.  
  2716.             VyberSlozku(DorucenaPostaButton, null);
  2717.             HledejTextbox_UpravaPopisku(HledejTextbox, null); // Počáteční inicializace popisku.  
  2718.         }
  2719.  
  2720.         /// <summary>
  2721.         /// Nebudeme nepořádní a před zavřením aplikace odešleme na servery zprávu o ukončení spojení.
  2722.         /// </summary>
  2723.         new public void Dispose()
  2724.         {
  2725.             aktualniPrihlaseni.ImapPripojeni.Disconnect();
  2726.             aktualniPrihlaseni.SmtpPripojeni.Dispose();
  2727.             Dispose(true);
  2728.         }
  2729.     }
  2730. }
  2731.  
  2732. using System;
  2733. using System.Collections.Generic;
  2734. using System.Drawing;
  2735. using System.Linq;
  2736. using System.Text;
  2737. using System.Threading.Tasks;
  2738. using System.Windows.Forms;
  2739.  
  2740. namespace Mail_Agent_2017
  2741. {
  2742.     // Definice obsluh tlačítek hlavní nabídky. Z důvodu konzistence kódu v samostatném souboru.
  2743.     public partial class MainForm
  2744.     {
  2745.         /// <summary>
  2746.         /// Odhlásí se a spustí nový přihlašovací proces.
  2747.         /// </summary>
  2748.         private void odhlásitSeToolStripMenuItem_Click(object sender, EventArgs e)
  2749.         {
  2750.             if (pozastavSpousteniEventHandleru) return;
  2751.             this.Hide();
  2752.             aktualniPrihlaseni.OdhlasitSe();
  2753.             aktualniPrihlaseni = new Prihlaseni();
  2754.             Utility.PrihlasovaciProces(ref aktualniPrihlaseni);
  2755.             this.Show();
  2756.         }
  2757.  
  2758.         /// <summary>
  2759.         /// Ukončí aplikaci.
  2760.         /// </summary>
  2761.         private void ukončitToolStripMenuItem_Click(object sender, EventArgs e)
  2762.         {
  2763.             this.Dispose();
  2764.             Environment.Exit(0);
  2765.         }
  2766.  
  2767.         /// <summary>
  2768.         /// Otevře okno na odeslání emailu.
  2769.         /// </summary>
  2770.         private void novýEmailToolStripMenuItem_Click(object sender, EventArgs e)
  2771.         {
  2772.             new SendForm(aktualniPrihlaseni).ShowDialog();
  2773.         }
  2774.  
  2775.         /// <summary>
  2776.         /// Otevře okni adresáře.
  2777.         /// </summary>
  2778.         private void zobrazitAdresářToolStripMenuItem_Click(object sender, EventArgs e)
  2779.         {
  2780.             using (var form = new AddressBookForm(aktualniPrihlaseni, false))
  2781.             {
  2782.                 form.ShowDialog();
  2783.                 form.adresar.Ulozit();
  2784.             }
  2785.         }
  2786.  
  2787.         /// <summary>
  2788.         /// Otevře okno s nastavením aplikace.
  2789.         /// </summary>
  2790.         private void nastaveníAplikaceToolStripMenuItem_Click(object sender, EventArgs e)
  2791.         {
  2792.             if (pozastavSpousteniEventHandleru) return;
  2793.             new AppSettingsForm(aktualniPrihlaseni).ShowDialog();
  2794.             this.Icon = BarevnyMotiv.ikona;
  2795.  
  2796.             if (vybranaSlozka == null) VyberSlozku(DorucenaPostaButton, null);
  2797.             else if (vybranaSlozka is Button) VyberSlozku(vybranaSlozka, null);
  2798.             else if (vybranaSlozka is ZakladniSlozky)
  2799.                 switch (vybranaSlozka)
  2800.                 {
  2801.                     case ZakladniSlozky.Dorucene: VyberSlozku(DorucenaPostaButton, null); break;
  2802.                     case ZakladniSlozky.Odeslane: VyberSlozku(OdeslanaPostaButton, null); break;
  2803.                     case ZakladniSlozky.Oznacene: VyberSlozku(OznaceneButton, null); break;
  2804.                     case ZakladniSlozky.Dulezite: VyberSlozku(DuleziteButton, null); break;
  2805.                     case ZakladniSlozky.Koncepty: VyberSlozku(KonceptyButton, null); break;
  2806.                     case ZakladniSlozky.Spam: VyberSlozku(SpamButton, null); break;
  2807.                     case ZakladniSlozky.Kos: VyberSlozku(KosButton, null); break;
  2808.  
  2809.                 }
  2810.  
  2811.             PreposlatButton.BackColor = BarevnyMotiv.barvaTlacitek;
  2812.             OdpovedetButton.BackColor = BarevnyMotiv.barvaTlacitek;
  2813.             PrilohyButton.BackColor = BarevnyMotiv.barvaTlacitek;
  2814.             SmazatButton.BackColor = BarevnyMotiv.barvaTlacitek;
  2815.             PresunoutButton.BackColor = BarevnyMotiv.barvaTlacitek;
  2816.         }
  2817.  
  2818.         /// <summary>
  2819.         /// Otevře okno s možností vytvořit koncept.
  2820.         /// </summary>
  2821.         private void novýKonceptToolStripMenuItem_Click(object sender, EventArgs e)
  2822.         {
  2823.             new ConceptForm(aktualniPrihlaseni).ShowDialog();
  2824.         }
  2825.  
  2826.  
  2827.         /// <summary>
  2828.         /// Otevře okno adresáře skupin.
  2829.         /// </summary>
  2830.         private void zobrazitSkupinyToolStripMenuItem_Click(object sender, EventArgs e)
  2831.         {
  2832.             using (var form = new GroupBookForm(aktualniPrihlaseni, false))
  2833.             {
  2834.                 form.ShowDialog();
  2835.                 form.skupiny.Ulozit();
  2836.             }
  2837.         }
  2838.  
  2839.  
  2840.  
  2841.         /// <summary>
  2842.         /// Manuální aktualizace doručené pošty.
  2843.         /// </summary>
  2844.         private void aktualizovatPoštuToolStripMenuItem_Click(object sender, EventArgs e)
  2845.         {
  2846.             if (pozastavSpousteniEventHandleru) return;
  2847.             VyberSlozku(NajdiTlacitko(vybranaSlozka), null);
  2848.         }
  2849.  
  2850.         /// <summary>
  2851.         /// Otevře okno se složkami.
  2852.         /// </summary>
  2853.         private void složkaToolStripMenuItem_Click(object sender, EventArgs e)
  2854.         {
  2855.             if (pozastavSpousteniEventHandleru) return;
  2856.             using (var form = new FolderForm(aktualniPrihlaseni, false))
  2857.             {
  2858.                 form.ShowDialog();
  2859.                 form.UlozitSlozky();
  2860.                 VlastniSlozky(form.slozky); // Aktualizujeme GUI.
  2861.             }
  2862.         }
  2863.  
  2864.         /// <summary>
  2865.         /// Otevře okno s nápovědou.
  2866.         /// </summary>
  2867.         private void nápovědaToolStripMenuItem_Click(object sender, EventArgs e)
  2868.         {
  2869.             new ManualForm().Show();
  2870.         }
  2871.     }
  2872. }
  2873.  
  2874.  
  2875. using System;
  2876. using System.Collections.Generic;
  2877. using System.IO;
  2878. using System.Linq;
  2879. using System.Text;
  2880. using System.Threading;
  2881. using System.Threading.Tasks;
  2882. using System.Windows.Forms;
  2883.  
  2884. namespace Mail_Agent_2017
  2885. {
  2886.     // Zde jsou hlavní metody pro náhled jednoho e-mailu. Z důvodu konzistence kódu v samostatném souboru.
  2887.     public partial class MainForm
  2888.     {
  2889.         /// <summary>
  2890.         /// Aktuální zpráva, která se zobrazuje ve velkém okně pro náhled e-mailu. Máme to tu, abychom měli možnost na tuto zprávu odpovědět, stáhnout přílohy apod.
  2891.         /// </summary>
  2892.         private ImapX.Message aktualniZprava;
  2893.  
  2894.         /// <summary>
  2895.         /// Metoda se spustí po kliknutí na e-mail, v důsledku toho se stáhne celý e-mail včetně příloh a zobrazí se ve velkém okně.
  2896.         /// </summary>
  2897.         /// <param name="sender">Jaký e-mail se má zobrazit.</param>
  2898.         public async void ZobrazEmail(object sender)
  2899.         {
  2900.             if (pozastavSpousteniEventHandleru) return;
  2901.             if (!(sender is StazeneEmaily.JedenEmail)) return;
  2902.  
  2903.             pozastavSpousteniEventHandleru = true;
  2904.  
  2905.             aktualniZprava = ((StazeneEmaily.JedenEmail)sender).email;
  2906.  
  2907.             ZobrazitGUI(false);
  2908.             this.LoadingEmailPicturebox.Visible = true;
  2909.  
  2910.             this.SuspendLayout();
  2911.  
  2912.             // Odebereme highlight nepřečteného e-mailu.
  2913.             ((StazeneEmaily.JedenEmail)sender).cas.Font = new System.Drawing.Font(((StazeneEmaily.JedenEmail)sender).cas.Font, System.Drawing.FontStyle.Regular);
  2914.             ((StazeneEmaily.JedenEmail)sender).odesilatel.Font = new System.Drawing.Font(((StazeneEmaily.JedenEmail)sender).odesilatel.Font, System.Drawing.FontStyle.Regular);
  2915.             ((StazeneEmaily.JedenEmail)sender).predmet.Font = new System.Drawing.Font(((StazeneEmaily.JedenEmail)sender).predmet.Font, System.Drawing.FontStyle.Regular);
  2916.  
  2917.             // Tato operace trvá paradoxně nejdéle. Pět set milisekund až řádově sekundy, záleží na kvalitě připojení.
  2918.             if(!aktualniZprava.Seen)
  2919.                 await Task.Run(() => aktualniZprava.Seen = true);
  2920.  
  2921.             this.PredmetInputLabel.Text = (aktualniZprava.Subject == null || string.IsNullOrEmpty(aktualniZprava.Subject)) ? "Bez předmětu" : aktualniZprava.Subject;
  2922.  
  2923.             if (aktualniZprava.From != null)
  2924.                 this.OdesilatelInputLabel.Text = !string.IsNullOrEmpty(aktualniZprava.From.DisplayName) ? aktualniZprava.From.DisplayName + " (" + aktualniZprava.From.Address + ")" : aktualniZprava.From.Address;
  2925.  
  2926.             this.CasInputLabel.Text = ((StazeneEmaily.JedenEmail)sender).cas.Text;
  2927.             if (((StazeneEmaily.JedenEmail)sender).cas.Text.Substring(0, 4) == "dne ")
  2928.                 this.CasInputLabel.Text += " v " + aktualniZprava.Date.Value.Hour + ":" + (aktualniZprava.Date.Value.Minute.ToString().Length == 1 ? "0" : "") + aktualniZprava.Date.Value.Minute + ":" + (aktualniZprava.Date.Value.Second.ToString().Length == 1 ? "0" : "") + aktualniZprava.Date.Value.Second;
  2929.  
  2930.             foreach (var kopie in aktualniZprava.Cc)
  2931.             {
  2932.                 if (!string.IsNullOrEmpty(this.KopieInputLabel.Text))
  2933.                     this.KopieInputLabel.Text += ", ";
  2934.                 this.KopieInputLabel.Text += kopie.DisplayName != null || string.IsNullOrEmpty(kopie.DisplayName) ? kopie.DisplayName + " (" + kopie.Address + ")" : kopie.Address;
  2935.             }
  2936.  
  2937.             if (aktualniZprava.Cc.Count == 0) this.KopieInputLabel.Text = "---";
  2938.  
  2939.             // Toto také může nějaký čas zabrat.
  2940.             await Task.Run(() =>
  2941.             {
  2942.                 if (aktualniZprava.Body.HasHtml)
  2943.                     TextWebbrowser.DocumentText = "<!DOCTYPE html><html><body style=\"font-family: Calibri; background-color: rgb(240,240,240); width: " + ObsahPanel.Size.Width + " px;\">" + aktualniZprava.Body.Html + "</body></html>";
  2944.                 else
  2945.                 {
  2946.                     var teloEmailu = aktualniZprava.Body.Text; // V této chvíli se tělo e-mailu teprve začne stahovat. Nebudeme tím zatěžovat UI vlákno.
  2947.                     this.BeginInvoke(new MethodInvoker(delegate () { TextInputLabel.Text = teloEmailu; }));
  2948.                 }
  2949.             });
  2950.  
  2951.             this.LoadingEmailPicturebox.Visible = false;
  2952.             ZobrazitGUI(true);
  2953.             this.PerformLayout();
  2954.  
  2955.             if (aktualniZprava.Body.HasHtml) TextInputLabel.Visible = false; else TextWebbrowser.Visible = false;
  2956.  
  2957.             pozastavSpousteniEventHandleru = false;
  2958.         }
  2959.  
  2960.         /// <summary>
  2961.         /// Zobrazuje GUI tohoto panelu.
  2962.         /// </summary>
  2963.         /// <param name="zobrazit">V případě hodnoty true zobrazí, v opačním přípdě skryje.</param>
  2964.         private void ZobrazitGUI(bool zobrazit)
  2965.         {
  2966.             if (!zobrazit) this.PrilohyButton.Visible = zobrazit;
  2967.             else if (aktualniZprava.Attachments.Count() > 0)
  2968.             {
  2969.                 this.PrilohyButton.Text = "Přílohy (" + aktualniZprava.Attachments.Count() + ")";
  2970.                 this.PrilohyButton.Visible = zobrazit;
  2971.             }
  2972.  
  2973.             if (vybranaSlozka is ZakladniSlozky && (ZakladniSlozky)vybranaSlozka == ZakladniSlozky.Koncepty)
  2974.             {
  2975.                 if (PreposlatButton.Visible || OdpovedetButton.Visible)
  2976.                 {
  2977.                     this.PreposlatButton.Visible = false;
  2978.                     this.OdpovedetButton.Visible = false;
  2979.                 }
  2980.  
  2981.                 this.KonceptButton.Visible = zobrazit;
  2982.             }
  2983.  
  2984.             else
  2985.             {
  2986.                 if (KonceptButton.Visible)
  2987.                     this.KonceptButton.Visible = false;
  2988.  
  2989.                 this.PreposlatButton.Visible = zobrazit;
  2990.                 this.OdpovedetButton.Visible = zobrazit;
  2991.             }
  2992.            
  2993.  
  2994.             this.KopieInputLabel.Visible = zobrazit;
  2995.             this.KopieLabel.Visible = zobrazit;
  2996.             this.OdesilatelInputLabel.Visible = zobrazit;
  2997.             this.OdesilatelLabel.Visible = zobrazit;
  2998.             this.PredmetInputLabel.Visible = zobrazit;
  2999.             this.PredmetLabel.Visible = zobrazit;
  3000.             this.PresunoutButton.Visible = zobrazit;
  3001.             this.SmazatButton.Visible = zobrazit;
  3002.             this.Separator.Visible = zobrazit;
  3003.             this.TextWebbrowser.Visible = zobrazit;
  3004.             this.TextInputLabel.Visible = zobrazit;
  3005.             this.CasInputLabel.Visible = zobrazit;
  3006.             this.CasLabel.Visible = zobrazit;
  3007.         }
  3008.  
  3009.         /// <summary>
  3010.         /// Zobrazí okno s možností odpovědi.
  3011.         /// </summary>
  3012.         private void OdpovedetButton_Click(object sender, EventArgs e)
  3013.         {
  3014.             new SendForm(aktualniPrihlaseni, aktualniZprava, true).ShowDialog();
  3015.         }
  3016.  
  3017.         /// <summary>
  3018.         /// Zobrazí okno s možností přeposlání.
  3019.         /// </summary>
  3020.         private void PreposlatButton_Click(object sender, EventArgs e)
  3021.         {
  3022.             new SendForm(aktualniPrihlaseni, aktualniZprava, false).ShowDialog();
  3023.         }
  3024.  
  3025.         /// <summary>
  3026.         /// Odstraní e-mail.
  3027.         /// </summary>
  3028.         private async void SmazatButton_Click(object sender, EventArgs e)
  3029.         {
  3030.             if (pozastavSpousteniEventHandleru) return;
  3031.  
  3032.             pozastavSpousteniEventHandleru = true;
  3033.  
  3034.             if (vybranaSlozka is ZakladniSlozky && (ZakladniSlozky)vybranaSlozka == ZakladniSlozky.Kos && MessageBox.Show("Opravdu chcete trvale odstranit tuto zprávu?", "Odstranit zprávu", MessageBoxButtons.YesNo) == DialogResult.Yes)
  3035.                 await Task.Run(() => aktualniZprava.Remove());
  3036.             else
  3037.             {
  3038.                 await Task.Run(() => aktualniZprava.MoveTo(aktualniPrihlaseni.ImapPripojeni.Folders.Trash));
  3039.                 MessageBox.Show("Zpráva byla přesunuta do koše. Odtud ji můžete odstranit trvale.");
  3040.             }
  3041.  
  3042.             pozastavSpousteniEventHandleru = false;
  3043.  
  3044.             VyberSlozku(NajdiTlacitko(vybranaSlozka), null);
  3045.         }
  3046.  
  3047.  
  3048.         /// <summary>
  3049.         /// Zobrazí nabídku složek a přesune e-mail do vybrané složky.
  3050.         /// </summary>
  3051.         private void PresunoutButton_Click(object sender, EventArgs e)
  3052.         {
  3053.             if (pozastavSpousteniEventHandleru) return;
  3054.  
  3055.             pozastavSpousteniEventHandleru = true;
  3056.  
  3057.             using (var form = new FolderForm(aktualniPrihlaseni, true))
  3058.                 if (form.ShowDialog() == DialogResult.OK)
  3059.                     aktualniZprava.MoveTo(form.kamPresunout);
  3060.  
  3061.             pozastavSpousteniEventHandleru = false;
  3062.  
  3063.             VyberSlozku(NajdiTlacitko(vybranaSlozka), null);
  3064.         }
  3065.  
  3066.  
  3067.         /// <summary>
  3068.         /// Zobrazí okno s editací konceptu. Pokud dojde ke změně nebo odeslání konceptů, koncept se smaže.
  3069.         /// </summary>
  3070.         private async void KonceptButton_Click(object sender, EventArgs e)
  3071.         {
  3072.             if (new SendForm(aktualniPrihlaseni, aktualniZprava).ShowDialog() == DialogResult.OK)
  3073.                 await Task.Run(() => aktualniZprava.Remove());
  3074.         }
  3075.  
  3076.         /// <summary>
  3077.         /// Zobrazí okno s přílohami, kde si je uživatel může stáhnout.
  3078.         /// </summary>
  3079.         private void PrilohyButton_Click(object sender, EventArgs e)
  3080.         {
  3081.             if (pozastavSpousteniEventHandleru) return;
  3082.             new ShowAttachmentForm(aktualniZprava).ShowDialog();
  3083.         }
  3084.  
  3085.         /// <summary>
  3086.         /// Třída zajišťující funkčnost tlačítka zobrazení příloh.
  3087.         /// </summary>
  3088.         private class ShowAttachmentForm : AttachmentForm
  3089.         {
  3090.             /// <summary>
  3091.             /// Základní inicializace tohoto okna.
  3092.             /// </summary>
  3093.             /// <param name="aktualniZprava">Aktuální zpráva, jejíž přílohy chceme zobrazit.</param>
  3094.             public ShowAttachmentForm(ImapX.Message aktualniZprava)
  3095.             {
  3096.                 this.Icon = BarevnyMotiv.ikona;
  3097.                 base.InitializeComponent();
  3098.                 this.PridatButton.Click += new EventHandler(delegate (object sender, EventArgs e) { this.Close(); });
  3099.                 this.PridatButton.Text = "Zavřít";
  3100.                 this.Text = "Mail Agent 2017 - Zobrazit přílohy";
  3101.                 this.PopisLabel.Text = "Mějte na paměti, že soubory mohou obsahovat viry.";
  3102.  
  3103.                 // Na základě počtu příloh upravíme velikost okna.
  3104.                 if (aktualniZprava.Attachments.Count() > 5)
  3105.                 {
  3106.                     this.ClientSize = new System.Drawing.Size(384, this.ClientSize.Height + 36 * (aktualniZprava.Attachments.Count() - 5));
  3107.                     this.PridatButton.Location = new System.Drawing.Point(90, this.PridatButton.Location.Y + 36 * (aktualniZprava.Attachments.Count() - 5));
  3108.                 }
  3109.  
  3110.                 // Zobrazí přílohy.
  3111.                 for (int i = 0; i < aktualniZprava.Attachments.Count(); i++)
  3112.                     new ZobrazPrilohu(this, i, aktualniZprava.Attachments[i]);
  3113.             }
  3114.  
  3115.             /// <summary>
  3116.             /// Přepíšeme metodu, která se nachází v konstruktoru výchozí třídy a která by naši zděděnou třídu rozbila.
  3117.             /// </summary>
  3118.             public override void InicializujNovouPrilohu(object cesta) { }
  3119.  
  3120.             /// <summary>
  3121.             /// Třída poskytující základní funkce jedné příloze.
  3122.             /// </summary>
  3123.             internal class ZobrazPrilohu : Priloha
  3124.             {
  3125.                 private ImapX.Attachment priloha;
  3126.  
  3127.                 /// <summary>
  3128.                 /// Konstruktor inicializuje GUI jedné přílohy.
  3129.                 /// </summary>
  3130.                 /// <param name="okno">K jakému oknu GUI patří.</param>
  3131.                 /// <param name="kolikataPriloha">O kolikátou přílohu se jedná.</param>
  3132.                 /// <param name="priloha">Příloha.</param>
  3133.                 public ZobrazPrilohu(AttachmentForm okno, int kolikataPriloha, ImapX.Attachment priloha) : base (okno, kolikataPriloha)
  3134.                 {
  3135.                     this.tlacitko.Text = "Stáhnout";
  3136.                     this.label.Text = priloha.FileName;
  3137.                     this.priloha = priloha;
  3138.                 }
  3139.  
  3140.                 /// <summary>
  3141.                 /// Metoda stáhne přílohu do vybraného umístění.
  3142.                 /// </summary>
  3143.                 protected async override void OtevriSoubor(object sender, EventArgs e)
  3144.                 {
  3145.                     using (var ulozit = new FolderBrowserDialog())
  3146.                         if (ulozit.ShowDialog() == DialogResult.OK)
  3147.                         {
  3148.                             if (!priloha.Downloaded) await Task.Run(() => priloha.Download());
  3149.                             try { priloha.Save(@ulozit.SelectedPath, priloha.FileName); }
  3150.                             catch { }
  3151.                            
  3152.                             MessageBox.Show("Soubor byl úspěšně uložen.");
  3153.                         }
  3154.                 }
  3155.             }
  3156.         }
  3157.     }
  3158. }
  3159.  
  3160.  
  3161. using ImapX;
  3162. using System;
  3163. using System.Collections.Generic;
  3164. using System.Drawing;
  3165. using System.Linq;
  3166. using System.Text;
  3167. using System.Threading.Tasks;
  3168. using System.Windows.Forms;
  3169.  
  3170. namespace Mail_Agent_2017
  3171. {
  3172.     // Zde jsou hlavní metody pro náhledy stažených e-mailů a složky. Z důvodu konzistence kódu v samostatném souboru.
  3173.     public partial class MainForm
  3174.     {
  3175.         private List<SlozkaButton> vlastniSlozky;
  3176.  
  3177.         /// <summary>
  3178.         /// Tato metoda způsobí to, že po kliknutí na tlačítko dané složky tuto složku vybere. Mění GUI.
  3179.         /// </summary>
  3180.         private async void VyberSlozku(object sender, EventArgs e)
  3181.         {
  3182.             if (pozastavSpousteniEventHandleru) return;
  3183.  
  3184.             // Nejdřív odebereme highlight složky, která byla vybrána předtím.
  3185.             if (vybranaSlozka != null && vybranaSlozka is Button)
  3186.             {
  3187.                 ((Control)vybranaSlozka).Font = new Font(DorucenaPostaButton.Font, FontStyle.Regular);
  3188.                 ((Control)vybranaSlozka).BackColor = System.Drawing.SystemColors.Control;
  3189.                 ((Control)vybranaSlozka).ForeColor = System.Drawing.SystemColors.ActiveCaptionText;
  3190.             }
  3191.             else if (vybranaSlozka != null && vybranaSlozka is ZakladniSlozky)
  3192.                 switch (vybranaSlozka)
  3193.                 {
  3194.                     case ZakladniSlozky.Dorucene: DorucenaPostaButton.Font = new Font(DorucenaPostaButton.Font, FontStyle.Regular); DorucenaPostaButton.BackColor = System.Drawing.SystemColors.Control; DorucenaPostaButton.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; break;
  3195.                     case ZakladniSlozky.Odeslane: OdeslanaPostaButton.Font = new Font(OdeslanaPostaButton.Font, FontStyle.Regular); OdeslanaPostaButton.BackColor = System.Drawing.SystemColors.Control; OdeslanaPostaButton.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; break;
  3196.                     case ZakladniSlozky.Oznacene: OznaceneButton.Font = new Font(OznaceneButton.Font, FontStyle.Regular); OznaceneButton.BackColor = System.Drawing.SystemColors.Control; OznaceneButton.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; break;
  3197.                     case ZakladniSlozky.Dulezite: DuleziteButton.Font = new Font(DuleziteButton.Font, FontStyle.Regular); DuleziteButton.BackColor = System.Drawing.SystemColors.Control; DuleziteButton.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; break;
  3198.                     case ZakladniSlozky.Koncepty: KonceptyButton.Font = new Font(KonceptyButton.Font, FontStyle.Regular); KonceptyButton.BackColor = System.Drawing.SystemColors.Control; KonceptyButton.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; break;
  3199.                     case ZakladniSlozky.Spam: SpamButton.Font = new Font(SpamButton.Font, FontStyle.Regular); SpamButton.BackColor = System.Drawing.SystemColors.Control; SpamButton.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; break;
  3200.                     case ZakladniSlozky.Kos: KosButton.Font = new Font(KosButton.Font, FontStyle.Regular); KosButton.BackColor = System.Drawing.SystemColors.Control; KosButton.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; break;
  3201.                 }
  3202.  
  3203.             switch (((Control)sender).Name)
  3204.             {
  3205.                 case "DorucenaPostaButton": vybranaSlozka = ZakladniSlozky.Dorucene; break;
  3206.                 case "OdeslanaPostaButton": vybranaSlozka = ZakladniSlozky.Odeslane; break;
  3207.                 case "OznaceneButton": vybranaSlozka = ZakladniSlozky.Oznacene; break;
  3208.                 case "DuleziteButton": vybranaSlozka = ZakladniSlozky.Dulezite; break;
  3209.                 case "KonceptyButton": vybranaSlozka = ZakladniSlozky.Koncepty; break;
  3210.                 case "SpamButton": vybranaSlozka = ZakladniSlozky.Spam; break;
  3211.                 case "KosButton": vybranaSlozka = ZakladniSlozky.Kos; break;
  3212.                 default: vybranaSlozka = (Control)sender; break; // Pokud se nejedná o základní složku, do proměnné vybrané složky vložíme tlačítko dané složky.
  3213.             }
  3214.  
  3215.             ((Control)sender).BackColor = BarevnyMotiv.barvaTlacitek;
  3216.             ((Control)sender).ForeColor = Color.WhiteSmoke;
  3217.             ((Control)sender).Font = new Font(DorucenaPostaButton.Font, FontStyle.Bold);
  3218.            
  3219.             await Aktualizuj();
  3220.  
  3221.             if (stazeneEmaily.stazeneEmaily.Count != 0)
  3222.                 ZobrazEmail(stazeneEmaily.stazeneEmaily[0]);
  3223.         }
  3224.  
  3225.  
  3226.         /// <summary>
  3227.         /// Až dojedeme na konec panelu, stáhneme nové e-maily.
  3228.         /// </summary>
  3229.         private async void AktualizujPostu(object sender, ScrollEventArgs e)
  3230.         {
  3231.             if (pozastavSpousteniEventHandleru) return;
  3232.             if (sender == null || e.NewValue == EmailPanel.VerticalScroll.Maximum - EmailPanel.VerticalScroll.LargeChange + 1)
  3233.                 if (sender == null || e.NewValue != e.OldValue)
  3234.                 {
  3235.                     pozastavSpousteniEventHandleru = true;
  3236.  
  3237.                     LoadingPicturebox.Visible = true;
  3238.                     await stazeneEmaily.StahniEmaily(stazeneEmaily.stazeneEmaily.Count + 10);
  3239.  
  3240.                     pozastavSpousteniEventHandleru = false;
  3241.                     foreach (var email in stazeneEmaily.stazeneEmaily) email.NastavEventHandlery(ZobrazEmail);
  3242.                 }
  3243.         }
  3244.  
  3245.         /// <summary>
  3246.         /// Bohužel, event Scroll nereaguje na scrollování kolečkem myši. Na to máme tuhle metodu.
  3247.         /// </summary>
  3248.         private void MouseScroll(object sender, MouseEventArgs e)
  3249.         {
  3250.             if (EmailPanel.VerticalScroll.Value == EmailPanel.VerticalScroll.Maximum - EmailPanel.VerticalScroll.LargeChange + 1)
  3251.                 AktualizujPostu(null, null);
  3252.         }
  3253.  
  3254.         /// <summary>
  3255.         /// Každých N sekund budeme aktualizovat poštu, pokud server nepodporuje idle mód.
  3256.         /// </summary>
  3257.         private async Task Aktualizuj()
  3258.         {
  3259.             ZadneEmailyLabel.Visible = false;
  3260.             LoadingPicturebox.Visible = true;
  3261.  
  3262.             pozastavSpousteniEventHandleru = true;
  3263.  
  3264.             // Nyní smažeme veškerý obsah okna stažených e-mailů. Prostě vrátíme panel do původního stavu.
  3265.             foreach (var c in EmailPanel.Controls.Cast<Control>().ToArray()) if (c is Panel) c.Dispose();
  3266.             this.EmailPanel.VerticalScroll.Value = 0;
  3267.             this.LoadingPicturebox.Location = new System.Drawing.Point(145, 17);
  3268.  
  3269.             stazeneEmaily = new StazeneEmaily(aktualniPrihlaseni, vybranaSlozka, EmailPanel);
  3270.  
  3271.             await stazeneEmaily.StahniEmaily(1 + Screen.PrimaryScreen.Bounds.Height / 85);
  3272.  
  3273.             pozastavSpousteniEventHandleru = false;
  3274.             foreach (var email in stazeneEmaily.stazeneEmaily) email.NastavEventHandlery(ZobrazEmail);
  3275.         }
  3276.  
  3277.         /// <summary>
  3278.         /// Po opuštění textboxu upravíme jeho popisek v případě, že je prázdné.
  3279.         /// Naopak, pokud dojde k focusu textboxu a bude v něm popisek, tak ho smažeme.
  3280.         /// </summary>
  3281.         private void HledejTextbox_UpravaPopisku(object sender, EventArgs e)
  3282.         {
  3283.             const string popis = "Hledat e-mail";
  3284.  
  3285.             if (string.IsNullOrEmpty(((TextBox)sender).Text))
  3286.             {
  3287.                 ((TextBox)sender).ForeColor = Color.DimGray;
  3288.                 ((TextBox)sender).Text = popis;
  3289.                 ((TextBox)sender).TextAlign = HorizontalAlignment.Center;
  3290.             }
  3291.  
  3292.             else if (((TextBox)sender).Text == popis)
  3293.             {
  3294.                 ((TextBox)sender).ForeColor = Color.Black;
  3295.                 ((TextBox)sender).Text = "";
  3296.                 ((TextBox)sender).TextAlign = HorizontalAlignment.Left;
  3297.             }
  3298.         }
  3299.  
  3300.         /// <summary>
  3301.         /// Vyhledá v dané složce e-mail, jehož identifikační znaky (odesílatel, předmět) byly zadány do textboxu.
  3302.         /// </summary>
  3303.         private async void VyhledejEmail(object sender, KeyEventArgs e)
  3304.         {
  3305.             if (pozastavSpousteniEventHandleru) return;
  3306.             if (e.KeyCode != Keys.Enter) return;
  3307.             if (string.IsNullOrEmpty(((TextBox)sender).Text)) { EmailPanel.Focus(); return; } // Takový sprostý trik. Ztratíme fokus na hledacím textboxu tak, že ho nastavíme na nějaký nedůležitý prvek. Tím spustíme event, který upraví GUI textboxu a aktualizuje poštu.
  3308.            
  3309.             EmailPanel.VerticalScroll.Value = 0;
  3310.  
  3311.             ZadneEmailyLabel.Visible = false;
  3312.             LoadingPicturebox.Visible = true;
  3313.  
  3314.             pozastavSpousteniEventHandleru = true;
  3315.  
  3316.             foreach (var c in EmailPanel.Controls.Cast<Control>().ToArray()) if (c is Panel) c.Dispose();
  3317.             this.LoadingPicturebox.Location = new System.Drawing.Point(145, 17);
  3318.  
  3319.             var nalezeneZpravy = await stazeneEmaily.NajdiEmaily(((TextBox)sender).Text);
  3320.  
  3321.             LoadingPicturebox.Visible = false;
  3322.  
  3323.             if (nalezeneZpravy.Count == 0) ZadneEmailyLabel.Visible = true;
  3324.  
  3325.             else await Task.Run(() =>
  3326.             {
  3327.                 for (int i = 0; i < nalezeneZpravy.Count(); i++)
  3328.                     stazeneEmaily.stazeneEmaily.Add(new StazeneEmaily.JedenEmail(nalezeneZpravy[i], i, EmailPanel, aktualniPrihlaseni));
  3329.             });
  3330.  
  3331.             pozastavSpousteniEventHandleru = false;
  3332.             if (stazeneEmaily != null) foreach (var email in stazeneEmaily.stazeneEmaily) email.NastavEventHandlery(ZobrazEmail);
  3333.            
  3334.         }
  3335.  
  3336.  
  3337.         /// <summary>
  3338.         /// Vytvoří GUI vlastních složek.
  3339.         /// </summary>
  3340.         /// <param name="jake">Jaké složky má vložit do GUI.</param>
  3341.         private void VlastniSlozky(List<string> jake)
  3342.         {
  3343.             if (vlastniSlozky != null) foreach (var slozka in vlastniSlozky) slozka.Dispose();
  3344.             vlastniSlozky = new List<SlozkaButton>();
  3345.  
  3346.             for (int i = 0; i < jake.Count; i++)
  3347.             {
  3348.                 vlastniSlozky.Add(new SlozkaButton(476 + 68 * i, jake[i]));
  3349.                 vlastniSlozky[i].Click += new EventHandler(VyberSlozku);
  3350.                 SlozkaPanel.Controls.Add(vlastniSlozky[i]);
  3351.             }
  3352.  
  3353.         }
  3354.  
  3355.         /// <summary>
  3356.         /// Jedná se o tlačítko s GUI pro složku. Pro jednodušší inicializaci objektů tohoto typu.
  3357.         /// </summary>
  3358.         private class SlozkaButton : Button
  3359.         {
  3360.             /// <summary>
  3361.             /// Inicializace tlačítka.
  3362.             /// </summary>
  3363.             /// <param name="pozice">Na jaké Y-ové souřadnici se má vyskytovat.</param>
  3364.             /// <param name="text">Text tlačítka.</param>
  3365.             public SlozkaButton(int pozice, string text) : base()
  3366.             {
  3367.                 Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
  3368.                 | System.Windows.Forms.AnchorStyles.Right)));
  3369.                 BackColor = System.Drawing.SystemColors.Control;
  3370.                 FlatAppearance.BorderSize = 0;
  3371.                 FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  3372.                 Font = new System.Drawing.Font("Calibri", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
  3373.                 ForeColor = System.Drawing.SystemColors.ActiveCaptionText;
  3374.                 Location = new System.Drawing.Point(0, pozice);
  3375.                 Margin = new System.Windows.Forms.Padding(0);
  3376.                 Name = "ADDED_MANUALLY";
  3377.                 Size = new System.Drawing.Size(194, 68);
  3378.                 TabIndex = 5;
  3379.                 Text = text;
  3380.                 UseVisualStyleBackColor = false;
  3381.             }
  3382.         }
  3383.  
  3384.         /// <summary>
  3385.         /// Najdé tlačítko dané složky.
  3386.         /// </summary>
  3387.         /// <param name="slozka">Tlačítko jaké složky se má najít.</param>
  3388.         /// <returns>Odkaz na tlačítko.</returns>
  3389.         private Button NajdiTlacitko(object slozka)
  3390.         {
  3391.             if (slozka is ZakladniSlozky)
  3392.                 switch (slozka)
  3393.                 {
  3394.                     case ZakladniSlozky.Dorucene: return DorucenaPostaButton;
  3395.                     case ZakladniSlozky.Odeslane: return OdeslanaPostaButton;
  3396.                     case ZakladniSlozky.Oznacene: return OznaceneButton;
  3397.                     case ZakladniSlozky.Dulezite: return DuleziteButton;
  3398.                     case ZakladniSlozky.Koncepty: return KonceptyButton;
  3399.                     case ZakladniSlozky.Spam: return SpamButton;
  3400.                     case ZakladniSlozky.Kos: return KosButton;
  3401.                 }
  3402.             else if (slozka is Button) return (Button)slozka;
  3403.             else if (slozka is string) // Teď nějak nevím, jestli toto vlastně může nastat.
  3404.                 foreach (Control c in SlozkaPanel.Controls) if (c is Button && ((Button)c).Name == slozka.ToString()) return (Button)c;
  3405.  
  3406.             return null;
  3407.         }
  3408.     }
  3409. }
  3410.  
  3411. using System;
  3412. using System.IO;
  3413. using System.Windows.Forms;
  3414.  
  3415. namespace Mail_Agent_2017
  3416. {
  3417.     /// <summary>
  3418.     /// Zobrazí manuálové stránky.
  3419.     /// </summary>
  3420.     public partial class ManualForm : Form
  3421.     {
  3422.         /// <summary>
  3423.         /// Inicializace nejdůležitějších komponent pro toto okno.
  3424.         /// </summary>
  3425.         public ManualForm()
  3426.         {
  3427.             this.Icon = BarevnyMotiv.ikona;
  3428.             InitializeComponent();
  3429.  
  3430.             StreamReader soubor = null;
  3431.  
  3432.             try
  3433.             {
  3434.                 ManualWebbrowser.Url = new Uri("https://www.ms.mff.cuni.cz/~riedell/MA2017/help/index.html");
  3435.                 // soubor = new StreamReader("help/index.html");
  3436.                 // ManualWebbrowser.DocumentText = soubor.ReadToEnd();
  3437.             }
  3438.             catch
  3439.             {
  3440.                 ManualWebbrowser.DocumentText = "<!DOCTYPE html><html><body>" +
  3441.                     "<div style=\"text-align: center; font-family: Calibri; font-size: 32px; color: red; position: relative; top: 150px;\">" +
  3442.                     "Soubor s nápovědou nebyl nalezen." +
  3443.                     "</div></body></html>";
  3444.             }
  3445.             finally
  3446.             {
  3447.                 if (soubor != null) soubor.Close();
  3448.             }
  3449.         }
  3450.  
  3451.         /// <summary>
  3452.         /// Zavře okno s nápovědou.
  3453.         /// </summary>
  3454.         private void ZavritButton_Click(object sender, EventArgs e)
  3455.         {
  3456.             this.Close();
  3457.         }
  3458.     }
  3459. }
  3460.  
  3461. using System;
  3462. using System.Collections.Generic;
  3463. using System.Drawing;
  3464. using System.IO;
  3465. using System.Linq;
  3466. using System.Text;
  3467.  
  3468. namespace Mail_Agent_2017
  3469. {
  3470.     /// <summary>
  3471.     /// Definuje barvu celé aplikace.
  3472.     /// </summary>
  3473.     public static class BarevnyMotiv
  3474.     {
  3475.         internal static Color barvaTlacitek;
  3476.         internal static Image logo;
  3477.         internal static Icon ikona;
  3478.  
  3479.         /// <summary>
  3480.         /// Barvy, které má uživatel na výběr.
  3481.         /// Dalo by se říct, že hlavní barva aplikace přímo závisí na tomto výčtovém typu.
  3482.         /// </summary>
  3483.         public enum BarevnaPaleta
  3484.         {
  3485.             /// <summary>
  3486.             /// Modrá barva RGB(28, 139, 196)
  3487.             /// </summary>
  3488.             Modra,
  3489.             /// <summary>
  3490.             /// Červená barva RGB(196, 28, 56)
  3491.             /// </summary>
  3492.             Cervena,
  3493.             /// <summary>
  3494.             /// Zelená barva RGB(140, 196, 28)
  3495.             /// </summary>
  3496.             Zelena,
  3497.             /// <summary>
  3498.             /// Černá barva RGB(32, 32, 32)
  3499.             /// </summary>
  3500.             Cerna,
  3501.             /// <summary>
  3502.             /// Šedá barva RGB(134, 136, 138)
  3503.             /// </summary>
  3504.             Seda,
  3505.             /// <summary>
  3506.             /// Žlutá barva RGB(252, 209, 22)
  3507.             /// </summary>
  3508.             Zluta
  3509.         }
  3510.  
  3511.         /// <summary>
  3512.         /// Vrací barvu na základě hodnoty výčtového typu.
  3513.         /// </summary>
  3514.         /// <param name="barva">Barva, jejíž RGB hodnota se má vrátit.</param>
  3515.         /// <returns>Chtěná barva.</returns>
  3516.         internal static object NastavBarvyTlacitek(BarevnaPaleta barva)
  3517.         {
  3518.             switch (barva)
  3519.             {
  3520.                 case BarevnaPaleta.Modra: return Color.FromArgb(((int)(((byte)(28)))), ((int)(((byte)(139)))), ((int)(((byte)(196)))));
  3521.                 case BarevnaPaleta.Cervena: return Color.FromArgb(((int)(((byte)(196)))), ((int)(((byte)(28)))), ((int)(((byte)(56)))));
  3522.                 case BarevnaPaleta.Zelena: return Color.FromArgb(((int)(((byte)(140)))), ((int)(((byte)(196)))), ((int)(((byte)(28)))));
  3523.                 case BarevnaPaleta.Cerna: return Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(32)))), ((int)(((byte)(32)))));
  3524.                 case BarevnaPaleta.Seda: return Color.FromArgb(((int)(((byte)(134)))), ((int)(((byte)(136)))), ((int)(((byte)(138)))));
  3525.                 case BarevnaPaleta.Zluta: return Color.FromArgb(((int)(((byte)(252)))), ((int)(((byte)(209)))), ((int)(((byte)(22)))));
  3526.             }
  3527.  
  3528.             return null;
  3529.         }
  3530.  
  3531.         /// <summary>
  3532.         /// Vrací barvu loga na základě hodnoty výčtového typu.
  3533.         /// </summary>
  3534.         /// <param name="barva">Barva loga, jež se má vrátit.</param>
  3535.         /// <returns>Chtěná barva loga.</returns>
  3536.         private static object NastavBarvuLoga(BarevnaPaleta barva)
  3537.         {
  3538.             switch (barva)
  3539.             {
  3540.                 case BarevnaPaleta.Modra: return global::Mail_Agent_2017.Properties.Resources.LogoModre;
  3541.                 case BarevnaPaleta.Cervena: return global::Mail_Agent_2017.Properties.Resources.LogoCervene;
  3542.                 case BarevnaPaleta.Zelena: return global::Mail_Agent_2017.Properties.Resources.LogoZelene;
  3543.                 case BarevnaPaleta.Cerna: return global::Mail_Agent_2017.Properties.Resources.LogoCerne;
  3544.                 case BarevnaPaleta.Seda: return global::Mail_Agent_2017.Properties.Resources.LogoSede;
  3545.                 case BarevnaPaleta.Zluta: return global::Mail_Agent_2017.Properties.Resources.LogoZlute;
  3546.             }
  3547.  
  3548.             return null;
  3549.         }
  3550.  
  3551.         /// <summary>
  3552.         /// Vrací barvu ikony na základě výčtového typu.
  3553.         /// </summary>
  3554.         /// <param name="barva">Barva ikony, jež se má vrátit.</param>
  3555.         /// <returns>Chtěná barva ikony.</returns>
  3556.         private static object NastavBarvuIkony(BarevnaPaleta barva)
  3557.         {
  3558.             switch (barva)
  3559.             {
  3560.                 case BarevnaPaleta.Modra: return global::Mail_Agent_2017.Properties.Resources.IkonaModra;
  3561.                 case BarevnaPaleta.Cervena: return global::Mail_Agent_2017.Properties.Resources.IkonaCervena;
  3562.                 case BarevnaPaleta.Zelena: return global::Mail_Agent_2017.Properties.Resources.IkonaZelena;
  3563.                 case BarevnaPaleta.Cerna: return global::Mail_Agent_2017.Properties.Resources.IkonaCerna;
  3564.                 case BarevnaPaleta.Seda: return global::Mail_Agent_2017.Properties.Resources.IkonaSeda;
  3565.                 case BarevnaPaleta.Zluta: return global::Mail_Agent_2017.Properties.Resources.IkonaZluta;
  3566.             }
  3567.  
  3568.             return null;
  3569.         }
  3570.  
  3571.         /// <summary>
  3572.         /// Pomocí této vlastnosti nastavujeme barvevný motiv. K této vlastnosti přistupujeme v nastavení aplikace nebo při startu aplikace.
  3573.         /// </summary>
  3574.         public static BarevnaPaleta Barva
  3575.         {
  3576.             get
  3577.             {
  3578.                 if (barvaTlacitek != null && logo != null && ikona != null)
  3579.                     foreach (var barva in Enum.GetValues(typeof(BarevnaPaleta)))
  3580.                         if (barvaTlacitek == (Color)NastavBarvyTlacitek((BarevnaPaleta)barva))
  3581.                             return (BarevnaPaleta)barva;
  3582.                 return BarevnaPaleta.Modra;
  3583.             }
  3584.             set
  3585.             {
  3586.                 // Každou změnu barevného motivu zapíšeme do souboru.
  3587.                 // Při první inicializaci ne, protože se načítá hodnota ze souboru, pokud je hodnota inicializovaná.
  3588.                 if (barvaTlacitek != null && logo != null && ikona != null)
  3589.                 {
  3590.                     StreamWriter nastaveni = new StreamWriter(".settings");
  3591.                     nastaveni.WriteLine((int)value);
  3592.                     nastaveni.Close();
  3593.                 }
  3594.  
  3595.                 barvaTlacitek = (Color)NastavBarvyTlacitek(value);
  3596.                 logo = (Image)NastavBarvuLoga(value);
  3597.                 ikona = (Icon)NastavBarvuIkony(value);
  3598.  
  3599.                
  3600.             }
  3601.         }
  3602.     }
  3603. }
  3604.  
  3605. using System;
  3606. using System.Text;
  3607. using System.Security.Cryptography;
  3608. using ImapX;
  3609. using System.Net.Mail;
  3610. using System.Net;
  3611. using System.IO;
  3612. using System.Windows.Forms;
  3613. using System.Collections.Generic;
  3614. using System.Drawing;
  3615. using System.Web;
  3616.  
  3617. namespace Mail_Agent_2017
  3618. {
  3619.     /// <summary>
  3620.     /// Třída sdružující informace o aktuálním přihlášení.
  3621.     /// </summary>
  3622.     public class Prihlaseni
  3623.     {
  3624.         internal string _email;
  3625.         internal string _heslo;
  3626.         internal string _jmeno;
  3627.         /// <summary>
  3628.         /// Aktuální IMAP připojení.
  3629.         /// </summary>
  3630.         public ImapClient ImapPripojeni;
  3631.         /// <summary>
  3632.         /// Aktuální SMTP připojení.
  3633.         /// </summary>
  3634.         public SmtpClient SmtpPripojeni;
  3635.         /// <summary>
  3636.         /// Jak často se budou aktualizovat e-maily.
  3637.         /// </summary>
  3638.         public int refresh;
  3639.  
  3640.         /// <summary>
  3641.         /// E-mail daného přihlášení.
  3642.         /// </summary>
  3643.         public string Email
  3644.         {
  3645.             get { return _email == null ? null : Sifrovani.Decrypt(_email); }
  3646.             set { _email = Sifrovani.Encrypt(value); }
  3647.         }
  3648.  
  3649.         /// <summary>
  3650.         /// Heslo daného přihlášení.
  3651.         /// </summary>
  3652.         public string Heslo
  3653.         {
  3654.             get { return _heslo == null ? null : Sifrovani.Decrypt(_heslo); }
  3655.             set { _heslo = Sifrovani.Encrypt(value); }
  3656.         }
  3657.  
  3658.         /// <summary>
  3659.         /// Jméno daného přihlášení.
  3660.         /// </summary>
  3661.         public string Jmeno
  3662.         {
  3663.             get { return _jmeno == null ? null : Sifrovani.Decrypt(_jmeno); }
  3664.             set { _jmeno = Sifrovani.Encrypt(value); }
  3665.         }
  3666.  
  3667.         /// <summary>
  3668.         /// Uloží aktuální přihlášení do souboru, aby při příštím přihlášení uživatel nemusel znovu podstupovat přihlašovací proces.
  3669.         /// </summary>
  3670.         public void UlozPrihlaseniDoSouboru()
  3671.         {
  3672.             try
  3673.             {
  3674.                 if (_email == null || _heslo == null || _jmeno == null || ImapPripojeni == null || SmtpPripojeni == null)
  3675.                     throw new ChybneZadaniException("Nepodařilo se uložit aktuální relaci. Při příštím spuštění aplikace se budete muset znovu přihlásit.");
  3676.             }
  3677.  
  3678.             catch (ChybneZadaniException ex)
  3679.                 { MessageBox.Show(ex.Message); return; }
  3680.  
  3681.             StreamWriter prihlaseniSoubor = new StreamWriter(".login_info");
  3682.  
  3683.             prihlaseniSoubor.WriteLine("{0} {1} {2} {3}", _email, _heslo, _jmeno, (refresh == 0 ? 840 : refresh)); // Pokud není refresh nastaven, defaultní nastavení bude 840 sekund. To je doba, po které IMAP server uzavře spojení s klientem, pokud nedojde k obnovení spojení.
  3684.             prihlaseniSoubor.WriteLine("{0} {1} {2}", ImapPripojeni.Host, ImapPripojeni.Port, ImapPripojeni.UseSsl);
  3685.             prihlaseniSoubor.WriteLine("{0} {1} {2} {3}", SmtpPripojeni.Host, SmtpPripojeni.Port, SmtpPripojeni.EnableSsl, !SmtpPripojeni.UseDefaultCredentials);
  3686.  
  3687.             prihlaseniSoubor.Close();
  3688.         }
  3689.  
  3690.         /// <summary>
  3691.         /// Načte poslední přihlášení ze souboru, pokud existuje.
  3692.         /// </summary>
  3693.         public bool NactiPrihlaseniZeSouboru()
  3694.         {
  3695.             try
  3696.             {
  3697.                 StreamReader prihlaseniSoubor = new StreamReader(".login_info");
  3698.  
  3699.                 string[] prihlaseni = prihlaseniSoubor.ReadLine().Split(' ');
  3700.                 string[] IMAP = prihlaseniSoubor.ReadLine().Split(' ');
  3701.                 string[] SMTP = prihlaseniSoubor.ReadLine().Split(' ');
  3702.  
  3703.                 this._email = prihlaseni[0];
  3704.                 this._heslo = prihlaseni[1];
  3705.                 this._jmeno = prihlaseni[2];
  3706.                 this.refresh = int.Parse(prihlaseni[3]);
  3707.  
  3708.                 this.ImapPripojeni = new ImapClient(IMAP[0], int.Parse(IMAP[1]), bool.Parse(IMAP[2]));
  3709.  
  3710.                 this.SmtpPripojeni = new SmtpClient(SMTP[0], int.Parse(SMTP[1]));
  3711.                 this.SmtpPripojeni.EnableSsl = bool.Parse(SMTP[2]);
  3712.                 if (bool.Parse(SMTP[3]))
  3713.                 {
  3714.                     this.SmtpPripojeni.UseDefaultCredentials = false;
  3715.                     this.SmtpPripojeni.Credentials = new NetworkCredential(Email, Heslo);                
  3716.                 }
  3717.  
  3718.                 // Pokud se nepovede přihlášení k IMAP serveru, bude uživatel vyzván, aby se přihlásil znovu.
  3719.                 if (!ImapPripojeni.Connect() || !ImapPripojeni.Login(Email, Heslo))
  3720.                     throw new ImapConnectFailException("Přihlášení bylo neúspěšné. Přihlašte se, prosím, znovu.");
  3721.  
  3722.                 prihlaseniSoubor.Close();
  3723.             }
  3724.  
  3725.             catch (Exception ex)
  3726.             {
  3727.                 if (ex is ImapConnectFailException)
  3728.                     MessageBox.Show(ex.Message);
  3729.  
  3730.                 // Pokud dojde k jiné výjimce, například chybný nebo prázdný vstup, uživatele s tím ani obeznamovat nebudeme. Nemusí vědět všechno.
  3731.                 return false;
  3732.             }    
  3733.  
  3734.             return true;
  3735.         }
  3736.  
  3737.         /// <summary>
  3738.         /// Odhlásí se a odstraní soubor s přihlášením.
  3739.         /// </summary>
  3740.         public void OdhlasitSe()
  3741.         {  
  3742.             File.Delete(".login_info");
  3743.             SmtpPripojeni.Dispose();
  3744.             ImapPripojeni.Disconnect();
  3745.             ImapPripojeni.Dispose();
  3746.             _email = null;
  3747.             _heslo = null;
  3748.             _jmeno = null;
  3749.         }
  3750.     }
  3751.     /// <summary>
  3752.     /// Třída poskytující drobné utility, které se hodí (nejen) u přihlašování.
  3753.     /// </summary>
  3754.     public static class Utility
  3755.     {
  3756.         /// <summary>
  3757.         /// Metoda rozhoduje, zdali má zadaná adresa správný formát.
  3758.         /// </summary>
  3759.         /// <param name="email">E-mailová adresa, která má být zkontrolována.</param>
  3760.         /// <returns>Úspěch v případě správného formátu adresy, neúspěch v opačném případě.</returns>
  3761.         public static bool SpravnyFormatAdresy(string email)
  3762.         {
  3763.             // Využijeme třídu .NET pro emailové adresy a pokusíme se vytvořit novou emailovou adresu.
  3764.             // V případě neúspěchu vyvolá výjimku - tedy v případě, že adresa má nesprávný formát.
  3765.             try { return new System.Net.Mail.MailAddress(email).Address == email; }
  3766.             catch { return false; }
  3767.         }
  3768.  
  3769.         /// <summary>
  3770.         /// Metoda se pokusí připojit k SMTP serveru podle údajů, které zadal uživatel.
  3771.         /// Také se pokusí poslat testovací zprávu, jakožto indikátor úspěšného připojení,
  3772.         /// </summary>
  3773.         /// <returns>V případě úspěšného připojení odkaz na objekt SmtpClient, v opačném případě null.</returns>
  3774.         public static SmtpClient SmtpConnect(string SmtpServer, int SmtpPort, bool SmtpSsl, bool SmtpAuth, string email, string heslo)
  3775.         {
  3776.             // Zde nemusíme ověřovat (v případě zaškrtnutého checkboxu Auth), zdali se e-mailová adresa shoduje s heslem, vlastně ani nemáme jak.
  3777.             // Proč nemusíme? Ověří to za nás připojení k IMAP serveru, které předchází připojení k SMTP serveru.
  3778.  
  3779.             SmtpClient SmtpPripojeni = new SmtpClient(SmtpServer, SmtpPort);
  3780.             SmtpPripojeni.EnableSsl = SmtpSsl;
  3781.             if (SmtpAuth)
  3782.             {
  3783.                 SmtpPripojeni.UseDefaultCredentials = false;
  3784.                 SmtpPripojeni.Credentials = new NetworkCredential(email, heslo);
  3785.             }
  3786.                
  3787.  
  3788.             // Metoda vyvolá výjimku, když se nepodaří odeslat zprávu.
  3789.             try
  3790.             {
  3791.                 SmtpPripojeni.Send(email , email, "Mail Agent 2017 - Testovací zpráva", @"Přihlášení do aplikace proběhlo úspěšně.");
  3792.                 return SmtpPripojeni;
  3793.             }
  3794.             catch
  3795.                 { return null; }
  3796.  
  3797.         }
  3798.  
  3799.         /// <summary>
  3800.         /// Spustí přihlašovací proces.
  3801.         /// </summary>
  3802.         /// <param name="aktualniPrihlaseni">Relace přihlášení, která má být inicializována.</param>
  3803.         public static void PrihlasovaciProces(ref Prihlaseni aktualniPrihlaseni)
  3804.         {
  3805.             Stack<Form> prihlasovaciProces = new Stack<Form>();
  3806.             if (!aktualniPrihlaseni.NactiPrihlaseniZeSouboru())
  3807.             {
  3808.                 /*
  3809.                  * Přihlašovací proces je řešený pomocí zásobníku oken.
  3810.                  * Při kliknutí na tlačítko "Zpět" se do zásobníku pushne předchozí okno, aby uživatel mohl provést změny.
  3811.                  * Přihlašovací proces končí, když je zásobník prázdný.
  3812.                  */
  3813.  
  3814.                 prihlasovaciProces.Push(new LoginForm1(aktualniPrihlaseni, prihlasovaciProces));
  3815.  
  3816.                 while (prihlasovaciProces.Count > 0)
  3817.                     prihlasovaciProces.Pop().ShowDialog();
  3818.  
  3819.                 // Pokud neprobělo přihlášení, dojde k ukončení celé aplikace.
  3820.                 if (aktualniPrihlaseni.ImapPripojeni == null || aktualniPrihlaseni.SmtpPripojeni == null || aktualniPrihlaseni.Email == null || aktualniPrihlaseni.Heslo == null)
  3821.                     Environment.Exit(0);
  3822.  
  3823.                 // Uložíme aktuální relaci do souboru, abychom ji při příštím spuštění aplikace mohli snadno načíst.
  3824.                 aktualniPrihlaseni.UlozPrihlaseniDoSouboru();
  3825.             }
  3826.         }
  3827.  
  3828.         /// <summary>
  3829.         /// Třída, která projde adresář a vypíše kontakty, které se nachází v dané skupině.
  3830.         /// </summary>
  3831.         /// <param name="adresar">Jaký adresář se má prohledat.</param>
  3832.         /// <param name="skupina">Skupina.</param>
  3833.         /// <returns>Seznam kontaktů ve skupině.</returns>
  3834.         public static List<Kontakt> VypisKontaktyVeSkupine(Adresar adresar, Skupina skupina)
  3835.         {
  3836.             List<Kontakt> clenoveSkupiny = new List<Kontakt>();
  3837.             foreach (Kontakt kontakt in adresar.seznamKontaktu)
  3838.                 if (kontakt.Skupina == skupina.Nazev)
  3839.                     clenoveSkupiny.Add(kontakt);
  3840.             return clenoveSkupiny;
  3841.         }
  3842.     }
  3843.  
  3844.     /// <summary>
  3845.     /// Následující třída poskytuje šifrovací a dešifrovací funkce.
  3846.     /// Autorem metod nejsem já, byly použity šifrovací funkce nalezené na internetu.
  3847.     /// </summary>
  3848.     public static class Sifrovani
  3849.     {
  3850.         private static readonly string PasswordHash = "h€$$łö";
  3851.         private static readonly string SaltKey = "M@iL&g€n†2oI7";
  3852.         private static readonly string VIKey = "@1B2c3D4e5F6g7H8";
  3853.  
  3854.         /// <summary>
  3855.         /// Metoda šifrující daný text.
  3856.         /// </summary>
  3857.         /// <param name="plainText">Text, který se má zašifrovat.</param>
  3858.         /// <returns>Zašifrovaný text.</returns>
  3859.         internal static string Encrypt(string plainText)
  3860.         {
  3861.             byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText.ToString());
  3862.  
  3863.             byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
  3864.             var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
  3865.             var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
  3866.  
  3867.             byte[] cipherTextBytes;
  3868.  
  3869.             using (var memoryStream = new MemoryStream())
  3870.             {
  3871.                 using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
  3872.                 {
  3873.                     cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
  3874.                     cryptoStream.FlushFinalBlock();
  3875.                     cipherTextBytes = memoryStream.ToArray();
  3876.                     cryptoStream.Close();
  3877.                 }
  3878.                 memoryStream.Close();
  3879.             }
  3880.  
  3881.             return HttpUtility.UrlEncode(Convert.ToBase64String(cipherTextBytes));
  3882.         }
  3883.  
  3884.         /// <summary>
  3885.         /// Metoda dešifrující daný text.
  3886.         /// </summary>
  3887.         /// <param name="encryptedText">Text, který se má dešifrovat.</param>
  3888.         /// <returns>Dešifrovaný text.</returns>
  3889.         internal static string Decrypt(string encryptedText)
  3890.         {
  3891.             byte[] cipherTextBytes = Convert.FromBase64String(HttpUtility.UrlDecode(encryptedText.ToString()));
  3892.             byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
  3893.             var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };
  3894.  
  3895.             var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
  3896.             var memoryStream = new MemoryStream(cipherTextBytes);
  3897.             var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
  3898.             byte[] plainTextBytes = new byte[cipherTextBytes.Length];
  3899.  
  3900.             int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
  3901.             memoryStream.Close();
  3902.             cryptoStream.Close();
  3903.             return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("\0".ToCharArray());
  3904.         }
  3905.  
  3906.         /// <summary>
  3907.         /// Metoda šifrující bitmapu do stringu.
  3908.         /// </summary>
  3909.         /// <param name="bitmap">Bitmapa, která se má zašifrovat.</param>
  3910.         /// <returns>Stringová hodnota dané bitmapy.</returns>
  3911.         internal static string BitmapToString(Bitmap bitmap)
  3912.         {
  3913.             MemoryStream memoryStream = new MemoryStream();
  3914.             bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
  3915.             byte[] bitmapBytes = memoryStream.GetBuffer();
  3916.             return Convert.ToBase64String(bitmapBytes, Base64FormattingOptions.None);
  3917.         }
  3918.  
  3919.         /// <summary>
  3920.         /// Metoda dešifrující bitmapu ze stringu.
  3921.         /// </summary>
  3922.         /// <param name="bitmapString">Bitmapa, která se má dešifrovat. Vložena jako text.</param>
  3923.         /// <returns>Objekt bitmapy.</returns>
  3924.         internal static Bitmap StringToBitmap(string bitmapString)
  3925.         {
  3926.             byte[] bitmapBytes = Convert.FromBase64String(bitmapString);
  3927.             MemoryStream memoryStream = new MemoryStream(bitmapBytes);
  3928.             return (Bitmap)(Image.FromStream(memoryStream));
  3929.         }
  3930.     }
  3931.  
  3932.     /// <summary>
  3933.     /// Vyrobíme si okno podobné příkazu prompt v Javascriptu.
  3934.     /// Přišlo mi zbytečné na to vytvářet další soubor s designerem, když je na to potřeba pár řádek kódu.
  3935.     /// </summary>
  3936.     public class Prompt
  3937.     {
  3938.         /// <summary>
  3939.         /// Implementace metody ShowDialog. Podobná té klasické ShowDialog ze třídy Form.
  3940.         /// </summary>
  3941.         /// <param name="text">Text, který se zobrazí v labelu.</param>
  3942.         /// <param name="popis">Název okna.</param>
  3943.         /// <param name="maxDelka">Maximální délka vstupu. Pokud je nastavena -1, pak nekonečno.</param>
  3944.         /// <returns>V případě úspěchu bude okno vracet obsah textboxu.</returns>
  3945.         public string ShowDialog(string text, string popis, int maxDelka)
  3946.         {
  3947.             Form prompt = new Form()
  3948.             {
  3949.                 Width = 500,
  3950.                 Height = 150,
  3951.                 FormBorderStyle = FormBorderStyle.FixedDialog,
  3952.                 Text = popis,
  3953.                 StartPosition = FormStartPosition.CenterScreen,
  3954.                 MaximizeBox = false,
  3955.                 MinimizeBox = false
  3956.             };
  3957.  
  3958.             Label label = new Label() { Left = 50, Top = 20, Text = text, Width = 400 };
  3959.             TextBox textbox = new TextBox() { Left = 50, Top = 40, Width = 400 };
  3960.             Button tlacitko = new Button() { Text = "Potvrdit", Left = 350, Width = 100, Top = 70, DialogResult = DialogResult.OK };
  3961.             tlacitko.Click += (sender, e) => { prompt.Close(); };
  3962.             if (maxDelka != -1) textbox.MaxLength = maxDelka;
  3963.             prompt.Controls.Add(textbox);
  3964.             prompt.Controls.Add(tlacitko);
  3965.             prompt.Controls.Add(label);
  3966.             prompt.AcceptButton = tlacitko;
  3967.  
  3968.             // V případě úspěchu bude okno vracet obsah textboxu.
  3969.             return prompt.ShowDialog() == DialogResult.OK ? textbox.Text : null;
  3970.         }
  3971.     }
  3972. }
  3973.  
  3974. using System;
  3975. using System.Collections.Generic;
  3976. using System.ComponentModel;
  3977. using System.Drawing;
  3978. using System.Linq;
  3979. using System.Text;
  3980. using System.Threading.Tasks;
  3981. using System.Windows.Forms;
  3982.  
  3983. namespace Mail_Agent_2017
  3984. {
  3985.     /// <summary>
  3986.     /// Výčtový typ definující základní složky.
  3987.     /// </summary>
  3988.     public enum ZakladniSlozky
  3989.     {
  3990.         /// <summary>
  3991.         /// Doručená pošta.
  3992.         /// </summary>
  3993.         Dorucene,
  3994.         /// <summary>
  3995.         /// Odeslaná pošta.
  3996.         /// </summary>
  3997.         Odeslane,
  3998.         /// <summary>
  3999.         /// Odstraněná pošta.
  4000.         /// </summary>
  4001.         Kos,
  4002.         /// <summary>
  4003.         /// Nevyžádaná pošta.
  4004.         /// </summary>
  4005.         Spam,
  4006.         /// <summary>
  4007.         /// Označená pošta.
  4008.         /// </summary>
  4009.         Oznacene,
  4010.         /// <summary>
  4011.         /// Důležitá pošta.
  4012.         /// </summary>
  4013.         Dulezite,
  4014.         /// <summary>
  4015.         /// Koncepty.
  4016.         /// </summary>
  4017.         Koncepty
  4018.     }
  4019.  
  4020.     /// <summary>
  4021.     /// Delegát pro obsluhu události zobrazení jednoho e-mailu.
  4022.     /// </summary>
  4023.     /// <param name="sender">Jaký e-mail se má zobrazit.</param>
  4024.     public delegate void ZobrazEmailEventHandler(object sender);
  4025.  
  4026.     /// <summary>
  4027.     /// Objekty této třídy budou obsahovat stažené e-maily z IMAP serveru.
  4028.     /// </summary>
  4029.     public class StazeneEmaily
  4030.     {
  4031.         private Prihlaseni aktualniPrihlaseni;
  4032.         internal ImapX.Folder slozka;
  4033.         private Panel panel;
  4034.  
  4035.         /// <summary>
  4036.         /// V tomto seznamu budeme uchovávaz informace o stažených e-mailech, včetně jejich GUI.
  4037.         /// </summary>
  4038.         internal List<JedenEmail> stazeneEmaily;
  4039.  
  4040.         /// <summary>
  4041.         /// Konstruktor stahuje požadované e-maily z IMAP serveru.
  4042.         /// </summary>
  4043.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení a údaje o IMAP serveru, z kterého se mají e-maily stáhnout.</param>
  4044.         /// <param name="slozka">Složka, která se má stáhnout.</param>
  4045.         /// <param name="panel">Panel, ke kterému se tato část kódu váže. Kvůli úpravě GUI.</param>
  4046.         public StazeneEmaily(Prihlaseni aktualniPrihlaseni, object slozka, Panel panel)
  4047.         {
  4048.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  4049.             this.panel = panel;
  4050.             this.stazeneEmaily = new List<JedenEmail>();
  4051.  
  4052.             string nazevSlozky = ""; // Toto využijeme pouze v případě, že náš poskytovatel nemá v základu běžné složky. Třeba seznam.cz.
  4053.  
  4054.             if (slozka is Button)
  4055.                 this.slozka = aktualniPrihlaseni.ImapPripojeni.Folders[((Button)slozka).Text];
  4056.             else if (slozka is ZakladniSlozky)
  4057.             {
  4058.                 switch (slozka)
  4059.                 {
  4060.                     case ZakladniSlozky.Dorucene: this.slozka = aktualniPrihlaseni.ImapPripojeni.Folders.Inbox; nazevSlozky = "Doručená pošta"; break;
  4061.                     case ZakladniSlozky.Odeslane: this.slozka = aktualniPrihlaseni.ImapPripojeni.Folders.Sent; nazevSlozky = "Odeslaná pošta"; break;
  4062.                     case ZakladniSlozky.Kos: this.slozka = aktualniPrihlaseni.ImapPripojeni.Folders.Trash; nazevSlozky = "Koš"; break;
  4063.                     case ZakladniSlozky.Oznacene: this.slozka = aktualniPrihlaseni.ImapPripojeni.Folders.Flagged; nazevSlozky = "Označená pošta"; break;
  4064.                     case ZakladniSlozky.Dulezite: this.slozka = aktualniPrihlaseni.ImapPripojeni.Folders.Important; nazevSlozky = "Důležitá pošta"; break;
  4065.                     case ZakladniSlozky.Koncepty: this.slozka = aktualniPrihlaseni.ImapPripojeni.Folders.Drafts; nazevSlozky = "Koncepty"; break;
  4066.                     case ZakladniSlozky.Spam: this.slozka = aktualniPrihlaseni.ImapPripojeni.Folders.Junk; nazevSlozky = "Nevyžádaná pošta"; break;
  4067.                 }
  4068.  
  4069.                 if (this.slozka == null) // Toto u gmailu nastat nemůže.
  4070.                 {
  4071.                     if (aktualniPrihlaseni.ImapPripojeni.Folders[nazevSlozky] == null)
  4072.                         aktualniPrihlaseni.ImapPripojeni.Folders.Add(nazevSlozky);
  4073.                     this.slozka = aktualniPrihlaseni.ImapPripojeni.Folders[nazevSlozky];
  4074.                 }
  4075.             }
  4076.                
  4077.         }
  4078.  
  4079.         /// <summary>
  4080.         /// Seřadí e-maily dle času odeslání.
  4081.         /// </summary>
  4082.         /// <param name="emaily">E-maily, které se mají setřídit.</param>
  4083.         /// <returns>Setřízené e-maily.</returns>
  4084.         private List<ImapX.Message> SeradEmaily(object emaily)
  4085.         {
  4086.             // Musíme to takto udělat, neboť ImapX složka je read-only. To znamená, že nepodporuje řazení "na místě".
  4087.             // Implementováno něčím, co připomíná Selection sort. V našem případě časově přijatelné, protože se jedná pouze o pár prvků.
  4088.             // A je to vlastně jeden z mála přijatelných algoritmů pro náš problém.
  4089.  
  4090.             // Typ object zde máme proto, že ve složce jsou zprávy uloženy pod typem MessageCollection. Zatímco hledání e-mailů vrací typ List<Message>.
  4091.  
  4092.             List<ImapX.Message> serazeneEmaily = new List<ImapX.Message>();
  4093.             var neserazeneEmaily = emaily is ImapX.Collections.MessageCollection ? ((ImapX.Collections.MessageCollection)emaily).ToList() : (List<ImapX.Message>)emaily;
  4094.  
  4095.             for (int i = 0; i < (emaily is ImapX.Collections.MessageCollection ? ((ImapX.Collections.MessageCollection)emaily).Count() : ((List<ImapX.Message>)emaily).Count); i++)
  4096.             {
  4097.                 ImapX.Message temp = null;
  4098.                 for (int j = 0; j < neserazeneEmaily.Count; j++)
  4099.                     if (temp == null || neserazeneEmaily[j].Date > temp.Date)
  4100.                         temp = neserazeneEmaily[j];
  4101.                 serazeneEmaily.Add(temp);
  4102.                 neserazeneEmaily.Remove(temp);
  4103.             }
  4104.  
  4105.             return serazeneEmaily;
  4106.         }
  4107.  
  4108.         /// <summary>
  4109.         /// Asynchronně stáhne požadovaný počet e-mailů.
  4110.         /// </summary>
  4111.         /// <param name="kolik">Kolik e-mailů se má stáhnout.</param>
  4112.         public async Task StahniEmaily(int kolik)
  4113.         {
  4114.             int puvodniPocetEmailu = stazeneEmaily.Count;
  4115.             List<ImapX.Message> serazeneEmaily = null;
  4116.  
  4117.             await Task.Run(() => // Toto může trvat netriviální množství času.
  4118.             {
  4119.                 slozka.Messages.Download("ALL", ImapX.Enums.MessageFetchMode.Tiny, kolik);
  4120.                 serazeneEmaily = SeradEmaily(slozka.Messages);
  4121.             });
  4122.  
  4123.             foreach (Control control in panel.Controls)
  4124.                 if (control is PictureBox && ((PictureBox)control).Name == "LoadingPicturebox")
  4125.                     ((PictureBox)control).Visible = false;
  4126.  
  4127.             // E-maily zobrazíme na vedlejším vlákně, protože by se jinak mohlo zasekávat UI. Assign e-mailu k panelu je vyřešen pomocí MethodInvokeru, který spustí na GUI vlákně jediný řádek kódu - a to právě onen assign.
  4128.             await Task.Run(() =>
  4129.             {
  4130.                 for (int i = puvodniPocetEmailu; i < serazeneEmaily.Count; i++)
  4131.                     stazeneEmaily.Add(new JedenEmail(serazeneEmaily[i], i, panel, aktualniPrihlaseni));
  4132.             });
  4133.  
  4134.             foreach (Control control in panel.Controls)
  4135.             {
  4136.                 if (control is Label && ((Label)control).Name == "ZadneEmailyLabel" && stazeneEmaily.Count == 0)
  4137.                     ((Label)control).Visible = true;
  4138.                 else if (control is PictureBox && ((PictureBox)control).Name == "LoadingPicturebox")
  4139.                     ((PictureBox)control).Location = new Point(((PictureBox)control).Location.X, 15 + 85 * stazeneEmaily.Count - this.panel.VerticalScroll.Value);
  4140.             }
  4141.         }
  4142.  
  4143.         /// <summary>
  4144.         /// Asynchronní prohledávání složky. Hledá e-maily dle zadaných kritérií.
  4145.         /// </summary>
  4146.         /// <param name="jake">Dle čeho se mají e-maily hledat.</param>
  4147.         /// <returns>Nalezené e-maily.</returns>
  4148.         public async Task<List<ImapX.Message>> NajdiEmaily(string jake)
  4149.         {
  4150.             List<ImapX.Message> nalezeneEmaily = new List<ImapX.Message>();
  4151.  
  4152.             ImapX.Message[] nalezeneEmaily1 = null;
  4153.             ImapX.Message[] nalezeneEmaily2 = null;
  4154.  
  4155.             // Napevno stáhneme pouze tolik e-mailů, kolik se vejde na obrazovku. Při scrollnutí na konec panelu se nové nenačtou, to by bylo v současné chvíli až moc implementačně náročné. Třeba někdy jindy...
  4156.             // Pozor, nefunguje pro stringy obsahující diakritiku!
  4157.             if (Encoding.UTF8.GetByteCount(jake) != jake.Length) { MessageBox.Show("Je nám líto, řetězce obsahující diakritiku nejsou v současnosti podporovány."); return nalezeneEmaily; }
  4158.             // A momentálně ani nevím, jak to vyřešit.
  4159.  
  4160.  
  4161.             await Task.Run(() => nalezeneEmaily1 = slozka.Search("SUBJECT \"" + jake + "\"", ImapX.Enums.MessageFetchMode.Tiny, 1 + Screen.PrimaryScreen.Bounds.Height / 85));
  4162.             await Task.Run(() => nalezeneEmaily2 = slozka.Search("FROM \"" + jake + "\"", ImapX.Enums.MessageFetchMode.Tiny, 1 + Screen.PrimaryScreen.Bounds.Height / 85));
  4163.  
  4164.             foreach (var email in nalezeneEmaily1) nalezeneEmaily.Add(email);
  4165.             foreach (var email in nalezeneEmaily2) if (nalezeneEmaily.IndexOf(email) == -1) nalezeneEmaily.Add(email);
  4166.  
  4167.             return SeradEmaily(nalezeneEmaily);
  4168.         }
  4169.  
  4170.         /// <summary>
  4171.         /// Třída poskytující GUI náhledu jednoho e-mailu.
  4172.         /// </summary>
  4173.         internal class JedenEmail : IDisposable
  4174.         {
  4175.             internal Panel jedenEmail;
  4176.             internal ImapX.Message email;
  4177.             internal Label odesilatel;
  4178.             internal Label predmet;
  4179.             internal Label cas;
  4180.  
  4181.             private Panel panel;
  4182.  
  4183.             /// <summary>
  4184.             /// Inicializace GUI jednoho e-mailu.
  4185.             /// </summary>
  4186.             /// <param name="email">E-mailová zpráva.</param>
  4187.             /// <param name="kolikaty">O kolikátý e-mail v GUI se jedná.</param>
  4188.             /// <param name="panel">Panel, jehož GUI máme měnit.</param>
  4189.             /// <param name="aktualniPrihlaseni">Aktuální přihlášení, kvůli prohledávání adresáře.</param>
  4190.             internal JedenEmail(ImapX.Message email, int kolikaty, Panel panel, Prihlaseni aktualniPrihlaseni)
  4191.             {
  4192.                 this.panel = panel;
  4193.                 this.email = email;
  4194.                 jedenEmail = new Panel();
  4195.                 odesilatel = new Label();
  4196.                 predmet = new Label();
  4197.                 cas = new Label();
  4198.  
  4199.                 if (email.From != null)
  4200.                     odesilatel.Text = string.IsNullOrEmpty(email.From.DisplayName.ToString()) ? email.From.Address.ToString() : email.From.DisplayName.ToString(); // Pokud má odesilatel nastavené jméno, zobrazíme to. Jinak adresu.
  4201.                 foreach (Kontakt kontakt in new Adresar(aktualniPrihlaseni).seznamKontaktu) // Zkontrolujeme, jestli daný e-mail není v adresáři.
  4202.                     if (kontakt.Email == email.From.Address)
  4203.                     {
  4204.                         if (!string.IsNullOrEmpty(kontakt.Prezdivka))
  4205.                             odesilatel.Text = kontakt.Prezdivka;
  4206.                         else
  4207.                             odesilatel.Text = kontakt.Jmeno;
  4208.                     }
  4209.                 odesilatel.Text = odesilatel.Text.Length > 40 ? odesilatel.Text.Substring(0, 40) + "..." : odesilatel.Text; // Pokud je jeho jméno moc dlouhé, zkrátíme ho, aby se vešlo do panelu.
  4210.  
  4211.  
  4212.                 predmet.Text = email.Subject == null || string.IsNullOrEmpty(email.Subject.ToString()) ? "Bez předmětu" : email.Subject.ToString();
  4213.                 predmet.Text = predmet.Text.Length > 40 ? predmet.Text.Substring(0, 40) + "..." : predmet.Text; // To stejné s předmětem.
  4214.  
  4215.                 // S časem to vymyslíme trochu sofistikovaněji. Pokud e-mail přišel dnes, napíšeme jen čas. Pokud včera, napíšeme, že včera. Jinak napíšeme celý datum bez času.
  4216.                 DateTime aktualniDatum = DateTime.Now;
  4217.                 if (int.Parse(aktualniDatum.Day.ToString()) == int.Parse(email.Date.Value.Day.ToString()) &&
  4218.                     int.Parse(aktualniDatum.Month.ToString()) == int.Parse(email.Date.Value.Month.ToString()) &&
  4219.                     int.Parse(aktualniDatum.Year.ToString()) == int.Parse(email.Date.Value.Year.ToString()))
  4220.                     cas.Text = "dnes v " + email.Date.Value.Hour + ":" + ((email.Date.Value.Minute.ToString().Length == 1) ? "0" + email.Date.Value.Minute.ToString() : email.Date.Value.Minute.ToString());
  4221.  
  4222.                 else if (int.Parse(aktualniDatum.Day.ToString()) - 1 == int.Parse(email.Date.Value.Day.ToString()) &&
  4223.                     int.Parse(aktualniDatum.Month.ToString()) == int.Parse(email.Date.Value.Month.ToString()) &&
  4224.                     int.Parse(aktualniDatum.Year.ToString()) == int.Parse(email.Date.Value.Year.ToString())) // Toto nefunguje, pokud je dnes první den v měsíci.
  4225.                     cas.Text = "včera v " + email.Date.Value.Hour + ":" + ((email.Date.Value.Minute.ToString().Length == 1) ? "0" + email.Date.Value.Minute.ToString() : email.Date.Value.Minute.ToString());
  4226.                 else
  4227.                     cas.Text = "dne " + email.Date.Value.Day + "." + email.Date.Value.Month + "." + email.Date.Value.Year;
  4228.  
  4229.                 #region Inicializace GUI.
  4230.                 this.jedenEmail.AutoScroll = false;
  4231.                 this.jedenEmail.Margin = new System.Windows.Forms.Padding(0);
  4232.                 this.jedenEmail.Size = new System.Drawing.Size(panel.Size.Width - 6 - 19, 85);
  4233.                 this.jedenEmail.Location = new System.Drawing.Point(3, this.jedenEmail.Size.Height * kolikaty - this.panel.VerticalScroll.Value);
  4234.                 this.jedenEmail.BorderStyle = BorderStyle.None;
  4235.                 this.jedenEmail.Controls.Add(new Label() { Height = 1, Dock = DockStyle.Bottom, BackColor = Color.Black }); // Tímto trikem vytvoříme dolní okraj.
  4236.                 this.jedenEmail.TabIndex = kolikaty;
  4237.  
  4238.                 this.odesilatel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  4239.                 this.odesilatel.Font = new System.Drawing.Font("Calibri", 14F);
  4240.                 this.odesilatel.Location = new System.Drawing.Point(10, 10);
  4241.                 this.odesilatel.Size = new System.Drawing.Size(this.jedenEmail.Size.Width - 6, 25);
  4242.                 this.odesilatel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
  4243.                 this.jedenEmail.Controls.Add(odesilatel);
  4244.  
  4245.                 this.predmet.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  4246.                 this.predmet.Font = new System.Drawing.Font("Calibri", 12F);
  4247.                 this.predmet.Location = new System.Drawing.Point(10, 35);
  4248.                 this.predmet.Size = new System.Drawing.Size(this.jedenEmail.Size.Width - 6, 20);
  4249.                 this.predmet.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
  4250.                 this.jedenEmail.Controls.Add(predmet);
  4251.  
  4252.                 this.cas.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  4253.                 this.cas.Font = new System.Drawing.Font("Calibri", 10F);
  4254.                 this.cas.Location = new System.Drawing.Point(10, 55);
  4255.                 this.cas.Size = new System.Drawing.Size(this.jedenEmail.Size.Width - 6, 20);
  4256.                 this.cas.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
  4257.                 this.jedenEmail.Controls.Add(cas);
  4258.  
  4259.                 panel.BeginInvoke(new MethodInvoker(delegate () { this.panel.Controls.Add(jedenEmail); }));
  4260.                 #endregion
  4261.  
  4262.                 // Pokud je zpráva nepřečtená, vyznačíme ji tučně.
  4263.                 if (!email.Seen)
  4264.                 {
  4265.                     this.odesilatel.Font = new Font(odesilatel.Font, FontStyle.Bold);
  4266.                     this.predmet.Font = new Font(predmet.Font, FontStyle.Bold);
  4267.                     this.cas.Font = new Font(cas.Font, FontStyle.Bold);
  4268.  
  4269.                 }
  4270.  
  4271.                 // Těmito eventy z panelu uděláme de facto tlačítko.
  4272.                 this.jedenEmail.MouseMove += new MouseEventHandler(delegate (object sender, MouseEventArgs e) { this.jedenEmail.BackColor = Color.FromArgb(215, 215, 215); });
  4273.                 this.jedenEmail.MouseLeave += new EventHandler(delegate (object sender, EventArgs e) { this.jedenEmail.BackColor = SystemColors.Control; });
  4274.                 this.odesilatel.MouseMove += new MouseEventHandler(delegate (object sender, MouseEventArgs e) { this.jedenEmail.BackColor = Color.FromArgb(215, 215, 215); });
  4275.                 this.odesilatel.MouseLeave += new EventHandler(delegate (object sender, EventArgs e) { this.jedenEmail.BackColor = SystemColors.Control; });
  4276.                 this.predmet.MouseMove += new MouseEventHandler(delegate (object sender, MouseEventArgs e) { this.jedenEmail.BackColor = Color.FromArgb(215, 215, 215); });
  4277.                 this.predmet.MouseLeave += new EventHandler(delegate (object sender, EventArgs e) { this.jedenEmail.BackColor = SystemColors.Control; });
  4278.                 this.cas.MouseMove += new MouseEventHandler(delegate (object sender, MouseEventArgs e) { this.jedenEmail.BackColor = Color.FromArgb(215, 215, 215); });
  4279.                 this.cas.MouseLeave += new EventHandler(delegate (object sender, EventArgs e) { this.jedenEmail.BackColor = SystemColors.Control; });
  4280.             }
  4281.  
  4282.             /// <summary>
  4283.             /// Klasická implementace metody Dispose.
  4284.             /// </summary>
  4285.             public void Dispose()
  4286.             {
  4287.                 odesilatel.Dispose();
  4288.                 predmet.Dispose();
  4289.                 cas.Dispose();
  4290.                 jedenEmail.Dispose();
  4291.             }
  4292.  
  4293.             /// <summary>
  4294.             /// Edituje event handlery celému tlačítku.
  4295.             /// </summary>
  4296.             /// <param name="zobrazit">Metoda, která se má při události spustit.</param>
  4297.             public void NastavEventHandlery(ZobrazEmailEventHandler zobrazit)
  4298.             {
  4299.                 // Nejdřív odebereme, to ničemu nevadí a zabráníme tomu, že na jeden prvek bude odkázáno více stejných event handlerů.
  4300.                 odesilatel.Click -= new EventHandler(delegate (object sender, EventArgs e) { zobrazit(this); });
  4301.                 cas.Click -= new EventHandler(delegate (object sender, EventArgs e) { zobrazit(this); });
  4302.                 predmet.Click -= new EventHandler(delegate (object sender, EventArgs e) { zobrazit(this); });
  4303.                 jedenEmail.Click -= new EventHandler(delegate (object sender, EventArgs e) { zobrazit(this); });
  4304.  
  4305.                 // Na každý element panelu tlačítka vytvoříme event handler, který spustí metodu na zobrazení právě tohoto e-mailu.
  4306.                 odesilatel.Click += new EventHandler(delegate (object sender, EventArgs e) { zobrazit(this); });
  4307.                 cas.Click += new EventHandler(delegate (object sender, EventArgs e) { zobrazit(this); });
  4308.                 predmet.Click += new EventHandler(delegate (object sender, EventArgs e) { zobrazit(this); });
  4309.                 jedenEmail.Click += new EventHandler(delegate (object sender, EventArgs e) { zobrazit(this); });
  4310.             }
  4311.         }
  4312.     }
  4313. }
  4314.  
  4315. using System;
  4316. using System.IO;
  4317. using System.Windows.Forms;
  4318.  
  4319. // Aplikace je naprosto bezpečná. Bez znalosti šifrovacího klíče nehrozí zneužití údajů.
  4320.  
  4321. namespace Mail_Agent_2017
  4322. {
  4323.     static class Program
  4324.     {
  4325.         /// <summary>
  4326.         /// Načte defaultní nastavení aplikace.
  4327.         /// </summary>
  4328.         private static void NactiDefaultniNastaveni()
  4329.         {
  4330.             BarevnyMotiv.Barva = BarevnyMotiv.BarevnaPaleta.Modra;
  4331.         }
  4332.  
  4333.         /// <summary>
  4334.         /// Rozšíření metody Contains. Tato rozšířená verze nám umožní ignorovat case-sensitivní znaky.
  4335.         /// </summary>
  4336.         /// <param name="zdroj">String, ve kterém se má daný substring hledat.</param>
  4337.         /// <param name="zkontrolovat">Substring, který se má nalézt.</param>
  4338.         /// <param name="comp">Možnosti porovnávání.</param>
  4339.         /// <returns>True, pokud daný string obsahuje daný substring.</returns>
  4340.         public static bool Contains(this string zdroj, string zkontrolovat, StringComparison comp)
  4341.         {
  4342.             return zdroj != null && zkontrolovat != null && zdroj.IndexOf(zkontrolovat, comp) >= 0;
  4343.         }
  4344.  
  4345.         /// <summary>
  4346.         /// Hlavní vstupní bod aplikace.
  4347.         /// </summary>
  4348.         [STAThread]
  4349.         static void Main()
  4350.         {
  4351.             // Nejdříve načteme uživatelské nastavení.
  4352.             StreamReader nastaveni = new StreamReader(".settings");
  4353.  
  4354.             try
  4355.             {
  4356.                 // Číslo barevného motivu (číslo přiřazené hodnotě ve výčtovém typu) odpovídá první řádce v souboru nastavení.
  4357.                 BarevnyMotiv.Barva = (BarevnyMotiv.BarevnaPaleta)Enum.ToObject(typeof(BarevnyMotiv.BarevnaPaleta), int.Parse(nastaveni.ReadLine()));
  4358.             }
  4359.  
  4360.             catch
  4361.             {
  4362.                 // Pokud neexistuje, načteme defaultní nastavení.
  4363.                 NactiDefaultniNastaveni();
  4364.             }
  4365.  
  4366.             finally
  4367.                 { nastaveni.Close(); }
  4368.  
  4369.             Application.EnableVisualStyles();
  4370.             Application.SetCompatibleTextRenderingDefault(false);
  4371.             Application.Run(new MainForm());
  4372.         }
  4373.     }
  4374. }
  4375. using System;
  4376. using System.Collections.Generic;
  4377. using System.Linq;
  4378. using System.Text;
  4379. using System.Threading.Tasks;
  4380. using System.Windows.Forms;
  4381.  
  4382. namespace Mail_Agent_2017
  4383. {
  4384.     // V tomto souboru je implementováno všechno týkající se adresáře a skupin v okně pro odesílní e-mailů.
  4385.     // Ačkoliv se jedná o tutéž třídu, je kód v tomto souboru, abychom nepřetěžovali soubor SendForm.cs, kde jsou nejdůležitější komponenty této třídy.
  4386.  
  4387.     public partial class SendForm
  4388.     {
  4389.  
  4390.         /// <summary>
  4391.         /// Otevře adresář, kde si může uživatel zvolit, jaké kontakty připojí k e-mailu.
  4392.         /// </summary>
  4393.         private void OtevritAdresar_Click(object sender, EventArgs e)
  4394.         {
  4395.             // Zde určíme, kam vybrané e-mailové adresy zapíšeme.
  4396.             TextBox kamZapsat = null;
  4397.             switch (((PictureBox)sender).Name)
  4398.             {
  4399.                 case "ToAdresarButton": kamZapsat = ToTextbox; break;
  4400.                 case "CcAdresarButton": kamZapsat = CcTextbox; break;
  4401.                 case "BccAdresarButton": kamZapsat = BccTextbox; break;
  4402.             }
  4403.  
  4404.             // Zde dochází k zobrazení adresářového okna a v případě úspěšného ukončení pomocí tlačítka, projde všechny zaškrtnuté adresy a napíše je do příslušného textboxu.
  4405.             using (var form = new AddressBookForm(aktualniPrihlaseni, true))
  4406.                 if (form.ShowDialog() == DialogResult.OK)
  4407.                     foreach (AddressBookForm.JedenKontakt kontakt in form.ovladaciPrvky)
  4408.                         if (kontakt.PridatKontaktCheckbox.Checked)
  4409.                             kamZapsat.Text += string.IsNullOrWhiteSpace(kamZapsat.Text) ? kontakt.kontakt.Email + ";" : ( (kamZapsat.Text.Last() == ';') ? kontakt.kontakt.Email : ";" + kontakt.kontakt.Email);
  4410.             kamZapsat.SelectionStart = kamZapsat.Text.Length;
  4411.         }
  4412.  
  4413.         /// <summary>
  4414.         /// Jedná se o obsluhu stisku klávesy, když uživatel zadává e-mailové adresy.
  4415.         /// Pokud je počet znaků v e-mailové adrese větší než 3, spustí prohledávání adresáře a navrhování adres.
  4416.         /// </summary>
  4417.         private async void Textbox_KeyDown(object sender, KeyEventArgs e)
  4418.         {
  4419.             // Na začátku odebereme obsluhu tohoto eventu, neboť kdyby se stejná obsluha spustila vícekrát současně (kdyby uživatel psal moc rychle), mohlo by dojít k "rozbití" GUI. Na konci opět přidáme.
  4420.             ((TextBox)sender).KeyDown -= new KeyEventHandler(Textbox_KeyDown);
  4421.             Panel aktualniPanel = null;
  4422.  
  4423.             switch (((TextBox)sender).Name)
  4424.             {
  4425.                 case "ToTextbox": aktualniPanel = ToAdresarPanel; break;
  4426.                 case "CcTextbox": aktualniPanel = CcAdresarPanel; break;
  4427.                 case "BccTextbox": aktualniPanel = BccAdresarPanel; break;
  4428.                 default: throw new MissingMemberException();
  4429.             }
  4430.  
  4431.             this.SuspendLayout();
  4432.  
  4433.             // Při aktualizaci vymažeme všechny stávájící kontakty v okně.
  4434.             foreach (Control prvek in aktualniPanel.Controls)
  4435.                 prvek.Dispose();
  4436.  
  4437.             if (((TextBox)sender).Text.Split(';').Last().Length >= 2)
  4438.             {  
  4439.                 var nalezeneKontakty = await ProhledejAdresar(((TextBox)sender).Text.Split(';').Last());
  4440.  
  4441.                 for (int i = 0; i < nalezeneKontakty.Count; i++)
  4442.                 {
  4443.                     ExtendedLabel novyZaznam = new ExtendedLabel();
  4444.                     novyZaznam.Font = new System.Drawing.Font("Calibri", 12F);
  4445.                     novyZaznam.FlatStyle = FlatStyle.Flat;
  4446.                     novyZaznam.Size = new System.Drawing.Size(600, 27);
  4447.                     novyZaznam.Location = new System.Drawing.Point(0, 27 * i);
  4448.                     novyZaznam.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
  4449.                     novyZaznam.PridruzenyTextbox = ((TextBox)sender);
  4450.                     novyZaznam.Click += new EventHandler(PridatKontaktDoEmailu);
  4451.                     novyZaznam.Text = nalezeneKontakty[i].Jmeno + ((string.IsNullOrEmpty(nalezeneKontakty[i].Prezdivka)) ? "" : (" \"" + nalezeneKontakty[i].Prezdivka + "\"")) + " - " + nalezeneKontakty[i].Email + "\n"; // Do popisku se přidá i přezdívka, pokud existuje.
  4452.                     novyZaznam.Cursor = Cursors.Hand;
  4453.                     aktualniPanel.Controls.Add(novyZaznam);
  4454.  
  4455.                     ToolTip AddContactTooltip = new ToolTip();
  4456.                     AddContactTooltip.UseFading = true;
  4457.                     AddContactTooltip.UseAnimation = true;
  4458.                     AddContactTooltip.ReshowDelay = 500;
  4459.                     AddContactTooltip.InitialDelay = 500;
  4460.                     AddContactTooltip.AutoPopDelay = 15000;
  4461.                     AddContactTooltip.ShowAlways = true;
  4462.                     AddContactTooltip.ToolTipIcon = ToolTipIcon.Info;
  4463.                     AddContactTooltip.SetToolTip(novyZaznam, "Připojí kontakt k e-mailu.");
  4464.  
  4465.                     // Jakmile se kurzor ocitne nad tímto textem, zvýrazní se modře. Přišlo mi zbytečné na jeden řádek kódu vytvářet metodu obsluhy události, tak jsem to vyřešil pomocí delegáta.
  4466.                     novyZaznam.MouseMove += new MouseEventHandler(delegate (object senderM, MouseEventArgs eM) { novyZaznam.ForeColor = System.Drawing.SystemColors.Highlight; });
  4467.  
  4468.                     // A opačně.
  4469.                     novyZaznam.MouseLeave += new EventHandler(delegate (object senderM, EventArgs eM) { novyZaznam.ForeColor = System.Drawing.Color.Black; });
  4470.                 }
  4471.  
  4472.                 if (nalezeneKontakty.Count > 0)
  4473.                     aktualniPanel.Visible = true;
  4474.             }
  4475.  
  4476.             else
  4477.                 aktualniPanel.Visible = false;
  4478.            
  4479.             this.ResumeLayout(false);
  4480.  
  4481.             ((TextBox)sender).KeyDown += new KeyEventHandler(Textbox_KeyDown);
  4482.         }
  4483.  
  4484.         /// <summary>
  4485.         /// Po kliknutí přidá kontakt do e-mailu.
  4486.         /// </summary>
  4487.         private void PridatKontaktDoEmailu(object sender, EventArgs e)
  4488.         {
  4489.             // Tato šílenost dělá jen to, že do textboxu adres přidá adresu , na kterou uživatel klikne.
  4490.             ((ExtendedLabel)sender).PridruzenyTextbox.Text = ((ExtendedLabel)sender).PridruzenyTextbox.Text.Substring(0, ((ExtendedLabel)sender).PridruzenyTextbox.Text.Length -
  4491.                 ((ExtendedLabel)sender).PridruzenyTextbox.Text.Split(';').Last().Length);
  4492.             ((ExtendedLabel)sender).PridruzenyTextbox.Text += ((ExtendedLabel)sender).Text.Split('-')[1].Substring(1, ((ExtendedLabel)sender).Text.Split('-')[1].Length - 2) + ";";
  4493.  
  4494.             ((ExtendedLabel)sender).PridruzenyTextbox.SelectionStart = ((ExtendedLabel)sender).PridruzenyTextbox.Text.Length;
  4495.  
  4496.             ToAdresarPanel.Visible = false;
  4497.             CcAdresarPanel.Visible = false;
  4498.             BccAdresarPanel.Visible = false;
  4499.         }
  4500.  
  4501.  
  4502.         /// <summary>
  4503.         /// Spustí asynchronní prohledávání adresáře na základě údajů v textboxu. To může být jméno, přezdívka nebo e-mail.
  4504.         /// </summary>
  4505.         /// <param name="naZakladeCeho">Na základě čeho se má začít prohledávat.</param>
  4506.         /// <returns>Nalezené kontakty.</returns>
  4507.         private async Task<List<Kontakt>> ProhledejAdresar(string naZakladeCeho)
  4508.         {
  4509.             // Tato metoda je psaná asynchronně, neboť vyhledávání kontaktů v adresáři může zabrat spoustu času a aplikace by pak nebyla responsibilní.
  4510.             List<Kontakt> nalezeneKontakty = new List<Kontakt>();
  4511.             await Task.Run(() =>
  4512.             {
  4513.                 foreach (Kontakt kontakt in adresar.seznamKontaktu)
  4514.                     if (kontakt.Email.Contains(naZakladeCeho, StringComparison.OrdinalIgnoreCase) || kontakt.Jmeno.Contains(naZakladeCeho, StringComparison.OrdinalIgnoreCase) || kontakt.Prezdivka.Contains(naZakladeCeho, StringComparison.OrdinalIgnoreCase))
  4515.                         nalezeneKontakty.Add(kontakt);
  4516.             });            
  4517.             return nalezeneKontakty;
  4518.         }
  4519.  
  4520.         /// <summary>
  4521.         /// Při opuštění textboxu zavře okno s návrhy kontaktů.
  4522.         /// </summary>
  4523.         private void Textbox_Leave(object sender, EventArgs e)
  4524.         {
  4525.             switch (((TextBox)sender).Name)
  4526.             {
  4527.                 case "ToTextbox": ToAdresarPanel.Visible = false; ; break;
  4528.                 case "CcTextbox": ToAdresarPanel.Visible = false; ; break;
  4529.                 case "BccTextbox": ToAdresarPanel.Visible = false; ; break;
  4530.                 default: throw new MissingMemberException();
  4531.             }
  4532.         }
  4533.  
  4534.         /// <summary>
  4535.         /// Rozšířený label.
  4536.         /// Použijeme ho v okénku pro napovídání kontaktů tak, že si každý label bude pamatovat, k jakému textboxu je přidružen, aby mohl zapsat adresu do správného okénka.
  4537.         /// </summary>
  4538.         private class ExtendedLabel : Label
  4539.         {
  4540.             public TextBox PridruzenyTextbox;
  4541.             public ExtendedLabel() : base() { }
  4542.         }
  4543.  
  4544.         /// <summary>
  4545.         /// Zobrazí uživateli skupiny, které může přidat do e-mailu.
  4546.         /// </summary>
  4547.         private void ZobrazitSkupiny_Click(object sender, EventArgs e)
  4548.         {
  4549.             // Zde určíme, kam vybrané e-mailové adrey zapíšeme.
  4550.             TextBox kamZapsat = null;
  4551.             switch (((PictureBox)sender).Name)
  4552.             {
  4553.                 case "ToSkupinaButton": kamZapsat = ToTextbox; break;
  4554.                 case "CcSkupinaButton": kamZapsat = CcTextbox; break;
  4555.                 case "BccoSkupinaButton": kamZapsat = BccTextbox; break;
  4556.             }
  4557.  
  4558.             // Zde dochází k zobrazení skupinového okna a v případě úspěšného ukončení pomocí tlačítka, projde všechny zaškrtnuté skupiny a napíše je do příslušného textboxu.
  4559.             using (var form = new GroupBookForm(aktualniPrihlaseni, true))
  4560.                 if (form.ShowDialog() == DialogResult.OK)
  4561.                     foreach (GroupBookForm.JednaSkupina skupina in form.ovladaciPrvky)
  4562.                         if (skupina.PridatSkupinuCheckbox.Checked)
  4563.                             foreach (Kontakt kontakt in Utility.VypisKontaktyVeSkupine(new Adresar(aktualniPrihlaseni), skupina.skupina))
  4564.                                 kamZapsat.Text += string.IsNullOrWhiteSpace(kamZapsat.Text) ? kontakt.Email + ";" : ((kamZapsat.Text.Last() == ';') ? kontakt.Email : ";" + kontakt.Email);
  4565.             kamZapsat.SelectionStart = kamZapsat.Text.Length;
  4566.         }
  4567.     }
  4568. }
  4569.  
  4570.  
  4571.  
  4572. using System;
  4573. using System.Collections.Generic;
  4574. using System.Linq;
  4575. using System.Net.Mail;
  4576. using System.Text;
  4577. using System.Threading.Tasks;
  4578. using System.Windows.Forms;
  4579.  
  4580. namespace Mail_Agent_2017
  4581. {
  4582.     // Jsem si vědom toho, že tato třída obsahuje příliš mnoho důležitých věcí a může to být nepřehledné.
  4583.     // Nicméně téměř každá metoda pracuje nějakým způsobem s GUI v této třídě, takže psaní metod do nějaké vnější třídy by mohlo být ještě nepřehlednější.
  4584.  
  4585.     /// <summary>
  4586.     /// Odesílání emailu.
  4587.     /// </summary>
  4588.     public partial class SendForm : Form
  4589.     {
  4590.  
  4591.         // TO-DO: Opravdový HTML editor pro textové pole. Bohužel, s mými aktuálními znalostmi jazyka nejspíš neproveditelné.
  4592.  
  4593.         Prihlaseni aktualniPrihlaseni;
  4594.         MailMessage emailovaZprava;
  4595.         AttachmentForm prilohy;
  4596.         Stack<string> undoZasobnik;
  4597.         Stack<string> redoZasobnik;
  4598.         Adresar adresar;
  4599.  
  4600.         /// <summary>
  4601.         /// Inicializace nejdůležitějších komponent pro toto okno.
  4602.         /// </summary>
  4603.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení.</param>
  4604.         public SendForm(Prihlaseni aktualniPrihlaseni)
  4605.         {
  4606.             InitializeComponent();
  4607.             this.Icon = BarevnyMotiv.ikona;
  4608.             this.redoZasobnik = new Stack<string>();
  4609.             this.undoZasobnik = new Stack<string>();
  4610.             this.aktualniPrihlaseni = aktualniPrihlaseni;
  4611.             this.emailovaZprava = new MailMessage();
  4612.             this.prilohy = new AttachmentForm();
  4613.             UndoTimer.Enabled = true;
  4614.             this.undoZasobnik.Push("");
  4615.             this.adresar = new Adresar(aktualniPrihlaseni);
  4616.  
  4617.             // Barvy tlačítek se nastavují zde, neboť se při každé změně designeru přenastavují a je otrava je neustále nastavovat znovu.
  4618.             this.SendButton.BackColor = BarevnyMotiv.barvaTlacitek;
  4619.             this.NahledButton.BackColor = BarevnyMotiv.barvaTlacitek;
  4620.             this.KonceptButton.BackColor = BarevnyMotiv.barvaTlacitek;
  4621.             this.DeleteButton.BackColor = BarevnyMotiv.barvaTlacitek;
  4622.             this.PrilohyButton.BackColor = BarevnyMotiv.barvaTlacitek;
  4623.         }
  4624.  
  4625.         /// <summary>
  4626.         /// Otevře okno na odeslání e-mailu a předvyplní okno na základě údajů v e-mailové zprávě.
  4627.         /// </summary>
  4628.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení.</param>
  4629.         /// <param name="email">E-mailová zpráva.</param>
  4630.         /// <param name="volba">True, pokud odpovědět. False, pokud přeposlat.</param> // Toto do budoucna předělat pomocí enumu, aby to bylo hezčí.
  4631.         public SendForm(Prihlaseni aktualniPrihlaseni, ImapX.Message email, bool volba) : this(aktualniPrihlaseni, email)
  4632.         {
  4633.             if (volba)
  4634.             {
  4635.                 this.prilohy = new AttachmentForm();
  4636.                 ToTextbox.Text = email.From.Address;
  4637.                 foreach (var addr in email.Cc) CcTextbox.Text += (!string.IsNullOrEmpty(CcTextbox.Text) ? ";" : "") + addr.Address;
  4638.                 foreach (var addr in email.Bcc) BccTextbox.Text += (!string.IsNullOrEmpty(BccTextbox.Text) ? ";" : "") + addr.Address;
  4639.                 SubjectTextbox.Text = "Re: " + email.Subject;
  4640.             }
  4641.  
  4642.             else
  4643.             {
  4644.                 ToTextbox.Text = "";
  4645.                 SubjectTextbox.Text = "Fwd: " + email.Subject;
  4646.             }
  4647.  
  4648.             TextTextarea.Text = "\n\n\n\nPůvodní zpráva od " + (!string.IsNullOrEmpty(email.From.DisplayName) ? email.From.DisplayName + " (" + email.From.Address + ")" : email.From.Address) + " z " +
  4649.                 (email.Date.Value.Day.ToString().Length == 1 ? "0" : "") + email.Date.Value.Day + "." + (email.Date.Value.Month.ToString().Length == 1 ? "0" : "") + email.Date.Value.Month + "." + email.Date.Value.Year + " " +
  4650.                 (email.Date.Value.Hour.ToString().Length == 1 ? "0" : "") + email.Date.Value.Hour + ":" + (email.Date.Value.Minute.ToString().Length == 1 ? "0" : "") + email.Date.Value.Minute + ":" + (email.Date.Value.Second.ToString().Length == 1 ? "0" : "") + email.Date.Value.Second + "\n\n";
  4651.  
  4652.             if (!email.Body.HasText)
  4653.             {
  4654.                 TextTextarea.Text += email.Body.Html;
  4655.                 HtmlCheckbox.Checked = true;
  4656.             }
  4657.  
  4658.             else
  4659.                 foreach (var radka in email.Body.Text.ToString().Split('\n'))
  4660.                     TextTextarea.Text += ">" + radka + "\n";
  4661.         }
  4662.  
  4663.         /// <summary>
  4664.         /// Otevře okno s možností editace konceptu.
  4665.         /// </summary>
  4666.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení.</param>
  4667.         /// <param name="email">E-mailová zpráva.</param>
  4668.         public SendForm(Prihlaseni aktualniPrihlaseni, ImapX.Message email) : this(aktualniPrihlaseni)
  4669.         {
  4670.             foreach (var addr in email.To) ToTextbox.Text += (!string.IsNullOrEmpty(ToTextbox.Text) ? ";" : "") + addr.Address;
  4671.             foreach (var addr in email.Cc) CcTextbox.Text += (!string.IsNullOrEmpty(CcTextbox.Text) ? ";" : "") + addr.Address;
  4672.             foreach (var addr in email.Bcc) BccTextbox.Text += (!string.IsNullOrEmpty(BccTextbox.Text) ? ";" : "") + addr.Address;
  4673.             SubjectTextbox.Text = email.Subject != null ? email.Subject : "";
  4674.             TextTextarea.Text = email.Body.Text;
  4675.  
  4676.             if (email.Attachments.Count() > 0)
  4677.             {
  4678.                 this.prilohy.OdstranExistujiciPrilohu(0);
  4679.  
  4680.                 foreach (var priloha in email.Attachments)
  4681.                     this.prilohy.InicializujNovouPrilohu(priloha);
  4682.  
  4683.                 this.prilohy.InicializujNovouPrilohu(null);
  4684.             }
  4685.         }
  4686.  
  4687.         /// <summary>
  4688.         /// Otevře okno na odeslání e-mailu a předvyplní okno adresou adresáta.
  4689.         /// </summary>
  4690.         /// <param name="aktualniPrihlaseni">Aktuální přihlášení.</param>
  4691.         /// <param name="email">E-mailová adresa příjemce.</param>
  4692.         public SendForm(Prihlaseni aktualniPrihlaseni, string email) : this(aktualniPrihlaseni)
  4693.         {
  4694.             ToTextbox.Text = email;
  4695.         }
  4696.  
  4697.         /// <summary>
  4698.         /// Tlačítko, které smaže obsah všech formulářů.
  4699.         /// </summary>
  4700.         private void DeleteButton_Click(object sender, EventArgs e)
  4701.         {
  4702.             if (MessageBox.Show("Opravdu chcete smazat veškerý obsah e-mailu?", "Smazat veškerý obsah", MessageBoxButtons.YesNo) == DialogResult.Yes)
  4703.             {
  4704.                 ToTextbox.Text = "";
  4705.                 CcTextbox.Text = "";
  4706.                 BccTextbox.Text = "";
  4707.                 SubjectTextbox.Text = "";
  4708.                 TextTextarea.Text = "";
  4709.                 PrilohaLabel.Text = "";
  4710.                 prilohy = new AttachmentForm();
  4711.             }            
  4712.         }
  4713.  
  4714.         /// <summary>
  4715.         /// Tlačítko spravující veškeré dění ohledně příloh.
  4716.         /// </summary>
  4717.         private void PrilohyButton_Click(object sender, EventArgs e)
  4718.         {
  4719.             prilohy.ShowDialog();
  4720.  
  4721.             // Počet přiložených souborů musíme řešit takto "složitě", neboť v seznamu příloh je poslední příloha neinicializovaná.
  4722.             // Je tam prázdné pole pro vložení nové přílohy, tedy až na případ, kdy je příloh 10. Pak je celý seznam obsazen přílohami.
  4723.             var pocetSouboru = (prilohy.seznamPriloh.Last().label.Text != "...") ? prilohy.seznamPriloh.Count.ToString() : (prilohy.seznamPriloh.Count - 1).ToString();
  4724.  
  4725.             // Podmínku pro if vymyslíme podobně. V této části se zapisuje do labelu na odesílací obrazovce, aby byl uživatel "v obraze" ohledně počtu příloh.
  4726.             if ((prilohy.seznamPriloh.Last().label.Text != "...") ? true : prilohy.seznamPriloh.Count - 1 > 0)
  4727.                 // Čeština je "krásná" řeč.
  4728.                 switch (pocetSouboru)
  4729.                 {
  4730.                     case "1": PrilohaLabel.Text = "K e-mailu je momentálně přiložen 1 soubor."; break;
  4731.                     case "2": case "3": case "4": PrilohaLabel.Text = "K e-mailu jsou momentálně přiloženy " + pocetSouboru + " soubory."; break;
  4732.                     default: PrilohaLabel.Text = "K e-mailu je momentálně přiloženo " + pocetSouboru + " souborů."; break;
  4733.                 }
  4734.             else
  4735.                 PrilohaLabel.Text = "";
  4736.         }
  4737.  
  4738.         /// <summary>
  4739.         /// Umožní uživateli psát email v jazyce HTML 5. Poskytuje mu k tomu drobné utility, de facto usnadnění.
  4740.         /// </summary>
  4741.         private void HtmlCheckbox_CheckedChanged(object sender, EventArgs e)
  4742.         {
  4743.             if (HtmlCheckbox.Checked)
  4744.                 MessageBox.Show("Zvažte použití HTML prvků ve svém e-mailu. E-mailový klient Vašeho adresáta nemusí tuto možnost podporovat.");
  4745.  
  4746.             emailovaZprava.IsBodyHtml = HtmlCheckbox.Checked;
  4747.             NahledButton.Visible = HtmlCheckbox.Checked;
  4748.             BoldButton.Visible = HtmlCheckbox.Checked;
  4749.             ItalicButton.Visible = HtmlCheckbox.Checked;
  4750.             UnderlineButton.Visible = HtmlCheckbox.Checked;
  4751.             FontButton.Visible = HtmlCheckbox.Checked;
  4752.             FontColorButton.Visible = HtmlCheckbox.Checked;
  4753.             LeftAlignmentButton.Visible = HtmlCheckbox.Checked;
  4754.             CenterAlignmentButton.Visible = HtmlCheckbox.Checked;
  4755.             RightAlignmentButton.Visible = HtmlCheckbox.Checked;
  4756.             HyperlinkButton.Visible = HtmlCheckbox.Checked;
  4757.             ImageButton.Visible = HtmlCheckbox.Checked;
  4758.         }
  4759.  
  4760.         /// <summary>
  4761.         /// Zobrazí náhled HTML kódu.
  4762.         /// </summary>
  4763.         private void NahledButton_Click(object sender, EventArgs e)
  4764.         {
  4765.             new HtmlPreviewForm(TextTextarea.Text).ShowDialog();
  4766.         }        
  4767.  
  4768.         /// <summary>
  4769.         /// Odešle e-mail na dané adresy z uživatelova e-mailu. Kontroluje chyby a nedostatky, které mohly vzniknout při psaní zprávy.
  4770.         /// Deklarováno jako asynchronní metoda, aby při posílání e-mailu neblokovala GUI. E-mail pošleme asynchronně na novém vlákně, tato možnost je implementována přímo v .NET.
  4771.         /// Také se stará o ukládání konceptů.
  4772.         /// </summary>
  4773.         private async void SendButton_Click(object sender, EventArgs e)
  4774.         {
  4775.             try
  4776.             {
  4777.                 // Nejdříve zkontrolujeme, jestli mají e-mailové adresy správný formát.
  4778.                 if (string.IsNullOrEmpty(ToTextbox.Text))
  4779.                     throw new SpatneVyplnenyAdresatException("Musíte vyplnit alespoň jednoho adresáta.");
  4780.  
  4781.                 foreach (string adresa in ToTextbox.Text.Split(';')) if (!string.IsNullOrEmpty(adresa))
  4782.                         if (Utility.SpravnyFormatAdresy(adresa))
  4783.                              emailovaZprava.To.Add(adresa);
  4784.                         else
  4785.                              throw new SpatneVyplnenyAdresatException("E-mailová adresa má nesprávný formát.");
  4786.  
  4787.                 if (!string.IsNullOrEmpty(CcTextbox.Text)) foreach (string adresa in CcTextbox.Text.Split(';')) if (!string.IsNullOrEmpty(adresa))
  4788.                             if (Utility.SpravnyFormatAdresy(adresa))
  4789.                                 emailovaZprava.CC.Add(adresa);
  4790.                             else
  4791.                                 throw new SpatneVyplnenyAdresatException("E-mailová adresa má nesprávný formát.");
  4792.  
  4793.                 if(!string.IsNullOrEmpty(BccTextbox.Text)) foreach (string adresa in BccTextbox.Text.Split(';')) if (!string.IsNullOrEmpty(adresa))
  4794.                             if (Utility.SpravnyFormatAdresy(adresa))
  4795.                                 emailovaZprava.Bcc.Add(adresa);
  4796.                             else
  4797.                                 throw new SpatneVyplnenyAdresatException("E-mailová adresa má nesprávný formát.");
  4798.  
  4799.  
  4800.                 emailovaZprava.Subject = Encoding.UTF8.GetString(Encoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(SubjectTextbox.Text)));
  4801.  
  4802.                 // Pokud se jedná o HTML zprávu, zaměnímě newliny za HTML tag <br>.
  4803.                 emailovaZprava.Body = (emailovaZprava.IsBodyHtml) ? TextTextarea.Text.Replace("\n", "<br>") : TextTextarea.Text;
  4804.             }
  4805.  
  4806.             catch (Exception ex)
  4807.             {
  4808.                 ChyboveOknoLabel.ForeColor = System.Drawing.Color.Red;
  4809.                 if (ex is SpatneVyplnenyAdresatException)
  4810.                 {
  4811.                     ChyboveOknoLabel.Show();
  4812.                     ChyboveOknoLabel.Text = ex.Message;
  4813.                     ZobrazeniChybyTimer.Enabled = true;
  4814.                     return;
  4815.                 }
  4816.  
  4817.                 else if (ex is EmailBezPredmetuException || ex is EmailBezTextuException)
  4818.                     { return; }
  4819.  
  4820.                 else MessageBox.Show(ex.Message); // Upřímně řečeno si momentálně nejsem vůbec jistý, jestli může nastat nějaká jiná výjimka.
  4821.             }
  4822.  
  4823.             // Přidáme adresu odesílatele - tedy sebe.
  4824.             emailovaZprava.From = new MailAddress(aktualniPrihlaseni.Email, aktualniPrihlaseni.Jmeno, Encoding.Unicode);
  4825.  
  4826.  
  4827.             // Přidáme k e-mailu přílohy, pokud existují.
  4828.             foreach (var priloha in (prilohy.seznamPriloh.Last().label.Text != "...") ? prilohy.seznamPriloh : prilohy.seznamPriloh.GetRange(0, prilohy.seznamPriloh.Count - 1))
  4829.             {
  4830.                 if (priloha.priloha == null)
  4831.                     emailovaZprava.Attachments.Add(new Attachment(priloha.soubor.FileName)); // Výjimka by nastat neměla, neboť máme cesty k souborům uloženy v OpenFileDialog objektu.
  4832.                 else
  4833.                 {
  4834.                     try { emailovaZprava.Attachments.Add(new Attachment(new System.IO.MemoryStream(priloha.priloha.FileData), priloha.priloha.FileName)); }
  4835.                     catch { }
  4836.                 }
  4837.                    
  4838.             }
  4839.  
  4840.             // Pokud se jednalo pouze o koncept, uložíme ho a nic dalšího podnikat nebudeme.
  4841.             if (((Button)sender).Name == "KonceptButton")
  4842.             {
  4843.                 await Task.Run(() => aktualniPrihlaseni.ImapPripojeni.Folders.Drafts.AppendMessage(emailovaZprava));
  4844.                 MessageBox.Show("Koncept byl úspěšně uložen.");
  4845.  
  4846.                 ChyboveOknoLabel.Show();
  4847.                 ZobrazeniChybyTimer.Enabled = false;
  4848.                 ChyboveOknoLabel.ForeColor = System.Drawing.Color.Black;
  4849.                 ChyboveOknoLabel.Text = "Koncept byl úspěšně uložen.";
  4850.                 this.DialogResult = DialogResult.OK;
  4851.                 return;
  4852.             }
  4853.  
  4854.             try
  4855.             {
  4856.                 // Optáme se uživatele, jestli chce opravdu odeslat email bez předmětu.
  4857.                 if (string.IsNullOrEmpty(SubjectTextbox.Text) && MessageBox.Show("Opravdu chcete odeslat e-mail bez předmětu?", "Nebyl vyplněn předmět e-mailu.", MessageBoxButtons.YesNo) == DialogResult.No)
  4858.                     throw new EmailBezPredmetuException();
  4859.  
  4860.                 // Optáme se uživatele, jestli chce opravdu odeslat prázdný email.
  4861.                 if (string.IsNullOrEmpty(TextTextarea.Text) && MessageBox.Show("Opravdu chcete odeslat prázdný e-mail?", "Nebyl vyplněn žádný text.", MessageBoxButtons.YesNo) == DialogResult.No)
  4862.                     throw new EmailBezTextuException();
  4863.             }
  4864.  
  4865.             catch (Exception ex)
  4866.             {
  4867.                 if (ex is EmailBezTextuException || ex is EmailBezPredmetuException)
  4868.                     return;
  4869.             }
  4870.  
  4871.             try
  4872.             {
  4873.                 // Zapneme blikající tečky a pro jistotu vypneme timer na hlášení chyby, kdyby byl náhodou aktivní, tak ať to nedělá nesmysly.
  4874.                 ChyboveOknoLabel.Show();
  4875.                 ZobrazeniChybyTimer.Enabled = false;
  4876.                 ChyboveOknoLabel.Text = ""; ChyboveOknoLabel.ForeColor = System.Drawing.Color.Black;
  4877.                 NacitaniTimer.Enabled = true;
  4878.  
  4879.                 // Počkáme na pracovní vlákno, které za nás odešle e-mail, abychom zbytečně neblokovali UI.
  4880.                 await aktualniPrihlaseni.SmtpPripojeni.SendMailAsync(emailovaZprava);
  4881.             }
  4882.            
  4883.             // Nevím, jestli asynchronní odesílání e-mailu může v našem případě vyvolat nějakou výjimku, ale pár řádek kódu navíc neuškodí.
  4884.             catch
  4885.             {                
  4886.                 ChyboveOknoLabel.Text = "Zprávu se nepodařilo odeslat.";
  4887.                 ChyboveOknoLabel.ForeColor = System.Drawing.Color.Red;
  4888.                 NacitaniTimer.Enabled = false;
  4889.                 ZobrazeniChybyTimer.Enabled = true;
  4890.                 return;
  4891.             }
  4892.  
  4893.             NacitaniTimer.Enabled = false;
  4894.            
  4895.             aktualniPrihlaseni.ImapPripojeni.Folders.Sent.AppendMessage(emailovaZprava); // Po úspěšném odeslání přidáme odeslanou zprávu na IMAP server do složky odeslaných e-mailů, neboť nám to bylo porazeno v dokumentaci knihovny ImapX.
  4896.  
  4897.             MessageBox.Show("Zpráva byla úspěšně odeslána.");
  4898.             ChyboveOknoLabel.Text = "Zpráva byla úspěšně odeslána.";
  4899.  
  4900.             this.DialogResult = DialogResult.OK;
  4901.         }
  4902.  
  4903.         /// <summary>
  4904.         /// Skryje chybovou hlášku po uplynutí deseti sekund.
  4905.         /// </summary>
  4906.         private void ZobrazeniChybyTimer_Tick(object sender, EventArgs e)
  4907.         {
  4908.             ZobrazeniChybyTimer.Enabled = false;            
  4909.             ChyboveOknoLabel.Hide();
  4910.             ChyboveOknoLabel.ForeColor = System.Drawing.Color.Black;
  4911.         }
  4912.  
  4913.         /// <summary>
  4914.         /// Metoda pro efekt, zobrazuje efekt blikajících teček při přihlašování.
  4915.         /// </summary>
  4916.         private void NacitaniTimer_Tick(object sender, EventArgs e)
  4917.         {            
  4918.             if (ChyboveOknoLabel.Text.Length >= 71 || ChyboveOknoLabel.Text.Length == 0)
  4919.                 ChyboveOknoLabel.Text = "Počkejte, prosím. Toto může chvíli trvat. Probíhá odesílání e-mailu ";
  4920.             else
  4921.                 ChyboveOknoLabel.Text += ".";
  4922.         }        
  4923.     }
  4924. }
  4925.  
  4926. using System;
  4927. using System.Collections.Generic;
  4928. using System.Linq;
  4929. using System.Windows.Forms;
  4930.  
  4931. // V tomto souboru jsou implementovány pomocná tlačítka, která slouží k editaci e-mailové zprávy a další komponenty spadající pod toto okno.
  4932. // Ačkoliv se jedná o tutéž třídu, je kód v tomto souboru, abychom nepřetěžovali soubor SendForm.cs, kde jsou nejdůležitější komponenty této třídy.
  4933.  
  4934. namespace Mail_Agent_2017
  4935. {
  4936.     public partial class SendForm
  4937.     {
  4938.         #region Implementace obsluh tlačítek usnadňující HTML zadávání.
  4939.         // Není to optimální, ale kdybych to chtěl dělat přesně dle svých představ, programoval bych spíš HTML editor než e-mailového klienta.
  4940.  
  4941.         private void DekoraceButton_Click(object sender, EventArgs e)
  4942.         {
  4943.             int start = TextTextarea.SelectionStart;
  4944.             switch (((Button)sender).Name)
  4945.             {
  4946.                 case "BoldButton": TextTextarea.Text = TextTextarea.Text.Insert(TextTextarea.SelectionStart, "<b></b>"); break;
  4947.                 case "ItalicButton": TextTextarea.Text = TextTextarea.Text.Insert(TextTextarea.SelectionStart, "<i></i>"); break;
  4948.                 case "UnderlineButton": TextTextarea.Text = TextTextarea.Text.Insert(TextTextarea.SelectionStart, "<u></u>"); break;
  4949.             }
  4950.  
  4951.             TextTextarea.Focus();
  4952.             TextTextarea.SelectionStart = start + 3;
  4953.         }
  4954.         private void FontButton_Click(object sender, EventArgs e)
  4955.         {
  4956.             // Na font se uživatele zeptáme pomocí font dialogu.
  4957.             FontDialog font = new FontDialog();
  4958.             font.ShowEffects = false;
  4959.             if (font.ShowDialog() == DialogResult.OK)
  4960.             {
  4961.                 int start = TextTextarea.SelectionStart;
  4962.                 string fontToHtml = "<span style = \"font-family: " + font.Font.ToString().Split('=')[1].Split(',')[0] + "; font-size: " + font.Font.ToString().Split('=')[2].Split(',')[0] + "px;\">";
  4963.                 TextTextarea.Text = TextTextarea.Text.Insert(start, fontToHtml + "</span>");
  4964.                 TextTextarea.Focus();
  4965.                 TextTextarea.SelectionStart = start + fontToHtml.Length;
  4966.             }
  4967.         }
  4968.  
  4969.         private void FontColorButton_Click(object sender, EventArgs e)
  4970.         {
  4971.             // Na barvu se uživatele zeptáme pomocí color dialogu.
  4972.             ColorDialog barva = new ColorDialog();
  4973.             barva.AllowFullOpen = true;
  4974.             if (barva.ShowDialog() == DialogResult.OK)
  4975.             {
  4976.                 int start = TextTextarea.SelectionStart;
  4977.                 string barvaToHtml = "<span style = \"color: rgb(" + barva.Color.R + ", " + barva.Color.G + ", " + barva.Color.B + ");\">";
  4978.                 TextTextarea.Text = TextTextarea.Text.Insert(start, barvaToHtml + "</span>");
  4979.                 TextTextarea.Focus();
  4980.                 TextTextarea.SelectionStart = start + barvaToHtml.Length;
  4981.             }
  4982.         }
  4983.  
  4984.         private void AlignmentButton_Click(object sender, EventArgs e)
  4985.         {
  4986.             int start = TextTextarea.SelectionStart;
  4987.             switch (((Button)sender).Name)
  4988.             {
  4989.                 case "LeftAlignmentButton":
  4990.                     TextTextarea.Text = TextTextarea.Text.Insert(start, "<div style=\"text-align: left;\"></div>");
  4991.                     start += 31;
  4992.                     break;
  4993.                 case "RightAlignmentButton":
  4994.                     TextTextarea.Text = TextTextarea.Text.Insert(start, "<div style=\"text-align: right;\"></div>");
  4995.                     start += 32;
  4996.                     break;
  4997.                 case "CenterAlignmentButton":
  4998.                     TextTextarea.Text = TextTextarea.Text.Insert(start, "<div style=\"text-align: center;\"></div>");
  4999.                     start += 33;
  5000.                     break;
  5001.             }
  5002.             TextTextarea.SelectionStart = start;
  5003.             TextTextarea.Focus();
  5004.         }
  5005.  
  5006.         private void HyperlinkButton_Click(object sender, EventArgs e)
  5007.         {
  5008.             string odkaz;
  5009.             string popisek;
  5010.  
  5011.             try
  5012.             {
  5013.                 if ((odkaz = new Prompt().ShowDialog("Vložte odkaz", "Mail Agent 2017 - Vložit hypertextový odkaz", -1)) == null)
  5014.                     throw new ChybneZadaniException();
  5015.  
  5016.                 if ((popisek = new Prompt().ShowDialog("Vložte popisek odkazu", "Mail Agent 2017 - Vložit hypertextový odkaz", -1)) == null)
  5017.                     throw new ChybneZadaniException();
  5018.             }
  5019.  
  5020.             catch
  5021.             { return; }
  5022.  
  5023.             int start = TextTextarea.SelectionStart;
  5024.             string odkazToHtml = "<a href = \"" + odkaz + "\">" + popisek + "</a>";
  5025.             TextTextarea.Text = TextTextarea.Text.Insert(start, odkazToHtml);
  5026.             TextTextarea.Focus();
  5027.             TextTextarea.SelectionStart = start + odkazToHtml.Length;
  5028.         }
  5029.  
  5030.         private void ImageButton_Click(object sender, EventArgs e)
  5031.         {
  5032.             string odkaz;
  5033.  
  5034.             try
  5035.             {
  5036.                 if ((odkaz = new Prompt().ShowDialog("Vložte odkaz na obrázek", "Mail Agent 2017 - Vložit obrázek", -1)) == null)
  5037.                     throw new ChybneZadaniException();
  5038.             }
  5039.  
  5040.             catch
  5041.             { return; }
  5042.  
  5043.             int start = TextTextarea.SelectionStart;
  5044.             string obrazekToHtml = "<img src = \"" + odkaz + "\">";
  5045.             TextTextarea.Text = TextTextarea.Text.Insert(start, obrazekToHtml);
  5046.             TextTextarea.Focus();
  5047.             TextTextarea.SelectionStart = start + obrazekToHtml.Length;
  5048.         }
  5049.  
  5050.         private void CopyButton_Click(object sender, EventArgs e)
  5051.         {
  5052.             Clipboard.SetText(TextTextarea.Text.Substring(TextTextarea.SelectionStart, TextTextarea.SelectionLength));
  5053.             TextTextarea.Focus();
  5054.         }
  5055.  
  5056.         private void PasteButton_Click(object sender, EventArgs e)
  5057.         {
  5058.             int start = TextTextarea.SelectionStart;
  5059.             TextTextarea.Text = TextTextarea.Text.Insert(start, Clipboard.GetText());
  5060.             TextTextarea.Focus();
  5061.             TextTextarea.SelectionStart = start + Clipboard.GetText().Length;
  5062.         }
  5063.         #endregion
  5064.  
  5065.  
  5066.         #region Implementace tlačítek zpět a vpřed.
  5067.  
  5068.         /*
  5069.          * Tlačítka si implementujeme po svém, aby splňovaly to, co od nich chceme.
  5070.          * Uděláme to tak, že každých 15 vteřin se uloží aktuální text na undo zásobník, pokud došlo ke změně.
  5071.          * Pří stisknutí tlačítka zpět se vždy do textboxu popne poslední záznam na zásobníku a aktuální stav se uloží na redo zásobník.
  5072.          * V případě provedení změny po undo se redo zásobník vymaže.
  5073.          */
  5074.  
  5075.         private void UndoButton_Click(object sender, EventArgs e)
  5076.         {
  5077.             if (undoZasobnik.Count > 0)
  5078.             {
  5079.                 redoZasobnik.Push(TextTextarea.Text);
  5080.                 TextTextarea.Text = undoZasobnik.Pop();
  5081.             }
  5082.             TextTextarea.Focus();
  5083.         }
  5084.  
  5085.         private void RedoButton_Click(object sender, EventArgs e)
  5086.         {
  5087.             if (redoZasobnik.Count > 0)
  5088.             {
  5089.                 undoZasobnik.Push(TextTextarea.Text);
  5090.                 TextTextarea.Text = redoZasobnik.Pop();
  5091.             }
  5092.             TextTextarea.Focus();
  5093.         }
  5094.  
  5095.         private void UndoTimer_Tick(object sender, EventArgs e)
  5096.         {
  5097.             // Pokud nedošlo od posledního ticku ke změně, nemá smysl pushovat na zásobník stejnou hodnotu.
  5098.             if ((TextTextarea.Text != null || undoZasobnik.Last() != TextTextarea.Text) && redoZasobnik.Count == 0)
  5099.                 undoZasobnik.Push(TextTextarea.Text);
  5100.         }
  5101.  
  5102.         private void TextTextarea_KeyDown(object sender, KeyEventArgs e)
  5103.         {
  5104.             if (redoZasobnik.Count > 0)
  5105.             {
  5106.                 redoZasobnik = new Stack<string>(); // Preventivně smažeme redo zásobník, jelikož po kroku zpět a následné změně se už "vpřed vrátit nemůžeme".
  5107.                 if (TextTextarea.Text != null || undoZasobnik.First() != TextTextarea.Text)
  5108.                     undoZasobnik.Push(TextTextarea.Text);
  5109.             }
  5110.  
  5111.         }
  5112.         #endregion
  5113.     }
  5114. }
  5115.  
  5116. using System;
  5117. using System.Collections.Generic;
  5118. using System.Linq;
  5119. using System.Text;
  5120. using System.Threading.Tasks;
  5121.  
  5122. namespace Mail_Agent_2017
  5123. {
  5124.     /// <summary>
  5125.     /// Definice výjimky pro nevyplněný předmět.
  5126.     /// </summary>
  5127.     public class EmailBezPredmetuException : Exception
  5128.     {
  5129.         /// <summary>
  5130.         /// Klasický konstruktor pro výjimku, volá konstruktor otce.
  5131.         /// </summary>
  5132.         public EmailBezPredmetuException() : base() { }
  5133.     }
  5134.  
  5135.     /// <summary>
  5136.     /// Definice výjimky pro prázdný text.
  5137.     /// </summary>
  5138.     public class EmailBezTextuException : Exception
  5139.     {
  5140.         /// <summary>
  5141.         /// Klasický konstruktor pro výjimku, volá konstruktor otce.
  5142.         /// </summary>
  5143.         public EmailBezTextuException() : base() { }
  5144.     }
  5145.  
  5146.     /// <summary>
  5147.     /// Definice výjimky pro chybně vyplněné adresáty.
  5148.     /// </summary>
  5149.     public class SpatneVyplnenyAdresatException : Exception
  5150.     {
  5151.         /// <summary>
  5152.         /// Klasický konstruktor pro výjimku, volá konstruktor otce.
  5153.         /// </summary>
  5154.         public SpatneVyplnenyAdresatException(string message) : base(message) { }
  5155.     }
  5156.  
  5157.     /// <summary>
  5158.     /// Výjimka, která je vyvolaná při chybě při navazování spojení se SMTP serverem.
  5159.     /// </summary>
  5160.     public class SmtpConnectFailException : Exception
  5161.     {
  5162.         /// <summary>
  5163.         /// Klasický konstruktor pro výjimku, volá konstruktor otce.
  5164.         /// </summary>
  5165.         public SmtpConnectFailException(string message) : base(message) { }
  5166.     }
  5167.  
  5168.     /// <summary>
  5169.     /// Výjimka, která je vyvolaná, když uživatel zadá chybné heslo.
  5170.     /// </summary>
  5171.     public class SpatneHesloException : Exception
  5172.     {
  5173.         /// <summary>
  5174.         /// Klasický konstruktor pro výjimku, volá konstruktor otce.
  5175.         /// </summary>
  5176.         public SpatneHesloException(string message) : base(message) { }
  5177.     }
  5178.  
  5179.     /// <summary>
  5180.     /// Výjimka, která je vyvolaná při chybě při navazování spojení s IMAP serverem.
  5181.     /// </summary>
  5182.     public class ImapConnectFailException : Exception
  5183.     {
  5184.         /// <summary>
  5185.         /// Klasický konstruktor pro výjimku, volá konstruktor otce.
  5186.         /// </summary>
  5187.         public ImapConnectFailException(string message) : base(message) { }
  5188.     }
  5189.  
  5190.     /// <summary>
  5191.     /// Výjimka, která je vyvolána při chybném vyplnění formuláře.
  5192.     /// </summary>
  5193.     public class ChybneZadaniException : Exception
  5194.     {
  5195.         /// <summary>
  5196.         /// Klasický konstruktor pro výjimku, volá konstruktor otce.
  5197.         /// </summary>
  5198.         public ChybneZadaniException(string message) : base(message) { }
  5199.         /// <summary>
  5200.         /// Klasický konstruktor pro výjimku, volá konstruktor otce.
  5201.         /// </summary>
  5202.         public ChybneZadaniException() : base() { }
  5203.     }
  5204.  
  5205.     /// <summary>
  5206.     /// Definice výjimky potřebné pro okno příloh.
  5207.     /// </summary>
  5208.     public class PrilisMnohoPrilohException : Exception
  5209.     {
  5210.         /// <summary>
  5211.      /// Klasický konstruktor pro výjimku, volá konstruktor otce.
  5212.      /// </summary>
  5213.         public PrilisMnohoPrilohException(string message) : base(message) { }
  5214.     }
  5215. }
Add Comment
Please, Sign In to add comment