summaryrefslogtreecommitdiff
path: root/library
authorsandman <sandman>2002-11-26 23:34:04 (UTC)
committer sandman <sandman>2002-11-26 23:34:04 (UTC)
commite52158d2f9e1fdc9766d991dc672729648d5a020 (patch) (unidiff)
tree2e87e8d9a24cdb336b2d7ca654a5ffa2f80c5f8c /library
parentac4f32931212847803534a72eb5e951bd01e6ff5 (diff)
downloadopie-e52158d2f9e1fdc9766d991dc672729648d5a020.zip
opie-e52158d2f9e1fdc9766d991dc672729648d5a020.tar.gz
opie-e52158d2f9e1fdc9766d991dc672729648d5a020.tar.bz2
Sharp ROM compatibilty upgrade:
All these functions are needed to get qtmail (from the Sharp ROM) running on Opie - I have even tested qtmail on an iPAQ and it seems to work ..
Diffstat (limited to 'library') (more/less context) (ignore whitespace changes)
-rw-r--r--library/config.cpp12
-rw-r--r--library/config.h5
-rw-r--r--library/datebookmonth.cpp12
-rw-r--r--library/datebookmonth.h15
-rw-r--r--library/qpemenubar.cpp9
-rw-r--r--library/qpemenubar.h7
6 files changed, 59 insertions, 1 deletions
diff --git a/library/config.cpp b/library/config.cpp
index 1121cd4..b47c620 100644
--- a/library/config.cpp
+++ b/library/config.cpp
@@ -1,488 +1,500 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#include <qdir.h> 21#include <qdir.h>
22#include <qfile.h> 22#include <qfile.h>
23#include <qfileinfo.h> 23#include <qfileinfo.h>
24#include <qmessagebox.h> 24#include <qmessagebox.h>
25#if QT_VERSION <= 230 && defined(QT_NO_CODECS) 25#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
26#include <qtextcodec.h> 26#include <qtextcodec.h>
27#endif 27#endif
28#include <qtextstream.h> 28#include <qtextstream.h>
29 29
30#include <sys/stat.h> 30#include <sys/stat.h>
31#include <sys/types.h> 31#include <sys/types.h>
32#include <fcntl.h> 32#include <fcntl.h>
33#include <stdlib.h> 33#include <stdlib.h>
34#include <unistd.h> 34#include <unistd.h>
35 35
36#define QTOPIA_INTERNAL_LANGLIST 36#define QTOPIA_INTERNAL_LANGLIST
37#include "config.h" 37#include "config.h"
38#include "global.h" 38#include "global.h"
39 39
40 40
41/*! 41/*!
42 \internal 42 \internal
43*/ 43*/
44QString Config::configFilename(const QString& name, Domain d) 44QString Config::configFilename(const QString& name, Domain d)
45{ 45{
46 switch (d) { 46 switch (d) {
47 case File: 47 case File:
48 return name; 48 return name;
49 case User: { 49 case User: {
50 QDir dir = (QString(getenv("HOME")) + "/Settings"); 50 QDir dir = (QString(getenv("HOME")) + "/Settings");
51 if ( !dir.exists() ) 51 if ( !dir.exists() )
52 mkdir(dir.path().local8Bit(),0700); 52 mkdir(dir.path().local8Bit(),0700);
53 return dir.path() + "/" + name + ".conf"; 53 return dir.path() + "/" + name + ".conf";
54 } 54 }
55 } 55 }
56 return name; 56 return name;
57} 57}
58 58
59/*! 59/*!
60 \class Config config.h 60 \class Config config.h
61 \brief The Config class provides for saving application cofniguration state. 61 \brief The Config class provides for saving application cofniguration state.
62 62
63 You should keep a Config in existence only while you do not want others 63 You should keep a Config in existence only while you do not want others
64 to be able to change the state. There is no locking currently, but there 64 to be able to change the state. There is no locking currently, but there
65 may be in the future. 65 may be in the future.
66*/ 66*/
67 67
68/*! 68/*!
69 \enum Config::ConfigGroup 69 \enum Config::ConfigGroup
70 \internal 70 \internal
71*/ 71*/
72 72
73/*! 73/*!
74 \enum Config::Domain 74 \enum Config::Domain
75 75
76 \value File 76 \value File
77 \value User 77 \value User
78 78
79 See Config for details. 79 See Config for details.
80*/ 80*/
81 81
82/*! 82/*!
83 Constructs a config that will load or create a configuration with the 83 Constructs a config that will load or create a configuration with the
84 given \a name in the given \a domain. 84 given \a name in the given \a domain.
85 85
86 You must call setGroup() before doing much else with the Config. 86 You must call setGroup() before doing much else with the Config.
87 87
88 In the default Domain, \e User, 88 In the default Domain, \e User,
89 the configuration is user-specific. \a name should not contain "/" in 89 the configuration is user-specific. \a name should not contain "/" in
90 this case, and in general should be the name of the C++ class that is 90 this case, and in general should be the name of the C++ class that is
91 primarily responsible for maintaining the configuration. 91 primarily responsible for maintaining the configuration.
92 92
93 In the File Domain, \a name is an absolute filename. 93 In the File Domain, \a name is an absolute filename.
94*/ 94*/
95Config::Config( const QString &name, Domain domain ) 95Config::Config( const QString &name, Domain domain )
96 : filename( configFilename(name,domain) ) 96 : filename( configFilename(name,domain) )
97{ 97{
98 git = groups.end(); 98 git = groups.end();
99 read(); 99 read();
100 QStringList l = Global::languageList(); 100 QStringList l = Global::languageList();
101 lang = l[0]; 101 lang = l[0];
102 glang = l[1]; 102 glang = l[1];
103} 103}
104 104
105
106// Sharp ROM compatibility
107Config::Config ( const QString &name, bool what )
108 : filename( configFilename(name,what ? User : File) )
109{
110 git = groups.end();
111 read();
112 QStringList l = Global::languageList();
113 lang = l[0];
114 glang = l[1];
115}
116
105/*! 117/*!
106 Writes any changes to disk and destroys the in-memory object. 118 Writes any changes to disk and destroys the in-memory object.
107*/ 119*/
108Config::~Config() 120Config::~Config()
109{ 121{
110 if ( changed ) 122 if ( changed )
111 write(); 123 write();
112} 124}
113 125
114/*! 126/*!
115 Returns whether the current group has an entry called \a key. 127 Returns whether the current group has an entry called \a key.
116*/ 128*/
117bool Config::hasKey( const QString &key ) const 129bool Config::hasKey( const QString &key ) const
118{ 130{
119 if ( groups.end() == git ) 131 if ( groups.end() == git )
120 return FALSE; 132 return FALSE;
121 ConfigGroup::ConstIterator it = ( *git ).find( key ); 133 ConfigGroup::ConstIterator it = ( *git ).find( key );
122 return it != ( *git ).end(); 134 return it != ( *git ).end();
123} 135}
124 136
125/*! 137/*!
126 Sets the current group for subsequent reading and writing of 138 Sets the current group for subsequent reading and writing of
127 entries to \a gname. Grouping allows the application to partition the namespace. 139 entries to \a gname. Grouping allows the application to partition the namespace.
128 140
129 This function must be called prior to any reading or writing 141 This function must be called prior to any reading or writing
130 of entries. 142 of entries.
131 143
132 The \a gname must not be empty. 144 The \a gname must not be empty.
133*/ 145*/
134void Config::setGroup( const QString &gname ) 146void Config::setGroup( const QString &gname )
135{ 147{
136 QMap< QString, ConfigGroup>::Iterator it = groups.find( gname ); 148 QMap< QString, ConfigGroup>::Iterator it = groups.find( gname );
137 if ( it == groups.end() ) { 149 if ( it == groups.end() ) {
138 git = groups.insert( gname, ConfigGroup() ); 150 git = groups.insert( gname, ConfigGroup() );
139 changed = TRUE; 151 changed = TRUE;
140 return; 152 return;
141 } 153 }
142 git = it; 154 git = it;
143} 155}
144 156
145/*! 157/*!
146 Writes a (\a key, \a value) entry to the current group. 158 Writes a (\a key, \a value) entry to the current group.
147 159
148 \sa readEntry() 160 \sa readEntry()
149*/ 161*/
150void Config::writeEntry( const QString &key, const char* value ) 162void Config::writeEntry( const QString &key, const char* value )
151{ 163{
152 writeEntry(key,QString(value)); 164 writeEntry(key,QString(value));
153} 165}
154 166
155/*! 167/*!
156 Writes a (\a key, \a value) entry to the current group. 168 Writes a (\a key, \a value) entry to the current group.
157 169
158 \sa readEntry() 170 \sa readEntry()
159*/ 171*/
160void Config::writeEntry( const QString &key, const QString &value ) 172void Config::writeEntry( const QString &key, const QString &value )
161{ 173{
162 if ( git == groups.end() ) { 174 if ( git == groups.end() ) {
163 qWarning( "no group set" ); 175 qWarning( "no group set" );
164 return; 176 return;
165 } 177 }
166 if ( (*git)[key] != value ) { 178 if ( (*git)[key] != value ) {
167 ( *git ).insert( key, value ); 179 ( *git ).insert( key, value );
168 changed = TRUE; 180 changed = TRUE;
169 } 181 }
170} 182}
171 183
172/* 184/*
173 Note that the degree of protection offered by the encryption here is 185 Note that the degree of protection offered by the encryption here is
174 only sufficient to avoid the most casual observation of the configuration 186 only sufficient to avoid the most casual observation of the configuration
175 files. People with access to the files can write down the contents and 187 files. People with access to the files can write down the contents and
176 decrypt it using this source code. 188 decrypt it using this source code.
177 189
178 Conceivably, and at some burden to the user, this encryption could 190 Conceivably, and at some burden to the user, this encryption could
179 be improved. 191 be improved.
180*/ 192*/
181static QString encipher(const QString& plain) 193static QString encipher(const QString& plain)
182{ 194{
183 // mainly, we make it long 195 // mainly, we make it long
184 QString cipher; 196 QString cipher;
185 int mix=28730492; 197 int mix=28730492;
186 for (int i=0; i<(int)plain.length(); i++) { 198 for (int i=0; i<(int)plain.length(); i++) {
187 int u = plain[i].unicode(); 199 int u = plain[i].unicode();
188 int c = u ^ mix; 200 int c = u ^ mix;
189 QString x = QString::number(c,36); 201 QString x = QString::number(c,36);
190 cipher.append(QChar('a'+x.length())); 202 cipher.append(QChar('a'+x.length()));
191 cipher.append(x); 203 cipher.append(x);
192 mix *= u; 204 mix *= u;
193 } 205 }
194 return cipher; 206 return cipher;
195} 207}
196 208
197static QString decipher(const QString& cipher) 209static QString decipher(const QString& cipher)
198{ 210{
199 QString plain; 211 QString plain;
200 int mix=28730492; 212 int mix=28730492;
201 for (int i=0; i<(int)cipher.length();) { 213 for (int i=0; i<(int)cipher.length();) {
202 int l = cipher[i].unicode()-'a'; 214 int l = cipher[i].unicode()-'a';
203 QString x = cipher.mid(i+1,l); i+=l+1; 215 QString x = cipher.mid(i+1,l); i+=l+1;
204 int u = x.toInt(0,36) ^ mix; 216 int u = x.toInt(0,36) ^ mix;
205 plain.append(QChar(u)); 217 plain.append(QChar(u));
206 mix *= u; 218 mix *= u;
207 } 219 }
208 return plain; 220 return plain;
209} 221}
210 222
211/*! 223/*!
212 Writes an encrypted (\a key, \a value) entry to the current group. 224 Writes an encrypted (\a key, \a value) entry to the current group.
213 225
214 Note that the degree of protection offered by the encryption is 226 Note that the degree of protection offered by the encryption is
215 only sufficient to avoid the most casual observation of the configuration 227 only sufficient to avoid the most casual observation of the configuration
216 files. 228 files.
217 229
218 \sa readEntry() 230 \sa readEntry()
219*/ 231*/
220void Config::writeEntryCrypt( const QString &key, const QString &value ) 232void Config::writeEntryCrypt( const QString &key, const QString &value )
221{ 233{
222 if ( git == groups.end() ) { 234 if ( git == groups.end() ) {
223 qWarning( "no group set" ); 235 qWarning( "no group set" );
224 return; 236 return;
225 } 237 }
226 QString evalue = encipher(value); 238 QString evalue = encipher(value);
227 if ( (*git)[key] != evalue ) { 239 if ( (*git)[key] != evalue ) {
228 ( *git ).insert( key, evalue ); 240 ( *git ).insert( key, evalue );
229 changed = TRUE; 241 changed = TRUE;
230 } 242 }
231} 243}
232 244
233/*! 245/*!
234 Writes a (\a key, \a num) entry to the current group. 246 Writes a (\a key, \a num) entry to the current group.
235 247
236 \sa readNumEntry() 248 \sa readNumEntry()
237*/ 249*/
238void Config::writeEntry( const QString &key, int num ) 250void Config::writeEntry( const QString &key, int num )
239{ 251{
240 QString s; 252 QString s;
241 s.setNum( num ); 253 s.setNum( num );
242 writeEntry( key, s ); 254 writeEntry( key, s );
243} 255}
244 256
245#ifdef Q_HAS_BOOL_TYPE 257#ifdef Q_HAS_BOOL_TYPE
246/*! 258/*!
247 Writes a (\a key, \a b) entry to the current group. This is equivalent 259 Writes a (\a key, \a b) entry to the current group. This is equivalent
248 to writing a 0 or 1 as an integer entry. 260 to writing a 0 or 1 as an integer entry.
249 261
250 \sa readBoolEntry() 262 \sa readBoolEntry()
251*/ 263*/
252void Config::writeEntry( const QString &key, bool b ) 264void Config::writeEntry( const QString &key, bool b )
253{ 265{
254 QString s; 266 QString s;
255 s.setNum( ( int )b ); 267 s.setNum( ( int )b );
256 writeEntry( key, s ); 268 writeEntry( key, s );
257} 269}
258#endif 270#endif
259 271
260/*! 272/*!
261 Writes a (\a key, \a lst) entry to the current group. The list 273 Writes a (\a key, \a lst) entry to the current group. The list
262 is separated by \a sep, so the strings must not contain that character. 274 is separated by \a sep, so the strings must not contain that character.
263 275
264 \sa readListEntry() 276 \sa readListEntry()
265*/ 277*/
266void Config::writeEntry( const QString &key, const QStringList &lst, const QChar &sep ) 278void Config::writeEntry( const QString &key, const QStringList &lst, const QChar &sep )
267{ 279{
268 QString s; 280 QString s;
269 QStringList::ConstIterator it = lst.begin(); 281 QStringList::ConstIterator it = lst.begin();
270 for ( ; it != lst.end(); ++it ) 282 for ( ; it != lst.end(); ++it )
271 s += *it + sep; 283 s += *it + sep;
272 writeEntry( key, s ); 284 writeEntry( key, s );
273} 285}
274 286
275/*! 287/*!
276 Removes the \a key entry from the current group. Does nothing if 288 Removes the \a key entry from the current group. Does nothing if
277 there is no such entry. 289 there is no such entry.
278*/ 290*/
279 291
280void Config::removeEntry( const QString &key ) 292void Config::removeEntry( const QString &key )
281{ 293{
282 if ( git == groups.end() ) { 294 if ( git == groups.end() ) {
283 qWarning( "no group set" ); 295 qWarning( "no group set" );
284 return; 296 return;
285 } 297 }
286 ( *git ).remove( key ); 298 ( *git ).remove( key );
287 changed = TRUE; 299 changed = TRUE;
288} 300}
289 301
290/*! 302/*!
291 \fn bool Config::operator == ( const Config & other ) const 303 \fn bool Config::operator == ( const Config & other ) const
292 304
293 Tests for equality with \a other. Config objects are equal if they refer to the same filename. 305 Tests for equality with \a other. Config objects are equal if they refer to the same filename.
294*/ 306*/
295 307
296/*! 308/*!
297 \fn bool Config::operator != ( const Config & other ) const 309 \fn bool Config::operator != ( const Config & other ) const
298 310
299 Tests for inequality with \a other. Config objects are equal if they refer to the same filename. 311 Tests for inequality with \a other. Config objects are equal if they refer to the same filename.
300*/ 312*/
301 313
302/*! 314/*!
303 \fn QString Config::readEntry( const QString &key, const QString &deflt ) const 315 \fn QString Config::readEntry( const QString &key, const QString &deflt ) const
304 316
305 Reads a string entry stored with \a key, defaulting to \a deflt if there is no entry. 317 Reads a string entry stored with \a key, defaulting to \a deflt if there is no entry.
306*/ 318*/
307 319
308/*! 320/*!
309 \internal 321 \internal
310 For compatibility, non-const version. 322 For compatibility, non-const version.
311*/ 323*/
312QString Config::readEntry( const QString &key, const QString &deflt ) 324QString Config::readEntry( const QString &key, const QString &deflt )
313{ 325{
314 QString res = readEntryDirect( key+"["+lang+"]" ); 326 QString res = readEntryDirect( key+"["+lang+"]" );
315 if ( !res.isNull() ) 327 if ( !res.isNull() )
316 return res; 328 return res;
317 if ( !glang.isEmpty() ) { 329 if ( !glang.isEmpty() ) {
318 res = readEntryDirect( key+"["+glang+"]" ); 330 res = readEntryDirect( key+"["+glang+"]" );
319 if ( !res.isNull() ) 331 if ( !res.isNull() )
320 return res; 332 return res;
321 } 333 }
322 return readEntryDirect( key, deflt ); 334 return readEntryDirect( key, deflt );
323} 335}
324 336
325/*! 337/*!
326 \fn QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const 338 \fn QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const
327 339
328 Reads an encrypted string entry stored with \a key, defaulting to \a deflt if there is no entry. 340 Reads an encrypted string entry stored with \a key, defaulting to \a deflt if there is no entry.
329*/ 341*/
330 342
331/*! 343/*!
332 \internal 344 \internal
333 For compatibility, non-const version. 345 For compatibility, non-const version.
334*/ 346*/
335QString Config::readEntryCrypt( const QString &key, const QString &deflt ) 347QString Config::readEntryCrypt( const QString &key, const QString &deflt )
336{ 348{
337 QString res = readEntryDirect( key+"["+lang+"]" ); 349 QString res = readEntryDirect( key+"["+lang+"]" );
338 if ( res.isNull() && glang.isEmpty() ) 350 if ( res.isNull() && glang.isEmpty() )
339 res = readEntryDirect( key+"["+glang+"]" ); 351 res = readEntryDirect( key+"["+glang+"]" );
340 if ( res.isNull() ) 352 if ( res.isNull() )
341 res = readEntryDirect( key, QString::null ); 353 res = readEntryDirect( key, QString::null );
342 if ( res.isNull() ) 354 if ( res.isNull() )
343 return deflt; 355 return deflt;
344 return decipher(res); 356 return decipher(res);
345} 357}
346 358
347/*! 359/*!
348 \fn QString Config::readEntryDirect( const QString &key, const QString &deflt ) const 360 \fn QString Config::readEntryDirect( const QString &key, const QString &deflt ) const
349 \internal 361 \internal
350*/ 362*/
351 363
352/*! 364/*!
353 \internal 365 \internal
354 For compatibility, non-const version. 366 For compatibility, non-const version.
355*/ 367*/
356QString Config::readEntryDirect( const QString &key, const QString &deflt ) 368QString Config::readEntryDirect( const QString &key, const QString &deflt )
357{ 369{
358 if ( git == groups.end() ) { 370 if ( git == groups.end() ) {
359 //qWarning( "no group set" ); 371 //qWarning( "no group set" );
360 return deflt; 372 return deflt;
361 } 373 }
362 ConfigGroup::ConstIterator it = ( *git ).find( key ); 374 ConfigGroup::ConstIterator it = ( *git ).find( key );
363 if ( it != ( *git ).end() ) 375 if ( it != ( *git ).end() )
364 return *it; 376 return *it;
365 else 377 else
366 return deflt; 378 return deflt;
367} 379}
368 380
369/*! 381/*!
370 \fn int Config::readNumEntry( const QString &key, int deflt ) const 382 \fn int Config::readNumEntry( const QString &key, int deflt ) const
371 Reads a numeric entry stored with \a key, defaulting to \a deflt if there is no entry. 383 Reads a numeric entry stored with \a key, defaulting to \a deflt if there is no entry.
372*/ 384*/
373 385
374/*! 386/*!
375 \internal 387 \internal
376 For compatibility, non-const version. 388 For compatibility, non-const version.
377*/ 389*/
378int Config::readNumEntry( const QString &key, int deflt ) 390int Config::readNumEntry( const QString &key, int deflt )
379{ 391{
380 QString s = readEntry( key ); 392 QString s = readEntry( key );
381 if ( s.isEmpty() ) 393 if ( s.isEmpty() )
382 return deflt; 394 return deflt;
383 else 395 else
384 return s.toInt(); 396 return s.toInt();
385} 397}
386 398
387/*! 399/*!
388 \fn bool Config::readBoolEntry( const QString &key, bool deflt ) const 400 \fn bool Config::readBoolEntry( const QString &key, bool deflt ) const
389 Reads a bool entry stored with \a key, defaulting to \a deflt if there is no entry. 401 Reads a bool entry stored with \a key, defaulting to \a deflt if there is no entry.
390*/ 402*/
391 403
392/*! 404/*!
393 \internal 405 \internal
394 For compatibility, non-const version. 406 For compatibility, non-const version.
395*/ 407*/
396bool Config::readBoolEntry( const QString &key, bool deflt ) 408bool Config::readBoolEntry( const QString &key, bool deflt )
397{ 409{
398 QString s = readEntry( key ); 410 QString s = readEntry( key );
399 if ( s.isEmpty() ) 411 if ( s.isEmpty() )
400 return deflt; 412 return deflt;
401 else 413 else
402 return (bool)s.toInt(); 414 return (bool)s.toInt();
403} 415}
404 416
405/*! 417/*!
406 \fn QStringList Config::readListEntry( const QString &key, const QChar &sep ) const 418 \fn QStringList Config::readListEntry( const QString &key, const QChar &sep ) const
407 Reads a string list entry stored with \a key, and with \a sep as the separator. 419 Reads a string list entry stored with \a key, and with \a sep as the separator.
408*/ 420*/
409 421
410/*! 422/*!
411 \internal 423 \internal
412 For compatibility, non-const version. 424 For compatibility, non-const version.
413*/ 425*/
414QStringList Config::readListEntry( const QString &key, const QChar &sep ) 426QStringList Config::readListEntry( const QString &key, const QChar &sep )
415{ 427{
416 QString s = readEntry( key ); 428 QString s = readEntry( key );
417 if ( s.isEmpty() ) 429 if ( s.isEmpty() )
418 return QStringList(); 430 return QStringList();
419 else 431 else
420 return QStringList::split( sep, s ); 432 return QStringList::split( sep, s );
421} 433}
422 434
423/*! 435/*!
424 Removes all entries from the current group. 436 Removes all entries from the current group.
425*/ 437*/
426void Config::clearGroup() 438void Config::clearGroup()
427{ 439{
428 if ( git == groups.end() ) { 440 if ( git == groups.end() ) {
429 qWarning( "no group set" ); 441 qWarning( "no group set" );
430 return; 442 return;
431 } 443 }
432 if ( !(*git).isEmpty() ) { 444 if ( !(*git).isEmpty() ) {
433 ( *git ).clear(); 445 ( *git ).clear();
434 changed = TRUE; 446 changed = TRUE;
435 } 447 }
436} 448}
437 449
438/*! 450/*!
439 \internal 451 \internal
440*/ 452*/
441void Config::write( const QString &fn ) 453void Config::write( const QString &fn )
442{ 454{
443 QString strNewFile; 455 QString strNewFile;
444 if ( !fn.isEmpty() ) 456 if ( !fn.isEmpty() )
445 filename = fn; 457 filename = fn;
446 strNewFile = filename + ".new"; 458 strNewFile = filename + ".new";
447 459
448 QFile f( strNewFile ); 460 QFile f( strNewFile );
449 if ( !f.open( IO_WriteOnly|IO_Raw ) ) { 461 if ( !f.open( IO_WriteOnly|IO_Raw ) ) {
450 qWarning( "could not open for writing `%s'", strNewFile.latin1() ); 462 qWarning( "could not open for writing `%s'", strNewFile.latin1() );
451 git = groups.end(); 463 git = groups.end();
452 return; 464 return;
453 } 465 }
454 466
455 QString str; 467 QString str;
456 QCString cstr; 468 QCString cstr;
457 QMap< QString, ConfigGroup >::Iterator g_it = groups.begin(); 469 QMap< QString, ConfigGroup >::Iterator g_it = groups.begin();
458 470
459 for ( ; g_it != groups.end(); ++g_it ) { 471 for ( ; g_it != groups.end(); ++g_it ) {
460 str += "[" + g_it.key() + "]\n"; 472 str += "[" + g_it.key() + "]\n";
461 ConfigGroup::Iterator e_it = ( *g_it ).begin(); 473 ConfigGroup::Iterator e_it = ( *g_it ).begin();
462 for ( ; e_it != ( *g_it ).end(); ++e_it ) 474 for ( ; e_it != ( *g_it ).end(); ++e_it )
463 str += e_it.key() + " = " + *e_it + "\n"; 475 str += e_it.key() + " = " + *e_it + "\n";
464 } 476 }
465 cstr = str.utf8(); 477 cstr = str.utf8();
466 478
467 int total_length; 479 int total_length;
468 total_length = f.writeBlock( cstr.data(), cstr.length() ); 480 total_length = f.writeBlock( cstr.data(), cstr.length() );
469 if ( total_length != int(cstr.length()) ) { 481 if ( total_length != int(cstr.length()) ) {
470 QMessageBox::critical( 0, QObject::tr("Out of Space"), 482 QMessageBox::critical( 0, QObject::tr("Out of Space"),
471 QObject::tr("There was a problem creating\nConfiguration Information \nfor this program.\n\nPlease free up some space and\ntry again.") ); 483 QObject::tr("There was a problem creating\nConfiguration Information \nfor this program.\n\nPlease free up some space and\ntry again.") );
472 f.close(); 484 f.close();
473 QFile::remove( strNewFile ); 485 QFile::remove( strNewFile );
474 return; 486 return;
475 } 487 }
476 488
477 f.close(); 489 f.close();
478 // now rename the file... 490 // now rename the file...
479 if ( rename( strNewFile, filename ) < 0 ) { 491 if ( rename( strNewFile, filename ) < 0 ) {
480 qWarning( "problem renaming the file %s to %s", strNewFile.latin1(), 492 qWarning( "problem renaming the file %s to %s", strNewFile.latin1(),
481 filename.latin1() ); 493 filename.latin1() );
482 QFile::remove( strNewFile ); 494 QFile::remove( strNewFile );
483 } 495 }
484} 496}
485 497
486/*! 498/*!
487 Returns whether the Config is in a valid state. 499 Returns whether the Config is in a valid state.
488*/ 500*/
diff --git a/library/config.h b/library/config.h
index 1dc32fa..0bab7ca 100644
--- a/library/config.h
+++ b/library/config.h
@@ -1,102 +1,105 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#ifndef CONFIG_H 21#ifndef CONFIG_H
22#define CONFIG_H 22#define CONFIG_H
23 23
24// ##### could use QSettings with Qt 3.0 24// ##### could use QSettings with Qt 3.0
25 25
26#include <qmap.h> 26#include <qmap.h>
27#include <qstringlist.h> 27#include <qstringlist.h>
28 28
29class ConfigPrivate; 29class ConfigPrivate;
30class Config 30class Config
31{ 31{
32public: 32public:
33 typedef QMap< QString, QString > ConfigGroup; 33 typedef QMap< QString, QString > ConfigGroup;
34 34
35 enum Domain { File, User }; 35 enum Domain { File, User };
36 Config( const QString &name, Domain domain=User ); 36 Config( const QString &name, Domain domain=User );
37 ~Config(); 37 ~Config();
38 38
39 bool operator == ( const Config & other ) const { return (filename == other.filename); } 39 bool operator == ( const Config & other ) const { return (filename == other.filename); }
40 bool operator != ( const Config & other ) const { return (filename != other.filename); } 40 bool operator != ( const Config & other ) const { return (filename != other.filename); }
41 41
42 bool isValid() const; 42 bool isValid() const;
43 bool hasKey( const QString &key ) const; 43 bool hasKey( const QString &key ) const;
44 44
45 void setGroup( const QString &gname ); 45 void setGroup( const QString &gname );
46 void writeEntry( const QString &key, const char* value ); 46 void writeEntry( const QString &key, const char* value );
47 void writeEntry( const QString &key, const QString &value ); 47 void writeEntry( const QString &key, const QString &value );
48 void writeEntryCrypt( const QString &key, const QString &value ); 48 void writeEntryCrypt( const QString &key, const QString &value );
49 void writeEntry( const QString &key, int num ); 49 void writeEntry( const QString &key, int num );
50#ifdef Q_HAS_BOOL_TYPE 50#ifdef Q_HAS_BOOL_TYPE
51 void writeEntry( const QString &key, bool b ); 51 void writeEntry( const QString &key, bool b );
52#endif 52#endif
53 void writeEntry( const QString &key, const QStringList &lst, const QChar &sep ); 53 void writeEntry( const QString &key, const QStringList &lst, const QChar &sep );
54 void removeEntry( const QString &key ); 54 void removeEntry( const QString &key );
55 55
56 QString readEntry( const QString &key, const QString &deflt = QString::null ) const; 56 QString readEntry( const QString &key, const QString &deflt = QString::null ) const;
57 QString readEntryCrypt( const QString &key, const QString &deflt = QString::null ) const; 57 QString readEntryCrypt( const QString &key, const QString &deflt = QString::null ) const;
58 QString readEntryDirect( const QString &key, const QString &deflt = QString::null ) const; 58 QString readEntryDirect( const QString &key, const QString &deflt = QString::null ) const;
59 int readNumEntry( const QString &key, int deflt = -1 ) const; 59 int readNumEntry( const QString &key, int deflt = -1 ) const;
60 bool readBoolEntry( const QString &key, bool deflt = FALSE ) const; 60 bool readBoolEntry( const QString &key, bool deflt = FALSE ) const;
61 QStringList readListEntry( const QString &key, const QChar &sep ) const; 61 QStringList readListEntry( const QString &key, const QChar &sep ) const;
62 62
63 // For compatibility, non-const versions. 63 // For compatibility, non-const versions.
64 QString readEntry( const QString &key, const QString &deflt ); 64 QString readEntry( const QString &key, const QString &deflt );
65 QString readEntryCrypt( const QString &key, const QString &deflt ); 65 QString readEntryCrypt( const QString &key, const QString &deflt );
66 QString readEntryDirect( const QString &key, const QString &deflt ); 66 QString readEntryDirect( const QString &key, const QString &deflt );
67 int readNumEntry( const QString &key, int deflt ); 67 int readNumEntry( const QString &key, int deflt );
68 bool readBoolEntry( const QString &key, bool deflt ); 68 bool readBoolEntry( const QString &key, bool deflt );
69 QStringList readListEntry( const QString &key, const QChar &sep ); 69 QStringList readListEntry( const QString &key, const QChar &sep );
70 70
71 void clearGroup(); 71 void clearGroup();
72 72
73 void write( const QString &fn = QString::null ); 73 void write( const QString &fn = QString::null );
74 74
75protected: 75protected:
76 void read(); 76 void read();
77 bool parse( const QString &line ); 77 bool parse( const QString &line );
78 78
79 QMap< QString, ConfigGroup > groups; 79 QMap< QString, ConfigGroup > groups;
80 QMap< QString, ConfigGroup >::Iterator git; 80 QMap< QString, ConfigGroup >::Iterator git;
81 QString filename; 81 QString filename;
82 QString lang; 82 QString lang;
83 QString glang; 83 QString glang;
84 bool changed; 84 bool changed;
85 ConfigPrivate *d; 85 ConfigPrivate *d;
86 static QString configFilename(const QString& name, Domain); 86 static QString configFilename(const QString& name, Domain);
87
88private: // Sharp ROM compatibility
89 Config( const QString &name, bool what );
87}; 90};
88 91
89inline QString Config::readEntry( const QString &key, const QString &deflt ) const 92inline QString Config::readEntry( const QString &key, const QString &deflt ) const
90{ return ((Config*)this)->readEntry(key,deflt); } 93{ return ((Config*)this)->readEntry(key,deflt); }
91inline QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const 94inline QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const
92{ return ((Config*)this)->readEntryCrypt(key,deflt); } 95{ return ((Config*)this)->readEntryCrypt(key,deflt); }
93inline QString Config::readEntryDirect( const QString &key, const QString &deflt ) const 96inline QString Config::readEntryDirect( const QString &key, const QString &deflt ) const
94{ return ((Config*)this)->readEntryDirect(key,deflt); } 97{ return ((Config*)this)->readEntryDirect(key,deflt); }
95inline int Config::readNumEntry( const QString &key, int deflt ) const 98inline int Config::readNumEntry( const QString &key, int deflt ) const
96{ return ((Config*)this)->readNumEntry(key,deflt); } 99{ return ((Config*)this)->readNumEntry(key,deflt); }
97inline bool Config::readBoolEntry( const QString &key, bool deflt ) const 100inline bool Config::readBoolEntry( const QString &key, bool deflt ) const
98{ return ((Config*)this)->readBoolEntry(key,deflt); } 101{ return ((Config*)this)->readBoolEntry(key,deflt); }
99inline QStringList Config::readListEntry( const QString &key, const QChar &sep ) const 102inline QStringList Config::readListEntry( const QString &key, const QChar &sep ) const
100{ return ((Config*)this)->readListEntry(key,sep); } 103{ return ((Config*)this)->readListEntry(key,sep); }
101 104
102#endif 105#endif
diff --git a/library/datebookmonth.cpp b/library/datebookmonth.cpp
index 4a9dcbd..e8be313 100644
--- a/library/datebookmonth.cpp
+++ b/library/datebookmonth.cpp
@@ -367,384 +367,396 @@ void DateBookMonthTable::setupLabels()
367 // setColumnStretchable( i, TRUE ); 367 // setColumnStretchable( i, TRUE );
368 if ( d->onMonday ) 368 if ( d->onMonday )
369 horizontalHeader()->setLabel( i, Calendar::nameOfDay( i + 1 ) ); 369 horizontalHeader()->setLabel( i, Calendar::nameOfDay( i + 1 ) );
370 else { 370 else {
371 if ( i == 0 ) 371 if ( i == 0 )
372 horizontalHeader()->setLabel( i, Calendar::nameOfDay( 7 ) ); 372 horizontalHeader()->setLabel( i, Calendar::nameOfDay( 7 ) );
373 else 373 else
374 horizontalHeader()->setLabel( i, Calendar::nameOfDay( i ) ); 374 horizontalHeader()->setLabel( i, Calendar::nameOfDay( i ) );
375 } 375 }
376 } 376 }
377} 377}
378 378
379 379
380//--------------------------------------------------------------------------- 380//---------------------------------------------------------------------------
381 381
382DateBookMonth::DateBookMonth( QWidget *parent, const char *name, bool ac, 382DateBookMonth::DateBookMonth( QWidget *parent, const char *name, bool ac,
383 DateBookDB *data ) 383 DateBookDB *data )
384 : QVBox( parent, name ), 384 : QVBox( parent, name ),
385 autoClose( ac ) 385 autoClose( ac )
386{ 386{
387 setFocusPolicy(StrongFocus); 387 setFocusPolicy(StrongFocus);
388 year = QDate::currentDate().year(); 388 year = QDate::currentDate().year();
389 month = QDate::currentDate().month(); 389 month = QDate::currentDate().month();
390 day = QDate::currentDate().day(); 390 day = QDate::currentDate().day();
391 header = new DateBookMonthHeader( this, "DateBookMonthHeader" ); 391 header = new DateBookMonthHeader( this, "DateBookMonthHeader" );
392 table = new DateBookMonthTable( this, "DateBookMonthTable", data ); 392 table = new DateBookMonthTable( this, "DateBookMonthTable", data );
393 header->setDate( year, month ); 393 header->setDate( year, month );
394 table->setDate( year, month, QDate::currentDate().day() ); 394 table->setDate( year, month, QDate::currentDate().day() );
395 header->setFocusPolicy(NoFocus); 395 header->setFocusPolicy(NoFocus);
396 table->setFocusPolicy(NoFocus); 396 table->setFocusPolicy(NoFocus);
397 connect( header, SIGNAL( dateChanged( int, int ) ), 397 connect( header, SIGNAL( dateChanged( int, int ) ),
398 this, SLOT( setDate( int, int ) ) ); 398 this, SLOT( setDate( int, int ) ) );
399 connect( table, SIGNAL( dateClicked( int, int, int ) ), 399 connect( table, SIGNAL( dateClicked( int, int, int ) ),
400 this, SLOT( finalDate(int, int, int) ) ); 400 this, SLOT( finalDate(int, int, int) ) );
401 connect( qApp, SIGNAL(weekChanged(bool)), this, 401 connect( qApp, SIGNAL(weekChanged(bool)), this,
402 SLOT(slotWeekChange(bool)) ); 402 SLOT(slotWeekChange(bool)) );
403 table->setFocus(); 403 table->setFocus();
404} 404}
405 405
406DateBookMonth::~DateBookMonth() 406DateBookMonth::~DateBookMonth()
407{ 407{
408 408
409} 409}
410 410
411void DateBookMonth::setDate( int y, int m ) 411void DateBookMonth::setDate( int y, int m )
412{ 412{
413 /* only change the date if this is a different date, 413 /* only change the date if this is a different date,
414 * other wise we may mistakenly overide the day */ 414 * other wise we may mistakenly overide the day */
415 if ( (y != year) || (m != month) ) { 415 if ( (y != year) || (m != month) ) {
416 year = y; 416 year = y;
417 month = m; 417 month = m;
418 QDate nd( y, m, 1 ); 418 QDate nd( y, m, 1 );
419 if ( nd.daysInMonth() < day ) 419 if ( nd.daysInMonth() < day )
420 day = nd.daysInMonth(); 420 day = nd.daysInMonth();
421 table->setDate( year, month, day ); 421 table->setDate( year, month, day );
422 } 422 }
423} 423}
424 424
425void DateBookMonth::setDate( int y, int m, int d ) 425void DateBookMonth::setDate( int y, int m, int d )
426{ 426{
427 header->setDate( y, m); 427 header->setDate( y, m);
428 table->setDate( y, m, d); 428 table->setDate( y, m, d);
429 year = y; 429 year = y;
430 month = m; 430 month = m;
431 day = d; 431 day = d;
432} 432}
433 433
434/* called when we wish to close or pass back the date */ 434/* called when we wish to close or pass back the date */
435void DateBookMonth::finalDate(int y, int m, int d) 435void DateBookMonth::finalDate(int y, int m, int d)
436{ 436{
437 setDate( y, m, d ); 437 setDate( y, m, d );
438 438
439 emit dateClicked(y, m, d); 439 emit dateClicked(y, m, d);
440 // emit dateClicked(QDate(y, m, d).toString()); 440 // emit dateClicked(QDate(y, m, d).toString());
441 441
442 if ( autoClose && parentWidget() ) 442 if ( autoClose && parentWidget() )
443 parentWidget()->close(); 443 parentWidget()->close();
444} 444}
445 445
446void DateBookMonth::setDate( QDate d) 446void DateBookMonth::setDate( QDate d)
447{ 447{
448 setDate(d.year(), d.month(), d.day()); 448 setDate(d.year(), d.month(), d.day());
449} 449}
450 450
451void DateBookMonth::redraw() 451void DateBookMonth::redraw()
452{ 452{
453 table->setDate( year, month, day ); 453 table->setDate( year, month, day );
454 table->redraw(); 454 table->redraw();
455} 455}
456 456
457QDate DateBookMonth::selectedDate() const 457QDate DateBookMonth::selectedDate() const
458{ 458{
459 if ( !table ) 459 if ( !table )
460 return QDate::currentDate(); 460 return QDate::currentDate();
461 int y, m, d; 461 int y, m, d;
462 table->getDate( y, m, d ); 462 table->getDate( y, m, d );
463 return QDate( y, m, d ); 463 return QDate( y, m, d );
464} 464}
465 465
466void DateBookMonth::slotWeekChange( bool startOnMonday ) 466void DateBookMonth::slotWeekChange( bool startOnMonday )
467{ 467{
468 table->setWeekStart( startOnMonday ); 468 table->setWeekStart( startOnMonday );
469} 469}
470 470
471void DateBookMonth::keyPressEvent( QKeyEvent *e ) 471void DateBookMonth::keyPressEvent( QKeyEvent *e )
472{ 472{
473 switch(e->key()) { 473 switch(e->key()) {
474 case Key_Up: 474 case Key_Up:
475 setDate(QDate(year, month, day).addDays(-7)); 475 setDate(QDate(year, month, day).addDays(-7));
476 break; 476 break;
477 case Key_Down: 477 case Key_Down:
478 setDate(QDate(year, month, day).addDays(7)); 478 setDate(QDate(year, month, day).addDays(7));
479 break; 479 break;
480 case Key_Left: 480 case Key_Left:
481 setDate(QDate(year, month, day).addDays(-1)); 481 setDate(QDate(year, month, day).addDays(-1));
482 break; 482 break;
483 case Key_Right: 483 case Key_Right:
484 setDate(QDate(year, month, day).addDays(1)); 484 setDate(QDate(year, month, day).addDays(1));
485 break; 485 break;
486 case Key_Space: 486 case Key_Space:
487 qWarning("space"); 487 qWarning("space");
488 emit dateClicked(year, month, day); 488 emit dateClicked(year, month, day);
489 if ( autoClose && parentWidget() ) 489 if ( autoClose && parentWidget() )
490 parentWidget()->close(); 490 parentWidget()->close();
491 break; 491 break;
492 default: 492 default:
493 qWarning("ignore"); 493 qWarning("ignore");
494 e->ignore(); 494 e->ignore();
495 break; 495 break;
496 } 496 }
497} 497}
498 498
499//--------------------------------------------------------------------------- 499//---------------------------------------------------------------------------
500class DayItemMonthPrivate 500class DayItemMonthPrivate
501{ 501{
502public: 502public:
503 DayItemMonthPrivate() {}; 503 DayItemMonthPrivate() {};
504 ~DayItemMonthPrivate() { mDayEvents.clear(); }; 504 ~DayItemMonthPrivate() { mDayEvents.clear(); };
505 QValueList<EffectiveEvent> mDayEvents; 505 QValueList<EffectiveEvent> mDayEvents;
506}; 506};
507 507
508DayItemMonth::DayItemMonth( QTable *table, EditType et, const QString &t ) 508DayItemMonth::DayItemMonth( QTable *table, EditType et, const QString &t )
509 : QTableItem( table, et, t ) 509 : QTableItem( table, et, t )
510{ 510{
511 d = new DayItemMonthPrivate(); 511 d = new DayItemMonthPrivate();
512} 512}
513 513
514DayItemMonth::~DayItemMonth() 514DayItemMonth::~DayItemMonth()
515{ 515{
516 daysEvents.clear(); 516 daysEvents.clear();
517 delete d; 517 delete d;
518} 518}
519 519
520void DayItemMonth::setEvents( const QValueList<EffectiveEvent> &effEv ) 520void DayItemMonth::setEvents( const QValueList<EffectiveEvent> &effEv )
521{ 521{
522 d->mDayEvents = effEv; 522 d->mDayEvents = effEv;
523} 523}
524 524
525void DayItemMonth::clearEffEvents() 525void DayItemMonth::clearEffEvents()
526{ 526{
527 d->mDayEvents.clear(); 527 d->mDayEvents.clear();
528} 528}
529 529
530void DayItemMonth::paint( QPainter *p, const QColorGroup &cg, 530void DayItemMonth::paint( QPainter *p, const QColorGroup &cg,
531 const QRect &cr, bool selected ) 531 const QRect &cr, bool selected )
532{ 532{
533 p->save(); 533 p->save();
534 534
535 QColorGroup g( cg ); 535 QColorGroup g( cg );
536 g.setBrush( QColorGroup::Base, back ); 536 g.setBrush( QColorGroup::Base, back );
537 g.setColor( QColorGroup::Text, forg ); 537 g.setColor( QColorGroup::Text, forg );
538 if ( selected ) 538 if ( selected )
539 p->setPen( g.highlightedText() ); 539 p->setPen( g.highlightedText() );
540 else 540 else
541 p->setPen( g.text() ); 541 p->setPen( g.text() );
542 542
543 QValueStack<int> normalLine; 543 QValueStack<int> normalLine;
544 QValueStack<int> repeatLine; 544 QValueStack<int> repeatLine;
545 QValueStack<int> travelLine; 545 QValueStack<int> travelLine;
546 546
547 bool normalAllDay = FALSE; 547 bool normalAllDay = FALSE;
548 bool repeatAllDay = FALSE; 548 bool repeatAllDay = FALSE;
549 bool travelAllDay = FALSE; 549 bool travelAllDay = FALSE;
550 550
551 QValueListIterator<EffectiveEvent> itDays = d->mDayEvents.begin(); 551 QValueListIterator<EffectiveEvent> itDays = d->mDayEvents.begin();
552 552
553 for ( ; itDays != d->mDayEvents.end(); ++itDays ) { 553 for ( ; itDays != d->mDayEvents.end(); ++itDays ) {
554 int w = cr.width(); 554 int w = cr.width();
555 Event ev = (*itDays).event(); 555 Event ev = (*itDays).event();
556 556
557 int f = (*itDays).start().hour(); // assume Effective event 557 int f = (*itDays).start().hour(); // assume Effective event
558 int t = (*itDays).end().hour(); // is truncated. 558 int t = (*itDays).end().hour(); // is truncated.
559 559
560 if (ev.isAllDay()) { 560 if (ev.isAllDay()) {
561 if (!ev.hasRepeat()) 561 if (!ev.hasRepeat())
562 normalAllDay = TRUE; 562 normalAllDay = TRUE;
563 else 563 else
564 repeatAllDay = TRUE; 564 repeatAllDay = TRUE;
565 } else { 565 } else {
566 int sLine, eLine; 566 int sLine, eLine;
567 if (f == 0) 567 if (f == 0)
568 sLine = 0; 568 sLine = 0;
569 else if (f < 8 ) 569 else if (f < 8 )
570 sLine = 1; 570 sLine = 1;
571 else if (f >= 17) 571 else if (f >= 17)
572 sLine = w - 4; 572 sLine = w - 4;
573 else { 573 else {
574 sLine = (f - 8) * (w - 8); 574 sLine = (f - 8) * (w - 8);
575 if (sLine) 575 if (sLine)
576 sLine /= 8; 576 sLine /= 8;
577 sLine += 4; 577 sLine += 4;
578 } 578 }
579 if (t == 23) 579 if (t == 23)
580 eLine = w; 580 eLine = w;
581 else if (t < 8) 581 else if (t < 8)
582 eLine = 4; 582 eLine = 4;
583 else if (t >= 17) 583 else if (t >= 17)
584 eLine = w - 1; 584 eLine = w - 1;
585 else { 585 else {
586 eLine = (t - 8) * (w - 8); 586 eLine = (t - 8) * (w - 8);
587 if (eLine) 587 if (eLine)
588 eLine /= 8; 588 eLine /= 8;
589 eLine += 4; 589 eLine += 4;
590 } 590 }
591 if (!ev.hasRepeat()) { 591 if (!ev.hasRepeat()) {
592 normalLine.push(sLine); 592 normalLine.push(sLine);
593 normalLine.push(eLine); 593 normalLine.push(eLine);
594 } else { 594 } else {
595 repeatLine.push(sLine); 595 repeatLine.push(sLine);
596 repeatLine.push(eLine); 596 repeatLine.push(eLine);
597 } 597 }
598 } 598 }
599 } 599 }
600 600
601 // draw the background 601 // draw the background
602 if (normalAllDay || repeatAllDay || travelAllDay) { 602 if (normalAllDay || repeatAllDay || travelAllDay) {
603 p->save(); 603 p->save();
604 604
605 if (normalAllDay) 605 if (normalAllDay)
606 if (repeatAllDay) { 606 if (repeatAllDay) {
607 p->fillRect( 0, 0, cr.width(), cr.height() / 2, 607 p->fillRect( 0, 0, cr.width(), cr.height() / 2,
608 colorNormalLight ); 608 colorNormalLight );
609 p->fillRect( 0, cr.height() / 2, cr.width(), cr.height() / 2, 609 p->fillRect( 0, cr.height() / 2, cr.width(), cr.height() / 2,
610 colorRepeatLight ); 610 colorRepeatLight );
611 } else 611 } else
612 p->fillRect( 0, 0, cr.width(), cr.height(), 612 p->fillRect( 0, 0, cr.width(), cr.height(),
613 colorNormalLight ); 613 colorNormalLight );
614 else if (repeatAllDay) 614 else if (repeatAllDay)
615 p->fillRect( 0, 0, cr.width(), cr.height(), 615 p->fillRect( 0, 0, cr.width(), cr.height(),
616 colorRepeatLight ); 616 colorRepeatLight );
617 } else { 617 } else {
618 p->fillRect( 0, 0, cr.width(), 618 p->fillRect( 0, 0, cr.width(),
619 cr.height(), selected 619 cr.height(), selected
620 ? g.brush( QColorGroup::Highlight ) 620 ? g.brush( QColorGroup::Highlight )
621 : g.brush( QColorGroup::Base ) ); 621 : g.brush( QColorGroup::Base ) );
622 } 622 }
623 623
624 // The lines 624 // The lines
625 // now for the lines. 625 // now for the lines.
626 int h = 5; 626 int h = 5;
627 int y = cr.height() / 2 - h; 627 int y = cr.height() / 2 - h;
628 628
629 while(normalLine.count() >= 2) { 629 while(normalLine.count() >= 2) {
630 int x2 = normalLine.pop(); 630 int x2 = normalLine.pop();
631 int x1 = normalLine.pop(); 631 int x1 = normalLine.pop();
632 if (x2 < x1 + 2) 632 if (x2 < x1 + 2)
633 x2 = x1 + 2; 633 x2 = x1 + 2;
634 p->fillRect(x1, y, x2 - x1, h, colorNormal); 634 p->fillRect(x1, y, x2 - x1, h, colorNormal);
635 } 635 }
636 636
637 y += h; 637 y += h;
638 638
639 while(repeatLine.count() >= 2) { 639 while(repeatLine.count() >= 2) {
640 int x2 = repeatLine.pop(); 640 int x2 = repeatLine.pop();
641 int x1 = repeatLine.pop(); 641 int x1 = repeatLine.pop();
642 if (x2 < x1 + 2) 642 if (x2 < x1 + 2)
643 x2 = x1 + 2; 643 x2 = x1 + 2;
644 p->fillRect(x1, y, x2 - x1, h, colorRepeat); 644 p->fillRect(x1, y, x2 - x1, h, colorRepeat);
645 } 645 }
646 646
647 647
648 // Finally, draw the number. 648 // Finally, draw the number.
649 QFont f = p->font(); 649 QFont f = p->font();
650 f.setPointSize( ( f.pointSize() / 3 ) * 2 ); 650 f.setPointSize( ( f.pointSize() / 3 ) * 2 );
651 p->setFont( f ); 651 p->setFont( f );
652 QFontMetrics fm( f ); 652 QFontMetrics fm( f );
653 p->drawText( 1, 1 + fm.ascent(), QString::number( day() ) ); 653 p->drawText( 1, 1 + fm.ascent(), QString::number( day() ) );
654 654
655 p->restore(); 655 p->restore();
656} 656}
657 657
658 658
659 659
660void DayItemMonth::setType( Calendar::Day::Type t ) 660void DayItemMonth::setType( Calendar::Day::Type t )
661{ 661{
662 switch ( t ) { 662 switch ( t ) {
663 case Calendar::Day::PrevMonth: 663 case Calendar::Day::PrevMonth:
664 case Calendar::Day::NextMonth: 664 case Calendar::Day::NextMonth:
665 back = QBrush( QColor( 224, 224, 224 ) ); 665 back = QBrush( QColor( 224, 224, 224 ) );
666 forg = black; 666 forg = black;
667 break; 667 break;
668 case Calendar::Day::ThisMonth: 668 case Calendar::Day::ThisMonth:
669 back = QBrush( white ); 669 back = QBrush( white );
670 forg = black; 670 forg = black;
671 break; 671 break;
672 } 672 }
673 typ = t; 673 typ = t;
674} 674}
675 675
676 676
677 677
678DateButton::DateButton( bool longDate, QWidget *parent, const char * name ) 678DateButton::DateButton( bool longDate, QWidget *parent, const char * name )
679 :QPushButton( parent, name ) 679 :QPushButton( parent, name )
680{ 680{
681 longFormat = longDate; 681 longFormat = longDate;
682 df = DateFormat('/', DateFormat::MonthDayYear, DateFormat::MonthDayYear); 682 df = DateFormat('/', DateFormat::MonthDayYear, DateFormat::MonthDayYear);
683 setDate( QDate::currentDate() ); 683 setDate( QDate::currentDate() );
684 684
685 connect(this,SIGNAL(pressed()),this,SLOT(pickDate())); 685 connect(this,SIGNAL(pressed()),this,SLOT(pickDate()));
686 686
687 687
688} 688}
689 689
690 690
691void DateButton::pickDate() 691void DateButton::pickDate()
692{ 692{
693 static QPopupMenu *m1 = 0; 693 static QPopupMenu *m1 = 0;
694 static DateBookMonth *picker = 0; 694 static DateBookMonth *picker = 0;
695 if ( !m1 ) { 695 if ( !m1 ) {
696 m1 = new QPopupMenu( this ); 696 m1 = new QPopupMenu( this );
697 picker = new DateBookMonth( m1, 0, TRUE ); 697 picker = new DateBookMonth( m1, 0, TRUE );
698 m1->insertItem( picker ); 698 m1->insertItem( picker );
699 connect( picker, SIGNAL( dateClicked( int, int, int ) ), 699 connect( picker, SIGNAL( dateClicked( int, int, int ) ),
700 this, SLOT( setDate( int, int, int ) ) ); 700 this, SLOT( setDate( int, int, int ) ) );
701 connect( picker, SIGNAL( dateClicked( int, int, int ) ), 701 connect( picker, SIGNAL( dateClicked( int, int, int ) ),
702 this, SIGNAL( dateSelected( int, int, int ) ) ); 702 this, SIGNAL( dateSelected( int, int, int ) ) );
703 connect( m1, SIGNAL( aboutToHide() ), 703 connect( m1, SIGNAL( aboutToHide() ),
704 this, SLOT( gotHide() ) ); 704 this, SLOT( gotHide() ) );
705 } 705 }
706 picker->slotWeekChange( weekStartsMonday ); 706 picker->slotWeekChange( weekStartsMonday );
707 picker->setDate( currDate.year(), currDate.month(), currDate.day() ); 707 picker->setDate( currDate.year(), currDate.month(), currDate.day() );
708 m1->popup(mapToGlobal(QPoint(0,height()))); 708 m1->popup(mapToGlobal(QPoint(0,height())));
709 picker->setFocus(); 709 picker->setFocus();
710} 710}
711 711
712 712
713void DateButton::gotHide() 713void DateButton::gotHide()
714{ 714{
715 // we have to redo the button... 715 // we have to redo the button...
716 setDown( false ); 716 setDown( false );
717} 717}
718 718
719 719
720// void dateSelected( int year, int month, int day ); 720// void dateSelected( int year, int month, int day );
721 721
722void DateButton::setWeekStartsMonday( int b ) 722void DateButton::setWeekStartsMonday( int b )
723{ 723{
724 weekStartsMonday = b; 724 weekStartsMonday = b;
725} 725}
726 726
727void DateButton::setDate( int y, int m, int d ) 727void DateButton::setDate( int y, int m, int d )
728{ 728{
729 setDate( QDate( y,m,d) ); 729 setDate( QDate( y,m,d) );
730} 730}
731 731
732void DateButton::setDate( QDate d ) 732void DateButton::setDate( QDate d )
733{ 733{
734 currDate = d; 734 currDate = d;
735 setText( longFormat ? TimeString::longDateString( d, df ) : 735 setText( longFormat ? TimeString::longDateString( d, df ) :
736 TimeString::shortDate( d, df ) ); 736 TimeString::shortDate( d, df ) );
737 737
738} 738}
739 739
740void DateButton::setDateFormat( DateFormat f ) 740void DateButton::setDateFormat( DateFormat f )
741{ 741{
742 df = f; 742 df = f;
743 setDate( currDate ); 743 setDate( currDate );
744} 744}
745 745
746bool DateButton::customWhatsThis() const 746bool DateButton::customWhatsThis() const
747{ 747{
748 return TRUE; 748 return TRUE;
749} 749}
750 750
751
752// this class is only here for Sharp ROM compatibility
753// I have reverse engineered this class and it seems to
754// work (only qtmail seems to use it) - sandman
755// DO NOT USE IT IN NEW CODE !!
756
757DateBookMonthPopup::DateBookMonthPopup ( QWidget *w )
758 : QPopupMenu ( w )
759{
760 m_dbm = new DateBookMonth( this, 0, TRUE );
761 insertItem( m_dbm );
762}
diff --git a/library/datebookmonth.h b/library/datebookmonth.h
index 3c57c19..cb436a8 100644
--- a/library/datebookmonth.h
+++ b/library/datebookmonth.h
@@ -1,213 +1,228 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20#ifndef DATEBOOKMONTH 20#ifndef DATEBOOKMONTH
21#define DATEBOOKMONTH 21#define DATEBOOKMONTH
22 22
23#include <qtopia/private/event.h> 23#include <qtopia/private/event.h>
24 24
25#include <qvbox.h> 25#include <qvbox.h>
26#include <qhbox.h> 26#include <qhbox.h>
27#include <qdatetime.h> 27#include <qdatetime.h>
28#include <qvaluelist.h> 28#include <qvaluelist.h>
29#include <qtable.h> 29#include <qtable.h>
30#include <qpushbutton.h> 30#include <qpushbutton.h>
31#include <qpopupmenu.h>
31 32
32#include "calendar.h" 33#include "calendar.h"
33#include "timestring.h" 34#include "timestring.h"
34 35
35class QToolButton; 36class QToolButton;
36class QComboBox; 37class QComboBox;
37class QSpinBox; 38class QSpinBox;
38class Event; 39class Event;
39class DateBookDB; 40class DateBookDB;
40 41
41class DateBookMonthHeaderPrivate; 42class DateBookMonthHeaderPrivate;
42class DateBookMonthHeader : public QHBox 43class DateBookMonthHeader : public QHBox
43{ 44{
44 Q_OBJECT 45 Q_OBJECT
45 46
46public: 47public:
47 DateBookMonthHeader( QWidget *parent = 0, const char *name = 0 ); 48 DateBookMonthHeader( QWidget *parent = 0, const char *name = 0 );
48 ~DateBookMonthHeader(); 49 ~DateBookMonthHeader();
49 void setDate( int year, int month ); 50 void setDate( int year, int month );
50 51
51signals: 52signals:
52 void dateChanged( int year, int month ); 53 void dateChanged( int year, int month );
53 54
54protected slots: 55protected slots:
55 void keyPressEvent(QKeyEvent *e ) { 56 void keyPressEvent(QKeyEvent *e ) {
56 e->ignore(); 57 e->ignore();
57 } 58 }
58 59
59private slots: 60private slots:
60 void updateDate(); 61 void updateDate();
61 void firstMonth(); 62 void firstMonth();
62 void lastMonth(); 63 void lastMonth();
63 void monthBack(); 64 void monthBack();
64 void monthForward(); 65 void monthForward();
65 66
66private: 67private:
67 QToolButton *begin, *back, *next, *end; 68 QToolButton *begin, *back, *next, *end;
68 QComboBox *month; 69 QComboBox *month;
69 QSpinBox *year; 70 QSpinBox *year;
70 DateBookMonthHeaderPrivate *d; 71 DateBookMonthHeaderPrivate *d;
71 int focus; 72 int focus;
72}; 73};
73 74
74class DayItemMonthPrivate; 75class DayItemMonthPrivate;
75class DayItemMonth : public QTableItem 76class DayItemMonth : public QTableItem
76{ 77{
77public: 78public:
78 DayItemMonth( QTable *table, EditType et, const QString &t ); 79 DayItemMonth( QTable *table, EditType et, const QString &t );
79 ~DayItemMonth(); 80 ~DayItemMonth();
80 void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected ); 81 void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected );
81 void setDay( int d ) { dy = d; } 82 void setDay( int d ) { dy = d; }
82 void setEvents( const QValueList<Event> &events ) { daysEvents = events; }; 83 void setEvents( const QValueList<Event> &events ) { daysEvents = events; };
83 void setEvents( const QValueList<EffectiveEvent> &effEvents ); 84 void setEvents( const QValueList<EffectiveEvent> &effEvents );
84 void clearEvents() { daysEvents.clear(); }; 85 void clearEvents() { daysEvents.clear(); };
85 void clearEffEvents(); 86 void clearEffEvents();
86 int day() const { return dy; } 87 int day() const { return dy; }
87 void setType( Calendar::Day::Type t ); 88 void setType( Calendar::Day::Type t );
88 Calendar::Day::Type type() const { return typ; } 89 Calendar::Day::Type type() const { return typ; }
89 90
90private: 91private:
91 QBrush back; 92 QBrush back;
92 QColor forg; 93 QColor forg;
93 int dy; 94 int dy;
94 Calendar::Day::Type typ; 95 Calendar::Day::Type typ;
95 QValueList<Event> daysEvents; // not used anymore... 96 QValueList<Event> daysEvents; // not used anymore...
96 DayItemMonthPrivate *d; 97 DayItemMonthPrivate *d;
97}; 98};
98 99
99class DateBookMonthTablePrivate; 100class DateBookMonthTablePrivate;
100class DateBookMonthTable : public QTable 101class DateBookMonthTable : public QTable
101{ 102{
102 Q_OBJECT 103 Q_OBJECT
103 104
104public: 105public:
105 DateBookMonthTable( QWidget *parent = 0, const char *name = 0, 106 DateBookMonthTable( QWidget *parent = 0, const char *name = 0,
106 DateBookDB *newDb = 0 ); 107 DateBookDB *newDb = 0 );
107 ~DateBookMonthTable(); 108 ~DateBookMonthTable();
108 void setDate( int y, int m, int d ); 109 void setDate( int y, int m, int d );
109 void redraw(); 110 void redraw();
110 111
111 QSize minimumSizeHint() const { return sizeHint(); } 112 QSize minimumSizeHint() const { return sizeHint(); }
112 QSize minimumSize() const { return sizeHint(); } 113 QSize minimumSize() const { return sizeHint(); }
113 void getDate( int& y, int &m, int &d ) const {y=selYear;m=selMonth;d=selDay;} 114 void getDate( int& y, int &m, int &d ) const {y=selYear;m=selMonth;d=selDay;}
114 void setWeekStart( bool onMonday ); 115 void setWeekStart( bool onMonday );
115signals: 116signals:
116 void dateClicked( int year, int month, int day ); 117 void dateClicked( int year, int month, int day );
117 118
118protected: 119protected:
119 void viewportMouseReleaseEvent( QMouseEvent * ); 120 void viewportMouseReleaseEvent( QMouseEvent * );
120 121
121protected slots: 122protected slots:
122 123
123 void keyPressEvent(QKeyEvent *e ) { 124 void keyPressEvent(QKeyEvent *e ) {
124 e->ignore(); 125 e->ignore();
125 } 126 }
126 127
127private slots: 128private slots:
128 void dayClicked( int row, int col ); 129 void dayClicked( int row, int col );
129 void dragDay( int row, int col ); 130 void dragDay( int row, int col );
130 131
131private: 132private:
132 void setupTable(); 133 void setupTable();
133 void setupLabels(); 134 void setupLabels();
134 135
135 void findDay( int day, int &row, int &col ); 136 void findDay( int day, int &row, int &col );
136 void getEvents(); 137 void getEvents();
137 void changeDaySelection( int row, int col ); 138 void changeDaySelection( int row, int col );
138 139
139 int year, month, day; 140 int year, month, day;
140 int selYear, selMonth, selDay; 141 int selYear, selMonth, selDay;
141 QValueList<Event> monthsEvents; // not used anymore... 142 QValueList<Event> monthsEvents; // not used anymore...
142 DateBookDB *db; 143 DateBookDB *db;
143 DateBookMonthTablePrivate *d; 144 DateBookMonthTablePrivate *d;
144}; 145};
145 146
146class DateBookMonthPrivate; 147class DateBookMonthPrivate;
147class DateBookMonth : public QVBox 148class DateBookMonth : public QVBox
148{ 149{
149 Q_OBJECT 150 Q_OBJECT
150 151
151public: 152public:
152 DateBookMonth( QWidget *parent = 0, const char *name = 0, bool ac = FALSE, 153 DateBookMonth( QWidget *parent = 0, const char *name = 0, bool ac = FALSE,
153 DateBookDB *data = 0 ); 154 DateBookDB *data = 0 );
154 ~DateBookMonth(); 155 ~DateBookMonth();
155 QDate selectedDate() const; 156 QDate selectedDate() const;
156 157
157signals: 158signals:
158 void dateClicked( int year, int month, int day ); 159 void dateClicked( int year, int month, int day );
159 160
160public slots: 161public slots:
161 void setDate( int y, int m ); 162 void setDate( int y, int m );
162 void setDate( int y, int m, int d ); 163 void setDate( int y, int m, int d );
163 void setDate( QDate ); 164 void setDate( QDate );
164 void redraw(); 165 void redraw();
165 void slotWeekChange( bool ); 166 void slotWeekChange( bool );
166 167
167protected slots: 168protected slots:
168 virtual void keyPressEvent(QKeyEvent *e); 169 virtual void keyPressEvent(QKeyEvent *e);
169 170
170private slots: 171private slots:
171 void forwardDateClicked( int y, int m, int d ) { emit dateClicked( y, m, d ); } 172 void forwardDateClicked( int y, int m, int d ) { emit dateClicked( y, m, d ); }
172 void finalDate(int, int, int); 173 void finalDate(int, int, int);
173 174
174private: 175private:
175 DateBookMonthHeader *header; 176 DateBookMonthHeader *header;
176 DateBookMonthTable *table; 177 DateBookMonthTable *table;
177 int year, month, day; 178 int year, month, day;
178 bool autoClose; 179 bool autoClose;
179 class DateBookMonthPrivate *d; 180 class DateBookMonthPrivate *d;
180}; 181};
181 182
182class DateButton : public QPushButton 183class DateButton : public QPushButton
183{ 184{
184 Q_OBJECT 185 Q_OBJECT
185 186
186public: 187public:
187 DateButton( bool longDate, QWidget *parent, const char * name = 0 ); 188 DateButton( bool longDate, QWidget *parent, const char * name = 0 );
188 QDate date() const { return currDate; } 189 QDate date() const { return currDate; }
189 190
190 bool customWhatsThis() const; 191 bool customWhatsThis() const;
191 192
192signals: 193signals:
193 void dateSelected( int year, int month, int day ); 194 void dateSelected( int year, int month, int day );
194 195
195public slots: 196public slots:
196 void setDate( int y, int m, int d ); 197 void setDate( int y, int m, int d );
197 void setDate( QDate ); 198 void setDate( QDate );
198 void setWeekStartsMonday( int ); 199 void setWeekStartsMonday( int );
199 void setDateFormat( DateFormat ); 200 void setDateFormat( DateFormat );
200 201
201private slots: 202private slots:
202 void pickDate(); 203 void pickDate();
203 void gotHide(); 204 void gotHide();
204 205
205private: 206private:
206 bool longFormat; 207 bool longFormat;
207 bool weekStartsMonday; 208 bool weekStartsMonday;
208 QDate currDate; 209 QDate currDate;
209 DateFormat df; 210 DateFormat df;
210}; 211};
211 212
213// this class is only here for Sharp ROM compatibility
214// I have reverse engineered this class and it seems to
215// work (only qtmail seems to use it) - sandman
216// DO NOT USE IT IN NEW CODE !!
217
218class DateBookMonthPopup : public QPopupMenu
219{
220 Q_OBJECT
221public:
222 DateBookMonthPopup ( QWidget *w );
223
224private:
225 DateBookMonth *m_dbm;
226};
212 227
213#endif 228#endif
diff --git a/library/qpemenubar.cpp b/library/qpemenubar.cpp
index c658d10..4aa0bf3 100644
--- a/library/qpemenubar.cpp
+++ b/library/qpemenubar.cpp
@@ -1,325 +1,334 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#define INCLUDE_MENUITEM_DEF 21#define INCLUDE_MENUITEM_DEF
22 22
23#include "qpemenubar.h" 23#include "qpemenubar.h"
24#include <qapplication.h> 24#include <qapplication.h>
25#include <qguardedptr.h> 25#include <qguardedptr.h>
26#include <qtimer.h> 26#include <qtimer.h>
27 27
28 28
29class QMenuBarHack : public QMenuBar 29class QMenuBarHack : public QMenuBar
30{ 30{
31public: 31public:
32 int activeItem() const { return actItem; } 32 int activeItem() const { return actItem; }
33 33
34 void goodbye() 34 void goodbye()
35 { 35 {
36 activateItemAt(-1); 36 activateItemAt(-1);
37 for ( unsigned int i = 0; i < count(); i++ ) { 37 for ( unsigned int i = 0; i < count(); i++ ) {
38 QMenuItem *mi = findItem( idAt(i) ); 38 QMenuItem *mi = findItem( idAt(i) );
39 if ( mi->popup() ) { 39 if ( mi->popup() ) {
40 mi->popup()->hide(); 40 mi->popup()->hide();
41 } 41 }
42 } 42 }
43 } 43 }
44}; 44};
45 45
46 46
47// Sharp ROM compatibility
48void QPEMenuToolFocusManager::setMenukeyEnabled ( bool )
49{
50}
51int QPEMenuBar::getOldFocus ( )
52{
53 return 0;
54}
55
47QPEMenuToolFocusManager *QPEMenuToolFocusManager::me = 0; 56QPEMenuToolFocusManager *QPEMenuToolFocusManager::me = 0;
48 57
49QPEMenuToolFocusManager::QPEMenuToolFocusManager() : QObject() 58QPEMenuToolFocusManager::QPEMenuToolFocusManager() : QObject()
50{ 59{
51 qApp->installEventFilter( this ); 60 qApp->installEventFilter( this );
52} 61}
53 62
54void QPEMenuToolFocusManager::addWidget( QWidget *w ) 63void QPEMenuToolFocusManager::addWidget( QWidget *w )
55{ 64{
56 list.append( GuardedWidget(w) ); 65 list.append( GuardedWidget(w) );
57} 66}
58 67
59void QPEMenuToolFocusManager::removeWidget( QWidget *w ) 68void QPEMenuToolFocusManager::removeWidget( QWidget *w )
60{ 69{
61 list.remove( GuardedWidget(w) ); 70 list.remove( GuardedWidget(w) );
62} 71}
63 72
64void QPEMenuToolFocusManager::setActive( bool a ) 73void QPEMenuToolFocusManager::setActive( bool a )
65{ 74{
66 if ( a ) { 75 if ( a ) {
67 oldFocus = qApp->focusWidget(); 76 oldFocus = qApp->focusWidget();
68 QValueList<GuardedWidget>::Iterator it; 77 QValueList<GuardedWidget>::Iterator it;
69 it = list.begin(); 78 it = list.begin();
70 while ( it != list.end() ) { 79 while ( it != list.end() ) {
71 QWidget *w = (*it); 80 QWidget *w = (*it);
72 if ( w && w->isEnabled() && w->isVisible() && 81 if ( w && w->isEnabled() && w->isVisible() &&
73 w->topLevelWidget() == qApp->activeWindow() ) { 82 w->topLevelWidget() == qApp->activeWindow() ) {
74 setFocus( w ); 83 setFocus( w );
75 return; 84 return;
76 } 85 }
77 ++it; 86 ++it;
78 } 87 }
79 } else { 88 } else {
80 if ( inFocus ) { 89 if ( inFocus ) {
81 if ( inFocus->inherits( "QMenuBar" ) ) 90 if ( inFocus->inherits( "QMenuBar" ) )
82 ((QMenuBarHack *)(QWidget *)inFocus)->goodbye(); 91 ((QMenuBarHack *)(QWidget *)inFocus)->goodbye();
83 if ( inFocus->hasFocus() ) { 92 if ( inFocus->hasFocus() ) {
84 if ( oldFocus && oldFocus->isVisible() && oldFocus->isEnabled() ) { 93 if ( oldFocus && oldFocus->isVisible() && oldFocus->isEnabled() ) {
85 oldFocus->setFocus(); 94 oldFocus->setFocus();
86 } else { 95 } else {
87 inFocus->clearFocus(); 96 inFocus->clearFocus();
88 } 97 }
89 } 98 }
90 } 99 }
91 inFocus = 0; 100 inFocus = 0;
92 oldFocus = 0; 101 oldFocus = 0;
93 } 102 }
94} 103}
95 104
96bool QPEMenuToolFocusManager::isActive() const 105bool QPEMenuToolFocusManager::isActive() const
97{ 106{
98 return !inFocus.isNull(); 107 return !inFocus.isNull();
99} 108}
100 109
101void QPEMenuToolFocusManager::moveFocus( bool next ) 110void QPEMenuToolFocusManager::moveFocus( bool next )
102{ 111{
103 if ( !isActive() ) 112 if ( !isActive() )
104 return; 113 return;
105 114
106 int n = list.count(); 115 int n = list.count();
107 QValueList<GuardedWidget>::Iterator it; 116 QValueList<GuardedWidget>::Iterator it;
108 it = list.find( inFocus ); 117 it = list.find( inFocus );
109 if ( it == list.end() ) 118 if ( it == list.end() )
110 it = list.begin(); 119 it = list.begin();
111 while ( --n ) { 120 while ( --n ) {
112 if ( next ) { 121 if ( next ) {
113 ++it; 122 ++it;
114 if ( it == list.end() ) 123 if ( it == list.end() )
115 it = list.begin(); 124 it = list.begin();
116 } else { 125 } else {
117 if ( it == list.begin() ) 126 if ( it == list.begin() )
118 it = list.end(); 127 it = list.end();
119 --it; 128 --it;
120 } 129 }
121 QWidget *w = (*it); 130 QWidget *w = (*it);
122 if ( w && w->isEnabled() && w->isVisible() && !w->inherits("QToolBarSeparator") && 131 if ( w && w->isEnabled() && w->isVisible() && !w->inherits("QToolBarSeparator") &&
123 w->topLevelWidget() == qApp->activeWindow() ) { 132 w->topLevelWidget() == qApp->activeWindow() ) {
124 setFocus( w, next ); 133 setFocus( w, next );
125 return; 134 return;
126 } 135 }
127 } 136 }
128} 137}
129 138
130void QPEMenuToolFocusManager::initialize() 139void QPEMenuToolFocusManager::initialize()
131{ 140{
132 if ( !me ) 141 if ( !me )
133 me = new QPEMenuToolFocusManager; 142 me = new QPEMenuToolFocusManager;
134} 143}
135 144
136QPEMenuToolFocusManager *QPEMenuToolFocusManager::manager() 145QPEMenuToolFocusManager *QPEMenuToolFocusManager::manager()
137{ 146{
138 if ( !me ) 147 if ( !me )
139 me = new QPEMenuToolFocusManager; 148 me = new QPEMenuToolFocusManager;
140 149
141 return me; 150 return me;
142} 151}
143 152
144void QPEMenuToolFocusManager::setFocus( QWidget *w, bool next ) 153void QPEMenuToolFocusManager::setFocus( QWidget *w, bool next )
145{ 154{
146 inFocus = w; 155 inFocus = w;
147// qDebug( "Set focus on %s", w->className() ); 156// qDebug( "Set focus on %s", w->className() );
148 if ( inFocus->inherits( "QMenuBar" ) ) { 157 if ( inFocus->inherits( "QMenuBar" ) ) {
149 QMenuBar *mb = (QMenuBar *)(QWidget *)inFocus; 158 QMenuBar *mb = (QMenuBar *)(QWidget *)inFocus;
150 if ( next ) 159 if ( next )
151 mb->activateItemAt( 0 ); 160 mb->activateItemAt( 0 );
152 else 161 else
153 mb->activateItemAt( mb->count()-1 ); 162 mb->activateItemAt( mb->count()-1 );
154 } 163 }
155 inFocus->setFocus(); 164 inFocus->setFocus();
156} 165}
157 166
158bool QPEMenuToolFocusManager::eventFilter( QObject *object, QEvent *event ) 167bool QPEMenuToolFocusManager::eventFilter( QObject *object, QEvent *event )
159{ 168{
160 if ( event->type() == QEvent::KeyPress ) { 169 if ( event->type() == QEvent::KeyPress ) {
161 QKeyEvent *ke = (QKeyEvent *)event; 170 QKeyEvent *ke = (QKeyEvent *)event;
162 if ( isActive() ) { 171 if ( isActive() ) {
163 if ( object->inherits( "QButton" ) ) { 172 if ( object->inherits( "QButton" ) ) {
164 switch ( ke->key() ) { 173 switch ( ke->key() ) {
165 case Key_Left: 174 case Key_Left:
166 moveFocus( FALSE ); 175 moveFocus( FALSE );
167 return TRUE; 176 return TRUE;
168 177
169 case Key_Right: 178 case Key_Right:
170 moveFocus( TRUE ); 179 moveFocus( TRUE );
171 return TRUE; 180 return TRUE;
172 181
173 case Key_Up: 182 case Key_Up:
174 case Key_Down: 183 case Key_Down:
175 return TRUE; 184 return TRUE;
176 } 185 }
177 } else if ( object->inherits( "QPopupMenu" ) ) { 186 } else if ( object->inherits( "QPopupMenu" ) ) {
178 // Deactivate when a menu item is selected 187 // Deactivate when a menu item is selected
179 if ( ke->key() == Key_Enter || ke->key() == Key_Return || 188 if ( ke->key() == Key_Enter || ke->key() == Key_Return ||
180 ke->key() == Key_Escape ) { 189 ke->key() == Key_Escape ) {
181 QTimer::singleShot( 0, this, SLOT(deactivate()) ); 190 QTimer::singleShot( 0, this, SLOT(deactivate()) );
182 } 191 }
183 } else if ( object->inherits( "QMenuBar" ) ) { 192 } else if ( object->inherits( "QMenuBar" ) ) {
184 int dx = 0; 193 int dx = 0;
185 switch ( ke->key() ) { 194 switch ( ke->key() ) {
186 case Key_Left: 195 case Key_Left:
187 dx = -1; 196 dx = -1;
188 break; 197 break;
189 198
190 case Key_Right: 199 case Key_Right:
191 dx = 1; 200 dx = 1;
192 break; 201 break;
193 } 202 }
194 203
195 QMenuBarHack *mb = (QMenuBarHack *)object; 204 QMenuBarHack *mb = (QMenuBarHack *)object;
196 if ( dx && mb->activeItem() >= 0 ) { 205 if ( dx && mb->activeItem() >= 0 ) {
197 int i = mb->activeItem(); 206 int i = mb->activeItem();
198 int c = mb->count(); 207 int c = mb->count();
199 int n = c; 208 int n = c;
200 while ( n-- ) { 209 while ( n-- ) {
201 i = i + dx; 210 i = i + dx;
202 if ( i == c ) { 211 if ( i == c ) {
203 mb->goodbye(); 212 mb->goodbye();
204 moveFocus( TRUE ); 213 moveFocus( TRUE );
205 return TRUE; 214 return TRUE;
206 } else if ( i < 0 ) { 215 } else if ( i < 0 ) {
207 mb->goodbye(); 216 mb->goodbye();
208 moveFocus( FALSE ); 217 moveFocus( FALSE );
209 return TRUE; 218 return TRUE;
210 } 219 }
211 QMenuItem *mi = mb->findItem( mb->idAt(i) ); 220 QMenuItem *mi = mb->findItem( mb->idAt(i) );
212 if ( mi->isEnabled() && !mi->isSeparator() ) { 221 if ( mi->isEnabled() && !mi->isSeparator() ) {
213 break; 222 break;
214 } 223 }
215 } 224 }
216 } 225 }
217 } 226 }
218 } 227 }
219 if ( ke->key() == Key_F11 ) { 228 if ( ke->key() == Key_F11 ) {
220 setActive( !isActive() ); 229 setActive( !isActive() );
221 return TRUE; 230 return TRUE;
222 } 231 }
223 } else if ( event->type() == QEvent::KeyRelease ) { 232 } else if ( event->type() == QEvent::KeyRelease ) {
224 QKeyEvent *ke = (QKeyEvent *)event; 233 QKeyEvent *ke = (QKeyEvent *)event;
225 if ( isActive() ) { 234 if ( isActive() ) {
226 if ( object->inherits( "QButton" ) ) { 235 if ( object->inherits( "QButton" ) ) {
227 // Deactivate when a button is selected 236 // Deactivate when a button is selected
228 if ( ke->key() == Key_Space ) 237 if ( ke->key() == Key_Space )
229 QTimer::singleShot( 0, this, SLOT(deactivate()) ); 238 QTimer::singleShot( 0, this, SLOT(deactivate()) );
230 } 239 }
231 } 240 }
232 } else if ( event->type() == QEvent::FocusIn ) { 241 } else if ( event->type() == QEvent::FocusIn ) {
233 if ( isActive() ) { 242 if ( isActive() ) {
234 // A non-menu/tool widget has been selected - we're deactivated 243 // A non-menu/tool widget has been selected - we're deactivated
235 QWidget *w = (QWidget *)object; 244 QWidget *w = (QWidget *)object;
236 if ( !w->isPopup() && !list.contains( GuardedWidget( w ) ) ) { 245 if ( !w->isPopup() && !list.contains( GuardedWidget( w ) ) ) {
237 inFocus = 0; 246 inFocus = 0;
238 } 247 }
239 } 248 }
240 } else if ( event->type() == QEvent::Hide ) { 249 } else if ( event->type() == QEvent::Hide ) {
241 if ( isActive() ) { 250 if ( isActive() ) {
242 // Deaticvate if a menu/tool has been hidden 251 // Deaticvate if a menu/tool has been hidden
243 QWidget *w = (QWidget *)object; 252 QWidget *w = (QWidget *)object;
244 if ( !w->isPopup() && !list.contains( GuardedWidget( w ) ) ) { 253 if ( !w->isPopup() && !list.contains( GuardedWidget( w ) ) ) {
245 setActive( FALSE ); 254 setActive( FALSE );
246 } 255 }
247 } 256 }
248 } else if ( event->type() == QEvent::ChildInserted ) { 257 } else if ( event->type() == QEvent::ChildInserted ) {
249 QChildEvent *ce = (QChildEvent *)event; 258 QChildEvent *ce = (QChildEvent *)event;
250 if ( ce->child()->isWidgetType() ) { 259 if ( ce->child()->isWidgetType() ) {
251 if ( ce->child()->inherits( "QMenuBar" ) ) { 260 if ( ce->child()->inherits( "QMenuBar" ) ) {
252 addWidget( (QWidget *)ce->child() ); 261 addWidget( (QWidget *)ce->child() );
253 ce->child()->installEventFilter( this ); 262 ce->child()->installEventFilter( this );
254 } else if ( object->inherits( "QToolBar" ) ) { 263 } else if ( object->inherits( "QToolBar" ) ) {
255 addWidget( (QWidget *)ce->child() ); 264 addWidget( (QWidget *)ce->child() );
256 } 265 }
257 } 266 }
258 } else if ( event->type() == QEvent::ChildRemoved ) { 267 } else if ( event->type() == QEvent::ChildRemoved ) {
259 QChildEvent *ce = (QChildEvent *)event; 268 QChildEvent *ce = (QChildEvent *)event;
260 if ( ce->child()->isWidgetType() ) { 269 if ( ce->child()->isWidgetType() ) {
261 if ( ce->child()->inherits( "QMenuBar" ) ) { 270 if ( ce->child()->inherits( "QMenuBar" ) ) {
262 removeWidget( (QWidget *)ce->child() ); 271 removeWidget( (QWidget *)ce->child() );
263 ce->child()->removeEventFilter( this ); 272 ce->child()->removeEventFilter( this );
264 } else if ( object->inherits( "QToolBar" ) ) { 273 } else if ( object->inherits( "QToolBar" ) ) {
265 removeWidget( (QWidget *)ce->child() ); 274 removeWidget( (QWidget *)ce->child() );
266 } 275 }
267 } 276 }
268 } 277 }
269 278
270 return FALSE; 279 return FALSE;
271} 280}
272 281
273void QPEMenuToolFocusManager::deactivate() 282void QPEMenuToolFocusManager::deactivate()
274{ 283{
275 setActive( FALSE ); 284 setActive( FALSE );
276} 285}
277 286
278/*! 287/*!
279 \class QPEMenuBar qpemenubar.h 288 \class QPEMenuBar qpemenubar.h
280 \brief The QPEMenuBar class is obsolete. Use QMenuBar instead. 289 \brief The QPEMenuBar class is obsolete. Use QMenuBar instead.
281 290
282 \obsolete 291 \obsolete
283 292
284 This class is obsolete. Use QMenuBar instead. 293 This class is obsolete. Use QMenuBar instead.
285 294
286*/ 295*/
287 296
288/*! 297/*!
289 Constructs a QPEMenuBar just as you would construct 298 Constructs a QPEMenuBar just as you would construct
290 a QMenuBar, passing \a parent and \a name. 299 a QMenuBar, passing \a parent and \a name.
291*/ 300*/
292QPEMenuBar::QPEMenuBar( QWidget *parent, const char *name ) 301QPEMenuBar::QPEMenuBar( QWidget *parent, const char *name )
293 : QMenuBar( parent, name ) 302 : QMenuBar( parent, name )
294{ 303{
295} 304}
296 305
297/*! 306/*!
298 \reimp 307 \reimp
299*/ 308*/
300QPEMenuBar::~QPEMenuBar() 309QPEMenuBar::~QPEMenuBar()
301{ 310{
302} 311}
303 312
304/*! 313/*!
305 \internal 314 \internal
306*/ 315*/
307void QPEMenuBar::keyPressEvent( QKeyEvent *e ) 316void QPEMenuBar::keyPressEvent( QKeyEvent *e )
308{ 317{
309 QMenuBar::keyPressEvent( e ); 318 QMenuBar::keyPressEvent( e );
310} 319}
311 320
312/*! 321/*!
313 \internal 322 \internal
314*/ 323*/
315void QPEMenuBar::activateItem( int index ) { 324void QPEMenuBar::activateItem( int index ) {
316 activateItemAt( index ); 325 activateItemAt( index );
317} 326}
318void QPEMenuBar::goodbye() { 327void QPEMenuBar::goodbye() {
319 activateItemAt(-1); 328 activateItemAt(-1);
320 for ( uint i = 0; i < count(); i++ ) { 329 for ( uint i = 0; i < count(); i++ ) {
321 QMenuItem* mi = findItem( idAt(i) ); 330 QMenuItem* mi = findItem( idAt(i) );
322 if (mi->popup() ) 331 if (mi->popup() )
323 mi->popup()->hide(); 332 mi->popup()->hide();
324 } 333 }
325} 334}
diff --git a/library/qpemenubar.h b/library/qpemenubar.h
index 05abc4e..66d0c85 100644
--- a/library/qpemenubar.h
+++ b/library/qpemenubar.h
@@ -1,78 +1,85 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#ifndef QPEMENUBAR_H 21#ifndef QPEMENUBAR_H
22#define QPEMENUBAR_H 22#define QPEMENUBAR_H
23 23
24#include <qmenubar.h> 24#include <qmenubar.h>
25#include <qguardedptr.h> 25#include <qguardedptr.h>
26#include <qvaluelist.h> 26#include <qvaluelist.h>
27 27
28class QPEMenuToolFocusManager : public QObject 28class QPEMenuToolFocusManager : public QObject
29{ 29{
30 Q_OBJECT 30 Q_OBJECT
31public: 31public:
32 QPEMenuToolFocusManager(); 32 QPEMenuToolFocusManager();
33 33
34 void addWidget( QWidget *w ); 34 void addWidget( QWidget *w );
35 void removeWidget( QWidget *w ); 35 void removeWidget( QWidget *w );
36 void setActive( bool a ); 36 void setActive( bool a );
37 bool isActive() const; 37 bool isActive() const;
38 void moveFocus( bool next ); 38 void moveFocus( bool next );
39 39
40 static QPEMenuToolFocusManager *manager(); 40 static QPEMenuToolFocusManager *manager();
41 static void initialize(); 41 static void initialize();
42 42
43protected: 43protected:
44 void setFocus( QWidget *w, bool next=TRUE ); 44 void setFocus( QWidget *w, bool next=TRUE );
45 bool eventFilter( QObject *object, QEvent *event ); 45 bool eventFilter( QObject *object, QEvent *event );
46 46
47private slots: 47private slots:
48 void deactivate(); 48 void deactivate();
49 49
50private: 50private:
51 typedef QGuardedPtr<QWidget> GuardedWidget; 51 typedef QGuardedPtr<QWidget> GuardedWidget;
52 QValueList<GuardedWidget> list; 52 QValueList<GuardedWidget> list;
53 GuardedWidget inFocus; 53 GuardedWidget inFocus;
54 GuardedWidget oldFocus; 54 GuardedWidget oldFocus;
55 static QPEMenuToolFocusManager *me; 55 static QPEMenuToolFocusManager *me;
56
57private: // Sharp ROM compatibility
58 void setMenukeyEnabled ( bool b );
56}; 59};
57 60
58 61
59class QPEMenuBar : public QMenuBar 62class QPEMenuBar : public QMenuBar
60{ 63{
61 Q_OBJECT 64 Q_OBJECT
62public: 65public:
63 QPEMenuBar( QWidget *parent=0, const char* name=0 ); 66 QPEMenuBar( QWidget *parent=0, const char* name=0 );
64 ~QPEMenuBar(); 67 ~QPEMenuBar();
65 68
66protected: 69protected:
67 virtual void keyPressEvent( QKeyEvent *e ); 70 virtual void keyPressEvent( QKeyEvent *e );
68 71
69 /* Patch from Mickey 72 /* Patch from Mickey
70 * Sharp Qtopia1.5 seems to have these functions 73 * Sharp Qtopia1.5 seems to have these functions
71 * TO BE RESOLVED - zecke 74 * TO BE RESOLVED - zecke
72 */ 75 */
73 void activateItem( int index ); 76 void activateItem( int index );
74 void goodbye(); 77 void goodbye();
78
79 // This is a special "lineo" add-on for the Sharp ROM
80 // nobody knows, what it does, though ...
81 int getOldFocus ( );
75}; 82};
76 83
77#endif 84#endif
78 85