From: Enar Väikene <enar@vaikene.net> Date: Mon, 26 Sep 2011 10:16:45 +0000 (+0300) Subject: Finalized tutorial files. X-Git-Url: https://www.vaikene.ee/gitweb/pswgen10.html?a=commitdiff_plain;h=30c0930d760d6338dba3982e01125b10f84c47b2;p=evaf Finalized tutorial files. --- diff --git a/www/pswgen09.html b/www/pswgen09.html new file mode 100644 index 0000000..7f05aba --- /dev/null +++ b/www/pswgen09.html @@ -0,0 +1,217 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html lang="et" xmlns="http://www.w3.org/1999/xhtml" xml:lang="et"> + + <head> + <meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" /> + <title>eVaf Tutorial - 09 - GUI Module</title> + <meta name="Author" content="Enar Väikene" /> + <meta name="description" content="eVaf Tutorial" /> + <meta name="keywords" content="evaf c++ application development framework tutorial password generator" /> + <link rel="StyleSheet" href="evaf.css" type="text/css" media="all" /> + <link rel="StyleSheet" href="highlight.css" type="text/css" media="all" /> + </head> + + <body> + + <h1>eVaf Tutorial</h1> + + <h2>09 - GUI Module</h2> + + <p>The Graphical User Interface (<tt>GUI</tt>) module implements the main window of the application. It uses previously + created <tt>Generator</tt> and <tt>Storage</tt> modules to generate and store passwords.</p> + + <p>We start by creating the <tt>gui.h</tt> file in the <tt>src/apps/PswGen/GUI</tt> directory:</p> + + <pre class="hl"><span class="hl com">/**</span> +<span class="hl com"> * @file PswGen/GUI/gui.h</span> +<span class="hl com"> */</span> + +<span class="hl ppc">#ifndef __PSWGEN_GUI_GUI_H</span> +<span class="hl ppc"># define __PSWGEN_GUI_GUI_H</span> + +<span class="hl ppc">#endif</span> <span class="hl slc">// gui.h</span><span class="hl ppc"></span></pre> + + <p>Include the <tt>Plugins/iPlugin</tt> header file as this is going to be a plugin and also <tt>QObject</tt> and + <tt>QString</tt> as these are almost always needed:</p> + + <pre class="hl"><span class="hl ppc">#include <Plugins/iPlugin></span> +<span class="hl ppc">#include <QObject></span> +<span class="hl ppc">#include <QString></span></pre> + + <p>We use the <tt>eVaf::PswGen::GUI</tt> namespace for this module:</p> + + <pre class="hl"><span class="hl kwa">namespace</span> eVaf <span class="hl opt">{</span> +<span class="hl kwa">namespace</span> PswGen <span class="hl opt">{</span> +<span class="hl kwa">namespace</span> GUI <span class="hl opt">{</span> + +<span class="hl opt">}</span> <span class="hl slc">// namespace eVaf::PswGen::GUI</span> +<span class="hl opt">}</span> <span class="hl slc">// namespace eVaf::PswGen</span> +<span class="hl opt">}</span> <span class="hl slc">// namespace eVaf</span></pre> + + <p>The module itself can be implemented as one single class derived from the <tt>Plugins::iPlugin</tt> parent class:</p> + + <pre class="hl"><span class="hl kwc">class</span> Module <span class="hl opt">:</span> <span class="hl kwc">public</span> Plugins<span class="hl opt">::</span>iPlugin +<span class="hl opt">{</span> + Q_OBJECT + +<span class="hl kwc">public</span><span class="hl opt">:</span> + + <span class="hl kwd">Module</span><span class="hl opt">();</span> + + <span class="hl kwc">virtual</span> <span class="hl opt">~</span><span class="hl kwd">Module</span><span class="hl opt">();</span> + +<span class="hl opt">};</span></pre> + + <p>Implement pure virtual methods derived from the parent class. The main GUI window is created in the <tt>init()</tt> method + and the module can only be ready when the initialization is completed. We use the <tt>mReady</tt> flag to indicate this.</p> + + <pre class="hl"> <span class="hl kwc">virtual</span> <span class="hl kwb">bool</span> <span class="hl kwd">init</span><span class="hl opt">(</span><span class="hl kwb">const</span> QString <span class="hl opt">&</span> args<span class="hl opt">);</span> + + <span class="hl kwc">virtual</span> <span class="hl kwb">void</span> <span class="hl kwd">done</span><span class="hl opt">();</span> + + <span class="hl kwc">virtual</span> <span class="hl kwb">bool</span> <span class="hl kwd">isReady</span><span class="hl opt">()</span> <span class="hl kwb">const</span> <span class="hl opt">{</span> <span class="hl kwa">return</span> mReady<span class="hl opt">; }</span> + +<span class="hl kwc">private</span><span class="hl opt">:</span> + + <span class="hl kwb">bool</span> mReady<span class="hl opt">;</span></pre> + + <p>In the private members section we store interfaces from previously written modules:</p> + + <pre class="hl"> + eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>iGenerator <span class="hl opt">*</span> mGenerator<span class="hl opt">;</span> + + eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>iStorage <span class="hl opt">*</span> mStorage<span class="hl opt">;</span></pre> + + <p>Since these are not known yet, we also need to add forward declarations. These go into the <tt>eVaf::PswGen</tt> namespace + at the beginning of the file:</p> + + <pre class="hl"> +<span class="hl kwa">namespace</span> eVaf <span class="hl opt">{</span> +<span class="hl kwa">namespace</span> PswGen <span class="hl opt">{</span> + <span class="hl kwb">struct</span> iGenerator<span class="hl opt">;</span> + <span class="hl kwb">struct</span> iStorage<span class="hl opt">;</span></pre> + + <p>The main window needs couple of widgets on it:</p> + + <ul> + <li>Master password - a QLineEdit widget;</li> + <li>Name of the password - a QLineEdit widget;</li> + <li>Length of the password - a QSpinBox widget;</li> + <li>Generated password - a QLineEdit widget that we make read-only;</li> + <li>Generate button - a QPushButton widget;</li> + <li>Copy button that copies generated passwords to the clipboard - a QPushButton widget.</li> + </ul> + + <pre class="hl"> + <span class="hl slc">/// Widgets on the screen</span> + QLineEdit <span class="hl opt">*</span> wMasterPassword<span class="hl opt">;</span> + QLineEdit <span class="hl opt">*</span> wName<span class="hl opt">;</span> + QSpinBox <span class="hl opt">*</span> wLength<span class="hl opt">;</span> + QLineEdit <span class="hl opt">*</span> wPassword<span class="hl opt">;</span> + QPushButton <span class="hl opt">*</span> wGenerate<span class="hl opt">;</span> + QPushButton <span class="hl opt">*</span> wCopy<span class="hl opt">;</span></pre> + + <p>Add slots for push buttons:</p> + + <pre class="hl"><span class="hl kwc">private</span> slots<span class="hl opt">:</span> + + <span class="hl slc">/// 'Generate' button clicked</span> + <span class="hl kwb">void</span> <span class="hl kwd">generateClicked</span><span class="hl opt">();</span> + + <span class="hl slc">/// 'Copy' button clicked</span> + <span class="hl kwb">void</span> <span class="hl kwd">copyClicked</span><span class="hl opt">();</span></pre> + + <p>The <tt>private</tt> keyword is ignored by the Qt meta-object compiler, but it is a good practice to have it here + as an indicator, that these slots are private and should not be used outside of the class.</p> + + <p>The <tt>Generate</tt> push button should be enabled only when the master password and name are given. Add another + slot that will be connected to the <tt>textChanged()</tt> signal from these widgets:</p> + + <pre class="hl"> + <span class="hl slc">/// Master password or name changed</span> + <span class="hl kwb">void</span> <span class="hl kwd">textChanged</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&);</span></pre> + + <p>And here is the final <tt>gui.h</tt> file:</p> + + <pre class="hl"><span class="hl com">/**</span> +<span class="hl com"> * @file PswGen/GUI/gui.h</span> +<span class="hl com"> */</span> +<span class="hl ppc">#ifndef __PSWGEN_GUI_GUI_H</span> +<span class="hl ppc"># define __PSWGEN_GUI_GUI_H</span> + +<span class="hl ppc">#include <Plugins/iPlugin></span> + +<span class="hl ppc">#include <QObject></span> +<span class="hl ppc">#include <QString></span> + +<span class="hl kwc">class</span> QLineEdit<span class="hl opt">;</span> +<span class="hl kwc">class</span> QSpinBox<span class="hl opt">;</span> +<span class="hl kwc">class</span> QPushButton<span class="hl opt">;</span> + +<span class="hl kwa">namespace</span> eVaf <span class="hl opt">{</span> +<span class="hl kwa">namespace</span> PswGen <span class="hl opt">{</span> + <span class="hl kwb">struct</span> iGenerator<span class="hl opt">;</span> + <span class="hl kwb">struct</span> iStorage<span class="hl opt">;</span> +<span class="hl kwa">namespace</span> GUI <span class="hl opt">{</span> + +<span class="hl com">/// Graphical User Interface for the PswGen application.</span> +<span class="hl kwc">class</span> Module <span class="hl opt">:</span> <span class="hl kwc">public</span> Plugins<span class="hl opt">::</span>iPlugin +<span class="hl opt">{</span> + Q_OBJECT + +<span class="hl kwc">public</span><span class="hl opt">:</span> + + <span class="hl kwd">Module</span><span class="hl opt">();</span> + + <span class="hl kwc">virtual</span> <span class="hl opt">~</span><span class="hl kwd">Module</span><span class="hl opt">();</span> + + <span class="hl kwc">virtual</span> <span class="hl kwb">bool</span> <span class="hl kwd">init</span><span class="hl opt">(</span><span class="hl kwb">const</span> QString <span class="hl opt">&</span> args<span class="hl opt">);</span> + + <span class="hl kwc">virtual</span> <span class="hl kwb">void</span> <span class="hl kwd">done</span><span class="hl opt">();</span> + + <span class="hl kwc">virtual</span> <span class="hl kwb">bool</span> <span class="hl kwd">isReady</span><span class="hl opt">()</span> <span class="hl kwb">const</span> <span class="hl opt">{</span> <span class="hl kwa">return</span> mReady<span class="hl opt">; }</span> + +<span class="hl kwc">private</span> slots<span class="hl opt">:</span> + + <span class="hl slc">/// Master password or name changed</span> + <span class="hl kwb">void</span> <span class="hl kwd">textChanged</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&);</span> + + <span class="hl slc">/// 'Generate' button clicked</span> + <span class="hl kwb">void</span> <span class="hl kwd">generateClicked</span><span class="hl opt">();</span> + + <span class="hl slc">/// 'Copy' button clicked</span> + <span class="hl kwb">void</span> <span class="hl kwd">copyClicked</span><span class="hl opt">();</span> + +<span class="hl kwc">private</span><span class="hl opt">:</span> <span class="hl slc">// Members</span> + + <span class="hl kwb">static int const</span> DefaultPasswordLength<span class="hl opt">;</span> + + <span class="hl slc">/// Flag indicating that the module is ready</span> + <span class="hl kwb">bool</span> mReady<span class="hl opt">;</span> + + <span class="hl slc">/// The iGenerator interface</span> + eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>iGenerator <span class="hl opt">*</span> mGenerator<span class="hl opt">;</span> + + <span class="hl slc">/// The iStorage interface (can be null)</span> + eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>iStorage <span class="hl opt">*</span> mStorage<span class="hl opt">;</span> + + <span class="hl slc">/// Widgets on the screen</span> + QLineEdit <span class="hl opt">*</span> wMasterPassword<span class="hl opt">;</span> + QLineEdit <span class="hl opt">*</span> wName<span class="hl opt">;</span> + QSpinBox <span class="hl opt">*</span> wLength<span class="hl opt">;</span> + QLineEdit <span class="hl opt">*</span> wPassword<span class="hl opt">;</span> + QPushButton <span class="hl opt">*</span> wGenerate<span class="hl opt">;</span> + QPushButton <span class="hl opt">*</span> wCopy<span class="hl opt">;</span> +<span class="hl opt">};</span> + +<span class="hl opt">}</span> <span class="hl slc">// namespace eVaf::PswGen::GUI</span> +<span class="hl opt">}</span> <span class="hl slc">// namespace eVaf::PswGen</span> +<span class="hl opt">}</span> <span class="hl slc">// namespace eVaf</span> + +<span class="hl ppc">#endif</span> <span class="hl slc">// gui.h</span><span class="hl ppc"></span> +</pre> + + <p>Continue implementing the <a href="pswgen10.html">GUI Module</a>.</p> + + </body> +</html> diff --git a/www/pswgen10.html b/www/pswgen10.html new file mode 100644 index 0000000..f1ea8e1 --- /dev/null +++ b/www/pswgen10.html @@ -0,0 +1,472 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html lang="et" xmlns="http://www.w3.org/1999/xhtml" xml:lang="et"> + + <head> + <meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" /> + <title>eVaf Tutorial - 10 - GUI Module</title> + <meta name="Author" content="Enar Väikene" /> + <meta name="description" content="eVaf Tutorial" /> + <meta name="keywords" content="evaf c++ application development framework tutorial password generator" /> + <link rel="StyleSheet" href="evaf.css" type="text/css" media="all" /> + <link rel="StyleSheet" href="highlight.css" type="text/css" media="all" /> + </head> + + <body> + + <h1>eVaf Tutorial</h1> + + <h2>10 - GUI Module</h2> + + <p>Create the <tt>gui.cpp</tt> file in the <tt>src/apps/PswGen/GUI</tt> directory:</p> + + <pre class="hl"><span class="hl com">/**</span> +<span class="hl com"> * @file PswGen/GUI/gui.cpp</span> +<span class="hl com"> */</span> + +<span class="hl ppc">#include</span> <span class="hl pps">"gui.h"</span><span class="hl ppc"></span> + +<span class="hl ppc">#include <QtGui></span></pre> + + <p>Copy version information files from the <tt>Storage</tt> module:</p> + + <pre>evaf/src/apps/PswGen/GUI $ <code>cp ../Storage/version.{h,rc} .</code></pre> + + <p>Modify the <tt>version.h</tt> file:</p> + + <pre class="hl"><span class="hl com">/**</span> +<span class="hl com"> * @file PswGen/GUI/version.h</span> +<span class="hl com"> */</span> + +<span class="hl ppc">#ifndef __PSWGEN_GUI_VERSION_H</span> +<span class="hl ppc"># define __PSWGEN_GUI_VERSION_H</span> + +<span class="hl ppc">#include <version_rc.h></span> + +<span class="hl com">/**</span> +<span class="hl com"> * Module/library version number in the form major,minor,release,build</span> +<span class="hl com"> */</span> +<span class="hl ppc">#define VER_FILE_VERSION 0,1,1,1</span> + +<span class="hl com">/**</span> +<span class="hl com"> * Module/library version number in the string format (shall end with \0)</span> +<span class="hl com"> */</span> +<span class="hl ppc">#define VER_FILE_VERSION_STR</span> <span class="hl pps">"0.1.1.2\0"</span><span class="hl ppc"></span> + +<span class="hl com">/**</span> +<span class="hl com"> * Module/library name (shall end with \0)</span> +<span class="hl com"> */</span> +<span class="hl ppc">#define VER_MODULE_NAME_STR</span> <span class="hl pps">"PswGui\0"</span><span class="hl ppc"></span> + +<span class="hl com">/**</span> +<span class="hl com"> * Module type (see version_rc.h for all the types)</span> +<span class="hl com"> */</span> +<span class="hl ppc">#define VER_MODULE_TYPE MT_GENERIC</span> + +<span class="hl com">/**</span> +<span class="hl com"> * Module type in the string format (see version_rc for all the types)</span> +<span class="hl com"> */</span> +<span class="hl ppc">#define VER_MODULE_TYPE_STR MT_GENERIC</span> + +<span class="hl com">/**</span> +<span class="hl com"> * Original file name for windows (shall end with \0)</span> +<span class="hl com"> */</span> +<span class="hl ppc">#define VER_ORIGINAL_FILE_NAME_STR</span> <span class="hl pps">"PswGui.dll\0"</span><span class="hl ppc"></span> + +<span class="hl com">/**</span> +<span class="hl com"> * Description of the module/library (shall end with \0)</span> +<span class="hl com"> */</span> +<span class="hl ppc">#define VER_FILE_DESCRIPTION_STR</span> <span class="hl pps">"User interface for the PswGen application.\0"</span><span class="hl ppc"></span> + +<span class="hl ppc">#endif</span> <span class="hl slc">// version.h</span><span class="hl ppc"></span></pre> + + <p>Include the <tt>version.h</tt> header file in the <tt>gui.cpp</tt> file and export version information:</p> + + <pre class="hl"><span class="hl ppc">#include</span> <span class="hl pps">"version.h"</span><span class="hl ppc"></span> +<span class="hl kwd">VER_EXPORT_VERSION_INFO</span><span class="hl opt">()</span></pre> + + <p>Use the <tt>Q_EXPORT_PLUGIN2()</tt> macro to make it a Qt plugin:</p> + + <pre class="hl"><span class="hl kwd">Q_EXPORT_PLUGIN2</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">,</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>GUI<span class="hl opt">::</span>Module<span class="hl opt">)</span></pre> + + <p>The main job of setting up the user interface is done in the <tt>init()</tt> function and our constructor and destructor are + very simple:</p> + + <pre class="hl">Module<span class="hl opt">::</span><span class="hl kwd">Module</span><span class="hl opt">()</span> + <span class="hl opt">:</span> Plugins<span class="hl opt">::</span><span class="hl kwd">iPlugin</span><span class="hl opt">()</span> + <span class="hl opt">,</span> <span class="hl kwd">mReady</span><span class="hl opt">(</span><span class="hl kwa">false</span><span class="hl opt">)</span> + <span class="hl opt">,</span> <span class="hl kwd">mGenerator</span><span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">)</span> + <span class="hl opt">,</span> <span class="hl kwd">mStorage</span><span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">)</span> +<span class="hl opt">{</span> + <span class="hl kwd">setObjectName</span><span class="hl opt">(</span><span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">"%1.%2"</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>__FUNCTION__<span class="hl opt">));</span> + + <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">"%s created"</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span> +<span class="hl opt">}</span> + +Module<span class="hl opt">::~</span><span class="hl kwd">Module</span><span class="hl opt">()</span> +<span class="hl opt">{</span> + <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">"%s destroyed"</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span> +<span class="hl opt">}</span></pre> + + <p>The <tt>init()</tt> function:</p> + + <ol> + <li>Queries and stores interfaces implemented in other modules. The <tt>iGenerator</tt> interface must be implemented; + the <tt>iStorage</tt> interface is optional and we can work without it.</li> + <li>Gets the main window interface <tt>iSdiWindow</tt>.</li> + <li>Creates the layout for the main window widget and adds our widgets to the layout.</li> + <li>Connects signals on widgets to slots in this class.</li> + <li>Uses actions <tt>QAction</tt> to add keyboard shortcuts -- <tt>Enter</tt> key generates a password and <tt>Esc</tt> key + quits the application.</li> + <li>Sets the <tt>mReady</tt> flag to true when all this is done.</li> + </ol> + + <pre class="hl"><span class="hl kwb">bool</span> Module<span class="hl opt">::</span><span class="hl kwd">init</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&</span> args<span class="hl opt">)</span> +<span class="hl opt">{</span> + <span class="hl kwd">Q_UNUSED</span><span class="hl opt">(</span>args<span class="hl opt">);</span> + + <span class="hl slc">// Get the iGenerator interface</span> + <span class="hl kwd">EVAF_TEST_X</span><span class="hl opt">((</span>mGenerator <span class="hl opt">=</span> evafQueryInterface<span class="hl opt"><</span>PswGen<span class="hl opt">::</span>iGenerator<span class="hl opt">>(</span><span class="hl str">"iGenerator"</span><span class="hl opt">)),</span> <span class="hl str">"No iGenerator interface"</span><span class="hl opt">);</span> + + <span class="hl slc">// Get the iStorage interface (can be null)</span> + mStorage <span class="hl opt">=</span> evafQueryInterface<span class="hl opt"><</span>PswGen<span class="hl opt">::</span>iStorage<span class="hl opt">>(</span><span class="hl str">"iStorage"</span><span class="hl opt">);</span> + <span class="hl kwa">if</span> <span class="hl opt">(!</span>mStorage<span class="hl opt">)</span> + <span class="hl kwd">EVAF_WARNING</span><span class="hl opt">(</span><span class="hl str">"No iStorage interface"</span><span class="hl opt">);</span> + + <span class="hl slc">// Get the main window interface and fill it with widgets</span> + SdiWindow<span class="hl opt">::</span>iSdiWindow <span class="hl opt">*</span> win <span class="hl opt">=</span> evafQueryInterface<span class="hl opt"><</span>SdiWindow<span class="hl opt">::</span>iSdiWindow<span class="hl opt">>(</span><span class="hl str">"iSdiWindow"</span><span class="hl opt">);</span> + <span class="hl kwd">EVAF_TEST_X</span><span class="hl opt">(</span>win<span class="hl opt">,</span> <span class="hl str">"No iSdiWindow interface"</span><span class="hl opt">);</span> + + QVBoxLayout <span class="hl opt">*</span> v <span class="hl opt">=</span> <span class="hl kwa">new</span> QVBoxLayout<span class="hl opt">;</span> + win<span class="hl opt">-></span><span class="hl kwd">widget</span><span class="hl opt">()-></span><span class="hl kwd">setLayout</span><span class="hl opt">(</span>v<span class="hl opt">);</span> + + QGridLayout <span class="hl opt">*</span> g <span class="hl opt">=</span> <span class="hl kwa">new</span> QGridLayout<span class="hl opt">;</span> + v<span class="hl opt">-></span><span class="hl kwd">addLayout</span><span class="hl opt">(</span>g<span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">setColumnStretch</span><span class="hl opt">(</span><span class="hl num">2</span><span class="hl opt">,</span> <span class="hl num">2</span><span class="hl opt">);</span> + + QLabel <span class="hl opt">*</span> l <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QLabel</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"Master &password:"</span><span class="hl opt">,</span> VER_MODULE_NAME_STR<span class="hl opt">));</span> + l<span class="hl opt">-></span><span class="hl kwd">setAlignment</span><span class="hl opt">(</span>Qt<span class="hl opt">::</span>AlignRight<span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>l<span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">);</span> + + wMasterPassword <span class="hl opt">=</span> <span class="hl kwa">new</span> QLineEdit<span class="hl opt">;</span> + l<span class="hl opt">-></span><span class="hl kwd">setBuddy</span><span class="hl opt">(</span>wMasterPassword<span class="hl opt">);</span> + <span class="hl kwd">connect</span><span class="hl opt">(</span>wMasterPassword<span class="hl opt">,</span> <span class="hl kwd">SIGNAL</span><span class="hl opt">(</span><span class="hl kwd">textChanged</span><span class="hl opt">(</span>QString<span class="hl opt">)),</span> <span class="hl kwa">this</span><span class="hl opt">,</span> <span class="hl kwd">SLOT</span><span class="hl opt">(</span><span class="hl kwd">textChanged</span><span class="hl opt">(</span>QString<span class="hl opt">)));</span> + wMasterPassword<span class="hl opt">-></span><span class="hl kwd">setEchoMode</span><span class="hl opt">(</span>QLineEdit<span class="hl opt">::</span>Password<span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>wMasterPassword<span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">2</span><span class="hl opt">);</span> + + l <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QLabel</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"Web site or application &name:"</span><span class="hl opt">,</span> VER_MODULE_NAME_STR<span class="hl opt">));</span> + l<span class="hl opt">-></span><span class="hl kwd">setAlignment</span><span class="hl opt">(</span>Qt<span class="hl opt">::</span>AlignRight<span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>l<span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">);</span> + + wName <span class="hl opt">=</span> <span class="hl kwa">new</span> QLineEdit<span class="hl opt">;</span> + l<span class="hl opt">-></span><span class="hl kwd">setBuddy</span><span class="hl opt">(</span>wName<span class="hl opt">);</span> + <span class="hl kwa">if</span> <span class="hl opt">(</span>mStorage<span class="hl opt">) {</span> + QCompleter <span class="hl opt">*</span> completer <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QCompleter</span><span class="hl opt">(</span>wName<span class="hl opt">);</span> + completer<span class="hl opt">-></span><span class="hl kwd">setModel</span><span class="hl opt">(</span>mStorage<span class="hl opt">-></span><span class="hl kwd">autoCompletionModel</span><span class="hl opt">());</span> + completer<span class="hl opt">-></span><span class="hl kwd">setCompletionMode</span><span class="hl opt">(</span>QCompleter<span class="hl opt">::</span>InlineCompletion<span class="hl opt">);</span> + wName<span class="hl opt">-></span><span class="hl kwd">setCompleter</span><span class="hl opt">(</span>completer<span class="hl opt">);</span> + <span class="hl opt">}</span> + <span class="hl kwd">connect</span><span class="hl opt">(</span>wName<span class="hl opt">,</span> <span class="hl kwd">SIGNAL</span><span class="hl opt">(</span><span class="hl kwd">textChanged</span><span class="hl opt">(</span>QString<span class="hl opt">)),</span> <span class="hl kwa">this</span><span class="hl opt">,</span> <span class="hl kwd">SLOT</span><span class="hl opt">(</span><span class="hl kwd">textChanged</span><span class="hl opt">(</span>QString<span class="hl opt">)));</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>wName<span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">2</span><span class="hl opt">);</span> + win<span class="hl opt">-></span><span class="hl kwd">widget</span><span class="hl opt">()-></span><span class="hl kwd">setFocusProxy</span><span class="hl opt">(</span>wName<span class="hl opt">);</span> + + l <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QLabel</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"&Length of the password:"</span><span class="hl opt">,</span> VER_MODULE_NAME_STR<span class="hl opt">));</span> + l<span class="hl opt">-></span><span class="hl kwd">setAlignment</span><span class="hl opt">(</span>Qt<span class="hl opt">::</span>AlignRight<span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>l<span class="hl opt">,</span> <span class="hl num">2</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">);</span> + + wLength <span class="hl opt">=</span> <span class="hl kwa">new</span> QSpinBox<span class="hl opt">;</span> + l<span class="hl opt">-></span><span class="hl kwd">setBuddy</span><span class="hl opt">(</span>wLength<span class="hl opt">);</span> + wLength<span class="hl opt">-></span><span class="hl kwd">setRange</span><span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">,</span> mGenerator<span class="hl opt">-></span><span class="hl kwd">maxLength</span><span class="hl opt">());</span> + wLength<span class="hl opt">-></span><span class="hl kwd">setValue</span><span class="hl opt">(</span>DefaultPasswordLength<span class="hl opt">);</span> + wLength<span class="hl opt">-></span><span class="hl kwd">setSpecialValueText</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"Maximum"</span><span class="hl opt">,</span> VER_MODULE_NAME_STR<span class="hl opt">));</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>wLength<span class="hl opt">,</span> <span class="hl num">2</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">);</span> + + l <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QLabel</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"Password:"</span><span class="hl opt">));</span> + l<span class="hl opt">-></span><span class="hl kwd">setAlignment</span><span class="hl opt">(</span>Qt<span class="hl opt">::</span>AlignRight<span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>l<span class="hl opt">,</span> <span class="hl num">3</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">);</span> + + wPassword <span class="hl opt">=</span> <span class="hl kwa">new</span> QLineEdit<span class="hl opt">;</span> + wPassword<span class="hl opt">-></span><span class="hl kwd">setReadOnly</span><span class="hl opt">(</span><span class="hl kwa">true</span><span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>wPassword<span class="hl opt">,</span> <span class="hl num">3</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">2</span><span class="hl opt">);</span> + + v<span class="hl opt">-></span><span class="hl kwd">addStretch</span><span class="hl opt">();</span> + + QHBoxLayout <span class="hl opt">*</span> h <span class="hl opt">=</span> <span class="hl kwa">new</span> QHBoxLayout<span class="hl opt">;</span> + h<span class="hl opt">-></span><span class="hl kwd">addStretch</span><span class="hl opt">();</span> + v<span class="hl opt">-></span><span class="hl kwd">addLayout</span><span class="hl opt">(</span>h<span class="hl opt">);</span> + + wGenerate <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QPushButton</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"&Generate"</span><span class="hl opt">,</span> VER_MODULE_NAME_STR<span class="hl opt">));</span> + wGenerate<span class="hl opt">-></span><span class="hl kwd">setDisabled</span><span class="hl opt">(</span><span class="hl kwa">true</span><span class="hl opt">);</span> + wGenerate<span class="hl opt">-></span><span class="hl kwd">setDefault</span><span class="hl opt">(</span><span class="hl kwa">true</span><span class="hl opt">);</span> + <span class="hl kwd">connect</span><span class="hl opt">(</span>wGenerate<span class="hl opt">,</span> <span class="hl kwd">SIGNAL</span><span class="hl opt">(</span><span class="hl kwd">clicked</span><span class="hl opt">()),</span> <span class="hl kwa">this</span><span class="hl opt">,</span> <span class="hl kwd">SLOT</span><span class="hl opt">(</span><span class="hl kwd">generateClicked</span><span class="hl opt">()));</span> + h<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>wGenerate<span class="hl opt">);</span> + + wCopy <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QPushButton</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"&Copy to Clipboard"</span><span class="hl opt">,</span> VER_MODULE_NAME_STR<span class="hl opt">));</span> + wCopy<span class="hl opt">-></span><span class="hl kwd">setDisabled</span><span class="hl opt">(</span><span class="hl kwa">true</span><span class="hl opt">);</span> + <span class="hl kwd">connect</span><span class="hl opt">(</span>wCopy<span class="hl opt">,</span> <span class="hl kwd">SIGNAL</span><span class="hl opt">(</span><span class="hl kwd">clicked</span><span class="hl opt">()),</span> <span class="hl kwa">this</span><span class="hl opt">,</span> <span class="hl kwd">SLOT</span><span class="hl opt">(</span><span class="hl kwd">copyClicked</span><span class="hl opt">()));</span> + h<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>wCopy<span class="hl opt">);</span> + + QAction <span class="hl opt">*</span> a <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QAction</span><span class="hl opt">(</span>win<span class="hl opt">-></span><span class="hl kwd">widget</span><span class="hl opt">());</span> + a<span class="hl opt">-></span><span class="hl kwd">setShortcut</span><span class="hl opt">(</span>Qt<span class="hl opt">::</span>Key_Return<span class="hl opt">);</span> + <span class="hl kwd">connect</span><span class="hl opt">(</span>a<span class="hl opt">,</span> <span class="hl kwd">SIGNAL</span><span class="hl opt">(</span><span class="hl kwd">triggered</span><span class="hl opt">()),</span> <span class="hl kwa">this</span><span class="hl opt">,</span> <span class="hl kwd">SLOT</span><span class="hl opt">(</span><span class="hl kwd">generateClicked</span><span class="hl opt">()));</span> + win<span class="hl opt">-></span><span class="hl kwd">widget</span><span class="hl opt">()-></span><span class="hl kwd">addAction</span><span class="hl opt">(</span>a<span class="hl opt">);</span> + + a <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QAction</span><span class="hl opt">(</span>win<span class="hl opt">-></span><span class="hl kwd">widget</span><span class="hl opt">());</span> + a<span class="hl opt">-></span><span class="hl kwd">setShortcut</span><span class="hl opt">(</span>Qt<span class="hl opt">::</span>Key_Escape<span class="hl opt">);</span> + <span class="hl kwd">connect</span><span class="hl opt">(</span>a<span class="hl opt">,</span> <span class="hl kwd">SIGNAL</span><span class="hl opt">(</span><span class="hl kwd">triggered</span><span class="hl opt">()),</span> qApp<span class="hl opt">,</span> <span class="hl kwd">SLOT</span><span class="hl opt">(</span><span class="hl kwd">quit</span><span class="hl opt">()));</span> + win<span class="hl opt">-></span><span class="hl kwd">widget</span><span class="hl opt">()-></span><span class="hl kwd">addAction</span><span class="hl opt">(</span>a<span class="hl opt">);</span> + + mReady <span class="hl opt">=</span> <span class="hl kwa">true</span><span class="hl opt">;</span> + + <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">"%s initialized"</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span> + + <span class="hl kwa">return true</span><span class="hl opt">;</span> +<span class="hl opt">}</span></pre> + + <p>The <tt>done()</tt> function simply sets the <tt>mReady</tt> flag back to <tt>false</tt>:</p> + + <pre class="hl"><span class="hl kwb">void</span> Module<span class="hl opt">::</span><span class="hl kwd">done</span><span class="hl opt">()</span> +<span class="hl opt">{</span> + mReady <span class="hl opt">=</span> <span class="hl kwa">false</span><span class="hl opt">;</span> + + <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">"%s finalized"</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span> +<span class="hl opt">}</span></pre> + + <p>The <tt>Generate</tt> push button is disabled by default. We connected <tt>textChanged()</tt> signals to the <tt>textChanged()</tt> slot, where we enable the <tt>Generate</tt> push button if master password and name fields are not empty.</p> + + <p>We can also query for stored passwords and update fields on the window with data from the storage. The <tt>iStorage::query()</tt> + method can return an empty shared data pointer and we have to check for it before using fields in the shared data object.</p> + + <pre class="hl"><span class="hl kwb">void</span> Module<span class="hl opt">::</span><span class="hl kwd">textChanged</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&)</span> +<span class="hl opt">{</span> + wGenerate<span class="hl opt">-></span><span class="hl kwd">setDisabled</span><span class="hl opt">(</span>wMasterPassword<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">().</span><span class="hl kwd">isEmpty</span><span class="hl opt">() ||</span> wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">().</span><span class="hl kwd">isEmpty</span><span class="hl opt">());</span> + <span class="hl kwa">if</span> <span class="hl opt">(!</span>wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">().</span><span class="hl kwd">isEmpty</span><span class="hl opt">() &&</span> mStorage<span class="hl opt">) {</span> + QExplicitlySharedDataPointer<span class="hl opt"><</span>PswGen<span class="hl opt">::</span>Storage<span class="hl opt">::</span>Data<span class="hl opt">></span> data <span class="hl opt">=</span> mStorage<span class="hl opt">-></span><span class="hl kwd">query</span><span class="hl opt">(</span>wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">());</span> + <span class="hl kwa">if</span> <span class="hl opt">(</span>data<span class="hl opt">)</span> + wLength<span class="hl opt">-></span><span class="hl kwd">setValue</span><span class="hl opt">(</span>data<span class="hl opt">-></span><span class="hl kwd">length</span><span class="hl opt">());</span> + <span class="hl opt">}</span> +<span class="hl opt">}</span></pre> + + <p>The <tt>generateClicked()</tt> slot is connected to the <tt>Generate</tt> push button and also to the <tt>Enter</tt> key + action. The push button is disabled if master password or name fields are empty, but not the <tt>Enter</tt> key action and + we need to check for it once more.</p> + + <p>Then we generate the password using the <tt>iGenerator::generatePassword()</tt> method and show it on the window. We also + enable the <tt>Copy to Clipboard</tt> push button.</p> + + <p>If we have the <tt>iStorage</tt>, we either store the new data record or update an existing one in the storage.</p> + + <pre class="hl"><span class="hl kwb">void</span> Module<span class="hl opt">::</span><span class="hl kwd">generateClicked</span><span class="hl opt">()</span> +<span class="hl opt">{</span> + <span class="hl kwa">if</span> <span class="hl opt">(</span>wMasterPassword<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">().</span><span class="hl kwd">isEmpty</span><span class="hl opt">() ||</span> wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">().</span><span class="hl kwd">isEmpty</span><span class="hl opt">())</span> + <span class="hl kwa">return</span><span class="hl opt">;</span> + wPassword<span class="hl opt">-></span><span class="hl kwd">setText</span><span class="hl opt">(</span>mGenerator<span class="hl opt">-></span><span class="hl kwd">generatePassword</span><span class="hl opt">(</span>wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">(),</span> wMasterPassword<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">(),</span> wLength<span class="hl opt">-></span><span class="hl kwd">value</span><span class="hl opt">()));</span> + wCopy<span class="hl opt">-></span><span class="hl kwd">setEnabled</span><span class="hl opt">(</span><span class="hl kwa">true</span><span class="hl opt">);</span> + <span class="hl kwa">if</span> <span class="hl opt">(</span>mStorage<span class="hl opt">) {</span> + QExplicitlySharedDataPointer<span class="hl opt"><</span>PswGen<span class="hl opt">::</span>Storage<span class="hl opt">::</span>Data<span class="hl opt">></span> data <span class="hl opt">=</span> mStorage<span class="hl opt">-></span><span class="hl kwd">query</span><span class="hl opt">(</span>wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">());</span> + <span class="hl kwa">if</span> <span class="hl opt">(!</span>data<span class="hl opt">)</span> + data <span class="hl opt">=</span> <span class="hl kwa">new</span> Storage<span class="hl opt">::</span><span class="hl kwd">Data</span><span class="hl opt">(</span>wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">(),</span> wLength<span class="hl opt">-></span><span class="hl kwd">value</span><span class="hl opt">());</span> + <span class="hl kwa">else</span> + data<span class="hl opt">-></span><span class="hl kwd">setLength</span><span class="hl opt">(</span>wLength<span class="hl opt">-></span><span class="hl kwd">value</span><span class="hl opt">());</span> + mStorage<span class="hl opt">-></span><span class="hl kwd">save</span><span class="hl opt">(</span>wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">(),</span> data<span class="hl opt">);</span> + <span class="hl opt">}</span> +<span class="hl opt">}</span></pre> + + <p>The final method in our module is the <tt>copyClicked()</tt> slot, which simply copies anything from the generated password + field to the clipboard:</p> + + <pre class="hl"><span class="hl kwb">void</span> Module<span class="hl opt">::</span><span class="hl kwd">copyClicked</span><span class="hl opt">()</span> +<span class="hl opt">{</span> + QClipboard <span class="hl opt">*</span> clipboard <span class="hl opt">=</span> QApplication<span class="hl opt">::</span><span class="hl kwd">clipboard</span><span class="hl opt">();</span> + <span class="hl kwa">if</span> <span class="hl opt">(</span>clipboard<span class="hl opt">)</span> + clipboard<span class="hl opt">-></span><span class="hl kwd">setText</span><span class="hl opt">(</span>wPassword<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">());</span> +<span class="hl opt">}</span></pre> + + <p>Here is the final <tt>gui.cpp</tt> file:</p> + + <pre class="hl"><span class="hl com">/**</span> +<span class="hl com"> * @file PswGen/GUI/gui.cpp</span> +<span class="hl com"> */</span> + +<span class="hl ppc">#include</span> <span class="hl pps">"gui.h"</span><span class="hl ppc"></span> +<span class="hl ppc">#include</span> <span class="hl pps">"version.h"</span><span class="hl ppc"></span> + +<span class="hl ppc">#include</span> <span class="hl pps">"Generator/iGenerator"</span><span class="hl ppc"></span> +<span class="hl ppc">#include</span> <span class="hl pps">"Storage/iStorage"</span><span class="hl ppc"></span> + +<span class="hl ppc">#include <Common/Globals></span> +<span class="hl ppc">#include <Common/iLogger></span> +<span class="hl ppc">#include <Common/iRegistry></span> +<span class="hl ppc">#include <SdiWindow/iSdiWindow></span> + +<span class="hl ppc">#include <QtGui></span> + +<span class="hl kwd">VER_EXPORT_VERSION_INFO</span><span class="hl opt">()</span> +<span class="hl kwd">Q_EXPORT_PLUGIN2</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">,</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>GUI<span class="hl opt">::</span>Module<span class="hl opt">)</span> + +<span class="hl kwa">using namespace</span> eVaf<span class="hl opt">;</span> +<span class="hl kwa">using namespace</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>GUI<span class="hl opt">;</span> + +<span class="hl kwb">int const</span> Module<span class="hl opt">::</span>DefaultPasswordLength <span class="hl opt">=</span> <span class="hl num">16</span><span class="hl opt">;</span> + +Module<span class="hl opt">::</span><span class="hl kwd">Module</span><span class="hl opt">()</span> + <span class="hl opt">:</span> Plugins<span class="hl opt">::</span><span class="hl kwd">iPlugin</span><span class="hl opt">()</span> + <span class="hl opt">,</span> <span class="hl kwd">mReady</span><span class="hl opt">(</span><span class="hl kwa">false</span><span class="hl opt">)</span> + <span class="hl opt">,</span> <span class="hl kwd">mGenerator</span><span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">)</span> + <span class="hl opt">,</span> <span class="hl kwd">mStorage</span><span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">)</span> +<span class="hl opt">{</span> + <span class="hl kwd">setObjectName</span><span class="hl opt">(</span><span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">"%1.%2"</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>__FUNCTION__<span class="hl opt">));</span> + + <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">"%s created"</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span> +<span class="hl opt">}</span> + +Module<span class="hl opt">::~</span><span class="hl kwd">Module</span><span class="hl opt">()</span> +<span class="hl opt">{</span> + <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">"%s destroyed"</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span> +<span class="hl opt">}</span> + +<span class="hl kwb">bool</span> Module<span class="hl opt">::</span><span class="hl kwd">init</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&</span> args<span class="hl opt">)</span> +<span class="hl opt">{</span> + <span class="hl kwd">Q_UNUSED</span><span class="hl opt">(</span>args<span class="hl opt">);</span> + + <span class="hl slc">// Get the iGenerator interface</span> + <span class="hl kwd">EVAF_TEST_X</span><span class="hl opt">((</span>mGenerator <span class="hl opt">=</span> evafQueryInterface<span class="hl opt"><</span>PswGen<span class="hl opt">::</span>iGenerator<span class="hl opt">>(</span><span class="hl str">"iGenerator"</span><span class="hl opt">)),</span> <span class="hl str">"No iGenerator interface"</span><span class="hl opt">);</span> + + <span class="hl slc">// Get the iStorage interface (can be null)</span> + mStorage <span class="hl opt">=</span> evafQueryInterface<span class="hl opt"><</span>PswGen<span class="hl opt">::</span>iStorage<span class="hl opt">>(</span><span class="hl str">"iStorage"</span><span class="hl opt">);</span> + <span class="hl kwa">if</span> <span class="hl opt">(!</span>mStorage<span class="hl opt">)</span> + <span class="hl kwd">EVAF_WARNING</span><span class="hl opt">(</span><span class="hl str">"No iStorage interface"</span><span class="hl opt">);</span> + + <span class="hl slc">// Get the main window interface and fill it with the widgets</span> + SdiWindow<span class="hl opt">::</span>iSdiWindow <span class="hl opt">*</span> win <span class="hl opt">=</span> evafQueryInterface<span class="hl opt"><</span>SdiWindow<span class="hl opt">::</span>iSdiWindow<span class="hl opt">>(</span><span class="hl str">"iSdiWindow"</span><span class="hl opt">);</span> + <span class="hl kwd">EVAF_TEST_X</span><span class="hl opt">(</span>win<span class="hl opt">,</span> <span class="hl str">"No iSdiWindow interface"</span><span class="hl opt">);</span> + + QVBoxLayout <span class="hl opt">*</span> v <span class="hl opt">=</span> <span class="hl kwa">new</span> QVBoxLayout<span class="hl opt">;</span> + win<span class="hl opt">-></span><span class="hl kwd">widget</span><span class="hl opt">()-></span><span class="hl kwd">setLayout</span><span class="hl opt">(</span>v<span class="hl opt">);</span> + + QGridLayout <span class="hl opt">*</span> g <span class="hl opt">=</span> <span class="hl kwa">new</span> QGridLayout<span class="hl opt">;</span> + v<span class="hl opt">-></span><span class="hl kwd">addLayout</span><span class="hl opt">(</span>g<span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">setColumnStretch</span><span class="hl opt">(</span><span class="hl num">2</span><span class="hl opt">,</span> <span class="hl num">2</span><span class="hl opt">);</span> + + QLabel <span class="hl opt">*</span> l <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QLabel</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"Master &password:"</span><span class="hl opt">,</span> VER_MODULE_NAME_STR<span class="hl opt">));</span> + l<span class="hl opt">-></span><span class="hl kwd">setAlignment</span><span class="hl opt">(</span>Qt<span class="hl opt">::</span>AlignRight<span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>l<span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">);</span> + + wMasterPassword <span class="hl opt">=</span> <span class="hl kwa">new</span> QLineEdit<span class="hl opt">;</span> + l<span class="hl opt">-></span><span class="hl kwd">setBuddy</span><span class="hl opt">(</span>wMasterPassword<span class="hl opt">);</span> + <span class="hl kwd">connect</span><span class="hl opt">(</span>wMasterPassword<span class="hl opt">,</span> <span class="hl kwd">SIGNAL</span><span class="hl opt">(</span><span class="hl kwd">textChanged</span><span class="hl opt">(</span>QString<span class="hl opt">)),</span> <span class="hl kwa">this</span><span class="hl opt">,</span> <span class="hl kwd">SLOT</span><span class="hl opt">(</span><span class="hl kwd">textChanged</span><span class="hl opt">(</span>QString<span class="hl opt">)));</span> + wMasterPassword<span class="hl opt">-></span><span class="hl kwd">setEchoMode</span><span class="hl opt">(</span>QLineEdit<span class="hl opt">::</span>Password<span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>wMasterPassword<span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">2</span><span class="hl opt">);</span> + + l <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QLabel</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"Web site or application &name:"</span><span class="hl opt">,</span> VER_MODULE_NAME_STR<span class="hl opt">));</span> + l<span class="hl opt">-></span><span class="hl kwd">setAlignment</span><span class="hl opt">(</span>Qt<span class="hl opt">::</span>AlignRight<span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>l<span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">);</span> + + wName <span class="hl opt">=</span> <span class="hl kwa">new</span> QLineEdit<span class="hl opt">;</span> + l<span class="hl opt">-></span><span class="hl kwd">setBuddy</span><span class="hl opt">(</span>wName<span class="hl opt">);</span> + <span class="hl kwa">if</span> <span class="hl opt">(</span>mStorage<span class="hl opt">) {</span> + QCompleter <span class="hl opt">*</span> completer <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QCompleter</span><span class="hl opt">(</span>wName<span class="hl opt">);</span> + completer<span class="hl opt">-></span><span class="hl kwd">setModel</span><span class="hl opt">(</span>mStorage<span class="hl opt">-></span><span class="hl kwd">autoCompletionModel</span><span class="hl opt">());</span> + completer<span class="hl opt">-></span><span class="hl kwd">setCompletionMode</span><span class="hl opt">(</span>QCompleter<span class="hl opt">::</span>InlineCompletion<span class="hl opt">);</span> + wName<span class="hl opt">-></span><span class="hl kwd">setCompleter</span><span class="hl opt">(</span>completer<span class="hl opt">);</span> + <span class="hl opt">}</span> + <span class="hl kwd">connect</span><span class="hl opt">(</span>wName<span class="hl opt">,</span> <span class="hl kwd">SIGNAL</span><span class="hl opt">(</span><span class="hl kwd">textChanged</span><span class="hl opt">(</span>QString<span class="hl opt">)),</span> <span class="hl kwa">this</span><span class="hl opt">,</span> <span class="hl kwd">SLOT</span><span class="hl opt">(</span><span class="hl kwd">textChanged</span><span class="hl opt">(</span>QString<span class="hl opt">)));</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>wName<span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">2</span><span class="hl opt">);</span> + win<span class="hl opt">-></span><span class="hl kwd">widget</span><span class="hl opt">()-></span><span class="hl kwd">setFocusProxy</span><span class="hl opt">(</span>wName<span class="hl opt">);</span> + + l <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QLabel</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"&Length of the password:"</span><span class="hl opt">,</span> VER_MODULE_NAME_STR<span class="hl opt">));</span> + l<span class="hl opt">-></span><span class="hl kwd">setAlignment</span><span class="hl opt">(</span>Qt<span class="hl opt">::</span>AlignRight<span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>l<span class="hl opt">,</span> <span class="hl num">2</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">);</span> + + wLength <span class="hl opt">=</span> <span class="hl kwa">new</span> QSpinBox<span class="hl opt">;</span> + l<span class="hl opt">-></span><span class="hl kwd">setBuddy</span><span class="hl opt">(</span>wLength<span class="hl opt">);</span> + wLength<span class="hl opt">-></span><span class="hl kwd">setRange</span><span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">,</span> mGenerator<span class="hl opt">-></span><span class="hl kwd">maxLength</span><span class="hl opt">());</span> + wLength<span class="hl opt">-></span><span class="hl kwd">setValue</span><span class="hl opt">(</span>DefaultPasswordLength<span class="hl opt">);</span> + wLength<span class="hl opt">-></span><span class="hl kwd">setSpecialValueText</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"Maximum"</span><span class="hl opt">,</span> VER_MODULE_NAME_STR<span class="hl opt">));</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>wLength<span class="hl opt">,</span> <span class="hl num">2</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">);</span> + + l <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QLabel</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"Password:"</span><span class="hl opt">));</span> + l<span class="hl opt">-></span><span class="hl kwd">setAlignment</span><span class="hl opt">(</span>Qt<span class="hl opt">::</span>AlignRight<span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>l<span class="hl opt">,</span> <span class="hl num">3</span><span class="hl opt">,</span> <span class="hl num">0</span><span class="hl opt">);</span> + + wPassword <span class="hl opt">=</span> <span class="hl kwa">new</span> QLineEdit<span class="hl opt">;</span> + wPassword<span class="hl opt">-></span><span class="hl kwd">setReadOnly</span><span class="hl opt">(</span><span class="hl kwa">true</span><span class="hl opt">);</span> + g<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>wPassword<span class="hl opt">,</span> <span class="hl num">3</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">1</span><span class="hl opt">,</span> <span class="hl num">2</span><span class="hl opt">);</span> + + v<span class="hl opt">-></span><span class="hl kwd">addStretch</span><span class="hl opt">();</span> + + QHBoxLayout <span class="hl opt">*</span> h <span class="hl opt">=</span> <span class="hl kwa">new</span> QHBoxLayout<span class="hl opt">;</span> + h<span class="hl opt">-></span><span class="hl kwd">addStretch</span><span class="hl opt">();</span> + v<span class="hl opt">-></span><span class="hl kwd">addLayout</span><span class="hl opt">(</span>h<span class="hl opt">);</span> + + wGenerate <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QPushButton</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"&Generate"</span><span class="hl opt">,</span> VER_MODULE_NAME_STR<span class="hl opt">));</span> + wGenerate<span class="hl opt">-></span><span class="hl kwd">setDisabled</span><span class="hl opt">(</span><span class="hl kwa">true</span><span class="hl opt">);</span> + wGenerate<span class="hl opt">-></span><span class="hl kwd">setDefault</span><span class="hl opt">(</span><span class="hl kwa">true</span><span class="hl opt">);</span> + <span class="hl kwd">connect</span><span class="hl opt">(</span>wGenerate<span class="hl opt">,</span> <span class="hl kwd">SIGNAL</span><span class="hl opt">(</span><span class="hl kwd">clicked</span><span class="hl opt">()),</span> <span class="hl kwa">this</span><span class="hl opt">,</span> <span class="hl kwd">SLOT</span><span class="hl opt">(</span><span class="hl kwd">generateClicked</span><span class="hl opt">()));</span> + h<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>wGenerate<span class="hl opt">);</span> + + wCopy <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QPushButton</span><span class="hl opt">(</span><span class="hl kwd">tr</span><span class="hl opt">(</span><span class="hl str">"&Copy to Clipboard"</span><span class="hl opt">,</span> VER_MODULE_NAME_STR<span class="hl opt">));</span> + wCopy<span class="hl opt">-></span><span class="hl kwd">setDisabled</span><span class="hl opt">(</span><span class="hl kwa">true</span><span class="hl opt">);</span> + <span class="hl kwd">connect</span><span class="hl opt">(</span>wCopy<span class="hl opt">,</span> <span class="hl kwd">SIGNAL</span><span class="hl opt">(</span><span class="hl kwd">clicked</span><span class="hl opt">()),</span> <span class="hl kwa">this</span><span class="hl opt">,</span> <span class="hl kwd">SLOT</span><span class="hl opt">(</span><span class="hl kwd">copyClicked</span><span class="hl opt">()));</span> + h<span class="hl opt">-></span><span class="hl kwd">addWidget</span><span class="hl opt">(</span>wCopy<span class="hl opt">);</span> + + QAction <span class="hl opt">*</span> a <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QAction</span><span class="hl opt">(</span>win<span class="hl opt">-></span><span class="hl kwd">widget</span><span class="hl opt">());</span> + a<span class="hl opt">-></span><span class="hl kwd">setShortcut</span><span class="hl opt">(</span>Qt<span class="hl opt">::</span>Key_Return<span class="hl opt">);</span> + <span class="hl kwd">connect</span><span class="hl opt">(</span>a<span class="hl opt">,</span> <span class="hl kwd">SIGNAL</span><span class="hl opt">(</span><span class="hl kwd">triggered</span><span class="hl opt">()),</span> <span class="hl kwa">this</span><span class="hl opt">,</span> <span class="hl kwd">SLOT</span><span class="hl opt">(</span><span class="hl kwd">generateClicked</span><span class="hl opt">()));</span> + win<span class="hl opt">-></span><span class="hl kwd">widget</span><span class="hl opt">()-></span><span class="hl kwd">addAction</span><span class="hl opt">(</span>a<span class="hl opt">);</span> + + a <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">QAction</span><span class="hl opt">(</span>win<span class="hl opt">-></span><span class="hl kwd">widget</span><span class="hl opt">());</span> + a<span class="hl opt">-></span><span class="hl kwd">setShortcut</span><span class="hl opt">(</span>Qt<span class="hl opt">::</span>Key_Escape<span class="hl opt">);</span> + <span class="hl kwd">connect</span><span class="hl opt">(</span>a<span class="hl opt">,</span> <span class="hl kwd">SIGNAL</span><span class="hl opt">(</span><span class="hl kwd">triggered</span><span class="hl opt">()),</span> qApp<span class="hl opt">,</span> <span class="hl kwd">SLOT</span><span class="hl opt">(</span><span class="hl kwd">quit</span><span class="hl opt">()));</span> + win<span class="hl opt">-></span><span class="hl kwd">widget</span><span class="hl opt">()-></span><span class="hl kwd">addAction</span><span class="hl opt">(</span>a<span class="hl opt">);</span> + + mReady <span class="hl opt">=</span> <span class="hl kwa">true</span><span class="hl opt">;</span> + + <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">"%s initialized"</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span> + + <span class="hl kwa">return true</span><span class="hl opt">;</span> +<span class="hl opt">}</span> + +<span class="hl kwb">void</span> Module<span class="hl opt">::</span><span class="hl kwd">done</span><span class="hl opt">()</span> +<span class="hl opt">{</span> + mReady <span class="hl opt">=</span> <span class="hl kwa">false</span><span class="hl opt">;</span> + + <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">"%s finalized"</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span> +<span class="hl opt">}</span> + +<span class="hl kwb">void</span> Module<span class="hl opt">::</span><span class="hl kwd">textChanged</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&)</span> +<span class="hl opt">{</span> + wGenerate<span class="hl opt">-></span><span class="hl kwd">setDisabled</span><span class="hl opt">(</span>wMasterPassword<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">().</span><span class="hl kwd">isEmpty</span><span class="hl opt">() ||</span> wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">().</span><span class="hl kwd">isEmpty</span><span class="hl opt">());</span> + <span class="hl kwa">if</span> <span class="hl opt">(!</span>wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">().</span><span class="hl kwd">isEmpty</span><span class="hl opt">() &&</span> mStorage<span class="hl opt">) {</span> + QExplicitlySharedDataPointer<span class="hl opt"><</span>PswGen<span class="hl opt">::</span>Storage<span class="hl opt">::</span>Data<span class="hl opt">></span> data <span class="hl opt">=</span> mStorage<span class="hl opt">-></span><span class="hl kwd">query</span><span class="hl opt">(</span>wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">());</span> + <span class="hl kwa">if</span> <span class="hl opt">(</span>data<span class="hl opt">)</span> + wLength<span class="hl opt">-></span><span class="hl kwd">setValue</span><span class="hl opt">(</span>data<span class="hl opt">-></span><span class="hl kwd">length</span><span class="hl opt">());</span> + <span class="hl opt">}</span> +<span class="hl opt">}</span> + +<span class="hl kwb">void</span> Module<span class="hl opt">::</span><span class="hl kwd">generateClicked</span><span class="hl opt">()</span> +<span class="hl opt">{</span> + <span class="hl kwa">if</span> <span class="hl opt">(</span>wMasterPassword<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">().</span><span class="hl kwd">isEmpty</span><span class="hl opt">() ||</span> wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">().</span><span class="hl kwd">isEmpty</span><span class="hl opt">())</span> + <span class="hl kwa">return</span><span class="hl opt">;</span> + wPassword<span class="hl opt">-></span><span class="hl kwd">setText</span><span class="hl opt">(</span>mGenerator<span class="hl opt">-></span><span class="hl kwd">generatePassword</span><span class="hl opt">(</span>wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">(),</span> wMasterPassword<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">(),</span> wLength<span class="hl opt">-></span><span class="hl kwd">value</span><span class="hl opt">()));</span> + wCopy<span class="hl opt">-></span><span class="hl kwd">setEnabled</span><span class="hl opt">(</span><span class="hl kwa">true</span><span class="hl opt">);</span> + <span class="hl kwa">if</span> <span class="hl opt">(</span>mStorage<span class="hl opt">) {</span> + QExplicitlySharedDataPointer<span class="hl opt"><</span>PswGen<span class="hl opt">::</span>Storage<span class="hl opt">::</span>Data<span class="hl opt">></span> data <span class="hl opt">=</span> mStorage<span class="hl opt">-></span><span class="hl kwd">query</span><span class="hl opt">(</span>wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">());</span> + <span class="hl kwa">if</span> <span class="hl opt">(!</span>data<span class="hl opt">)</span> + data <span class="hl opt">=</span> <span class="hl kwa">new</span> Storage<span class="hl opt">::</span><span class="hl kwd">Data</span><span class="hl opt">(</span>wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">(),</span> wLength<span class="hl opt">-></span><span class="hl kwd">value</span><span class="hl opt">());</span> + <span class="hl kwa">else</span> + data<span class="hl opt">-></span><span class="hl kwd">setLength</span><span class="hl opt">(</span>wLength<span class="hl opt">-></span><span class="hl kwd">value</span><span class="hl opt">());</span> + mStorage<span class="hl opt">-></span><span class="hl kwd">save</span><span class="hl opt">(</span>wName<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">(),</span> data<span class="hl opt">);</span> + <span class="hl opt">}</span> +<span class="hl opt">}</span> + +<span class="hl kwb">void</span> Module<span class="hl opt">::</span><span class="hl kwd">copyClicked</span><span class="hl opt">()</span> +<span class="hl opt">{</span> + QClipboard <span class="hl opt">*</span> clipboard <span class="hl opt">=</span> QApplication<span class="hl opt">::</span><span class="hl kwd">clipboard</span><span class="hl opt">();</span> + <span class="hl kwa">if</span> <span class="hl opt">(</span>clipboard<span class="hl opt">)</span> + clipboard<span class="hl opt">-></span><span class="hl kwd">setText</span><span class="hl opt">(</span>wPassword<span class="hl opt">-></span><span class="hl kwd">text</span><span class="hl opt">());</span> +<span class="hl opt">}</span></pre> + + <p>Build the <a href="pswgen11.html">PswGen application</a>.</p> + + </body> +</html> diff --git a/www/pswgen11.html b/www/pswgen11.html new file mode 100644 index 0000000..7fb3f32 --- /dev/null +++ b/www/pswgen11.html @@ -0,0 +1,198 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html lang="et" xmlns="http://www.w3.org/1999/xhtml" xml:lang="et"> + + <head> + <meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" /> + <title>eVaf Tutorial - 11 - Building PswGen application</title> + <meta name="Author" content="Enar Väikene" /> + <meta name="description" content="eVaf Tutorial" /> + <meta name="keywords" content="evaf c++ application development framework tutorial password generator" /> + <link rel="StyleSheet" href="evaf.css" type="text/css" media="all" /> + <link rel="StyleSheet" href="highlight.css" type="text/css" media="all" /> + </head> + + <body> + + <h1>eVaf Tutorial</h1> + + <h2>11 - Buiding PswGen application</h2> + + <h3>CMakeLists.txt</h3> + + <p>Copy an existing <tt>CMakeLists.txt</tt> file from the <tt>Storage</tt> module:</p> + + <pre>evaf/src/apps/PswGen/GUI $ <code>cp ../Storage/CMakeLists.txt .</code></pre> + + <p>We need to modify the <tt>TARGET</tt> variable and remove <tt>QT_USE_QTSQL</tt> and <tt>QT_DONT_USE_QTGUI</tt> variables. + This module needs <tt>QtGui</tt> and does not need <tt>QtSql</tt>. Als add <tt>SdiWindow</tt> to the list of eVaf libraries + as the module that implements the main window.</p> + + <pre class="hl"><span class="hl com"># Name of the target</span> +<span class="hl kwa">set</span><span class="hl opt">(</span>TARGET PswGui<span class="hl opt">)</span> + +<span class="hl com"># Qt modules</span> +<span class="hl kwa">include</span><span class="hl opt">(</span><span class="hl kwd">${QT_USE_FILE}</span><span class="hl opt">)</span> + +<span class="hl com"># Required eVaf libraries</span> +<span class="hl kwa">set</span><span class="hl opt">(</span>eVaf_LIBRARIES CommonLib PluginsLib SdiWindow<span class="hl opt">)</span></pre> + + <p>Here is the final <tt>CMakeLists.txt</tt> file:</p> + +<pre class="hl"><span class="hl com"># src/apps/PswGen/GUI/CMakeLists.txt</span> + +<span class="hl com"># Name of the target</span> +<span class="hl kwa">set</span><span class="hl opt">(</span>TARGET PswGui<span class="hl opt">)</span> + +<span class="hl com"># Qt modules</span> +<span class="hl kwa">include</span><span class="hl opt">(</span><span class="hl kwd">${QT_USE_FILE}</span><span class="hl opt">)</span> + +<span class="hl com"># Include directories</span> +<span class="hl kwa">include_directories</span><span class="hl opt">(</span><span class="hl kwd">${eVaf_INCLUDE}<span class="hl opt">)</span> + +<span class="hl com"># Required eVaf libraries</span> +<span class="hl kwa">set</span><span class="hl opt">(</span>eVaf_LIBRARIES CommonLib PluginsLib SdiWindow<span class="hl opt">)</span> + +<span class="hl com"># Source files</span> +<span class="hl kwa">set</span><span class="hl opt">(</span>SRCS + gui.cpp +<span class="hl opt">)</span> + +<span class="hl com"># Header files for the Qt meta-object compiler</span> +<span class="hl kwa">set</span><span class="hl opt">(</span>MOC_HDRS + gui.h +<span class="hl opt">)</span> + +<span class="hl com"># Version info resource file for Windows builds</span> +<span class="hl kwa">if</span><span class="hl opt">(</span><span class="hl kwb">WIN32</span><span class="hl opt">)</span> + <span class="hl kwa">set</span><span class="hl opt">(</span>SRCS <span class="hl kwd">${SRCS}</span> version.rc<span class="hl opt">)</span> +<span class="hl kwa">endif</span><span class="hl opt">(</span><span class="hl kwb">WIN32</span><span class="hl opt">)</span> + +<span class="hl com"># Run the Qt meta-object compiler</span> +<span class="hl kwd">qt4_wrap_cpp</span><span class="hl opt">(</span>MOC_SRCS <span class="hl kwd">${MOC_HDRS}</span><span class="hl opt">)</span> + +<span class="hl com"># Compile the module</span> +<span class="hl kwa">add_library</span><span class="hl opt">(</span><span class="hl kwd">${TARGET}</span> <span class="hl kwb">SHARED</span> <span class="hl kwd">${SRCS} ${MOC_SRCS}</span><span class="hl opt">)</span> + +<span class="hl com"># Link the module</span> +<span class="hl kwa">target_link_libraries</span><span class="hl opt">(</span><span class="hl kwd">${TARGET} ${QT_LIBRARIES} ${eVaf_LIBRARIES}</span><span class="hl opt">)</span></pre> + + <p>Open the <tt>CMakeLists.txt</tt> file in the parent directory and add the command to include the <tt>GUI</tt> + sub-directory:</p> + + <pre class="hl"><span class="hl com"># src/apps/PswGen/CMakeLists.txt</span> +<span class="hl com"># ...</span> +<span class="hl kwa">add_subdirectory</span><span class="hl opt">(</span>GUI<span class="hl opt">)</span></pre> + + <h3>Building the module</h3> + + <p>Go to the previously made <tt>build</tt> directory and build the module:</p> + + <pre>evaf $ <code>cd build</code> +evaf/build $ <code>make PswGui</code></pre> + + <p>Check the <tt>bin</tt> directory, which should now contain two new libraries:</p> + + <pre>evaf/build $ <code>ls bin</code> +libCommonLib.so* libPluginsLib.so* libPswGen.so* <b>libPswGui.so*</b> libPswStorage.so* <b>libSdiWindow.so*</b> +evaf/build $</pre> + + <p>The <tt>libSdiWindow.so</tt> library was built because it is a dependency of the <tt>GUI</tt> module.</p> + + <h3>Running the PswGen application</h3> + + <p>In the same <tt>build</tt> directory, create few more sub-directories needed by any <tt>eVaf</tt> applications:</p> + + <pre> evaf/build $ <code>mkdir {etc,log}</code></pre> + + <p>Create the <tt>PswGen.xml</tt> file in the <tt>build/etc</tt> directory. The <tt>PswGen.xml</tt> file defines the + application by specifying all the modules that the application needs to load.</p> + + <pre class="hl"><span class="hl kwa"><?xml</span> <span class="hl kwb">version</span>=<span class="hl str">"1.0"</span> <span class="hl kwb">encoding</span>=<span class="hl str">"UTF-8"</span><span class="hl kwa">?></span> +<span class="hl kwa"><!DOCTYPE</span> eVaf<span class="hl kwa">></span> +<span class="hl kwa"><eVaf</span> <span class="hl kwb">version</span>=<span class="hl str">"1.0"</span><span class="hl kwa">></span> + <span class="hl kwa"><plugins></span> + <span class="hl kwa"><plugin</span> <span class="hl kwb">name</span>=<span class="hl str">"SdiWindow"</span> <span class="hl kwb">filename</span>=<span class="hl str">"SdiWindow"</span> <span class="hl kwa">/></span> + <span class="hl kwa"><plugin</span> <span class="hl kwb">name</span>=<span class="hl str">"Generator"</span> <span class="hl kwb">filename</span>=<span class="hl str">"PswGen"</span> <span class="hl kwa">/></span> + <span class="hl kwa"><plugin</span> <span class="hl kwb">name</span>=<span class="hl str">"Storage"</span> <span class="hl kwb">filename</span>=<span class="hl str">"PswStorage"</span> <span class="hl kwa">/></span> + <span class="hl kwa"><plugin</span> <span class="hl kwb">name</span>=<span class="hl str">"GUI"</span> <span class="hl kwb">filename</span>=<span class="hl str">"PswGui"</span> <span class="hl kwa">/></span> + <span class="hl kwa"></plugins></span> +<span class="hl kwa"></eVaf></span></pre> + + <p>Modules are loaded and initialized in the order how they are specified in the xml file. We have to make sure that + <tt>SdiWindow</tt>, <tt>Generator</tt> and <tt>Storage</tt> modules are loaded before the <tt>GUI</tt> module. Otherwise + their interfaces wouldn't be available when the <tt>GUI</tt> module is initialized.</p> + + <p>The <tt>name</tt> attribute here is optional and will be replaced with the name reported by the actual module.</p> + + <p>The <tt>filename</tt> attribute specifies the name of the library file without prefixes and suffixes meaning that + <tt>lib<b>PswGen</b>.so</tt> shall be specified as <tt>PswGen</tt>. This makes sure that the same xml file can be also used + on Windows, where the library would be called <tt><b>PswGen</b>.dll</tt>.</p> + + <p>There is no executable file yet that we can run. Build it with the following command:</p> + + <pre>evaf/build $ <code>make eVafGUI</code></pre> + + <p>This command builds the GUI executable and stores it in the <tt>evaf/build/bin</tt> directory. The <tt>bin</tt> directory should look now the following:</p> + + <pre>evaf/build $ <code>ls bin</code> +eVafGUI* libCommonLib.so* libPluginsLib.so* libPswGen.so* libPswGui.so* libPswStorage.so* libSdiWindow.so* +evaf/build $</pre> + + <p>Now we can run the PswGen application. Change <tt>--dataroot=${HOME}/evaf/build</tt> to your actual build directory name:</p> + + <pre>evaf/build $ <code>bin/eVafGUI --application=PswGen --dataroot=${HOME}/evaf/build --verbose=INFO</code></pre> + + <p>The <tt>--application=PswGen</tt> command line option specifies the name of the application and also means that the xml file + should be called <tt>PswGen.xml</tt>. Different applications can be run in the same build directories by changing the name + of the application. The default application is called <tt>eVaf</tt> and if no name is given, then the xml file should be called + <tt>eVaf.xml</tt>.</p> + + <p>The <tt>--dataroot=${HOME}/evaf/build</tt> command line option specifies the location of data files for the application. The + application assumes that <tt>etc</tt> and <tt>spool</tt> directories are sub-directories in the data root directory. The default + data root directory is <tt>${HOME}/.local/share/data</tt> on + Linux.</p> + + <p>Finally, the <tt>--verbose=INFO</tt> command line option makes the application to be verbose and output all the info + messages to the console.</p> + + <h3>Releasing the PswGen application</h3> + + <p>Now the application is written and tested. We are ready to make a release build and ship it.</p> + + <p>Clean the build directory:</p> + + <pre>evaf/build $ <code>make clean && rm CMakeCache.txt</code></pre> + + <p>Prepare for a release build and build the application:</p> + + <pre>evaf/build $ <code>cmake -DCMAKE_BUILD_TYPE=Release ..</code> +evaf/build $ <code>make eVafGUI SdiWindow PswGen PswStorage PswGui</code></pre> + + <p>Packaging and shipping the application is out of the scope of this tutorial and involves more than just copying files that + we built. As a minimum, we have to make sure that the target system has Qt libraries installed. In this tutorial, we simply copy the + released application into the <tt>{$HOME}/bin/evaf</tt> directory. Qt libraries are already installed and we do not need to + worry about them.</p> + + <p>Create the <tt>${HOME}/bin/evaf</tt> directory:</p> + + <pre>evaf/build $ <code>mkdir -p ${HOME}/bin/evaf</code></pre> + + <p>Copy the content of <tt>bin</tt> and </tt>etc</tt> directories</p> + + <pre>evaf/build $ <code>cp -R bin etc ${HOME}/bin/evaf/</code></pre> + + <p>Create the bash script <tt>PswGen</tt> in the <tt>${HOME}/bin</tt> directory:</p> + + <pre class="hl"><span class="hl slc">#!/bin/bash</span> +EVAF_DIR<span class="hl opt">=</span><span class="hl kwd">${HOME}</span><span class="hl opt">/</span>bin<span class="hl opt">/</span>evaf +<span class="hl kwd">${EVAF_DIR}</span><span class="hl opt">/</span>bin<span class="hl opt">/</span>eVafGUI <span class="hl opt">--</span>rootdir<span class="hl opt">=</span><span class="hl kwd">${EVAF_DIR}</span> <span class="hl opt">--</span>dataroot<span class="hl opt">=</span><span class="hl kwd">${EVAF_DIR}</span> <span class="hl opt">--</span>application<span class="hl opt">=</span>PswGen +</pre> + + <p>Don't forget to make it runnable:</p> + + <pre> bin $ <code>chmod a+x PswGen</code></pre> + + <p>Now we can run the application by simply running the bash script <tt>PswGen</tt> in the <tt>${HOME}/bin</tt> directory. + + </body> +</html>