Changeset 1229 for trunk/Documentation


Ignore:
Timestamp:
Mar 2, 2010, 6:18:43 PM (12 years ago)
Author:
Patrick Vacek
Message:

HowTo: further edits, mostly to middle section. Still more to come!

Location:
trunk/Documentation/Developer/PluginHowTo
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Documentation/Developer/PluginHowTo/HowToDeveloper.tex

    r1181 r1229  
    1515\usepackage{listings}
    1616\usepackage{fix-cm}
     17\usepackage{textcomp}
    1718
    1819
     
    3334breaklines=true, % Wordwrap activated
    3435showstringspaces=false,
     36upquote=true, % changes smart single quotes to straight ' marks
    3537% emph defines certain colors for specific words
    3638emph={double,bool,int,unsigned,char,true,false,void},
     
    167169     Since the first launch of CrypTool 1 in 1999 the art of software development has changed dramatically. The CrypTool 2 team began working in 2008 to develop a completely new e-learning application, embracing the newest trends in both didactics and software architecture to delight the end-user with an entirely new experience.\\
    168170
    169      CrypTool 2 is built using
     171     To meet these ends, CrypTool 2 is built using the following:
    170172
    171173\begin{itemize}
    172         \item .NET (a modern software framework with solutions to common programming problems from Microsoft),
    173         \item C\# (a modern object-oriented programming language, comparable to Java), and
    174     \item WPF (a modern purely vector-based graphical subsystem for rendering user interfaces in Windows-based applications), plus
    175     \item Visual Studio 2008 (a development environment) and
    176         \item Subversion (a source code and documentation version management system).
     174        \item .NET (a modern software framework with solutions to common programming problems from Microsoft)
     175        \item C\# (a modern object-oriented programming language, comparable to Java)
     176    \item WPF (a modern purely vector-based graphical subsystem for rendering user interfaces in Windows-based applications)
     177    \item Visual Studio 2008 (a development environment)
     178        \item Subversion (a source code and documentation version management system)
    177179\end{itemize}
    178180
  • trunk/Documentation/Developer/PluginHowTo/part1.tex

    r1181 r1229  
    2424
    2525Now you will need a way of accessing and downloading the source code. In the CrypTool 2.0 project we use Subversion (SVN) for version control, and hence you need an \textbf{SVN client}, e.g.\ \textbf{TortoiseSVN} or the \textbf{svn commandline from cygwin}. It does not matter which client you use, but if you have never worked with SVN before, we suggest using \href{http://www.tortoisesvn.net/}{TortoiseSVN}, since it offers a nice Windows Explorer integration of SVN.
     26\clearpage
    2627
    2728\subsection*{The CrypTool2 SVN URL}
     
    3940As mentioned above, in order to access the SVN repository one of the best options is \href{http://www.tortoisesvn.net/}{TortoiseSVN}. We will describe here how to use the basics of the program, although you should be able to use any SVN client in a similar fashion.
    4041
    41 First install TortoiseSVN (which unfortunately requires you to reboot your computer) and then create a directory (for instance ``CrypTool2") for storing the local working files somewhere on your computer. Right-click on this directory and select ``SVN Checkout" from the context menu. A window will appear in which you will be asked for the URL of the repository as given above. The ``Checkout directory" should already be filled in correctly with your new folder. Then just hit ``OK", accept the certificate (if necessary), and enter your login information as described above. Mark the checkbox for saving your credentials if you don't want to enter them every time you work with the repository. Then hit ``OK", and now the whole CrypTool2 repository should be checked out into your chosen directory.
     42\begin{figure}[h!]
     43        \centering
     44                \includegraphics[width=0.40\textwidth]{figures/tortoise_svn_checkout.jpg}
     45        \caption{Selecting ``SVN Checkout" from the context menu after installing TortoiseSVN.}
     46        \label{fig:tortoise_svn_checkout}
     47\end{figure}
     48
     49First install TortoiseSVN (which unfortunately requires you to reboot your computer) and then create a directory (for instance ``CrypTool2") for storing the local working files somewhere on your computer. Right-click on this directory and select ``SVN Checkout" from the context menu. A window will appear in which you will be asked for the URL of the repository; use the address given above, as seen in Figure \ref{fig:tortoise_svn_checkout2}. The ``Checkout directory" should already be filled in correctly with your new folder. Then just hit ``OK", accept the certificate (if necessary), and enter your login information as described above. Mark the checkbox for saving your credentials if you don't want to enter them every time you work with the repository. Then hit ``OK", and now the whole CrypTool2 repository should be checked out into your chosen directory.
     50\clearpage
     51
     52\begin{figure}[h!]
     53        \centering
     54                \includegraphics[width=0.60\textwidth]{figures/tortoise_svn_checkout2.jpg}
     55        \caption{Checking out the CrypTool2 repository.}
     56        \label{fig:tortoise_svn_checkout2}
     57\end{figure}
    4258
    4359Later on, if changes have been made in the repository and you want to update your working copy, you can do this by right-clicking on any directory within the working files and choosing ``SVN Update" from the context menu. You should do this often to maintain a current version of the files.
     
    4965
    5066If you are a registered developer, you can commit your file changes to the public CrypTool2 repository. Right-click on the directory within the working files that contains your changes and select ``SVN Commit" from the context menu to upload your changes. Please always provide \textit{meaningful descriptions} of your updates. You should commit your sources to our SVN repository as often as you can to ensure your interoperability with the rest of the project, but only commit code that successfully compiles and runs!
     67
     68\begin{figure}[h!]
     69        \centering
     70                \includegraphics[width=0.40\textwidth]{figures/tortoise_svn_commit.jpg}
     71        \caption{Selecting ``SVN Commit" from the context menu.}
     72        \label{fig:tortoise_svn_commit}
     73\end{figure}
    5174
    5275You can use command words in the SVN comment to link your changes to a particular ticket. The command syntax is as follows:
     
    109132
    110133Please note that any text after the colon and the whitespace will be treated as the file name. Therefore, do not use quotation marks and do not write any text after the file name.
     134\clearpage
    111135
    112136\section{Compiling the sources}
  • trunk/Documentation/Developer/PluginHowTo/part2.tex

    r1181 r1229  
    2020        \centering
    2121                \includegraphics[width=0.80\textwidth]{figures/save_solution_csharp_express.JPG}
    22         \caption{The Microsoft C\# Express Edition ``Save Project" dialog window.}
     22        \caption{The Visual Studio C\# Express Edition ``Save Project" dialog window.}
    2323        \label{fig:save_solution_csharp_express}
    2424\end{figure}
     
    5555\clearpage
    5656
    57 \noindent Select the project ``CrypPluginBase". If you do not have the ``CrypPluginBase" source code, it is also possible to add a reference the binary DLL. In this case browse to the path where the library file \textit{CrypPluginBase.dll} is located, e.g.\ \textit{C:\textbackslash Documents and Settings\textbackslash $<$Username$>$\textbackslash My Documents\textbackslash Visual Studio 2008\textbackslash Projects\textbackslash CrypPluginBase\textbackslash bin\textbackslash Debug} and select the library by double clicking the file or pressing the ``OK" button. (You can also select the binary DLL located in the folder where \textit{CrypWin.exe} was placed when you downloaded CrypTool2.)
     57\noindent Unless you have created your new project in the same CrypTool 2.0 solution, you probably will not be able to select the library directly as seen above in Figure \ref{fig:add_pluginbase_source}; instead you can browse for the binary DLL as seen below in Figure \ref{fig:browse_reference}. Click on the ``Browse" tab and navigate to the folder in which you downloaded the CrypTool 2 project. Within that folder, go to \textit{\textbackslash CrypPluginBase\textbackslash bin\textbackslash Debug} and select the file ``CryptPluginBase.dll". The library reference can then be added by double clicking the file or pressing the ``OK" button.
    5858
    5959\begin{figure}[h!]
     
    6464\end{figure}
    6565
    66 \noindent Besides CrypPluginBase you will need to add three assembly references to provide the necessary ``Windows" namespaces for the \textbf{user control} functions ``Presentation" and ``QuickWatchPresentation". This can be done in the same manner as before with the ``CrypPluginBase" but by selecting the ``.NET" tab. Select the following .NET components:
     66\noindent Besides CrypPluginBase you will need to add three Windows assembly references to provide the necessary namespaces for the \textbf{user control} functions ``Presentation" and ``QuickWatchPresentation". This can be done in a similar manner as before with the ``CrypPluginBase" reference, but by selecting the ``.NET" tab and searching for the references there. Select the following .NET components:
    6767
    6868\begin{itemize}
     
    103103\label{sec:CreatingClassesForTheAlgorithmAndItsSettings}
    104104
    105 In the next step we will create two classes. The first class will be the main driver; we will call ours ``Caesar" since that is the name of the cipher that it will implement. In our case, this class has to inherit from IEncryption because it will be an ecryption plugin. If it was instead a hash plugin, this class should inherit from IHash. The second class will be used to store setting information for the plugin, and thus we will name ours ``CaesarSettings". It has to inherit from ISettings.
     105In the next step we will create two classes. The first class will be the main driver; we will call ours ``Caesar" since that is the name of the cipher that it will implement. In our case, this class has to inherit from IEncryption because it will be an ecryption plugin. If it was instead a hash plugin, this class should inherit from IHash. The second class will be used to store setting information for the plugin, and thus we will name ours ``CaesarSettings". It will need to inherit from ISettings.
    106106\clearpage
    107107
     
    179179        \item Cryptool.PluginBase.Miscellaneous --- contains assorted helper classes, including \textit{GuiLogMessage} and \textit{PropertyChanged}.
    180180        \item Cryptool.PluginBase.Resources --- used only by CrypWin and the editor; not necessary for plugin development.
    181         \item Cryptool.PluginBase.Tool --- contains an interface for all external tools implemented by CrypTool 2.0 that do not entirely support the CrypTool 2.0 API .
     181        \item Cryptool.PluginBase.Tool --- contains an interface for all external tools implemented by CrypTool 2.0 that do not entirely support the CrypTool 2.0 API.
    182182        \item Cryptool.PluginBase.Validation --- contains interfaces for validation methods, including regular expressions.
    183183\end{itemize}
     
    226226\end{lstlisting}
    227227
    228 \subsection{Adding interface functions for the Caesar class}
    229 \label{sec:AddingInterfaceFunctionsForTheCaesarClass}
    230 
    231 There is an underscore at the ''I'' in IEncryption statement. Move your mouse over it or place the cursor at it and press ''Shift+Alt+F10'' and you will see the following submenu:
     228\subsection{Adding interface functions to the Caesar class}
     229\label{sec:AddingInterfaceFunctionsToTheCaesarClass}
     230
     231You may notice an underscore underneath the ``I" in ``IEncryption". Move your mouse over it, or place the cursor on it and press ``Shift+Alt+F10" and the following submenu should appear:
     232
    232233\begin{figure}[h!]
    233234        \centering
     
    235236        \caption{Inherit submenu}
    236237        \label{fig:inherit_submenu}
    237 \end{figure}\\
    238 Choose the item ''Implement interface 'IEncryption'''. Visual Studio/C\# Express will now place all available and needed interface members to interact with the CrypTool core (this saves you also a lot of typing code).\\
    239 Your code will now look like this:
     238\end{figure}
     239
     240Select the item ``Implement interface `IEncryption'". Visual Studio will automatically generate all the interface members necessary for interaction with the CrypTool 2 core. (This step will save you a lot of typing!)
     241\clearpage
     242
     243\noindent Your code should now look like this:
     244
    240245\begin{lstlisting}
    241246using System.Collections.Generic;
     
    319324}
    320325\end{lstlisting}
    321 \subsection{Add namespace and interfaces for the class CaesarSettings}\label{sec:AddNamespaceAndInterfacesForTheClassCaesarSettings}
    322 Let's now take a look at the second class "CaesarSettings" by double clicking at the "CaesarSettings.cs" file at the Solution Explorer. First we also have to include the namespace of "Cryptool.PluginBase" to the class header and let the settings class inherit from "ISettings" analogous as seen before at the Caesar class. Visual Studio/C\# Express will here also automatically place code from the CrypTool interface if available.
     326
     327\subsection{Adding the namespace and interfaces to the CaesarSettings class}
     328\label{sec:AddingTheNamespaceAndInterfacesToTheCaesarSettingsClass}
     329
     330Let's now take a look at the second class in our example, ``CaesarSettings", by double-clicking on the ``CaesarSettings.cs" file in the Solution Explorer. First, we need to again include the ``Cryptool.PluginBase" namespace to the class header. Then we must let the settings class inherit from ``ISettings" in the same manner as was done with the Caesar class. Visual Studio will again automatically generate code from the CrypTool interface as seen below. (We can again remove the lines \texttt{using System;} and \texttt{using System.Linq;}, as we do not need those references.)\\
     331
    323332\begin{lstlisting}
    324333using System.Collections.Generic;
     
    355364}
    356365\end{lstlisting}
    357 \subsection{Add controls for the class CaesarSettings (if needed)}\label{sec:AddControlsForTheClassCaesarSettingsIfNeeded}
    358 Now we have to implement some kind of controls (like button, text box) if we need them in the CrypTool \textbf{TaskPane} to modify settings of the algorithm. If you decided to provide an algorithm (e.g. Hash) which do not have any kind of settings you can leave this class now empty. The only part you have to modify is the ''HasChanges'' property to avoid any ''NotImplementedException''. How to modify this property you can see in the following code which demonstrate the modifications fot the TaskPane for our Caesar algorithm. You can also take a look at the other algorithm source codes which are stored in our subversion how you can provide a TaskPane. The following source code demonstrates how we provide our TaskPane as seen above.
     366
     367\subsection{Adding controls to the CaesarSettings class}
     368\label{sec:AddingControlsToTheCaesarSettingsClass}
     369
     370The settings class is used to populate the TaskPane in the CrypTool 2 application so that the user can modify settings at will. To meet these ends we will need to implement some controls such as buttons and text boxes. If you will be implementing an algorithm that does not have any user-defined settings (e.g. a hash function), then this class can be left empty; you will, however, still have to modify the ``HasChanges" property to avoid a ``NotImplementedException". The following code demonstrates the modifications necessary to create the backend for the TaskPane for our Caesar algorithm. You can also look at the source code of other algorithms in the subversion repository for examples of how to create the TaskPane backend.\\
     371
    359372\begin{lstlisting}
    360373using System;
     
    371384
    372385        /// <summary>
    373         /// We use this delegate to send log messages from the settings class to the Caesar plugin
     386        /// We use this delegate to send log messages from
     387        /// the settings class to the Caesar plugin.
    374388        /// </summary>
    375389        public delegate void CaesarLogMessage(string msg, NotificationLevel loglevel);
    376390
    377391        /// <summary>
    378         /// An enumaration for the different modes of dealing with unknown characters
     392        /// An enumeration for the different modes of handling
     393        /// unknown characters.
    379394        /// </summary>
    380395        public enum UnknownSymbolHandlingMode { Ignore = 0, Remove = 1, Replace = 2 };
    381396
    382397        /// <summary>
    383         /// Fire if a new status message was send
     398        /// Fires when a new status message was sent.
    384399        /// </summary>
    385400        public event CaesarLogMessage LogMessage;
     
    390405
    391406        /// <summary>
    392         /// Retrieves the current sihft value of Caesar (i.e. the key), or sets it
     407        /// Retrieves or sets the current shift value (i.e. the key).
    393408        /// </summary>
    394409        [PropertySaveOrder(0)]
     
    403418
    404419        /// <summary>
    405         /// Retrieves the current setting whether the alphabet should be treated as case sensitive or not
     420        /// Retrieves the current setting of whether or not the
     421        /// alphabet should be treated as case-sensitive.
    406422        /// </summary>
    407423        [PropertySaveOrder(1)]
     
    415431                {   return true;    }
    416432            }
    417             set {} // readonly, because there are some problems if we omit the set part.
     433            set {} // this setting is readonly, but we must include
     434                   // some form of set method to prevent problems.
    418435        }
    419436
    420437
    421438        /// <summary>
    422         /// Returns true if some settings have been changed. This value should be set externally to false e.g.
    423         /// when a project was saved.
     439        /// Returns true if any settings have been changed.
     440        /// This value should be set externally to false e.g.
     441        /// when a project is saved.
    424442        /// </summary>
    425443        [PropertySaveOrder(3)]
     
    435453        private bool hasChanges;
    436454        private int selectedAction = 0;
    437         private string upperAlphabet = ''ABCDEFGHIJKLMNOPQRSTUVWXYZ'';
    438         private string lowerAlphabet = ''abcdefghijklmnopqrstuvwxyz'';
    439         private string alphabet = ''ABCDEFGHIJKLMNOPQRSTUVWXYZ'';
     455        private string upperAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     456        private string lowerAlphabet = "abcdefghijklmnopqrstuvwxyz";
     457        private string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    440458        private char shiftChar = 'C';
    441459        private int shiftValue = 2;
    442         // private int shiftValue = 2;
    443460        private UnknownSymbolHandlingMode unknownSymbolHandling = UnknownSymbolHandlingMode.Ignore;
    444         private int caseSensitiveAlphabet = 0; // 0 = case insensitve, 1 = case sensitive
     461        private int caseSensitiveAlphabet = 0; // 0 = case-insensitve, 1 = case-sensitive
    445462        private bool sensitivityEnabled = true;
    446463        #endregion
     
    458475                    if ((value[i] == value[j]) || (!CaseSensitiveAlphabet & (char.ToUpper(value[i]) == char.ToUpper(value[j]))))
    459476                    {
    460                         LogMessage(''Removing duplicate letter: \''' + value[j] + ''\' from alphabet!'', NotificationLevel.Warning);
     477                        LogMessage("Removing duplicate letter: \'" + value[j] + "\' from alphabet!", NotificationLevel.Warning);
    461478                        value = value.Remove(j,1);
    462479                        j--;
     
    470487
    471488        /// <summary>
    472         /// Set the new shiftValue and the new shiftCharacter to offset % alphabet.Length
     489        /// Set the new shiftValue and the new shiftCharacter
     490        /// to offset % alphabet.Length.
    473491        /// </summary>
    474492        private void setKeyByValue(int offset)
     
    476494            HasChanges = true;
    477495
    478             // making sure the shift value lies within the alphabet range
     496            // Make sure the shift value lies within the alphabet range.
    479497            offset = offset % alphabet.Length;
    480498
    481             // set the new shiftChar
     499            // Set the new shiftChar.
    482500            shiftChar = alphabet[offset];
    483501
    484             // set the new shiftValue
     502            // Set the new shiftValue.
    485503            shiftValue = offset;
    486504
    487             // Anounnce this to the settings pane
    488             OnPropertyChanged(''ShiftValue'');
    489             OnPropertyChanged(''ShiftChar'');
    490 
    491             // print some info in the log.
    492             LogMessage(''Accepted new shift value '' + offset + ''! (Adjusted shift character to \''' + shiftChar + ''\')'', NotificationLevel.Info);
     505            // Announce this to the settings pane.
     506            OnPropertyChanged("ShiftValue");
     507            OnPropertyChanged("ShiftChar");
     508
     509            // Print some info in the log.
     510            LogMessage("Accepted new shift value " + offset + "! (Adjusted shift character to \'" + shiftChar + "\')", NotificationLevel.Info);
    493511        }
    494512
     
    512530                    shiftValue = offset;
    513531                    shiftChar = alphabet[shiftValue];
    514                     LogMessage(''Accepted new shift character \''' + shiftChar + ''\'! (Adjusted shift value to '' + shiftValue + '')'', NotificationLevel.Info);
    515                     OnPropertyChanged(''ShiftValue'');
    516                     OnPropertyChanged(''ShiftChar'');
     532                    LogMessage("Accepted new shift character \'" + shiftChar + "\'! (Adjusted shift value to " + shiftValue + ")", NotificationLevel.Info);
     533                    OnPropertyChanged("ShiftValue");
     534                    OnPropertyChanged("ShiftChar");
    517535                }
    518536                else
    519537                {
    520                     LogMessage(''Bad input \'''' + value + ''\''! (Character not in alphabet!) Reverting to '' + shiftChar.ToString() + ''!'', NotificationLevel.Error);
     538                    LogMessage("Bad input \"" + value + "\"! (Character not in alphabet!) Reverting to " + shiftChar.ToString() + "!", NotificationLevel.Error);
    521539                }
    522540            }
    523541            catch (Exception e)
    524542            {
    525                 LogMessage(''Bad input \'''' + value + ''\''! ('' + e.Message + '') Reverting to '' + shiftChar.ToString() + ''!'', NotificationLevel.Error);
     543                LogMessage("Bad input \"" + value + "\"! (" + e.Message + ") Reverting to " + shiftChar.ToString() + "!", NotificationLevel.Error);
    526544            }
    527545        }
     
    532550
    533551        [PropertySaveOrder(4)]
    534         [ContextMenu(''Action'', ''Select the Algorithm action'', 1, DisplayLevel.Beginner, ContextMenuControlType.ComboBox, new int[] { 1, 2 }, ''Encrypt'', ''Decrypt'')]
    535         [TaskPane(''Action'', ''setAlgorithmActionDescription'', null, 1, true, DisplayLevel.Beginner, ControlType.ComboBox, new string[] { ''Encrypt'', ''Decrypt'' })]
     552        [ContextMenu("Action", "Select the algorithm action", 1, DisplayLevel.Beginner, ContextMenuControlType.ComboBox, new int[] { 1, 2 }, "Encrypt", "Decrypt")]
     553        [TaskPane("Action", "setAlgorithmActionDescription", null, 1, true, DisplayLevel.Beginner, ControlType.ComboBox, new string[] { "Encrypt", "Decrypt" })]
    536554        public int Action
    537555        {
     
    544562                if (value != selectedAction) HasChanges = true;
    545563                this.selectedAction = value;
    546                 OnPropertyChanged(''Action'');
     564                OnPropertyChanged("Action");
    547565
    548566                if (ReExecute != null) ReExecute();
     
    551569
    552570        [PropertySaveOrder(5)]
    553         [TaskPane(''Key as integer'', ''Enter the number of letters to shift. For instance a value of 1 means that the plaintext character a gets mapped to the ciphertext character B, b to C and so on.'', null, 2, true, DisplayLevel.Beginner, ControlType.NumericUpDown, ValidationType.RangeInteger, 0, 100)]
     571        [TaskPane("Key as integer", "Enter the number of letters to shift. For example, a value of 1 means that the plaintext character 'a' gets mapped to the ciphertext character 'B', 'b' to 'C', and so on.", null, 2, true, DisplayLevel.Beginner, ControlType.NumericUpDown, ValidationType.RangeInteger, 0, 100)]
    554572        public int ShiftValue
    555573        {
     
    562580        }
    563581
    564 
    565582        [PropertySaveOrder(6)]
    566         [TaskPaneAttribute(''Key as single letter'', ''Enter a single letter as the key. This letter is mapped to an integer stating the position in the alphabet. The values for 'Key as integer' and 'Key as single letter' are always synchronized.'', null, 3, true, DisplayLevel.Beginner, ControlType.TextBox, ValidationType.RegEx, ''^([A-Z]|[a-z]){1,1}'')]
     583        [TaskPaneAttribute("Key as single letter", "Enter a single letter as the key. This letter is mapped to an integer stating the position in the alphabet. The values for 'Key as integer' and 'Key as single letter' are always synchronized.", null, 3, true, DisplayLevel.Beginner, ControlType.TextBox, ValidationType.RegEx, "^([A-Z]|[a-z]){1,1}")]
    567584        public string ShiftChar
    568585        {
     
    576593
    577594        [PropertySaveOrder(7)]
    578         [ContextMenu(''Unknown symbol handling'', ''What should be done with encountered characters at the input which are not in the alphabet?'', 4, DisplayLevel.Expert, ContextMenuControlType.ComboBox, null, new string[] { ''Ignore (leave unmodified)'', ''Remove'', ''Replace with \'?\''' })]
    579         [TaskPane(''Unknown symbol handling'', ''What should be done with encountered characters at the input which are not in the alphabet?'', null, 4, true, DisplayLevel.Expert, ControlType.ComboBox, new string[] { ''Ignore (leave unmodified)'', ''Remove'', ''Replace with \'?\''' })]
     595        [ContextMenu("Unknown symbol handling", "What should be done with characters encountered in the input which are not in the alphabet?", 4, DisplayLevel.Expert, ContextMenuControlType.ComboBox, null, new string[] { "Ignore (leave unmodified)", "Remove", "Replace with \'?\'" })]
     596        [TaskPane("Unknown symbol handling", "What should be done with characters encountered in the input which are not in the alphabet?", null, 4, true, DisplayLevel.Expert, ControlType.ComboBox, new string[] { "Ignore (leave unmodified)", "Remove", "Replace with \'?\'" })]
    580597        public int UnknownSymbolHandling
    581598        {
     
    585602                if ((UnknownSymbolHandlingMode)value != unknownSymbolHandling) HasChanges = true;
    586603                this.unknownSymbolHandling = (UnknownSymbolHandlingMode)value;
    587                 OnPropertyChanged(''UnknownSymbolHandling'');
     604                OnPropertyChanged("UnknownSymbolHandling");
    588605
    589606                if (ReExecute != null) ReExecute();
     
    591608        }
    592609
    593         [SettingsFormat(0, ''Normal'', ''Normal'', ''Black'', ''White'', Orientation.Vertical)]
     610        [SettingsFormat(0, "Normal", "Normal", "Black", "White", Orientation.Vertical)]
    594611        [PropertySaveOrder(9)]
    595         [TaskPane(''Alphabet'', ''This is the used alphabet.'', null, 6, true, DisplayLevel.Expert, ControlType.TextBox, '''')]
     612        [TaskPane("Alphabet", "This is the alphabet currently in use.", null, 6, true, DisplayLevel.Expert, ControlType.TextBox, "")]
    596613        public string AlphabetSymbols
    597614        {
     
    602619            if (a.Length == 0) // cannot accept empty alphabets
    603620            {
    604               LogMessage(''Ignoring empty alphabet from user! Using previous alphabet: \'''' + alphabet + ''\'' ('' + alphabet.Length.ToString() + '' Symbols)'', NotificationLevel.Info);
     621              LogMessage("Ignoring empty alphabet from user! Using previous alphabet instead: \" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
    605622            }
    606623            else if (!alphabet.Equals(a))
     
    608625              HasChanges = true;
    609626              this.alphabet = a;
    610               setKeyByValue(shiftValue); //re-evaluate if the shiftvalue is still within the range
    611               LogMessage(''Accepted new alphabet from user: \'''' + alphabet + ''\'' ('' + alphabet.Length.ToString() + '' Symbols)'', NotificationLevel.Info);
    612               OnPropertyChanged(''AlphabetSymbols'');
     627              setKeyByValue(shiftValue); // reevaluate if the shiftvalue is still within the range
     628              LogMessage("Accepted new alphabet from user: \" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
     629              OnPropertyChanged("AlphabetSymbols");
    613630
    614631              if (ReExecute != null) ReExecute();
     
    618635
    619636        /// <summary>
    620         /// Visible setting how to deal with alphabet case. 0 = case insentive, 1 = case sensitive
     637        /// Visible setting how to deal with alphabet case.
     638        /// 0 = case-insentive, 1 = case-sensitive
    621639        /// </summary>
    622         //[SettingsFormat(1, ''Normal'')]
     640        //[SettingsFormat(1, "Normal")]
    623641        [PropertySaveOrder(8)]
    624         [ContextMenu(''Alphabet case sensitivity'', ''Should upper and lower case be treated differently? (Should a == A)'', 7, DisplayLevel.Expert, ContextMenuControlType.ComboBox, null, new string[] { ''Case insensitive'', ''Case sensitive'' })]
    625         [TaskPane(''Alphabet case sensitivity'', ''Should upper and lower case be treated differently? (Should a == A)'', null, 7, true, DisplayLevel.Expert, ControlType.ComboBox, new string[] { ''Case insensitive'', ''Case sensitive'' })]
     642        [ContextMenu("Alphabet case sensitivity", "Should upper and lower case be treated as the same (so that 'a' = 'A')?", 7, DisplayLevel.Expert, ContextMenuControlType.ComboBox, null, new string[] { "Case insensitive", "Case sensitive" })]
     643        [TaskPane("Alphabet case sensitivity", "Should upper and lower case be treated as the same (so that 'a' = 'A')?", null, 7, true, DisplayLevel.Expert, ControlType.ComboBox, new string[] { "Case insensitive", "Case sensitive" })]
    626644        public int AlphabetCase
    627645        {
     
    636654                    {
    637655                        alphabet = upperAlphabet;
    638                         LogMessage(''Changing alphabet to: \'''' + alphabet + ''\'' ('' + alphabet.Length.ToString() + '' Symbols)'', NotificationLevel.Info);
    639                         OnPropertyChanged(''AlphabetSymbols'');
    640                         // re-set also the key (shiftvalue/shiftChar to be in the range of the new alphabet
     656                        LogMessage("Changing alphabet to: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
     657                        OnPropertyChanged("AlphabetSymbols");
     658                        // reset the key (shiftvalue/shiftChar)
     659                        // to be in the range of the new alphabet.
    641660                        setKeyByValue(shiftValue);
    642661                    }
     
    647666                    {
    648667                        alphabet = upperAlphabet + lowerAlphabet;
    649                         LogMessage(''Changing alphabet to: \'''' + alphabet + ''\'' ('' + alphabet.Length.ToString() + '' Symbols)'', NotificationLevel.Info);
    650                         OnPropertyChanged(''AlphabetSymbols'');
     668                        LogMessage("Changing alphabet to: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
     669                        OnPropertyChanged("AlphabetSymbols");
    651670                    }
    652671                }
    653672
    654                 // remove equal characters from the current alphabet
     673                // Remove equal characters from the current alphabet.
    655674                string a = alphabet;
    656675                alphabet = removeEqualChars(alphabet);
    657 
    658676                if (a != alphabet)
    659677                {
    660                     OnPropertyChanged(''AlphabetSymbols'');
    661                     LogMessage(''Changing alphabet to: \'''' + alphabet + ''\'' ('' + alphabet.Length.ToString() + '' Symbols)'', NotificationLevel.Info);
     678                    OnPropertyChanged("AlphabetSymbols");
     679                    LogMessage("Changing alphabet to: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
    662680                }
    663 
    664                 OnPropertyChanged(''AlphabetCase'');
     681                OnPropertyChanged("AlphabetCase");
    665682                if (ReExecute != null) ReExecute();
    666683            }
     
    683700        #endregion
    684701
    685         #region TaskPaneAttributeChanged-Sample
     702        #region TaskPaneAttributeChanged (Sample)
    686703        /// <summary>
    687         /// This event is just used here for sample reasons
     704        /// This event is here merely as a sample.
    688705        /// </summary>
    689706        public event TaskPaneAttributeChangedHandler TaskPaneAttributeChanged;
    690707
    691         [TaskPane(''Enable/Disable sensitivity'', ''This setting is just a sample and shows how to enable / disable a setting.'', ''AttributeChangedSample'', 8, false, DisplayLevel.Beginner, ControlType.Button)]
     708        [TaskPane("Enable/Disable sensitivity", "This setting is just a sample and shows how to enable / disable a setting.", "AttributeChangedSample", 8, false, DisplayLevel.Beginner, ControlType.Button)]
    692709        public void EnableDisableSesitivity()
    693710        {
     
    697714            if (sensitivityEnabled)
    698715            {
    699               TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer(''AlphabetCase'', Visibility.Visible)));
     716              TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("AlphabetCase", Visibility.Visible)));
    700717            }
    701718            else
    702719            {
    703               TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer(''AlphabetCase'', Visibility.Collapsed)));
     720              TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("AlphabetCase", Visibility.Collapsed)));
    704721            }
    705722          }
    706723        }
    707         #endregion TaskPaneAttributeChanged-Sample
     724        #endregion TaskPaneAttributeChanged (Sample)
    708725    }
    709726}
    710727\end{lstlisting}
    711 \section{Select and add an image as icon for the class Caesar}\label{sec:SelectAndAddAnImageAsIconForTheClassCaesar}
    712 Before we go back to the code of the Caesar class, we have to add an icon image to our project, which will be shown in the CrypTool \textbf{ribbon bar} or/and \textbf{navigation pane}. As there is no default, using an icon image is mandatory.\\\\
    713 \textit{\small Note: This will be changed in future. A default icon will be used if no icon image has been provided.}\\\\
    714 For testing purposes you may create a simple black and white PNG image with MS Paint or Paint.NET. As image size you can use 40x40 pixels for example, but as the image will be scaled when required, any size should do it. Place the image file in your project directory or in a subdirectory.\clearpage
    715 Then make a right click on the project item "Caesar" or any subdirectory within the Solution Explorer, and select ''Add-$>$Existing Item...'':
     728\clearpage
     729
     730\section{Adding an icon to the Caesar class}
     731\label{sec:AddingAnIconToTheCaesarClass}
     732
     733Before we go back to the code of the Caesar class, we have to add an icon to our project, which will be shown in the CrypTool \textbf{ribbon bar} and \textbf{navigation pane}. As there is currently no default, it is mandatory to add an icon. (It is planned to include a default icon in future versions.)
     734
     735For testing purposes you can just create a simple black and white PNG image with MS Paint or Paint.NET. The proper image size is 40x40 pixels, but since the image will be rescaled if necessary, any size is technically acceptable.
     736
     737Once you have saved your icon, you should add it directly to the project or to a subdirectory. In the project solution, we created a new folder named ``Images". This can be done by right-clicking on the project item (``Caesar" in our example) and selecting ``Add $\rightarrow$ New Folder". The icon can be added to this folder (or to the project directly, or to any other subdirectory) by right-clicking on the folder and selecting ``Add $\rightarrow$ Existing Item".
    716738
    717739\begin{figure}[h!]
    718740        \centering
    719741                \includegraphics{figures/add_existing_item.jpg}
    720         \caption{Add existing item}
     742        \caption{Adding an existing item.}
    721743        \label{fig:add_existing_item}
    722744\end{figure}
    723 
    724 As you can see, in our solution we create an new folder named ''Images'' (make a right click on the project item ''Caesar'' and select ''Add-$>$New Folder'') and placed there the new icon by clicking right on the folder as mentioned aboved.\clearpage
    725 Then select ''Image Files'' as file type, and choose the icon for your plugin:
     745\clearpage
     746
     747A new window will then appear. Select ``Image Files" as the file type and select your newly-created icon for your plugin.
     748
    726749\begin{figure}[h!]
    727750        \centering
    728751                \includegraphics{figures/choose_icon.jpg}
    729         \caption{Choose the right icon}
     752        \caption{Selecting the image file.}
    730753        \label{fig:choose_icon}
    731754\end{figure}
    732 Finally we have to set the icon as a ''Resource'' to avoid providing the icon as a separate file. Make a right click on the icon and select the item ''Properties'':\clearpage
     755\clearpage
     756
     757Finally, we must set the icon as a ``Resource" to avoid including the icon as a separate file. Right-click on the icon and select ``Properties" as seen below.
     758
    733759\begin{figure}[h!]
    734760        \centering
    735761                \includegraphics{figures/icon_properties.jpg}
    736         \caption{Icon properties}
     762        \caption{Selecting the image properties.}
    737763        \label{fig:icon_properties}
    738764\end{figure}
    739 In the ''Properties'' panel you have to set the ''Build Action'' to ''Resource'' (not embedded resource):
     765
     766In the ``Properties" panel, set the ``Build Action" to ``Resource".
     767
    740768\begin{figure}[h!]
    741769        \centering
    742770                \includegraphics{figures/icon_build_action.jpg}
    743         \caption{Icon  build action}
     771        \caption{Selecting the icon's build action.}
    744772        \label{fig:icon_build_action}
    745773\end{figure}
    746 \section{Set the attributes for the class Caesar}\label{sec:SetTheAttributesForTheClassCaesar}
    747 Now let's go back to the code of the Caesar class (''Caesar.cs'' file). First we have to set the necessary attributes for our class. This attributes are used to provide additional information for the CrypTool 2.0 environment. If not set, your plugin won't show up in the GUI, even if everything else is implemented correctly.
    748 
    749 Attributes are used for \textbf{declarative} programming and provide meta data, that can be attached to the existing .NET meta data , like classes and properties. CrypTool provides a set of custom attributes, that are used to mark the different parts of your plugin.
    750 
    751 
    752 \textit{[Author]}\\
    753 The first attribute called ''Author'' is optional, which means we are not forced to define this attribute. It provides the additional information about the plugin developer. This informations you can see for example in the TaskPane as shown on a screenshot above. We set this attribute to demonstrate how it has to look in case you want to provide this attribute.
    754 \begin{figure}[h!]
    755         \centering
    756                 \includegraphics[width=1.00\textwidth]{figures/attribute_author.jpg}
    757         \caption{Attribute author}
     774\clearpage
     775
     776\section{Defining the attributes of the Caesar class}
     777\label{sec:DefiningTheAttributesOfTheCaesarClass}
     778
     779Now let's go back to the code of the Caesar class (the ``Caesar.cs" file in our example). The first thing we will do is define the attributes of our class. These attributes are used to provide additional information for the CrypTool 2.0 environment. If they are not properly defined, your plugin won't show up in the application display, even if everything else is implemented correctly.
     780
     781Attributes are used for \textbf{declarative} programming and provide metadata that can be added to the existing .NET metadata. CrypTool provides a set of custom attributes that are used to mark the different parts of your plugin.
     782
     783These attributes can be defined anywhere within the ``Cryptool.Caesar" namespace, but customarily they are defined right before the class declaration.
     784
     785\subsubsection*{The \textit{[Author]} attribute}
     786\label{sec:TheAuthorAttribute}
     787
     788The \textit{[Author]} attribute is optional, and thus we are not required to define it. The attribute can be used to provide additional information about the plugin developer. This information will appear in the TaskPane, as for example in Figure \ref{fig:task_pane}. We will define the attribute to demonstrate how it should look in case you want to use it in your plugin.
     789
     790\begin{figure}[h!]
     791        \centering
     792                \includegraphics[width=.90\textwidth]{figures/attribute_author_new.jpg}
     793        \caption{The defintion for the \textit{[Author]} attribute.}
    758794        \label{fig:attribute_author}
    759795\end{figure}
    760796
    761 As we can see above the author attribute takes four elements of type string. These elements are:
     797As can be see above, the author attribute takes four elements of type string. These elements are:
     798
    762799\begin{itemize}
    763         \item Author = name of the plugin developer
    764         \item Email = email of the plugin developer if he wants to be contact
    765         \item Institute = current employment of the developer like University or Company
    766         \item Url = the website or homepage of the developer
     800        \item Author --- the name of the plugin developer(s).
     801        \item Email --- the email address of the plugin developer(s), should they wish to be available for contact.
     802        \item Institute --- the organization, company or university with which the developer(s) are affiliated.
     803        \item URL --- the website of the developer(s) or their institution.
    767804\end{itemize}
    768 All this elements are also optional. The developer decides what he wants to publish. Unused elements shall be set to null or a zero-length string ('''').
    769 
    770 Our author attribute should look now as you can see below:
    771 \begin{figure}[h!]
    772         \centering
    773                 \includegraphics[width=1.00\textwidth]{figures/attribute_author_filled.jpg}
    774         \caption{Filled author auttribute}
    775         \label{fig:attribute_author_filled}
    776 \end{figure}
    777 
    778 
    779 \textit{[PluginInfo]}\\
    780 The second attribute called ''PluginInfo'' provides the necessary information about the plugin like caption and tool tip. This attribute is mandatory. The attribute has the definition as you can see below:
     805
     806All of these elements are optional; the developer(s) can choose what information will be published. Unused elements should be set to null or an empty string.
     807\clearpage
     808
     809%Our author attribute should look now as you can see below:
     810%\begin{figure}[h!]
     811%       \centering
     812%               \includegraphics[width=1.00\textwidth]{figures/attribute_author_filled.jpg}
     813%       \caption{Filled author auttribute}
     814%       \label{fig:attribute_author_filled}
     815%\end{figure}
     816
     817\subsubsection*{The \textit{[PluginInfo]} attribute}
     818\label{sec:ThePluginInfoAttribute}
     819
     820The second attribute, \textit{[PluginInfo]}, provides necessary information about the plugin, and is therefore mandatory. This information appears in the caption and tool tip window. The attribute is defined as follows:
     821
    781822\begin{figure}[h]
    782823        \centering
    783                 \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo.jpg}
    784         \caption{Attribute PluginInfo}
     824                \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_new.jpg}
     825        \caption{The defintion for the \textit{[PluginInfo]} attribute.}
    785826        \label{fig:attribute_plugininfo}
    786827\end{figure}
    787828
    788 This attribute expects the following elements:
     829This attribute has the following parameters:
     830
    789831\begin{itemize}
    790         \item resourceFile = Defines if resource files will be provided and where to find them. E.g. to provide the plugin multilingual you can store the labels in such a resource file. This element is optional.
    791         \item startable = Set this flag to true only if your plugin is some kind of input or generator plugin (probably if your plugin just has outputs and no inputs). In all other cases use false here. This flag is important. Setting this flag to true for a non input/generator plugin will result in unpredictable chain runs. This element is mandatory.
    792         \item caption = from type string, the name of the plugin or the resource field name if you provide the caption in a resource file (e.g. to provide the button content). This element is mandatory.
    793         \item toolTip = from type string, description of the plugin or the resource field name if you provide the toolTip in a resource file (e.g. to provide the button tool tip). This element is optional.
    794         \item descriptionUrl = from type string, define where to find the whole description files (e.g. XAML files). This element is optional.
    795         \item icons = from type string array, which provides all necessary icon paths you want to use in the plugin (e.g. the plugin icon as seen above). This element is mandatory.
     832        \item Resource File --- defines where to find the associated resource file, if one is to be implemented. These are used, for example, to provide multilingual support for the plugin. This element is optional.
     833        \item Startable --- a flag that should be set to true only if the plugin is an input generator plugin (i.e. if your plugin only has outputs and no inputs). In all other cases this should be set to false. This flag is important --- setting it incorrectly will result in unpredictable results. This element is mandatory.
     834        \item Caption --- the name of the plugin or, if the caption is specified in a resource file, the name of the appropriate field in the resource file. This element is mandatory.
     835        \item ToolTip --- a description of the plugin or, if the tool tip is specified in a resource file, the name of the appropriate field in the resource file. This element is optional.
     836        \item DescriptionURL --- defines where to find the description file (e.g. XAML file). This element is optional.
     837        \item Icons --- an array of strings to define all the paths for the icons to be used in the plugin (i.e. the plugin icon described in section \ref{sec:AddingAnIconToTheCaesarClass}). This element is mandatory.
    796838\end{itemize}
    797 Unused optional elements shall be set to null or a zero-length string ('''').
    798 
    799 
    800 \textit{\small Note 1: It is possible to use the plugin without setting a caption though it is not recommended. This will be changed in future and the plugin will fail to load without a caption.\\\\
    801 \small Note 2: Currently a zero-length toolTip string appears as empty box. This will be changed in future.\\\\
    802 \small Note 3: Tooltip and description currently do not support internationalization and localization. This will be changed in future.\\\\}
     839
     840Unused elements should be set to null or an empty string.
     841
     842(There are a few limitations and bugs that still exist in the \textit{[PluginInfo]} attribute that will be resolved in a future version. Firstly, it is possible to use the plugin without setting a caption, although this is not recommended. In the future the plugin will fail to load without a caption. Secondly, a zero-length toolTip string currently causes the toolTip to appear as an empty box in the application. Lastly, the toolTip and description do not currently support internationalization and localization.)
     843
    803844In our example the first parameter called ''resourceFile'' has to be set to ''Cryptool.Caesar.Resource.res'' because we want to provide the plugin multilingual and want to store the labels and caption in a resource file. Otherwise ignore this element.
    804845\begin{figure}[h]
Note: See TracChangeset for help on using the changeset viewer.