]> vaikene.ee Git - evaf/blobdiff - www/pswgen09.html
Finalized tutorial files.
[evaf] / www / pswgen09.html
diff --git a/www/pswgen09.html b/www/pswgen09.html
new file mode 100644 (file)
index 0000000..7f05aba
--- /dev/null
@@ -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"> * &#64;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 &lt;Plugins/iPlugin&gt;</span>
+<span class="hl ppc">#include &lt;QObject&gt;</span>
+<span class="hl ppc">#include &lt;QString&gt;</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">&amp;</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">&amp;);</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"> * &#64;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 &lt;Plugins/iPlugin&gt;</span>
+
+<span class="hl ppc">#include &lt;QObject&gt;</span>
+<span class="hl ppc">#include &lt;QString&gt;</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">&amp;</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">&amp;);</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>