⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eventxmlio.cpp

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 CPP
字号:
/************************************************************************ 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 <qfile.h>#include <qasciidict.h>#include <qtopia/config.h>#include <qtopia/global.h>#include <qtopia/stringutil.h>#include <qtopia/quuid.h>#include <qfileinfo.h>#ifdef Q_WS_QWS#include <qtopia/qcopenvelope_qws.h>#endif#include <qtopia/timeconversion.h>#include <qtopia/alarmserver.h>#include <qapplication.h>#include <errno.h>#include <sys/types.h>#include <stdlib.h>#include "eventxmlio_p.h"#include "event.h"#ifdef Q_OS_WIN32#include <process.h>#else#include <unistd.h>#endif// from time_t to QDateTime, but no timezone conversion.QDateTime asQDateTime( time_t time ){    struct tm *lt;#if defined(Q_WS_WIN32) || defined (Q_OS_WIN64)    _tzset();#else    tzset();#endif    lt = gmtime( &time );    QDateTime dt(	    QDate( lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday ),	    QTime( lt->tm_hour, lt->tm_min, lt->tm_sec ) );    return dt;}time_t asTimeT( const QDateTime& dt ){    time_t tmp;    struct tm *lt;#if defined(Q_WS_WIN32) || defined (Q_OS_WIN64)    _tzset();#else    tzset();#endif    // get a tm structure from the system to get the correct tz_name    tmp = time( 0 );    lt = gmtime( &tmp );    lt->tm_sec = dt.time().second();    lt->tm_min = dt.time().minute();    lt->tm_hour = dt.time().hour();    lt->tm_mday = dt.date().day();    lt->tm_mon = dt.date().month() - 1; // 0-11 instead of 1-12    lt->tm_year = dt.date().year() - 1900; // year - 1900    //lt->tm_wday = dt.date().dayOfWeek(); ignored anyway    //lt->tm_yday = dt.date().dayOfYear(); ignored anyway    lt->tm_wday = -1;    lt->tm_yday = -1;    // tm_isdst negative -> mktime will find out about DST    lt->tm_isdst = -1;    // keep tm_zone and tm_gmtoff    tmp = mktime( lt );    return tmp;}EventXmlIO::EventXmlIO(AccessMode m,		     const QString &file,		     const QString &journal )    : EventIO(m),      PimXmlIO(PimEvent::keyToIdentifierMap(), PimEvent::identifierToKeyMap() ),      needsSave(FALSE){    if ( file != QString::null )	setDataFilename( file );    else setDataFilename( Global::applicationFileName( "datebook", "datebook.xml" ) );    if ( journal != QString::null )	setJournalFilename( journal );    else setJournalFilename( Global::journalFileName( ".caljournal" ) );    m_PrEvents.setAutoDelete(TRUE);    loadData();    if (m == ReadOnly) {#ifndef QT_NO_COP	QCopChannel *channel = new QCopChannel( "QPE/PIM",  this );	connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),		this, SLOT(pimMessage(const QCString&, const QByteArray&)) );#endif    }}void EventXmlIO::pimMessage(const QCString &message, const QByteArray &data){    QDataStream ds(data, IO_ReadOnly);    if (message == "addedEvent(int,PimEvent)") {	int pid;	PimEvent event;	ds >> pid;	ds >> event;	if (pid != getpid()) {	    internalAddRecord(new PimEvent(event));	    emit eventsUpdated();	}    } else if (message == "removedEvent(int,PimEvent)") {	int pid;	PimEvent event;	ds >> pid;	ds >> event;	if (pid != getpid()) {	    internalRemoveRecord(new PimEvent(event));	    emit eventsUpdated();	}    } else if (message == "updatedEvent(int,PimEvent)") {	int pid;	PimEvent event;	ds >> pid;	ds >> event;	if (pid != getpid()) {	    internalUpdateRecord( &event );	    emit eventsUpdated();	}    } else if (message == "reloadEvents()") {        ensureDataCurrent();    } else if ( message == "reload(int)" ) {	int force;	ds >> force;        ensureDataCurrent(force);    }}EventXmlIO::~EventXmlIO() {}bool EventXmlIO::loadData(){    if (PimXmlIO::loadData()) {	emit eventsUpdated();	return TRUE;    }    return FALSE;}bool EventXmlIO::internalAddRecord(PimRecord *rec){    PrEvent *ev = (PrEvent *)rec;    m_PrEvents.append( ev );    return TRUE;}bool EventXmlIO::internalRemoveRecord(PimRecord *rec){    PrEvent *ev = (PrEvent *)rec;    for (m_PrEvents.first(); m_PrEvents.current(); m_PrEvents.next()) {	if (m_PrEvents.current()->uid() == ev->uid()) {	    m_PrEvents.remove();	    delete ev;	    return TRUE;	}    }    delete ev;    return FALSE;}bool EventXmlIO::internalUpdateRecord(PimRecord *rec){    PrEvent *ev = (PrEvent *)rec;    for (m_PrEvents.first(); m_PrEvents.current(); m_PrEvents.next()) {	PrEvent *current = m_PrEvents.current();	if (current->uid() == ev->uid()) {	    if ( current != ev ) {		*current = *ev;	    }	    return TRUE;	}    }    return FALSE;}bool EventXmlIO::saveData(){    if ( !QFile::exists( dataFilename() ) || QFile::exists( journalFilename() ) )	needsSave = TRUE;    if (!needsSave)	return TRUE;    if (accessMode() != ReadOnly ) {	if (PimXmlIO::saveData((QList<PimRecord> &)m_PrEvents)) {	    needsSave = FALSE;	    return TRUE;	}    }    return FALSE;}QString EventXmlIO::recordToXml(const PimRecord *p){    const PrEvent *e = (const PrEvent *)p;    QMap<int,QString> data = p->fields();    bool hasAlarm = e->hasAlarm();    bool hasRepeat = e->hasRepeat();    bool isException = e->isException();    bool hasException = e->hasExceptions();    const QMap<int,QCString> keyToIdentifier = PimEvent::keyToIdentifierMap();    QString out;    for ( QMap<int, QString>::ConstIterator fit = data.begin();	    fit != data.end(); ++fit ) {	int key = fit.key();	if ( !hasAlarm && ( key == PimEvent::HasAlarm || key == PimEvent::SoundType || key == PimEvent::AlarmDelay) )	    continue;	if ( key == PimEvent::SoundType && fit.data() == "silent" ) // No tr ; skip default	    continue;	if ( key == PimEvent::AlarmDelay && fit.data() == "0" ) // skip default	    continue;	if ( !hasRepeat )  {	    if (key == PimEvent::RepeatPattern || key == PimEvent::RepeatWeekdays || key == PimEvent::RepeatFrequency )	    	continue;	    if ( key == PimEvent::RepeatHasEndDate || key == PimEvent::RepeatEndDate )		continue;	}	if ( !isException && key == PimEvent::RecordParent )	    continue;	if ( !hasException && ( key == PimEvent::RecordChildren || key == PimEvent::Exceptions ) )	    continue;	const QString &value = fit.data();	if ( !value.isEmpty() ) {	    QString k = keyToIdentifier[key];	    if ( !k.isEmpty() ) { // else custom		out += k;		out += "=\"" + Qtopia::escapeString(value) + "\" ";	    }	}    }    out += customToXml( p );    return out;}const QList<PrEvent>& EventXmlIO::events(){    ensureDataCurrent();    return m_PrEvents;}PrEvent EventXmlIO::eventForId(const QUuid &u, bool *ok) const{    QListIterator<PrEvent> it(m_PrEvents);    PrEvent *p;    for (; it.current(); ++it ) {	p = *it;	if (u == p->uid()) {	    if (ok)		*ok = TRUE;	    return *p;	}    }    if (ok)	*ok = FALSE;    return PrEvent();}/*! Returns the events between \a from and \a to where \a from and \a to are in local time. */QValueList<Occurrence> EventXmlIO::getOccurrencesInCurrentTZ(const QDate& from, const QDate& to) const{    QValueList<Occurrence> results;    QListIterator<PrEvent> it(m_PrEvents);    for (; it.current(); ++it ) {	PrEvent e(*(it.current()));	QDate date = from.addDays(-1);	int duration = e.start().date().daysTo(e.end().date()) + 1;	bool ok;	date = e.nextOccurrence(date, &ok);	while (ok && date <= to.addDays(1)) {	    // loose check succeed, tight check on TZ now.	    Occurrence o(date, e);	    if (o.startInCurrentTZ().date() <= to && o.endInCurrentTZ() >= from)		results.append(o);	    date = e.nextOccurrence(date.addDays(duration), &ok);	}    }    return results;}QUuid EventXmlIO::addEvent(const PimEvent &event, bool assignUid ){    QUuid u;    if (accessMode() == ReadOnly)	return u;    // Don't add events that will never occur.    if (!event.isValid())	return u;    PrEvent *ev = new PrEvent((const PrEvent &)event);    if ( assignUid || ev->uid().isNull() )	assignNewUid(ev);    u = ev->uid();    if (internalAddRecord(ev)) {	needsSave = TRUE;	if (ev->hasAlarm())	    addEventAlarm(*ev);	updateJournal(*ev, ACTION_ADD);	{#ifndef QT_NO_COP	    QCopEnvelope e("QPE/PIM", "addedEvent(int,PimEvent)");	    e << getpid();	    e << *ev;#endif	}    }    return u;}void EventXmlIO::addException(const QDate &d, const PimEvent &p){    if (accessMode() == ReadOnly)	return;    PrEvent *parent = new PrEvent((const PrEvent &)p);    parent->addException(d);    // don't add empty uid to parent.    //parent->addChildUid(QUuid());    if (!parent->isValid()) {	// apperently this is really a delete of the event.	delete (parent);	removeEvent(p);	return;    }    if (internalUpdateRecord(parent)) {	needsSave = TRUE;	updateJournal(*parent, ACTION_REPLACE);#ifndef QT_NO_COP	{	    QCopEnvelope e("QPE/PIM", "updatedEvent(int,PimEvent)");	    e << getpid();	    e << *parent;	}#endif    }    delete parent;}QUuid EventXmlIO::addException(const QDate &d, const PimEvent &p, const PimEvent& event){    QUuid u;    if (accessMode() == ReadOnly)	return u;    // don't need to check is valid as can't disapear by adding an exception.    PrEvent *parent = new PrEvent((const PrEvent &)p);    PrEvent *ev = new PrEvent((const PrEvent &)event);    assignNewUid(ev);    u = ev->uid();    ev->setParentUid(parent->uid());    parent->addException(d);    parent->addChildUid(ev->uid());    if (internalAddRecord(ev) && internalUpdateRecord(parent)) {	needsSave = TRUE;	if (ev->hasAlarm())	    addEventAlarm(*ev);	updateJournal(*ev, ACTION_ADD);	updateJournal(*parent, ACTION_REPLACE);#ifndef QT_NO_COP	{	    QCopEnvelope e("QPE/PIM", "addedEvent(int,PimEvent)");	    e << getpid();	    e << *ev;	}	{	    QCopEnvelope e("QPE/PIM", "updatedEvent(int,PimEvent)");	    e << getpid();	    e << *parent;	}#endif    }    delete parent;    return u;}void EventXmlIO::removeEvent(const PimEvent &event){    if (accessMode() == ReadOnly)	return;    // in case parent becomes invalid.    PimEvent parent;    PrEvent *ev = new PrEvent((const PrEvent &)event);    if (event.isException()) {	for (m_PrEvents.first(); m_PrEvents.current(); m_PrEvents.next()) {	    if (m_PrEvents.current()->uid() == ev->seriesUid()) {		m_PrEvents.current()->removeChildUid(ev->uid());		if (!m_PrEvents.current()->isValid()) {		    parent = *(m_PrEvents.current());		}	    }	}    }    for (m_PrEvents.first(); m_PrEvents.current(); m_PrEvents.next()) {	if (m_PrEvents.current()->uid() == ev->uid()) {	    if (m_PrEvents.current()->hasAlarm())		delEventAlarm(*(m_PrEvents.current()));	}    }    if (internalRemoveRecord(ev)) {	needsSave = TRUE;	updateJournal(event, ACTION_REMOVE);	{#ifndef QT_NO_COP	    QCopEnvelope e("QPE/PIM", "removedEvent(int,PimEvent)");	    e << getpid();	    e << event;#endif	}    }    if (!parent.uid().isNull()) {	// parent is invalid,	removeEvent(parent);    }}void EventXmlIO::updateEvent(const PimEvent &event){    if (accessMode() == ReadOnly)	return;    if (!event.isValid()) {	// really a remove.	removeEvent(event);	return;    }    PrEvent *ev = new PrEvent((const PrEvent&)event);        for (m_PrEvents.first(); m_PrEvents.current(); m_PrEvents.next()) {	if (m_PrEvents.current()->uid() == ev->uid()) {	    if (m_PrEvents.current()->hasAlarm())		delEventAlarm(*(m_PrEvents.current()));	}    }    if (internalUpdateRecord(ev)) {	needsSave = TRUE;	if (ev->hasAlarm())	    addEventAlarm(*ev);	updateJournal(*ev, ACTION_REPLACE);	{#ifndef QT_NO_COP	    QCopEnvelope e("QPE/PIM", "updatedEvent(int,PimEvent)");	    e << getpid();	    e << *ev;#endif	}    }    delete ev;}void EventXmlIO::ensureDataCurrent(bool forceReload){    if (accessMode() == WriteOnly || ( isDataCurrent() && !forceReload) )	return;    // get rid of all events first    QListIterator<PrEvent> it(m_PrEvents);    for ( ; it.current(); ++it ) {	if ( it.current()->hasAlarm() )	    delEventAlarm( *(it.current()) );    }    m_PrEvents.clear();    loadData();}bool EventXmlIO::nextAlarm( const PrEvent &ev, QDateTime& when, int& warn){    QDateTime now = QDateTime::currentDateTime();    bool ok;    warn = ev.alarmDelay();    // -1 days to make room for timezone shift.    QDate next = ev.nextOccurrence(now.date().addDays(-1), &ok);    while (ok) {	Occurrence o(next, ev);	// only need to check in TZ... want to shift in orig time	if (now <= o.startInCurrentTZ().addSecs(-60*ev.alarmDelay())) {	    when = o.startInCurrentTZ().addSecs(-60*ev.alarmDelay());	    return TRUE;	}	next = ev.nextOccurrence(		next.addDays(ev.start().daysTo(ev.end()) + 1), &ok);    }    return FALSE;}void EventXmlIO::addEventAlarm(const PrEvent &ev){#ifdef Q_WS_QWS    QDateTime when;    int warn;    if (nextAlarm(ev, when, warn)) {	AlarmServer::addAlarm(when, "QPE/Application/datebook",		"alarm(QDateTime,int)", warn);    }#endif}void EventXmlIO::delEventAlarm(const PrEvent &ev){#ifdef Q_WS_QWS    QDateTime when;    int warn;    if ( nextAlarm(ev,when,warn) ) {	AlarmServer::deleteAlarm( when, "QPE/Application/datebook",		"alarm(QDateTime,int)", warn);    }#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -