Changeset 1626


Ignore:
Timestamp:
Jun 12, 2010, 2:01:27 AM (12 years ago)
Author:
Matthäus Wander
Message:

HowTo:

  • reworked part 2
  • removed no longer needed stuff (the plugin template saves a lot of manual work)
  • moved very long settings example to appendix
Location:
trunk/Documentation/Developer/PluginHowTo
Files:
5 added
18 deleted
4 edited

Legend:

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

    r1624 r1626  
    1 \documentclass[11pt, a4paper, titlepage]{scrreprt}
     1\documentclass[11pt, a4paper, titlepage, appendixprefix]{scrreprt}
    22
    33\usepackage[latin1]{inputenc}
     
    2020
    2121%\usepackage[automark]{scrpage2}
    22 %\usepackage[absolute]{textpos}
     22%\usepackage[absolute]{textpos}
    2323
    2424
     
    194194        \include{part1}
    195195        \include{part2}
     196       
     197        \begin{appendix}
     198        \include{appendix}
     199        \end{appendix}
    196200
    197201\end{document}
  • trunk/Documentation/Developer/PluginHowTo/part1.tex

    r1625 r1626  
    182182\label{DownloadingThePluginTemplate}
    183183
    184 Before you can start implementing a new plugin, you will have to download the CrypTool~2 plugin template. The template is located at the CrypTool 2 website at \url{http://www.cryptool2.vs.uni-due.de/index.php?page=33&lm=3}. Save the template zip file in your documents folder in the subdirectory \texttt{Visual Studio 2010\textbackslash{}Templates\textbackslash{}Project Templates\textbackslash{}} (applies to both, Visual Studio and Visual C\# Express). Do not unpack the zip file.
     184Before you can start implementing a new plugin, you will have to download the CrypTool~2 plugin template. The template is located at the CrypTool 2 website at \url{http://www.cryptool2.vs.uni-due.de/index.php?page=33&lm=3}. Save the template zip file in your documents folder in the subdirectory \texttt{Visual Studio 2010\textbackslash{}Templates\textbackslash{}ProjectTemplates\textbackslash{}} (applies to both, Visual Studio and Visual C\# Express). Do not unpack the zip file.
     185
     186\begin{figure}[htbp]
     187        \centering
     188                \includegraphics{figures/vs_template.png}
     189        \caption{Saving plugin template.}
     190        \label{fig:vs_template}
     191\end{figure}
     192\clearpage
  • trunk/Documentation/Developer/PluginHowTo/part2.tex

    r1625 r1626  
    1414\label{sec:CreatingANewProject}
    1515
    16 %To begin, open Visual Studio, go to the menu bar and select \textit{File~$\rightarrow$ New $\rightarrow$ Project\ldots }. The following window will appear:
    17 
    18 XXX: update screenshot
    19 
    20 XXX: right click in solution explorer on CrypPlugins (Express: on solution), select Add, New Project
    21 
    22 XXX: select CrypTool 2 Plugin as project type
    23 
    24 XXX: enter some plugin name
    25 
    26 XXX: enter CrypPlugins as location (!!!)
    27 
    28 \begin{figure}[h!]
    29         \centering
    30                 \includegraphics[width=1.00\textwidth]{figures/vs_create_new_project.jpg}
    31         \caption{Creating a new Visual Studio project.}
     16Open the CrypTool 2 solution, right click in the solution explorer on \textit{CrypPlugins} (or on the top solution item, if you're using Visual C\# Express) and select \textit{Add~$\rightarrow$ New Project}. In the dialog opening up, select \textit{Visual C\# $\rightarrow$ CrypTool 2.0 Plugin} as project template and enter a unique name for your new plugin project (such as \textit{Caesar} in our case). The \textbf{next step is crucial} to ensure that your plugin will compile and run correctly: select the subdirectory \texttt{CrypPlugins\textbackslash} as location for your project (Figure~\ref{fig:vs_create_new_project}).
     17
     18\begin{figure}
     19        \centering
     20                \includegraphics{figures/vs_create_new_project.png}
     21        \caption{Creating a new CrypTool 2 plugin project.}
    3222        \label{fig:vs_create_new_project}
    3323\end{figure}
    34 \clearpage
    35 
    36 %Select \textbf{\textit{.NET-Framework 3.5}} as the target framework. Then choose \textit{Class Library} as the default template, as this will build the project for your plugin as a DLL file. Give the project a unique and meaningful name (such as \textit{Caesar} in our case), and choose a location to save it to. Select the subdirectory \textit{CrypPlugins} from your SVN trunk as the location. Finally, confirm by pressing the \textit{OK} button. Note that creating a new project in this manner also creates a new solution into which the project is placed. At this point, your Visual Studio solution should look like this:
    37 
    38 \begin{figure}[h!]
    39         \centering
    40                 \includegraphics[width=1.00\textwidth]{figures/solution_start_up.jpg}
    41         \caption{A newly created solution and project.}
    42         \label{fig:solution_start_up}
    43 \end{figure}
    44 \clearpage
    45 
    46 XXX: rename files in solution explorer to something meaningful (ExamplePluginCT2.cs, ExamplePluginCT2Settings.cs)
    47 
    48 XXX: rename class ExamplePluginCT2Settings to something meaningful (right-click, refactor/rename).
    49 
    50 %In our case, this class has to inherit from \textit{IEncryption} because it will be an encryption plugin. If it was instead a hash plugin, this class should inherit from \textit{IHash}. The second class will be used to store setting information for the plugin, and thus we will name ours \textit{CaesarSettings}. It will need to inherit from \textit{ISettings}.
    51 
    52 %When starting a new project, Visual Studio automatically creates a class named \textit{Class1.cs}. Since this is a rather non-descriptive name, we will change it. In our example, it will be \textit{Caesar.cs}.
    53 
    54 %Then right-click on the project item (in our case, \textit{Caesar}) and select \textit{Add $\rightarrow$ Class\ldots }:
    55 
    56 %The settings class will store the necessary information about controls, captions, descriptions and default parameters (e.g.\ for key settings, alphabets, key length and type of action) to build the \textbf{TaskPane} in the CrypTool application.
    57 \clearpage
    58 
    59 \noindent Below is an example of what a completed TaskPane for the existing Caesar plugin in CrypTool 2 looks like:
    60 
    61 \begin{figure}[h!]
    62         \centering
    63                 \includegraphics{figures/task_pane.jpg}
    64         \caption{The completed TaskPane for the existing Caesar plugin.}
    65         \label{fig:task_pane}
    66 \end{figure}
    67 \clearpage
    68 
    69 \subsection{Adding the namespaces and inheritance sources for the Caesar class}
    70 \label{sec:AddingTheNamespacesAndInheritanceSourcesForTheCaesarClass}
    71 
    72 XXX: your plugin main class should inherit from some interface from the following CrypPluginBase interfaces
    73 
    74 XXX: CT2 determines by your chosen interface in which algorithm category your plugin will be shown (encryption, hash, analysis etc.)
    75 
    76 Open the \textit{Caesar.cs} file by double clicking on it in the Solution Explorer. To include the necessary namespaces in the class header, use the \texttt{using} statement followed by the name of the desired namespace. The CrypTool 2 API provides the following namespaces:
     24
     25As the project basics are already set up in the template correctly, you should now be able to compile the new plugin. First of all, rename the two files in the solution explorer to some more meaningful filenames, for example \texttt{Caesar.cs} and \texttt{CaesarSettings.cs}.
     26
     27\begin{figure}
     28        \centering
     29                \includegraphics{figures/caesar_project.png}
     30        \caption{Items of a new plugin project.}
     31        \label{fig:caesar_project}
     32\end{figure}
     33
     34\section{Adapting the plugin skeleton}
     35\label{AdaptingThePluginSkeleton}
     36
     37If you look into the two C\# source files (Figure~\ref{fig:caesar_project}), you will notice a lot of comments marked with the keyword \texttt{HOWTO}. These are hints, what you should change in order to adapt the plugin skeleton to your custom implementation. Most \texttt{HOWTO} hints are self-explanatory and we won't discuss all of them in detail. For example, at the top of both source files, there is a hint to enter your name and affiliation in the license boilerplate:
     38
     39\begin{lstlisting}
     40/* HOWTO: Change year, author name and organization.
     41   Copyright 2010 Your Name, University of Duckburg
     42
     43\end{lstlisting}
     44
     45After you have done this, remove the \texttt{HOWTO} hint:
     46
     47\begin{lstlisting}
     48/*
     49   Copyright 2010 John Doe, University of Duisburg-Essen
     50
     51\end{lstlisting}
     52
     53\section{Defining the attributes of the Caesar class}
     54\label{sec:DefiningTheAttributesOfTheCaesarClass}
     55
     56The next thing we will do in our example \textit{Caesar.cs} is define the attributes of our class. These attributes are used to provide necessary information for the CrypTool 2 environment. If they are not properly defined, your plugin won't show up in the application user interface, even if everything else is implemented correctly.
     57
     58Attributes are used for declarative programming and provide metadata that can be added to the existing .NET metadata. CrypTool 2 provides a set of custom attributes that are used to mark the different parts of your plugin. These attributes should be defined right before the class declaration.
     59
     60\subsection{The \protect\textit{[Author]} attribute}
     61\label{sec:TheAuthorAttribute}
     62
     63The \textit{[Author]} attribute is optional, meaning that we are not required to define it. The attribute can be used to provide additional information about the plugin developer (or developers, as the case may be). This information will appear in the TaskPane, as for example in Appendix \ref{app:CaesarSettings}. We will define the attribute to demonstrate how it should look in case you want to use it in your plugin.
     64
     65\begin{figure}[h!]
     66        \centering
     67                \includegraphics[width=.90\textwidth]{figures/attribute_author.jpg}
     68        \caption{The defintion for the \textit{[Author]} attribute.}
     69        \label{fig:attribute_author}
     70\end{figure}
     71
     72As can be seen above, the author attribute takes four elements of type string. These elements are:
     73
     74\begin{itemize}
     75        \item \textit{Author} --- the name of the plugin developer.
     76        \item \textit{Email} --- the email address of the plugin developer, should he or she wish to be available for contact.
     77        \item \textit{Institute} --- the organization, company or university with which the developer is affiliated.
     78        \item \textit{URL} --- the website of the developer or of his or her institution.
     79\end{itemize}
     80
     81All of these elements are optional; the developer can choose what information will be published. Unused elements should be set to \texttt{null} or an empty string.
     82
     83\subsection{The \protect\textit{[PluginInfo]} attribute}
     84\label{sec:ThePluginInfoAttribute}
     85
     86The second attribute, \textit{[PluginInfo]}, provides necessary information about the plugin, and is therefore mandatory. The information defined in this attribute appears in the caption and tool tip window. The attribute is defined as follows:
     87
     88\begin{figure}[h]
     89        \centering
     90                \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo.jpg}
     91        \caption{The defintion for the \textit{[PluginInfo]} attribute.}
     92        \label{fig:attribute_plugininfo}
     93\end{figure}
     94
     95\noindent This attribute has the following parameters:
     96
     97\begin{itemize}
     98        \item \textit{Resource File} --- the relative path of the associated resource file (if the plugin makes use of one). These files are used primarily to provide multilingual support for the plugin, although this is currently a work in progress. This element is optional.
     99        \item \textit{Startable} --- a flag that should be set to \texttt{true} only if the plugin is an input generator (i.e.\ if your plugin only has outputs and no inputs). In all other cases this should be set to \texttt{false}. This flag is important --- setting it incorrectly will result in unpredictable results. This element is mandatory.
     100        \item \textit{Caption} --- the name of the plugin, or, if using a resource file, the name of the field in the file with the caption data. This element is mandatory.
     101        \item \textit{ToolTip} --- a description of the plugin, or, if using a resource file, the name of the field in the resource file with the toolTip data. This element is optional.
     102        \item \textit{DescriptionURL} --- the local path of the description file (e.g.\ XAML file). This element is optional.
     103        \item \textit{Icons} --- an array of strings to define all the paths of the icons used in the plugin (i.e.\ the plugin icon described in Section \ref{sec:AddingAnIconToTheCaesarClass}). This element is mandatory.
     104\end{itemize}
     105
     106\noindent Unused elements should be set to \texttt{null} or an empty string.
     107
     108There are a few limitations and bugs that still exist in the \textit{[PluginInfo]} attribute that will be resolved in a future version. First, it is possible to use the plugin without setting a caption, although this is not recommended, and future versions of the plugin will fail to load without a caption. Second, a zero-length toolTip string currently causes the toolTip to appear as an empty box in the application. Third, the toolTip and description do not currently support internationalization and localization. Since the precise formulation and functionality of this attribute is still being developed, it is recommended to view other plugins for examples.
     109
     110In our example, the \textit{resourceFile} parameter is set to \textit{Cryptool.Caesar.Resource.res}. This file will be used to store the label and caption text to support multilingualism.
     111
     112The second parameter, \textit{startable}, should be set to \texttt{false}, because our encryption algorithm is not an input generator.
     113
     114The next two parameters are necessary to define the plugin's name and description. Since we are using a resource file, we should place here the names of the resource fields that contain the caption and toolTip. (We could also just write simple text strings instead of using outsourced references.)
     115
     116The \textit{DescriptionURL} element defines the location path of the description file. The parameter is composed in the format \textit{$<$assembly name$>$/$<$file name$>$} or, if you want to store your description files in a separate folder (as in our case), \textit{$<$assembly name$>$/$<$path$>$/$<$file name$>$}. The description file must be an XAML file. In our case, we shall create a folder named \textit{DetailedDescription} in which to store our XAML file with any necessary images. Our folder structure now looks as follows:
     117
     118\begin{figure}[h!]
     119        \centering
     120                \includegraphics[width=.30\textwidth]{figures/detailed_description.jpg}
     121        \caption{The folder structure as seen in the Solution Explorer.}
     122        \label{fig:attribute_plugininfo_icon_path}
     123\end{figure}
     124
     125Once a detailed description has been written in the XAML file, it can be accessed in the CrypTool~2 application by right-clicking on the plugin icon in the workspace and selecting \textit{Show description} (Figure~\ref{fig:xaml_description}).
     126
     127\begin{figure}
     128        \centering
     129                \includegraphics[width=1.00\textwidth]{figures/xaml_description.jpg}
     130        \caption{A detailed description provided through an XAML file.}
     131        \label{fig:xaml_description}
     132\end{figure}
     133
     134The last parameter tells CrypTool 2 the names of the provided icons. This parameter is an array composed of strings in the format \textit{$<$assembly name$>$/$<$file name$>$} or \textit{$<$assembly name$>$/$<$path$>$/\linebreak $<$file~name$>$}.
     135
     136The first and most important icon is the plugin icon, which will be shown in CrypTool 2 in the ribbon bar and navigation pane. Once the icon has been added to the project as described in Section~\ref{sec:AddingAnIconToTheCaesarClass}, we must accordingly tell CrypTool 2 where to find the icon. This can be seen above in Figure \ref{fig:attribute_plugininfo}.
     137
     138If your plugin will use additional icons, you should define the paths to each of them by adding the path strings to the \textit{[PluginInfo]} attribute parameter list, each separated by a comma. We have added two further icons for the context menu in the CrypTool 2 workspace. (If you choose to add more icons, don't forget to add the icons to your solution.)
     139
     140\subsection{Algorithm category and the \protect\textit{[EncryptionType]} attribute}
     141
     142In the CrypTool 2 user interface plugins are grouped by their algorithm category, for example hash algorithm, encryption algorithm and so on. To set the category, your plugin must inherit from a specific interface, like \textit{IHash} or \textit{IEncryption}. Some categories require the choice of a subcategory, which is entered as attribute\footnote{The current category system is unhandy and will be changed in future, see trac ticket \#50.}. In our example, Caesar inherits from \textit{IEncryption} and needs the attribute \textit{[EncryptionType]}.
     143
     144\begin{lstlisting}
     145    [EncryptionType(EncryptionType.Classic)]
     146    public class Caesar : IEncryption
     147                {
     148\end{lstlisting}
     149
     150The possible values of the \textit{[EncryptionType]} attribute are as follows:
     151
     152\begin{itemize}
     153        \item \textit{Asymmetric} --- for asymmetrical encryption algorithms, such as RSA.
     154        \item \textit{SymmetricBlock} --- for block cipher algorithms, such as DES, AES and Twofish.
     155        \item \textit{SymmetricStream} --- for stream cipher algorithms, such as RC4, Rabbit and SEAL.
     156        \item \textit{Hybrid} --- for algorithms which are actually a combination of several algorithms, such as algorithms in which the data is encrypted symmetrically and the encryption key asymmetrically.
     157        \item \textit{Classic} --- for classical encryption or hash algorithms, such as Caesar or MD5.
     158\end{itemize}
     159
     160\subsection{Importing CrypPluginBase namespaces}
     161\label{sec:ImportingCrypPluginBaseNamespaces}
     162
     163Depending on which algorithm category you choose, you will need to import the corresponding namespace of \textit{CrypPluginBase}. To include the necessary namespaces in the class header, use the \texttt{using} statement followed by the name of the desired namespace. \textit{CrypPluginBase} provides the following namespaces:
    77164
    78165\begin{itemize}
     
    86173        \item \textit{Cryptool.PluginBase.Miscellaneous} --- contains assorted helper classes, including \textit{GuiLogMessage} and \textit{PropertyChanged}.
    87174        \item \textit{Cryptool.PluginBase.Resources} --- used only by CrypWin and the editor; not necessary for plugin development.
    88         \item \textit{Cryptool.PluginBase.Tool} --- contains an interface for all external tools implemented by CrypTool~2 that do not entirely support the CrypTool 2 API.
     175        \item \textit{Cryptool.PluginBase.Tool} --- contains an interface for standalone tools in CrypTool~2 that are not run in a workspace editor.
    89176        \item \textit{Cryptool.PluginBase.Validation} --- contains interfaces for validation methods, including regular expressions.
    90177\end{itemize}
     
    99186\end{itemize}
    100187
    101 \clearpage
    102 
    103 \subsection{Adding controls to the CaesarSettings class}
    104 \label{sec:AddingControlsToTheCaesarSettingsClass}
    105 
    106 The settings class is used to populate the TaskPane in the CrypTool 2 application so that the user can modify the plugin settings at will. Thus we will need to implement some controls, such as buttons and text boxes, to allow for the necessary interaction. If you will be implementing an algorithm that does not have any user-defined settings (i.e.\ a hash function), then this class can be left mostly empty. 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 CrypTool 2 plugins for examples of how to create the TaskPane backend.\\
    107 
    108 \begin{lstlisting}
    109 using System;
    110 using System.ComponentModel;
    111 using System.Windows;
    112 using System.Windows.Controls;
    113 
    114 using Cryptool.PluginBase;
    115 
    116 namespace Cryptool.Caesar
    117 {
    118     public class CaesarSettings : ISettings
    119     {
    120         #region Public Caesar specific interface
    121 
    122         /// <summary>
    123         /// This delegate is ued to send log messages from
    124         /// the settings class to the Caesar plugin.
    125         /// </summary>
    126         public delegate void CaesarLogMessage(string msg, NotificationLevel loglevel);
    127 
    128         /// <summary>
    129         /// An enumeration for the different modes of handling
    130         /// unknown characters.
    131         /// </summary>
    132         public enum UnknownSymbolHandlingMode { Ignore = 0, Remove = 1, Replace = 2 };
    133 
    134         /// <summary>
    135         /// Fires when a new status message was sent.
    136         /// </summary>
    137         public event CaesarLogMessage LogMessage;
    138 
    139         public delegate void CaesarReExecute();
    140 
    141         public event CaesarReExecute ReExecute;
    142 
    143         /// <summary>
    144         /// Retrieves or sets the current shift value (i.e. the key).
    145         /// </summary>
    146         [PropertySaveOrder(0)]
    147         public int ShiftKey
    148         {
    149             get { return shiftValue; }
    150             set
    151             {
    152                 setKeyByValue(value);
    153             }
    154         }
    155 
    156         /// <summary>
    157         /// Retrieves the current setting of whether or not the
    158         /// alphabet should be treated as case-sensitive.
    159         /// </summary>
    160         [PropertySaveOrder(1)]
    161         public bool CaseSensitiveAlphabet
    162         {
    163             get
    164             {
    165                 if (caseSensitiveAlphabet == 0)
    166                 {   return false;   }
    167                 else
    168                 {   return true;    }
    169             }
    170             set {} // this setting is readonly, but we must include
    171                    // some form of set method to prevent problems.
    172         }
    173 
    174         /// <summary>
    175         /// Returns true if any settings have been changed.
    176         /// This value should be set externally to false, i.e.
    177         /// when a project is saved.
    178         /// </summary>
    179         [PropertySaveOrder(3)]
    180         public bool HasChanges
    181         {
    182             get { return hasChanges; }
    183             set { hasChanges = value; }
    184         }
    185 
    186         #endregion
    187 
    188         #region Private variables
    189         private bool hasChanges;
    190         private int selectedAction = 0;
    191         private string upperAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    192         private string lowerAlphabet = "abcdefghijklmnopqrstuvwxyz";
    193         private string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    194         private char shiftChar = 'C';
    195         private int shiftValue = 2;
    196         private UnknownSymbolHandlingMode unknownSymbolHandling = UnknownSymbolHandlingMode.Ignore;
    197         private int caseSensitiveAlphabet = 0; // 0 = case-insensitve, 1 = case-sensitive
    198         private bool sensitivityEnabled = true;
    199         #endregion
    200 
    201         #region Private methods
    202 
    203         private string removeEqualChars(string value)
    204         {
    205             int length = value.Length;
    206 
    207             for (int i = 0; i < length; i++)
    208             {
    209                 for (int j = i + 1; j < length; j++)
    210                 {
    211                     if ((value[i] == value[j]) || (!CaseSensitiveAlphabet & (char.ToUpper(value[i]) == char.ToUpper(value[j]))))
    212                     {
    213                         LogMessage("Removing duplicate letter: \'" + value[j] + "\' from alphabet!", NotificationLevel.Warning);
    214                         value = value.Remove(j,1);
    215                         j--;
    216                         length--;
    217                     }
    218                 }
    219             }
    220 
    221             return value;
    222         }
    223 
    224         /// <summary>
    225         /// Set the new shiftValue and the new shiftCharacter
    226         /// to offset % alphabet.Length.
    227         /// </summary>
    228         private void setKeyByValue(int offset)
    229         {
    230             HasChanges = true;
    231 
    232             // Make sure the shift value lies within the alphabet range.
    233             offset = offset % alphabet.Length;
    234 
    235             // Set the new shiftChar.
    236             shiftChar = alphabet[offset];
    237 
    238             // Set the new shiftValue.
    239             shiftValue = offset;
    240 
    241             // Announce this to the settings pane.
    242             OnPropertyChanged("ShiftValue");
    243             OnPropertyChanged("ShiftChar");
    244 
    245             // Print some info in the log.
    246             LogMessage("Accepted new shift value " + offset + "! (Adjusted shift character to \'" + shiftChar + "\')", NotificationLevel.Info);
    247         }
    248 
    249         private void setKeyByCharacter(string value)
    250         {
    251             try
    252             {
    253                 int offset;
    254                 if (this.CaseSensitiveAlphabet)
    255                 {
    256                     offset = alphabet.IndexOf(value[0]);
    257                 }
    258                 else
    259                 {
    260                     offset = alphabet.ToUpper().IndexOf(char.ToUpper(value[0]));
    261                 }
    262 
    263                 if (offset >= 0)
    264                 {
    265                     HasChanges = true;
    266                     shiftValue = offset;
    267                     shiftChar = alphabet[shiftValue];
    268                     LogMessage("Accepted new shift character \'" + shiftChar + "\'! (Adjusted shift value to " + shiftValue + ")", NotificationLevel.Info);
    269                     OnPropertyChanged("ShiftValue");
    270                     OnPropertyChanged("ShiftChar");
    271                 }
    272                 else
    273                 {
    274                     LogMessage("Bad input \"" + value + "\"! (Character not in alphabet!) Reverting to " + shiftChar.ToString() + "!", NotificationLevel.Error);
    275                 }
    276             }
    277             catch (Exception e)
    278             {
    279                 LogMessage("Bad input \"" + value + "\"! (" + e.Message + ") Reverting to " + shiftChar.ToString() + "!", NotificationLevel.Error);
    280             }
    281         }
    282 
    283         #endregion
    284 
    285         #region Algorithm settings properties (visible in the Settings pane)
    286 
    287         [PropertySaveOrder(4)]
    288         [ContextMenu("Action", "Select the algorithm action", 1, DisplayLevel.Beginner, ContextMenuControlType.ComboBox, new int[] { 1, 2 }, "Encrypt", "Decrypt")]
    289         [TaskPane("Action", "setAlgorithmActionDescription", null, 1, true, DisplayLevel.Beginner, ControlType.ComboBox, new string[] { "Encrypt", "Decrypt" })]
    290         public int Action
    291         {
    292             get
    293             {
    294                 return this.selectedAction;
    295             }
    296             set
    297             {
    298                 if(value != selectedAction)
    299                 {
    300                         HasChanges = true;
    301                         this.selectedAction = value;
    302                     OnPropertyChanged("Action");
    303                 }
    304                 if(ReExecute != null)
    305                 {       ReExecute();    }
    306             }
    307         }
    308 
    309         [PropertySaveOrder(5)]
    310         [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)]
    311         public int ShiftValue
    312         {
    313             get { return shiftValue; }
    314             set
    315             {
    316                 setKeyByValue(value);
    317                 if (ReExecute != null)
    318                 {       ReExecute();    }
    319             }
    320         }
    321 
    322         [PropertySaveOrder(6)]
    323         [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}")]
    324         public string ShiftChar
    325         {
    326             get { return this.shiftChar.ToString(); }
    327             set
    328             {
    329                 setKeyByCharacter(value);
    330                 if (ReExecute != null)
    331                         {   ReExecute();    }
    332             }
    333         }
    334 
    335         [PropertySaveOrder(7)]
    336         [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 \'?\'" })]
    337         [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 \'?\'" })]
    338         public int UnknownSymbolHandling
    339         {
    340             get { return (int)this.unknownSymbolHandling; }
    341             set
    342             {
    343                 if((UnknownSymbolHandlingMode)value != unknownSymbolHandling)
    344                 {
    345                         HasChanges = true;
    346                         this.unknownSymbolHandling = (UnknownSymbolHandlingMode)value;
    347                     OnPropertyChanged("UnknownSymbolHandling");
    348                                 }
    349                 if (ReExecute != null)
    350                 {       ReExecute();    }
    351             }
    352         }
    353 
    354         [SettingsFormat(0, "Normal", "Normal", "Black", "White", Orientation.Vertical)]
    355         [PropertySaveOrder(9)]
    356         [TaskPane("Alphabet", "This is the alphabet currently in use.", null, 6, true, DisplayLevel.Expert, ControlType.TextBox, "")]
    357         public string AlphabetSymbols
    358         {
    359           get { return this.alphabet; }
    360           set
    361           {
    362             string a = removeEqualChars(value);
    363             if (a.Length == 0) // cannot accept empty alphabets
    364             {
    365               LogMessage("Ignoring empty alphabet from user! Using previous alphabet instead: \" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
    366             }
    367             else if (!alphabet.Equals(a))
    368             {
    369               HasChanges = true;
    370               this.alphabet = a;
    371               setKeyByValue(shiftValue); // reevaluate if the shiftvalue is still within the range
    372               LogMessage("Accepted new alphabet from user: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
    373               OnPropertyChanged("AlphabetSymbols");
    374 
    375               if (ReExecute != null)
    376               { ReExecute();    }
    377             }
    378           }
    379         }
    380 
    381         /// <summary>
    382         /// Visible setting how to deal with alphabet case.
    383         /// 0 = case-insentive, 1 = case-sensitive
    384         /// </summary>
    385         [PropertySaveOrder(8)]
    386         [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" })]
    387         [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" })]
    388         public int AlphabetCase
    389         {
    390             get { return this.caseSensitiveAlphabet; }
    391             set
    392             {
    393                 if (value != caseSensitiveAlphabet)
    394                 {       HasChanges = true;      }
    395                 this.caseSensitiveAlphabet = value;
    396                 if (value == 0)
    397                 {
    398                     if (alphabet == (upperAlphabet + lowerAlphabet))
    399                     {
    400                         alphabet = upperAlphabet;
    401                         LogMessage("Changing alphabet to: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
    402                         OnPropertyChanged("AlphabetSymbols");
    403                         // reset the key (shiftvalue/shiftChar)
    404                         // to be in the range of the new alphabet.
    405                         setKeyByValue(shiftValue);
    406                     }
    407                 }
    408                 else
    409                 {
    410                     if (alphabet == upperAlphabet)
    411                     {
    412                         alphabet = upperAlphabet + lowerAlphabet;
    413                         LogMessage("Changing alphabet to: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
    414                         OnPropertyChanged("AlphabetSymbols");
    415                     }
    416                 }
    417 
    418                 // Remove equal characters from the current alphabet.
    419                 string a = alphabet;
    420                 alphabet = removeEqualChars(alphabet);
    421                 if (a != alphabet)
    422                 {
    423                     OnPropertyChanged("AlphabetSymbols");
    424                     LogMessage("Changing alphabet to: \"" + alphabet + "\" (" + alphabet.Length.ToString() + " Symbols)", NotificationLevel.Info);
    425                 }
    426                 OnPropertyChanged("AlphabetCase");
    427                 if (ReExecute != null)
    428                 {       ReExecute();    }
    429             }
    430         }
    431 
    432         #endregion
    433 
    434         #region INotifyPropertyChanged Members
    435 
    436         public event PropertyChangedEventHandler PropertyChanged;
    437 
    438         protected void OnPropertyChanged(string name)
    439         {
    440           if (PropertyChanged != null)
    441           {
    442             PropertyChanged(this, new PropertyChangedEventArgs(name));
    443           }
    444         }
    445 
    446         #endregion
    447 
    448         #region TaskPaneAttributeChanged (Sample)
    449         /// <summary>
    450         /// This event is here merely as a sample.
    451         /// </summary>
    452         public event TaskPaneAttributeChangedHandler TaskPaneAttributeChanged;
    453 
    454         [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)]
    455         public void EnableDisableSesitivity()
    456         {
    457           if (TaskPaneAttributeChanged!= null)
    458           {
    459             sensitivityEnabled = !sensitivityEnabled;
    460             if (sensitivityEnabled)
    461             {
    462               TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("AlphabetCase", Visibility.Visible)));
    463             }
    464             else
    465             {
    466               TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("AlphabetCase", Visibility.Collapsed)));
    467             }
    468           }
    469         }
    470         #endregion TaskPaneAttributeChanged (Sample)
    471     }
    472 }
    473 \end{lstlisting}
    474 \clearpage
    475 
    476 \section{Adding an icon to the Caesar class}
    477 \label{sec:AddingAnIconToTheCaesarClass}
    478 
    479 Before 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 2 \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.)
    480 
    481 For testing purposes you can just create a simple black and white PNG image with any graphics editing program, such as 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.
    482 
    483 Once you have saved your icon, you should add it directly to the project or to a subdirectory with it. In the project solution, we created a new folder named \textit{Images}. This can be done by right-clicking on the project item (\textit{Caesar} in our example) and selecting \textit{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 \textit{Add $\rightarrow$ Existing Item}.
    484 
    485 \begin{figure}[h!]
    486         \centering
    487                 \includegraphics{figures/add_existing_item.jpg}
    488         \caption{Adding an existing item.}
    489         \label{fig:add_existing_item}
    490 \end{figure}
    491 \clearpage
    492 
    493 A new window will then appear. Select \textit{Image Files} as the file type and select your newly-created icon for your plugin.
    494 
    495 \begin{figure}[h!]
    496         \centering
    497                 \includegraphics{figures/choose_icon.jpg}
    498         \caption{Selecting the image file.}
    499         \label{fig:choose_icon}
    500 \end{figure}
    501 \clearpage
    502 
    503 Finally, we must set the icon as a \textit{Resource} to avoid including the icon as a separate file. Right-click on the icon and select \textit{Properties} as seen below.
    504 
    505 \begin{figure}[h!]
    506         \centering
    507                 \includegraphics{figures/icon_properties.jpg}
    508         \caption{Selecting the image properties.}
    509         \label{fig:icon_properties}
    510 \end{figure}
    511 
    512 In the \textit{Properties} panel, set the \textit{Build Action} to \textit{Resource}.
    513 
    514 \begin{figure}[h!]
    515         \centering
    516                 \includegraphics{figures/icon_build_action.jpg}
    517         \caption{Selecting the icon's build action.}
    518         \label{fig:icon_build_action}
    519 \end{figure}
    520 \clearpage
    521 
    522 \section{Defining the attributes of the Caesar class}
    523 \label{sec:DefiningTheAttributesOfTheCaesarClass}
    524 
    525 Now let's go back to the code of the Caesar class (the \textit{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 environment. If they are not properly defined, your plugin won't show up in the application user interface, even if everything else is implemented correctly.
    526 
    527 Attributes are used for declarative programming and provide metadata that can be added to the existing .NET metadata. CrypTool 2 provides a set of custom attributes that are used to mark the different parts of your plugin.
    528 
    529 These attributes can be defined anywhere within the \textit{Cryptool.Caesar} namespace, but customarily they are defined right before the class declaration.
    530 
    531 \subsection{The \protect\textit{[Author]} attribute}
    532 \label{sec:TheAuthorAttribute}
    533 
    534 The \textit{[Author]} attribute is optional, meaning that we are not required to define it. The attribute can be used to provide additional information about the plugin developer (or developers, as the case may be). 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.
    535 
    536 \begin{figure}[h!]
    537         \centering
    538                 \includegraphics[width=.90\textwidth]{figures/attribute_author.jpg}
    539         \caption{The defintion for the \textit{[Author]} attribute.}
    540         \label{fig:attribute_author}
    541 \end{figure}
    542 
    543 As can be seen above, the author attribute takes four elements of type string. These elements are:
    544 
    545 \begin{itemize}
    546         \item \textit{Author} --- the name of the plugin developer.
    547         \item \textit{Email} --- the email address of the plugin developer, should he or she wish to be available for contact.
    548         \item \textit{Institute} --- the organization, company or university with which the developer is affiliated.
    549         \item \textit{URL} --- the website of the developer or of his or her institution.
    550 \end{itemize}
    551 
    552 All of these elements are optional; the developer can choose what information will be published. Unused elements should be set to \texttt{null} or an empty string.
    553 \clearpage
    554 
    555 \subsection{The \protect\textit{[PluginInfo]} attribute}
    556 \label{sec:ThePluginInfoAttribute}
    557 
    558 The second attribute, \textit{[PluginInfo]}, provides necessary information about the plugin, and is therefore mandatory. The information defined in this attribute appears in the caption and tool tip window. The attribute is defined as follows:
    559 
    560 \begin{figure}[h]
    561         \centering
    562                 \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo.jpg}
    563         \caption{The defintion for the \textit{[PluginInfo]} attribute.}
    564         \label{fig:attribute_plugininfo}
    565 \end{figure}
    566 
    567 \noindent This attribute has the following parameters:
    568 
    569 \begin{itemize}
    570         \item \textit{Resource File} --- the relative path of the associated resource file (if the plugin makes use of one). These files are used primarily to provide multilingual support for the plugin, although this is currently a work in progress. This element is optional.
    571         \item \textit{Startable} --- a flag that should be set to \texttt{true} only if the plugin is an input generator (i.e.\ if your plugin only has outputs and no inputs). In all other cases this should be set to \texttt{false}. This flag is important --- setting it incorrectly will result in unpredictable results. This element is mandatory.
    572         \item \textit{Caption} --- the name of the plugin, or, if using a resource file, the name of the field in the file with the caption data. This element is mandatory.
    573         \item \textit{ToolTip} --- a description of the plugin, or, if using a resource file, the name of the field in the resource file with the toolTip data. This element is optional.
    574         \item \textit{DescriptionURL} --- the local path of the description file (e.g.\ XAML file). This element is optional.
    575         \item \textit{Icons} --- an array of strings to define all the paths of the icons used in the plugin (i.e.\ the plugin icon described in Section \ref{sec:AddingAnIconToTheCaesarClass}). This element is mandatory.
    576 \end{itemize}
    577 
    578 \noindent Unused elements should be set to \texttt{null} or an empty string.
    579 
    580 There are a few limitations and bugs that still exist in the \textit{[PluginInfo]} attribute that will be resolved in a future version. First, it is possible to use the plugin without setting a caption, although this is not recommended, and future versions of the plugin will fail to load without a caption. Second, a zero-length toolTip string currently causes the toolTip to appear as an empty box in the application. Third, the toolTip and description do not currently support internationalization and localization. Since the precise formulation and functionality of this attribute is still being developed, it is recommended to view other plugins for examples.
    581 
    582 In our example, the \textit{resourceFile} parameter should be set to \textit{Cryptool.Caesar.Resource.res}. This file will be used to store the label and caption text to support multilingualism.
    583 
    584 The second parameter, \textit{startable}, should be set to \texttt{false}, because our encryption algorithm is not an input generator.
    585 
    586 The next two parameters are necessary to define the plugin's name and description. Since we are using a resource file, we should place here the names of the resource fields that contain the caption and toolTip. (We could also just write simple text strings instead of using outsourced references.)
    587 
    588 The \textit{DescriptionURL} element defines the location path of the description file. The parameter is composed in the format \textit{$<$assembly name$>$/$<$file name$>$} or, if you want to store your description files in a separate folder (as in our case), \textit{$<$assembly name$>$/$<$path$>$/$<$file name$>$}. The description file must be an XAML file. In our case, we shall create a folder named \textit{DetailedDescription} in which to store our XAML file with any necessary images. Our folder structure now looks as follows:
    589 
    590 \begin{figure}[h!]
    591         \centering
    592                 \includegraphics[width=.30\textwidth]{figures/detailed_description.jpg}
    593         \caption{The folder structure as seen in the Solution Explorer.}
    594         \label{fig:attribute_plugininfo_icon_path}
    595 \end{figure}
    596 
    597 Once a detailed description has been written in the XAML file, it can be accessed in the CrypTool~2 application by right-clicking on the plugin icon in the workspace and selecting \textit{Show description}.
    598 
    599 \begin{figure}[h!]
    600         \centering
    601                 \includegraphics[width=1.00\textwidth]{figures/xaml_description.jpg}
    602         \caption{A detailed description provided through an XAML file.}
    603         \label{fig:xaml_description}
    604 \end{figure}
    605 \clearpage
    606 
    607 The last parameter tells CrypTool 2 the names of the provided icons. This parameter is an array composed of strings in the format \textit{$<$assembly name$>$/$<$file name$>$} or \textit{$<$assembly name$>$/$<$path$>$/\linebreak $<$file~name$>$}.
    608 
    609 The first and most important icon is the plugin icon, which will be shown in CrypTool 2 in the ribbon bar and navigation pane. Once the icon has been added to the project as described in Section~\ref{sec:AddingAnIconToTheCaesarClass}, we must accordingly tell CrypTool 2 where to find the icon. This can be seen above in Figure \ref{fig:attribute_plugininfo}.
    610 
    611 If your plugin will use additional icons, you should define the paths to each of them by adding the path strings to the \textit{[PluginInfo]} attribute parameter list, each separated by a comma. We have added two further icons for the context menu in the CrypTool 2 workspace. (If you choose to add more icons, don't forget to add the icons to your solution.)
    612 
    613 \subsection{The \protect\textit{[EncryptionType]} attribute}
    614 \label{sec:TheEncryptionTypeAttribute}
    615 
    616 The third and last attribute, \textit{[EncryptionType]}, is needed to tell CrypTool 2 what type of plugin we are creating. CrypTool 2 uses this information to place the plugin in the correct group in the navigation pane and ribbon bar. In our example, since Caesar is a classical algorithm, we will define the attribute as follows:
    617 
    618 \begin{figure}[h]
    619         \centering
    620                 \includegraphics[width=.90\textwidth]{figures/attribute_encryptiontype.jpg}
    621         \caption{A defined \textit{[EncryptionType]} attribute.}
    622         \label{fig:attribute_encryption_type}
    623 \end{figure}
    624 
    625 The possible values of the \textit{[EncryptionType]} attribute are as follows:
    626 
    627 \begin{itemize}
    628         \item \textit{Asymmetric} --- for asymmetrical encryption algorithms, such as RSA.
    629         \item \textit{SymmetricBlock} --- for block cipher algorithms, such as DES, AES and Twofish.
    630         \item \textit{SymmetricStream} --- for stream cipher algorithms, such as RC4, Rabbit and SEAL.
    631         \item \textit{Hybrid} --- for algorithms which are actually a combination of several algorithms, such as algorithms in which the data is encrypted symmetrically and the encryption key asymmetrically.
    632         \item \textit{Classic} --- for classical encryption or hash algorithms, such as Caesar or MD5.
    633 \end{itemize}
    634 
    635188\section{Defining the private variables of the settings in the Caesar class}
    636189\label{sec:DefiningThePrivateVariablesOfTheSettingsInTheCaesarClass}
     
    639192
    640193\begin{lstlisting}
    641 public class Caesar : IEncryption
    642 {
    643194        #region Private variables
    644195        private CaesarSettings settings;
     
    651202
    652203\ \\ % ugly but functional
    653 If your algorithm deals with long strings of code, it is recommended to use the \textit{CryptoolStream} data type. This was designed for input and output between plugins and to handle large amounts of data. To use the native CrypTool stream type, include the namespace \textit{Cryptool.PluginBase.IO} with a \texttt{using} statement as explained in Section \ref{sec:AddingTheNamespacesAndInheritanceSourcesForTheCaesarClass}.
     204If your algorithm deals with long strings of code, it is recommended to use the \textit{CryptoolStream} data type. This was designed for input and output between plugins and to handle large amounts of data. To use the native CrypTool stream type, include the namespace \textit{Cryptool.PluginBase.IO} with a \texttt{using} statement as explained in Section \ref{sec:ImportingCrypPluginBaseNamespaces}.
    654205
    655206Our example makes use of the following private variables:
     
    663214\end{itemize}
    664215
    665 \section{Implementing the interfaces in the Caesar class}
    666 \label{sec:ImplementingTheInterfacesInTheCaesarClass}
    667 
    668 \subsection{Connecting the settings class}
    669 \label{sec:ConnectingTheSettingsClass}
    670 
    671 The next major step is to write out our implementations of the interfaces. First we will add a constructor to our class. We will use this to create an instance of our settings class and a function to handle events:
    672 
    673 \begin{lstlisting}
    674 public Caesar()
    675 {
    676         this.settings = new CaesarSettings();
    677         this.settings.LogMessage += GuiLogMessage;
    678 }
    679 \end{lstlisting}
    680 
    681 \ \\
    682 \indent Secondly, we must implement the \textit{Settings} property declared in the interface. An outline of this property should have been automatically generated by implementing the interface (see Section \ref{sec:AddingInterfaceFunctionsToTheCaesarClass}); just edit it appropriately to communicate with your settings class as we have done here:
    683 
    684 \begin{lstlisting}
    685 public ISettings Settings
    686 {
    687         get { return (ISettings)this.settings; }
    688         set { this.settings = (CaesarSettings)value; }
    689 }
    690 \end{lstlisting}
     216\subsection{Adding controls to the CaesarSettings class}
     217\label{sec:AddingControlsToTheCaesarSettingsClass}
     218
     219The settings class contains the necessary information about controls, captions, descriptions and default parameters (e.g.\ for key settings, alphabets, key length and type of action) to build the settings \textbf{TaskPane} in the CrypTool application. The settings class is used to populate the TaskPane in the CrypTool 2 application so that the user can modify the plugin settings at will. Thus we will need to implement some controls, such as buttons and text boxes, to allow for the necessary interaction. If you will be implementing an algorithm that does not have any user-defined settings (i.e.\ a hash function), then this class can be left mostly empty. In Appendix \ref{app:CaesarSettings} there is a full example of what a completed TaskPane and the corresponding source code for the existing Caesar plugin in CrypTool 2 looks like. You can also look at the source code of other CrypTool 2 plugins for examples of how to create the TaskPane backend.
     220
     221\section{Adding an icon to the Caesar class}
     222\label{sec:AddingAnIconToTheCaesarClass}
     223
     224Before we go back to the code of the Caesar class, we add a custom icon to our project, which will be shown in the CrypTool 2 \textbf{ribbon bar} and \textbf{navigation pane}. The template has a default icon set, so you don't need to create a custom own.
     225
     226The proper image size is 40x40 pixels, but since the image will be rescaled if necessary, any size is technically acceptable. Once you have saved your icon, you should add it directly to the project or to a subdirectory with it. In the project solution, we created a new folder named \textit{Images}. This can be done by right-clicking on the project item (\textit{Caesar} in our example) and selecting \textit{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 \textit{Add $\rightarrow$ Existing Item}.
     227
     228\begin{figure}[h!]
     229        \centering
     230                \includegraphics{figures/add_existing_item.jpg}
     231        \caption{Adding an existing item.}
     232        \label{fig:add_existing_item}
     233\end{figure}
    691234\clearpage
     235
     236A new window will then appear. Select \textit{Image Files} as the file type and select your newly-created icon for your plugin.
     237
     238\begin{figure}[h!]
     239        \centering
     240                \includegraphics{figures/choose_icon.jpg}
     241        \caption{Selecting the image file.}
     242        \label{fig:choose_icon}
     243\end{figure}
     244\clearpage
     245
     246Finally, we must set the icon as a \textit{Resource} to avoid including the icon as a separate file. Right-click on the icon and select \textit{Properties} as seen below.
     247
     248\begin{figure}[h!]
     249        \centering
     250                \includegraphics{figures/icon_properties.jpg}
     251        \caption{Selecting the image properties.}
     252        \label{fig:icon_properties}
     253\end{figure}
     254
     255In the \textit{Properties} panel, set the \textit{Build Action} to \textit{Resource}.
     256
     257\begin{figure}[h!]
     258        \centering
     259                \includegraphics{figures/icon_build_action.jpg}
     260        \caption{Selecting the icon's build action.}
     261        \label{fig:icon_build_action}
     262\end{figure}
     263\clearpage
     264
     265\section{Input and output dockpoints}
    692266
    693267\subsection{The input/output attributes}
    694268\label{sec:TheInputOutputAttributes}
    695269
    696 %\ \\
    697 \indent Next we will define five properties, each with an appropriate attribute, to be used for input and output. Th attributes are necessary to tell CrypTool 2 whether the properties are used for input or output and to provide the plugin with external data.
     270Next we will define five properties, each with an appropriate attribute, to be used for input and output. Th attributes are necessary to tell CrypTool 2 whether the properties are used for input or output and to provide the plugin with external data.
    698271
    699272The attribute that we will use for each proprerty is called \textit{[PropertyInfo]} and it consists of the following elements:
     
    726299                \item \texttt{DisplayLevel.Professional}
    727300        \end{itemize}
    728 \clearpage
    729301       
    730302        \item \textit{quickWatchFormat} --- determines how the content of the property will be shown in the quickwatch perspective. CrypTool 2 accepts the following quickwatch formats:
     
    774346
    775347\ \\
    776 In the get method we simply return the value of the input data. The set method checks if the input value has changed, and, if so, sets the new input data and announces the change to the CrypTool 2 environment by calling the function \textit{OnPropertyChanged(\textit{$<$Property name$>$})}. This step is necessary for input properties to update the quickwatch view.
    777 \clearpage
     348In the get method we simply return the value of the input data. The set method checks if the input value has changed, and, if so, sets the new input data and announces the change to the CrypTool 2 environment by calling the function \textit{OnPropertyChanged(\textit{$<$Property name$>$})}. This step is necessary for input properties to update the quickwatch view. The output data property (which handles the input data after it has been encrypted or decrypted) will in our example look as follows:
    778349
    779350%\textit{\small Note 1: It is currently not possible to read directly from the input data stream without creating an intermediate CryptoolStream.\\\\
    780351%\small Note 2: The naming may be confusing. The new CryptoolStream is not an output stream, but it is added to the list of output streams to enable a clean dispose afterwards. See chapter 9 below.\\\\}
    781 
    782 The output data property (which handles the input data after it has been encrypted or decrypted) will in our example look as follows:
    783352
    784353\begin{lstlisting}
     
    849418\end{lstlisting}
    850419
    851 
    852 \subsection{Sending messages to the CrypTool 2 core}
    853 \label{sec:SendingMessagesToTheCrypTool2Core}
    854 
    855 The CrypTool 2 API provides two methods to send messages from the plugin to the CrypTool 2 core. \textit{GuiLogMessage} is used to send messages to the CrypTool 2 status bar. This method is a nice mechanism to inform the user as to what your plugin is currently doing. \textit{OnPropertyChanged} is used to inform the core application of changes to any plugin properties and data. This may not affect the user interface, but is important to keep the core appraised of the plugin's current state.
    856 
    857 \begin{figure}[h]
    858         \centering
    859                 \includegraphics[width=1.00\textwidth]{figures/status_bar.jpg}
    860         \caption{An example status bar.}
    861         \label{fig:status_bar}
    862 \end{figure}
    863 \clearpage
    864 
    865 The \textit{GuiLogMessage} method takes two parameters:
    866 
    867 \begin{itemize}
    868         \item \textit{Message} --- the text to be shown in the status bar.
    869         \item \textit{NotificationLevel} --- the type of message, that is, its alert level:
    870         \begin{itemize}
    871                 \item \texttt{NotificationLevel.Error}
    872                 \item \texttt{NotificationLevel.Warning}
    873                 \item \texttt{NotificationLevel.Info}
    874                 \item \texttt{NotificationLevel.Debug}
    875         \end{itemize}
    876 \end{itemize}
    877 
    878 Both of these notification methods also have associated events. Outlines of both related events will have been automatically generated by implementing the interface (see Section \ref{sec:AddingInterfaceFunctionsToTheCaesarClass}), but we must define the appropriate methods as follows:
    879 
    880 \begin{lstlisting}
    881 public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
    882 
    883 private void GuiLogMessage(string message, NotificationLevel logLevel)
    884 {
    885         EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(message, this, logLevel));
    886 }
    887 
    888 public event PropertyChangedEventHandler PropertyChanged;
    889 
    890 public void OnPropertyChanged(String name)
    891 {
    892         EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
    893 }
    894 \end{lstlisting}
    895 
    896 \ \\
    897 \indent Note that to use \textit{PropertyChangedEventHandler} you must include the namespace \textit{System.\linebreak ComponentModel}. Our collection of included namespaces should now look as follows:
    898 
    899 \begin{lstlisting}
    900 using System;
    901 using System.Collections.Generic;
    902 using System.ComponentModel;
    903 using System.Text;
    904 
    905 using Cryptool.PluginBase;
    906 using Cryptool.PluginBase.Cryptography;
    907 using Cryptool.PluginBase.IO;
    908 using Cryptool.PluginBase.Miscellaneous;
    909 \end{lstlisting}
    910 \clearpage
    911 
    912 \section{Completing the algorithmic code of the Caesar class}
    913 \label{sec:CompletingTheAlgorithmicCodeOfTheCaesarClass}
    914 
    915 At this point, the plugin should be ready to be read by and shown correctly in the CrypTool 2 application. However, we haven't actually implemented the algorithm yet; we have just implemented interfaces and constructed a thorough set of properties. Algorithmic processing should be done in the \textit{Execute()} function, as this is what CrypTool 2 will always call first. The actual functionality of your algorithm, as well as the structure thereof, is up to you. Note that an outline of the \textit{Execute()} function will have been automatically generated by implementing the interface (see Section \ref{sec:AddingInterfaceFunctionsToTheCaesarClass}).
    916 
    917 We have chosen to split our algorithm's encryption and decryption processes into two separate functions, which will both ultimately call the \textit{ProcessCaesar()} function. Below is our implementation of the Caesar algothmic processing and the \textit{Execute()} function:
     420\section{Implementing the actual algorithm}
     421
     422Algorithmic processing should be done in the \textit{Execute()} function. The actual functionality of your algorithm, as well as the structure thereof, is up to you. Below is our implementation of the Caesar algorithmic processing and the \textit{Execute()} function:
    918423
    919424\begin{lstlisting}
     
    1002507
    1003508                        // Show the progress.
    1004                         if (OnPluginProgressChanged != null)
    1005                         {
    1006                                 OnPluginProgressChanged(this, new PluginProgressEventArgs(i, inputString.Length - 1));
    1007                         }
     509                        ProgressChanged(i, inputString.Length - 1);
    1008510                }
    1009511                outputString = output.ToString();
     
    1013515}
    1014516
    1015 public void Encrypt()
    1016 {
    1017         ProcessCaesar(CaesarMode.encrypt);
    1018 }
    1019 
    1020 public void Decrypt()
    1021 {
    1022         ProcessCaesar(CaesarMode.decrypt);
    1023 }
    1024 
    1025517public void Execute()
    1026518{
     
    1029521                case 0:
    1030522                        GuiLogMessage("Encrypting", NotificationLevel.Debug);
    1031                         Encrypt();
     523                        ProcessCaesar(CaesarMode.encrypt);
    1032524                        break;
    1033525                case 1:
    1034526                        GuiLogMessage("Decrypting", NotificationLevel.Debug);
    1035                         Decrypt();
     527                        ProcessCaesar(CaesarMode.decrypt);
    1036528                        break;
    1037529                default:
     
    1041533\end{lstlisting}
    1042534
    1043 \ \\
    1044535It is important to make sure that all changes to the output properties will be announced to the CrypTool 2 environment. In our example this happens by calling the set method of \textit{OutputData}, which in turn calls \textit{OnPropertyChanged} to indicate that both output properties \textit{OutputData} and \textit{OutputDataStream} have changed. Instead of calling the property's set method you could instead call \textit{OnPropertyChanged} directly within the \textit{Execute()} method.
    1045 \clearpage
    1046 
    1047 You may have noticed that the \textit{ProgressChanged} method is undefined. This method can be used to show the current algorithm process as a progress bar in the plugin icon. To use this method and compile successfully, you must declare this method, which we have done for our example below. Note that the \textit{OnPluginProgressChanged} event will have been automatically generated by implementing the interface (see Section \ref{sec:AddingInterfaceFunctionsToTheCaesarClass}).
    1048 
    1049 \begin{lstlisting}
    1050 public event PluginProgressChangedEventHandler OnPluginProgressChanged;
    1051 
    1052 private void ProgressChanged(double value, double max)
    1053 {
    1054         EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
    1055 }
    1056 \end{lstlisting}
    1057 
    1058 \section{Performing a clean dispose}
    1059 \label{sec:PerformingACleanDispose}
    1060 
    1061 Be sure you have closed and cleaned all your streams after execution before CrypTool 2 decides to dispose the plugin instance.
     536
     537\subsection{Sending messages to the CrypTool 2 core}
     538\label{sec:SendingMessagesToTheCrypTool2Core}
     539
     540The CrypTool 2 API provides three methods to send messages from the plugin to the CrypTool 2 core. \textit{GuiLogMessage} is used to send messages to the CrypTool 2 status bar. This method is a nice mechanism to inform the user as to what your plugin is currently doing. \textit{OnPropertyChanged} is used to inform the core application of changes to any data output properties. This is necessary for a correct plugin execution. \textit{ProgressChanged} is used to visualize the progress of the algorithm as a bar.
     541
     542\begin{figure}[h]
     543        \centering
     544                \includegraphics[width=1.00\textwidth]{figures/status_bar.jpg}
     545        \caption{An example status bar.}
     546        \label{fig:status_bar}
     547\end{figure}
     548
     549The \textit{GuiLogMessage} method takes two parameters:
     550
     551\begin{itemize}
     552        \item \textit{Message} --- the text to be shown in the status bar.
     553        \item \textit{NotificationLevel} --- the type of message, that is, its alert level:
     554        \begin{itemize}
     555                \item \texttt{NotificationLevel.Error}
     556                \item \texttt{NotificationLevel.Warning}
     557                \item \texttt{NotificationLevel.Info}
     558                \item \texttt{NotificationLevel.Debug}
     559        \end{itemize}
     560\end{itemize}
     561
     562\subsection{Performing a clean dispose}
     563
     564Be sure you have closed and cleaned all your streams after execution before CrypTool 2 decides to dispose the plugin instance. There has been some misunderstanding about the meaning of \textit{Dispose()}. Dispose will be called ultimately before object destruction. After disposal, the object will be in an undefined state.
     565
    1062566\begin{lstlisting}
    1063567public void Dispose()
     
    1070574}
    1071575\end{lstlisting}
    1072 \clearpage
    1073576
    1074577\section{Drawing the workflow of your plugin}
    1075578\label{DrawingTheWorkfloweOfYourPlugin}
    1076579
    1077 Each plugin should have an associated workflow file to show the algorithm in action in CrypTool 2. These workflow files are saved with the special \textit{.cte} file extension. You can view the example files from other plugins by opening any of the files in the \textit{\textbackslash ProjectSamples} folder with CrypTool 2. Below is a sample workflow for our Caesar example:
     580Each plugin should have an associated workflow file to show the algorithm in action in CrypTool 2. These workflow files are saved with the special \textit{.cte} file extension. You can view the example files from other plugins by opening any of the files in the \texttt{ProjectSamples\textbackslash} folder with CrypTool 2. Below is a sample workflow for our Caesar example:
    1078581
    1079582\begin{figure}[h]
     
    1084587\end{figure}
    1085588
    1086 As your last step of development, once your plugin runs smoothly, you should also create one of these sample workflow files for your plugin. Such a file can be automatically created by simply saving a CrypTool 2 workspace project featuring your plugin. You should store the workflow file in the \textit{\textbackslash ProjectSamples} folder and make sure to commit the file to the SVN repository (see Section \ref{CommitingYourChanges}).
     589As your last step of development, once your plugin runs smoothly, you should also create one of these sample workflow files for your plugin. You should store the workflow file in the \texttt{ProjectSamples\textbackslash} folder and make sure to commit the file to the SVN repository (see Section \ref{CommitingYourChanges}).
Note: See TracChangeset for help on using the changeset viewer.