summaryrefslogtreecommitdiffstats
path: root/doc/html/motif-walkthrough-8.html
blob: f461b889d737cf8080ac5dc3adbff126cc045a99 (plain)
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
<!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:1190 -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Replacing the View Widget</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&nbsp;Classes</font></a>
 | <a href="mainclasses.html">
<font color="#004faf">Main&nbsp;Classes</font></a>
 | <a href="annotated.html">
<font color="#004faf">Annotated</font></a>
 | <a href="groups.html">
<font color="#004faf">Grouped&nbsp;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>Replacing the View Widget</h1>



[ <a href="motif-walkthrough-7.html">Previous: Refactoring Existing Code</a> ]
[ <a href="motif-walkthrough.html">Home</a> ]
[ <a href="motif-walkthrough-9.html">Next: Replacing the Print Dialog</a> ]
<p> We are ready to start replacing the <em>View</em> widget.  However, our
example program uses the <tt>XmNotebook</tt> widget class.  Qt does not
provide a direct equivalent of this class, so we are faced with three
possibilities, each with several advantages and disadvantages.
<p> <ol type=1>
<p> <li> We can continue the conversion using existing Qt widgets.
<p> <ul>
<p> <li> Advantages - The widgets provided by Qt are well designed and
tested, allowing us to quickly redesign the user interface.
<p> <li> Disadvantages - Most, if not all, of the existing data structures
and code will need to be modified or rewritten.  New code must be
written in a way that maintains compatibility with previous versions
of our application.
<p> </ul>
<p> <li> We can write a new <a href="qwidget.html">QWidget</a> subclass that is identical to the <tt>XmNotebook</tt> widget class.
<p> <ul>
<p> <li> Advantages - The existing data structures will not change, allowing
compatibility with previous and future versions.
<p> <li> Disadvantages - The new widget will need to be written and
regression tested.  Existing code in our application will need to be
changed in order to deal with the new widget's API.
<p> </ul>
<p> <li> We can leave the <tt>XmNotebook</tt> widget untouched.
<p> <ul>
<p> <li> Advantages - The existing data structures and code remain
unchanged, allowing us to continue development on other projects,
new features, etc.
<p> <li> Disadvantages - This is the simplest solution, but the application
will still be dependent upon X11; we will not be able to deploy our
application on all platforms supported by Qt.
<p> </ul>
<p> </ol>
<p> We will use the first approach to complete the migration of the
example project used in this walkthrough, using <a href="qtextedit.html">QTextEdit</a>, <a href="qlabel.html">QLabel</a> and
<a href="qspinbox.html">QSpinBox</a> to provide a similar look.  The only difference is that we
will not have tabs.
<p> We use <a href="designer-manual.html">Qt Designer</a> to add the
QTextEdit, QLabel and QSpinBox widgets to the <em>Main Window</em> widget.
<p> <h2> Data Structure Modifications
</h2>
<a name="1"></a><p> The <tt>Page</tt> struct contains <tt>majorPB</tt> and <tt>minorPB</tt> members which
need to be removed.  These members correspond to the tabs displayed in
the existing version.  The new version will not have any tabs, so we
remove them.
<p> 

<pre></pre>
<p> <h2> Code Modifications
</h2>
<a name="2"></a><p> Most of the existing functions in our application need to be modified
to work with the new <em>View</em> widget.  The <tt>MainWindow</tt> class has five
new functions that correspond to existing functions.
<p> <center><table cellpadding="4" cellspacing="2" border="0">
<tr bgcolor="#a2c511"> <th valign="top">Existing Function            <th valign="top">New Function 
<tr bgcolor="#f0f0f0">    <td valign="top"><tt>void SetPage( int )</tt>    <td valign="top"><tt>void MainWindow::setPage( int )</tt>
<tr bgcolor="#d0d0d0">    <td valign="top"><tt>void PageChange( ... )</tt>  <td valign="top"><tt>void MainWnidow::pageChange( int )</tt>
<tr bgcolor="#f0f0f0">    <td valign="top"><tt>void TextChanged( ... )</tt> <td valign="top"><tt>void MainWnidow::textChanged()</tt>
<tr bgcolor="#d0d0d0">    <td valign="top"><tt>void ReadDB( char * )</tt>   <td valign="top"><tt>void MainWindow::readDB( char * )</tt>
<tr bgcolor="#f0f0f0">    <td valign="top"><tt>void SaveDB( char * )</tt>   <td valign="top"><tt>void MainWindow::saveDB( char * )</tt>
</table></center>
<p> <a name="mainwindow-ui-h-view-widget-modifications"></a>
<p> The <tt>SetPage()</tt> function implementation is moved to the <tt>MainWindow::setPage()</tt> function in <tt>mainwindow.ui.h</tt>.  We remove the
<tt>SetPage()</tt> function declaration and implementation from <tt>page.h</tt>
and <tt>actions.cpp</tt>, respectively.  In order to make <tt>MainWindow::setPage()</tt> work correctly, we need to modify the code to
use the new widgets in our <em>Main Window</em> widget.
<p> 

<pre></pre>
<p> First, we set the current value of the <tt>spinbox</tt> to the current page
number.
<p> <pre></pre>
<p> Next, we set the current text and cursor position of the <tt>textedit</tt>
to the contents of the current page.
<p> <pre></pre>
<p> If the current page has a custom label, we set it as the current text
of the <tt>textlabel</tt>; otherwise we set the <tt>textlabel</tt> contents to
"Page X" (where X is the current page number).
<p> <pre></pre>
<p> If the current page has major and/or minor tab text, we append these
to the <tt>labeltext</tt>.  This ensures that all information entered by the
user remains visible.
<p> <pre></pre>
<p> We should continue to handle the possibility that the current page
does not exist.  In this case, we clear the contents of the <tt>textedit</tt> widget and set the <tt>textlabel</tt> contents to the current page
number (with an indication that the page is invalid).
<p> <pre></pre>
<p> The <tt>PageChange()</tt> function is moved from <tt>todo.cpp</tt> to the <tt>MainWindow::pageChange()</tt> function in <tt>mainwindow.ui.h</tt>.  As with the
<tt>MainWindow::setPae()</tt> function, we need to modify the code to use
the new widgets in our <em>Main Window</em> widget.
<p> Note: <a href="qtextedit.html#text">QTextEdit::text</a>() returns a <a href="qstring.html">QString</a>, which needs to be converted
into a normal <tt>char*</tt> array.  To do this we create a copy of the
string in the local encoding.  We need to make the copy using <a href="qcstring.html#qstrdup">qstrdup</a>() because the data contained in the <a href="qcstring.html">QCString</a> returned by
<a href="qstring.html#local8Bit">QString::local8Bit</a>() is deallocated when the QCString is destroyed.
<p> <pre></pre>
<p> The <tt>TextChanged()</tt> function does nothing more than set the <tt>modified</tt> variable to 1.  Our new <tt>MainWindow::textChanged()</tt> function
does exactly the same.
<p> <pre></pre>
<p> Since both the <tt>MainWindow::pageChange()</tt> and <tt>MainWindow::textChanged()</tt> functions access the <tt>modified</tt> global
variable, we add a forward declaration at the top of <tt>mainwindow.ui.h</tt>.
<p> <a name="io-cpp-view-widget-modifications"></a>
<p> The <tt>ReadDB()</tt> and \s SaveDB() implementations in <tt>io.cpp</tt> are
renamed to <tt>MainWindow::readDB()</tt> and <tt>MainWindow::saveDB()</tt>,
respectively.  We need to modify the code in order to make the code
work properly.
<p> First, We add <tt>#include</tt> statements for the <tt>MainWindow</tt>, <a href="qspinbox.html">QSpinBox</a>
and <a href="qtextedit.html">QTextEdit</a> classes.
<p> 

<pre></pre><pre></pre>
<p> The new <tt>MainWindow::readDB()</tt> and <tt>MainWindow::saveDB()</tt> functions
will not use any Xt/Motif functions, so we remove the Xt/Motif <tt>#include</tt> statements and the global variables <tt>notebook</tt> and <tt>textw</tt>.
These functions remain largely unchanged, maintaining compatibility
with previous versions.  Also, the <tt>ReadDB()</tt> and <tt>SaveDB()</tt>
functions have been converted into <tt>MainWindow</tt> member functions, so
we can pass <em>this</em> as the <em>parent</em> argument to the <a href="qmessagebox.html">QMessageBox</a>
functions.
<p> <pre></pre>
<p> After reading the file in the <tt>MainWindow::readDB()</tt> function, we set
the current and maximum values of the <tt>spinbox</tt> to the appropriate
values.
<p> 

<p> <pre></pre>
<p> In the <tt>MainWindow::saveDB()</tt> function, we need to store the text
currently displayed, so we use <a href="qtextedit.html#text">QTextEdit::text</a>() instead of <tt>XmTextGetString()</tt>.  Note: QTextEdit::text() returns a <a href="qstring.html">QString</a>, which
needs to be converted into a normal <tt>char*</tt> array.  To do this we
create a copy of the string in the local encoding.  We need to make
the copy using <a href="qcstring.html#qstrdup">qstrdup</a>() because the data contained in the <a href="qcstring.html">QCString</a>
returned by <a href="qstring.html#local8Bit">QString::local8Bit</a>() is deallocated when the QCString is
destroyed.
<p> <pre></pre>
<p> <a name="actions-cpp-viewwidget-modifications"></a>
<p> Due to the removal of the <tt>majorPB</tt> and <tt>minorPB</tt> members from the
<tt>Page</tt> struct, the <tt>FixPages()</tt> function in <tt>actions.cpp</tt> is no
longer needed.  We remove the implementation and forward declaration
of <tt>FixPages()</tt> from <tt>actions.cpp</tt> and <tt>page.h</tt>, respectively.
Calls to <tt>FixPages()</tt> are removed from the <tt>MainWindow::selNewPage()</tt> and <tt>MainWindow::selDeletePage()</tt>, both of
which are in <tt>mainwindow.ui.h</tt>.
<p> We move <tt>AdjustPages()</tt> to <tt>mainwindow.ui.h</tt> and make it <tt>static</tt>,
since it is only used in this file.  We remove the forward declaration
from <tt>page.h</tt> as well.
<p> After our modifications, the <tt>actions.cpp</tt> file is empty. We remove
it from our project file and regenerate our <tt>Makefile</tt>.
<p> <a name="todo-cpp-view-widget-modifications"></a>
<p> Now that we have implemented our new <em>View</em> widget, we need to remove
the old <a href="motif-extension.html#Motif">Motif</a> based view widget from <tt>todo.cpp</tt>.
<p> Since we will not be using any Motif widgets, we remove all Motif <tt>#include</tt> statements, including <a href="qmotifwidget-h.html">qmotifwidget.h</a>. 
<p> 

<pre></pre><pre></pre>
<p> We also remove the forward declarations of the <tt>ReadDB()</tt> function
and the <tt>notebook</tt>, <tt>textw</tt> and <tt>labelw</tt> global variables.
<p> <pre></pre>
<p> Next, we remove the <tt>center</tt> widget, which uses <a href="qmotifwidget.html">QMotifWidget</a>.  The <em>Main Window</em> widget and <em>View</em> widget are contained entirely in our
<tt>MainWindow</tt> class, so no extra initialization is needed after
creating the <tt>mainwindow</tt> widget.
<p> <pre></pre>
<p> Since the <tt>ReadDB()</tt> and <tt>SetPage()</tt> functions have been changed into
<tt>MainWindow</tt> member functions, we need to call them using our <tt>mainwindow</tt> instance.
<p> <pre></pre>
<p> The <em>View</em> widget has now been replaced.  After building our project,
we confirm that the application works correctly.
<p> [ <a href="motif-walkthrough-7.html">Previous: Refactoring Existing Code</a> ]
[ <a href="motif-walkthrough.html">Home</a> ]
[ <a href="motif-walkthrough-9.html">Next: Replacing the Print Dialog</a> ]
<p> 
<!-- eof -->
<p><address><hr><div align=center>
<table width=100% cellspacing=0 border=0><tr>
<td>Copyright &copy; 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>