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