mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-24 10:52:52 +00:00
829 lines
26 KiB
C++
829 lines
26 KiB
C++
![]() |
/*
|
||
|
* alarmresources.cpp - alarm calendar resources
|
||
|
* Program: kalarm
|
||
|
* Copyright © 2006-2011 by David Jarvie <djarvie@kde.org>
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation; either version 2 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License along
|
||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
#include "kalarm.h"
|
||
|
|
||
|
#include "alarmresource.h"
|
||
|
#include "resourcelocal.h"
|
||
|
#include "resourceremote.h"
|
||
|
#include "alarmresources.moc"
|
||
|
|
||
|
#include <kalarmcal/kacalendar.h>
|
||
|
|
||
|
#include <kresources/selectdialog.h>
|
||
|
#include <kcal/calformat.h>
|
||
|
#include <kcal/event.h>
|
||
|
|
||
|
#include <kconfiggroup.h>
|
||
|
#include <kstandarddirs.h>
|
||
|
#include <klocale.h>
|
||
|
#include <kapplication.h>
|
||
|
#include <kurl.h>
|
||
|
#include <kdebug.h>
|
||
|
|
||
|
using namespace KCal;
|
||
|
using namespace KAlarmCal;
|
||
|
|
||
|
AlarmResources* AlarmResources::mInstance = 0;
|
||
|
QString AlarmResources::mReservedFile;
|
||
|
QString AlarmResources::mConstructionError;
|
||
|
|
||
|
AlarmResources* AlarmResources::create(const KDateTime::Spec& timeSpec, bool activeOnly, bool passiveClient)
|
||
|
{
|
||
|
if (!mInstance)
|
||
|
{
|
||
|
AlarmResources* cal = new AlarmResources(timeSpec, activeOnly, passiveClient);
|
||
|
if (!mConstructionError.isEmpty())
|
||
|
delete cal;
|
||
|
else
|
||
|
mInstance = cal;
|
||
|
}
|
||
|
return mInstance;
|
||
|
}
|
||
|
|
||
|
AlarmResources::AlarmResources(const KDateTime::Spec& timeSpec, bool activeOnly, bool passiveClient)
|
||
|
: Calendar(timeSpec),
|
||
|
mActiveOnly(activeOnly),
|
||
|
mPassiveClient(passiveClient),
|
||
|
mNoGui(false),
|
||
|
mAskDestination(false),
|
||
|
mShowProgress(false),
|
||
|
mOpen(false),
|
||
|
mClosing(false)
|
||
|
{
|
||
|
mManager = new AlarmResourceManager(QString::fromLatin1("alarms"));
|
||
|
mManager->addObserver(this);
|
||
|
mAskDestination = true; // prompt the user for a resource every time an alarm is saved
|
||
|
|
||
|
mManager->readConfig(0);
|
||
|
for (AlarmResourceManager::Iterator it = mManager->begin(); it != mManager->end(); ++it)
|
||
|
{
|
||
|
if (!mActiveOnly || (*it)->alarmType() == CalEvent::ACTIVE)
|
||
|
connectResource(*it);
|
||
|
}
|
||
|
|
||
|
if (!mPassiveClient && mManager->isEmpty())
|
||
|
{
|
||
|
KConfigGroup config(KGlobal::config(), "General");
|
||
|
AlarmResource* resource;
|
||
|
resource = addDefaultResource(config, CalEvent::ACTIVE);
|
||
|
setStandardResource(resource);
|
||
|
if (!mActiveOnly)
|
||
|
{
|
||
|
resource = addDefaultResource(config, CalEvent::ARCHIVED);
|
||
|
setStandardResource(resource);
|
||
|
resource = addDefaultResource(config, CalEvent::TEMPLATE);
|
||
|
setStandardResource(resource);
|
||
|
}
|
||
|
|
||
|
#ifndef NDEBUG
|
||
|
kDebug(KARES_DEBUG) << "AlarmResources used:";
|
||
|
for (AlarmResourceManager::Iterator it = mManager->begin(); it != mManager->end(); ++it)
|
||
|
kDebug(KARES_DEBUG) << (*it)->resourceName();
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
AlarmResources::~AlarmResources()
|
||
|
{
|
||
|
kDebug(KARES_DEBUG);
|
||
|
close();
|
||
|
delete mManager;
|
||
|
mManager = 0;
|
||
|
mInstance = 0;
|
||
|
}
|
||
|
|
||
|
void AlarmResources::setNoGui(bool noGui)
|
||
|
{
|
||
|
mNoGui = noGui;
|
||
|
if (mNoGui)
|
||
|
mShowProgress = false;
|
||
|
AlarmResource::setNoGui(mNoGui);
|
||
|
}
|
||
|
|
||
|
AlarmResource* AlarmResources::addDefaultResource(CalEvent::Type type)
|
||
|
{
|
||
|
KConfigGroup config(KGlobal::config(), "General");
|
||
|
return addDefaultResource(config, type);
|
||
|
}
|
||
|
|
||
|
AlarmResource* AlarmResources::addDefaultResource(const KConfigGroup& config, CalEvent::Type type)
|
||
|
{
|
||
|
QString configKey, defaultFile, title;
|
||
|
switch (type)
|
||
|
{
|
||
|
case CalEvent::ACTIVE:
|
||
|
configKey = QString::fromLatin1("Calendar");
|
||
|
defaultFile = QString::fromLatin1("calendar.ics");
|
||
|
title = i18nc("@info/plain", "Active Alarms");
|
||
|
break;
|
||
|
case CalEvent::TEMPLATE:
|
||
|
configKey = QString::fromLatin1("TemplateCalendar");
|
||
|
defaultFile = QString::fromLatin1("template.ics");
|
||
|
title = i18nc("@info/plain", "Alarm Templates");
|
||
|
break;
|
||
|
case CalEvent::ARCHIVED:
|
||
|
configKey = QString::fromLatin1("ExpiredCalendar");
|
||
|
defaultFile = QString::fromLatin1("expired.ics");
|
||
|
title = i18nc("@info/plain", "Archived Alarms");
|
||
|
break;
|
||
|
default:
|
||
|
return 0;
|
||
|
}
|
||
|
AlarmResource* resource = 0;
|
||
|
QString fileName = config.readPathEntry(configKey, QString());
|
||
|
if (!fileName.isEmpty())
|
||
|
{
|
||
|
// Calendar is specified in KAlarm config file
|
||
|
KUrl url(fileName);
|
||
|
if (!url.isValid())
|
||
|
{
|
||
|
kError(KARES_DEBUG) << configKey << ": invalid name:" << fileName;
|
||
|
mConstructionError = i18nc("@info", "%1: invalid calendar file name: <filename>%2</filename>", configKey, fileName);
|
||
|
return 0;
|
||
|
}
|
||
|
if (!url.isLocalFile())
|
||
|
resource = new KAResourceRemote(type, url);
|
||
|
else if (fileName == mReservedFile)
|
||
|
{
|
||
|
kError(KARES_DEBUG) << configKey << ": name not allowed:" << fileName;
|
||
|
mConstructionError = i18nc("@info", "%1: file name not permitted: <filename>%2</filename>", configKey, fileName);
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
resource = new KAResourceLocal(type, url.toLocalFile());
|
||
|
}
|
||
|
if (!resource)
|
||
|
{
|
||
|
// No calendar is specified in config file, or the calendar
|
||
|
// specified is invalid - use default file
|
||
|
fileName = KStandardDirs::locateLocal("appdata", defaultFile);
|
||
|
resource = new KAResourceLocal(type, fileName);
|
||
|
}
|
||
|
|
||
|
resource->setTimeSpec(timeSpec());
|
||
|
resource->setResourceName(title);
|
||
|
resourceManager()->add(resource);
|
||
|
connectResource(resource);
|
||
|
return resource;
|
||
|
}
|
||
|
|
||
|
AlarmResources::Result AlarmResources::addEvent(Event* event, CalEvent::Type type, QWidget* promptParent, bool noPrompt)
|
||
|
{
|
||
|
kDebug(KARES_DEBUG) << event->uid();
|
||
|
bool cancelled;
|
||
|
AlarmResource* resource = destination(type, promptParent, noPrompt, &cancelled);
|
||
|
if (!resource)
|
||
|
{
|
||
|
delete event;
|
||
|
if (cancelled)
|
||
|
return Cancelled;
|
||
|
kDebug(KARES_DEBUG) << "No resource";
|
||
|
return Failed;
|
||
|
}
|
||
|
if (!addEvent(event, resource))
|
||
|
{
|
||
|
kDebug(KARES_DEBUG) << "Failed";
|
||
|
return Failed; // event was deleted by addEvent()
|
||
|
}
|
||
|
return Success;
|
||
|
}
|
||
|
|
||
|
AlarmResource* AlarmResources::getStandardResource(CalEvent::Type type)
|
||
|
{
|
||
|
switch (type)
|
||
|
{
|
||
|
case CalEvent::ACTIVE:
|
||
|
{
|
||
|
AlarmResource* std = mManager->standardResource();
|
||
|
if (std && std->standardResource() && std->alarmType() == CalEvent::ACTIVE && !std->readOnly())
|
||
|
return std;
|
||
|
break;
|
||
|
}
|
||
|
case CalEvent::ARCHIVED:
|
||
|
case CalEvent::TEMPLATE:
|
||
|
if (mActiveOnly)
|
||
|
return 0;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
{
|
||
|
AlarmResource* r = *it;
|
||
|
if (r->alarmType() == type && r->standardResource())
|
||
|
return r;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// There's no nominated default alarm resource of the right type.
|
||
|
// If there's only one read/write alarm resource, use it.
|
||
|
AlarmResource* std = 0;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
{
|
||
|
AlarmResource* r = *it;
|
||
|
if (!r->readOnly() && r->alarmType() == type)
|
||
|
{
|
||
|
if (std)
|
||
|
return 0; // there's more than one candidate
|
||
|
std = r;
|
||
|
}
|
||
|
}
|
||
|
if (std && type == CalEvent::ACTIVE && !mPassiveClient)
|
||
|
setStandardResource(std); // mark it as the standard resource
|
||
|
return std;
|
||
|
}
|
||
|
|
||
|
void AlarmResources::setStandardResource(AlarmResource* resource)
|
||
|
{
|
||
|
if (resource->standardResource())
|
||
|
return; // it's already the standard resource for its alarm type
|
||
|
CalEvent::Type type = resource->alarmType();
|
||
|
bool active = (type == CalEvent::ACTIVE);
|
||
|
for (AlarmResourceManager::Iterator it = mManager->begin(); it != mManager->end(); ++it)
|
||
|
{
|
||
|
AlarmResource* r = *it;
|
||
|
if (r->alarmType() == type && r->standardResource())
|
||
|
{
|
||
|
r->setStandardResource(false);
|
||
|
if (!active && !mPassiveClient)
|
||
|
mManager->change(r); // save resource's new configuration
|
||
|
}
|
||
|
}
|
||
|
resource->setStandardResource(true);
|
||
|
if (active)
|
||
|
{
|
||
|
mManager->setStandardResource(resource);
|
||
|
if (!mPassiveClient)
|
||
|
mManager->writeConfig();
|
||
|
}
|
||
|
else if (!mPassiveClient)
|
||
|
mManager->change(resource); // save resource's new configuration
|
||
|
emit standardResourceChange(type);
|
||
|
}
|
||
|
|
||
|
void AlarmResources::writeConfig()
|
||
|
{
|
||
|
if (!mPassiveClient)
|
||
|
mManager->writeConfig();
|
||
|
}
|
||
|
|
||
|
int AlarmResources::activeCount(CalEvent::Type type, bool writable)
|
||
|
{
|
||
|
int count = 0;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
{
|
||
|
AlarmResource* resource = *it;
|
||
|
if (resource->alarmType() == type
|
||
|
&& (!writable || !resource->readOnly()))
|
||
|
++count;
|
||
|
}
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
AlarmResource* AlarmResources::destination(Incidence* incidence, QWidget* promptParent, bool* cancelled)
|
||
|
{
|
||
|
Event* event = dynamic_cast<Event*>(incidence);
|
||
|
CalEvent::Type type = event ? CalEvent::status(event) : CalEvent::ACTIVE;
|
||
|
return destination(type, promptParent, false, cancelled);
|
||
|
}
|
||
|
|
||
|
AlarmResource* AlarmResources::destination(CalEvent::Type type, QWidget* promptParent, bool noPrompt, bool* cancelled)
|
||
|
{
|
||
|
if (cancelled)
|
||
|
*cancelled = false;
|
||
|
AlarmResource* standard;
|
||
|
switch (type)
|
||
|
{
|
||
|
case CalEvent::ACTIVE:
|
||
|
break;
|
||
|
case CalEvent::TEMPLATE:
|
||
|
if (mActiveOnly)
|
||
|
return 0;
|
||
|
break;
|
||
|
case CalEvent::ARCHIVED:
|
||
|
if (mActiveOnly)
|
||
|
return 0;
|
||
|
// Archived alarms are always saved in the default resource
|
||
|
return getStandardResource(CalEvent::ARCHIVED);
|
||
|
default:
|
||
|
return 0;
|
||
|
}
|
||
|
standard = getStandardResource(type);
|
||
|
if (noPrompt || (!mAskDestination && standard))
|
||
|
return standard;
|
||
|
QList<KRES::Resource*> list;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
{
|
||
|
AlarmResource* resource = *it;
|
||
|
if (!resource->readOnly() && resource->alarmType() == type)
|
||
|
{
|
||
|
// Insert the standard resource at the beginning so as to be the default
|
||
|
if (resource == standard)
|
||
|
list.insert(0, resource);
|
||
|
else
|
||
|
list.append(resource);
|
||
|
}
|
||
|
}
|
||
|
switch (list.count())
|
||
|
{
|
||
|
case 0:
|
||
|
return 0;
|
||
|
case 1:
|
||
|
// return static_cast<AlarmResource*>(list.first());
|
||
|
default:
|
||
|
{
|
||
|
KRES::Resource* r = KRES::SelectDialog::getResource(list, promptParent);
|
||
|
if (!r && cancelled)
|
||
|
*cancelled = true;
|
||
|
return static_cast<AlarmResource*>(r);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int AlarmResources::loadedState(CalEvent::Type type) const
|
||
|
{
|
||
|
if (!mOpen)
|
||
|
return 0;
|
||
|
bool loaded = false;
|
||
|
bool notloaded = false;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
{
|
||
|
AlarmResource* res = *it;
|
||
|
if (res->alarmType() == type)
|
||
|
{
|
||
|
if (res->isLoaded())
|
||
|
{
|
||
|
if (notloaded)
|
||
|
return 1; // some loaded, some not loaded
|
||
|
loaded = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (loaded)
|
||
|
return 1; // some loaded, some not loaded
|
||
|
notloaded = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return !loaded ? 0 : notloaded ? 1 : 2;
|
||
|
}
|
||
|
|
||
|
bool AlarmResources::isLoading(CalEvent::Type type) const
|
||
|
{
|
||
|
if (mOpen)
|
||
|
{
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
{
|
||
|
AlarmResource* res = *it;
|
||
|
if (res->alarmType() == type && res->isLoading())
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void AlarmResources::load(ResourceCached::CacheAction action)
|
||
|
{
|
||
|
kDebug(KARES_DEBUG);
|
||
|
if (!mManager->standardResource())
|
||
|
kDebug(KARES_DEBUG) << "Warning! No standard resource yet.";
|
||
|
|
||
|
// Set the timezone for all resources. Otherwise we'll have those terrible tz troubles ;-((
|
||
|
// Open all active resources
|
||
|
QList<AlarmResource*> failed;
|
||
|
for (AlarmResourceManager::Iterator it = mManager->begin(); it != mManager->end(); ++it)
|
||
|
{
|
||
|
AlarmResource* resource = *it;
|
||
|
if (!mActiveOnly || resource->alarmType() == CalEvent::ACTIVE)
|
||
|
{
|
||
|
resource->setTimeSpec(timeSpec());
|
||
|
if (resource->isActive())
|
||
|
{
|
||
|
if (!load(resource, action))
|
||
|
failed.append(resource);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
for (int i = 0, end = failed.count(); i < end; ++i)
|
||
|
{
|
||
|
failed[i]->setActive(false);
|
||
|
emit signalResourceModified(failed[i]);
|
||
|
}
|
||
|
|
||
|
// Ensure that if there is only one active alarm resource,
|
||
|
// it is marked as the standard resource.
|
||
|
getStandardResource(CalEvent::ACTIVE);
|
||
|
|
||
|
mOpen = true;
|
||
|
}
|
||
|
|
||
|
bool AlarmResources::load(AlarmResource* resource, ResourceCached::CacheAction action)
|
||
|
{
|
||
|
switch (action)
|
||
|
{
|
||
|
case ResourceCached::SyncCache:
|
||
|
case ResourceCached::NoSyncCache:
|
||
|
break;
|
||
|
default:
|
||
|
action = ResourceCached::SyncCache;
|
||
|
break;
|
||
|
}
|
||
|
return resource->load(action);
|
||
|
}
|
||
|
|
||
|
// Called whenever a remote resource download has completed.
|
||
|
void AlarmResources::slotCacheDownloaded(AlarmResource* resource)
|
||
|
{
|
||
|
if (resource->isActive())
|
||
|
emit cacheDownloaded(resource);
|
||
|
}
|
||
|
|
||
|
void AlarmResources::remap(AlarmResource* resource)
|
||
|
{
|
||
|
for (ResourceMap::Iterator it = mResourceMap.begin(); it != mResourceMap.end(); )
|
||
|
{
|
||
|
if (it.value() == resource)
|
||
|
it = mResourceMap.erase(it);
|
||
|
else
|
||
|
++it;
|
||
|
}
|
||
|
Event::List events = resource->rawEvents();
|
||
|
for (int i = 0, end = events.count(); i < end; ++i)
|
||
|
mResourceMap[events[i]] = resource;
|
||
|
}
|
||
|
|
||
|
bool AlarmResources::reload()
|
||
|
{
|
||
|
save();
|
||
|
close();
|
||
|
load();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void AlarmResources::close()
|
||
|
{
|
||
|
if (mOpen && !mClosing)
|
||
|
{
|
||
|
kDebug(KARES_DEBUG);
|
||
|
mClosing = true;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
(*it)->close();
|
||
|
setModified(false);
|
||
|
mOpen = false;
|
||
|
mClosing = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool AlarmResources::save()
|
||
|
{
|
||
|
kDebug(KARES_DEBUG);
|
||
|
if (!mOpen)
|
||
|
return false;
|
||
|
bool saved = false;
|
||
|
if (isModified())
|
||
|
{
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
{
|
||
|
if ((!mActiveOnly || (*it)->alarmType() == CalEvent::ACTIVE)
|
||
|
&& (*it)->hasChanges())
|
||
|
{
|
||
|
kDebug(KARES_DEBUG) << "Saving modified resource" << (*it)->identifier();
|
||
|
(*it)->save();
|
||
|
saved = true;
|
||
|
}
|
||
|
}
|
||
|
setModified(false);
|
||
|
}
|
||
|
if (!saved)
|
||
|
kDebug(KARES_DEBUG) << "No modified resources to save";
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool AlarmResources::isSaving()
|
||
|
{
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
{
|
||
|
if ((*it)->isSaving())
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void AlarmResources::showProgress(bool show)
|
||
|
{
|
||
|
if (show != mShowProgress)
|
||
|
{
|
||
|
mShowProgress = show;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
(*it)->showProgress(show);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool AlarmResources::addEvent(Event* event, AlarmResource* resource)
|
||
|
{
|
||
|
bool validRes = false;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
{
|
||
|
if ((*it) == resource)
|
||
|
validRes = true;
|
||
|
}
|
||
|
AlarmResource* oldResource = mResourceMap.contains(event) ? mResourceMap[event] : 0;
|
||
|
mResourceMap[event] = resource;
|
||
|
if (validRes && resource->addIncidence(event))
|
||
|
{
|
||
|
event->registerObserver(this);
|
||
|
notifyIncidenceAdded(event);
|
||
|
setModified(true);
|
||
|
return true;
|
||
|
}
|
||
|
if (oldResource)
|
||
|
mResourceMap[event] = oldResource;
|
||
|
else
|
||
|
mResourceMap.remove(event);
|
||
|
delete event;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
AlarmResources::Result AlarmResources::addEvent(Event* event, QWidget* promptParent)
|
||
|
{
|
||
|
kDebug(KARES_DEBUG) << this;
|
||
|
bool cancelled;
|
||
|
AlarmResource* resource = destination(event, promptParent, &cancelled);
|
||
|
if (resource)
|
||
|
{
|
||
|
mResourceMap[event] = resource;
|
||
|
if (resource->addIncidence(event))
|
||
|
{
|
||
|
event->registerObserver(this);
|
||
|
notifyIncidenceAdded(event);
|
||
|
mResourceMap[event] = resource;
|
||
|
setModified(true);
|
||
|
return Success;
|
||
|
}
|
||
|
mResourceMap.remove(event);
|
||
|
}
|
||
|
else if (cancelled)
|
||
|
return Cancelled;
|
||
|
else
|
||
|
kDebug(KARES_DEBUG) << "No resource";
|
||
|
return Failed;
|
||
|
}
|
||
|
|
||
|
bool AlarmResources::deleteEvent(Event *event)
|
||
|
{
|
||
|
kDebug(KARES_DEBUG) << event->uid();
|
||
|
bool status = false;
|
||
|
ResourceMap::Iterator rit = mResourceMap.find(event);
|
||
|
if (rit != mResourceMap.end())
|
||
|
{
|
||
|
status = rit.value()->deleteEvent(event);
|
||
|
if (status)
|
||
|
mResourceMap.erase(rit);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
status = (*it)->deleteEvent(event) || status;
|
||
|
}
|
||
|
setModified(status);
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
Event* AlarmResources::event(const QString& uid)
|
||
|
{
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
{
|
||
|
Event* event = (*it)->event(uid);
|
||
|
if (event)
|
||
|
{
|
||
|
mResourceMap[event] = *it;
|
||
|
return event;
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
Alarm::List AlarmResources::alarmsTo(const KDateTime &to)
|
||
|
{
|
||
|
Alarm::List result;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
result += (*it)->alarmsTo(to);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
Alarm::List AlarmResources::alarms(const KDateTime &from, const KDateTime &to)
|
||
|
{
|
||
|
Alarm::List result;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
result += (*it)->alarms(from, to);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
Event::List AlarmResources::rawEventsForDate(const QDate &date, const KDateTime::Spec& timespec, EventSortField sortField, SortDirection sortDirection)
|
||
|
{
|
||
|
Event::List result;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
appendEvents(result, (*it)->rawEventsForDate(date, timespec), *it);
|
||
|
return sortEvents(&result, sortField, sortDirection);
|
||
|
}
|
||
|
|
||
|
Event::List AlarmResources::rawEvents(const QDate& start, const QDate& end, const KDateTime::Spec& timespec, bool inclusive)
|
||
|
{
|
||
|
kDebug(KARES_DEBUG) << "(start,end,inclusive)";
|
||
|
Event::List result;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
appendEvents(result, (*it)->rawEvents(start, end, timespec, inclusive), *it);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
Event::List AlarmResources::rawEventsForDate(const KDateTime& dt)
|
||
|
{
|
||
|
kDebug(KARES_DEBUG) << "(dt)";
|
||
|
Event::List result;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
appendEvents(result, (*it)->rawEventsForDate(dt), *it);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
Event::List AlarmResources::rawEvents(EventSortField sortField, SortDirection sortDirection)
|
||
|
{
|
||
|
kDebug(KARES_DEBUG);
|
||
|
Event::List result;
|
||
|
for (AlarmResourceManager::ActiveIterator it = mManager->activeBegin(); it != mManager->activeEnd(); ++it)
|
||
|
appendEvents(result, (*it)->rawEvents(EventSortUnsorted), *it);
|
||
|
return sortEvents(&result, sortField, sortDirection);
|
||
|
}
|
||
|
|
||
|
Event::List AlarmResources::rawEvents(AlarmResource* resource, EventSortField sortField, SortDirection sortDirection)
|
||
|
{
|
||
|
kDebug(KARES_DEBUG) << "(resource)";
|
||
|
Event::List result;
|
||
|
if (!resource->isActive())
|
||
|
return result;
|
||
|
appendEvents(result, resource->rawEvents(EventSortUnsorted), resource);
|
||
|
return sortEvents(&result, sortField, sortDirection);
|
||
|
}
|
||
|
|
||
|
void AlarmResources::appendEvents(Event::List& result, const Event::List& events, AlarmResource* resource)
|
||
|
{
|
||
|
result += events;
|
||
|
for (int i = 0, end = events.count(); i < end; ++i)
|
||
|
mResourceMap[events[i]] = resource;
|
||
|
}
|
||
|
|
||
|
// Called whenever a resource is added to those managed by the AlarmResources,
|
||
|
// to initialise it and connect its signals.
|
||
|
void AlarmResources::connectResource(AlarmResource* resource)
|
||
|
{
|
||
|
kDebug(KARES_DEBUG) << resource->resourceName();
|
||
|
resource->disconnect(this); // just in case we're called twice
|
||
|
connect(resource, SIGNAL(enabledChanged(AlarmResource*)), SLOT(slotActiveChanged(AlarmResource*)));
|
||
|
connect(resource, SIGNAL(readOnlyChanged(AlarmResource*)), SLOT(slotReadOnlyChanged(AlarmResource*)));
|
||
|
connect(resource, SIGNAL(wrongAlarmTypeChanged(AlarmResource*)), SLOT(slotWrongTypeChanged(AlarmResource*)));
|
||
|
connect(resource, SIGNAL(locationChanged(AlarmResource*)), SLOT(slotLocationChanged(AlarmResource*)));
|
||
|
connect(resource, SIGNAL(colourChanged(AlarmResource*)), SLOT(slotColourChanged(AlarmResource*)));
|
||
|
connect(resource, SIGNAL(invalidate(AlarmResource*)), SLOT(slotResourceInvalidated(AlarmResource*)));
|
||
|
connect(resource, SIGNAL(loaded(AlarmResource*)), SLOT(slotResourceLoaded(AlarmResource*)));
|
||
|
connect(resource, SIGNAL(cacheDownloaded(AlarmResource*)), SLOT(slotCacheDownloaded(AlarmResource*)));
|
||
|
// connect(resource, SIGNAL(downloading(AlarmResource*,ulong)),
|
||
|
// SLOT(slotResourceDownloading(AlarmResource*,ulong)));
|
||
|
connect(resource, SIGNAL(resourceSaved(AlarmResource*)), SLOT(slotResourceSaved(AlarmResource*)));
|
||
|
connect(resource, SIGNAL(resourceChanged(ResourceCalendar*)), SLOT(slotResourceChanged(ResourceCalendar*)));
|
||
|
connect(resource, SIGNAL(resourceLoadError(ResourceCalendar*,QString)),
|
||
|
SLOT(slotLoadError(ResourceCalendar*,QString)));
|
||
|
connect(resource, SIGNAL(resourceSaveError(ResourceCalendar*,QString)),
|
||
|
SLOT(slotSaveError(ResourceCalendar*,QString)));
|
||
|
}
|
||
|
|
||
|
void AlarmResources::slotResourceInvalidated(AlarmResource* resource)
|
||
|
{
|
||
|
emit resourceStatusChanged(resource, Invalidated);
|
||
|
}
|
||
|
|
||
|
void AlarmResources::slotResourceLoaded(AlarmResource* resource)
|
||
|
{
|
||
|
remap(resource);
|
||
|
Incidence::List incidences = resource->rawIncidences();
|
||
|
for (int i = 0, end = incidences.count(); i < end; ++i)
|
||
|
{
|
||
|
incidences[i]->registerObserver(this);
|
||
|
notifyIncidenceAdded(incidences[i]);
|
||
|
}
|
||
|
emit resourceLoaded(resource, resource->isActive());
|
||
|
}
|
||
|
|
||
|
void AlarmResources::slotResourceSaved(AlarmResource* resource)
|
||
|
{
|
||
|
if (resource->isActive())
|
||
|
emit resourceSaved(resource);
|
||
|
}
|
||
|
|
||
|
/*void AlarmResources::slotResourceDownloading(AlarmResource* resource, unsigned long percent)
|
||
|
{
|
||
|
if (resource->isActive())
|
||
|
emit downloading(resource, percent);
|
||
|
}*/
|
||
|
|
||
|
void AlarmResources::slotResourceChanged(ResourceCalendar* resource)
|
||
|
{
|
||
|
if (resource->isActive())
|
||
|
emit calendarChanged();
|
||
|
}
|
||
|
|
||
|
void AlarmResources::slotLoadError(ResourceCalendar* resource, const QString& err)
|
||
|
{
|
||
|
if (resource->isActive())
|
||
|
emit signalErrorMessage(err);
|
||
|
}
|
||
|
|
||
|
void AlarmResources::slotSaveError(ResourceCalendar* resource, const QString& err)
|
||
|
{
|
||
|
if (resource->isActive())
|
||
|
emit signalErrorMessage(err);
|
||
|
}
|
||
|
|
||
|
void AlarmResources::slotResourceStatusChanged(AlarmResource* resource, Change change)
|
||
|
{
|
||
|
kDebug(KARES_DEBUG) << resource->resourceName() << ", " << (change == Added ? "Added" : change == Enabled ? "Enabled" : change == ReadOnly ? "ReadOnly" : change == WrongType ? "WrongType" : change == Location ? "Location" : "Colour");
|
||
|
if (!resource->writable())
|
||
|
{
|
||
|
// The resource is no longer writable, so it can't be a standard resource
|
||
|
// N.B. Setting manager's standard resource to 0 does nothing.
|
||
|
if (resource->standardResource())
|
||
|
resource->setStandardResource(false);
|
||
|
}
|
||
|
if (!mPassiveClient)
|
||
|
mManager->change(resource); // save resource's new configuration
|
||
|
emit resourceStatusChanged(resource, change);
|
||
|
if (change == Location && resource->isActive())
|
||
|
load(resource);
|
||
|
}
|
||
|
|
||
|
AlarmResource* AlarmResources::resourceWithId(const QString& resourceID) const
|
||
|
{
|
||
|
for (AlarmResourceManager::Iterator it = mManager->begin(); it != mManager->end(); ++it)
|
||
|
{
|
||
|
if ((*it)->identifier() == resourceID)
|
||
|
return *it;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
AlarmResource* AlarmResources::resourceForIncidence(const QString& incidenceID)
|
||
|
{
|
||
|
return resource(incidence(incidenceID));
|
||
|
}
|
||
|
|
||
|
AlarmResource* AlarmResources::resource(const Incidence* incidence) const
|
||
|
{
|
||
|
if (!incidence)
|
||
|
return 0;
|
||
|
ResourceMap::ConstIterator it = mResourceMap.find(const_cast<Incidence*>(incidence));
|
||
|
return (it != mResourceMap.constEnd()) ? it.value() : 0;
|
||
|
}
|
||
|
|
||
|
// Called by the resource manager when a resource is added to the collection
|
||
|
void AlarmResources::resourceAdded(AlarmResource* resource)
|
||
|
{
|
||
|
kDebug(KARES_DEBUG) << resource->resourceName();
|
||
|
connectResource(resource);
|
||
|
if (resource->isActive())
|
||
|
load(resource);
|
||
|
emit resourceStatusChanged(resource, Added);
|
||
|
}
|
||
|
|
||
|
void AlarmResources::resourceDeleted(AlarmResource* resource)
|
||
|
{
|
||
|
kDebug(KARES_DEBUG);
|
||
|
emit resourceStatusChanged(resource, Deleted);
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
* Set the time zone for all resources.
|
||
|
*/
|
||
|
void AlarmResources::doSetTimeSpec(const KDateTime::Spec& timeSpec)
|
||
|
{
|
||
|
AlarmResourceManager::Iterator i1;
|
||
|
for (i1 = mManager->begin(); i1 != mManager->end(); ++i1)
|
||
|
(*i1)->setTimeSpec(timeSpec);
|
||
|
}
|
||
|
|
||
|
// vim: et sw=4:
|