Changeset 1053


Ignore:
Timestamp:
Jan 3, 2010, 1:50:57 PM (12 years ago)
Author:
Sebastian Przybylski
Message:

complete new over-worked howto

Location:
trunk/Documentation/Developer/PluginHowTo
Files:
36 added
3 edited

Legend:

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

    r857 r1053  
    1313\usepackage{colortbl}
    1414\usepackage{eso-pic}
     15\usepackage{listings}
    1516
    1617%\usepackage[automark]{scrpage2}
    1718%\usepackage[absolute]{textpos}
    1819
    19 
     20\lstset{language=[Sharp]C, % Grundsprache ist C und Dialekt ist Sharp (C#)
     21captionpos=b, % Beschriftung ist unterhalb
     22frame=lines, % Oberhalb und unterhalb des Listings ist eine Linie
     23basicstyle=\ttfamily, % Schriftart
     24keywordstyle=\color{blue}, % Farbe für die Keywords wie public, void, object u.s.w.
     25commentstyle=\color{green}, % Farbe der Kommentare
     26stringstyle=\color{red}, % Farbe der Zeichenketten
     27numbers=left, % Zeilennummern links vom Code
     28numberstyle=\tiny, % kleine Zeilennummern
     29numbersep=5pt,
     30tabsize=2,
     31breaklines=true, % Wordwrap a.k.a. Zeilenumbruch aktiviert
     32showstringspaces=false,
     33% emph legt Farben für bestimmte Wörter manuell fest
     34emph={double,bool,int,unsigned,char,true,false,void},
     35emphstyle=\color{blue},
     36emph={Assert,Test},
     37emphstyle=\color{red},
     38emph={[2]\using,\#define,\#ifdef,\#endif}, emphstyle={[2]\color{blue}}
     39}
    2040
    2141\geometry{a4paper, portrait, left=2cm, right=2cm, top=2cm, bottom=2cm, includefoot}
    22 
    2342
    2443%\pagestyle{headings}
    2544%\pagestyle{scrheadings}
    2645\pagestyle{fancy} %eigener Seitenstil
    27 \fancyhf{} %alle Kopf- und Fußzeilenfelder bereinigen
     46\fancyhf{} %alle Kopf- und Fußzeilenfelder bereinigen
    2847\fancyhead[L]{\leftmark} %Kopfzeile links
    2948\fancyhead[C]{\AddToShipoutPicture*{\BackgroundHeaderPic}} %zentrierte Kopfzeile
    3049\fancyhead[R]{\rightmark} %Kopfzeile rechts
    3150
    32 \fancyfoot[C]{\thepage\AddToShipoutPicture*{\BackgroundFooterPic}} %zentrierte Fußzeile
     51\fancyfoot[C]{\thepage\AddToShipoutPicture*{\BackgroundFooterPic}} %zentrierte Fußzeile
    3352%\fancyfoot[EL,OR]{\thepage} %Seitennummer
    3453%\fancyfoot[ER,OL]{\includegraphics[height=0.3cm]{figures/ct_logo}}
  • trunk/Documentation/Developer/PluginHowTo/part2.tex

    r845 r1053  
    11\chapter{Plugin Implementation}
    2 In this chapter we provide step-by-step instructions for implementing your own CrypTool 2.0 plugin. The given instructions refer to the usage of MS Visual Studio 2008 Professional, hence before starting you should have installed your copy of MS Visual Studio 2008.
    3 
    4 
    5 
     2In this chapter we provide step-by-step instructions for implementing your own CrypTool 2.0 plugin. The given instructions refer mostly to the usage of MS Visual C\# 2008 Express Edition, hence before starting you should have installed your copy of Microsoft Visual Studio 2008 or Microsoft Visual C\# 2008 Express Edition.
    63\section{New project}
    74\label{sec:CreateANewProjectInVS2008ForYourPlugin}
    8 Open Visual Studio 2008 and create a new project:
    9 
    10 Select ''.NET-Framework 3.5'' as the target framework (the Visual Studio Express edition don't provide this selection because it automatically chooses the actual target framework), and ''Class Library'' as default template to create a DLL file. Give the project a unique and significant name (here: ''Caesar''), and choose a location where to save (the Express edition will ask later for a save location when you close your project or your environment).  Finally confirm by pressing the ''OK'' button.
    11 
    12 Now your Visual Studio solution should look like this:
    13 
    14 
    15 \begin{figure}
    16     %includegraphics...
    17     \caption{Figure 1}\label{fig:figure1}
     5Open Visual Studio 2008 or C\# 2008 Express Edition and create a new project:\\
     6\begin{figure}[h]
     7        \centering
     8                \includegraphics[width=1.00\textwidth]{figures/vs_create_new_project.jpg}
     9        \caption{Create New Visual Studio/C\# Express Project}
     10        \label{fig:vs_create_new_project}
     11\end{figure}\\
     12Select ''.NET-Framework 3.5'' as the target framework (the Visual Studio Express edition don't provide this selection because it automatically chooses the actual target framework), and ''Class Library'' as default template to create a DLL file. Give the project a unique and significant name (here: ''Caesar''), and choose a location where to save (the Express edition will ask later for a save location when you close your project or your environment). Select the subdirectory ''CrypPlugins'' from your SVN trunk as location. Finally confirm by pressing the ''OK'' button.
     13\begin{figure}[h]
     14        \centering
     15                \includegraphics[width=0.80\textwidth]{figures/save_solution_csharp_express.JPG}
     16        \caption{Microsoft C\# Express Edition save solution dialog}
     17        \label{fig:save_solution_csharp_express}
     18\end{figure}\\
     19Now your Visual Studio/C\# Express solution should look like this:\\
     20\begin{figure}[h]
     21        \centering
     22                \includegraphics[width=1.00\textwidth]{figures/solution_start_up.jpg}
     23        \caption{Start-Up solution}
     24        \label{fig:solution_start_up}
    1825\end{figure}
    19 
    20 
    2126\section{Interface selection}
    2227\label{sec:SelectTheInterfaceYourPluginWantsToServe}
    23 First we have to add a reference to the CrypTool library called "CrypPluginBase.dll" where all necessary CrypTool plugin interfaces are declared.
    24 
    25 \begin{figure}
    26     %includegraphics...
    27     \caption{Figure 2}\label{fig:figure2}
    28 \end{figure}
    29 
    30 Make a right click in the Solution Explorer on the ''Reference'' item and choose ''Add Reference''.
    31 
    32 Now browse to the path where the library file is located (e.g. ''C:\\Documents and Settings\\<Username>\\My Documents\\Visual Studio 2008\\Projects\\CrypPluginBase\\bin\\Debug'')
    33 
    34 and select the library by double clicking the file or pressing the "OK" button.
    35 
    36 \begin{figure}
    37     %includegraphics...
    38     \caption{Figure 3}\label{fig:figure3}
    39 \end{figure}
    40 
    41 Besides the CrypPluginBase you need to add three assembly references to provide the necessary "Windows" namespace for your user control functions called "Presentation" and "QuickWatchPresentation". Select the following .NET components:
    42 
     28First we have to add a reference to the CrypTool library called ''CrypPluginBase.dll'' where all necessary CrypTool plugin interfaces are declared.\\
     29\begin{figure}[h!]
     30        \includegraphics{figures/add_reference.jpg}
     31        \caption{Add new reference}
     32        \label{fig:add_reference}
     33\end{figure}\\
     34Make a right click in the Solution Explorer on the ''Reference'' item and choose ''Add Reference''.\\
     35\begin{figure}[h]
     36        \centering
     37                \includegraphics{figures/add_pluginbase_source.jpg}
     38        \caption{Add reference PluginBase source code}
     39        \label{fig:add_pluginbase_source}
     40\end{figure}\\
     41Select the project ''CrypPluginBase''. If you don't have the CrypPluginBase source code, it's also possible to add a reference the the binary DLL. In this case browse to the path where the library file ''CrypPluginBase.dll'' is located e.g. ''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.\\
     42\begin{figure}[h]
     43        \centering
     44                \includegraphics{figures/browse_reference.jpg}
     45        \caption{Browse reference}
     46        \label{fig:browse_reference}
     47\end{figure}\\
     48Besides the CrypPluginBase you need to add three assembly references (same way like the ''CrypPluginBase'' before by selectig the ''.NET'' tab) to provide the necessary "Windows" namespace for your \textbf{user control} functions called "Presentation" and "QuickWatchPresentation". Select the following .NET components:\\
    4349\begin{itemize}
    4450    \item PresentationCore
     
    4652    \item WindowsBase
    4753\end{itemize}
    48 
    4954Afterwards your reference tree view should look like this:
    50 
    51 [IMAGE]
    52 
     55\begin{figure}[h!]
     56                \includegraphics{figures/reference_tree.jpg}
     57        \caption{Reference tree}
     58        \label{fig:reference_tree}
     59\end{figure}
    5360If your plugin will be based on further libraries, you have to add them in the same way.
    54 
    55 
    5661\section{Create the classes for the algorithm and for its settings}\label{sec:CreateTheClassesForTheAlgorithmAndForItsSettings}
    5762In the next step we have to create two classes. The first class named "Caesar" has to inherit from IEncryption to provide an ecryption plugin. If you want to develop a Hash plugin your class has to inherit from IHash.
     
    5964\subsection{Create the class for the algorithm (Caesar)}\label{sec:CreateTheClassForTheAlgorithmCaesar}
    6065Visual Studio automatically creates a class which has the name "Class1.cs".  There are two ways to change the name to "Caesar.cs":
    61 
    62 \hspace{20pt}-Rename the existent class
    63 
    64 \hspace{20pt}-Delete the existent class and create a new one.
    65 
     66\renewcommand{\labelitemi}{-}
     67\begin{itemize}
     68        \item Rename the existent class
     69        \item Delete the existent class and create a new one.
     70\end{itemize}
    6671Which one you choose is up to you. We choose the second way as you can see in the next screenshot:
    67 
    68 [IMAGE]
    69 
    70 Now make a right click on the project item "Caesar" and select "Add->Class...":
    71 
    72 [IMAGE]
    73 
    74 Now give your class a unique name. We call the class as mentioned above "Caesar.cs" and make it public to be available to other classes.
    75 
    76 [IMAGE]
    77 
    78 \subsection{Create the class for the settings (MD5Settings)}\label{sec:CreateTheClassForTheSettingsCaesarSettings}
    79 Add a second public class for ISettings in the same way. We call the class "CaesarSettings". The settings class provides the necessary information about controls, captions and descriptions and default parameters for e.g. key settings, alphabets, key length and action to build the TaskPane in CrypTool. How a TaskPane could look like you can see below for the example of a Caesar encryption.
    80 
    81 [IMAGE]
    82 \subsection{Add namespace for the class MD5 and the place from where to inherit}
    83 \label{sec:AddNamespaceForTheClassMD5AndThePlaceFromWhereToInherit}
    84 Now open the "Caesar.cs" file by double clicking on it at the Solution Explorer and include the necessary namespaces to the class header by typing in the according "using" statement. The CrypTool 2.0 API provides the following namespaces:
    85 
    86 \hspace{20pt}-Cryptool.PluginBase = interfaces like IPlugin, IHash, ISettings, attributes, enumerations, delegates and extensions.
    87 
    88 \hspace{20pt}-Cryptool.PluginBase.Analysis = interface for the crypto analysis plugins like "Stream Comparator"
    89 
    90 \hspace{20pt}-Cryptool.PluginBase.Cryptography = interface for all encryption and hash algorithms like AES, DES or MD5 hash
    91 
    92 \hspace{20pt}-Cryptool.PluginBase.Editor = interface for editors you want to implement for CrypTool 2.0 like the default editor
    93 
    94 \hspace{20pt}-Cryptool.PluginBase.Generator = interface for generators like the random input generator
    95 
    96 \hspace{20pt}-Cryptool.PluginBase.IO = interface for CryptoolStream, input and output plugins like text input, file input, text output and file output
    97 
    98 \hspace{20pt}-Cryptool.PluginBase.Miscellaneous = provides all event helper like GuiLogMessage or PropertyChanged
    99 
    100 \hspace{20pt}-Cryptool.PluginBase.Tool = interface for all foreign tools which CrypTool 2.0 has to provide and which does not exactly support the CrypTool 2.0 API
    101 
    102 \hspace{20pt}-Cryptool.PluginBase.Validation = interface which provides method for validation like regular expression
    103 
     72\begin{figure}[h!]
     73        \centering
     74                \includegraphics{figures/new_class.jpg}
     75        \caption{Create new class}
     76        \label{fig:new_class}
     77\end{figure}\\
     78Now make a right click on the project item "Caesar" and select "Add-$>$Class...":
     79\begin{figure}[h]
     80        \centering
     81                \includegraphics{figures/add_new_class.jpg}
     82        \caption{Add a new class}
     83        \label{fig:add_new_class}
     84\end{figure}\\
     85Now give your class a unique name. We call the class as mentioned above "Caesar.cs" and make it public to be available to other classes.\\
     86\begin{figure}[h!]
     87        \centering
     88                \includegraphics[width=1.00\textwidth]{figures/name_new_class.jpg}
     89        \caption{Name the new class}
     90        \label{fig:name_new_class}
     91\end{figure}\\
     92\subsection{Create the class for the settings (CaesarSettings)}\label{sec:CreateTheClassForTheSettingsCaesarSettings}
     93Add a second public class for ISettings in the same way. We call the class "CaesarSettings". The settings class provides the necessary information about controls, captions and descriptions and default parameters for e.g. key settings, alphabets, key length and action to build the \textbf{TaskPane} in CrypTool. How a \textbf{TaskPane} could look like you can see below for the example of a Caesar encryption.\\
     94\begin{figure}[h!]
     95        \centering
     96                \includegraphics{figures/task_pane.jpg}
     97        \caption{TaskPane}
     98        \label{fig:task_pane}
     99\end{figure}\\
     100\subsection{Add namespace for the class Caesar and the place from where to inherit}
     101\label{sec:AddNamespaceForTheClassCaesarAndThePlaceFromWhereToInherit}
     102Now open the ''Caesar.cs'' file by double clicking on it at the Solution Explorer and include the necessary namespaces to the class header by typing in the according ''using'' statement. The CrypTool 2.0 API provides the following namespaces:
     103\begin{itemize}
     104        \item Cryptool.PluginBase = interfaces like IPlugin, IHash, ISettings, attributes, enumerations, delegates and extensions.
     105        \item Cryptool.PluginBase.Analysis = interface for the crypto analysis plugins like ''Stream Comparator''
     106        \item Cryptool.PluginBase.Control = ?
     107        \item Cryptool.PluginBase.Cryptography = interface for all encryption and hash algorithms like AES, DES or MD5 hash
     108        \item Cryptool.PluginBase.Editor = interface for editors you want to implement for CrypTool 2.0 like the default editor
     109        \item Cryptool.PluginBase.Generator = interface for generators like the random input generator
     110        \item Cryptool.PluginBase.IO = interface for CryptoolStream, input and output plugins like text input, file input, text output and file output
     111        \item Cryptool.PluginBase.Miscellaneous = provides all event helper like GuiLogMessage or PropertyChanged
     112        \item Cryptool.PluginBase.Resources = ?
     113        \item Cryptool.PluginBase.Tool = interface for all foreign tools which CrypTool 2.0 has to provide and which does not exactly support the CrypTool 2.0 API
     114        \item Cryptool.PluginBase.Validation = interface which provides method for validation like regular expression
     115\end{itemize}
    104116In this case we want to implement a Caesar algorithm which means we need to include the following namespaces:
    105 
    106 \hspace{20pt}-"Cryptool.PluginBase" to provide "ISettings" for the CaesarSettings class
    107 
    108 \hspace{20pt}-"Cryptool.PluginBase.Cryptography" to provide "IEncryption" for the Caesar class
    109 
    110 \hspace{20pt}-"Cryptool.PluginBase.Miscellaneous" to use the entire CrypTool event handler
    111 
    112 It is important to define a new default namespace of our public class ("Caesar"). In CrypTool the default namespace is presented by "Cryptool.[name of class]". Therefore our namespace has to be defined as follows: "Cryptool.Caesar".
    113 
     117\begin{itemize}
     118        \item ''Cryptool.PluginBase'' to provide ''ISettings'' for the CaesarSettings class
     119        \item ''Cryptool.PluginBase.Cryptography'' to provide ''IEncryption'' for the Caesar class
     120        \item ''Cryptool.PluginBase.IO'' to provide CryptoolStream for the input and output Data
     121        \item ''Cryptool.PluginBase.Miscellaneous'' to use the entire CrypTool event handler
     122\end{itemize}
     123It is important to define a new default namespace of our public class (''Caesar''). In CrypTool the default namespace is presented by ''Cryptool.[name of class]''. Therefore our namespace has to be defined as follows: ''Cryptool.Caesar''.\\
    114124Up to now the source code should look as you can see below:
    115 
    116 [IMAGE]
    117 
    118 Next let your class "Caesar" inherit from IHash by inserting of the following statement:
    119 
    120 [IMAGE]
    121 
    122 \subsection{Add the interface functions for the class Caesar}\label{sec:AddTheInterfaceFunctionsForTheClassMD5}
    123 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:
    124 
    125 [IMAGE]
    126 
    127 Choose the item "Implement interface 'IEncryption'". Visual Studio will now place all available and needed interface members to interact with the CrypTool core (this saves you also a lot of typing code).
    128 
     125\begin{lstlisting}
     126using System.Collections.Generic;
     127using System.Text;
     128
     129//needed CrypTool namespaces
     130using Cryptool.PluginBase;
     131using Cryptool.PluginBase.Cryptography;
     132using Cryptool.PluginBase.IO;
     133using Cryptool.PluginBase.Miscellaneous;
     134
     135namespace Cryptool.Caesar
     136{
     137        public class Caesar
     138        {
     139        }
     140}
     141\end{lstlisting}
     142Next let your class ''Caesar'' inherit from IEncryption by inserting of the following statement:
     143\begin{lstlisting}
     144namespace Cryptool.Caesar
     145{
     146        public class Caesar: IEncryption
     147        {
     148        }
     149}
     150\end{lstlisting}
     151\subsection{Add the interface functions for the class Caesar}\label{sec:AddTheInterfaceFunctionsForTheClassCaesar}
     152There 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:
     153\begin{figure}[h!]
     154        \centering
     155                \includegraphics{figures/inherit_submenu.jpg}
     156        \caption{Inherit submenu}
     157        \label{fig:inherit_submenu}
     158\end{figure}\\
     159Choose 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).\\
    129160Your code will now look like this:
    130 
    131 [IMAGE]
    132 
    133 
    134 
    135 \subsection{Add namespace and interfaces for the class CaesarSettings}\label{sec:AddNamespaceAndInterfacesForTheClassMD5Settings}
    136 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 will here also automatically place code from the CrypTool interface if available.
    137 
    138 [IMAGE]
    139 
    140 \subsection{Add controls for the class CaesarSettings (if needed)}\label{sec:AddControlsForTheClassMD5SettingsIfNeeded}
    141 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.
    142 
    143 \section{Select and add an image as icon for the class MD5}\label{sec:SelectAndAddAnImageAsIconForTheClassMD5}
    144 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 ribbon bar or/and navigation pane. As there is no default, using an icon image is mandatory.
    145 Note: This will be changed in future. A default icon will be used if no icon image has been provided.
    146 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. Then make a right click on the project item "Caesar" within the Solution Explorer, and select "Add$\textendash$$\textgreater$Existing Item...":
    147 
    148 [IMAGE]
    149 
    150 Then select "Image Files" as file type, and choose the icon for your plugin:
    151 
    152 [IMAGE]
    153 
    154 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":
    155 
    156 [IMAGE]
    157 
    158 In the "Properties" panel you have to set the "Build Action" to "Resource" (not embedded resource):
    159 
    160 [IMAGE]
    161 
    162 
    163 \section{Set the attributes for the class Caesar}\label{sec:SetTheAttributesForTheClassMD5}
    164 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.
    165 
    166 Attributes are used for 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.
    167 
    168 \textit{[Author]}
    169 
    170 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. We set this attribute to demonstrate how it has to look in case you want to provide this attribute.
    171 
    172 [IMAGE]
    173 
     161\begin{lstlisting}
     162using System.Collections.Generic;
     163using System.Text;
     164
     165using Cryptool.PluginBase;
     166using Cryptool.PluginBase.Cryptography;
     167using Cryptool.PluginBase.IO;
     168using Cryptool.PluginBase.Miscellaneous;
     169
     170namespace Cryptool.Caesar
     171{
     172    public class Caesar : IEncryption
     173    {
     174        #region IPlugin Members
     175
     176        public void Dispose()
     177        {
     178            throw new NotImplementedException();
     179        }
     180
     181        public void Execute()
     182        {
     183            throw new NotImplementedException();
     184        }
     185
     186        public void Initialize()
     187        {
     188            throw new NotImplementedException();
     189        }
     190
     191        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
     192
     193        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
     194
     195        public event StatusChangedEventHandler OnPluginStatusChanged;
     196
     197        public void Pause()
     198        {
     199            throw new NotImplementedException();
     200        }
     201
     202        public void PostExecution()
     203        {
     204            throw new NotImplementedException();
     205        }
     206
     207        public void PreExecution()
     208        {
     209            throw new NotImplementedException();
     210        }
     211
     212        public System.Windows.Controls.UserControl Presentation
     213        {
     214            get { throw new NotImplementedException(); }
     215        }
     216
     217        public System.Windows.Controls.UserControl QuickWatchPresentation
     218        {
     219            get { throw new NotImplementedException(); }
     220        }
     221
     222        public ISettings Settings
     223        {
     224            get { throw new NotImplementedException(); }
     225        }
     226
     227        public void Stop()
     228        {
     229            throw new NotImplementedException();
     230        }
     231
     232        #endregion
     233
     234        #region INotifyPropertyChanged Members
     235
     236        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
     237
     238        #endregion
     239    }
     240}
     241\end{lstlisting}
     242\subsection{Add namespace and interfaces for the class CaesarSettings}\label{sec:AddNamespaceAndInterfacesForTheClassCaesarSettings}
     243Let'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.
     244\begin{lstlisting}
     245using System.Collections.Generic;
     246using System.Text;
     247
     248using Cryptool.PluginBase;
     249
     250namespace Cryptool.Caesar
     251{
     252    public class CaesarSettings : ISettings
     253    {
     254        #region ISettings Members
     255
     256        public bool HasChanges
     257        {
     258            get
     259            {
     260                throw new NotImplementedException();
     261            }
     262            set
     263            {
     264                throw new NotImplementedException();
     265            }
     266        }
     267
     268        #endregion
     269
     270        #region INotifyPropertyChanged Members
     271
     272        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
     273
     274        #endregion
     275    }
     276}
     277\end{lstlisting}
     278\subsection{Add controls for the class CaesarSettings (if needed)}\label{sec:AddControlsForTheClassCaesarSettingsIfNeeded}
     279Now 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.
     280\begin{lstlisting}
     281using System;
     282using System.ComponentModel;
     283using System.Windows;
     284using Cryptool.PluginBase;
     285using System.Windows.Controls;
     286
     287namespace Cryptool.Caesar
     288{
     289    public class CaesarSettings : ISettings
     290    {
     291        #region Public Caesar specific interface
     292       
     293        /// <summary>
     294        /// We use this delegate to send log messages from the settings class to the Caesar plugin
     295        /// </summary>
     296        public delegate void CaesarLogMessage(string msg, NotificationLevel loglevel);
     297
     298        /// <summary>
     299        /// An enumaration for the different modes of dealing with unknown characters
     300        /// </summary>
     301        public enum UnknownSymbolHandlingMode { Ignore = 0, Remove = 1, Replace = 2 };
     302
     303        /// <summary>
     304        /// Fire if a new status message was send
     305        /// </summary>
     306        public event CaesarLogMessage LogMessage;
     307
     308        public delegate void CaesarReExecute();
     309
     310        public event CaesarReExecute ReExecute;
     311
     312        /// <summary>
     313        /// Retrieves the current sihft value of Caesar (i.e. the key), or sets it
     314        /// </summary>
     315        [PropertySaveOrder(0)]
     316        public int ShiftKey
     317        {
     318            get { return shiftValue; }
     319            set
     320            {
     321                setKeyByValue(value);
     322            }
     323        }
     324
     325        /// <summary>
     326        /// Retrieves the current setting whether the alphabet should be treated as case sensitive or not
     327        /// </summary>
     328        [PropertySaveOrder(1)]
     329        public bool CaseSensitiveAlphabet
     330        {
     331            get
     332            {
     333                if (caseSensitiveAlphabet == 0)
     334                {   return false;   }
     335                else
     336                {   return true;    }
     337            }
     338            set {} // readonly, because there are some problems if we omit the set part.
     339        }
     340
     341
     342        /// <summary>
     343        /// Returns true if some settings have been changed. This value should be set externally to false e.g.
     344        /// when a project was saved.
     345        /// </summary>
     346        [PropertySaveOrder(3)]
     347        public bool HasChanges
     348        {
     349            get { return hasChanges; }
     350            set { hasChanges = value; }
     351        }
     352
     353        #endregion
     354
     355        #region Private variables
     356        private bool hasChanges;
     357        private int selectedAction = 0;
     358        private string upperAlphabet = ''ABCDEFGHIJKLMNOPQRSTUVWXYZ'';
     359        private string lowerAlphabet = ''abcdefghijklmnopqrstuvwxyz'';
     360        private string alphabet = ''ABCDEFGHIJKLMNOPQRSTUVWXYZ'';
     361        private char shiftChar = 'C';
     362        private int shiftValue = 2;
     363        // private int shiftValue = 2;
     364        private UnknownSymbolHandlingMode unknownSymbolHandling = UnknownSymbolHandlingMode.Ignore;
     365        private int caseSensitiveAlphabet = 0; // 0 = case insensitve, 1 = case sensitive
     366        private bool sensitivityEnabled = true;
     367        #endregion
     368
     369        #region Private methods
     370
     371        private string removeEqualChars(string value)
     372        {
     373            int length = value.Length;
     374
     375            for (int i = 0; i < length; i++)
     376            {
     377                for (int j = i + 1; j < length; j++)
     378                {
     379                    if ((value[i] == value[j]) || (!CaseSensitiveAlphabet & (char.ToUpper(value[i]) == char.ToUpper(value[j]))))
     380                    {
     381                        LogMessage(''Removing duplicate letter: \''' + value[j] + ''\' from alphabet!'', NotificationLevel.Warning);
     382                        value = value.Remove(j,1);
     383                        j--;
     384                        length--;
     385                    }
     386                }
     387            }
     388
     389            return value;
     390        }
     391
     392        /// <summary>
     393        /// Set the new shiftValue and the new shiftCharacter to offset % alphabet.Length
     394        /// </summary>
     395        private void setKeyByValue(int offset)
     396        {
     397            HasChanges = true;
     398
     399            // making sure the shift value lies within the alphabet range     
     400            offset = offset % alphabet.Length;
     401
     402            // set the new shiftChar
     403            shiftChar = alphabet[offset];
     404
     405            // set the new shiftValue
     406            shiftValue = offset;
     407
     408            // Anounnce this to the settings pane
     409            OnPropertyChanged(''ShiftValue'');
     410            OnPropertyChanged(''ShiftChar'');
     411
     412            // print some info in the log.
     413            LogMessage(''Accepted new shift value '' + offset + ''! (Adjusted shift character to \''' + shiftChar + ''\')'', NotificationLevel.Info);
     414        }
     415
     416        private void setKeyByCharacter(string value)
     417        {
     418            try
     419            {
     420                int offset;
     421                if (this.CaseSensitiveAlphabet)
     422                {
     423                    offset = alphabet.IndexOf(value[0]);
     424                }
     425                else
     426                {
     427                    offset = alphabet.ToUpper().IndexOf(char.ToUpper(value[0]));
     428                }
     429               
     430                if (offset >= 0)
     431                {
     432                    HasChanges = true;
     433                    shiftValue = offset;
     434                    shiftChar = alphabet[shiftValue];
     435                    LogMessage(''Accepted new shift character \''' + shiftChar + ''\'! (Adjusted shift value to '' + shiftValue + '')'', NotificationLevel.Info);
     436                    OnPropertyChanged(''ShiftValue'');
     437                    OnPropertyChanged(''ShiftChar'');
     438                }
     439                else
     440                {
     441                    LogMessage(''Bad input \'''' + value + ''\''! (Character not in alphabet!) Reverting to '' + shiftChar.ToString() + ''!'', NotificationLevel.Error);
     442                }
     443            }
     444            catch (Exception e)
     445            {
     446                LogMessage(''Bad input \'''' + value + ''\''! ('' + e.Message + '') Reverting to '' + shiftChar.ToString() + ''!'', NotificationLevel.Error);
     447            }
     448        }
     449
     450        #endregion
     451
     452        #region Algorithm settings properties (visible in the Settings pane)
     453
     454        [PropertySaveOrder(4)]
     455        [ContextMenu(''Action'', ''Select the Algorithm action'', 1, DisplayLevel.Beginner, ContextMenuControlType.ComboBox, new int[] { 1, 2 }, ''Encrypt'', ''Decrypt'')]
     456        [TaskPane(''Action'', ''setAlgorithmActionDescription'', null, 1, true, DisplayLevel.Beginner, ControlType.ComboBox, new string[] { ''Encrypt'', ''Decrypt'' })]
     457        public int Action
     458        {
     459            get
     460            {
     461                return this.selectedAction;
     462            }
     463            set
     464            {
     465                if (value != selectedAction) HasChanges = true;
     466                this.selectedAction = value;
     467                OnPropertyChanged(''Action'');
     468
     469                if (ReExecute != null) ReExecute();
     470            }
     471        }
     472       
     473        [PropertySaveOrder(5)]
     474        [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)]       
     475        public int ShiftValue
     476        {
     477            get { return shiftValue; }
     478            set
     479            {
     480                setKeyByValue(value);
     481                if (ReExecute != null) ReExecute();
     482            }
     483        }
     484
     485
     486        [PropertySaveOrder(6)]
     487        [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}'')]
     488        public string ShiftChar
     489        {
     490            get { return this.shiftChar.ToString(); }
     491            set
     492            {
     493                setKeyByCharacter(value);
     494                if (ReExecute != null) ReExecute();
     495            }
     496        }
     497
     498        [PropertySaveOrder(7)]
     499        [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 \'?\''' })]
     500        [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 \'?\''' })]
     501        public int UnknownSymbolHandling
     502        {
     503            get { return (int)this.unknownSymbolHandling; }
     504            set
     505            {
     506                if ((UnknownSymbolHandlingMode)value != unknownSymbolHandling) HasChanges = true;
     507                this.unknownSymbolHandling = (UnknownSymbolHandlingMode)value;
     508                OnPropertyChanged(''UnknownSymbolHandling'');
     509
     510                if (ReExecute != null) ReExecute();
     511            }
     512        }
     513
     514        [SettingsFormat(0, ''Normal'', ''Normal'', ''Black'', ''White'', Orientation.Vertical)]
     515        [PropertySaveOrder(9)]
     516        [TaskPane(''Alphabet'', ''This is the used alphabet.'', null, 6, true, DisplayLevel.Expert, ControlType.TextBox, '''')]
     517        public string AlphabetSymbols
     518        {
     519          get { return this.alphabet; }
     520          set
     521          {
     522            string a = removeEqualChars(value);
     523            if (a.Length == 0) // cannot accept empty alphabets
     524            {
     525              LogMessage(''Ignoring empty alphabet from user! Using previous alphabet: \'''' + alphabet + ''\'' ('' + alphabet.Length.ToString() + '' Symbols)'', NotificationLevel.Info);
     526            }
     527            else if (!alphabet.Equals(a))
     528            {
     529              HasChanges = true;
     530              this.alphabet = a;
     531              setKeyByValue(shiftValue); //re-evaluate if the shiftvalue is still within the range
     532              LogMessage(''Accepted new alphabet from user: \'''' + alphabet + ''\'' ('' + alphabet.Length.ToString() + '' Symbols)'', NotificationLevel.Info);
     533              OnPropertyChanged(''AlphabetSymbols'');
     534
     535              if (ReExecute != null) ReExecute();
     536            }
     537          }
     538        }
     539
     540        /// <summary>
     541        /// Visible setting how to deal with alphabet case. 0 = case insentive, 1 = case sensitive
     542        /// </summary>   
     543        //[SettingsFormat(1, ''Normal'')]
     544        [PropertySaveOrder(8)]
     545        [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'' })]
     546        [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'' })]
     547        public int AlphabetCase
     548        {
     549            get { return this.caseSensitiveAlphabet; }
     550            set
     551            {
     552                if (value != caseSensitiveAlphabet) HasChanges = true;
     553                this.caseSensitiveAlphabet = value;
     554                if (value == 0)
     555                {
     556                    if (alphabet == (upperAlphabet + lowerAlphabet))
     557                    {
     558                        alphabet = upperAlphabet;
     559                        LogMessage(''Changing alphabet to: \'''' + alphabet + ''\'' ('' + alphabet.Length.ToString() + '' Symbols)'', NotificationLevel.Info);
     560                        OnPropertyChanged(''AlphabetSymbols'');                       
     561                        // re-set also the key (shiftvalue/shiftChar to be in the range of the new alphabet
     562                        setKeyByValue(shiftValue);
     563                    }
     564                }
     565                else
     566                {
     567                    if (alphabet == upperAlphabet)
     568                    {
     569                        alphabet = upperAlphabet + lowerAlphabet;
     570                        LogMessage(''Changing alphabet to: \'''' + alphabet + ''\'' ('' + alphabet.Length.ToString() + '' Symbols)'', NotificationLevel.Info);
     571                        OnPropertyChanged(''AlphabetSymbols'');                       
     572                    }
     573                }
     574
     575                // remove equal characters from the current alphabet
     576                string a = alphabet;
     577                alphabet = removeEqualChars(alphabet);
     578
     579                if (a != alphabet)
     580                {
     581                    OnPropertyChanged(''AlphabetSymbols'');
     582                    LogMessage(''Changing alphabet to: \'''' + alphabet + ''\'' ('' + alphabet.Length.ToString() + '' Symbols)'', NotificationLevel.Info);
     583                }
     584
     585                OnPropertyChanged(''AlphabetCase'');
     586                if (ReExecute != null) ReExecute();
     587            }
     588        }
     589
     590        #endregion
     591
     592        #region INotifyPropertyChanged Members
     593
     594        public event PropertyChangedEventHandler PropertyChanged;
     595
     596        protected void OnPropertyChanged(string name)
     597        {         
     598          if (PropertyChanged != null)
     599          {
     600            PropertyChanged(this, new PropertyChangedEventArgs(name));
     601          }
     602        }
     603
     604        #endregion
     605
     606        #region TaskPaneAttributeChanged-Sample
     607        /// <summary>
     608        /// This event is just used here for sample reasons
     609        /// </summary>
     610        public event TaskPaneAttributeChangedHandler TaskPaneAttributeChanged;
     611
     612        [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)]
     613        public void EnableDisableSesitivity()
     614        {
     615          if (TaskPaneAttributeChanged!= null)
     616          {
     617            sensitivityEnabled = !sensitivityEnabled;
     618            if (sensitivityEnabled)
     619            {             
     620              TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer(''AlphabetCase'', Visibility.Visible)));
     621            }
     622            else
     623            {
     624              TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer(''AlphabetCase'', Visibility.Collapsed)));
     625            }
     626          }
     627        }
     628        #endregion TaskPaneAttributeChanged-Sample
     629    }
     630}
     631\end{lstlisting}
     632\section{Select and add an image as icon for the class Caesar}\label{sec:SelectAndAddAnImageAsIconForTheClassCaesar}
     633Before 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.\\\\
     634\textit{\small Note: This will be changed in future. A default icon will be used if no icon image has been provided.}\\\\
     635For 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. Then make a right click on the project item "Caesar" or any subdirectory within the Solution Explorer, and select ''Add-$>$Existing Item...'':
     636\begin{figure}[h!]
     637        \centering
     638                \includegraphics{figures/add_existing_item.jpg}
     639        \caption{Add existing item}
     640        \label{fig:add_existing_item}
     641\end{figure}\\
     642As 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.
     643Then select ''Image Files'' as file type, and choose the icon for your plugin:
     644\begin{figure}[h!]
     645        \centering
     646                \includegraphics{figures/choose_icon.jpg}
     647        \caption{Choose the right icon}
     648        \label{fig:choose_icon}
     649\end{figure}\\
     650Finally 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'':
     651\begin{figure}[h!]
     652        \centering
     653                \includegraphics{figures/icon_properties.jpg}
     654        \caption{Icon properties}
     655        \label{fig:icon_properties}
     656\end{figure}\\
     657In the ''Properties'' panel you have to set the ''Build Action'' to ''Resource'' (not embedded resource):
     658\begin{figure}[h!]
     659        \centering
     660                \includegraphics{figures/icon_build_action.jpg}
     661        \caption{Icon  build action}
     662        \label{fig:icon_build_action}
     663\end{figure}
     664\section{Set the attributes for the class Caesar}\label{sec:SetTheAttributesForTheClassCaesar}
     665Now 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.\\\\
     666Attributes 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.\\\\
     667\textit{[Author]}\\
     668The 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.
     669\begin{figure}[h!]
     670        \centering
     671                \includegraphics[width=1.00\textwidth]{figures/attribute_author.jpg}
     672        \caption{Attribute author}
     673        \label{fig:attribute_author}
     674\end{figure}\\
    174675As we can see above the author attribute takes four elements of type string. These elements are:
    175 
    176 \hspace{20pt}-Author = name of the plugin developer
    177 
    178 \hspace{20pt}-Email = email of the plugin developer if he wants to be contact
    179 
    180 \hspace{20pt}-Institute = current employment of the developer like University or Company
    181 
    182 \hspace{20pt}-Url = the website or homepage of the developer
    183 
    184 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 ("").
     676\begin{itemize}
     677        \item Author = name of the plugin developer
     678        \item Email = email of the plugin developer if he wants to be contact
     679        \item Institute = current employment of the developer like University or Company
     680        \item Url = the website or homepage of the developer
     681\end{itemize}
     682All 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 ('''').\\
    185683Our author attribute should look now as you can see below:
    186 
    187 [IMAGE]
    188 
    189 \textit{[PluginInfo]}
    190 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:
    191 
    192 [IMAGE]
    193 
     684\begin{figure}[h!]
     685        \centering
     686                \includegraphics[width=1.00\textwidth]{figures/attribute_author_filled.jpg}
     687        \caption{Filled author auttribute}
     688        \label{fig:attribute_author_filled}
     689\end{figure}\\\\
     690\textit{[PluginInfo]}\\
     691The 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:
     692\begin{figure}[h]
     693        \centering
     694                \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo.jpg}
     695        \caption{Attribute PluginInfo}
     696        \label{fig:attribute_plugininfo}
     697\end{figure}\\
    194698This attribute expects the following elements:
    195 
    196 \hspace{20pt}o\hspace{10pt}startable =
    197 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.
    198 
    199 \hspace{20pt}o\hspace{10pt}caption =
    200 from type string, the name of the plugin (e.g. to provide the button content). This element is mandatory.
    201 
    202 \hspace{20pt}o\hspace{10pt}toolTip = from type string, description of the plugin (e.g. to provide the button tool tip). This element is optional.
    203 
    204 \hspace{20pt}o\hspace{10pt}descriptionUrl = from type string, define where to find the whole description files (e.g. XAML files). This element is optional.
    205 o       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.
    206 
    207 Unused optional elements shall be set to null or a zero-length string ("").
    208 
    209 $\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.
    210 
    211 Note 2: Currently a zero-length toolTip string appears as empty box. This will be changed in future.
    212 
    213 Note 3: Tooltip and description currently do not support internationalization and localization. This will be changed in future.
    214 
    215 In our example the first parameter called "startable" has to be set to "false", because our hash algorithm is neither an input nor generator plugin.
    216 
    217 [IMAGE]
    218 
    219 The next two parameters are needed to define the plugin's name and its description:
    220 
    221 [IMAGE]
    222 
    223 The fourth element defines the location path of the description file. The parameter is made up by $\guilsinglleft$Assembly name$\guilsinglright$/$\guilsinglleft$filename$\guilsinglright$ or $\guilsinglleft$Assembly name$\guilsinglright$/$\guilsinglleft$Path$\guilsinglright$/$\guilsinglleft$file name$\guilsinglright$ if you want to store your description files in a separate folder. The description file has to be of type XAML. In our case we create a folder called "DetailedDescription" and store our XAML file there with the necessary images if needed. How you manage the files and folders is up to you. This folder could now look as you can see below:
    224 
    225 [IMAGE]
    226 
     699\begin{itemize}
     700        \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.
     701        \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.
     702        \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.
     703        \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.
     704        \item descriptionUrl = from type string, define where to find the whole description files (e.g. XAML files). This element is optional.
     705        \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.
     706\end{itemize}
     707Unused optional elements shall be set to null or a zero-length string ('''').\\\\
     708\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.\\\\
     709\small Note 2: Currently a zero-length toolTip string appears as empty box. This will be changed in future.\\\\
     710\small Note 3: Tooltip and description currently do not support internationalization and localization. This will be changed in future.\\\\}
     711In 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.
     712\begin{figure}[h]
     713        \centering
     714                \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_resourceFile.JPG}
     715        \caption{Attribute PluginInfo element resourceFile}
     716        \label{fig:attribute_plugininfo_resourceFile}
     717\end{figure}\\
     718The second parameter called ''startable'' has to be set to ''false'', because our encryption algorithm is neither an input nor generator plugin.
     719\begin{figure}[h!]
     720        \centering
     721                \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_startable.jpg}
     722        \caption{Attribute PluginInfo startable}
     723        \label{fig:attribute_plugininfo_startable}
     724\end{figure}\\
     725The next two parameters are needed to define the plugin's name and its description. Now that we decided to provide a resource file we have to place here the both resource field names which contains the description and captions. Otherwise just write here a simple string text:
     726\begin{figure}[h!]
     727        \centering
     728                \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_description.jpg}
     729        \caption{Attribute PluginInfo name and description}
     730        \label{fig:attribute_plugininfo_description}
     731\end{figure}\\
     732The next element defines the location path of the description file. The parameter is made up by $<$Assembly name$>$/$<$filename$>$ or $<$Assembly name$>$/$<$Path$>$/$<$file name$>$ if you want to store your description files in a separate folder (as seen on the icon). The description file has to be of type XAML. In our case we create a folder called ''DetailedDescription'' and store our XAML file there with the necessary images if needed. How you manage the files and folders is up to you. This folder could now look as you can see below:
     733\begin{figure}[h!]
     734        \centering
     735                \includegraphics{figures/attribute_plugininfo_detailed_descr_path.jpg}
     736        \caption{Attribute PluginInfo icon path}
     737        \label{fig:attribute_plugininfo_icon_path}
     738\end{figure}\\
    227739Accordingly the attribute parameter has to be set to:
    228 
    229 [IMAGE]
    230 
    231 The detailed description could now look like this in CrypTool (right click plugin icon on workspace and select "Show description"):
    232 
    233 [IMAGE]
    234 
    235 The last parameter tells CrypTool the names of the provided icons. This parameter is made up by $\guilsinglleft$Assembly name$\guilsinglright$/$\guilsinglleft$file name$\guilsinglright$ or $\guilsinglleft$Assembly name$\guilsinglright$/$\guilsinglleft$Path$\guilsinglright$/$\guilsinglleft$file name$\guilsinglright$.
    236 
     740\begin{figure}[h!]
     741        \centering
     742                \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_detailed_descr.jpg}
     743        \caption{Attribute PluginInfo icon}
     744        \label{fig:attribute_plugininfo_icon}
     745\end{figure}\\
     746The detailed description could now look like this in CrypTool (right click plugin icon on workspace and select ''Show description''):
     747\begin{figure}[h]
     748        \centering
     749                \includegraphics[width=1.00\textwidth]{figures/xaml_description.jpg}
     750        \caption{XAML detailed description}
     751        \label{fig:xaml_description}
     752\end{figure}\\
     753The last parameter tells CrypTool the names of the provided icons. This parameter is made up by $<$Assembly name$>$/$<$file name$>$ or $<$Assembly name$>$/$<$Path$>$/$<$file name$>$.\\\\
    237754The most important icon is the plugin icon, which will be shown in CrypTool in the ribbon bar or navigation pane (This is the first icon in list, so you have to provide at least one icon for a plugin). As named above how to add an icon to the solution accordingly we have to tell CrypTool where to find the icon by setting this parameter as you can see below:
    238 
    239 [IMAGE]
    240 
    241 You can define further icon paths if needed, by adding the path string separated by a comma.
    242 \section{Set the private variables for the settings in the class Caesar}
    243 \label{sec:SetThePrivateVariablesForTheSettingsInTheClassMD5}
     755\begin{figure}[h!]
     756        \centering
     757                \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_icons.jpg}
     758        \caption{Attribute PluginInfo icons}
     759        \label{fig:attribute_plugininfo_icons}
     760\end{figure}\\
     761You can define further icon paths if needed, by adding the path string separated by a comma. We just add here two further icons (don't forget to add the icons to your solution) to provide them for the context menu in the CrypTool workspace.\\\\
     762\textit{[EncryptionType]}\\
     763The third and last attribute called ''EncryptionType'' is needed to tell CrypTool which type of plugin we want to provide. CrypTool is now able to place the plugin in the right group at the navigation pane or/and ribbon bar. Therefore Caesar is a classical algorithm so we have to set the following attribute:
     764\begin{figure}[h]
     765        \centering
     766                \includegraphics[width=1.00\textwidth]{figures/attribute_encryption_type.JPG}
     767        \caption{Attribute encryption type}
     768        \label{fig:attribute_encryption_type}
     769\end{figure}\\
     770The ''EncryptionType'' attribute can also be set as the following types:
     771\begin{itemize}
     772        \item Asymmetric = for asymmetric encryption algorithms like RSA
     773        \item Classic = for classic encryption or hash algorithms like Caesar or MD5
     774        \item Hybrid = for a combination of several algorithm where the data is encrypted symmetric and the encryption key asymmetric
     775        \item SymmetricBlock = for all block cipher algorithms like DES, AES or Twofish
     776        \item SymmetricStream = for all stream cipher algorithms like RC4, Rabbit or SEAL
     777\end{itemize}
     778\section{Set the private variables for the settings in the class Caesar}\label{sec:SetThePrivateVariablesForTheSettingsInTheClassCaesar}
    244779The next step is to define some private variables needed for the settings, input and output data which could look like this:
    245 
    246 [IMAGE]
    247 
    248 Please notice the sinuous line at the type "CryptoolStream" of the variable inputData and the list listCryptoolStreamsOut. "CryptoolStream" is a data type for input and output between plugins and is able to handle large data amounts. To use the CrypTool own stream type, include the namespace "Cryptool.PluginBase.IO" with a "using" statement as explained in chapter 3.3.
    249 
     780\begin{lstlisting}
     781public class Caesar : IEncryption
     782{
     783        #region Private variables
     784        private CaesarSettings settings;
     785        private string inputString;
     786        private string outputString;
     787        private enum CaesarMode { encrypt, decrypt };
     788        private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
     789        #endregion
     790\end{lstlisting}
     791Please notice if there is a sinuous line at the code you type for example at the ''CryptoolStream'' type of the variable listCryptoolStreamsOut. ''CryptoolStream'' is a data type for input and output between plugins and is able to handle large data amounts. To use the CrypTool own stream type, include the namespace ''Cryptool.PluginBase.IO'' with a ''using'' statement as explained in chapter 3.3. Check the other code entries while typing and update the missing namespaces.\\
    250792The following private variables are being used in this example:
    251 
    252 \hspace{20pt}-CaesarSettings settings: required to implement the IPlugin interface properly
    253 
    254 \hspace{20pt}-CryptoolStream inputData: stream to read the input data from
    255 
    256 \hspace{20pt}-byte[] outputData: byte array to save the output hash value
    257 
    258 \hspace{20pt}-List$\guilsinglleft$CryptoolStream$\guilsinglright$ listCryptoolStreamsOut: list of all streams being created by Caesar plugin, required to perform a clean dispose
    259 
    260 
    261 \section{Define the code of the class Caesar to fit the interface}\label{sec:DefineTheCodeOfTheClassMD5ToFitTheInterface}
    262 Next we have to complete our code to correctly serve the interface.
    263 
    264 First we add a constructor to our class where we can create an instance of our settings class:
    265 
    266 [IMAGE]
    267 
    268 Secondly, we have to implement the property "Settings" defined in the interface:
    269 
    270 [IMAGE]
    271 
    272 Thirdly we have to define two properties with their according attributes. This step is necessary to tell Cryptool that these properties are input/output properties used for data exchange with other plugins.
    273 
    274 The attribute is named "PropertyInfo" and consists of the following elements:
    275 
    276 \hspace{20pt}-direction = defines whether this property is an input or output property, i.e. whether it reads input data or writes output data
    277 
    278 \hspace{30pt}o\hspace{10pt}Direction.Input
    279 
    280 \hspace{30pt}o\hspace{10pt}Direction.Output
    281 
    282 \hspace{20pt}-caption = caption of the property (e.g. shown at the input on the dropped icon in the editor), see below:
    283 
    284 [IMAGE]
    285 
    286 \hspace{20pt}-toolTip = tooltip of the property (e.g. shown at the input arrow on the dropped icon in the editor), see above
    287 
    288 \hspace{20pt}-descriptionUrl = not used right now
    289 
    290 \hspace{20pt}-mandatory = this flag defines whether an input is required to be connected by the user. If set to true, there has to be an input connection that provides data. If no input data is provided for mandatory input, your plugin will not be executed in the workflow chain. If set to false, connecting the input is optional. This only applies to input properties. If using Direction.Output, this flag is ignored.
    291 
    292 \hspace{20pt}-hasDefaultValue = if this flag is set to true, CrypTool treats this plugin as though the input has already input data.
    293 
    294 \hspace{20pt}-DisplayLevel = define in which display levels your property will be shown in CrypTool. CrypTool provides the following display levels:
    295 
    296 \hspace{30pt}o\hspace{10pt}DisplayLevel.Beginner
    297 
    298 \hspace{30pt}o\hspace{10pt}DisplayLevel.Experienced
    299 
    300 \hspace{30pt}o\hspace{10pt}DisplayLevel.Expert
    301 
    302 \hspace{30pt}o\hspace{10pt}DisplayLevel.Professional
    303 
    304 \hspace{20pt}-QuickWatchFormat = defines how the content of the property will be shown in the quick watch. CrypTool accepts the following quick watch formats:
    305 
    306 \hspace{30pt}o\hspace{10pt}QuickWatchFormat.Base64
    307 
    308 \hspace{30pt}o\hspace{10pt}QuickWatchFormat.Hex
    309 
    310 \hspace{30pt}o\hspace{10pt}QuickWatchFormat.None
    311 
    312 \hspace{30pt}o\hspace{10pt}QuickWatchFormat.Text
    313 
    314 A quick watch in Hex could look like this:
    315 
    316 [IMAGE]
    317 
    318 \hspace{20pt}-quickWatchConversionMethod = this string points to a conversion method; most plugins can use a "null" value here, because no conversion is necessary. The QuickWatch function uses system "default" encoding to display data. So only if your data is in some other format, like Unicode or UTF8, you have to provide the name of a conversion method as string. The method header has to look like this:
     793\begin{itemize}
     794        \item CaesarSettings settings: required to implement the IPlugin interface properly
     795        \item string inputString: sting to read the input data from
     796        \item string outputString: string to save the output data
     797        \item enum CaesarMode: our own definition how to select between an encryption or decryption. It's up to you how to solve your algorithm
     798        \item List$<$CryptoolStream$>$ listCryptoolStreamsOut: list of all streams being created by Caesar plugin, required to perform a clean dispose
     799\end{itemize}
     800\section{Define the code of the class Caesar to fit the interface}\label{sec:DefineTheCodeOfTheClassCaesarToFitTheInterface}
     801Next we have to complete our code to correctly serve the interface.\\
     802First we add a constructor to our class where we can create an instance of our settings class and a function to handle events:
     803\begin{lstlisting}
     804public class Caesar : IEncryption
     805{
     806        #region Private variables
     807        private CaesarSettings settings;
     808        private string inputString;
     809        private string outputString;
     810        private enum CaesarMode { encrypt, decrypt };
     811        private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
     812        #endregion
     813       
     814        public Caesar()
     815        {
     816                this.settings = new CaesarSettings();
     817                this.settings.LogMessage += Caesar_LogMessage;
     818        }
     819\end{lstlisting}
     820Secondly, we have to implement the property ''Settings'' defined in the interface:
     821\begin{lstlisting}
     822public ISettings Settings
     823{
     824        get { return (ISettings)this.settings; }
     825        set { this.settings = (CaesarSettings)value; }
     826}
     827\end{lstlisting}
     828Thirdly we have to define five properties with their according attributes. This step is necessary to tell Cryptool that these properties are input/output properties used for data exchange with other plugins or to provide our plugin with external data.\\
     829The attribute is named ''PropertyInfo'' and consists of the following elements:
     830\begin{itemize}
     831        \item direction = defines whether this property is an input or output property, i.e. whether it reads input data or writes output data
     832        \begin{itemize}
     833                \item Direction.Input
     834                \item Direction.Output
     835        \end{itemize}
     836        \item caption = caption of the property (e.g. shown at the input on the dropped icon in the editor), see below:
     837\begin{figure}[h]
     838        \centering
     839                \includegraphics{figures/property_caption.jpg}
     840        \caption{Possible property caption}
     841        \label{fig:property_caption}
     842\end{figure}
     843        \item toolTip = tooltip of the property (e.g. shown at the input arrow on the dropped icon in the editor), see above
     844        \item descriptionUrl = not used right now
     845        \item mandatory = this flag defines whether an input is required to be connected by the user. If set to true, there has to be an input connection that provides data. If no input data is provided for mandatory input, your plugin will not be executed in the workflow chain. If set to false, connecting the input is optional. This only applies to input properties. If using Direction.Output, this flag is ignored.
     846        \item hasDefaultValue = if this flag is set to true, CrypTool treats this plugin as though the input has already input data.
     847        \item DisplayLevel = define in which display levels your property will be shown in CrypTool. CrypTool provides the following display levels:
     848        \begin{itemize}
     849                \item DisplayLevel.Beginner
     850                \item DisplayLevel.Experienced
     851                \item DisplayLevel.Expert
     852                \item DisplayLevel.Professional
     853        \end{itemize}
     854        \item QuickWatchFormat = defines how the content of the property will be shown in the quick watch. CrypTool accepts the following quick watch formats:
     855        \begin{itemize}
     856                \item QuickWatchFormat.Base64
     857                \item QuickWatchFormat.Hex
     858                \item QuickWatchFormat.None
     859                \item QuickWatchFormat.Text\\
     860                A quick watch in Hex could look like this:
     861\begin{figure}[h]
     862        \centering
     863                \includegraphics{figures/quick_watch.jpg}
     864        \caption{Possible quick watch}
     865        \label{fig:quick_watch}
     866\end{figure}
     867        \end{itemize}
     868        \item quickWatchConversionMethod = this string points to a conversion method; most plugins can use a ''null'' value here, because no conversion is necessary. The QuickWatch function uses system ''default'' encoding to display data. So only if your data is in some other format, like Unicode or UTF8, you have to provide the name of a conversion method as string. The method header has to look like this:
     869\begin{lstlisting}
    319870object YourMethodName(string PropertyNameToConvert)
    320 
    321 First we define the "InputData" property getter and setter:
    322 
    323 [IMAGE]
    324 
    325 In the getter we check if the input data is not null. If input data is filled, we declare a new CryptoolStream to read the input data, open it and add it to our list where all output stream references are stored. Finally the new stream will be returned.
    326 
    327 $\small$Note 1: It is currently not possible to read directly from the input data stream without creating an intermediate CryptoolStream.
    328 
    329 $\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.
    330 
    331 The setter sets the new input data and announces the data to the Cryptool 2.0 environment by using the expression "OnPropertyChanged("$\guilsinglleft$Property name$\guilsinglright$"). For input properties this step is necessary to update the quick watch view.
    332 
    333 The output data property could look like this:
    334 
    335 [IMAGE]
    336 
    337 CrypTool does not require implementing output setters, as they will never be called from outside of the plugin. Nevertheless in this example our plugin accesses the property itself, therefore we chose to implement the setter.
    338 
    339 You can also provide additional output data types if you like. For example we provide also an output data of type CryptoolStream:
    340 
    341 [IMAGE]
    342 
    343 This property's setter is not called and therefore not implemented.
    344 
    345 Notice the method "GuiLogMessage" in the source codes above. This method is used to send messages to the CrypTool status bar. This is a nice feature to inform the user what your plugin is currently doing.
    346 
    347 [IMAGE]
    348 
     871\end{lstlisting}
     872\end{itemize}
     873First we define the ''InputString'' property getter and setter which is needed to provide our plugin with data which has to be encrypted or decrypted:
     874\begin{lstlisting}
     875[PropertyInfo(Direction.InputData, ''Text input'', ''Input a string to be processed by the Caesar cipher'', '''', true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
     876public string InputString
     877{
     878        get { return this.inputString; }
     879        set
     880  {
     881                if (value != inputString)
     882                {
     883                        this.inputString = value;
     884                        OnPropertyChanged(''InputString'');
     885                }
     886        }
     887}
     888\end{lstlisting}
     889In the getter we return the value of the input data.\\\\
     890\textit{\small Note 1: It is currently not possible to read directly from the input data stream without creating an intermediate CryptoolStream.\\\\
     891\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.\\\\}
     892The setter checkes if the input value has changed and sets the new input data and announces the data to the CrypTool 2.0 environment by using the expression ''OnPropertyChanged($<$Property name$>$)''. For input properties this step is necessary to update the quick watch view.\\
     893The output data property (which provides the encrypted or decrypted input data) could look like this:
     894\begin{lstlisting}
     895[PropertyInfo(Direction.OutputData, ''Text output'', ''The string after processing with the Caesar cipher'', '''', false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
     896public string OutputString
     897{
     898        get { return this.outputString; }
     899        set
     900        {
     901                outputString = value;
     902                OnPropertyChanged(''OutputString'');
     903        }
     904}
     905\end{lstlisting}
     906CrypTool does not require implementing output setters, as they will never be called from outside of the plugin. Nevertheless in this example our plugin accesses the property itself, therefore we chose to implement the setter.\\
     907You can also provide additional output data types if you like. For example we provide also an output data of type CryptoolStream, an input data for external alphabets and an input data for the shift value of our Caesar algorithm:
     908\begin{lstlisting}
     909[PropertyInfo(Direction.OutputData, ''propStreamOutputToolTip'', ''propStreamOutputDescription'', '''', false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
     910public CryptoolStream OutputData
     911{
     912        get
     913        {
     914                if (outputString != null)
     915                {                   
     916                        CryptoolStream cs = new CryptoolStream();
     917                        listCryptoolStreamsOut.Add(cs);
     918                        cs.OpenRead(Encoding.Default.GetBytes(outputString.ToCharArray()));
     919                        return cs;
     920                }
     921                else
     922                {
     923                        return null;
     924                }
     925        }
     926        set { }
     927}
     928
     929[PropertyInfo(Direction.InputData, ''External alphabet input'', ''Input a string containing the alphabet which should be used by Caesar.\nIf no alphabet is provided on this input, the internal alphabet will be used.'', '''', false, false, DisplayLevel.Expert, QuickWatchFormat.Text, null)]
     930public string InputAlphabet
     931{
     932        get { return ((CaesarSettings)this.settings).AlphabetSymbols; }
     933        set
     934        {
     935                if (value != null && value != settings.AlphabetSymbols)
     936                {
     937                        ((CaesarSettings)this.settings).AlphabetSymbols = value;
     938                        OnPropertyChanged(''InputAlphabet'');
     939                }
     940        }
     941}
     942
     943[PropertyInfo(Direction.InputData, ''Shift value (integer)'', ''Same setting as Shift value in Settings-Pane but as dynamic input.'', '''', false, false, DisplayLevel.Expert, QuickWatchFormat.Text, null)]
     944public int ShiftKey
     945{
     946        get { return settings.ShiftKey; }
     947        set
     948        {
     949                if (value != settings.ShiftKey)
     950                {
     951                        settings.ShiftKey = value;
     952                }
     953        }
     954}
     955\end{lstlisting}
     956This property's setter is not called and therefore not implemented.\\
     957The CrypTool-API provides two methods to send messages to the CrypTool. The method ''GuiLogMessage'' is used to send messages to the CrypTool status bar. This is a nice feature to inform the user what your plugin is currently doing.
     958\begin{figure}[h]
     959        \centering
     960                \includegraphics[width=1.00\textwidth]{figures/status_bar.jpg}
     961        \caption{Status Bar}
     962        \label{fig:status_bar}
     963\end{figure}\\
    349964The method takes two parameters which are:
    350 
    351 \hspace{20pt}-Message = will be shown in the status bar and is of type string
    352 
    353 \hspace{20pt}-NotificationLevel = to group the messages to their alert level
    354 
    355 \hspace{30pt}o\hspace{10pt}NotificationLevel.Error
    356 
    357 \hspace{30pt}o\hspace{10pt}NotificationLevel.Warning
    358 
    359 \hspace{30pt}o\hspace{10pt}NotificationLevel.Info
    360 
    361 \hspace{30pt}o\hspace{10pt}NotificationLevel.Debug
    362 
    363 As we can recognize we have two methods named "OnPropertyChanged" and "GuiLogMessage" which are not defined. So we have to define these two methods as you can see below:
    364 
    365 [IMAGE]
    366 
    367 To use the "PropertyChangedEventHandler" you have to include the namespace "System.ComponentModel".
    368 
     965\begin{itemize}
     966        \item Message = will be shown in the status bar and is of type string
     967        \item NotificationLevel = to group the messages to their alert level
     968        \begin{itemize}
     969                \item NotificationLevel.Error
     970                \item NotificationLevel.Warning
     971                \item NotificationLevel.Info
     972                \item NotificationLevel.Debug
     973        \end{itemize}
     974\end{itemize}
     975As we can recognize we have two methods named ''OnPropertyChanged'' and ''GuiLogMessage'' which are not defined. So we have to define these two methods as you can see below:
     976\begin{lstlisting}
     977public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
     978private void GuiLogMessage(string message, NotificationLevel logLevel)
     979{
     980        EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(message, this, logLevel));
     981}
     982
     983public event PropertyChangedEventHandler PropertyChanged;
     984
     985public void OnPropertyChanged(String name)
     986{
     987        EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
     988}
     989\end{lstlisting}
     990To use the ''PropertyChangedEventHandler'' you have to include the namespace ''System.ComponentModel''.\\
    369991Our whole included namespaces looks now like this:
    370 
    371 [IMAGE]
    372 
    373 
    374 \section{Complete the actual code for the class Caesar}\label{sec:CompleteTheActualCodeForTheClassMD5}
    375 Up to now, the plugin is ready for the CrypTool base application to be accepted and been shown correctly in the CrypTool menu. What we need now, is the implementation of the actual algorithm in the function "Execute()" which is up to you as the plugin developer.
    376 
    377 Let us demonstrate the Execute() function, too. Our algorithm is based on the .NET framework:
    378 
    379 [IMAGE]
    380 
    381 It is important to make sure that all changes of output properties will be announced to the CrypTool environment. In this example this happens by calling the setter of OutputData which in turn calls "OnPropertyChanged" for both output properties "OutputData" and "OutputDataStream". Instead of calling the property's setter you can as well call "OnPropertyChanged" directly within the "Execute()" method.
    382 
    383 Certainly you have seen the unknown method "ProgressChanged" which you can use to show the current algorithm process as a progress on the plugin icon.
     992\begin{lstlisting}
     993using System.Collections.Generic;
     994using System.Text;
     995using System.ComponentModel;
     996using System.Windows.Control;
     997
     998using Cryptool.PluginBase;
     999using Cryptool.PluginBase.Cryptography;
     1000using Cryptool.PluginBase.IO;
     1001using Cryptool.PluginBase.Miscellaneous;
     1002\end{lstlisting}
     1003\section{Complete the actual code for the class Caesar}\label{sec:CompleteTheActualCodeForTheClassCaesar}
     1004Up to now, the plugin is ready for the CrypTool base application to be accepted and been shown correctly in the CrypTool menu. What we need now, is the implementation of the actual algorithm in the function ''Execute()'' which is up to you as the plugin developer. CrypTool will always call first the Execute() function.If you place the whole algorithm in this function or split in other as needed is also up to you.\\
     1005We decided to split our algorithm encryption and decryption in two seperate functions, which finally call the function ProcessCaesar.\\
     1006Let us demonstrate the Execute() function, too:
     1007\begin{lstlisting}
     1008private void ProcessCaesar(CaesarMode mode)
     1009{
     1010        CaesarSettings cfg = (CaesarSettings)this.settings;
     1011        StringBuilder output = new StringBuilder('''');
     1012        string alphabet = cfg.AlphabetSymbols;
     1013
     1014  // in case we want don't consider case in the alphabet, we use only capital letters, hence transform
     1015        // the whole alphabet to uppercase
     1016        if (!cfg.CaseSensitiveAlphabet)
     1017        {
     1018                alphabet = cfg.AlphabetSymbols.ToUpper(); ;
     1019        }
     1020           
     1021        if (inputString != null)
     1022        {
     1023                for (int i = 0; i < inputString.Length; i++)
     1024                {
     1025                        // get plaintext char which is currently processed
     1026                        char currentchar = inputString[i];
     1027
     1028                        // remember if it is upper case (otherwise lowercase is assumed)
     1029                        bool uppercase = char.IsUpper(currentchar);
     1030
     1031                        // get the position of the plaintext character in the alphabet
     1032                        int ppos = 0;
     1033                        if (cfg.CaseSensitiveAlphabet)
     1034                        {
     1035                                ppos = alphabet.IndexOf(currentchar);
     1036                        }
     1037                        else
     1038                        {
     1039                                ppos = alphabet.IndexOf(char.ToUpper(currentchar));
     1040                        }
     1041
     1042                        if (ppos >= 0)
     1043                        {
     1044                                // we found the plaintext character in the alphabet, hence we do the shifting
     1045                                int cpos = 0; ;
     1046                                switch (mode)
     1047                                {
     1048                                        case CaesarMode.encrypt:
     1049                                                cpos = (ppos + cfg.ShiftKey) % alphabet.Length;
     1050                                                break;
     1051                                        case CaesarMode.decrypt:
     1052                                                cpos = (ppos - cfg.ShiftKey + alphabet.Length) % alphabet.Length;
     1053                                                break;
     1054                                }
     1055
     1056                                // we have the position of the ciphertext character, hence just output it in the correct case
     1057                                if (cfg.CaseSensitiveAlphabet)
     1058                                {
     1059                                        output.Append(alphabet[cpos]);
     1060                                }
     1061                                else
     1062                                {
     1063                                        if (uppercase)
     1064                                        {
     1065                                                output.Append(char.ToUpper(alphabet[cpos]));
     1066                                        }
     1067                                        else
     1068                                        {
     1069                                                output.Append(char.ToLower(alphabet[cpos]));
     1070                                        }
     1071                                }
     1072                        }
     1073                        else
     1074                        {
     1075                                // the plaintext character was not found in the alphabet, hence proceed with handling unknown characters
     1076                                switch ((CaesarSettings.UnknownSymbolHandlingMode)cfg.UnknownSymbolHandling)
     1077                                {
     1078                                        case CaesarSettings.UnknownSymbolHandlingMode.Ignore:
     1079                                                output.Append(inputString[i]);
     1080                                                break;
     1081                                        case CaesarSettings.UnknownSymbolHandlingMode.Replace:
     1082                                                output.Append('?');
     1083                                                break;
     1084                                }
     1085                        }
     1086
     1087                        //show the progress
     1088                        if (OnPluginProgressChanged != null)
     1089                        {
     1090                                OnPluginProgressChanged(this, new PluginProgressEventArgs(i, inputString.Length - 1));
     1091                        }
     1092                }
     1093                outputString = output.ToString();
     1094                OnPropertyChanged(''OutputString'');
     1095                OnPropertyChanged(''OutputData'');
     1096        }
     1097}
     1098
     1099public void Encrypt()
     1100{
     1101        ProcessCaesar(CaesarMode.encrypt);
     1102}
     1103
     1104public void Decrypt()
     1105{
     1106        ProcessCaesar(CaesarMode.decrypt);
     1107}
     1108
     1109public void Execute()
     1110{
     1111        switch (settings.Action)
     1112        {
     1113                case 0:
     1114                        Caesar_LogMessage(''encrypting'', NotificationLevel.Debug);
     1115                        Encrypt();
     1116                        break;
     1117                case 1:
     1118                        Decrypt();
     1119                        break;
     1120                default:
     1121        break;
     1122        }
     1123}
     1124\end{lstlisting}
     1125It is important to make sure that all changes of output properties will be announced to the CrypTool environment. In this example this happens by calling the setter of OutputData which in turn calls ''OnPropertyChanged'' for both output properties ''OutputData'' and ''OutputDataStream''. Instead of calling the property's setter you can as well call ''OnPropertyChanged'' directly within the ''Execute()'' method.\\\\
     1126Certainly you have seen the unknown method ''ProgressChanged'' which you can use to show the current algorithm process as a progress on the plugin icon.
    3841127To use this method you also have to declare this method to afford a successful compilation:
    385 
    386 [IMAGE]
    387 
     1128\begin{lstlisting}
     1129public event PluginProgressChangedEventHandler OnPluginProgressChanged;
     1130private void ProgressChanged(double value, double max)
     1131{
     1132        EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
     1133}
     1134\end{lstlisting}
    3881135\section{Perform a clean dispose}\label{sec:PerformACleanDispose}
    3891136Be sure you have closed and cleaned all your streams after execution and when CrypTool decides to dispose the plugin instance. Though not required, we run the dispose code before execution as well:
    390 
    391 [IMAGE]
     1137\begin{lstlisting}
     1138public void Dispose()
     1139{
     1140        foreach(CryptoolStream stream in listCryptoolStreamOut)
     1141        {
     1142                stream.Close();
     1143        }
     1144        listCryptoolStreamOut.Clear();
     1145}
     1146
     1147public void PostExecution()
     1148{
     1149        Dispose();
     1150}
     1151
     1152public void PreExecution()
     1153{
     1154        Dispose();
     1155}
     1156\end{lstlisting}
    3921157\section{Finish implementation}\label{sec:FinishImplementation}
    393 When adding plugin instances to the CrypTool workspace, CrypTool checks whether the plugin runs without any exception. If any IPlugin method throws an exception, CrypTool will show an error and prohibit using the plugin. Therefore we have to remove the "NotImplementedException" from the methods "Initialize()", "Pause()" and "Stop()". In our example it's sufficient to provide empty implementations.
    394 
    395 [IMAGE]
    396 
    397 The methods "Presentation()" and "QuickWatchPresentation()" can be used if a plugin developer wants to provide an own visualization of the plugin algorithm which will be shown in CrypTool. Take a look at the PRESENT plugin to see how a custom visualization can be realized. For our Caesar example we don't want to implement a custom visualization, therefore we return "null":
    398 
    399 [IMAGE]
    400 
     1158When adding plugin instances to the CrypTool workspace, CrypTool checks whether the plugin runs without any exception. If any IPlugin method throws an exception, CrypTool will show an error and prohibit using the plugin. Therefore we have to remove the ''NotImplementedException'' from the methods ''Initialize()'', ''Pause()'' and ''Stop()''. In our example it's sufficient to provide empty implementations.
     1159\begin{lstlisting}
     1160public void Initialize()
     1161{
     1162}
     1163
     1164public void Pause()
     1165{
     1166}
     1167
     1168public void Stop()
     1169{
     1170}
     1171\end{lstlisting}
     1172The methods ''Presentation()'' and ''QuickWatchPresentation()'' can be used if a plugin developer wants to provide an own visualization of the plugin algorithm which will be shown in CrypTool. Take a look at the PRESENT plugin to see how a custom visualization can be realized. For our Caesar example we don't want to implement a custom visualization, therefore we return ''null'':
     1173\begin{lstlisting}
     1174public UserControl Presentation
     1175{
     1176        get { return null; }
     1177}
     1178
     1179public UserControl QuickWatchPresentation
     1180{
     1181        get { return null; }
     1182}
     1183\end{lstlisting}
    4011184Your plugin should compile without errors at this point.
    4021185\section{Sign the created plugin}\label{sec:SignTheCreatedPlugin}
    403 
    4041186\section{Import the plugin to Cryptool and test it}\label{sec:ImportThePluginToCryptoolAndTestIt}
    4051187After you have built the plugin, you need to move the newly created plugin DLL to a location, where CrypTool can find it. To do this, there are the following ways:
    406 
    407 \hspace{20pt}1. Copy your plugin DLL file in the folder "CrypPlugins" which has to be in the same folder as the CrypTool executable, called "CrypWin.exe". If necessary, create the folder "CrypPlugins". This folder is called "Global storage" in the CrypTool architecture. Changes in this folder will take effect for all users on a multi user Windows. Finally restart CrypTool.
    408 
    409 [IMAGE]
    410 
    411 \hspace{20pt}2. Copy your plugin DLL file in the folder "CrypPlugins" which is located in your home path in the folder "ApplicationData" and restart CrypTool.  This home folder path is called "Custom storage" in the CrypTool architecture. Changes in this folder will only take effect for current user.  On a German Windows XP the home folder path could look like:
    412 "C:$\backslash$Dokumente und Einstellungen$\backslash$$\guilsinglleft$User$\guilsinglright$$\backslash$Anwendungsdaten$\backslash$CrypPlugins" and in Vista the path will look like "C:$\backslash$Users$\backslash$$\guilsinglleft$user$\guilsinglright$$\backslash$Application Data$\backslash$CrypPlugins".
    413 
    414 [IMAGE]
    415 
    416 \hspace{20pt}3. You can also import new plugins directly from the CrypTool interface. Just execute CrypWin.exe and select the "Download Plugins" button. An "Open File Dialog" will open and ask where the new plugin is located. After selecting the new plugin, CrypTool will automatically import the new plugin in the custom storage folder. With this option you will not have to restart CrypTool. All according menu entries will be updated automatically.
    417 Notice, that this plugin importing function only accepts signed plugins.
    418 
    419 This option is a temporary solution for importing new plugins. In the future this will be done online by a web service.
    420 
    421 \hspace{20pt}4. Use post-build in your project properties to copy the DLL automatically after building it in Visual Studio. Right-click on your plugin project and select "Properties":
    422 
    423 [IMAGE]
    424 
    425 Select "Build Events":
    426 
    427 [IMAGE]
    428 
    429 Enter the following text snippet into "Post-build event command line":
    430 
    431 cd "\$(ProjectDir)"
    432 
    433 cd ..$\backslash$..$\backslash$CrypWin$\backslash$\$(OutDir)
    434 
    435 if not exist "./CrypPlugins" mkdir "./CrypPlugins"
    436 
    437 del /F /S /Q /s /q "Caesar*.*"
    438 
    439 copy "\$(TargetDir)Caesar*.*" "./CrypPlugins"
    440 
     1188\begin{itemize}
     1189        \item Copy your plugin DLL file in the folder ''CrypPlugins'' which has to be in the same folder as the CrypTool executable, called ''CrypWin.exe''. If necessary, create the folder ''CrypPlugins''.
     1190\begin{figure}[h]
     1191        \centering
     1192                \includegraphics{figures/copy_dll_global_storage.jpg}
     1193        \caption{Copy plugin to global storage}
     1194        \label{fig:copy_dll_global_storage}
     1195\end{figure}\\
     1196This folder is called ''Global storage'' in the CrypTool architecture. Changes in this folder will take effect for all users on a multi user Windows. Finally restart CrypTool.
     1197\begin{figure}[h]
     1198        \centering
     1199                \includegraphics{figures/global_storage.jpg}
     1200        \caption{Plugins global storage}
     1201        \label{fig:global_storage}
     1202\end{figure}\\
     1203        \item Copy your plugin DLL file in the folder ''CrypPlugins'' which is located in your home path in the folder ''ApplicationData'' and restart CrypTool.  This home folder path is called ''Custom storage'' in the CrypTool architecture. Changes in this folder will only take effect for current user.  On a German Windows XP the home folder path could look like:
     1204''C:\textbackslash Dokumente und Einstellungen\textbackslash $<$User$>$\textbackslash Anwendungsdaten\textbackslash CrypPlugins'' and in Vista/Windows7 the path will look like ''C:\textbackslash Users\textbackslash $<$user$>$\textbackslash Application Data\textbackslash CrypPlugins''.
     1205\begin{figure}[h]
     1206        \centering
     1207                \includegraphics[width=1.00\textwidth]{figures/custom_storage.jpg}
     1208        \caption{Plugins custom storage}
     1209        \label{fig:custom_storage}
     1210\end{figure}
     1211        \item You can also import new plugins directly from the CrypTool interface. Just execute CrypWin.exe and select the ''Download Plugins'' button. An ''Open File Dialog'' will open and ask where the new plugin is located. After selecting the new plugin, CrypTool will automatically import the new plugin in the custom storage folder. With this option you will not have to restart CrypTool. All according menu entries will be updated automatically.
     1212Notice, that this plugin importing function only accepts \textbf{signed} plugins.
     1213
     1214\textit{\small Note: This option is a temporary solution for importing new plugins. In the future this will be done online by a web service.}
     1215
     1216        \item Use post-build in your project properties to copy the DLL automatically after building it in Visual Studio with other plugins. Right-click on your plugin project and select ''Properties'':
     1217\begin{figure}[h]
     1218        \centering
     1219                \includegraphics{figures/solution_properties.JPG}
     1220        \caption{Solution Properties}
     1221        \label{fig:solution_properties}
     1222\end{figure}\\
     1223Select ''Build Events'':
     1224\begin{figure}[h]
     1225        \centering
     1226                \includegraphics{figures/post_build.JPG}
     1227        \caption{Build Events}
     1228        \label{fig:post_build}
     1229\end{figure}\\
     1230Enter the following text snippet into ''Post-build event command line'':\\\\
     1231cd ''\$(ProjectDir)''\\
     1232cd ..\textbackslash ..\textbackslash CrypWin\$(OutDir)\\
     1233if not exist ''./CrypPlugins'' mkdir ''./CrypPlugins''\\
     1234del /F /S /Q /s /q ''\fcolorbox{yellow}{yellow}{Caesar}*.*''\\
     1235copy ''\$(TargetDir)\fcolorbox{yellow}{yellow}{Caesar}*.*'' ''./CrypPlugins''\\\\
    4411236You need to adapt the yellow marked field to your actual project name.
    442 
     1237\end{itemize}
    4431238\section{Source code and source template}\label{sec:SourceCodeAndSourceTemplate}
    444 Here you can download the whole source code which was presented in this "Howto" as a Visual Studio solution:
    445 
    446 username: anonymous\newline
    447 password: not required
    448 
    449 https://www.cryptool.org/svn/CrypTool2/trunk/CrypPlugins/Caesar/
    450 
    451 
    452 Here you can download the Visual Studio plugin template to begin with the development of a new Cryptool plugin:
    453 
    454 http://cryptool2.vs.uni-due.de/downloads/template/encryptionplugin.zip
    455 
     1239Here you can download the whole source code which was presented in this ''Howto'' as a Visual Studio \textbf{solution}:\\\\
     1240\textit{username: anonymous\\
     1241password: not required\\}
     1242\htmladdnormallink{https://www.cryptool.org/svn/CrypTool2/trunk/CrypPlugins/Caesar/}{https://www.cryptool.org/svn/CrypTool2/trunk/CrypPlugins/Caesar/}\\\\
     1243Here you can download the Visual Studio plugin \textbf{template} to begin with the development of a new Cryptool plugin:\\\\
     1244\htmladdnormallink{http://cryptool2.vs.uni-due.de/downloads/template/encryptionplugin.zip}{http://cryptool2.vs.uni-due.de/downloads/template/encryptionplugin.zip}
    4561245\section{Provide a workflow file of your plugin}\label{ProvideAWorkflowFileOfYourPlugin}
    4571246Every plugin developer should provide a workflow file which shows his algorithm working in CrypTool2. You will automatically create a workflow file by saving your project which was created on CrypTool2 work space. Here is an example how a workflow could look like:
    458 
    459 [IMAGE]
     1247\begin{figure}[h]
     1248        \centering
     1249                \includegraphics{figures/sample.jpg}
     1250        \caption{Plugin sample}
     1251        \label{fig:sample}
     1252\end{figure}
Note: See TracChangeset for help on using the changeset viewer.