source: trunk/CrypPlugins/Vigenere/VigenereSettings.cs @ 2527

Last change on this file since 2527 was 2334, checked in by Matthäus Wander, 11 years ago

removed 1006 occurences of DisplayLevel in 218 files (see #122)

File size: 15.1 KB
Line 
1/*
2   Copyright 2008 Sebastian Przybylski, University of Siegen
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17using System;
18using System.Collections.Generic;
19using System.Linq;
20using System.Text;
21using System.IO;
22using Cryptool.PluginBase;
23using System.ComponentModel;
24
25namespace Cryptool.Vigenere
26{
27    public class VigenereSettings : ISettings
28    {
29        #region Public Vigenere specific interface
30
31        /// <summary>
32        /// We use this delegate to send log messages from the settings class to the Vigenere plugin
33        /// </summary>
34        /// <param name="sender"></param>
35        /// <param name="msg"></param>
36        /// <param name="logLevel"></param>
37        public delegate void VigenereLogMessage(string msg, NotificationLevel logLevel);
38
39        /// <summary>
40        /// An enumaration for the different modes of dealing with unknown characters
41        /// </summary>
42        public enum UnknownSymbolHandlingMode { Ignore = 0, Remove = 1, Replace = 2 };
43
44        /// <summary>
45        /// Fire if a new text has to be shown in the status bar
46        /// </summary>
47        public event VigenereLogMessage LogMessage;
48
49        /// <summary>
50        /// Retrieves the current shift values of Vigenere (i.e. the key), or sets it
51        /// </summary>
52        [PropertySaveOrder(0)]
53        public int[] ShiftKey
54        {
55            get { return shiftValue; }
56            set { setKeyByValue(value); }
57        }
58
59        /// <summary>
60        /// Retrieves the current setting whether the alphabet should be treated as case sensitive or not
61        /// </summary>
62        [PropertySaveOrder(1)]
63        public bool CaseSensitiveAlphabet
64        {
65            get
66            {
67                if (caseSensitiveAlphabet == 0) return false;
68                else return true;
69            }
70            set { } //readonly
71        }
72
73        /// <summary>
74        /// Returns true if some settings have been changed. This value should be set externally to false. e.g
75        /// when a project was saved.
76        /// </summary>
77        [PropertySaveOrder(2)]
78        public bool HasChanges
79        {
80            get { return hasChanges; }
81            set { hasChanges = value; }
82        }
83
84        #endregion
85
86        #region Private variables
87        private bool hasChanges;
88        private int selectedAction = 0;
89        private int selectedModus = 0;
90        private string upperAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
91        private string lowerAlphabet = "abcdefghijklmnopqrstuvwxyz";
92        private string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
93        private char[] shiftChar = { 'B', 'C', 'D' };
94        private int[] shiftValue = { 1, 2, 3 };
95        private UnknownSymbolHandlingMode unknowSymbolHandling = UnknownSymbolHandlingMode.Ignore;
96        private int caseSensitiveAlphabet = 0; //0=case insensitive, 1 = case sensitive
97        #endregion
98
99        #region Private methods
100        private string removeEqualChars(string value)
101        {
102            int length = value.Length;
103
104            for (int i = 0; i < length; i++)
105            {
106                for (int j = i + 1; j < length; j++)
107                {
108                    if((value[i]) == value[j] || (!CaseSensitiveAlphabet & (char.ToUpper(value[i]) == char.ToUpper(value[j]))))
109                    {
110                        LogMessage("Removing duplicate letter: \'" + value[j] + "\' from alphabet!", NotificationLevel.Warning);
111                        value = value.Remove(j,1);
112                        j--;
113                        length--;
114                    }
115                }
116            }
117            return value;
118        }
119
120        /// <summary>
121        /// Parse the offset string and set the shiftValue/ShiftChar accordingly
122        /// </summary>
123        /// <param name="offsetString"></param>
124        private void setKeyByValue(string offsetString)
125        {
126            try
127            {
128                string[] offsetStr = offsetString.Split(',');
129                int[] offset = new int[offsetStr.Length];
130                for (int i = 0; i < offsetStr.Length; i++)
131                {
132                    offset[i] = int.Parse(offsetStr[i]);
133                }
134                setKeyByValue(offset);
135            }
136            catch (Exception e)
137            {
138                LogMessage("Bad input \"" + offsetString + "\"! (" + e.Message + ") Reverting to " + shiftValue.ToString() + "!", NotificationLevel.Error);
139                OnPropertyChanged("ShiftValue");
140            }
141        }
142
143        /// <summary>
144        /// Set the new shiftValue and the new shiftCharacter to offset % alphabet.Length
145        /// </summary>
146        /// <param name="offset"></param>
147        public void setKeyByValue(int[] offset)
148        {
149            hasChanges = true;
150
151            //making sure the shift value lies within the alphabet range
152            for (int i = 0; i < offset.Length; i++)
153                offset[i] = offset[i] % alphabet.Length;
154
155            //set the new shiftChar
156            shiftChar = new char[offset.Length];
157            for (int i = 0; i < offset.Length; i++)
158                shiftChar[i] = alphabet[offset[i]];
159
160            //set the new shiftValue
161            shiftValue = new int[offset.Length];
162            for (int i = 0; i < offset.Length; i++)
163                shiftValue[i] = offset[i];
164
165            //Anounnce this to the settings pane
166            OnPropertyChanged("ShiftValue");
167            OnPropertyChanged("ShiftChar");
168
169            //print some info in the log.
170            LogMessage("Accepted new shift value " + offset.ToString() + "! (Adjusted shift character to '" + shiftChar.ToString() + "\'", NotificationLevel.Info);
171        }
172
173        private void setKeyByCharacter(string value)
174        {
175            try
176            {
177                int[] offset = new int[value.Length];
178                if (this.CaseSensitiveAlphabet)
179                {
180                    for (int i = 0; i < value.Length; i++)
181                        offset[i] = alphabet.IndexOf(value[i]);
182                }
183                else
184                {
185                    for (int i = 0; i < value.Length; i++)
186                        offset[i] = alphabet.ToUpper().IndexOf(char.ToUpper(value[i]));
187                }
188                for (int i = 0; i < offset.Length; i++)
189                {
190                    if (offset[i] >= 0)
191                    {
192                        hasChanges = true;
193                        shiftValue = new int[offset.Length];
194                        for (int j = 0; j < offset.Length; j++)
195                            shiftValue[j] = offset[j];
196                        shiftChar = new char[shiftValue.Length];
197                        for (int j = 0; j < shiftValue.Length; j++)
198                            shiftChar[j] = alphabet[shiftValue[j]];
199                        LogMessage("Accepted new shift character \'" + shiftChar.ToString() + "\'! (Adjusted shift value to " + shiftValue.ToString() + ")", NotificationLevel.Info);
200                        OnPropertyChanged("ShiftValue");
201                        OnPropertyChanged("ShiftChar");
202                        break;
203                    }
204                    else
205                    {
206                        LogMessage("Bad input \"" + value + "\"! (Character not in alphabet!) Reverting to " + shiftChar.ToString() + "!", NotificationLevel.Error);
207                    }
208                }
209            }
210            catch (Exception e)
211            {
212                LogMessage("Bad input \"" + value + "\"! (" + e.Message + ") Reverting to " + shiftChar.ToString() + "!", NotificationLevel.Error);
213            }
214        }
215        #endregion
216
217        #region Algorithm settings properties (visible in the Settings pane)
218
219        [PropertySaveOrder(3)]
220        [ContextMenu("Modus", "Select the Algorithm action", 1, ContextMenuControlType.ComboBox, new int[] { 1, 2 }, "Classic", "Autokey")]
221        [TaskPane("Modus", "Select the Algorithm action", null, 1, false, ControlType.ComboBox, new string[] { "Classic", "Autokey" })]
222        public int Modus
223        {
224            get { return this.selectedModus; }
225            set
226            {
227                if (value != selectedModus) HasChanges = true;
228                this.selectedModus = value;
229                OnPropertyChanged("Modus");
230            }
231        }
232
233
234        [PropertySaveOrder(4)]
235        [ContextMenu("Action","Select the Algorithm action",2,ContextMenuControlType.ComboBox,new int[]{1,2},"Encrypt","Decrypt")]
236        [TaskPane("Action", "Select the Algorithm action", null, 2, false, ControlType.ComboBox, new string[] { "Encrypt", "Decrypt"})]
237        public int Action
238        {
239            get { return this.selectedAction; }
240            set
241            {
242                if (value != selectedAction) HasChanges = true;
243                this.selectedAction = value;
244                OnPropertyChanged("Action");
245            }
246        }
247
248        [PropertySaveOrder(5)]
249        [TaskPane("Shift value (integer)", "Enter the numbers of letters to shift seperated by comma.", null, 3, false, ControlType.TextBox, null)]
250        public string ShiftValue
251        {
252            get
253            {
254                StringBuilder str = new StringBuilder(string.Empty);
255                for (int i = 0; i < this.shiftValue.Length; i++)
256                {
257                    str.Append(this.shiftValue[i].ToString());
258                    if (i != this.shiftValue.Length - 1)
259                        str.Append(",");
260                }
261                return str.ToString();
262            }
263            set { setKeyByValue(value); }
264        }
265
266        [PropertySaveOrder(6)]
267        [TaskPane("Shift key (multiple letters)", "Enter multiple letters as the key", null, 4, false, ControlType.TextBox, null)]
268        public string ShiftChar
269        {
270            get { return new String(this.shiftChar); }
271            set { setKeyByCharacter(value); }
272        }
273
274        [PropertySaveOrder(7)]
275        [ContextMenu("Unknown symbol handling","What should be done with ecountered characters at the input which are not in the alphabet?",5,ContextMenuControlType.ComboBox,null,"Ignore (leave unmodified)","Remove","Replace with \'?\'")]
276        [TaskPane("Unknown symbol handling", "What should be done with encountered characters at the input which are not in the alphabet?", null, 5, false, ControlType.ComboBox, new string[] { "Ignore (leave unmodified)", "Remove", "Replace with \'?\'" })]
277        public int UnknownSymbolHandling
278        {
279            get { return (int)this.unknowSymbolHandling; }
280            set
281            {
282                if ((UnknownSymbolHandlingMode)value != unknowSymbolHandling) hasChanges = true;
283                this.unknowSymbolHandling = (UnknownSymbolHandlingMode)value;
284                OnPropertyChanged("UnknownSymbolHandling");
285            }
286        }
287
288        [PropertySaveOrder(8)]
289        [ContextMenu("Alphabet case sensitive","Should upper and lower case be treated differently? (Should a == A)",8,ContextMenuControlType.ComboBox,null, "Case insensitive","Case sensitive")]
290        [TaskPane("Alphabet case sensitive", "Should upper and lower case be treated differently? (Should a == A)", null, 8, false, ControlType.ComboBox, new string[] { "Case insensitive", "Case sensitive" })]
291        public int AlphabetCase
292        {
293            get { return this.caseSensitiveAlphabet; }
294            set
295            {
296                if (value != caseSensitiveAlphabet) hasChanges = true;
297                this.caseSensitiveAlphabet = value;
298                if (value == 0)
299                {
300                    if (alphabet == (upperAlphabet + lowerAlphabet))
301                    {
302                        alphabet = upperAlphabet;
303                        LogMessage("Changing alphabet to: \"" + alphabet + "\" (" + alphabet.Length.ToString() + "Symbols)",NotificationLevel.Info);
304                        OnPropertyChanged("AlphabetSymbols");
305                        //re-set also the key (shifvalue/shiftchar to be in the range of the new alphabet
306                        setKeyByValue(shiftValue);
307                    }
308                }
309                else
310                {
311                    if(alphabet == upperAlphabet)
312                    {
313                        alphabet = upperAlphabet + lowerAlphabet;
314                        LogMessage("Changing alphabet to: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
315                        OnPropertyChanged("AlphabetSymbols");
316                    }
317                }
318
319                //remove equal characters from the current alphabet
320                string a = alphabet;
321                alphabet = removeEqualChars(alphabet);
322
323                if(a != alphabet)
324                {
325                    OnPropertyChanged("AlphabetSymbols");
326                    LogMessage("Changing alphabet to: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)",NotificationLevel.Info);
327                }
328                OnPropertyChanged("CaseSensitiveAlphabet");
329            }
330        }
331
332        [PropertySaveOrder(9)]
333        [TaskPane("Alphabet", "This is the used alphabet.", null, 7, false, ControlType.TextBox, null)]
334        public string AlphabetSymbols
335        {
336            get { return this.alphabet; }
337            set
338            {
339                string a = removeEqualChars(value);
340                if (a.Length == 0) //cannot accept empty alphabets
341                {
342                    LogMessage("Ignoring empty alphabet from user! Using previous alphabet: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
343                }
344                else if (!alphabet.Equals(a))
345                {
346                    hasChanges = true;
347                    this.alphabet = a;
348                    setKeyByValue(shiftValue); //re-evaluate if the shiftvalue is stillt within the range
349                    LogMessage("Accepted new alphabet from user: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
350                    OnPropertyChanged("AlphabetSymbols");
351                }
352            }
353        }
354        #endregion
355
356        #region INotifyPropertyChanged Members
357
358        public event PropertyChangedEventHandler PropertyChanged;
359
360        protected void OnPropertyChanged(string name)
361        {
362            if (PropertyChanged != null)
363            {
364                PropertyChanged(this, new PropertyChangedEventArgs(name));
365            }
366        }
367
368        #endregion
369    }
370}
Note: See TracBrowser for help on using the repository browser.