[190] | 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
---|
| 2 | <!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/extensions/motif/doc/walkthrough.doc:921 -->
|
---|
| 3 | <html>
|
---|
| 4 | <head>
|
---|
| 5 | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
---|
| 6 | <title>Refactoring Existing Code</title>
|
---|
| 7 | <style type="text/css"><!--
|
---|
| 8 | fn { margin-left: 1cm; text-indent: -1cm; }
|
---|
| 9 | a:link { color: #004faf; text-decoration: none }
|
---|
| 10 | a:visited { color: #672967; text-decoration: none }
|
---|
| 11 | body { background: #ffffff; color: black; }
|
---|
| 12 | --></style>
|
---|
| 13 | </head>
|
---|
| 14 | <body>
|
---|
| 15 |
|
---|
| 16 | <table border="0" cellpadding="0" cellspacing="0" width="100%">
|
---|
| 17 | <tr bgcolor="#E5E5E5">
|
---|
| 18 | <td valign=center>
|
---|
| 19 | <a href="index.html">
|
---|
| 20 | <font color="#004faf">Home</font></a>
|
---|
| 21 | | <a href="classes.html">
|
---|
| 22 | <font color="#004faf">All Classes</font></a>
|
---|
| 23 | | <a href="mainclasses.html">
|
---|
| 24 | <font color="#004faf">Main Classes</font></a>
|
---|
| 25 | | <a href="annotated.html">
|
---|
| 26 | <font color="#004faf">Annotated</font></a>
|
---|
| 27 | | <a href="groups.html">
|
---|
| 28 | <font color="#004faf">Grouped Classes</font></a>
|
---|
| 29 | | <a href="functions.html">
|
---|
| 30 | <font color="#004faf">Functions</font></a>
|
---|
| 31 | </td>
|
---|
| 32 | <td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table><h1 align=center>Refactoring Existing Code</h1>
|
---|
| 33 |
|
---|
| 34 |
|
---|
| 35 |
|
---|
| 36 | [ <a href="motif-walkthrough-6.html">Previous: Using Qt Main Window Classes</a> ]
|
---|
| 37 | [ <a href="motif-walkthrough.html">Home</a> ]
|
---|
| 38 | [ <a href="motif-walkthrough-8.html">Next: Replacing the View Widget</a> ]
|
---|
| 39 | <p> In the author's view, the existing code is slightly disorganized.
|
---|
| 40 | Even though the code <em>does</em> work, some cleanups and reorganization
|
---|
| 41 | can only help with readability and maintainability. The steps
|
---|
| 42 | described below are not necessary during the migration process but are
|
---|
| 43 | included for completeness.
|
---|
| 44 | <p> <h2> Migrating Data Structures to C++
|
---|
| 45 | </h2>
|
---|
| 46 | <a name="1"></a><p> The <tt>Page</tt> data structure is an opaque data type. The real data
|
---|
| 47 | structure is called <tt>PageRec</tt>; <tt>Page</tt> defined to be a pointer to a
|
---|
| 48 | <tt>PageRec</tt>. In addition, we have the <tt>AllocPage()</tt> function that
|
---|
| 49 | allocates and initializes memory for a <tt>PageRec</tt> struct.
|
---|
| 50 | <p> With C++, we can do this in the constructor. We can also write a
|
---|
| 51 | destructor which automatically frees all resources in the <tt>PageRec</tt>,
|
---|
| 52 | instead of having to do it in several different places.
|
---|
| 53 | <p> The <tt>PageRec</tt> struct declaration is removed from <tt>page.h</tt>. We
|
---|
| 54 | declare a <tt>Page</tt> struct with the same data members as <tt>PageRec</tt>, a
|
---|
| 55 | constructor and a destructor.
|
---|
| 56 | <p>
|
---|
| 57 |
|
---|
| 58 | <pre></pre>
|
---|
| 59 | <p> The existing <tt>pages</tt>, <tt>currentPage</tt> and <tt>maxpages</tt> global variables
|
---|
| 60 | are removed from the source files. We replace them with <tt>extern</tt>
|
---|
| 61 | declarations in <tt>page.h</tt>.
|
---|
| 62 | <p> <pre></pre>
|
---|
| 63 | <p> The global variable instantiations are placed in <tt>todo.cpp</tt>.
|
---|
| 64 | <p> Each source file contains function declarations that deal with the
|
---|
| 65 | global <tt>Page</tt> related variables. We remove these declarations from
|
---|
| 66 | the source files and declare them once in the <tt>page.h</tt> header file.
|
---|
| 67 | <p> <pre></pre>
|
---|
| 68 | <p> Now that <tt>Page</tt> has a constructor, we remove the <tt>AllocPage()</tt>
|
---|
| 69 | function. It is no longer needed. The calls to <tt>AllocPage()</tt> are
|
---|
| 70 | replaced with <tt>'new Page()'</tt> in the <tt>NewPage()</tt>, <tt>DeletePage()</tt>
|
---|
| 71 | and <tt>ReadDB()</tt> functions. We also replace the code to deallocate
|
---|
| 72 | pages with <tt>delete pages[X]</tt>, where <em>X</em> is the appropriate index
|
---|
| 73 | value. This is done in the <tt>ReadDB</tt> and <tt>DeletePage()</tt> functions.
|
---|
| 74 | <p> Code that accesses the global <tt>pages</tt> variable does not need to be
|
---|
| 75 | modified since the data members of the <tt>Page</tt> struct did not change.
|
---|
| 76 | The existing code will continue to work.
|
---|
| 77 | <p> The <tt>OptionsRec</tt> struct declared in <tt>page.h</tt> is also updated,
|
---|
| 78 | following the same pattern as the <tt>Page</tt> struct above.
|
---|
| 79 | <p> <pre></pre>
|
---|
| 80 | <p> The global variable instantiation is also placed in <tt>todo.cpp</tt>.
|
---|
| 81 | <p> Code that accesses the global <tt>options</tt> variable does not need to be
|
---|
| 82 | modified since the data members of the <tt>Options</tt> struct did not
|
---|
| 83 | change. The existing code will continue to work.
|
---|
| 84 | <p> <h2> Using <em>new</em> and <em>delete</em>
|
---|
| 85 | </h2>
|
---|
| 86 | <a name="2"></a><p> The destructors of the <tt>Page</tt> and <tt>Options</tt> structs use <em>delete</em>
|
---|
| 87 | instead of <tt>XtFree()</tt> to deallocate all <tt>char*</tt> members. This is a
|
---|
| 88 | necessary change since we are migrating away from Xt/Motif. We need
|
---|
| 89 | to fix existing code that modifies the <tt>Page</tt> struct members to use
|
---|
| 90 | <em>new</em> and <em>delete</em> ( instead of <tt>XtMalloc()</tt>, <tt>XtNewString()</tt> and
|
---|
| 91 | <tt>XtFree()</tt> ).
|
---|
| 92 | <p> The <tt>PageChange()</tt> function in <tt>todo.cpp</tt> simply saves the contents
|
---|
| 93 | and cursor position of current page before calling <tt>SetPage()</tt>. We
|
---|
| 94 | use <em>new</em> and <em>delete</em> when modifying members of the <tt>Page</tt> struct.
|
---|
| 95 | <p>
|
---|
| 96 |
|
---|
| 97 | <pre></pre>
|
---|
| 98 | <p> When storing the context of the <tt>XmText</tt> widget, we use <a href="qcstring.html#qstrdup">qstrdup</a>()
|
---|
| 99 | to make a copy of the string returned by the <tt>XmTextGetString()</tt>
|
---|
| 100 | function.
|
---|
| 101 | <p> <pre></pre>
|
---|
| 102 | <p> The <tt>ReadDB()</tt> function in <tt>io.cpp</tt> needs similar changes. We
|
---|
| 103 | replace all use of <tt>XtMalloc()</tt> and <tt>XtNewString()</tt> with <em>new</em> and
|
---|
| 104 | <a href="qcstring.html#qstrdup">qstrdup</a>(), respectively.
|
---|
| 105 | <p> This needs to be done just after opening the file.
|
---|
| 106 | <p>
|
---|
| 107 |
|
---|
| 108 | <pre></pre>
|
---|
| 109 | <p> ... when starting a new page ...
|
---|
| 110 | <p> <pre>
|
---|
| 111 | ...
|
---|
| 112 | </pre>
|
---|
| 113 |
|
---|
| 114 | <pre></pre>
|
---|
| 115 | <p> ... and when reading in the label and tab texts/
|
---|
| 116 | <p> <pre>
|
---|
| 117 | ...
|
---|
| 118 | </pre>
|
---|
| 119 |
|
---|
| 120 | <pre></pre><pre>
|
---|
| 121 | ...
|
---|
| 122 | </pre>
|
---|
| 123 |
|
---|
| 124 | <pre></pre><pre>
|
---|
| 125 | ...
|
---|
| 126 | </pre>
|
---|
| 127 |
|
---|
| 128 | <pre></pre>
|
---|
| 129 | <p> The <tt>ReadDB()</tt> function uses <tt>XtRealloc()</tt> to expand the data
|
---|
| 130 | storage buffer. Unfortunately, C++ does not provide a way to
|
---|
| 131 | reallocate an existing block of data, so we have to do this ourselves.
|
---|
| 132 | <p> <pre></pre>
|
---|
| 133 | <p> There is also one occurence in <tt>ReadDB()</tt> where we call <tt>XtMalloc()</tt>
|
---|
| 134 | with an argument of 2. This was done when a file could not be read.
|
---|
| 135 | Creating an empty string is not necessary, so we remove this code
|
---|
| 136 | instead of using <em>new</em>.
|
---|
| 137 | <p> <pre></pre>
|
---|
| 138 | <p> The <tt>SaveDB()</tt> function in <tt>io.cpp</tt> also needs these changes. We
|
---|
| 139 | change one occurence of <tt>XtFree()</tt> to <em>delete</em>.
|
---|
| 140 | <p> <pre></pre>
|
---|
| 141 | <p> Finally, We need to replace two occurences of <tt>XtNewString()</tt> in the <tt>main()</tt> function in <tt>todo.cpp</tt>.
|
---|
| 142 | <p>
|
---|
| 143 |
|
---|
| 144 | <pre></pre>
|
---|
| 145 | <p> <h2> Moving Existing Code
|
---|
| 146 | </h2>
|
---|
| 147 | <a name="3"></a><p> The rest of the refactoring process involves moving existing code into
|
---|
| 148 | new places. Currently, each function in the <tt>mainwindow.ui.h</tt> file
|
---|
| 149 | simply calls the old callback handlers present in the other files.
|
---|
| 150 | Instead of calling the old callback functions, the implementations are
|
---|
| 151 | moved accordingly.
|
---|
| 152 | <p> <center><table cellpadding="4" cellspacing="2" border="0">
|
---|
| 153 | <tr bgcolor="#a2c511"> <th valign="top">Function <th valign="top">Original File <th valign="top">Moved to Function
|
---|
| 154 | <tr bgcolor="#f0f0f0"> <td valign="top"><tt>New()</tt> <td valign="top"><tt>todo.cpp</tt> <td valign="top"><tt>MainWindow::fileNew()</tt>
|
---|
| 155 | <tr bgcolor="#d0d0d0"> <td valign="top"><tt>Open()</tt> <td valign="top"><tt>todo.cpp</tt> <td valign="top"><tt>MainWindow::fileOpen()</tt>
|
---|
| 156 | <tr bgcolor="#f0f0f0"> <td valign="top"><tt>SaveIt()</tt> <td valign="top"><tt>actions.cpp</tt> <td valign="top"><tt>MainWindow::fileSave()</tt>
|
---|
| 157 | <tr bgcolor="#d0d0d0"> <td valign="top"><tt>Save()</tt> <td valign="top"><tt>todo.cpp</tt> <td valign="top"><tt>MainWindow::fileSaveAs()</tt>
|
---|
| 158 | <tr bgcolor="#f0f0f0"> <td valign="top"><tt>ShowPrintDialog()</tt> <td valign="top"><tt>todo.cpp</tt> <td valign="top"><tt>MainWindow::filePrint()</tt>
|
---|
| 159 | <tr bgcolor="#d0d0d0"> <td valign="top"><tt>EditPage()</tt> <td valign="top"><tt>actions.cpp</tt> <td valign="top"><tt>MainWindow::selProperties()</tt>
|
---|
| 160 | <tr bgcolor="#f0f0f0"> <td valign="top"><tt>NewPage()</tt> <td valign="top"><tt>actions.cpp</tt> <td valign="top"><tt>MainWindow::selNewPage()</tt>
|
---|
| 161 | <tr bgcolor="#d0d0d0"> <td valign="top"><tt>DeletePage()</tt> <td valign="top"><tt>actions.cpp</tt> <td valign="top"><tt>MainWindow::selDeletePage()</tt>
|
---|
| 162 | </table></center>
|
---|
| 163 | <p> The <tt>Print()</tt> callback function is still used by the <em>Print</em>
|
---|
| 164 | dialog, so we move it into <tt>mainwindow.ui.h</tt> and make it <tt>static</tt>.
|
---|
| 165 | <p> Previously, the <tt>Open()</tt>, <tt>Save()</tt>, <tt>EditPage()</tt> and <tt>DeletePage()</tt>
|
---|
| 166 | functions created dialogs with <em>client_data</em> as the parent argument.
|
---|
| 167 | Since we have moved the code directly into the <em>Main Window</em>
|
---|
| 168 | implementation, we create these dialogs with <em>this</em> as the parent
|
---|
| 169 | argument.
|
---|
| 170 | <p> The <tt>PageChange()</tt> callback function is moved from <tt>actions.cpp</tt>
|
---|
| 171 | to <tt>todo.cpp</tt> and made <tt>static</tt> since it is not used anywhere else.
|
---|
| 172 | <p> Earlier modifications to <tt>actions.cpp</tt> caused the <tt>Trim()</tt> function
|
---|
| 173 | to become redundant, so we remove it.
|
---|
| 174 | <p> The <tt>MIN()</tt> and <tt>MAX()</tt> macros in <tt>todo.cpp</tt> are redundant. Qt
|
---|
| 175 | provides the <tt>QMIN()</tt> and <tt>QMAX()</tt> macros which we will use.
|
---|
| 176 | <p> Earlier modifications caused the <tt>fallback_resources</tt> array to become
|
---|
| 177 | redundant, so we remove it.
|
---|
| 178 | <p> In the near future, our program will not use <a href="motif-extension.html#Motif">Motif</a> any more, and we
|
---|
| 179 | will no longer need to use <a href="qmotif.html">QMotif</a>. To prepare for this, we remove the
|
---|
| 180 | <tt>resources</tt> and <tt>optionDesc</tt> arrays and create the QMotif instance
|
---|
| 181 | with just the <em>APP_CLASS</em> argument.
|
---|
| 182 | <p> The <tt>#include</tt> statements in the source files are mostly incorrect
|
---|
| 183 | due to the refactoring changes. Many of the <tt>#include</tt> statements
|
---|
| 184 | are no longer needed. The <tt>#include</tt> statements from each file are
|
---|
| 185 | listed below, instead of describing which includes are removed and
|
---|
| 186 | added to each file.
|
---|
| 187 | <p> Includes for <tt>actions.cpp</tt>:
|
---|
| 188 | <p>
|
---|
| 189 |
|
---|
| 190 | <pre></pre>
|
---|
| 191 | <p> Includes for <tt>io.cpp</tt>:
|
---|
| 192 | <p>
|
---|
| 193 |
|
---|
| 194 | <pre></pre><pre></pre><pre></pre>
|
---|
| 195 | <p> Includes for <tt>todo.cpp</tt>:
|
---|
| 196 | <p>
|
---|
| 197 |
|
---|
| 198 | <pre></pre><pre></pre><pre></pre>
|
---|
| 199 | <p> Includes for <tt>mainwindow.ui.h</tt>:
|
---|
| 200 | <p>
|
---|
| 201 |
|
---|
| 202 | <pre></pre><pre></pre><pre></pre><pre></pre><pre></pre>
|
---|
| 203 | <p> [ <a href="motif-walkthrough-6.html">Previous: Using Qt Main Window Classes</a> ]
|
---|
| 204 | [ <a href="motif-walkthrough.html">Home</a> ]
|
---|
| 205 | [ <a href="motif-walkthrough-8.html">Next: Replacing the View Widget</a> ]
|
---|
| 206 | <p>
|
---|
| 207 | <!-- eof -->
|
---|
| 208 | <p><address><hr><div align=center>
|
---|
| 209 | <table width=100% cellspacing=0 border=0><tr>
|
---|
| 210 | <td>Copyright © 2007
|
---|
| 211 | <a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a>
|
---|
| 212 | <td align=right><div align=right>Qt 3.3.8</div>
|
---|
| 213 | </table></div></address></body>
|
---|
| 214 | </html>
|
---|