author | zecke <zecke> | 2002-10-15 21:42:20 (UTC) |
---|---|---|
committer | zecke <zecke> | 2002-10-15 21:42:20 (UTC) |
commit | 676be5604cbdb3213c00775e0ff66f4e766f8dcb (patch) (side-by-side diff) | |
tree | 63c29adab530a60371f78880ff75e2689398e239 | |
parent | b774e015816e51ac65e5d1c685306f8404a3a19e (diff) | |
download | opie-676be5604cbdb3213c00775e0ff66f4e766f8dcb.zip opie-676be5604cbdb3213c00775e0ff66f4e766f8dcb.tar.gz opie-676be5604cbdb3213c00775e0ff66f4e766f8dcb.tar.bz2 |
Actually most of them are -+ cause I opened them in xemacs..
The main goal is to
replace some header names to let them be overwritten by external once
so "qpeapplication.h" is now <qpe/qpeapplication.h>
I'll check if it's building on non Qt2/X11 systems...
-rw-r--r-- | library/alarmserver.cpp | 4 | ||||
-rw-r--r-- | library/backend/vcc.y | 2 | ||||
-rw-r--r-- | library/backend/vcc_yacc.cpp | 2 | ||||
-rw-r--r-- | library/backend/vobject.cpp | 4 | ||||
-rw-r--r-- | library/datebookmonth.cpp | 2 | ||||
-rw-r--r-- | library/fileselector.cpp | 6 | ||||
-rw-r--r-- | library/fontdatabase.cpp | 2 | ||||
-rw-r--r-- | library/fontdatabase.h | 1 | ||||
-rw-r--r-- | library/mimetype.cpp | 2 | ||||
-rw-r--r-- | library/qpedialog.cpp | 2 | ||||
-rw-r--r-- | library/qpestyle.cpp | 2 | ||||
-rw-r--r-- | library/resource.cpp | 2 | ||||
-rw-r--r-- | library/timestring.cpp | 2 |
13 files changed, 17 insertions, 16 deletions
diff --git a/library/alarmserver.cpp b/library/alarmserver.cpp index 1ee05c6..177a0cb 100644 --- a/library/alarmserver.cpp +++ b/library/alarmserver.cpp @@ -1,403 +1,403 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include <qdir.h> #include <qfile.h> #include <qmessagebox.h> #include <qtextstream.h> -#include "qpeapplication.h" +#include <qpe/qpeapplication.h> #include "global.h" #include "resource.h" #if defined(Q_WS_QWS) && !defined(QT_NO_COP) -#include "qcopenvelope_qws.h" +#include <qpe/qcopenvelope_qws.h> #endif #include "alarmserver.h" #include <qpe/timeconversion.h> #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <unistd.h> struct timerEventItem { time_t UTCtime; QCString channel, message; int data; bool operator==( const timerEventItem &right ) const { return ( UTCtime == right.UTCtime && channel == right.channel && message == right.message && data == right.data ); } }; class TimerReceiverObject : public QObject { public: TimerReceiverObject() { } ~TimerReceiverObject() { } void resetTimer(); void setTimerEventItem(); void deleteTimer(); protected: void timerEvent( QTimerEvent *te ); private: QString atfilename; }; TimerReceiverObject *timerEventReceiver = NULL; QList<timerEventItem> timerEventList; timerEventItem *nearestTimerEvent = NULL; // set the timer to go off on the next event in the list void setNearestTimerEvent() { nearestTimerEvent = NULL; QListIterator<timerEventItem> it( timerEventList ); if ( *it ) nearestTimerEvent = *it; for ( ; *it; ++it ) if ( (*it)->UTCtime < nearestTimerEvent->UTCtime ) nearestTimerEvent = *it; if (nearestTimerEvent) timerEventReceiver->resetTimer(); else timerEventReceiver->deleteTimer(); } //store current state to file //Simple implementation. Should run on a timer. static void saveState() { QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" ); if ( timerEventList.isEmpty() ) { unlink( savefilename ); return; } QFile savefile(savefilename+".new"); if ( savefile.open(IO_WriteOnly) ) { QDataStream ds( &savefile ); //save QListIterator<timerEventItem> it( timerEventList ); for ( ; *it; ++it ) { ds << it.current()->UTCtime; ds << it.current()->channel; ds << it.current()->message; ds << it.current()->data; } savefile.close(); unlink( savefilename ); QDir d; d.rename(savefilename+".new",savefilename); } } /*! Sets up the alarm server. Restoring to previous state (session management). */ void AlarmServer::initialize() { //read autosave file and put events in timerEventList QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" ); QFile savefile(savefilename); if ( savefile.open(IO_ReadOnly) ) { QDataStream ds( &savefile ); while ( !ds.atEnd() ) { timerEventItem *newTimerEventItem = new timerEventItem; ds >> newTimerEventItem->UTCtime; ds >> newTimerEventItem->channel; ds >> newTimerEventItem->message; ds >> newTimerEventItem->data; timerEventList.append( newTimerEventItem ); } savefile.close(); if (!timerEventReceiver) timerEventReceiver = new TimerReceiverObject; setNearestTimerEvent(); } } static const char* atdir = "/var/spool/at/"; static bool triggerAtd( bool writeHWClock = FALSE ) { QFile trigger(QString(atdir) + "trigger"); if ( trigger.open(IO_WriteOnly|IO_Raw) ) { const char* data = #ifdef QT_QWS_CUSTOM //custom atd only writes HW Clock if we write a 'W' ( writeHWClock ) ? "W\n" : #endif data = "\n"; int len = strlen(data); int total_written = trigger.writeBlock(data,len); if ( total_written != len ) { QMessageBox::critical( 0, QObject::tr( "Out of Space" ), QObject::tr( "Unable to schedule alarm.\nFree some memory and try again." ) ); trigger.close(); QFile::remove( trigger.name() ); return FALSE; } return TRUE; } return FALSE; } void TimerReceiverObject::deleteTimer() { if ( !atfilename.isEmpty() ) { unlink( atfilename ); atfilename = QString::null; triggerAtd( FALSE ); } } void TimerReceiverObject::resetTimer() { const int maxsecs = 2147000; int total_written; QDateTime nearest = TimeConversion::fromUTC(nearestTimerEvent->UTCtime); QDateTime now = QDateTime::currentDateTime(); if ( nearest < now ) nearest = now; int secs = TimeConversion::secsTo( now, nearest ); if ( secs > maxsecs ) { // too far for millisecond timing secs = maxsecs; } // System timer (needed so that we wake from deep sleep), // from the Epoch in seconds. // int at_secs = TimeConversion::toUTC(nearest); // qDebug("reset timer to %d seconds from Epoch",at_secs); QString fn = atdir + QString::number(at_secs) + "." + QString::number(getpid()); if ( fn != atfilename ) { QFile atfile(fn+".new"); if ( atfile.open(IO_WriteOnly|IO_Raw) ) { // just wake up and delete the at file QString cmd = "#!/bin/sh\nrm " + fn; total_written = atfile.writeBlock(cmd.latin1(),cmd.length()); if ( total_written != int(cmd.length()) ) { QMessageBox::critical( 0, tr("Out of Space"), tr("Unable to schedule alarm.\n" "Please free up space and try again") ); atfile.close(); QFile::remove( atfile.name() ); return; } atfile.close(); unlink( atfilename ); QDir d; d.rename(fn+".new",fn); chmod(fn.latin1(),0755); atfilename = fn; triggerAtd( FALSE ); } else { qWarning("Cannot open atd file %s",fn.latin1()); } } // Qt timers (does the actual alarm) // from now in milliseconds // qDebug("AlarmServer waiting %d seconds",secs); startTimer( 1000 * secs + 500 ); } void TimerReceiverObject::timerEvent( QTimerEvent * ) { bool needSave = FALSE; killTimers(); if (nearestTimerEvent) { if ( nearestTimerEvent->UTCtime <= TimeConversion::toUTC(QDateTime::currentDateTime()) ) { #ifndef QT_NO_COP QCopEnvelope e( nearestTimerEvent->channel, nearestTimerEvent->message ); e << TimeConversion::fromUTC( nearestTimerEvent->UTCtime ) << nearestTimerEvent->data; #endif timerEventList.remove( nearestTimerEvent ); needSave = TRUE; } setNearestTimerEvent(); } else { resetTimer(); } if ( needSave ) saveState(); } /*! \class AlarmServer alarmserver.h \brief The AlarmServer class allows alarms to be scheduled and unscheduled. Applications can schedule alarms with addAlarm() and can unschedule alarms with deleteAlarm(). When the time for an alarm to go off is reached the specified \link qcop.html QCop\endlink message is sent on the specified channel (optionally with additional data). Scheduling an alarm using this class is important (rather just using a QTimer) since the machine may be asleep and needs to get woken up using the Linux kernel which implements this at the kernel level to minimize battery usage while asleep. \ingroup qtopiaemb \sa QCopEnvelope */ /*! Schedules an alarm to go off at (or soon after) time \a when. When the alarm goes off, the \link qcop.html QCop\endlink \a message will be sent to \a channel, with \a data as a parameter. If this function is called with exactly the same data as a previous call the subsequent call is ignored, so there is only ever one alarm with a given set of parameters. \sa deleteAlarm() */ void AlarmServer::addAlarm ( QDateTime when, const QCString& channel, const QCString& message, int data) { if ( qApp->type() == QApplication::GuiServer ) { bool needSave = FALSE; // Here we are the server so either it has been directly called from // within the server or it has been sent to us from a client via QCop if (!timerEventReceiver) timerEventReceiver = new TimerReceiverObject; timerEventItem *newTimerEventItem = new timerEventItem; newTimerEventItem->UTCtime = TimeConversion::toUTC( when ); newTimerEventItem->channel = channel; newTimerEventItem->message = message; newTimerEventItem->data = data; // explore the case of already having the event in here... QListIterator<timerEventItem> it( timerEventList ); for ( ; *it; ++it ) if ( *(*it) == *newTimerEventItem ) return; // if we made it here, it is okay to add the item... timerEventList.append( newTimerEventItem ); needSave = TRUE; // quicker than using setNearestTimerEvent() if ( nearestTimerEvent ) { if (newTimerEventItem->UTCtime < nearestTimerEvent->UTCtime) { nearestTimerEvent = newTimerEventItem; timerEventReceiver->killTimers(); timerEventReceiver->resetTimer(); } } else { nearestTimerEvent = newTimerEventItem; timerEventReceiver->resetTimer(); } if ( needSave ) saveState(); } else { #ifndef QT_NO_COP QCopEnvelope e( "QPE/System", "addAlarm(QDateTime,QCString,QCString,int)" ); e << when << channel << message << data; #endif } } /*! Deletes previously scheduled alarms which match \a when, \a channel, \a message, and \a data. Passing null values for \a when, \a channel, or for the \link qcop.html QCop\endlink \a message, acts as a wildcard meaning "any". Similarly, passing -1 for \a data indicates "any". If there is no matching alarm, nothing happens. \sa addAlarm() */ void AlarmServer::deleteAlarm (QDateTime when, const QCString& channel, const QCString& message, int data) { if ( qApp->type() == QApplication::GuiServer) { bool needSave = FALSE; if ( timerEventReceiver != NULL ) { timerEventReceiver->killTimers(); // iterate over the list of events QListIterator<timerEventItem> it( timerEventList ); time_t deleteTime = TimeConversion::toUTC( when ); for ( ; *it; ++it ) { // if its a match, delete it if ( ( (*it)->UTCtime == deleteTime || when.isNull() ) && ( channel.isNull() || (*it)->channel == channel ) && ( message.isNull() || (*it)->message == message ) && ( data==-1 || (*it)->data == data ) ) { // if it's first, then we need to update the timer if ( (*it) == nearestTimerEvent ) { timerEventList.remove(*it); setNearestTimerEvent(); } else { timerEventList.remove(*it); } needSave = TRUE; } } if ( nearestTimerEvent ) timerEventReceiver->resetTimer(); } if ( needSave ) saveState(); } else { #ifndef QT_NO_COP QCopEnvelope e( "QPE/System", "deleteAlarm(QDateTime,QCString,QCString,int)" ); e << when << channel << message << data; #endif } } /*! Writes the system clock to the hardware clock. */ void Global::writeHWClock() { if ( !triggerAtd( TRUE ) ) { // atd not running? set it ourselves system("/sbin/hwclock --systohc"); // ##### UTC? } } diff --git a/library/backend/vcc.y b/library/backend/vcc.y index 5bcf0cb..6781312 100644 --- a/library/backend/vcc.y +++ b/library/backend/vcc.y @@ -1,1208 +1,1208 @@ %{
/***************************************************************************
(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
Business Machines Corporation and Siemens Rolm Communications Inc.
For purposes of this license notice, the term Licensors shall mean,
collectively, Apple Computer, Inc., AT&T Corp., International
Business Machines Corporation and Siemens Rolm Communications Inc.
The term Licensor shall mean any of the Licensors.
Subject to acceptance of the following conditions, permission is hereby
granted by Licensors without the need for written agreement and without
license or royalty fees, to use, copy, modify and distribute this
software for any purpose.
The above copyright notice and the following four paragraphs must be
reproduced in all copies of this software and any software including
this software.
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
MODIFICATIONS.
IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.
The software is provided with RESTRICTED RIGHTS. Use, duplication, or
disclosure by the government are subject to restrictions set forth in
DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
***************************************************************************/
/*
* src: vcc.c
* doc: Parser for vCard and vCalendar. Note that this code is
* generated by a yacc parser generator. Generally it should not
* be edited by hand. The real source is vcc.y. The #line directives
* can be commented out here to make it easier to trace through
* in a debugger. However, if a bug is found it should
* be fixed in vcc.y and this file regenerated.
*/
/* debugging utilities */
#if __DEBUG
#define DBG_(x) printf x
#else
#define DBG_(x)
#endif
/**** External Functions ****/
/* assign local name to parser variables and functions so that
we can use more than one yacc based parser.
*/
#if 0
#define yyparse mime_parse
#define yylex mime_lex
#define yyerror mime_error
#define yychar mime_char
/* #define p_yyval p_mime_val */
#undef yyval
#define yyval mime_yyval
/* #define p_yylval p_mime_lval */
#undef yylval
#define yylval mime_yylval
#define yydebug mime_debug
#define yynerrs mime_nerrs
#define yyerrflag mime_errflag
#define yyss mime_ss
#define yyssp mime_ssp
#define yyvs mime_vs
#define yyvsp mime_vsp
#define yylhs mime_lhs
#define yylen mime_len
#define yydefred mime_defred
#define yydgoto mime_dgoto
#define yysindex mime_sindex
#define yyrindex mime_rindex
#define yygindex mime_gindex
#define yytable mime_table
#define yycheck mime_check
#define yyname mime_name
#define yyrule mime_rule
#ifdef YYPREFIX
#undef YYPREFIX
#endif
#define YYPREFIX "mime_"
#endif
#ifndef _NO_LINE_FOLDING
#define _SUPPORT_LINE_FOLDING 1
#endif
/* undef below if compile with MFC */
/* #define INCLUDEMFC 1 */
#if defined(WIN32) || defined(_WIN32)
#ifdef INCLUDEMFC
#include <afx.h>
#endif
#endif
#include <string.h>
#ifndef __MWERKS__
#include <stdlib.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
//#ifdef PALMTOPCENTER
//#include <qpe/vobject_p.h>
//#else
-#include "vobject_p.h"
+#include <qtopia/private/vobject_p.h> //#endif
/**** Types, Constants ****/
#define YYDEBUG 0 /* 1 to compile in some debugging code */
#define MAXTOKEN 256 /* maximum token (line) length */
#define YYSTACKSIZE 100 // ~unref ?
#define MAXLEVEL 10 /* max # of nested objects parseable */
/* (includes outermost) */
/**** Global Variables ****/
int mime_lineNum, mime_numErrors; /* yyerror() can use these */
static VObject* vObjList;
static VObject *curProp;
static VObject *curObj;
static VObject* ObjStack[MAXLEVEL];
static int ObjStackTop;
/* A helpful utility for the rest of the app. */
#if __CPLUSPLUS__
extern "C" {
#endif
extern void yyerror(char *s);
#if __CPLUSPLUS__
};
#endif
int yyparse();
enum LexMode {
L_NORMAL,
L_VCARD,
L_VCAL,
L_VEVENT,
L_VTODO,
L_VALUES,
L_BASE64,
L_QUOTED_PRINTABLE
};
/**** Private Forward Declarations ****/
static int pushVObject(const char *prop);
static VObject* popVObject();
static void lexPopMode(int top);
static int lexWithinMode(enum LexMode mode);
static void lexPushMode(enum LexMode mode);
static void enterProps(const char *s);
static void enterAttr(const char *s1, const char *s2);
static void enterValues(const char *value);
#define mime_error yyerror
void mime_error(char *s);
void mime_error_(char *s);
%}
/***************************************************************************/
/*** The grammar ****/
/***************************************************************************/
%union {
char *str;
VObject *vobj;
}
%token
EQ COLON DOT SEMICOLON SPACE HTAB LINESEP NEWLINE
BEGIN_VCARD END_VCARD BEGIN_VCAL END_VCAL
BEGIN_VEVENT END_VEVENT BEGIN_VTODO END_VTODO
ID
/*
* NEWLINE is the token that would occur outside a vCard,
* while LINESEP is the token that would occur inside a vCard.
*/
%token <str>
STRING ID
%type <str> name value
%type <vobj> vcard vcal vobject
%start mime
%%
mime: vobjects
;
vobjects: vobjects vobject
{ addList(&vObjList, $2); curObj = 0; }
| vobject
{ addList(&vObjList, $1); curObj = 0; }
;
vobject: vcard
| vcal
;
vcard:
BEGIN_VCARD
{
lexPushMode(L_VCARD);
if (!pushVObject(VCCardProp)) YYERROR;
}
items END_VCARD
{
lexPopMode(0);
$$ = popVObject();
}
| BEGIN_VCARD
{
lexPushMode(L_VCARD);
if (!pushVObject(VCCardProp)) YYERROR;
}
END_VCARD
{
lexPopMode(0);
$$ = popVObject();
}
;
items: items item
| item
;
item: prop COLON
{
lexPushMode(L_VALUES);
}
values LINESEP
{
if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE))
lexPopMode(0);
lexPopMode(0);
}
| error
;
prop: name
{
enterProps($1);
}
attr_params
| name
{
enterProps($1);
}
;
attr_params: attr_params attr_param
| attr_param
;
attr_param: SEMICOLON attr
;
attr: name
{
enterAttr($1,0);
}
| name EQ name
{
enterAttr($1,$3);
}
;
name: ID
;
values: value SEMICOLON { enterValues($1); } values
| value
{ enterValues($1); }
;
value: STRING
|
{ $$ = 0; }
;
vcal:
BEGIN_VCAL
{ if (!pushVObject(VCCalProp)) YYERROR; }
calitems
END_VCAL
{ $$ = popVObject(); }
| BEGIN_VCAL
{ if (!pushVObject(VCCalProp)) YYERROR; }
END_VCAL
{ $$ = popVObject(); }
;
calitems: calitems calitem
| calitem
;
calitem:
eventitem
| todoitem
| items
;
eventitem:
BEGIN_VEVENT
{
lexPushMode(L_VEVENT);
if (!pushVObject(VCEventProp)) YYERROR;
}
items
END_VEVENT
{
lexPopMode(0);
popVObject();
}
| BEGIN_VEVENT
{
lexPushMode(L_VEVENT);
if (!pushVObject(VCEventProp)) YYERROR;
}
END_VEVENT
{
lexPopMode(0);
popVObject();
}
;
todoitem:
BEGIN_VTODO
{
lexPushMode(L_VTODO);
if (!pushVObject(VCTodoProp)) YYERROR;
}
items
END_VTODO
{
lexPopMode(0);
popVObject();
}
| BEGIN_VTODO
{
lexPushMode(L_VTODO);
if (!pushVObject(VCTodoProp)) YYERROR;
}
END_VTODO
{
lexPopMode(0);
popVObject();
}
;
%%
/*------------------------------------*/
static int pushVObject(const char *prop)
{
VObject *newObj;
if (ObjStackTop == MAXLEVEL)
return FALSE;
ObjStack[++ObjStackTop] = curObj;
if (curObj) {
newObj = addProp(curObj,prop);
curObj = newObj;
}
else
curObj = newVObject(prop);
return TRUE;
}
/*---------------------------------------*/
/* This pops the recently built vCard off the stack and returns it. */
static VObject* popVObject()
{
VObject *oldObj;
if (ObjStackTop < 0) {
yyerror("pop on empty Object Stack\n");
return 0;
}
oldObj = curObj;
curObj = ObjStack[ObjStackTop--];
return oldObj;
}
static void enterValues(const char *value)
{
if (fieldedProp && *fieldedProp) {
if (value) {
addPropValue(curProp,*fieldedProp,value);
}
/* else this field is empty, advance to next field */
fieldedProp++;
}
else {
if (value) {
setVObjectStringZValue_(curProp,strdup( value ));
}
}
deleteStr(value);
}
static void enterProps(const char *s)
{
curProp = addGroup(curObj,s);
deleteStr(s);
}
static void enterAttr(const char *s1, const char *s2)
{
const char *p1, *p2;
p1 = lookupProp_(s1);
if (s2) {
VObject *a;
p2 = lookupProp_(s2);
a = addProp(curProp,p1);
setVObjectStringZValue(a,p2);
}
else
addProp(curProp,p1);
if (qstricmp(p1,VCBase64Prop) == 0 || (s2 && qstricmp(p2,VCBase64Prop)==0))
lexPushMode(L_BASE64);
else if (qstricmp(p1,VCQuotedPrintableProp) == 0
|| (s2 && qstricmp(p2,VCQuotedPrintableProp)==0))
lexPushMode(L_QUOTED_PRINTABLE);
deleteStr(s1); deleteStr(s2);
}
#define MAX_LEX_LOOKAHEAD_0 32
#define MAX_LEX_LOOKAHEAD 64
#define MAX_LEX_MODE_STACK_SIZE 10
#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop])
struct LexBuf {
/* input */
#ifdef INCLUDEMFC
CFile *inputFile;
#else
FILE *inputFile;
#endif
char *inputString;
unsigned long curPos;
unsigned long inputLen;
/* lookahead buffer */
/* -- lookahead buffer is short instead of char so that EOF
/ can be represented correctly.
*/
unsigned long len;
short buf[MAX_LEX_LOOKAHEAD];
unsigned long getPtr;
/* context stack */
unsigned long lexModeStackTop;
enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE];
/* token buffer */
unsigned long maxToken;
char *strs;
unsigned long strsLen;
} lexBuf;
static void lexPushMode(enum LexMode mode)
{
if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1))
yyerror("lexical context stack overflow");
else {
lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode;
}
}
static void lexPopMode(int top)
{
/* special case of pop for ease of error recovery -- this
version will never underflow */
if (top)
lexBuf.lexModeStackTop = 0;
else
if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--;
}
static int lexWithinMode(enum LexMode mode) {
unsigned long i;
for (i=0;i<lexBuf.lexModeStackTop;i++)
if (mode == lexBuf.lexModeStack[i]) return 1;
return 0;
}
static int lexGetc_()
{
/* get next char from input, no buffering. */
if (lexBuf.curPos == lexBuf.inputLen)
return EOF;
else if (lexBuf.inputString)
return *(lexBuf.inputString + lexBuf.curPos++);
else {
#ifdef INCLUDEMFC
char result;
return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF;
#else
return fgetc(lexBuf.inputFile);
#endif
}
}
static int lexGeta()
{
++lexBuf.len;
return (lexBuf.buf[lexBuf.getPtr] = lexGetc_());
}
static int lexGeta_(int i)
{
++lexBuf.len;
return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_());
}
static void lexSkipLookahead() {
if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
/* don't skip EOF. */
lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
lexBuf.len--;
}
}
static int lexLookahead() {
int c = (lexBuf.len)?
lexBuf.buf[lexBuf.getPtr]:
lexGeta();
/* do the \r\n -> \n or \r -> \n translation here */
if (c == '\r') {
int a = (lexBuf.len>1)?
lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]:
lexGeta_(1);
if (a == '\n') {
lexSkipLookahead();
}
lexBuf.buf[lexBuf.getPtr] = c = '\n';
}
else if (c == '\n') {
int a = (lexBuf.len>1)?
lexBuf.buf[lexBuf.getPtr+1]:
lexGeta_(1);
if (a == '\r') {
lexSkipLookahead();
}
lexBuf.buf[lexBuf.getPtr] = '\n';
}
return c;
}
static int lexGetc() {
int c = lexLookahead();
if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
/* EOF will remain in lookahead buffer */
lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
lexBuf.len--;
}
return c;
}
static void lexSkipLookaheadWord() {
if (lexBuf.strsLen <= lexBuf.len) {
lexBuf.len -= lexBuf.strsLen;
lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD;
}
}
static void lexClearToken()
{
lexBuf.strsLen = 0;
}
static void lexAppendc(int c)
{
lexBuf.strs[lexBuf.strsLen] = c;
/* append up to zero termination */
if (c == 0) return;
lexBuf.strsLen++;
if (lexBuf.strsLen > lexBuf.maxToken) {
/* double the token string size */
lexBuf.maxToken <<= 1;
lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken);
}
}
static char* lexStr() {
return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1);
}
static void lexSkipWhite() {
int c = lexLookahead();
while (c == ' ' || c == '\t') {
lexSkipLookahead();
c = lexLookahead();
}
}
static char* lexGetWord() {
int c;
lexSkipWhite();
lexClearToken();
c = lexLookahead();
while (c != EOF && !strchr("\t\n ;:=",c)) {
lexAppendc(c);
lexSkipLookahead();
c = lexLookahead();
}
lexAppendc(0);
return lexStr();
}
static void lexPushLookaheadc(int c) {
int putptr;
/* can't putback EOF, because it never leaves lookahead buffer */
if (c == EOF) return;
putptr = (int)lexBuf.getPtr - 1;
if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
lexBuf.getPtr = putptr;
lexBuf.buf[putptr] = c;
lexBuf.len += 1;
}
static char* lexLookaheadWord() {
/* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0
/ and thing bigger than that will stop the lookahead and return 0;
/ leading white spaces are not recoverable.
*/
int c;
int len = 0;
int curgetptr = 0;
lexSkipWhite();
lexClearToken();
curgetptr = (int)lexBuf.getPtr; // remember!
while (len < (MAX_LEX_LOOKAHEAD_0)) {
c = lexGetc();
len++;
if (c == EOF || strchr("\t\n ;:=", c)) {
lexAppendc(0);
/* restore lookahead buf. */
lexBuf.len += len;
lexBuf.getPtr = curgetptr;
return lexStr();
}
else
lexAppendc(c);
}
lexBuf.len += len; /* char that has been moved to lookahead buffer */
lexBuf.getPtr = curgetptr;
return 0;
}
#ifdef _SUPPORT_LINE_FOLDING
static void handleMoreRFC822LineBreak(int c) {
/* suport RFC 822 line break in cases like
* ADR: foo;
* morefoo;
* more foo;
*/
if (c == ';') {
int a;
lexSkipLookahead();
/* skip white spaces */
a = lexLookahead();
while (a == ' ' || a == '\t') {
lexSkipLookahead();
a = lexLookahead();
}
if (a == '\n') {
lexSkipLookahead();
a = lexLookahead();
if (a == ' ' || a == '\t') {
/* continuation, throw away all the \n and spaces read so
* far
*/
lexSkipWhite();
lexPushLookaheadc(';');
}
else {
lexPushLookaheadc('\n');
lexPushLookaheadc(';');
}
}
else {
lexPushLookaheadc(';');
}
}
}
static char* lexGet1Value() {
int c;
lexSkipWhite();
c = lexLookahead();
lexClearToken();
while (c != EOF && c != ';') {
if (c == '\\' ) {
int a;
lexSkipLookahead();
a = lexLookahead();
if ( a != ';' ) {
lexAppendc('\\');
} else {
lexAppendc( ';' );
lexSkipLookahead();
}
} else if (c == '\n') {
int a;
lexSkipLookahead();
a = lexLookahead();
if (a == ' ' || a == '\t') {
lexAppendc(' ');
lexSkipLookahead();
}
else {
lexPushLookaheadc('\n');
break;
}
}
else {
lexAppendc(c);
lexSkipLookahead();
}
c = lexLookahead();
}
lexAppendc(0);
handleMoreRFC822LineBreak(c);
return c==EOF?0:lexStr();
}
#endif
static int match_begin_name(int end) {
char *n = lexLookaheadWord();
int token = ID;
if (n) {
if (!qstricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD;
else if (!qstricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL;
else if (!qstricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT;
else if (!qstricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO;
deleteStr(n);
return token;
}
return 0;
}
#ifdef INCLUDEMFC
void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile)
#else
void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile)
#endif
{
// initialize lex mode stack
lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL;
// iniatialize lex buffer.
lexBuf.inputString = (char*) inputstring;
lexBuf.inputLen = inputlen;
lexBuf.curPos = 0;
lexBuf.inputFile = inputfile;
lexBuf.len = 0;
lexBuf.getPtr = 0;
lexBuf.maxToken = MAXTOKEN;
lexBuf.strs = (char*)malloc(MAXTOKEN);
lexBuf.strsLen = 0;
}
static void finiLex() {
free(lexBuf.strs);
}
/*-----------------------------------*/
/* This parses and converts the base64 format for binary encoding into
* a decoded buffer (allocated with new). See RFC 1521.
*/
static char * lexGetDataFromBase64()
{
unsigned long bytesLen = 0, bytesMax = 0;
int quadIx = 0, pad = 0;
unsigned long trip = 0;
unsigned char b;
int c;
unsigned char *bytes = NULL;
unsigned char *oldBytes = NULL;
DBG_(("db: lexGetDataFromBase64\n"));
while (1) {
c = lexGetc();
if (c == '\n') {
++mime_lineNum;
if (lexLookahead() == '\n') {
/* a '\n' character by itself means end of data */
break;
}
else continue; /* ignore '\n' */
}
else {
if ((c >= 'A') && (c <= 'Z'))
b = (unsigned char)(c - 'A');
else if ((c >= 'a') && (c <= 'z'))
b = (unsigned char)(c - 'a') + 26;
else if ((c >= '0') && (c <= '9'))
b = (unsigned char)(c - '0') + 52;
else if (c == '+')
b = 62;
else if (c == '/')
b = 63;
else if (c == '=') {
b = 0;
pad++;
} else if ((c == ' ') || (c == '\t')) {
continue;
} else { /* error condition */
if (bytes) free(bytes);
else if (oldBytes) free(oldBytes);
// error recovery: skip until 2 adjacent newlines.
DBG_(("db: invalid character 0x%x '%c'\n", c,c));
if (c != EOF) {
c = lexGetc();
while (c != EOF) {
if (c == '\n' && lexLookahead() == '\n') {
++mime_lineNum;
break;
}
c = lexGetc();
}
}
return NULL;
}
trip = (trip << 6) | b;
if (++quadIx == 4) {
unsigned char outBytes[3];
int numOut;
int i;
for (i = 0; i < 3; i++) {
outBytes[2-i] = (unsigned char)(trip & 0xFF);
trip >>= 8;
}
numOut = 3 - pad;
if (bytesLen + numOut > bytesMax) {
if (!bytes) {
bytesMax = 1024;
bytes = (unsigned char*)malloc((size_t)bytesMax);
}
else {
bytesMax <<= 2;
oldBytes = bytes;
bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax);
}
if (bytes == 0) {
mime_error("out of memory while processing BASE64 data\n");
}
}
if (bytes) {
memcpy(bytes + bytesLen, outBytes, numOut);
bytesLen += numOut;
}
trip = 0;
quadIx = 0;
}
}
} /* while */
DBG_(("db: bytesLen = %d\n", bytesLen));
/* kludge: all this won't be necessary if we have tree form
representation */
if (bytes) {
setValueWithSize(curProp,bytes,(unsigned int)bytesLen);
free(bytes);
}
else if (oldBytes) {
setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen);
free(oldBytes);
}
return 0;
}
static int match_begin_end_name(int end) {
int token;
lexSkipWhite();
if (lexLookahead() != ':') return ID;
lexSkipLookahead();
lexSkipWhite();
token = match_begin_name(end);
if (token == ID) {
lexPushLookaheadc(':');
DBG_(("db: ID '%s'\n", yylval.str));
return ID;
}
else if (token != 0) {
lexSkipLookaheadWord();
deleteStr(yylval.str);
DBG_(("db: begin/end %d\n", token));
return token;
}
return 0;
}
static char* lexGetQuotedPrintable()
{
int c;
lexSkipWhite();
c = lexLookahead();
lexClearToken();
while (c != EOF && c != ';') {
if (c == '\n') {
// break, leave '\n' on remaining chars.
break;
} else if (c == '=') {
int cur = 0;
int next;
lexSkipLookahead(); // skip '='
next = lexLookahead();
if (next == '\n') {
// skip and only skip the \n
lexSkipLookahead();
c = lexLookahead();
++mime_lineNum; // aid in error reporting
continue;
} else if (next >= '0' && next <= '9') {
cur = next - '0';
} else if (next >= 'A' && next <= 'F') {
cur = next - 'A' + 10;
} else {
// we have been sent buggy stuff. doesn't matter
// what we do so long as we keep going.
// should probably spit an error here
c = lexLookahead();
continue;
}
lexSkipLookahead(); // skip A-Z0-9
next = lexLookahead();
cur = cur * 16;
// this time really just expecting 0-9A-F
if (next >= '0' && next <= '9') {
cur += next - '0';
} else if (next >= 'A' && next <= 'F') {
cur += next - 'A' + 10;
} else {
// we have been sent buggy stuff. doesn't matter
// what we do so long as we keep going.
// should probably spit an error here
c = lexLookahead();
continue;
}
// got a valid escaped =. append it.
lexSkipLookahead(); // skip second 0-9A-F
lexAppendc(cur);
} else {
lexSkipLookahead(); // skip whatever we just read.
lexAppendc(c); // and append it.
}
c = lexLookahead();
}
lexAppendc(0);
return c==EOF?0:lexStr();
}
static int yylex() {
int lexmode = LEXMODE();
if (lexmode == L_VALUES) {
int c = lexGetc();
if (c == ';') {
DBG_(("db: SEMICOLON\n"));
lexPushLookaheadc(c);
handleMoreRFC822LineBreak(c);
lexSkipLookahead();
return SEMICOLON;
}
else if (strchr("\n",c)) {
++mime_lineNum;
/* consume all line separator(s) adjacent to each other */
c = lexLookahead();
while (strchr("\n",c)) {
lexSkipLookahead();
c = lexLookahead();
++mime_lineNum;
}
DBG_(("db: LINESEP\n"));
return LINESEP;
}
else {
char *p = 0;
lexPushLookaheadc(c);
if (lexWithinMode(L_BASE64)) {
/* get each char and convert to bin on the fly... */
p = lexGetDataFromBase64();
yylval.str = p;
return STRING;
}
else if (lexWithinMode(L_QUOTED_PRINTABLE)) {
p = lexGetQuotedPrintable();
}
else {
#ifdef _SUPPORT_LINE_FOLDING
p = lexGet1Value();
#else
p = lexGetStrUntil(";\n");
#endif
}
if (p) {
DBG_(("db: STRING: '%s'\n", p));
yylval.str = p;
return STRING;
}
else return 0;
}
}
else {
/* normal mode */
while (1) {
int c = lexGetc();
switch(c) {
case ':': {
/* consume all line separator(s) adjacent to each other */
/* ignoring linesep immediately after colon. */
c = lexLookahead();
while (strchr("\n",c)) {
lexSkipLookahead();
c = lexLookahead();
++mime_lineNum;
}
DBG_(("db: COLON\n"));
return COLON;
}
case ';':
DBG_(("db: SEMICOLON\n"));
return SEMICOLON;
case '=':
DBG_(("db: EQ\n"));
return EQ;
/* ignore whitespace in this mode */
case '\t':
case ' ': continue;
case '\n': {
++mime_lineNum;
continue;
}
case EOF: return 0;
break;
default: {
lexPushLookaheadc(c);
if (isalnum(c)) {
char *t = lexGetWord();
yylval.str = t;
if (!qstricmp(t, "begin")) {
return match_begin_end_name(0);
}
else if (!qstricmp(t,"end")) {
return match_begin_end_name(1);
}
else {
DBG_(("db: ID '%s'\n", t));
return ID;
}
}
else {
/* unknow token */
return 0;
}
break;
}
}
}
}
return 0;
}
/***************************************************************************/
/*** Public Functions ****/
/***************************************************************************/
static VObject* Parse_MIMEHelper()
{
ObjStackTop = -1;
mime_numErrors = 0;
mime_lineNum = 1;
vObjList = 0;
curObj = 0;
if (yyparse() != 0)
return 0;
finiLex();
return vObjList;
}
/*--------------------------------------------*/
DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len)
{
initLex(input, len, 0);
return Parse_MIMEHelper();
}
#if INCLUDEMFC
DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file)
{
unsigned long startPos;
VObject *result;
initLex(0,-1,file);
startPos = file->GetPosition();
if (!(result = Parse_MIMEHelper()))
file->Seek(startPos, CFile::begin);
return result;
}
#else
VObject* Parse_MIME_FromFile(FILE *file)
{
VObject *result;
long startPos;
initLex(0,(unsigned long)-1,file);
startPos = ftell(file);
if (!(result = Parse_MIMEHelper())) {
fseek(file,startPos,SEEK_SET);
}
return result;
}
DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname)
{
FILE *fp = fopen(fname,"r");
if (fp) {
VObject* o = Parse_MIME_FromFile(fp);
fclose(fp);
return o;
}
else {
char msg[80];
sprintf(msg, "can't open file '%s' for reading\n", fname);
mime_error_(msg);
return 0;
}
}
#endif
/*-------------------------------------*/
static MimeErrorHandler mimeErrorHandler;
DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me)
{
mimeErrorHandler = me;
}
void mime_error(char *s)
{
char msg[256];
if (mimeErrorHandler) {
sprintf(msg,"%s at line %d", s, mime_lineNum);
mimeErrorHandler(msg);
}
}
void mime_error_(char *s)
{
if (mimeErrorHandler) {
mimeErrorHandler(s);
}
}
diff --git a/library/backend/vcc_yacc.cpp b/library/backend/vcc_yacc.cpp index 19a108f..b2b0c14 100644 --- a/library/backend/vcc_yacc.cpp +++ b/library/backend/vcc_yacc.cpp @@ -1,1576 +1,1576 @@ #ifndef lint /*static char yysccsid[] = "from: @(#)yaccpar 1.9 (Berkeley) 02/21/93";*/ static char yyrcsid[] = "$Id$"; #endif #define YYBYACC 1 #define YYMAJOR 1 #define YYMINOR 9 #define yyclearin (yychar=(-1)) #define yyerrok (yyerrflag=0) #define YYRECOVERING (yyerrflag!=0) #define yyparse vccparse #define yylex vcclex #define yyerror vccerror #define yychar vccchar #define yyval vccval #define yylval vcclval #define yydebug vccdebug #define yynerrs vccnerrs #define yyerrflag vccerrflag #define yyss vccss #define yyssp vccssp #define yyvs vccvs #define yyvsp vccvsp #define yylhs vcclhs #define yylen vcclen #define yydefred vccdefred #define yydgoto vccdgoto #define yysindex vccsindex #define yyrindex vccrindex #define yygindex vccgindex #define yytable vcctable #define yycheck vcccheck #define yyname vccname #define yyrule vccrule #define YYPREFIX "vcc" #line 1 "backend/vcc.y" /***************************************************************************
(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
Business Machines Corporation and Siemens Rolm Communications Inc.
For purposes of this license notice, the term Licensors shall mean,
collectively, Apple Computer, Inc., AT&T Corp., International
Business Machines Corporation and Siemens Rolm Communications Inc.
The term Licensor shall mean any of the Licensors.
Subject to acceptance of the following conditions, permission is hereby
granted by Licensors without the need for written agreement and without
license or royalty fees, to use, copy, modify and distribute this
software for any purpose.
The above copyright notice and the following four paragraphs must be
reproduced in all copies of this software and any software including
this software.
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
MODIFICATIONS.
IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.
The software is provided with RESTRICTED RIGHTS. Use, duplication, or
disclosure by the government are subject to restrictions set forth in
DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
***************************************************************************/
/*
* src: vcc.c
* doc: Parser for vCard and vCalendar. Note that this code is
* generated by a yacc parser generator. Generally it should not
* be edited by hand. The real source is vcc.y. The #line directives
* can be commented out here to make it easier to trace through
* in a debugger. However, if a bug is found it should
* be fixed in vcc.y and this file regenerated.
*/
/* debugging utilities */
#if __DEBUG
#define DBG_(x) printf x
#else
#define DBG_(x)
#endif
/**** External Functions ****/
/* assign local name to parser variables and functions so that
we can use more than one yacc based parser.
*/
#if 0
#define yyparse mime_parse
#define yylex mime_lex
#define yyerror mime_error
#define yychar mime_char
/* #define p_yyval p_mime_val */
#undef yyval
#define yyval mime_yyval
/* #define p_yylval p_mime_lval */
#undef yylval
#define yylval mime_yylval
#define yydebug mime_debug
#define yynerrs mime_nerrs
#define yyerrflag mime_errflag
#define yyss mime_ss
#define yyssp mime_ssp
#define yyvs mime_vs
#define yyvsp mime_vsp
#define yylhs mime_lhs
#define yylen mime_len
#define yydefred mime_defred
#define yydgoto mime_dgoto
#define yysindex mime_sindex
#define yyrindex mime_rindex
#define yygindex mime_gindex
#define yytable mime_table
#define yycheck mime_check
#define yyname mime_name
#define yyrule mime_rule
#ifdef YYPREFIX
#undef YYPREFIX
#endif
#define YYPREFIX "mime_"
#endif
#ifndef _NO_LINE_FOLDING
#define _SUPPORT_LINE_FOLDING 1
#endif
/* undef below if compile with MFC */
/* #define INCLUDEMFC 1 */
#if defined(WIN32) || defined(_WIN32)
#ifdef INCLUDEMFC
#include <afx.h>
#endif
#endif
#include <string.h>
#ifndef __MWERKS__
#include <stdlib.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
/*#ifdef PALMTOPCENTER
*/ /*#include <qpe/vobject_p.h>
*/ /*#else
*/ -#include "vobject_p.h"
+#include <qtopia/private/vobject_p.h> /*#endif
*/ /**** Types, Constants ****/
#define YYDEBUG 0 /* 1 to compile in some debugging code */
#define MAXTOKEN 256 /* maximum token (line) length */
#define YYSTACKSIZE 100 /* ~unref ?
*/ #define MAXLEVEL 10 /* max # of nested objects parseable */
/* (includes outermost) */
/**** Global Variables ****/
int mime_lineNum, mime_numErrors; /* yyerror() can use these */
static VObject* vObjList;
static VObject *curProp;
static VObject *curObj;
static VObject* ObjStack[MAXLEVEL];
static int ObjStackTop;
/* A helpful utility for the rest of the app. */
#if __CPLUSPLUS__
extern "C" {
#endif
extern void yyerror(char *s);
#if __CPLUSPLUS__
};
#endif
int yyparse();
enum LexMode {
L_NORMAL,
L_VCARD,
L_VCAL,
L_VEVENT,
L_VTODO,
L_VALUES,
L_BASE64,
L_QUOTED_PRINTABLE
};
/**** Private Forward Declarations ****/
static int pushVObject(const char *prop);
static VObject* popVObject();
static void lexPopMode(int top);
static int lexWithinMode(enum LexMode mode);
static void lexPushMode(enum LexMode mode);
static void enterProps(const char *s);
static void enterAttr(const char *s1, const char *s2);
static void enterValues(const char *value);
#define mime_error yyerror
void mime_error(char *s);
void mime_error_(char *s);
#line 189 "backend/vcc.y" typedef union {
char *str;
VObject *vobj;
} YYSTYPE; #line 225 "y.tab.c" #define EQ 257 #define COLON 258 #define DOT 259 #define SEMICOLON 260 #define SPACE 261 #define HTAB 262 #define LINESEP 263 #define NEWLINE 264 #define BEGIN_VCARD 265 #define END_VCARD 266 #define BEGIN_VCAL 267 #define END_VCAL 268 #define BEGIN_VEVENT 269 #define END_VEVENT 270 #define BEGIN_VTODO 271 #define END_VTODO 272 #define ID 273 #define STRING 274 #define YYERRCODE 256 short vcclhs[] = { -1, 0, 6, 6, 5, 5, 8, 3, 9, 3, 7, 7, 13, 10, 10, 15, 11, 11, 14, 14, 16, 17, 17, 1, 18, 12, 12, 2, 2, 20, 4, 21, 4, 19, 19, 22, 22, 22, 25, 23, 26, 23, 27, 24, 28, 24, }; short vcclen[] = { 2, 1, 2, 1, 1, 1, 0, 4, 0, 3, 2, 1, 0, 5, 1, 0, 3, 1, 2, 1, 2, 1, 3, 1, 0, 4, 1, 1, 0, 0, 4, 0, 3, 2, 1, 1, 1, 1, 0, 4, 0, 3, 0, 4, 0, 3, }; short vccdefred[] = { 0, 0, 0, 0, 4, 5, 3, 0, 0, 0, 0, 0, 2, 14, 23, 0, 0, 11, 0, 9, 0, 0, 0, 0, 34, 35, 36, 32, 0, 7, 10, 12, 0, 0, 0, 0, 30, 33, 0, 0, 19, 0, 0, 41, 0, 45, 0, 20, 18, 27, 0, 0, 39, 43, 0, 24, 13, 22, 0, 25, }; short vccdgoto[] = { 3, 15, 50, 4, 5, 6, 7, 22, 8, 9, 17, 18, 51, 41, 39, 28, 40, 47, 58, 23, 10, 11, 24, 25, 26, 32, 33, 34, 35, }; short vccsindex[] = { -262, 0, 0, 0, 0, 0, 0, -262, -252, -219, -249, -256, 0, 0, 0, 0, -227, 0, -242, 0, 0, 0, -252, -254, 0, 0, 0, 0, -208, 0, 0, 0, -252, -228, -252, -213, 0, 0, -212, -208, 0, -214, -233, 0, -224, 0, -195, 0, 0, 0, -197, -199, 0, 0, -212, 0, 0, 0, -214, 0, }; short vccrindex[] = { 0, -222, -238, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, -215, 0, 0, 0, 0, -220, -218, -260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, -250, 0, 0, 0, 0, -202, 0, 0, 0, -196, 0, 0, 0, 0, 0, 0, 0, -250, 0, }; short vccgindex[] = { 0, 3, 0, 0, 0, 61, 0, -7, 0, 0, -16, 0, 11, 0, 0, 0, 31, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, }; #define YYTABLESIZE 71 short vcctable[] = { 30, 16, 13, 1, 13, 2, 30, 13, 37, 37, 28, 37, 27, 28, 36, 20, 31, 21, 29, 14, 20, 14, 21, 13, 14, 42, 30, 44, 30, 13, 31, 29, 13, 29, 6, 29, 38, 52, 42, 29, 14, 46, 43, 17, 8, 15, 14, 19, 53, 14, 40, 6, 38, 38, 44, 42, 21, 57, 21, 45, 49, 14, 54, 55, 56, 1, 16, 26, 12, 59, 48, 37, }; short vcccheck[] = { 16, 8, 256, 265, 256, 267, 22, 256, 268, 269, 260, 271, 268, 263, 268, 269, 258, 271, 256, 273, 269, 273, 271, 256, 273, 32, 42, 34, 44, 256, 268, 269, 256, 271, 256, 273, 256, 270, 256, 266, 273, 38, 270, 258, 266, 260, 273, 266, 272, 273, 270, 273, 260, 273, 272, 273, 258, 54, 260, 272, 274, 273, 257, 260, 263, 0, 258, 263, 7, 58, 39, 23, }; #define YYFINAL 3 #ifndef YYDEBUG #define YYDEBUG 0 #endif #define YYMAXTOKEN 274 #if YYDEBUG char *vccname[] = { "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"EQ","COLON","DOT","SEMICOLON", "SPACE","HTAB","LINESEP","NEWLINE","BEGIN_VCARD","END_VCARD","BEGIN_VCAL", "END_VCAL","BEGIN_VEVENT","END_VEVENT","BEGIN_VTODO","END_VTODO","ID","STRING", }; char *vccrule[] = { "$accept : mime", "mime : vobjects", "vobjects : vobjects vobject", "vobjects : vobject", "vobject : vcard", "vobject : vcal", "$$1 :", "vcard : BEGIN_VCARD $$1 items END_VCARD", "$$2 :", "vcard : BEGIN_VCARD $$2 END_VCARD", "items : items item", "items : item", "$$3 :", "item : prop COLON $$3 values LINESEP", "item : error", "$$4 :", "prop : name $$4 attr_params", "prop : name", "attr_params : attr_params attr_param", "attr_params : attr_param", "attr_param : SEMICOLON attr", "attr : name", "attr : name EQ name", "name : ID", "$$5 :", "values : value SEMICOLON $$5 values", "values : value", "value : STRING", "value :", "$$6 :", "vcal : BEGIN_VCAL $$6 calitems END_VCAL", "$$7 :", "vcal : BEGIN_VCAL $$7 END_VCAL", "calitems : calitems calitem", "calitems : calitem", "calitem : eventitem", "calitem : todoitem", "calitem : items", "$$8 :", "eventitem : BEGIN_VEVENT $$8 items END_VEVENT", "$$9 :", "eventitem : BEGIN_VEVENT $$9 END_VEVENT", "$$10 :", "todoitem : BEGIN_VTODO $$10 items END_VTODO", "$$11 :", "todoitem : BEGIN_VTODO $$11 END_VTODO", }; #endif #ifdef YYSTACKSIZE #undef YYMAXDEPTH #define YYMAXDEPTH YYSTACKSIZE #else #ifdef YYMAXDEPTH #define YYSTACKSIZE YYMAXDEPTH #else #define YYSTACKSIZE 500 #define YYMAXDEPTH 500 #endif #endif int yydebug; int yynerrs; int yyerrflag; int yychar; short *yyssp; YYSTYPE *yyvsp; YYSTYPE yyval; YYSTYPE yylval; short yyss[YYSTACKSIZE]; YYSTYPE yyvs[YYSTACKSIZE]; #define yystacksize YYSTACKSIZE #line 382 "backend/vcc.y" /*------------------------------------*/
static int pushVObject(const char *prop)
{
VObject *newObj;
if (ObjStackTop == MAXLEVEL)
return FALSE;
ObjStack[++ObjStackTop] = curObj;
if (curObj) {
newObj = addProp(curObj,prop);
curObj = newObj;
}
else
curObj = newVObject(prop);
return TRUE;
}
/*---------------------------------------*/
/* This pops the recently built vCard off the stack and returns it. */
static VObject* popVObject()
{
VObject *oldObj;
if (ObjStackTop < 0) {
yyerror("pop on empty Object Stack\n");
return 0;
}
oldObj = curObj;
curObj = ObjStack[ObjStackTop--];
return oldObj;
}
static void enterValues(const char *value)
{
if (fieldedProp && *fieldedProp) {
if (value) {
addPropValue(curProp,*fieldedProp,value);
}
/* else this field is empty, advance to next field */
fieldedProp++;
}
else {
if (value) {
setVObjectStringZValue_(curProp,strdup( value ));
}
}
deleteStr(value);
}
static void enterProps(const char *s)
{
curProp = addGroup(curObj,s);
deleteStr(s);
}
static void enterAttr(const char *s1, const char *s2)
{
const char *p1, *p2;
p1 = lookupProp_(s1);
if (s2) {
VObject *a;
p2 = lookupProp_(s2);
a = addProp(curProp,p1);
setVObjectStringZValue(a,p2);
}
else
addProp(curProp,p1);
if (qstricmp(p1,VCBase64Prop) == 0 || (s2 && qstricmp(p2,VCBase64Prop)==0))
lexPushMode(L_BASE64);
else if (qstricmp(p1,VCQuotedPrintableProp) == 0
|| (s2 && qstricmp(p2,VCQuotedPrintableProp)==0))
lexPushMode(L_QUOTED_PRINTABLE);
deleteStr(s1); deleteStr(s2);
}
#define MAX_LEX_LOOKAHEAD_0 32
#define MAX_LEX_LOOKAHEAD 64
#define MAX_LEX_MODE_STACK_SIZE 10
#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop])
struct LexBuf {
/* input */
#ifdef INCLUDEMFC
CFile *inputFile;
#else
FILE *inputFile;
#endif
char *inputString;
unsigned long curPos;
unsigned long inputLen;
/* lookahead buffer */
/* -- lookahead buffer is short instead of char so that EOF
/ can be represented correctly.
*/
unsigned long len;
short buf[MAX_LEX_LOOKAHEAD];
unsigned long getPtr;
/* context stack */
unsigned long lexModeStackTop;
enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE];
/* token buffer */
unsigned long maxToken;
char *strs;
unsigned long strsLen;
} lexBuf;
static void lexPushMode(enum LexMode mode)
{
if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1))
yyerror("lexical context stack overflow");
else {
lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode;
}
}
static void lexPopMode(int top)
{
/* special case of pop for ease of error recovery -- this
version will never underflow */
if (top)
lexBuf.lexModeStackTop = 0;
else
if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--;
}
static int lexWithinMode(enum LexMode mode) {
unsigned long i;
for (i=0;i<lexBuf.lexModeStackTop;i++)
if (mode == lexBuf.lexModeStack[i]) return 1;
return 0;
}
static int lexGetc_()
{
/* get next char from input, no buffering. */
if (lexBuf.curPos == lexBuf.inputLen)
return EOF;
else if (lexBuf.inputString)
return *(lexBuf.inputString + lexBuf.curPos++);
else {
#ifdef INCLUDEMFC
char result;
return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF;
#else
return fgetc(lexBuf.inputFile);
#endif
}
}
static int lexGeta()
{
++lexBuf.len;
return (lexBuf.buf[lexBuf.getPtr] = lexGetc_());
}
static int lexGeta_(int i)
{
++lexBuf.len;
return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_());
}
static void lexSkipLookahead() {
if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
/* don't skip EOF. */
lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
lexBuf.len--;
}
}
static int lexLookahead() {
int c = (lexBuf.len)?
lexBuf.buf[lexBuf.getPtr]:
lexGeta();
/* do the \r\n -> \n or \r -> \n translation here */
if (c == '\r') {
int a = (lexBuf.len>1)?
lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]:
lexGeta_(1);
if (a == '\n') {
lexSkipLookahead();
}
lexBuf.buf[lexBuf.getPtr] = c = '\n';
}
else if (c == '\n') {
int a = (lexBuf.len>1)?
lexBuf.buf[lexBuf.getPtr+1]:
lexGeta_(1);
if (a == '\r') {
lexSkipLookahead();
}
lexBuf.buf[lexBuf.getPtr] = '\n';
}
return c;
}
static int lexGetc() {
int c = lexLookahead();
if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
/* EOF will remain in lookahead buffer */
lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
lexBuf.len--;
}
return c;
}
static void lexSkipLookaheadWord() {
if (lexBuf.strsLen <= lexBuf.len) {
lexBuf.len -= lexBuf.strsLen;
lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD;
}
}
static void lexClearToken()
{
lexBuf.strsLen = 0;
}
static void lexAppendc(int c)
{
lexBuf.strs[lexBuf.strsLen] = c;
/* append up to zero termination */
if (c == 0) return;
lexBuf.strsLen++;
if (lexBuf.strsLen > lexBuf.maxToken) {
/* double the token string size */
lexBuf.maxToken <<= 1;
lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken);
}
}
static char* lexStr() {
return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1);
}
static void lexSkipWhite() {
int c = lexLookahead();
while (c == ' ' || c == '\t') {
lexSkipLookahead();
c = lexLookahead();
}
}
static char* lexGetWord() {
int c;
lexSkipWhite();
lexClearToken();
c = lexLookahead();
while (c != EOF && !strchr("\t\n ;:=",c)) {
lexAppendc(c);
lexSkipLookahead();
c = lexLookahead();
}
lexAppendc(0);
return lexStr();
}
static void lexPushLookaheadc(int c) {
int putptr;
/* can't putback EOF, because it never leaves lookahead buffer */
if (c == EOF) return;
putptr = (int)lexBuf.getPtr - 1;
if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
lexBuf.getPtr = putptr;
lexBuf.buf[putptr] = c;
lexBuf.len += 1;
}
static char* lexLookaheadWord() {
/* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0
/ and thing bigger than that will stop the lookahead and return 0;
/ leading white spaces are not recoverable.
*/
int c;
int len = 0;
int curgetptr = 0;
lexSkipWhite();
lexClearToken();
curgetptr = (int)lexBuf.getPtr; // remember!
while (len < (MAX_LEX_LOOKAHEAD_0)) {
c = lexGetc();
len++;
if (c == EOF || strchr("\t\n ;:=", c)) {
lexAppendc(0);
/* restore lookahead buf. */
lexBuf.len += len;
lexBuf.getPtr = curgetptr;
return lexStr();
}
else
lexAppendc(c);
}
lexBuf.len += len; /* char that has been moved to lookahead buffer */
lexBuf.getPtr = curgetptr;
return 0;
}
#ifdef _SUPPORT_LINE_FOLDING
static void handleMoreRFC822LineBreak(int c) {
/* suport RFC 822 line break in cases like
* ADR: foo;
* morefoo;
* more foo;
*/
if (c == ';') {
int a;
lexSkipLookahead();
/* skip white spaces */
a = lexLookahead();
while (a == ' ' || a == '\t') {
lexSkipLookahead();
a = lexLookahead();
}
if (a == '\n') {
lexSkipLookahead();
a = lexLookahead();
if (a == ' ' || a == '\t') {
/* continuation, throw away all the \n and spaces read so
* far
*/
lexSkipWhite();
lexPushLookaheadc(';');
}
else {
lexPushLookaheadc('\n');
lexPushLookaheadc(';');
}
}
else {
lexPushLookaheadc(';');
}
}
}
static char* lexGet1Value() {
int c;
lexSkipWhite();
c = lexLookahead();
lexClearToken();
while (c != EOF && c != ';') {
if (c == '\\' ) {
int a;
lexSkipLookahead();
a = lexLookahead();
if ( a != ';' ) {
lexAppendc('\\');
} else {
lexAppendc( ';' );
lexSkipLookahead();
}
} else if (c == '\n') {
int a;
lexSkipLookahead();
a = lexLookahead();
if (a == ' ' || a == '\t') {
lexAppendc(' ');
lexSkipLookahead();
}
else {
lexPushLookaheadc('\n');
break;
}
}
else {
lexAppendc(c);
lexSkipLookahead();
}
c = lexLookahead();
}
lexAppendc(0);
handleMoreRFC822LineBreak(c);
return c==EOF?0:lexStr();
}
#endif
static int match_begin_name(int end) {
char *n = lexLookaheadWord();
int token = ID;
if (n) {
if (!qstricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD;
else if (!qstricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL;
else if (!qstricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT;
else if (!qstricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO;
deleteStr(n);
return token;
}
return 0;
}
#ifdef INCLUDEMFC
void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile)
#else
void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile)
#endif
{
// initialize lex mode stack
lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL;
// iniatialize lex buffer.
lexBuf.inputString = (char*) inputstring;
lexBuf.inputLen = inputlen;
lexBuf.curPos = 0;
lexBuf.inputFile = inputfile;
lexBuf.len = 0;
lexBuf.getPtr = 0;
lexBuf.maxToken = MAXTOKEN;
lexBuf.strs = (char*)malloc(MAXTOKEN);
lexBuf.strsLen = 0;
}
static void finiLex() {
free(lexBuf.strs);
}
/*-----------------------------------*/
/* This parses and converts the base64 format for binary encoding into
* a decoded buffer (allocated with new). See RFC 1521.
*/
static char * lexGetDataFromBase64()
{
unsigned long bytesLen = 0, bytesMax = 0;
int quadIx = 0, pad = 0;
unsigned long trip = 0;
unsigned char b;
int c;
unsigned char *bytes = NULL;
unsigned char *oldBytes = NULL;
DBG_(("db: lexGetDataFromBase64\n"));
while (1) {
c = lexGetc();
if (c == '\n') {
++mime_lineNum;
if (lexLookahead() == '\n') {
/* a '\n' character by itself means end of data */
break;
}
else continue; /* ignore '\n' */
}
else {
if ((c >= 'A') && (c <= 'Z'))
b = (unsigned char)(c - 'A');
else if ((c >= 'a') && (c <= 'z'))
b = (unsigned char)(c - 'a') + 26;
else if ((c >= '0') && (c <= '9'))
b = (unsigned char)(c - '0') + 52;
else if (c == '+')
b = 62;
else if (c == '/')
b = 63;
else if (c == '=') {
b = 0;
pad++;
} else if ((c == ' ') || (c == '\t')) {
continue;
} else { /* error condition */
if (bytes) free(bytes);
else if (oldBytes) free(oldBytes);
// error recovery: skip until 2 adjacent newlines.
DBG_(("db: invalid character 0x%x '%c'\n", c,c));
if (c != EOF) {
c = lexGetc();
while (c != EOF) {
if (c == '\n' && lexLookahead() == '\n') {
++mime_lineNum;
break;
}
c = lexGetc();
}
}
return NULL;
}
trip = (trip << 6) | b;
if (++quadIx == 4) {
unsigned char outBytes[3];
int numOut;
int i;
for (i = 0; i < 3; i++) {
outBytes[2-i] = (unsigned char)(trip & 0xFF);
trip >>= 8;
}
numOut = 3 - pad;
if (bytesLen + numOut > bytesMax) {
if (!bytes) {
bytesMax = 1024;
bytes = (unsigned char*)malloc((size_t)bytesMax);
}
else {
bytesMax <<= 2;
oldBytes = bytes;
bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax);
}
if (bytes == 0) {
mime_error("out of memory while processing BASE64 data\n");
}
}
if (bytes) {
memcpy(bytes + bytesLen, outBytes, numOut);
bytesLen += numOut;
}
trip = 0;
quadIx = 0;
}
}
} /* while */
DBG_(("db: bytesLen = %d\n", bytesLen));
/* kludge: all this won't be necessary if we have tree form
representation */
if (bytes) {
setValueWithSize(curProp,bytes,(unsigned int)bytesLen);
free(bytes);
}
else if (oldBytes) {
setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen);
free(oldBytes);
}
return 0;
}
static int match_begin_end_name(int end) {
int token;
lexSkipWhite();
if (lexLookahead() != ':') return ID;
lexSkipLookahead();
lexSkipWhite();
token = match_begin_name(end);
if (token == ID) {
lexPushLookaheadc(':');
DBG_(("db: ID '%s'\n", yylval.str));
return ID;
}
else if (token != 0) {
lexSkipLookaheadWord();
deleteStr(yylval.str);
DBG_(("db: begin/end %d\n", token));
return token;
}
return 0;
}
static char* lexGetQuotedPrintable()
{
int cur;
lexClearToken();
do {
cur = lexGetc();
switch (cur) {
case '=': {
int c = 0;
int next[2];
int i;
for (i = 0; i < 2; i++) {
next[i] = lexGetc();
if (next[i] >= '0' && next[i] <= '9')
c = c * 16 + next[i] - '0';
else if (next[i] >= 'A' && next[i] <= 'F')
c = c * 16 + next[i] - 'A' + 10;
else
break;
}
if (i == 0) {
/* single '=' follow by LINESEP is continuation sign? */
if (next[0] == '\n') {
++mime_lineNum;
}
else {
lexPushLookaheadc('=');
goto EndString;
}
}
else if (i == 1) {
lexPushLookaheadc(next[1]);
lexPushLookaheadc(next[0]);
lexAppendc('=');
} else {
lexAppendc(c);
}
break;
} /* '=' */
case '\n': {
lexPushLookaheadc('\n');
goto EndString;
}
case (int)EOF:
break;
default:
lexAppendc(cur);
break;
} /* switch */
} while (cur != (int)EOF);
EndString:
lexAppendc(0);
return lexStr();
} /* LexQuotedPrintable */
static int yylex() {
int lexmode = LEXMODE();
if (lexmode == L_VALUES) {
int c = lexGetc();
if (c == ';') {
DBG_(("db: SEMICOLON\n"));
lexPushLookaheadc(c);
handleMoreRFC822LineBreak(c);
lexSkipLookahead();
return SEMICOLON;
}
else if (strchr("\n",c)) {
++mime_lineNum;
/* consume all line separator(s) adjacent to each other */
c = lexLookahead();
while (strchr("\n",c)) {
lexSkipLookahead();
c = lexLookahead();
++mime_lineNum;
}
DBG_(("db: LINESEP\n"));
return LINESEP;
}
else {
char *p = 0;
lexPushLookaheadc(c);
if (lexWithinMode(L_BASE64)) {
/* get each char and convert to bin on the fly... */
p = lexGetDataFromBase64();
yylval.str = p;
return STRING;
}
else if (lexWithinMode(L_QUOTED_PRINTABLE)) {
p = lexGetQuotedPrintable();
}
else {
#ifdef _SUPPORT_LINE_FOLDING
p = lexGet1Value();
#else
p = lexGetStrUntil(";\n");
#endif
}
if (p) {
DBG_(("db: STRING: '%s'\n", p));
yylval.str = p;
return STRING;
}
else return 0;
}
}
else {
/* normal mode */
while (1) {
int c = lexGetc();
switch(c) {
case ':': {
/* consume all line separator(s) adjacent to each other */
/* ignoring linesep immediately after colon. */
c = lexLookahead();
while (strchr("\n",c)) {
lexSkipLookahead();
c = lexLookahead();
++mime_lineNum;
}
DBG_(("db: COLON\n"));
return COLON;
}
case ';':
DBG_(("db: SEMICOLON\n"));
return SEMICOLON;
case '=':
DBG_(("db: EQ\n"));
return EQ;
/* ignore whitespace in this mode */
case '\t':
case ' ': continue;
case '\n': {
++mime_lineNum;
continue;
}
case EOF: return 0;
break;
default: {
lexPushLookaheadc(c);
if (isalnum(c)) {
char *t = lexGetWord();
yylval.str = t;
if (!qstricmp(t, "begin")) {
return match_begin_end_name(0);
}
else if (!qstricmp(t,"end")) {
return match_begin_end_name(1);
}
else {
DBG_(("db: ID '%s'\n", t));
return ID;
}
}
else {
/* unknow token */
return 0;
}
break;
}
}
}
}
return 0;
}
/***************************************************************************/
/*** Public Functions ****/
/***************************************************************************/
static VObject* Parse_MIMEHelper()
{
ObjStackTop = -1;
mime_numErrors = 0;
mime_lineNum = 1;
vObjList = 0;
curObj = 0;
if (yyparse() != 0)
return 0;
finiLex();
return vObjList;
}
/*--------------------------------------------*/
DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len)
{
initLex(input, len, 0);
return Parse_MIMEHelper();
}
#if INCLUDEMFC
DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file)
{
unsigned long startPos;
VObject *result;
initLex(0,-1,file);
startPos = file->GetPosition();
if (!(result = Parse_MIMEHelper()))
file->Seek(startPos, CFile::begin);
return result;
}
#else
VObject* Parse_MIME_FromFile(FILE *file)
{
VObject *result;
long startPos;
initLex(0,(unsigned long)-1,file);
startPos = ftell(file);
if (!(result = Parse_MIMEHelper())) {
fseek(file,startPos,SEEK_SET);
}
return result;
}
DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname)
{
FILE *fp = fopen(fname,"r");
if (fp) {
VObject* o = Parse_MIME_FromFile(fp);
fclose(fp);
return o;
}
else {
char msg[80];
sprintf(msg, "can't open file '%s' for reading\n", fname);
mime_error_(msg);
return 0;
}
}
#endif
/*-------------------------------------*/
static MimeErrorHandler mimeErrorHandler;
DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me)
{
mimeErrorHandler = me;
}
void mime_error(char *s)
{
char msg[256];
if (mimeErrorHandler) {
sprintf(msg,"%s at line %d", s, mime_lineNum);
mimeErrorHandler(msg);
}
}
void mime_error_(char *s)
{
if (mimeErrorHandler) {
mimeErrorHandler(s);
}
}
#line 1221 "y.tab.c" #define YYABORT goto yyabort #define YYREJECT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab int #if defined(__STDC__) yyparse(void) #else yyparse() #endif { register int yym, yyn, yystate; #if YYDEBUG register char *yys; extern char *getenv(); if (yys = getenv("YYDEBUG")) { yyn = *yys; if (yyn >= '0' && yyn <= '9') yydebug = yyn - '0'; } #endif yynerrs = 0; yyerrflag = 0; yychar = (-1); yyssp = yyss; yyvsp = yyvs; *yyssp = yystate = 0; yyloop: if ((yyn = yydefred[yystate]) != 0) goto yyreduce; if (yychar < 0) { if ((yychar = yylex()) < 0) yychar = 0; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("%sdebug: state %d, reading %d (%s)\n", YYPREFIX, yystate, yychar, yys); } #endif } if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { #if YYDEBUG if (yydebug) printf("%sdebug: state %d, shifting to state %d\n", YYPREFIX, yystate, yytable[yyn]); #endif if (yyssp >= yyss + yystacksize - 1) { goto yyoverflow; } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; yychar = (-1); if (yyerrflag > 0) --yyerrflag; goto yyloop; } if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { yyn = yytable[yyn]; goto yyreduce; } if (yyerrflag) goto yyinrecovery; yyerror("syntax error"); #ifdef lint goto yyerrlab; #endif yyerrlab: ++yynerrs; yyinrecovery: if (yyerrflag < 3) { yyerrflag = 3; for (;;) { if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) { #if YYDEBUG if (yydebug) printf("%sdebug: state %d, error recovery shifting\ to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); #endif if (yyssp >= yyss + yystacksize - 1) { goto yyoverflow; } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; goto yyloop; } else { #if YYDEBUG if (yydebug) printf("%sdebug: error recovery discarding state %d\n", YYPREFIX, *yyssp); #endif if (yyssp <= yyss) goto yyabort; --yyssp; --yyvsp; } } } else { if (yychar == 0) goto yyabort; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("%sdebug: state %d, error recovery discards token %d (%s)\n", YYPREFIX, yystate, yychar, yys); } #endif yychar = (-1); goto yyloop; } yyreduce: #if YYDEBUG if (yydebug) printf("%sdebug: state %d, reducing by rule %d (%s)\n", YYPREFIX, yystate, yyn, yyrule[yyn]); #endif yym = yylen[yyn]; yyval = yyvsp[1-yym]; switch (yyn) { case 2: #line 221 "backend/vcc.y" { addList(&vObjList, yyvsp[0].vobj); curObj = 0; } break; case 3: #line 223 "backend/vcc.y" { addList(&vObjList, yyvsp[0].vobj); curObj = 0; } break; case 6: #line 232 "backend/vcc.y" {
lexPushMode(L_VCARD);
if (!pushVObject(VCCardProp)) YYERROR;
} break; case 7: #line 237 "backend/vcc.y" {
lexPopMode(0);
yyval.vobj = popVObject();
} break; case 8: #line 242 "backend/vcc.y" {
lexPushMode(L_VCARD);
if (!pushVObject(VCCardProp)) YYERROR;
} break; case 9: #line 247 "backend/vcc.y" {
lexPopMode(0);
yyval.vobj = popVObject();
} break; case 12: #line 258 "backend/vcc.y" {
lexPushMode(L_VALUES);
} break; case 13: #line 262 "backend/vcc.y" {
if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE))
lexPopMode(0);
lexPopMode(0);
} break; case 15: #line 271 "backend/vcc.y" {
enterProps(yyvsp[0].str);
} break; case 17: #line 276 "backend/vcc.y" {
enterProps(yyvsp[0].str);
} break; case 21: #line 289 "backend/vcc.y" {
enterAttr(yyvsp[0].str,0);
} break; case 22: #line 293 "backend/vcc.y" {
enterAttr(yyvsp[-2].str,yyvsp[0].str);
} break; case 24: #line 302 "backend/vcc.y" { enterValues(yyvsp[-1].str); } break; case 26: #line 304 "backend/vcc.y" { enterValues(yyvsp[0].str); } break; case 28: #line 309 "backend/vcc.y" { yyval.str = 0; } break; case 29: #line 314 "backend/vcc.y" { if (!pushVObject(VCCalProp)) YYERROR; } break; case 30: #line 317 "backend/vcc.y" { yyval.vobj = popVObject(); } break; case 31: #line 319 "backend/vcc.y" { if (!pushVObject(VCCalProp)) YYERROR; } break; case 32: #line 321 "backend/vcc.y" { yyval.vobj = popVObject(); } break; case 38: #line 336 "backend/vcc.y" {
lexPushMode(L_VEVENT);
if (!pushVObject(VCEventProp)) YYERROR;
} break; case 39: #line 342 "backend/vcc.y" {
lexPopMode(0);
popVObject();
} break; case 40: #line 347 "backend/vcc.y" {
lexPushMode(L_VEVENT);
if (!pushVObject(VCEventProp)) YYERROR;
} break; case 41: #line 352 "backend/vcc.y" {
lexPopMode(0);
popVObject();
} break; case 42: #line 360 "backend/vcc.y" {
lexPushMode(L_VTODO);
if (!pushVObject(VCTodoProp)) YYERROR;
} break; case 43: #line 366 "backend/vcc.y" {
lexPopMode(0);
popVObject();
} break; case 44: #line 371 "backend/vcc.y" {
lexPushMode(L_VTODO);
if (!pushVObject(VCTodoProp)) YYERROR;
} break; case 45: #line 376 "backend/vcc.y" {
lexPopMode(0);
popVObject();
} break; #line 1521 "y.tab.c" } yyssp -= yym; yystate = *yyssp; yyvsp -= yym; yym = yylhs[yyn]; if (yystate == 0 && yym == 0) { #if YYDEBUG if (yydebug) printf("%sdebug: after reduction, shifting from state 0 to\ state %d\n", YYPREFIX, YYFINAL); #endif yystate = YYFINAL; *++yyssp = YYFINAL; *++yyvsp = yyval; if (yychar < 0) { if ((yychar = yylex()) < 0) yychar = 0; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("%sdebug: state %d, reading %d (%s)\n", YYPREFIX, YYFINAL, yychar, yys); } #endif } if (yychar == 0) goto yyaccept; goto yyloop; } if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yystate) yystate = yytable[yyn]; else yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) printf("%sdebug: after reduction, shifting from state %d \ to state %d\n", YYPREFIX, *yyssp, yystate); #endif if (yyssp >= yyss + yystacksize - 1) { goto yyoverflow; } *++yyssp = yystate; *++yyvsp = yyval; goto yyloop; yyoverflow: yyerror("yacc stack overflow"); yyabort: return (1); yyaccept: return (0); } diff --git a/library/backend/vobject.cpp b/library/backend/vobject.cpp index e6f6b78..dab128e 100644 --- a/library/backend/vobject.cpp +++ b/library/backend/vobject.cpp @@ -1,1315 +1,1315 @@ /*************************************************************************** (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International Business Machines Corporation and Siemens Rolm Communications Inc. For purposes of this license notice, the term Licensors shall mean, collectively, Apple Computer, Inc., AT&T Corp., International Business Machines Corporation and Siemens Rolm Communications Inc. The term Licensor shall mean any of the Licensors. Subject to acceptance of the following conditions, permission is hereby granted by Licensors without the need for written agreement and without license or royalty fees, to use, copy, modify and distribute this software for any purpose. The above copyright notice and the following four paragraphs must be reproduced in all copies of this software and any software including this software. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS. IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. The software is provided with RESTRICTED RIGHTS. Use, duplication, or disclosure by the government are subject to restrictions set forth in DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. ***************************************************************************/ /* * src: vobject.c * doc: vobject and APIs to construct vobject, APIs pretty print * vobject, and convert a vobject into its textual representation. */ #ifndef MWERKS #include <malloc.h> #endif -#include "vobject_p.h" -#include "qfiledirect_p.h" +#include <qtopia/private/vobject_p.h> +#include <qtopia/private/qfiledirect_p.h> #include <string.h> #include <stdio.h> #include <fcntl.h> //#include <io.h> #define NAME_OF(o) o->id #define VALUE_TYPE(o) o->valType #define STRINGZ_VALUE_OF(o) o->val.strs #define INTEGER_VALUE_OF(o) o->val.i #define LONG_VALUE_OF(o) o->val.l #define ANY_VALUE_OF(o) o->val.any #define VOBJECT_VALUE_OF(o) o->val.vobj typedef union ValueItem { const char *strs; unsigned int i; unsigned long l; void *any; VObject *vobj; } ValueItem; struct VObject { VObject *next; const char *id; VObject *prop; unsigned short valType; ValueItem val; }; typedef struct StrItem StrItem; struct StrItem { StrItem *next; const char *s; unsigned int refCnt; }; const char** fieldedProp; /*---------------------------------------------------------------------- The following functions involve with memory allocation: newVObject deleteVObject dupStr deleteStr newStrItem deleteStrItem ----------------------------------------------------------------------*/ DLLEXPORT(VObject*) newVObject_(const char *id) { VObject *p = (VObject*)malloc(sizeof(VObject)); p->next = 0; p->id = id; p->prop = 0; VALUE_TYPE(p) = 0; ANY_VALUE_OF(p) = 0; return p; } DLLEXPORT(VObject*) newVObject(const char *id) { return newVObject_(lookupStr(id)); } DLLEXPORT(void) deleteVObject(VObject *p) { unUseStr(p->id); free(p); } DLLEXPORT(char*) dupStr(const char *s, unsigned int size) { char *t; if (size == 0) { size = strlen(s); } t = (char*)malloc(size+1); if (t) { memcpy(t,s,size); t[size] = 0; return t; } else { return (char*)0; } } DLLEXPORT(void) deleteStr(const char *p) { if (p) free((void*)p); } static StrItem* newStrItem(const char *s, StrItem *next) { StrItem *p = (StrItem*)malloc(sizeof(StrItem)); p->next = next; p->s = s; p->refCnt = 1; return p; } static void deleteStrItem(StrItem *p) { free((void*)p); } /*---------------------------------------------------------------------- The following function provide accesses to VObject's value. ----------------------------------------------------------------------*/ DLLEXPORT(const char*) vObjectName(VObject *o) { return NAME_OF(o); } DLLEXPORT(void) setVObjectName(VObject *o, const char* id) { NAME_OF(o) = id; } DLLEXPORT(const char*) vObjectStringZValue(VObject *o) { return STRINGZ_VALUE_OF(o); } DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s) { STRINGZ_VALUE_OF(o) = dupStr(s,0); VALUE_TYPE(o) = VCVT_STRINGZ; } DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s) { STRINGZ_VALUE_OF(o) = s; VALUE_TYPE(o) = VCVT_STRINGZ; } DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o) { return INTEGER_VALUE_OF(o); } DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i) { INTEGER_VALUE_OF(o) = i; VALUE_TYPE(o) = VCVT_UINT; } DLLEXPORT(unsigned long) vObjectLongValue(VObject *o) { return LONG_VALUE_OF(o); } DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l) { LONG_VALUE_OF(o) = l; VALUE_TYPE(o) = VCVT_ULONG; } DLLEXPORT(void*) vObjectAnyValue(VObject *o) { return ANY_VALUE_OF(o); } DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t) { ANY_VALUE_OF(o) = t; VALUE_TYPE(o) = VCVT_RAW; } DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o) { return VOBJECT_VALUE_OF(o); } DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p) { VOBJECT_VALUE_OF(o) = p; VALUE_TYPE(o) = VCVT_VOBJECT; } DLLEXPORT(int) vObjectValueType(VObject *o) { return VALUE_TYPE(o); } /*---------------------------------------------------------------------- The following functions can be used to build VObject. ----------------------------------------------------------------------*/ DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p) { /* circular link list pointed to tail */ /* o {next,id,prop,val} V pn {next,id,prop,val} V ... p1 {next,id,prop,val} V pn --> o {next,id,prop,val} V pn {next,id,prop,val} V p {next,id,prop,val} ... p1 {next,id,prop,val} V pn */ VObject *tail = o->prop; if (tail) { p->next = tail->next; o->prop = tail->next = p; } else { o->prop = p->next = p; } return p; } DLLEXPORT(VObject*) addProp(VObject *o, const char *id) { return addVObjectProp(o,newVObject(id)); } DLLEXPORT(VObject*) addProp_(VObject *o, const char *id) { return addVObjectProp(o,newVObject_(id)); } DLLEXPORT(void) addList(VObject **o, VObject *p) { p->next = 0; if (*o == 0) { *o = p; } else { VObject *t = *o; while (t->next) { t = t->next; } t->next = p; } } DLLEXPORT(VObject*) nextVObjectInList(VObject *o) { return o->next; } DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size) { VObject *sizeProp; setVObjectAnyValue(prop, val); sizeProp = addProp(prop,VCDataSizeProp); setVObjectLongValue(sizeProp, size); return prop; } DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size) { void *p = dupStr((const char *)val,size); return setValueWithSize_(prop,p,p?size:0); } DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o) { i->start = o->prop; i->next = 0; } DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o) { i->start = o->next; i->next = 0; } DLLEXPORT(int) moreIteration(VObjectIterator *i) { return (i->start && (i->next==0 || i->next!=i->start)); } DLLEXPORT(VObject*) nextVObject(VObjectIterator *i) { if (i->start && i->next != i->start) { if (i->next == 0) { i->next = i->start->next; return i->next; } else { i->next = i->next->next; return i->next; } } else return (VObject*)0; } DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id) { VObjectIterator i; initPropIterator(&i,o); while (moreIteration(&i)) { VObject *each = nextVObject(&i); if (!qstricmp(id,each->id)) return each; } return (VObject*)0; } DLLEXPORT(VObject*) addGroup(VObject *o, const char *g) { /* a.b.c --> prop(c) prop(VCGrouping=b) prop(VCGrouping=a) */ char *dot = strrchr(g,'.'); if (dot) { VObject *p, *t; char *gs, *n = dot+1; gs = dupStr(g,0); /* so we can write to it. */ /* used to be * t = p = addProp_(o,lookupProp_(n)); */ t = p = addProp_(o,lookupProp(n)); dot = strrchr(gs,'.'); *dot = 0; do { dot = strrchr(gs,'.'); if (dot) { n = dot+1; *dot=0; } else n = gs; /* property(VCGroupingProp=n); * and the value may have VCGrouping property */ t = addProp(t,VCGroupingProp); setVObjectStringZValue(t,lookupProp_(n)); } while (n != gs); deleteStr(gs); return p; } else return addProp_(o,lookupProp(g)); } DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v) { VObject *prop; prop = addProp(o,p); setVObjectStringZValue_(prop, strdup( v ) ); return prop; } DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, unsigned int size) { VObject *prop; prop = addProp(o,p); setValueWithSize_(prop, (void*)v, size); return prop; } DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, unsigned int size) { return addPropSizedValue_(o,p,dupStr(v,size),size); } DLLEXPORT(void) cleanVObject(VObject *o) { if (o == 0) return; if (o->prop) { /* destroy time: cannot use the iterator here. Have to break the cycle in the circular link list and turns it into regular NULL-terminated list -- since at some point of destruction, the reference entry for the iterator to work will not longer be valid. */ VObject *p; p = o->prop->next; o->prop->next = 0; do { VObject *t = p->next; cleanVObject(p); p = t; } while (p); } switch (VALUE_TYPE(o)) { case VCVT_STRINGZ: case VCVT_RAW: // assume they are all allocated by malloc. free((char*)STRINGZ_VALUE_OF(o)); break; case VCVT_VOBJECT: cleanVObject(VOBJECT_VALUE_OF(o)); break; } deleteVObject(o); } DLLEXPORT(void) cleanVObjects(VObject *list) { while (list) { VObject *t = list; list = nextVObjectInList(list); cleanVObject(t); } } /*---------------------------------------------------------------------- The following is a String Table Facilities. ----------------------------------------------------------------------*/ #define STRTBLSIZE 255 static StrItem *strTbl[STRTBLSIZE]; static unsigned int hashStr(const char *s) { unsigned int h = 0; int i; for (i=0;s[i];i++) { h += s[i]*i; } return h % STRTBLSIZE; } DLLEXPORT(const char*) lookupStr(const char *s) { StrItem *t; unsigned int h = hashStr(s); if ((t = strTbl[h]) != 0) { do { if (qstricmp(t->s,s) == 0) { t->refCnt++; return t->s; } t = t->next; } while (t); } s = dupStr(s,0); strTbl[h] = newStrItem(s,strTbl[h]); return s; } DLLEXPORT(void) unUseStr(const char *s) { StrItem *t, *p; unsigned int h = hashStr(s); if ((t = strTbl[h]) != 0) { p = t; do { if (qstricmp(t->s,s) == 0) { t->refCnt--; if (t->refCnt == 0) { if (p == strTbl[h]) { strTbl[h] = t->next; } else { p->next = t->next; } deleteStr(t->s); deleteStrItem(t); return; } } p = t; t = t->next; } while (t); } } DLLEXPORT(void) cleanStrTbl() { int i; for (i=0; i<STRTBLSIZE;i++) { StrItem *t = strTbl[i]; while (t) { StrItem *p; deleteStr(t->s); p = t; t = t->next; deleteStrItem(p); } while (t); strTbl[i] = 0; } } struct PreDefProp { const char *name; const char *alias; const char** fields; unsigned int flags; }; /* flags in PreDefProp */ #define PD_BEGIN 0x1 #define PD_INTERNAL 0x2 static const char *adrFields[] = { VCPostalBoxProp, VCExtAddressProp, VCStreetAddressProp, VCCityProp, VCRegionProp, VCPostalCodeProp, VCCountryNameProp, 0 }; static const char *nameFields[] = { VCFamilyNameProp, VCGivenNameProp, VCAdditionalNamesProp, VCNamePrefixesProp, VCNameSuffixesProp, NULL }; static const char *orgFields[] = { VCOrgNameProp, VCOrgUnitProp, VCOrgUnit2Prop, VCOrgUnit3Prop, VCOrgUnit4Prop, NULL }; static const char *AAlarmFields[] = { VCRunTimeProp, VCSnoozeTimeProp, VCRepeatCountProp, VCAudioContentProp, 0 }; /* ExDate -- has unamed fields */ /* RDate -- has unamed fields */ static const char *DAlarmFields[] = { VCRunTimeProp, VCSnoozeTimeProp, VCRepeatCountProp, VCDisplayStringProp, 0 }; static const char *MAlarmFields[] = { VCRunTimeProp, VCSnoozeTimeProp, VCRepeatCountProp, VCEmailAddressProp, VCNoteProp, 0 }; static const char *PAlarmFields[] = { VCRunTimeProp, VCSnoozeTimeProp, VCRepeatCountProp, VCProcedureNameProp, 0 }; static struct PreDefProp propNames[] = { { VC7bitProp, 0, 0, 0 }, { VC8bitProp, 0, 0, 0 }, { VCAAlarmProp, 0, AAlarmFields, 0 }, { VCAdditionalNamesProp, 0, 0, 0 }, { VCAdrProp, 0, adrFields, 0 }, { VCAgentProp, 0, 0, 0 }, { VCAIFFProp, 0, 0, 0 }, { VCAOLProp, 0, 0, 0 }, { VCAppleLinkProp, 0, 0, 0 }, { VCAttachProp, 0, 0, 0 }, { VCAttendeeProp, 0, 0, 0 }, { VCATTMailProp, 0, 0, 0 }, { VCAudioContentProp, 0, 0, 0 }, { VCAVIProp, 0, 0, 0 }, { VCBase64Prop, 0, 0, 0 }, { VCBBSProp, 0, 0, 0 }, { VCBirthDateProp, 0, 0, 0 }, { VCBMPProp, 0, 0, 0 }, { VCBodyProp, 0, 0, 0 }, { VCBusinessRoleProp, 0, 0, 0 }, { VCCalProp, 0, 0, PD_BEGIN }, { VCCaptionProp, 0, 0, 0 }, { VCCardProp, 0, 0, PD_BEGIN }, { VCCarProp, 0, 0, 0 }, { VCCategoriesProp, 0, 0, 0 }, { VCCellularProp, 0, 0, 0 }, { VCCGMProp, 0, 0, 0 }, { VCCharSetProp, 0, 0, 0 }, { VCCIDProp, VCContentIDProp, 0, 0 }, { VCCISProp, 0, 0, 0 }, { VCCityProp, 0, 0, 0 }, { VCClassProp, 0, 0, 0 }, { VCCommentProp, 0, 0, 0 }, { VCCompletedProp, 0, 0, 0 }, { VCContentIDProp, 0, 0, 0 }, { VCCountryNameProp, 0, 0, 0 }, { VCDAlarmProp, 0, DAlarmFields, 0 }, { VCDataSizeProp, 0, 0, PD_INTERNAL }, { VCDayLightProp, 0, 0, 0 }, { VCDCreatedProp, 0, 0, 0 }, { VCDeliveryLabelProp, 0, 0, 0 }, { VCDescriptionProp, 0, 0, 0 }, { VCDIBProp, 0, 0, 0 }, { VCDisplayStringProp, 0, 0, 0 }, { VCDomesticProp, 0, 0, 0 }, { VCDTendProp, 0, 0, 0 }, { VCDTstartProp, 0, 0, 0 }, { VCDueProp, 0, 0, 0 }, { VCEmailAddressProp, 0, 0, 0 }, { VCEncodingProp, 0, 0, 0 }, { VCEndProp, 0, 0, 0 }, { VCEventProp, 0, 0, PD_BEGIN }, { VCEWorldProp, 0, 0, 0 }, { VCExNumProp, 0, 0, 0 }, { VCExpDateProp, 0, 0, 0 }, { VCExpectProp, 0, 0, 0 }, { VCExtAddressProp, 0, 0, 0 }, { VCFamilyNameProp, 0, 0, 0 }, { VCFaxProp, 0, 0, 0 }, { VCFullNameProp, 0, 0, 0 }, { VCGeoLocationProp, 0, 0, 0 }, { VCGeoProp, 0, 0, 0 }, { VCGIFProp, 0, 0, 0 }, { VCGivenNameProp, 0, 0, 0 }, { VCGroupingProp, 0, 0, 0 }, { VCHomeProp, 0, 0, 0 }, { VCIBMMailProp, 0, 0, 0 }, { VCInlineProp, 0, 0, 0 }, { VCInternationalProp, 0, 0, 0 }, { VCInternetProp, 0, 0, 0 }, { VCISDNProp, 0, 0, 0 }, { VCJPEGProp, 0, 0, 0 }, { VCLanguageProp, 0, 0, 0 }, { VCLastModifiedProp, 0, 0, 0 }, { VCLastRevisedProp, 0, 0, 0 }, { VCLocationProp, 0, 0, 0 }, { VCLogoProp, 0, 0, 0 }, { VCMailerProp, 0, 0, 0 }, { VCMAlarmProp, 0, MAlarmFields, 0 }, { VCMCIMailProp, 0, 0, 0 }, { VCMessageProp, 0, 0, 0 }, { VCMETProp, 0, 0, 0 }, { VCModemProp, 0, 0, 0 }, { VCMPEG2Prop, 0, 0, 0 }, { VCMPEGProp, 0, 0, 0 }, { VCMSNProp, 0, 0, 0 }, { VCNamePrefixesProp, 0, 0, 0 }, { VCNameProp, 0, nameFields, 0 }, { VCNameSuffixesProp, 0, 0, 0 }, { VCNoteProp, 0, 0, 0 }, { VCOrgNameProp, 0, 0, 0 }, { VCOrgProp, 0, orgFields, 0 }, { VCOrgUnit2Prop, 0, 0, 0 }, { VCOrgUnit3Prop, 0, 0, 0 }, { VCOrgUnit4Prop, 0, 0, 0 }, { VCOrgUnitProp, 0, 0, 0 }, { VCPagerProp, 0, 0, 0 }, { VCPAlarmProp, 0, PAlarmFields, 0 }, { VCParcelProp, 0, 0, 0 }, { VCPartProp, 0, 0, 0 }, { VCPCMProp, 0, 0, 0 }, { VCPDFProp, 0, 0, 0 }, { VCPGPProp, 0, 0, 0 }, { VCPhotoProp, 0, 0, 0 }, { VCPICTProp, 0, 0, 0 }, { VCPMBProp, 0, 0, 0 }, { VCPostalBoxProp, 0, 0, 0 }, { VCPostalCodeProp, 0, 0, 0 }, { VCPostalProp, 0, 0, 0 }, { VCPowerShareProp, 0, 0, 0 }, { VCPreferredProp, 0, 0, 0 }, { VCPriorityProp, 0, 0, 0 }, { VCProcedureNameProp, 0, 0, 0 }, { VCProdIdProp, 0, 0, 0 }, { VCProdigyProp, 0, 0, 0 }, { VCPronunciationProp, 0, 0, 0 }, { VCPSProp, 0, 0, 0 }, { VCPublicKeyProp, 0, 0, 0 }, { VCQPProp, VCQuotedPrintableProp, 0, 0 }, { VCQuickTimeProp, 0, 0, 0 }, { VCQuotedPrintableProp, 0, 0, 0 }, { VCRDateProp, 0, 0, 0 }, { VCRegionProp, 0, 0, 0 }, { VCRelatedToProp, 0, 0, 0 }, { VCRepeatCountProp, 0, 0, 0 }, { VCResourcesProp, 0, 0, 0 }, { VCRNumProp, 0, 0, 0 }, { VCRoleProp, 0, 0, 0 }, { VCRRuleProp, 0, 0, 0 }, { VCRSVPProp, 0, 0, 0 }, { VCRunTimeProp, 0, 0, 0 }, { VCSequenceProp, 0, 0, 0 }, { VCSnoozeTimeProp, 0, 0, 0 }, { VCStartProp, 0, 0, 0 }, { VCStatusProp, 0, 0, 0 }, { VCStreetAddressProp, 0, 0, 0 }, { VCSubTypeProp, 0, 0, 0 }, { VCSummaryProp, 0, 0, 0 }, { VCTelephoneProp, 0, 0, 0 }, { VCTIFFProp, 0, 0, 0 }, { VCTimeZoneProp, 0, 0, 0 }, { VCTitleProp, 0, 0, 0 }, { VCTLXProp, 0, 0, 0 }, { VCTodoProp, 0, 0, PD_BEGIN }, { VCTranspProp, 0, 0, 0 }, { VCUniqueStringProp, 0, 0, 0 }, { VCURLProp, 0, 0, 0 }, { VCURLValueProp, 0, 0, 0 }, { VCValueProp, 0, 0, 0 }, { VCVersionProp, 0, 0, 0 }, { VCVideoProp, 0, 0, 0 }, { VCVoiceProp, 0, 0, 0 }, { VCWAVEProp, 0, 0, 0 }, { VCWMFProp, 0, 0, 0 }, { VCWorkProp, 0, 0, 0 }, { VCX400Prop, 0, 0, 0 }, { VCX509Prop, 0, 0, 0 }, { VCXRuleProp, 0, 0, 0 }, { 0,0,0,0 } }; static struct PreDefProp* lookupPropInfo(const char* str) { /* brute force for now, could use a hash table here. */ int i; for (i = 0; propNames[i].name; i++) if (qstricmp(str, propNames[i].name) == 0) { return &propNames[i]; } return 0; } DLLEXPORT(const char*) lookupProp_(const char* str) { int i; for (i = 0; propNames[i].name; i++) if (qstricmp(str, propNames[i].name) == 0) { const char* s; s = propNames[i].alias?propNames[i].alias:propNames[i].name; return lookupStr(s); } return lookupStr(str); } DLLEXPORT(const char*) lookupProp(const char* str) { int i; for (i = 0; propNames[i].name; i++) if (qstricmp(str, propNames[i].name) == 0) { const char *s; fieldedProp = propNames[i].fields; s = propNames[i].alias?propNames[i].alias:propNames[i].name; return lookupStr(s); } fieldedProp = 0; return lookupStr(str); } /*---------------------------------------------------------------------- APIs to Output text form. ----------------------------------------------------------------------*/ #define OFILE_REALLOC_SIZE 256 typedef struct OFile { FILE *fp; char *s; int len; int limit; int alloc:1; int fail:1; } OFile; #if 0 static void appendsOFile(OFile *fp, const char *s) { int slen; if (fp->fail) return; slen = strlen(s); if (fp->fp) { fwrite(s,1,slen,fp->fp); } else { stuff: if (fp->len + slen < fp->limit) { memcpy(fp->s+fp->len,s,slen); fp->len += slen; return; } else if (fp->alloc) { fp->limit = fp->limit + OFILE_REALLOC_SIZE; if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen; fp->s = (char *) realloc(fp->s,fp->limit); if (fp->s) goto stuff; } if (fp->alloc) free(fp->s); fp->s = 0; fp->fail = 1; } } static void appendcOFile(OFile *fp, char c) { if (fp->fail) return; if (fp->fp) { fputc(c,fp->fp); } else { stuff: if (fp->len+1 < fp->limit) { fp->s[fp->len] = c; fp->len++; return; } else if (fp->alloc) { fp->limit = fp->limit + OFILE_REALLOC_SIZE; fp->s = (char *) realloc(fp->s,fp->limit); if (fp->s) goto stuff; } if (fp->alloc) free(fp->s); fp->s = 0; fp->fail = 1; } } #else static void appendcOFile_(OFile *fp, char c) { if (fp->fail) return; if (fp->fp) { fputc(c,fp->fp); } else { stuff: if (fp->len+1 < fp->limit) { fp->s[fp->len] = c; fp->len++; return; } else if (fp->alloc) { fp->limit = fp->limit + OFILE_REALLOC_SIZE; fp->s = (char *)realloc(fp->s,fp->limit); if (fp->s) goto stuff; } if (fp->alloc) free(fp->s); fp->s = 0; fp->fail = 1; } } static void appendcOFile(OFile *fp, char c) { if (c == '\n') { /* write out as <CR><LF> */ appendcOFile_(fp,0xd); appendcOFile_(fp,0xa); } else appendcOFile_(fp,c); } static void appendsOFile(OFile *fp, const char *s) { int i, slen; slen = strlen(s); for (i=0; i<slen; i++) { appendcOFile(fp,s[i]); } } #endif static void initOFile(OFile *fp, FILE *ofp) { fp->fp = ofp; fp->s = 0; fp->len = 0; fp->limit = 0; fp->alloc = 0; fp->fail = 0; } static int writeBase64(OFile *fp, unsigned char *s, long len) { long cur = 0; int i, numQuads = 0; unsigned long trip; unsigned char b; char quad[5]; #define MAXQUADS 16 quad[4] = 0; while (cur < len) { // collect the triplet of bytes into 'trip' trip = 0; for (i = 0; i < 3; i++) { b = (cur < len) ? *(s + cur) : 0; cur++; trip = trip << 8 | b; } // fill in 'quad' with the appropriate four characters for (i = 3; i >= 0; i--) { b = (unsigned char)(trip & 0x3F); trip = trip >> 6; if ((3 - i) < (cur - len)) quad[i] = '='; // pad char else if (b < 26) quad[i] = (char)b + 'A'; else if (b < 52) quad[i] = (char)(b - 26) + 'a'; else if (b < 62) quad[i] = (char)(b - 52) + '0'; else if (b == 62) quad[i] = '+'; else quad[i] = '/'; } // now output 'quad' with appropriate whitespace and line ending appendsOFile(fp, (numQuads == 0 ? " " : "")); appendsOFile(fp, quad); appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : ""))); numQuads = (numQuads + 1) % MAXQUADS; } appendcOFile(fp,'\n'); return 1; } static const char *replaceChar(unsigned char c) { if (c == '\n') { return "=0A=\n"; } else if ( (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c >= '\'' && c <= ')') || (c >= '+' && c <= '-') || (c == '/') || (c == '?') || (c == ' ')) { return 0; } static char trans[4]; trans[0] = '='; trans[3] = '\0'; int rem = c % 16; int div = c / 16; if (div < 10) trans[1] = '0' + div; else trans[1] = 'A' + (div - 10); if (rem < 10) trans[2] = '0' + rem; else trans[2] = 'A' + (rem - 10); return trans; } static void writeQPString(OFile *fp, const char *s) { /* only A-Z, 0-9 and "'" (ASCII code 39) "(" (ASCII code 40) ")" (ASCII code 41) "+" (ASCII code 43) "," (ASCII code 44) "-" (ASCII code 45) "/" (ASCII code 47) "?" (ASCII code 63) should remain un-encoded. '=' needs to be encoded as it is the escape character. ';' needs to be as it is a field separator. */ const char *p = s; while (*p) { const char *rep = replaceChar(*p); if (rep) appendsOFile(fp, rep); else appendcOFile(fp, *p); p++; } } static bool includesUnprintable(VObject *o) { if (o) { if (VALUE_TYPE(o) == VCVT_STRINGZ) { const char *p = STRINGZ_VALUE_OF(o); if (p) { while (*p) { if (replaceChar(*p)) return TRUE; p++; } } } } return FALSE; } static void writeVObject_(OFile *fp, VObject *o); static void writeValue(OFile *fp, VObject *o, unsigned long size) { if (o == 0) return; switch (VALUE_TYPE(o)) { case VCVT_STRINGZ: { writeQPString(fp, STRINGZ_VALUE_OF(o)); break; } case VCVT_UINT: { char buf[16]; sprintf(buf,"%u", INTEGER_VALUE_OF(o)); appendsOFile(fp,buf); break; } case VCVT_ULONG: { char buf[16]; sprintf(buf,"%lu", LONG_VALUE_OF(o)); appendsOFile(fp,buf); break; } case VCVT_RAW: { appendcOFile(fp,'\n'); writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size); break; } case VCVT_VOBJECT: appendcOFile(fp,'\n'); writeVObject_(fp,VOBJECT_VALUE_OF(o)); break; } } static void writeAttrValue(OFile *fp, VObject *o) { if (NAME_OF(o)) { struct PreDefProp *pi; pi = lookupPropInfo(NAME_OF(o)); if (pi && ((pi->flags & PD_INTERNAL) != 0)) return; if ( includesUnprintable(o) ) { appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8"); } appendcOFile(fp,';'); appendsOFile(fp,NAME_OF(o)); } else appendcOFile(fp,';'); if (VALUE_TYPE(o)) { appendcOFile(fp,'='); writeValue(fp,o,0); } } static void writeGroup(OFile *fp, VObject *o) { char buf1[256]; char buf2[256]; strcpy(buf1,NAME_OF(o)); while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) { strcpy(buf2,STRINGZ_VALUE_OF(o)); strcat(buf2,"."); strcat(buf2,buf1); strcpy(buf1,buf2); } appendsOFile(fp,buf1); } static int inList(const char **list, const char *s) { if (list == 0) return 0; while (*list) { if (qstricmp(*list,s) == 0) return 1; list++; } return 0; } static void writeProp(OFile *fp, VObject *o) { if (NAME_OF(o)) { struct PreDefProp *pi; VObjectIterator t; const char **fields_ = 0; pi = lookupPropInfo(NAME_OF(o)); if (pi && ((pi->flags & PD_BEGIN) != 0)) { writeVObject_(fp,o); return; } if (isAPropertyOf(o,VCGroupingProp)) writeGroup(fp,o); else appendsOFile(fp,NAME_OF(o)); if (pi) fields_ = pi->fields; initPropIterator(&t,o); while (moreIteration(&t)) { const char *s; VObject *eachProp = nextVObject(&t); s = NAME_OF(eachProp); if (qstricmp(VCGroupingProp,s) && !inList(fields_,s)) writeAttrValue(fp,eachProp); } if (fields_) { int i = 0, n = 0; const char** fields = fields_; /* output prop as fields */ bool printable = TRUE; while (*fields && printable) { VObject *t = isAPropertyOf(o,*fields); if (includesUnprintable(t)) printable = FALSE; fields++; } fields = fields_; if (!printable) { appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8"); } appendcOFile(fp,':'); while (*fields) { VObject *t = isAPropertyOf(o,*fields); i++; if (t) n = i; fields++; } fields = fields_; for (i=0;i<n;i++) { writeValue(fp,isAPropertyOf(o,*fields),0); fields++; if (i<(n-1)) appendcOFile(fp,';'); } } } if (VALUE_TYPE(o)) { if ( includesUnprintable(o) ) { appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8"); } unsigned long size = 0; VObject *p = isAPropertyOf(o,VCDataSizeProp); if (p) size = LONG_VALUE_OF(p); appendcOFile(fp,':'); writeValue(fp,o,size); } appendcOFile(fp,'\n'); } static void writeVObject_(OFile *fp, VObject *o) { if (NAME_OF(o)) { struct PreDefProp *pi; pi = lookupPropInfo(NAME_OF(o)); if (pi && ((pi->flags & PD_BEGIN) != 0)) { VObjectIterator t; const char *begin = NAME_OF(o); appendsOFile(fp,"BEGIN:"); appendsOFile(fp,begin); appendcOFile(fp,'\n'); initPropIterator(&t,o); while (moreIteration(&t)) { VObject *eachProp = nextVObject(&t); writeProp(fp, eachProp); } appendsOFile(fp,"END:"); appendsOFile(fp,begin); appendsOFile(fp,"\n\n"); } } } void writeVObject(FILE *fp, VObject *o) { OFile ofp; // ##### //_setmode(_fileno(fp), _O_BINARY); initOFile(&ofp,fp); writeVObject_(&ofp,o); } DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o) { QFileDirect f( fname); if ( !f.open( IO_WriteOnly ) ) { qWarning("Unable to open vobject write %s", fname); return; } writeVObject( f.directHandle(),o ); } DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list) { QFileDirect f( fname); if ( !f.open( IO_WriteOnly ) ) { qWarning("Unable to open vobject write %s", fname); return; } while (list) { writeVObject(f.directHandle(),list); list = nextVObjectInList(list); } } DLLEXPORT(const char *) vObjectTypeInfo(VObject *o) { const char *type = vObjectName( o ); if ( strcmp( type, "TYPE" ) == 0 ) type = vObjectStringZValue( o ); return type; } // end of source file vobject.c diff --git a/library/datebookmonth.cpp b/library/datebookmonth.cpp index 272c223..4a9dcbd 100644 --- a/library/datebookmonth.cpp +++ b/library/datebookmonth.cpp @@ -1,750 +1,750 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "config.h" #include "datebookmonth.h" #include "datebookdb.h" #include <qtopia/private/event.h> #include "resource.h" -#include "qpeapplication.h" +#include <qpe/qpeapplication.h> #include "timestring.h" #include <qtoolbutton.h> #include <qspinbox.h> #include <qcombobox.h> #include <qdatetime.h> #include <qpainter.h> #include <qpopupmenu.h> #include <qvaluestack.h> #include <qwhatsthis.h> DateBookMonthHeader::DateBookMonthHeader( QWidget *parent, const char *name ) : QHBox( parent, name ) { setBackgroundMode( PaletteButton ); begin = new QToolButton( this ); begin->setFocusPolicy(NoFocus); begin->setPixmap( Resource::loadPixmap( "start" ) ); begin->setAutoRaise( TRUE ); begin->setFixedSize( begin->sizeHint() ); QWhatsThis::add( begin, tr("Show January in the selected year") ); back = new QToolButton( this ); back->setFocusPolicy(NoFocus); back->setPixmap( Resource::loadPixmap( "back" ) ); back->setAutoRaise( TRUE ); back->setFixedSize( back->sizeHint() ); QWhatsThis::add( back, tr("Show the previous month") ); month = new QComboBox( FALSE, this ); for ( int i = 0; i < 12; ++i ) month->insertItem( Calendar::nameOfMonth( i + 1 ) ); year = new QSpinBox( 1752, 8000, 1, this ); next = new QToolButton( this ); next->setFocusPolicy(NoFocus); next->setPixmap( Resource::loadPixmap( "forward" ) ); next->setAutoRaise( TRUE ); next->setFixedSize( next->sizeHint() ); QWhatsThis::add( next, tr("Show the next month") ); end = new QToolButton( this ); end->setFocusPolicy(NoFocus); end->setPixmap( Resource::loadPixmap( "finish" ) ); end->setAutoRaise( TRUE ); end->setFixedSize( end->sizeHint() ); QWhatsThis::add( end, tr("Show December in the selected year") ); connect( month, SIGNAL( activated( int ) ), this, SLOT( updateDate() ) ); connect( year, SIGNAL( valueChanged( int ) ), this, SLOT( updateDate() ) ); connect( begin, SIGNAL( clicked() ), this, SLOT( firstMonth() ) ); connect( end, SIGNAL( clicked() ), this, SLOT( lastMonth() ) ); connect( back, SIGNAL( clicked() ), this, SLOT( monthBack() ) ); connect( next, SIGNAL( clicked() ), this, SLOT( monthForward() ) ); back->setAutoRepeat( TRUE ); next->setAutoRepeat( TRUE ); } DateBookMonthHeader::~DateBookMonthHeader() { } void DateBookMonthHeader::updateDate() { emit dateChanged( year->value(), month->currentItem() + 1 ); } void DateBookMonthHeader::firstMonth() { emit dateChanged( year->value(), 1 ); month->setCurrentItem( 0 ); } void DateBookMonthHeader::lastMonth() { emit dateChanged( year->value(), 12 ); month->setCurrentItem( 11 ); } void DateBookMonthHeader::monthBack() { if ( month->currentItem() > 0 ) { emit dateChanged( year->value(), month->currentItem() ); month->setCurrentItem( month->currentItem() - 1 ); } else { emit dateChanged( year->value() - 1, 12 ); // we have a signal set to a changed value in year so we only need to change // year to get the result... month->setCurrentItem( 11 ); year->setValue( year->value() - 1 ); } } void DateBookMonthHeader::monthForward() { if ( month->currentItem() < 11 ) { emit dateChanged( year->value(), month->currentItem() + 2 ); month->setCurrentItem( month->currentItem() + 1 ); } else { // we have a signal set to a changed value in year so we only need to change // year to get the result... month->setCurrentItem( 0 ); year->setValue( year->value() + 1 ); } } void DateBookMonthHeader::setDate( int y, int m ) { year->setValue( y ); month->setCurrentItem( m - 1 ); } //--------------------------------------------------------------------------- class DateBookMonthTablePrivate { public: DateBookMonthTablePrivate() {}; ~DateBookMonthTablePrivate() { mMonthEvents.clear(); }; QValueList<EffectiveEvent> mMonthEvents; bool onMonday; }; DateBookMonthTable::DateBookMonthTable( QWidget *parent, const char *name, DateBookDB *newDb ) : QTable( 6, 7, parent, name ), db( newDb ) { d = new DateBookMonthTablePrivate(); selYear = -1; selMonth = -1; selDay = -1; Config cfg( "qpe" ); cfg.setGroup( "Time" ); d->onMonday = cfg.readBoolEntry( "MONDAY" ); horizontalHeader()->setResizeEnabled( FALSE ); // we have to do this here... or suffer the consequences later... for ( int i = 0; i < 7; i++ ){ horizontalHeader()->resizeSection( i, 30 ); setColumnStretchable( i, TRUE ); } setupLabels(); verticalHeader()->hide(); setLeftMargin( 0 ); for ( int i = 0; i < 6; ++i ) setRowStretchable( i, TRUE ); setSelectionMode( NoSelection ); connect( this, SIGNAL( clicked( int, int, int, const QPoint & ) ), this, SLOT( dayClicked( int, int ) ) ); connect( this, SIGNAL( currentChanged( int, int ) ), this, SLOT( dragDay( int, int ) ) ); setVScrollBarMode( AlwaysOff ); setHScrollBarMode( AlwaysOff ); } DateBookMonthTable::~DateBookMonthTable() { monthsEvents.clear(); delete d; } void DateBookMonthTable::setDate(int y, int m, int d) { if (month == m && year == y) { if ( selYear == -1 ) year = selYear; if ( selMonth == -1 ) month = selMonth; int r1, c1, r2, c2; findDay(selDay, r1, c1); selDay = day = d; findDay(selDay, r2, c2); setCurrentCell( r2, c2 ); //updateCell(r1,c1); //updateCell(r2,c2); } else { selYear = year = y; selMonth = month = m; selDay = day = d; setupTable(); } } void DateBookMonthTable::redraw() { setupLabels(); setupTable(); } void DateBookMonthTable::setWeekStart( bool onMonday ) { d->onMonday = onMonday; setupLabels(); setupTable(); } void DateBookMonthTable::setupTable() { QValueList<Calendar::Day> days = Calendar::daysOfMonth( year, month, d->onMonday ); QValueList<Calendar::Day>::Iterator it = days.begin(); int row = 0, col = 0; int crow = 0; int ccol = 0; for ( ; it != days.end(); ++it ) { DayItemMonth *i = (DayItemMonth *)item( row, col ); if ( !i ) { i = new DayItemMonth( this, QTableItem::Never, "" ); setItem( row, col, i ); } Calendar::Day calDay = *it; i->clearEffEvents(); i->setDay( calDay.date ); i->setType( calDay.type ); if ( i->day() == day && calDay.type == Calendar::Day::ThisMonth ) { crow = row; ccol = col; } updateCell( row, col ); if ( col == 6 ) { ++row; col = 0; } else { ++col; } } setCurrentCell( crow, ccol ); getEvents(); } void DateBookMonthTable::findDay( int day, int &row, int &col ) { QDate dtBegin( year, month, 1 ); int skips = dtBegin.dayOfWeek(); int effective_day = day + skips - 1; // row/columns begin at 0 // make an extra adjustment if we start on Mondays. if ( d->onMonday ) effective_day--; row = effective_day / 7; col = effective_day % 7; } void DateBookMonthTable::dayClicked( int row, int col ) { changeDaySelection( row, col ); emit dateClicked( selYear, selMonth, selDay ); } void DateBookMonthTable::dragDay( int row, int col ) { changeDaySelection( row, col ); } void DateBookMonthTable::changeDaySelection( int row, int col ) { DayItemMonth *i = (DayItemMonth*)item( row, col ); if ( !i ) return; switch ( i->type() ) { case Calendar::Day::ThisMonth: selMonth = month; break; case Calendar::Day::PrevMonth: selMonth = month-1; break; default: selMonth = month+1; } selYear = year; if ( selMonth <= 0 ) { selMonth = 12; selYear--; } else if ( selMonth > 12 ) { selMonth = 1; selYear++; } selDay = i->day(); } void DateBookMonthTable::viewportMouseReleaseEvent( QMouseEvent * ) { dayClicked( currentRow(), currentColumn() ); } void DateBookMonthTable::getEvents() { if ( !db ) return; QDate dtStart( year, month, 1 ); d->mMonthEvents = db->getEffectiveEvents( dtStart, QDate( year, month, dtStart.daysInMonth() ) ); QValueListIterator<EffectiveEvent> it = d->mMonthEvents.begin(); // now that the events are sorted, basically go through the list, make // a small list for every day and set it for each item... // clear all the items... while ( it != d->mMonthEvents.end() ) { QValueList<EffectiveEvent> dayEvent; EffectiveEvent e = *it; ++it; dayEvent.append( e ); while ( it != d->mMonthEvents.end() && e.date() == (*it).date() ) { dayEvent.append( *it ); ++it; } int row, col; findDay( e.date().day(), row, col ); DayItemMonth* w = static_cast<DayItemMonth*>( item( row, col ) ); w->setEvents( dayEvent ); updateCell( row, col ); dayEvent.clear(); } } void DateBookMonthTable::setupLabels() { for ( int i = 0; i < 7; ++i ) { // horizontalHeader()->resizeSection( i, 30 ); // setColumnStretchable( i, TRUE ); if ( d->onMonday ) horizontalHeader()->setLabel( i, Calendar::nameOfDay( i + 1 ) ); else { if ( i == 0 ) horizontalHeader()->setLabel( i, Calendar::nameOfDay( 7 ) ); else horizontalHeader()->setLabel( i, Calendar::nameOfDay( i ) ); } } } //--------------------------------------------------------------------------- DateBookMonth::DateBookMonth( QWidget *parent, const char *name, bool ac, DateBookDB *data ) : QVBox( parent, name ), autoClose( ac ) { setFocusPolicy(StrongFocus); year = QDate::currentDate().year(); month = QDate::currentDate().month(); day = QDate::currentDate().day(); header = new DateBookMonthHeader( this, "DateBookMonthHeader" ); table = new DateBookMonthTable( this, "DateBookMonthTable", data ); header->setDate( year, month ); table->setDate( year, month, QDate::currentDate().day() ); header->setFocusPolicy(NoFocus); table->setFocusPolicy(NoFocus); connect( header, SIGNAL( dateChanged( int, int ) ), this, SLOT( setDate( int, int ) ) ); connect( table, SIGNAL( dateClicked( int, int, int ) ), this, SLOT( finalDate(int, int, int) ) ); connect( qApp, SIGNAL(weekChanged(bool)), this, SLOT(slotWeekChange(bool)) ); table->setFocus(); } DateBookMonth::~DateBookMonth() { } void DateBookMonth::setDate( int y, int m ) { /* only change the date if this is a different date, * other wise we may mistakenly overide the day */ if ( (y != year) || (m != month) ) { year = y; month = m; QDate nd( y, m, 1 ); if ( nd.daysInMonth() < day ) day = nd.daysInMonth(); table->setDate( year, month, day ); } } void DateBookMonth::setDate( int y, int m, int d ) { header->setDate( y, m); table->setDate( y, m, d); year = y; month = m; day = d; } /* called when we wish to close or pass back the date */ void DateBookMonth::finalDate(int y, int m, int d) { setDate( y, m, d ); emit dateClicked(y, m, d); // emit dateClicked(QDate(y, m, d).toString()); if ( autoClose && parentWidget() ) parentWidget()->close(); } void DateBookMonth::setDate( QDate d) { setDate(d.year(), d.month(), d.day()); } void DateBookMonth::redraw() { table->setDate( year, month, day ); table->redraw(); } QDate DateBookMonth::selectedDate() const { if ( !table ) return QDate::currentDate(); int y, m, d; table->getDate( y, m, d ); return QDate( y, m, d ); } void DateBookMonth::slotWeekChange( bool startOnMonday ) { table->setWeekStart( startOnMonday ); } void DateBookMonth::keyPressEvent( QKeyEvent *e ) { switch(e->key()) { case Key_Up: setDate(QDate(year, month, day).addDays(-7)); break; case Key_Down: setDate(QDate(year, month, day).addDays(7)); break; case Key_Left: setDate(QDate(year, month, day).addDays(-1)); break; case Key_Right: setDate(QDate(year, month, day).addDays(1)); break; case Key_Space: qWarning("space"); emit dateClicked(year, month, day); if ( autoClose && parentWidget() ) parentWidget()->close(); break; default: qWarning("ignore"); e->ignore(); break; } } //--------------------------------------------------------------------------- class DayItemMonthPrivate { public: DayItemMonthPrivate() {}; ~DayItemMonthPrivate() { mDayEvents.clear(); }; QValueList<EffectiveEvent> mDayEvents; }; DayItemMonth::DayItemMonth( QTable *table, EditType et, const QString &t ) : QTableItem( table, et, t ) { d = new DayItemMonthPrivate(); } DayItemMonth::~DayItemMonth() { daysEvents.clear(); delete d; } void DayItemMonth::setEvents( const QValueList<EffectiveEvent> &effEv ) { d->mDayEvents = effEv; } void DayItemMonth::clearEffEvents() { d->mDayEvents.clear(); } void DayItemMonth::paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected ) { p->save(); QColorGroup g( cg ); g.setBrush( QColorGroup::Base, back ); g.setColor( QColorGroup::Text, forg ); if ( selected ) p->setPen( g.highlightedText() ); else p->setPen( g.text() ); QValueStack<int> normalLine; QValueStack<int> repeatLine; QValueStack<int> travelLine; bool normalAllDay = FALSE; bool repeatAllDay = FALSE; bool travelAllDay = FALSE; QValueListIterator<EffectiveEvent> itDays = d->mDayEvents.begin(); for ( ; itDays != d->mDayEvents.end(); ++itDays ) { int w = cr.width(); Event ev = (*itDays).event(); int f = (*itDays).start().hour(); // assume Effective event int t = (*itDays).end().hour(); // is truncated. if (ev.isAllDay()) { if (!ev.hasRepeat()) normalAllDay = TRUE; else repeatAllDay = TRUE; } else { int sLine, eLine; if (f == 0) sLine = 0; else if (f < 8 ) sLine = 1; else if (f >= 17) sLine = w - 4; else { sLine = (f - 8) * (w - 8); if (sLine) sLine /= 8; sLine += 4; } if (t == 23) eLine = w; else if (t < 8) eLine = 4; else if (t >= 17) eLine = w - 1; else { eLine = (t - 8) * (w - 8); if (eLine) eLine /= 8; eLine += 4; } if (!ev.hasRepeat()) { normalLine.push(sLine); normalLine.push(eLine); } else { repeatLine.push(sLine); repeatLine.push(eLine); } } } // draw the background if (normalAllDay || repeatAllDay || travelAllDay) { p->save(); if (normalAllDay) if (repeatAllDay) { p->fillRect( 0, 0, cr.width(), cr.height() / 2, colorNormalLight ); p->fillRect( 0, cr.height() / 2, cr.width(), cr.height() / 2, colorRepeatLight ); } else p->fillRect( 0, 0, cr.width(), cr.height(), colorNormalLight ); else if (repeatAllDay) p->fillRect( 0, 0, cr.width(), cr.height(), colorRepeatLight ); } else { p->fillRect( 0, 0, cr.width(), cr.height(), selected ? g.brush( QColorGroup::Highlight ) : g.brush( QColorGroup::Base ) ); } // The lines // now for the lines. int h = 5; int y = cr.height() / 2 - h; while(normalLine.count() >= 2) { int x2 = normalLine.pop(); int x1 = normalLine.pop(); if (x2 < x1 + 2) x2 = x1 + 2; p->fillRect(x1, y, x2 - x1, h, colorNormal); } y += h; while(repeatLine.count() >= 2) { int x2 = repeatLine.pop(); int x1 = repeatLine.pop(); if (x2 < x1 + 2) x2 = x1 + 2; p->fillRect(x1, y, x2 - x1, h, colorRepeat); } // Finally, draw the number. QFont f = p->font(); f.setPointSize( ( f.pointSize() / 3 ) * 2 ); p->setFont( f ); QFontMetrics fm( f ); p->drawText( 1, 1 + fm.ascent(), QString::number( day() ) ); p->restore(); } void DayItemMonth::setType( Calendar::Day::Type t ) { switch ( t ) { case Calendar::Day::PrevMonth: case Calendar::Day::NextMonth: back = QBrush( QColor( 224, 224, 224 ) ); forg = black; break; case Calendar::Day::ThisMonth: back = QBrush( white ); forg = black; break; } typ = t; } DateButton::DateButton( bool longDate, QWidget *parent, const char * name ) :QPushButton( parent, name ) { longFormat = longDate; df = DateFormat('/', DateFormat::MonthDayYear, DateFormat::MonthDayYear); setDate( QDate::currentDate() ); connect(this,SIGNAL(pressed()),this,SLOT(pickDate())); } void DateButton::pickDate() { static QPopupMenu *m1 = 0; static DateBookMonth *picker = 0; if ( !m1 ) { m1 = new QPopupMenu( this ); picker = new DateBookMonth( m1, 0, TRUE ); m1->insertItem( picker ); connect( picker, SIGNAL( dateClicked( int, int, int ) ), this, SLOT( setDate( int, int, int ) ) ); connect( picker, SIGNAL( dateClicked( int, int, int ) ), this, SIGNAL( dateSelected( int, int, int ) ) ); connect( m1, SIGNAL( aboutToHide() ), this, SLOT( gotHide() ) ); } picker->slotWeekChange( weekStartsMonday ); picker->setDate( currDate.year(), currDate.month(), currDate.day() ); m1->popup(mapToGlobal(QPoint(0,height()))); picker->setFocus(); } void DateButton::gotHide() { // we have to redo the button... setDown( false ); } // void dateSelected( int year, int month, int day ); void DateButton::setWeekStartsMonday( int b ) { weekStartsMonday = b; } void DateButton::setDate( int y, int m, int d ) { setDate( QDate( y,m,d) ); } void DateButton::setDate( QDate d ) { currDate = d; setText( longFormat ? TimeString::longDateString( d, df ) : TimeString::shortDate( d, df ) ); } void DateButton::setDateFormat( DateFormat f ) { df = f; setDate( currDate ); } bool DateButton::customWhatsThis() const { return TRUE; } diff --git a/library/fileselector.cpp b/library/fileselector.cpp index 7ff09b4..052a29e 100644 --- a/library/fileselector.cpp +++ b/library/fileselector.cpp @@ -1,583 +1,583 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ // WARNING: Do *NOT* define this yourself. The SL5xxx from SHARP does NOT // have this class. #define QTOPIA_INTERNAL_FSLP #include "fileselector.h" #include "fileselector_p.h" #include "global.h" #include "resource.h" #include "config.h" #include "applnk.h" #include "storage.h" #include "qpemenubar.h" #ifdef QWS -#include "qcopchannel_qws.h" +#include <qcopchannel_qws.h> #endif #include "lnkproperties.h" #include "applnk.h" -#include "qpeapplication.h" +#include <qpe/qpeapplication.h> #include "categorymenu.h" #include "categoryselect.h" #include "mimetype.h" -#include "categories.h" +#include <qpe/categories.h> #include <stdlib.h> #include <qdir.h> #include <qwidget.h> #include <qpopupmenu.h> #include <qtoolbutton.h> #include <qpushbutton.h> #include <qheader.h> #include <qtooltip.h> #include <qwhatsthis.h> class TypeCombo : public QComboBox { Q_OBJECT public: TypeCombo( QWidget *parent, const char *name=0 ) : QComboBox( parent, name ) { connect( this, SIGNAL(activated(int)), this, SLOT(selectType(int)) ); } void reread( DocLnkSet &files, const QString &filter ); signals: void selected( const QString & ); protected slots: void selectType( int idx ) { emit selected( typelist[idx] ); } protected: QStringList typelist; QString prev; }; void TypeCombo::reread( DocLnkSet &files, const QString &filter ) { typelist.clear(); QStringList filters = QStringList::split( ';', filter ); int pos = filter.find( '/' ); //### do for each filter if ( filters.count() == 1 && pos >= 0 && filter[pos+1] != '*' ) { typelist.append( filter ); clear(); QString minor = filter.mid( pos+1 ); minor[0] = minor[0].upper(); insertItem( tr("%1 files").arg(minor) ); setCurrentItem(0); setEnabled( FALSE ); return; } QListIterator<DocLnk> dit( files.children() ); for ( ; dit.current(); ++dit ) { if ( !typelist.contains( (*dit)->type() ) ) typelist.append( (*dit)->type() ); } QStringList types; QStringList::ConstIterator it; for (it = typelist.begin(); it!=typelist.end(); ++it) { QString t = *it; if ( t.left(12) == "application/" ) { MimeType mt(t); const AppLnk* app = mt.application(); if ( app ) t = app->name(); else t = t.mid(12); } else { QString major, minor; int pos = t.find( '/' ); if ( pos >= 0 ) { major = t.left( pos ); minor = t.mid( pos+1 ); } if ( minor.find( "x-" ) == 0 ) minor = minor.mid( 2 ); minor[0] = minor[0].upper(); major[0] = major[0].upper(); if ( filters.count() > 1 ) t = tr("%1 %2", "minor mimetype / major mimetype").arg(minor).arg(major); else t = minor; } types += tr("%1 files").arg(t); } for (it = filters.begin(); it!=filters.end(); ++it) { typelist.append( *it ); int pos = (*it).find( '/' ); if ( pos >= 0 ) { QString maj = (*it).left( pos ); maj[0] = maj[0].upper(); types << tr("All %1 files").arg(maj); } } if ( filters.count() > 1 ) { typelist.append( filter ); types << tr("All files"); } prev = currentText(); clear(); insertStringList(types); for (int i=0; i<count(); i++) { if ( text(i) == prev ) { setCurrentItem(i); break; } } if ( prev.isNull() ) setCurrentItem(count()-1); setEnabled( TRUE ); } //=========================================================================== FileSelectorItem::FileSelectorItem( QListView *parent, const DocLnk &f ) : QListViewItem( parent ), fl( f ) { setText( 0, f.name() ); setPixmap( 0, f.pixmap() ); } FileSelectorItem::~FileSelectorItem() { } FileSelectorView::FileSelectorView( QWidget *parent, const char *name ) : QListView( parent, name ) { setAllColumnsShowFocus( TRUE ); addColumn( tr( "Name" ) ); header()->hide(); } FileSelectorView::~FileSelectorView() { } void FileSelectorView::keyPressEvent( QKeyEvent *e ) { QString txt = e->text(); if (e->key() == Key_Space) emit returnPressed( currentItem() ); else if ( !txt.isNull() && txt[0] > ' ' && e->key() < 0x1000 ) e->ignore(); else QListView::keyPressEvent(e); } class NewDocItem : public FileSelectorItem { public: NewDocItem( QListView *parent, const DocLnk &f ) : FileSelectorItem( parent, f ) { setText( 0, QObject::tr("New Document") ); QImage img( Resource::loadImage( "new" ) ); QPixmap pm; pm = img.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() ); setPixmap( 0, pm ); } QString key ( int, bool ) const { return QString("\n"); } void paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int alignment ) { QFont oldFont = p->font(); QFont newFont = p->font(); newFont.setWeight( QFont::Bold ); p->setFont( newFont ); FileSelectorItem::paintCell( p, cg, column, width, alignment ); p->setFont( oldFont ); } int width( const QFontMetrics &fm, const QListView *v, int c ) const { return FileSelectorItem::width( fm, v, c )*4/3; // allow for bold font } }; //=========================================================================== class FileSelectorPrivate { public: TypeCombo *typeCombo; CategorySelect *catSelect; QValueList<QRegExp> mimeFilters; int catId; bool showNew; NewDocItem *newDocItem; DocLnkSet files; QHBox *toolbar; }; /*! \class FileSelector fileselector.h \brief The FileSelector widget allows the user to select DocLnk objects. This class presents a file selection dialog to the user. This widget is usually the first widget seen in a \link docwidget.html document-oriented application\endlink. The developer will most often create this widget in combination with a <a href="../qt/qwidgetstack.html"> QWidgetStack</a> and the appropriate editor and/or viewer widget for their application. This widget should be shown first and the user can the select which document they wish to operate on. Please refer to the implementation of texteditor for an example of how to tie these classes together. Use setNewVisible() depending on whether the application can be used to create new files or not. Use setCloseVisible() depending on whether the user may leave the dialog without creating or selecting a document or not. The number of files in the view is available from fileCount(). To force the view to be updated call reread(). If the user presses the 'New Document' button the newSelected() signal is emitted. If the user selects an existing file the fileSelected() signal is emitted. The selected file's \link doclnk.html DocLnk\endlink is available from the selected() function. If the file selector is no longer necessary the closeMe() signal is emitted. \ingroup qtopiaemb \sa FileManager */ /*! Constructs a FileSelector with mime filter \a f. The standard Qt \a parent and \a name parameters are passed to the parent widget. If \a newVisible is TRUE, the widget has a button to allow the user the create "new" documents; this is useful for applications that can create and edit documents but not suitable for applications that only provide viewing. \a closeVisible is deprecated \sa DocLnkSet::DocLnkSet() */ FileSelector::FileSelector( const QString &f, QWidget *parent, const char *name, bool newVisible, bool closeVisible ) : QVBox( parent, name ), filter( f ) { setMargin( 0 ); setSpacing( 0 ); d = new FileSelectorPrivate(); d->newDocItem = 0; d->showNew = newVisible; d->catId = -2; // All files d->toolbar = new QHBox( this ); d->toolbar->setBackgroundMode( PaletteButton ); // same colour as toolbars d->toolbar->setSpacing( 0 ); d->toolbar->hide(); QWidget *spacer = new QWidget( d->toolbar ); spacer->setBackgroundMode( PaletteButton ); QToolButton *tb = new QToolButton( d->toolbar ); tb->setPixmap( Resource::loadPixmap( "close" ) ); connect( tb, SIGNAL( clicked() ), this, SIGNAL( closeMe() ) ); buttonClose = tb; tb->setFixedSize( 18, 20 ); // tb->sizeHint() ); tb->setAutoRaise( TRUE ); QToolTip::add( tb, tr( "Close the File Selector" ) ); QPEMenuToolFocusManager::manager()->addWidget( tb ); view = new FileSelectorView( this, "fileview" ); QPEApplication::setStylusOperation( view->viewport(), QPEApplication::RightOnHold ); connect( view, SIGNAL( mouseButtonClicked( int, QListViewItem *, const QPoint &, int ) ), this, SLOT( fileClicked( int, QListViewItem *, const QPoint &, int ) ) ); connect( view, SIGNAL( mouseButtonPressed( int, QListViewItem *, const QPoint &, int ) ), this, SLOT( filePressed( int, QListViewItem *, const QPoint &, int ) ) ); connect( view, SIGNAL( returnPressed( QListViewItem * ) ), this, SLOT( fileClicked( QListViewItem * ) ) ); QHBox *hb = new QHBox( this ); d->typeCombo = new TypeCombo( hb ); connect( d->typeCombo, SIGNAL(selected(const QString&)), this, SLOT(typeSelected(const QString&)) ); QWhatsThis::add( d->typeCombo, tr("Show documents of this type") ); Categories c; c.load(categoryFileName()); QArray<int> vl( 0 ); d->catSelect = new CategorySelect( hb ); d->catSelect->setRemoveCategoryEdit( TRUE ); d->catSelect->setCategories( vl, "Document View", tr("Document View") ); d->catSelect->setAllCategories( TRUE ); connect( d->catSelect, SIGNAL(signalSelected(int)), this, SLOT(catSelected(int)) ); QWhatsThis::add( d->catSelect, tr("Show documents in this category") ); setCloseVisible( closeVisible ); QCopChannel *channel = new QCopChannel( "QPE/Card", this ); connect( channel, SIGNAL(received(const QCString &, const QByteArray &)), this, SLOT(cardMessage( const QCString &, const QByteArray &)) ); reread(); updateWhatsThis(); } /*! Destroys the widget. */ FileSelector::~FileSelector() { delete d; } /*! Returns the number of files in the view. If this is zero, an editor application might bypass the selector and immediately start with a "new" document. */ int FileSelector::fileCount() { return d->files.children().count();; } /*! Calling this function is the programmatic equivalent of the user pressing the "new" button. \sa newSelected(), closeMe() */ void FileSelector::createNew() { DocLnk f; emit newSelected( f ); emit closeMe(); } void FileSelector::fileClicked( int button, QListViewItem *i, const QPoint &, int ) { if ( !i ) return; if ( button == Qt::LeftButton ) { fileClicked( i ); } } void FileSelector::filePressed( int button, QListViewItem *i, const QPoint &, int ) { if ( !i || i == d->newDocItem ) return; if ( button == Qt::RightButton ) { DocLnk l = ((FileSelectorItem *)i)->file(); LnkProperties prop( &l ); prop.showMaximized(); prop.exec(); reread(); } } void FileSelector::fileClicked( QListViewItem *i ) { if ( !i ) return; if ( i == d->newDocItem ) { createNew(); } else { emit fileSelected( ( (FileSelectorItem*)i )->file() ); emit closeMe(); } } void FileSelector::typeSelected( const QString &type ) { d->mimeFilters.clear(); QStringList subFilter = QStringList::split(";", type); for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++it ) d->mimeFilters.append( QRegExp(*it, FALSE, TRUE) ); updateView(); } void FileSelector::catSelected( int c ) { d->catId = c; updateView(); } void FileSelector::cardMessage( const QCString &msg, const QByteArray &) { if ( msg == "mtabChanged()" ) reread(); } /*! Returns the selected \link doclnk.html DocLnk\endlink. The caller is responsible for deleting the returned value. */ const DocLnk *FileSelector::selected() { FileSelectorItem *item = (FileSelectorItem *)view->selectedItem(); if ( item && item != d->newDocItem ) return new DocLnk( item->file() ); return NULL; } /*! \fn void FileSelector::fileSelected( const DocLnk &f ) This signal is emitted when the user selects a document. \a f is the document. */ /*! \fn void FileSelector::newSelected( const DocLnk &f ) This signal is emitted when the user selects a "new" document. \a f is a DocLnk for the document. You will need to set the type of the document after copying it. */ /*! \fn void FileSelector::closeMe() This signal is emitted when the user no longer needs to view the widget. */ /*! If \a b is TRUE a "new document" entry is visible; if \a b is FALSE this entry is not visible and the user is unable to create new documents from the dialog. */ void FileSelector::setNewVisible( bool b ) { if ( d->showNew != b ) { d->showNew = b; updateView(); updateWhatsThis(); } } /*! If \a b is TRUE a "close" or "no document" button is visible; if \a b is FALSE this button is not visible and the user is unable to leave the dialog without creating or selecting a document. This function is deprecated. */ void FileSelector::setCloseVisible( bool b ) { if ( b ) d->toolbar->show(); else d->toolbar->hide(); } /*! */ void FileSelector::setTypeComboVisible( bool b ) { if ( b ) d->typeCombo->show(); else d->typeCombo->hide(); } /*! */ void FileSelector::setCategorySelectVisible( bool b ) { if ( b ) d->catSelect->show(); else d->catSelect->hide(); } /*! Rereads the list of documents. */ void FileSelector::reread() { d->files.clear(); Global::findDocuments(&d->files, filter); d->typeCombo->reread( d->files, filter ); updateView(); } void FileSelector::updateView() { FileSelectorItem *item = (FileSelectorItem *)view->selectedItem(); if ( item == d->newDocItem ) item = 0; QString oldFile; if ( item ) oldFile = item->file().file(); view->clear(); QListIterator<DocLnk> dit( d->files.children() ); for ( ; dit.current(); ++dit ) { bool mimeMatch = FALSE; if ( d->mimeFilters.count() ) { QValueList<QRegExp>::Iterator it; for ( it = d->mimeFilters.begin(); it != d->mimeFilters.end(); ++it ) { if ( (*it).match((*dit)->type()) >= 0 ) { mimeMatch = TRUE; break; } } } else { mimeMatch = TRUE; } if ( mimeMatch && (d->catId == -2 || (*dit)->categories().contains(d->catId) || (d->catId == -1 && (*dit)->categories().isEmpty())) ) { item = new FileSelectorItem( view, **dit ); if ( item->file().file() == oldFile ) view->setCurrentItem( item ); } } if ( d->showNew ) d->newDocItem = new NewDocItem( view, DocLnk() ); else d->newDocItem = 0; if ( !view->selectedItem() || view->childCount() == 1 ) { view->setCurrentItem( view->firstChild() ); view->setSelected( view->firstChild(), TRUE ); } } void FileSelector::updateWhatsThis() { QWhatsThis::remove( this ); QString text = tr("Click to select a document from the list"); if ( d->showNew ) text += tr(", or select <b>New Document</b> to create a new document."); text += tr("<br><br>Click and hold for document properties."); QWhatsThis::add( this, text ); } #include "fileselector.moc" diff --git a/library/fontdatabase.cpp b/library/fontdatabase.cpp index c64e645..2b5e0d2 100644 --- a/library/fontdatabase.cpp +++ b/library/fontdatabase.cpp @@ -1,232 +1,232 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#include "qpeapplication.h" +#include <qpe/qpeapplication.h> #include "fontfactoryinterface.h" #include "fontdatabase.h" #include <qpe/qlibrary.h> #ifdef QWS #include <qfontmanager_qws.h> #endif #include <qdir.h> #include <qdict.h> #include <stdio.h> #include <stdlib.h> static QString fontDir() { QString qtdir = getenv("QTDIR"); if ( qtdir.isEmpty() ) qtdir = "/usr/local/qt-embedded"; return qtdir+"/lib/fonts/"; } #ifdef QT_NO_FONTDATABASE static QString fontFamily( const QString& key ) { int u0 = key.find('_'); int u1 = key.find('_',u0+1); int u2 = key.find('_',u1+1); QString family = key.left(u0); //int pointSize = key.mid(u0+1,u1-u0-1).toInt(); //int weight = key.mid(u1+1,u2-u1-1).toInt(); //bool italic = key.mid(u2-1,1) == "i"; // #### ignores _t and _I fields return family; } #endif QValueList<FontFactory> *FontDatabase::factoryList = 0; /*! \class FontDatabase fontdatabase.h \brief The FontDatabase class provides information about available fonts. Most often you will simply want to query the database for the available font families(). Use FontDatabase rather than QFontDatabase when you may need access to fonts that are not normally available. For example, if the freetype library and the Qtopia freetype plugin are installed, TrueType fonts will be available to your application. Font renderer plugins have greater resource requirements than system fonts so they should be used only when necessary. You can force the loading of font renderer plugins with loadRenderers(). \ingroup qtopiaemb */ /*! Constructs a FontDatabase object. */ FontDatabase::FontDatabase() #ifndef QT_NO_FONTDATABASE : QFontDatabase() #endif { if ( !factoryList ) loadRenderers(); } /*! Returns a list of names of all the available font families. */ QStringList FontDatabase::families() const { #ifndef QT_NO_FONTDATABASE return QFontDatabase::families(); #else QStringList list; QDict<void> familyDict; QDiskFont *qdf; for ( qdf=qt_fontmanager->diskfonts.first(); qdf!=0; qdf=qt_fontmanager->diskfonts.next()) { QString familyname = qdf->name; if ( !familyDict.find( familyname ) ) { familyDict.insert( familyname, (void *)1 ); list.append( familyname ); } } QDir dir(fontDir(),"*.qpf"); for (int i=0; i<(int)dir.count(); i++) { QString familyname = fontFamily(dir[i]); if ( !familyDict.find( familyname ) ) { familyDict.insert( familyname, (void *)1 ); list.append( familyname ); } } return list; #endif } #ifdef QT_NO_FONTDATABASE /*! Returns a list of standard fontsizes. */ QValueList<int> FontDatabase::standardSizes() { static int s[]={ 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72, 0 }; static bool first = TRUE; static QValueList<int> sList; if ( first ) { first = FALSE; int i = 0; while( s[i] ) sList.append( s[i++] ); } return sList; } #endif /*! Load any font renderer plugins that are available and make the fonts that the plugins can read available. */ void FontDatabase::loadRenderers() { #ifndef QT_NO_COMPONENT if ( !factoryList ) factoryList = new QValueList<FontFactory>; QValueList<FontFactory>::Iterator mit; for ( mit = factoryList->begin(); mit != factoryList->end(); ++mit ) { qt_fontmanager->factories.setAutoDelete( false ); qt_fontmanager->factories.removeRef( (*mit).factory ); qt_fontmanager->factories.setAutoDelete( true ); (*mit).interface->release(); (*mit).library->unload(); delete (*mit).library; } factoryList->clear(); QString path = QPEApplication::qpeDir() + "/plugins/fontfactories"; QDir dir( path, "lib*.so" ); QStringList list = dir.entryList(); QStringList::Iterator it; for ( it = list.begin(); it != list.end(); ++it ) { FontFactoryInterface *iface = 0; QLibrary *lib = new QLibrary( path + "/" + *it ); if ( lib->queryInterface( IID_FontFactory, (QUnknownInterface**)&iface ) == QS_OK ) { FontFactory factory; factory.library = lib; factory.interface = iface; factory.factory = factory.interface->fontFactory(); factoryList->append( factory ); qt_fontmanager->factories.append( factory.factory ); readFonts( factory.factory ); } else { delete lib; } } #endif } /*! \internal */ void FontDatabase::readFonts( QFontFactory *factory ) { // Load in font definition file QString fn = fontDir() + "fontdir"; FILE* fontdef=fopen(fn.local8Bit(),"r"); if(!fontdef) { QCString temp=fn.local8Bit(); qWarning("Cannot find font definition file %s - is $QTDIR set correctly?", temp.data()); return; } char buf[200]=""; char name[200]=""; char render[200]=""; char file[200]=""; char flags[200]=""; char isitalic[10]=""; fgets(buf,200,fontdef); while(!feof(fontdef)) { if ( buf[0] != '#' ) { int weight=50; int size=0; flags[0]=0; sscanf(buf,"%s %s %s %s %d %d %s",name,file,render,isitalic,&weight,&size,flags); QString filename; if ( file[0] != '/' ) filename = fontDir(); filename += file; if ( QFile::exists(filename) ) { if( factory->name() == render ) { QDiskFont * qdf=new QDiskFont(factory,name,isitalic[0]=='y', weight,size,flags,filename); qt_fontmanager->diskfonts.append(qdf); #if QT_VERSION >= 232 QFontDatabase::qwsAddDiskFont( qdf ); #endif } } } fgets(buf,200,fontdef); } fclose(fontdef); } diff --git a/library/fontdatabase.h b/library/fontdatabase.h index 10aec91..991847b 100644 --- a/library/fontdatabase.h +++ b/library/fontdatabase.h @@ -1,62 +1,63 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef FONTFACTORY_H #define FONTFACTORY_H #include <qpe/fontfactoryinterface.h> #include <qfontdatabase.h> #include <qvaluelist.h> class QLibrary; struct FontFactory { #ifndef QT_NO_COMPONENT QLibrary *library; #endif FontFactoryInterface *interface; QFontFactory *factory; }; +#undef QT_NO_FONTDATABASE class FontDatabase #ifndef QT_NO_FONTDATABASE : public QFontDatabase #endif { public: FontDatabase(); // minimal functionality QStringList families () const; #ifdef QT_NO_FONTDATABASE static QValueList<int> standardSizes (); #endif static void loadRenderers(); private: static void readFonts( QFontFactory *factory ); private: static QValueList<FontFactory> *factoryList; }; #endif diff --git a/library/mimetype.cpp b/library/mimetype.cpp index 92fe5e6..ef5d619 100644 --- a/library/mimetype.cpp +++ b/library/mimetype.cpp @@ -1,306 +1,306 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #define QTOPIA_INTERNAL_MIMEEXT #include "mimetype.h" #include "applnk.h" #include "resource.h" -#include "qpeapplication.h" +#include <qpe/qpeapplication.h> #include "config.h" #include <qfile.h> #include <qdict.h> #include <qregexp.h> #include <qstringlist.h> #include <qtextstream.h> #include <qmap.h> static void cleanupMime() { MimeType::clear(); } class MimeTypeData { public: MimeTypeData(const QString& i) : id(i) { apps.setAutoDelete(TRUE); } QString id; QString extension; QList<AppLnk> apps; QString description() { if ( desc.isEmpty() ) desc = QPEApplication::tr("%1 document").arg(apps.first()->name()); return desc; } QPixmap regIcon() { if ( regicon.isNull() ) loadPixmaps(); return regicon; } QPixmap bigIcon() { if ( bigicon.isNull() ) loadPixmaps(); return bigicon; } private: void loadPixmaps() { if ( apps.count() ) { QString icon; for (AppLnk* lnk = apps.first(); icon.isNull() && lnk; lnk=apps.next()) { QStringList icons = lnk->mimeTypeIcons(); if ( icons.count() ) { QStringList types = lnk->mimeTypes(); for (QStringList::ConstIterator t=types.begin(),i=icons.begin(); t!=types.end() && i!=icons.end(); ++i,++t) { if ( *t == id ) { icon = *i; break; } } } } if ( icon.isNull() ) { AppLnk* lnk = apps.first(); regicon = lnk->pixmap(); bigicon = lnk->bigPixmap(); } else { QImage unscaledIcon = Resource::loadImage( icon ); regicon.convertFromImage( unscaledIcon.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() ) ); bigicon.convertFromImage( unscaledIcon.smoothScale( AppLnk::bigIconSize(), AppLnk::bigIconSize() ) ); } } } QPixmap regicon; QPixmap bigicon; QString desc; }; class MimeType::Private : public QDict<MimeTypeData> { public: Private() {} ~Private() {} // ... }; MimeType::Private* MimeType::d=0; static QMap<QString,QString> *typeFor = 0; static QMap<QString,QStringList> *extFor = 0; MimeType::Private& MimeType::data() { if ( !d ) { d = new Private; d->setAutoDelete(TRUE); static bool setCleanup = FALSE; if ( !setCleanup ) { qAddPostRoutine( cleanupMime ); setCleanup = TRUE; } } return *d; } MimeType::MimeType( const QString& ext_or_id ) { init(ext_or_id); } MimeType::MimeType( const DocLnk& lnk ) { init(lnk.type()); } QString MimeType::id() const { return i; } QString MimeType::description() const { MimeTypeData* d = data(i); return d ? d->description() : QString::null; } QPixmap MimeType::pixmap() const { MimeTypeData* d = data(i); return d ? d->regIcon() : QPixmap(); } QString MimeType::extension() const { return extensions().first(); } QStringList MimeType::extensions() const { loadExtensions(); return *(*extFor).find(i); } QPixmap MimeType::bigPixmap() const { MimeTypeData* d = data(i); return d ? d->bigIcon() : QPixmap(); } const AppLnk* MimeType::application() const { MimeTypeData* d = data(i); return d ? d->apps.first() : 0; } static QString serviceBinding(const QString& service) { // Copied from qtopiaservices QString svrc = service; for (int i=0; i<(int)svrc.length(); i++) if ( svrc[i]=='/' ) svrc[i] = '-'; return "Service-"+svrc; } void MimeType::registerApp( const AppLnk& lnk ) { QStringList list = lnk.mimeTypes(); for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) { MimeTypeData* cur = data()[*it]; AppLnk* l = new AppLnk(lnk); if ( !cur ) { cur = new MimeTypeData( *it ); data().insert( *it, cur ); cur->apps.append(l); } else if ( cur->apps.count() ) { Config binding(serviceBinding("Open/"+*it)); binding.setGroup("Service"); QString def = binding.readEntry("default"); if ( l->exec() == def ) cur->apps.prepend(l); else cur->apps.append(l); } else { cur->apps.append(l); } } } void MimeType::clear() { delete d; d = 0; } void MimeType::loadExtensions() { if ( !typeFor ) { extFor = new QMap<QString,QStringList>; typeFor = new QMap<QString,QString>; loadExtensions("/etc/mime.types"); loadExtensions(QPEApplication::qpeDir()+"etc/mime.types"); } } void MimeType::loadExtensions(const QString& filename) { QFile file(filename); if ( file.open(IO_ReadOnly) ) { QTextStream in(&file); QRegExp space("[ \t]+"); while (!in.atEnd()) { QStringList tokens = QStringList::split(space, in.readLine()); QStringList::ConstIterator it = tokens.begin(); if ( it != tokens.end() ) { QString id = *it; ++it; // new override old (though left overrides right) QStringList exts = (*extFor)[id]; QStringList newexts; while ( it != tokens.end() ) { exts.remove(*it); if ( !newexts.contains(*it) ) newexts.append(*it); (*typeFor)[*it] = id; ++it; } (*extFor)[id] = newexts + exts; } } } } void MimeType::init( const QString& ext_or_id ) { if ( ext_or_id[0] != '/' && ext_or_id.contains('/') ) { i = ext_or_id.lower(); } else { loadExtensions(); int dot = ext_or_id.findRev('.'); QString ext = dot >= 0 ? ext_or_id.mid(dot+1) : ext_or_id; i = (*typeFor)[ext.lower()]; if ( i.isNull() ) i = "application/octet-stream"; } static bool appsUpdated = FALSE; if ( !appsUpdated ) { appsUpdated = TRUE; updateApplications(); } } MimeTypeData* MimeType::data(const QString& id) { MimeTypeData* d = data()[id]; if ( !d ) { int s = id.find('/'); QString idw = id.left(s)+"/*"; d = data()[idw]; } return d; } QString MimeType::appsFolderName() { return QPEApplication::qpeDir() + "apps"; } void MimeType::updateApplications() { clear(); AppLnkSet apps( appsFolderName() ); updateApplications(&apps); } void MimeType::updateApplications(AppLnkSet* folder) { for ( QListIterator<AppLnk> it( folder->children() ); it.current(); ++it ) { registerApp(*it.current()); } } diff --git a/library/qpedialog.cpp b/library/qpedialog.cpp index 0db161b..b98e42e 100644 --- a/library/qpedialog.cpp +++ b/library/qpedialog.cpp @@ -1,46 +1,46 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #define protected public #include <qdialog.h> #undef protected #include "qpedialog.h" -#include "qpeapplication.h" +#include <qpe/qpeapplication.h> QPEDialogListener::QPEDialogListener(QDialog *di ) : QObject(di) { dialog = di; connect(qApp, SIGNAL(appMessage(const QCString&, const QByteArray&)), this, SLOT(appMessage(const QCString&, const QByteArray&)) ); } QPEDialogListener::~QPEDialogListener() {} void QPEDialogListener::appMessage( const QCString &msg, const QByteArray & ) { if (!dialog) return; if (msg == "accept()") { dialog->accept(); } else if (msg == "reject()") { dialog->reject(); } } diff --git a/library/qpestyle.cpp b/library/qpestyle.cpp index dfd300f..665910c 100644 --- a/library/qpestyle.cpp +++ b/library/qpestyle.cpp @@ -1,1194 +1,1194 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "qpestyle.h" -#include "qpeapplication.h" +#include <qpe/qpeapplication.h> #include <qpushbutton.h> #include <qpainter.h> #define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) #if QT_VERSION >= 300 #include <qdrawutil.h> #include <qcombobox.h> #include <qtabbar.h> QPEStyle::QPEStyle() { } QPEStyle::~QPEStyle() { } void QPEStyle::drawPrimitive( PrimitiveElement pe, QPainter *p, const QRect &r, const QColorGroup &cg, SFlags flags, const QStyleOption &data) const { switch ( pe ) { case PE_ButtonTool: { QColorGroup mycg = cg; if ( flags & Style_On ) { QBrush fill( cg.mid(), Dense4Pattern ); mycg.setBrush( QColorGroup::Button, fill ); } drawPrimitive( PE_ButtonBevel, p, r, mycg, flags, data ); break; } case PE_ButtonCommand: case PE_ButtonDefault: case PE_ButtonBevel: case PE_HeaderSection: { QPen oldPen = p->pen(); p->fillRect( r.x()+1, r.y()+1, r.width()-2, r.height()-2, cg.brush(QColorGroup::Button) ); int x2 = r.right(); int y2 = r.bottom(); if ( flags & (Style_Sunken | Style_Down | Style_On) ) p->setPen( cg.dark() ); else p->setPen( cg.light() ); p->drawLine( r.x(), r.y()+1, r.x(), y2-1 ); p->drawLine( r.x()+1, r.y(), x2-1, r.y() ); if ( flags & (Style_Sunken | Style_Down | Style_On) ) p->setPen( cg.light() ); else p->setPen( cg.dark() ); p->drawLine( x2, r.y()+1, x2, y2-1 ); p->drawLine( r.x()+1, y2, x2-1, y2 ); p->setPen( oldPen ); break; } case PE_FocusRect: break; case PE_Indicator: { QColorGroup mycg( cg ); QBrush fill; if ( flags & Style_Down ) fill = cg.brush( QColorGroup::Button ); else fill = cg.brush( (flags&Style_Enabled) ? QColorGroup::Base : QColorGroup::Background ); mycg.setBrush( QColorGroup::Button, fill ); if ( flags&Style_Enabled ) flags |= Style_Sunken; drawPrimitive( PE_ButtonBevel, p, r, mycg, flags ); if ( flags & Style_On ) { QPointArray a( 7*2 ); int i, xx, yy; xx = r.x()+3; yy = r.y()+5; for ( i=0; i<3; i++ ) { a.setPoint( 2*i, xx, yy ); a.setPoint( 2*i+1, xx, yy+2 ); xx++; yy++; } yy -= 2; for ( i=3; i<7; i++ ) { a.setPoint( 2*i, xx, yy ); a.setPoint( 2*i+1, xx, yy+2 ); xx++; yy--; } if ( flags & Style_NoChange ) { p->setPen( mycg.dark() ); } else { p->setPen( mycg.text() ); } p->drawLineSegments( a ); } break; } case PE_ExclusiveIndicator: { static const QCOORD pts1[] = { // dark lines 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 }; static const QCOORD pts4[] = { // white lines 2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7, 11,4, 10,3, 10,2 }; static const QCOORD pts5[] = { // inner fill 4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 }; int x, y, w, h; r.rect( &x, &y, &w, &h ); p->eraseRect( x, y, w, h ); QPointArray a( QCOORDARRLEN(pts1), pts1 ); a.translate( x, y ); p->setPen( cg.dark() ); p->drawPolyline( a ); a.setPoints( QCOORDARRLEN(pts4), pts4 ); a.translate( x, y ); p->setPen( cg.light() ); p->drawPolyline( a ); a.setPoints( QCOORDARRLEN(pts5), pts5 ); a.translate( x, y ); QColor fillColor = ( flags&Style_Down || !(flags&Style_Enabled) ) ? cg.button() : cg.base(); p->setPen( fillColor ); p->setBrush( fillColor ) ; p->drawPolygon( a ); if ( flags&Style_On ) { p->setPen( NoPen ); p->setBrush( cg.text() ); p->drawRect( x+5, y+4, 2, 4 ); p->drawRect( x+4, y+5, 4, 2 ); } break; } default: QWindowsStyle::drawPrimitive( pe, p, r, cg, flags, data ); break; } } void QPEStyle::drawControl( ControlElement ce, QPainter *p, const QWidget *widget, const QRect &r, const QColorGroup &cg, SFlags how, const QStyleOption &data) const { switch ( ce ) { case CE_PushButton: { const QPushButton *btn = (QPushButton*)widget; SFlags flags; flags = Style_Default; if ( btn->isDown() ) flags |= Style_Down; if ( btn->isOn() ) flags |= Style_On; if ( btn->isEnabled() ) flags |= Style_Enabled; if ( btn->isDefault() ) flags |= Style_Default; if (! btn->isFlat() && !(flags & Style_Down)) flags |= Style_Raised; p->setPen( cg.foreground() ); p->setBrush( QBrush(cg.button(), NoBrush) ); QColorGroup mycg( cg ); if ( flags & Style_On ) { QBrush fill = QBrush( cg.mid(), Dense4Pattern ); mycg.setBrush( QColorGroup::Button, fill ); } drawPrimitive( PE_ButtonBevel, p, r, mycg, flags, data ); break; } case CE_TabBarTab: { if ( !widget || !widget->parentWidget() ) break; const QTabBar *tb = (const QTabBar *) widget; bool selected = how & Style_Selected; QRect r2(r); if ( tb->shape() == QTabBar::RoundedAbove ) { p->setPen( cg.light() ); p->drawLine( r2.left(), r2.bottom(), r2.right(), r2.bottom() ); if ( r2.left() == 0 ) p->drawPoint( tb->rect().bottomLeft() ); else { p->setPen( cg.light() ); p->drawLine( r2.left(), r2.bottom(), r2.right(), r2.bottom() ); } if ( selected ) { p->setPen( cg.background() ); p->drawLine( r2.left()+2, r2.top()+1, r2.right()-2, r2.top()+1 ); p->fillRect( QRect( r2.left()+1, r2.top()+2, r2.width()-2, r2.height()-2), cg.brush( QColorGroup::Background )); } else { r2.setRect( r2.left() + 2, r2.top() + 2, r2.width() - 4, r2.height() - 2 ); p->setPen( cg.button() ); p->drawLine( r2.left()+2, r2.top()+1, r2.right()-2, r2.top()+1 ); p->fillRect( QRect( r2.left()+1, r2.top()+2, r2.width()-2, r2.height()-3), cg.brush( QColorGroup::Button )); //do shading; will not work for pixmap brushes QColor bg = cg.button(); // int h,s,v; // bg.hsv( &h, &s, &v ); int n = r2.height()/2; int dark = 100; for ( int i = 1; i < n; i++ ) { dark = (dark * (100+(i*15)/n) )/100; p->setPen( bg.dark( dark ) ); int y = r2.bottom()-n+i; int x1 = r2.left()+1; int x2 = r2.right()-1; p->drawLine( x1, y, x2, y ); } } p->setPen( cg.light() ); p->drawLine( r2.left(), r2.bottom()-1, r2.left(), r2.top() + 2 ); p->drawPoint( r2.left()+1, r2.top() + 1 ); p->drawLine( r2.left()+2, r2.top(), r2.right() - 2, r2.top() ); p->setPen( cg.dark() ); p->drawPoint( r2.right() - 1, r2.top() + 1 ); p->drawLine( r2.right(), r2.top() + 2, r2.right(), r2.bottom() - 1); } else if ( tb->shape() == QTabBar::RoundedBelow ) { if ( selected ) { p->setPen( cg.background() ); p->drawLine( r2.left()+2, r2.bottom()-1, r2.right()-2, r2.bottom()-1 ); p->fillRect( QRect( r2.left()+1, r2.top(), r2.width()-2, r2.height()-2), tb->palette().normal().brush( QColorGroup::Background )); } else { p->setPen( cg.dark() ); p->drawLine( r2.left(), r2.top(), r2.right(), r2.top() ); r2.setRect( r2.left() + 2, r2.top(), r2.width() - 4, r2.height() - 2 ); p->setPen( cg.button() ); p->drawLine( r2.left()+2, r2.bottom()-1, r2.right()-2, r2.bottom()-1 ); p->fillRect( QRect( r2.left()+1, r2.top()+1, r2.width()-2, r2.height()-3), tb->palette().normal().brush( QColorGroup::Button )); } p->setPen( cg.dark() ); p->drawLine( r2.right(), r2.top(), r2.right(), r2.bottom() - 2 ); p->drawPoint( r2.right() - 1, r2.bottom() - 1 ); p->drawLine( r2.right() - 2, r2.bottom(), r2.left() + 2, r2.bottom() ); p->setPen( cg.light() ); p->drawLine( r2.left(), r2.top()+1, r2.left(), r2.bottom() - 2 ); p->drawPoint( r2.left() + 1, r2.bottom() - 1 ); if ( r2.left() == 0 ) p->drawPoint( tb->rect().topLeft() ); } else { QCommonStyle::drawControl( ce, p, widget, r, cg, how, data ); } break; } default: QWindowsStyle::drawControl( ce, p, widget, r, cg, how, data ); break; } } void QPEStyle::drawComplexControl( ComplexControl control, QPainter *p, const QWidget *widget, const QRect &r, const QColorGroup &cg, SFlags how, SCFlags sub, SCFlags subActive, const QStyleOption &data) const { switch ( control ) { case CC_ComboBox: if ( sub & SC_ComboBoxArrow ) { SFlags flags = Style_Default; drawPrimitive( PE_ButtonBevel, p, r, cg, flags, data ); QRect ar = QStyle::visualRect( querySubControlMetrics( CC_ComboBox, widget, SC_ComboBoxArrow ), widget ); if ( subActive == SC_ComboBoxArrow ) { p->setPen( cg.dark() ); p->setBrush( cg.brush( QColorGroup::Button ) ); p->drawRect( ar ); } ar.addCoords( 2, 2, -2, -2 ); if ( widget->isEnabled() ) flags |= Style_Enabled; if ( subActive & Style_Sunken ) { flags |= Style_Sunken; } drawPrimitive( PE_ArrowDown, p, ar, cg, flags ); } if ( sub & SC_ComboBoxEditField ) { const QComboBox * cb = (const QComboBox *) widget; QRect re = QStyle::visualRect( querySubControlMetrics( CC_ComboBox, widget, SC_ComboBoxEditField ), widget ); if ( cb->hasFocus() && !cb->editable() ) p->fillRect( re.x(), re.y(), re.width(), re.height(), cg.brush( QColorGroup::Highlight ) ); if ( cb->hasFocus() ) { p->setPen( cg.highlightedText() ); p->setBackgroundColor( cg.highlight() ); } else { p->setPen( cg.text() ); p->setBackgroundColor( cg.background() ); } if ( cb->hasFocus() && !cb->editable() ) { QRect re = QStyle::visualRect( subRect( SR_ComboBoxFocusRect, cb ), widget ); drawPrimitive( PE_FocusRect, p, re, cg, Style_FocusAtBorder, QStyleOption(cg.highlight())); } } break; default: QWindowsStyle::drawComplexControl( control, p, widget, r, cg, how, sub, subActive, data ); break; } } int QPEStyle::pixelMetric( PixelMetric metric, const QWidget *widget ) const { int ret; switch( metric ) { case PM_ButtonMargin: ret = 2; break; case PM_DefaultFrameWidth: ret = 1; break; case PM_ButtonDefaultIndicator: ret = 2; break; case PM_ButtonShiftHorizontal: case PM_ButtonShiftVertical: ret = -1; break; case PM_IndicatorWidth: ret = 15; break; case PM_IndicatorHeight: ret = 13; break; case PM_ExclusiveIndicatorHeight: case PM_ExclusiveIndicatorWidth: ret = 15; break; case PM_ScrollBarExtent: ret = 13; break; case PM_SliderLength: ret = 12; break; default: ret = QWindowsStyle::pixelMetric( metric, widget ); break; } return ret; } QSize QPEStyle::sizeFromContents( ContentsType contents, const QWidget *widget, const QSize &contentsSize, const QStyleOption &data) const { QSize sz(contentsSize); switch ( contents ) { case CT_PopupMenuItem: { if ( !widget || data.isDefault() ) break; sz = QWindowsStyle::sizeFromContents( contents, widget, contentsSize, data ); sz = QSize( sz.width(), sz.height()-2 ); break; } default: sz = QWindowsStyle::sizeFromContents( contents, widget, contentsSize, data ); break; } return sz; } #else #include <qfontmetrics.h> #include <qpalette.h> #include <qdrawutil.h> #include <qscrollbar.h> #include <qbutton.h> #include <qframe.h> #include <qtabbar.h> #define INCLUDE_MENUITEM_DEF #include <qmenudata.h> QPEStyle::QPEStyle() { #if QT_VERSION < 300 setButtonMargin(buttonMargin()); setScrollBarExtent(scrollBarExtent().width(),scrollBarExtent().height()); #endif } QPEStyle::~QPEStyle() { } int QPEStyle::buttonMargin() const { return 2; } QSize QPEStyle::scrollBarExtent() const { return QSize(13,13); } void QPEStyle::polish ( QPalette & ) { } void QPEStyle::polish( QWidget *w ) { if ( w->inherits( "QListBox" ) || w->inherits( "QListView" ) || w->inherits( "QPopupMenu" ) || w->inherits( "QSpinBox" ) ) { QFrame *f = (QFrame *)w; f->setFrameShape( QFrame::StyledPanel ); f->setLineWidth( 1 ); } } void QPEStyle::unPolish( QWidget *w ) { if ( w->inherits( "QListBox" ) || w->inherits( "QListView" ) || w->inherits( "QPopupMenu" ) || w->inherits( "QSpinBox" ) ) { QFrame *f = (QFrame *)w; f->setFrameShape( QFrame::StyledPanel ); f->setLineWidth( 2 ); } } int QPEStyle::defaultFrameWidth() const { return 1; } void QPEStyle::drawPanel ( QPainter * p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, int lineWidth, const QBrush * fill ) { qDrawShadePanel( p, QRect(x, y, w, h), g, sunken, lineWidth, fill ); } void QPEStyle::drawButton( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, const QBrush* fill ) { QPen oldPen = p->pen(); if ( sunken ) p->setPen( g.dark() ); else p->setPen( g.light() ); int x2 = x+w-1; int y2 = y+h-1; p->drawLine( x, y, x, y2 ); p->drawLine( x, y, x2, y ); if ( sunken ) p->setPen( g.light() ); else p->setPen( g.dark() ); p->drawLine( x2, y, x2, y2 ); p->drawLine( x, y2, x2, y2 ); p->setPen( oldPen ); p->fillRect( x+1, y+1, w-2, h-2, fill?(*fill):g.brush(QColorGroup::Button) ); } void QPEStyle::drawButtonMask ( QPainter * p, int x, int y, int w, int h ) { p->fillRect( x, y, w, h, color1 ); } void QPEStyle::drawBevelButton( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, const QBrush* fill ) { drawButton( p, x, y, w, h, g, sunken, fill ); } QRect QPEStyle::comboButtonRect( int x, int y, int w, int h) { return QRect(x+1, y+1, w-2-14, h-2); } QRect QPEStyle::comboButtonFocusRect( int x, int y, int w, int h) { return QRect(x+2, y+2, w-4-14, h-4); } void QPEStyle::drawComboButton( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, bool /*editable*/, bool enabled, const QBrush *fill ) { drawBevelButton( p, x, y, w, h, g, FALSE, fill ); drawBevelButton( p, x+w-14, y, 14, h, g, sunken, fill ); drawArrow( p, QStyle::DownArrow, sunken, x+w-14+ 2, y+ 2, 14- 4, h- 4, g, enabled, &g.brush( QColorGroup::Button ) ); } void QPEStyle::drawExclusiveIndicator ( QPainter * p, int x, int y, int w, int h, const QColorGroup & g, bool on, bool down, bool enabled ) { static const QCOORD pts1[] = { // dark lines 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 }; static const QCOORD pts4[] = { // white lines 2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7, 11,4, 10,3, 10,2 }; static const QCOORD pts5[] = { // inner fill 4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 }; p->eraseRect( x, y, w, h ); QPointArray a( QCOORDARRLEN(pts1), pts1 ); a.translate( x, y ); p->setPen( g.dark() ); p->drawPolyline( a ); a.setPoints( QCOORDARRLEN(pts4), pts4 ); a.translate( x, y ); p->setPen( g.light() ); p->drawPolyline( a ); a.setPoints( QCOORDARRLEN(pts5), pts5 ); a.translate( x, y ); QColor fillColor = ( down || !enabled ) ? g.button() : g.base(); p->setPen( fillColor ); p->setBrush( fillColor ) ; p->drawPolygon( a ); if ( on ) { p->setPen( NoPen ); p->setBrush( g.text() ); p->drawRect( x+5, y+4, 2, 4 ); p->drawRect( x+4, y+5, 4, 2 ); } } void QPEStyle::drawIndicator ( QPainter * p, int x, int y, int w, int h, const QColorGroup & g, int state, bool down, bool enabled ) { QBrush fill; if ( state == QButton::NoChange ) { QBrush b = p->brush(); QColor c = p->backgroundColor(); p->setBackgroundMode( TransparentMode ); p->setBackgroundColor( green ); fill = QBrush(g.base(), Dense4Pattern); p->setBackgroundColor( c ); p->setBrush( b ); } else if ( down ) fill = g.brush( QColorGroup::Button ); else fill = g.brush( enabled ? QColorGroup::Base : QColorGroup::Background ); drawPanel( p, x, y, w, h, g, TRUE, 1, &fill ); if ( state != QButton::Off ) { QPointArray a( 7*2 ); int i, xx, yy; xx = x+3; yy = y+5; for ( i=0; i<3; i++ ) { a.setPoint( 2*i, xx, yy ); a.setPoint( 2*i+1, xx, yy+2 ); xx++; yy++; } yy -= 2; for ( i=3; i<7; i++ ) { a.setPoint( 2*i, xx, yy ); a.setPoint( 2*i+1, xx, yy+2 ); xx++; yy--; } if ( state == QButton::NoChange ) { p->setPen( g.dark() ); } else { p->setPen( g.text() ); } p->drawLineSegments( a ); } } #define HORIZONTAL (sb->orientation() == QScrollBar::Horizontal) #define VERTICAL !HORIZONTAL #define MOTIF_BORDER 2 #define SLIDER_MIN 9 // ### motif says 6 but that's too small /*! \reimp */ void QPEStyle::scrollBarMetrics( const QScrollBar* sb, int &sliderMin, int &sliderMax, int &sliderLength, int& buttonDim ) { int maxLength; int length = HORIZONTAL ? sb->width() : sb->height(); int extent = HORIZONTAL ? sb->height() : sb->width(); if ( length > (extent - 1)*2 ) buttonDim = extent; else buttonDim = length/2 - 1; sliderMin = 0; maxLength = length - buttonDim*2; if ( sb->maxValue() == sb->minValue() ) { sliderLength = maxLength; } else { sliderLength = (sb->pageStep()*maxLength)/ (sb->maxValue()-sb->minValue()+sb->pageStep()); uint range = sb->maxValue()-sb->minValue(); if ( sliderLength < SLIDER_MIN || range > INT_MAX/2 ) sliderLength = SLIDER_MIN; if ( sliderLength > maxLength ) sliderLength = maxLength; } sliderMax = sliderMin + maxLength - sliderLength; } /*!\reimp */ QStyle::ScrollControl QPEStyle::scrollBarPointOver( const QScrollBar* sb, int sliderStart, const QPoint& p ) { if ( !sb->rect().contains( p ) ) return NoScroll; int sliderMin, sliderMax, sliderLength, buttonDim, pos; scrollBarMetrics( sb, sliderMin, sliderMax, sliderLength, buttonDim ); if (sb->orientation() == QScrollBar::Horizontal) pos = p.x(); else pos = p.y(); if (pos < sliderStart) return SubPage; if (pos < sliderStart + sliderLength) return Slider; if (pos < sliderMax + sliderLength) return AddPage; if (pos < sliderMax + sliderLength + buttonDim) return SubLine; return AddLine; } /*! \reimp */ void QPEStyle::drawScrollBarControls( QPainter* p, const QScrollBar* sb, int sliderStart, uint controls, uint activeControl ) { #define ADD_LINE_ACTIVE ( activeControl == AddLine ) #define SUB_LINE_ACTIVE ( activeControl == SubLine ) QColorGroup g = sb->colorGroup(); int sliderMin, sliderMax, sliderLength, buttonDim; scrollBarMetrics( sb, sliderMin, sliderMax, sliderLength, buttonDim ); if ( controls == (AddLine | SubLine | AddPage | SubPage | Slider | First | Last ) ) p->fillRect( 0, 0, sb->width(), sb->height(), g.brush( QColorGroup::Mid )); if (sliderStart > sliderMax) { // sanity check sliderStart = sliderMax; } int dimB = buttonDim; QRect addB; QRect subB; QRect addPageR; QRect subPageR; QRect sliderR; int addX, addY, subX, subY; int length = HORIZONTAL ? sb->width() : sb->height(); int extent = HORIZONTAL ? sb->height() : sb->width(); if ( HORIZONTAL ) { subY = addY = ( extent - dimB ) / 2; subX = length - dimB - dimB; addX = length - dimB; } else { subX = addX = ( extent - dimB ) / 2; subY = length - dimB - dimB; addY = length - dimB; } int sliderEnd = sliderStart + sliderLength; int sliderW = extent; if ( HORIZONTAL ) { subB.setRect( subX,subY+1,dimB,dimB-1 ); addB.setRect( addX,addY+1,dimB,dimB-1 ); subPageR.setRect( 0, 0, sliderStart+1, sliderW ); addPageR.setRect( sliderEnd-1, 0, subX - sliderEnd+1, sliderW ); sliderR .setRect( sliderStart, 1, sliderLength, sliderW-1 ); } else { subB.setRect( subX+1,subY,dimB-1,dimB ); addB.setRect( addX+1,addY,dimB-1,dimB ); subPageR.setRect( 0, 0, sliderW, sliderStart+1 ); addPageR.setRect( 0, sliderEnd-1, sliderW, subY - sliderEnd+1 ); sliderR .setRect( 1, sliderStart, sliderW-1, sliderLength ); } bool maxedOut = (sb->maxValue() == sb->minValue()); if ( controls & AddLine ) { drawBevelButton( p, addB.x(), addB.y(), addB.width(), addB.height(), g, ADD_LINE_ACTIVE); p->setPen(g.shadow()); drawArrow( p, VERTICAL ? DownArrow : RightArrow, FALSE, addB.x()+2, addB.y()+2, addB.width()-4, addB.height()-4, g, !maxedOut, &g.brush( QColorGroup::Button )); } if ( controls & SubLine ) { drawBevelButton( p, subB.x(), subB.y(), subB.width(), subB.height(), g, SUB_LINE_ACTIVE ); p->setPen(g.shadow()); drawArrow( p, VERTICAL ? UpArrow : LeftArrow, FALSE, subB.x()+2, subB.y()+2, subB.width()-4, subB.height()-4, g, !maxedOut, &g.brush( QColorGroup::Button )); } if ( controls & SubPage ) p->fillRect( subPageR.x(), subPageR.y(), subPageR.width(), subPageR.height(), g.brush( QColorGroup::Mid )); if ( controls & AddPage ) p->fillRect( addPageR.x(), addPageR.y(), addPageR.width(), addPageR.height(), g.brush( QColorGroup::Mid )); if ( controls & Slider ) { QPoint bo = p->brushOrigin(); p->setBrushOrigin(sliderR.topLeft()); drawBevelButton( p, sliderR.x(), sliderR.y(), sliderR.width(), sliderR.height(), g, FALSE, &g.brush( QColorGroup::Button ) ); p->setBrushOrigin(bo); drawRiffles( p, sliderR.x(), sliderR.y(), sliderR.width(), sliderR.height(), g, HORIZONTAL ); } // ### perhaps this should not be able to accept focus if maxedOut? if ( sb->hasFocus() && (controls & Slider) ) p->drawWinFocusRect( sliderR.x()+2, sliderR.y()+2, sliderR.width()-5, sliderR.height()-5, sb->backgroundColor() ); } void QPEStyle::drawRiffles( QPainter* p, int x, int y, int w, int h, const QColorGroup &g, bool horizontal ) { if (!horizontal) { if (h > 20) { y += (h-20)/2 ; h = 20; } if (h > 12) { int n = 3; int my = y+h/2-4; int i ; p->setPen(g.light()); for (i=0; i<n; i++) { p->drawLine(x+2, my+3*i, x+w-4, my+3*i); } p->setPen(g.dark()); my++; for (i=0; i<n; i++) { p->drawLine(x+2, my+3*i, x+w-4, my+3*i); } } } else { if (w > 20) { x += (w-20)/2 ; w = 20; } if (w > 12) { int n = 3; int mx = x+w/2-4; int i ; p->setPen(g.light()); for (i=0; i<n; i++) { p->drawLine(mx+3*i, y+2, mx + 3*i, y+h-4); } p->setPen(g.dark()); mx++; for (i=0; i<n; i++) { p->drawLine(mx+3*i, y+2, mx + 3*i, y+h-4); } } } } int QPEStyle::sliderLength() const { return 12; } void QPEStyle::drawSlider( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, Orientation o, bool tickAbove, bool tickBelow ) { int a = tickAbove ? 3 : 0; int b = tickBelow ? 3 : 0; if ( o == Horizontal ) { drawBevelButton( p, x, y+a, w, h-a-b, g, FALSE, &g.brush( QColorGroup::Button ) ); int xp = x + w/2; qDrawShadeLine( p, xp, y+a+2, xp, y+h-b-3, g ); } else { drawBevelButton( p, x+a, y, w-a-b, h, g, FALSE, &g.brush( QColorGroup::Button ) ); int yp = y + h/2; qDrawShadeLine( p, x+a+2, yp, x+w-b-3, yp, g ); } } void QPEStyle::drawSliderMask ( QPainter * p, int x, int y, int w, int h, Orientation o, bool tickAbove, bool tickBelow ) { int a = tickAbove ? 3 : 0; int b = tickBelow ? 3 : 0; if ( o == Horizontal ) p->fillRect( x, y+a, w, h-a-b, color1 ); else p->fillRect( x+a, y, w-a-b, h, color1 ); } /*!\reimp */ void QPEStyle::drawSliderGrooveMask( QPainter *p, int x, int y, int w, int h, const QColorGroup& , QCOORD c, Orientation orient ) { if ( orient == Horizontal ) p->fillRect( x, y + c - 2, w, 4, color1 ); else p->fillRect( x + c - 2, y, 4, h, color1 ); } void QPEStyle::drawTab( QPainter *p, const QTabBar *tb, QTab *t, bool selected ) { QRect r( t->rect() ); if ( tb->shape() == QTabBar::RoundedAbove ) { p->setPen( tb->colorGroup().light() ); p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() ); if ( r.left() == 0 ) p->drawPoint( tb->rect().bottomLeft() ); else { p->setPen( tb->colorGroup().light() ); p->drawLine( r.left(), r.bottom(), r.right(), r.bottom() ); } if ( selected ) { p->setPen( tb->colorGroup().background() ); p->drawLine( r.left()+2, r.top()+1, r.right()-2, r.top()+1 ); p->fillRect( QRect( r.left()+1, r.top()+2, r.width()-2, r.height()-2), tb->colorGroup().brush( QColorGroup::Background )); } else { r.setRect( r.left() + 2, r.top() + 2, r.width() - 4, r.height() - 2 ); p->setPen( tb->colorGroup().button() ); p->drawLine( r.left()+2, r.top()+1, r.right()-2, r.top()+1 ); p->fillRect( QRect( r.left()+1, r.top()+2, r.width()-2, r.height()-3), tb->colorGroup().brush( QColorGroup::Button )); //do shading; will not work for pixmap brushes QColor bg = tb->colorGroup().button(); // int h,s,v; // bg.hsv( &h, &s, &v ); int n = r.height()/2; int dark = 100; for ( int i = 1; i < n; i++ ) { dark = (dark * (100+(i*15)/n) )/100; p->setPen( bg.dark( dark ) ); int y = r.bottom()-n+i; int x1 = r.left()+1; int x2 = r.right()-1; p->drawLine( x1, y, x2, y ); } } p->setPen( tb->colorGroup().light() ); p->drawLine( r.left(), r.bottom()-1, r.left(), r.top() + 2 ); p->drawPoint( r.left()+1, r.top() + 1 ); p->drawLine( r.left()+2, r.top(), r.right() - 2, r.top() ); p->setPen( tb->colorGroup().dark() ); p->drawPoint( r.right() - 1, r.top() + 1 ); p->drawLine( r.right(), r.top() + 2, r.right(), r.bottom() - 1); } else if ( tb->shape() == QTabBar::RoundedBelow ) { if ( selected ) { p->setPen( tb->colorGroup().background() ); p->drawLine( r.left()+2, r.bottom()-1, r.right()-2, r.bottom()-1 ); p->fillRect( QRect( r.left()+1, r.top(), r.width()-2, r.height()-2), tb->palette().normal().brush( QColorGroup::Background )); } else { p->setPen( tb->colorGroup().dark() ); p->drawLine( r.left(), r.top(), r.right(), r.top() ); r.setRect( r.left() + 2, r.top(), r.width() - 4, r.height() - 2 ); p->setPen( tb->colorGroup().button() ); p->drawLine( r.left()+2, r.bottom()-1, r.right()-2, r.bottom()-1 ); p->fillRect( QRect( r.left()+1, r.top()+1, r.width()-2, r.height()-3), tb->palette().normal().brush( QColorGroup::Button )); } p->setPen( tb->colorGroup().dark() ); p->drawLine( r.right(), r.top(), r.right(), r.bottom() - 2 ); p->drawPoint( r.right() - 1, r.bottom() - 1 ); p->drawLine( r.right() - 2, r.bottom(), r.left() + 2, r.bottom() ); p->setPen( tb->colorGroup().light() ); p->drawLine( r.left(), r.top()+1, r.left(), r.bottom() - 2 ); p->drawPoint( r.left() + 1, r.bottom() - 1 ); if ( r.left() == 0 ) p->drawPoint( tb->rect().topLeft() ); } else { QCommonStyle::drawTab( p, tb, t, selected ); } } static const int motifItemFrame = 0; // menu item frame width static const int motifSepHeight = 2; // separator item height static const int motifItemHMargin = 1; // menu item hor text margin static const int motifItemVMargin = 2; // menu item ver text margin static const int motifArrowHMargin = 0; // arrow horizontal margin static const int motifTabSpacing = 12; // space between text and tab static const int motifCheckMarkHMargin = 1; // horiz. margins of check mark static const int windowsRightBorder = 8; // right border on windows static const int windowsCheckMarkWidth = 2; // checkmarks width on windows /*! \reimp */ int QPEStyle::extraPopupMenuItemWidth( bool checkable, int maxpmw, QMenuItem* mi, const QFontMetrics& /*fm*/ ) { #ifndef QT_NO_MENUDATA int w = 2*motifItemHMargin + 2*motifItemFrame; // a little bit of border can never harm if ( mi->isSeparator() ) return 10; // arbitrary else if ( mi->pixmap() ) w += mi->pixmap()->width(); // pixmap only if ( !mi->text().isNull() ) { if ( mi->text().find('\t') >= 0 ) // string contains tab w += motifTabSpacing; } if ( maxpmw ) { // we have iconsets w += maxpmw; w += 6; // add a little extra border around the iconset } if ( checkable && maxpmw < windowsCheckMarkWidth ) { w += windowsCheckMarkWidth - maxpmw; // space for the checkmarks } if ( maxpmw > 0 || checkable ) // we have a check-column ( iconsets or checkmarks) w += motifCheckMarkHMargin; // add space to separate the columns w += windowsRightBorder; // windows has a strange wide border on the right side return w; #endif } /*! \reimp */ int QPEStyle::popupMenuItemHeight( bool /*checkable*/, QMenuItem* mi, const QFontMetrics& fm ) { #ifndef QT_NO_MENUDATA int h = 0; if ( mi->isSeparator() ) // separator height h = motifSepHeight; else if ( mi->pixmap() ) // pixmap height h = mi->pixmap()->height() + 2*motifItemFrame; else // text height h = fm.height() + 2*motifItemVMargin + 2*motifItemFrame - 1; if ( !mi->isSeparator() && mi->iconSet() != 0 ) { h = QMAX( h, mi->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height() + 2*motifItemFrame ); } if ( mi->custom() ) h = QMAX( h, mi->custom()->sizeHint().height() + 2*motifItemVMargin + 2*motifItemFrame ) - 1; return h; #endif } void QPEStyle::drawPopupMenuItem( QPainter* p, bool checkable, int maxpmw, int tab, QMenuItem* mi, const QPalette& pal, bool act, bool enabled, int x, int y, int w, int h) { #ifndef QT_NO_MENUDATA const QColorGroup & g = pal.active(); bool dis = !enabled; QColorGroup itemg = dis ? pal.disabled() : pal.active(); if ( checkable ) maxpmw = QMAX( maxpmw, 8 ); // space for the checkmarks int checkcol = maxpmw; if ( mi && mi->isSeparator() ) { // draw separator p->setPen( g.dark() ); p->drawLine( x, y, x+w, y ); p->setPen( g.light() ); p->drawLine( x, y+1, x+w, y+1 ); return; } QBrush fill = act? g.brush( QColorGroup::Highlight ) : g.brush( QColorGroup::Button ); p->fillRect( x, y, w, h, fill); if ( !mi ) return; if ( mi->isChecked() ) { if ( act && !dis ) { qDrawShadePanel( p, x, y, checkcol, h, g, TRUE, 1, &g.brush( QColorGroup::Button ) ); } else { qDrawShadePanel( p, x, y, checkcol, h, g, TRUE, 1, &g.brush( QColorGroup::Midlight ) ); } } else if ( !act ) { p->fillRect(x, y, checkcol , h, g.brush( QColorGroup::Button )); } if ( mi->iconSet() ) { // draw iconset QIconSet::Mode mode = dis ? QIconSet::Disabled : QIconSet::Normal; if (act && !dis ) mode = QIconSet::Active; QPixmap pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode ); int pixw = pixmap.width(); int pixh = pixmap.height(); if ( act && !dis ) { if ( !mi->isChecked() ) qDrawShadePanel( p, x, y, checkcol, h, g, FALSE, 1, &g.brush( QColorGroup::Button ) ); } QRect cr( x, y, checkcol, h ); QRect pmr( 0, 0, pixw, pixh ); pmr.moveCenter( cr.center() ); p->setPen( itemg.text() ); p->drawPixmap( pmr.topLeft(), pixmap ); QBrush fill = act? g.brush( QColorGroup::Highlight ) : g.brush( QColorGroup::Button ); p->fillRect( x+checkcol + 1, y, w - checkcol - 1, h, fill); } else if ( checkable ) { // just "checking"... int mw = checkcol + motifItemFrame; int mh = h - 2*motifItemFrame; if ( mi->isChecked() ) { drawCheckMark( p, x + motifItemFrame + 2, y+motifItemFrame, mw, mh, itemg, act, dis ); } } p->setPen( act ? g.highlightedText() : g.buttonText() ); QColor discol; if ( dis ) { discol = itemg.text(); p->setPen( discol ); } int xm = motifItemFrame + checkcol + motifItemHMargin; if ( mi->custom() ) { int m = motifItemVMargin; p->save(); if ( dis && !act ) { p->setPen( g.light() ); mi->custom()->paint( p, itemg, act, enabled, x+xm+1, y+m+1, w-xm-tab+1, h-2*m ); p->setPen( discol ); } mi->custom()->paint( p, itemg, act, enabled, x+xm, y+m, w-xm-tab+1, h-2*m ); p->restore(); } QString s = mi->text(); if ( !s.isNull() ) { // draw text int t = s.find( '\t' ); int m = motifItemVMargin; const int text_flags = AlignVCenter|ShowPrefix | DontClip | SingleLine; if ( t >= 0 ) { // draw tab text if ( dis && !act ) { p->setPen( g.light() ); p->drawText( x+w-tab-windowsRightBorder-motifItemHMargin-motifItemFrame+1, y+m+1, tab, h-2*m, text_flags, s.mid( t+1 )); p->setPen( discol ); } p->drawText( x+w-tab-windowsRightBorder-motifItemHMargin-motifItemFrame, y+m, tab, h-2*m, text_flags, s.mid( t+1 ) ); } if ( dis && !act ) { p->setPen( g.light() ); p->drawText( x+xm+1, y+m+1, w-xm+1, h-2*m, text_flags, s, t ); p->setPen( discol ); } p->drawText( x+xm, y+m, w-xm-tab+1, h-2*m, text_flags, s, t ); } else if ( mi->pixmap() ) { // draw pixmap QPixmap *pixmap = mi->pixmap(); if ( pixmap->depth() == 1 ) p->setBackgroundMode( OpaqueMode ); p->drawPixmap( x+xm, y+motifItemFrame, *pixmap ); if ( pixmap->depth() == 1 ) p->setBackgroundMode( TransparentMode ); } if ( mi->popup() ) { // draw sub menu arrow int dim = (h-2*motifItemFrame) / 2; if ( act ) { if ( !dis ) discol = white; QColorGroup g2( discol, g.highlight(), white, white, dis ? discol : white, discol, white ); drawArrow( p, RightArrow, FALSE, x+w - motifArrowHMargin - motifItemFrame - dim, y+h/2-dim/2, dim, dim, g2, TRUE ); } else { drawArrow( p, RightArrow, FALSE, x+w - motifArrowHMargin - motifItemFrame - dim, y+h/2-dim/2, dim, dim, g, mi->isEnabled() ); } } #endif } #endif diff --git a/library/resource.cpp b/library/resource.cpp index bdcd603..0920b67 100644 --- a/library/resource.cpp +++ b/library/resource.cpp @@ -1,217 +1,217 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #define QTOPIA_INTERNAL_MIMEEXT -#include "qpeapplication.h" +#include <qpe/qpeapplication.h> #include "resource.h" #include "mimetype.h" #include <qdir.h> #include <qfile.h> #include <qregexp.h> #include <qpixmapcache.h> #include <qpainter.h> // this namespace is just a workaround for a gcc bug // gcc exports inline functions in the generated file // inlinepics_p.h namespace { #include "inlinepics_p.h" } /*! \class Resource resource.h \brief The Resource class provides access to named resources. The resources may be provided from files or other sources. The allSounds() function returns a list of all the sounds available. A particular sound can be searched for using findSound(). Images can be loaded with loadImage(), loadPixmap(), loadBitmap() and loadIconSet(). \ingroup qtopiaemb */ /*! \fn Resource::Resource() \internal */ /*! Returns the QPixmap called \a pix. You should avoid including any filename type extension (e.g. .png, .xpm). */ QPixmap Resource::loadPixmap( const QString &pix ) { QPixmap pm; QString key="QPE_"+pix; if ( !QPixmapCache::find(key,pm) ) { pm.convertFromImage(loadImage(pix)); QPixmapCache::insert(key,pm); } return pm; } /*! Returns the QBitmap called \a pix. You should avoid including any filename type extension (e.g. .png, .xpm). */ QBitmap Resource::loadBitmap( const QString &pix ) { QBitmap bm; bm = loadPixmap(pix); return bm; } /*! Returns the filename of a pixmap called \a pix. You should avoid including any filename type extension (e.g. .png, .xpm). Normally you will use loadPixmap() rather than this function. */ QString Resource::findPixmap( const QString &pix ) { QString picsPath = QPEApplication::qpeDir() + "pics/"; QString f; // Common case optimizations... f = picsPath + pix + ".png"; if ( QFile( f ).exists() ) return f; f = picsPath + pix + ".xpm"; if ( QFile( f ).exists() ) return f; // All formats... QStrList fileFormats = QImageIO::inputFormats(); QString ff = fileFormats.first(); while ( fileFormats.current() ) { QStringList exts = MimeType("image/"+ff.lower()).extensions(); for ( QStringList::ConstIterator it = exts.begin(); it!=exts.end(); ++it ) { QString f = picsPath + pix + "." + *it; if ( QFile(f).exists() ) return f; } ff = fileFormats.next(); } // Finally, no (or existing) extension... if ( QFile( picsPath + pix ).exists() ) return picsPath + pix; //qDebug("Cannot find pixmap: %s", pix.latin1()); return QString(); } /*! Returns a sound file for a sound called \a name. You should avoid including any filename type extension (e.g. .wav), as the system will search for only those fileformats which are supported by the library. Currently, only WAV files are supported. */ QString Resource::findSound( const QString &name ) { QString picsPath = QPEApplication::qpeDir() + "sounds/"; QString result; if ( QFile( (result = picsPath + name + ".wav") ).exists() ) return result; return QString(); } /*! Returns a list of all sound names. */ QStringList Resource::allSounds() { QDir resourcedir( QPEApplication::qpeDir() + "sounds/", "*.wav" ); QStringList entries = resourcedir.entryList(); QStringList result; for (QStringList::Iterator i=entries.begin(); i != entries.end(); ++i) result.append((*i).replace(QRegExp("\\.wav"),"")); return result; } static QImage load_image(const QString &name) { QImage img = qembed_findImage(name.latin1()); if ( img.isNull() ) { // No inlined image, try file QString f = Resource::findPixmap(name); if ( !f.isEmpty() ) img.load(f); } return img; } /*! Returns the QImage called \a name. You should avoid including any filename type extension (e.g. .png, .xpm). */ QImage Resource::loadImage( const QString &name) { #ifndef QT_NO_DEPTH_32 // have alpha-blended pixmaps static QImage last_enabled; static QString last_enabled_name; if ( name == last_enabled_name ) return last_enabled; #endif QImage img = load_image(name); #ifndef QT_NO_DEPTH_32 // have alpha-blended pixmaps if ( img.isNull() ) { // No file, try generating if ( name[name.length()-1]=='d' && name.right(9)=="_disabled" ) { last_enabled_name = name.left(name.length()-9); last_enabled = load_image(last_enabled_name); if ( last_enabled.isNull() ) { last_enabled_name = QString::null; } else { img.detach(); img.create( last_enabled.width(), last_enabled.height(), 32 ); for ( int y = 0; y < img.height(); y++ ) { for ( int x = 0; x < img.width(); x++ ) { QRgb p = last_enabled.pixel( x, y ); int a = qAlpha(p)/3; int g = qGray(qRed(p),qGreen(p),qBlue(p)); img.setPixel( x, y, qRgba(g,g,g,a) ); } } img.setAlphaBuffer( TRUE ); } } } #endif return img; } /*! \fn QIconSet Resource::loadIconSet( const QString &name ) Returns a QIconSet for the pixmap named \a name. A disabled icon is generated that conforms to the Qtopia look & feel. You should avoid including any filename type extension (eg. .png, .xpm). */ diff --git a/library/timestring.cpp b/library/timestring.cpp index 4c6fa72..6443b6b 100644 --- a/library/timestring.cpp +++ b/library/timestring.cpp @@ -1,365 +1,365 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "timestring.h" #include <qobject.h> -#include "qpeapplication.h" //for qApp +#include <qpe/qpeapplication.h> //for qApp #include "config.h" class TimeStringFormatKeeper : public QObject { Q_OBJECT public: static DateFormat currentFormat() { if ( !self ) self = new TimeStringFormatKeeper; return self->format; } private slots: void formatChanged( DateFormat f ) { format = f; } private: static TimeStringFormatKeeper *self; DateFormat format; TimeStringFormatKeeper() : QObject( qApp ) { Config config("qpe"); config.setGroup( "Date" ); format = DateFormat(QChar(config.readEntry("Separator", "/")[0]), (DateFormat::Order)config .readNumEntry("ShortOrder", DateFormat::DayMonthYear), (DateFormat::Order)config.readNumEntry("LongOrder", DateFormat::DayMonthYear)); connect( qApp, SIGNAL( dateFormatChanged(DateFormat) ), this, SLOT( formatChanged( DateFormat ) ) ); } }; TimeStringFormatKeeper *TimeStringFormatKeeper::self = 0; QString DateFormat::toNumberString() const { QString buf = ""; // for each part of the order for (int i = 0; i < 3; i++) { // switch on the relavent 3 bits. switch((_shortOrder >> (i * 3)) & 0x0007) { case 0x0001: buf += QObject::tr( "D" ); break; case 0x0002: buf += QObject::tr( "M" ); break; case 0x0004: buf += QObject::tr( "Y" ); break; } if (i < 2) buf += _shortSeparator; } return buf; } QString DateFormat::toWordString() const { QString buf = ""; // for each part of the order for (int i = 0; i < 3; i++) { // switch on the relavent 3 bits. switch((_longOrder >> (i * 3)) & 0x0007) { case 0x0001: buf += QObject::tr( "day" ); if (i < 2) { if ((_shortOrder << ((i+1) * 3)) & 0x0007) buf += ", "; else buf += " "; } break; case 0x0002: buf += QObject::tr( "month" ); if (i < 2) buf += " "; break; case 0x0004: buf += QObject::tr( "year" ); if (i < 2) buf += ", "; break; } } return buf; } QString DateFormat::numberDate(const QDate &d, int v) const { QString buf = ""; int pad = 2; // for each part of the order for (int i = 0; i < 3; i++) { // switch on the relavent 3 bits. switch((_shortOrder >> (i * 3)) & 0x0007) { case 0x0001: if (pad==2) buf += QString().sprintf("%02d",d.day()); else buf += QString().sprintf("%d",d.day()); break; case 0x0002: if (i==0) { // no padding with only MM/DD/YY format pad=0; } if (pad==2) buf += QString().sprintf("%02d",d.month()); else buf += QString().sprintf("%d",d.month()); break; case 0x0004: { int year = d.year(); if (!(v & longNumber)) year = year % 100; buf += QString().sprintf("%02d",year); } break; } if (i < 2) buf += _shortSeparator; } return buf; } QString DateFormat::wordDate(const QDate &d, int v) const { QString buf = ""; // for each part of the order if (v & showWeekDay) { QString weekDay = d.dayName(d.dayOfWeek()); if (!(v & longWord)) { weekDay = weekDay.left(3); } buf += weekDay; if ((_longOrder & 0x0007) == 0x0002) buf += ' '; else buf += ", "; } for (int i = 0; i < 3; i++) { // switch on the relavent 3 bits. switch((_longOrder >> (i * 3)) & 0x0007) { case 0x0001: if (i==1) { buf += QString().sprintf("%02d, ",d.day()); } else { buf += QString().sprintf("%2d",d.day()); if (separator()=='.') // 2002/1/11 buf += ". "; else buf += " "; } break; case 0x0002: { QString monthName = d.monthName(d.month()); if (!(v & longWord)) { monthName = monthName.left(3); } buf += monthName; } if (i < 2) buf += " "; break; case 0x0004: { int year = d.year(); if (!(v & longNumber)) year = year % 100; if (year < 10) buf += "0"; buf += QString::number(year); } if (i < 2) buf += ", "; break; } } return buf; } #ifndef QT_NO_DATASTREAM void DateFormat::save(QDataStream &d) const { d << _shortSeparator.unicode(); uint v= _shortOrder; d << v; v = _longOrder; d << v; } void DateFormat::load(QDataStream &d) { ushort value; d >> value; _shortSeparator = QChar(value); uint v = 0; d >> v; _shortOrder = (Order)v; v = 0; d >> v; _longOrder = (Order)v; } QDataStream &operator<<(QDataStream &s, const DateFormat&df) { df.save(s); return s; } QDataStream &operator>>(QDataStream &s, DateFormat&df) { df.load(s); return s; } #endif QString TimeString::shortDate( const QDate &d, DateFormat dtf ) { return dtf.wordDate(d); } QString TimeString::dateString( const QDate &d, DateFormat dtf ) { return dtf.wordDate(d, DateFormat::longNumber | DateFormat::longWord); } QString TimeString::longDateString( const QDate &d, DateFormat dtf ) { return dtf.wordDate(d, DateFormat::showWeekDay | DateFormat::longNumber | DateFormat::longWord); } DateFormat TimeString::currentDateFormat() { return TimeStringFormatKeeper::currentFormat(); } QString TimeString::dateString( const QDateTime &dt, bool ampm, bool seconds, DateFormat dtf ) { const QDate& d = dt.date(); const QTime& t = dt.time(); // based on QDateTime::toString() QString buf = timeString(t,ampm,seconds); buf += " "; buf += longDateString( d, dtf ); return buf; } QString TimeString::timeString( const QTime &t, bool ampm, bool seconds ) { if ( !ampm ) { if ( seconds ) return t.toString(); QString r = QString::number(t.hour()); if ( t.hour() < 10 ) r.prepend( "0" ); r.append( ":" ); if ( t.minute() < 10 ) r.append( "0" ); r.append(QString::number(t.minute())); return r; } // ### else the hard case that should disappear in Qt 3.0 QString argString = seconds ? "%4:%5:%6 %7" : "%4:%5 %7"; int hour = t.hour(); QString strMin = QString::number( t.minute() ); QString strSec = QString::number( t.second() ); if ( hour > 12 ) argString = argString.arg( hour - 12, 2 ); else { if ( hour == 0 ) argString = argString.arg( 12 ); else argString = argString.arg( hour, 2 ); } if ( t.minute() < 10 ) strMin.prepend( "0" ); if ( t.second() < 10 ) strSec.prepend( "0" ); argString = argString.arg( strMin ); if ( seconds ) argString = argString.arg( strSec ); if ( hour >= 12 ) argString = argString.arg( QObject::tr("PM") ); else argString = argString.arg( QObject::tr("AM") ); return argString; } QString TimeString::shortTime( bool ampm, bool seconds ) { static const char* const day[] = { QT_TRANSLATE_NOOP( "QObject", "Mon" ), QT_TRANSLATE_NOOP( "QObject", "Tue" ), QT_TRANSLATE_NOOP( "QObject", "Wed" ), QT_TRANSLATE_NOOP( "QObject", "Thu" ), QT_TRANSLATE_NOOP( "QObject", "Fri" ), QT_TRANSLATE_NOOP( "QObject", "Sat" ), QT_TRANSLATE_NOOP( "QObject", "Sun" ) }; // just create a shorter time String QDateTime dtTmp = QDateTime::currentDateTime(); QString strTime; strTime = QObject::tr( day[dtTmp.date().dayOfWeek()-1] ) + " " + timeString( dtTmp.time(), ampm, seconds ); return strTime; } QString TimeString::dateString( const QDateTime &t, bool ampm ) { return dateString(t,ampm,FALSE); } QString TimeString::timeString( const QTime &t, bool ampm) { return timeString(t,ampm,FALSE); } QString TimeString::shortTime( bool ampm ) { return shortTime(ampm,FALSE); } QString TimeString::numberDateString( const QDate &d, DateFormat dtf ) { return dtf.numberDate(d); } QString TimeString::longNumberDateString( const QDate &d, DateFormat dtf ) { return dtf.numberDate(d,DateFormat::longNumber); } #include "timestring.moc" |