59
69
#include <QResizeEvent>
60
70
#include <QApplication>
73
using namespace KCalCore;
62
75
using namespace KCal;
78
using namespace Akonadi;
83
ResourceSelector::ResourceSelector(QWidget* parent)
65
85
ResourceSelector::ResourceSelector(AlarmResources* calendar, QWidget* parent)
70
QBoxLayout* topLayout = new QVBoxLayout(this);
71
topLayout->setMargin(KDialog::spacingHint()); // use spacingHint for the margin
73
QLabel* label = new QLabel(i18nc("@title:group", "Calendars"), this);
74
topLayout->addWidget(label, 0, Qt::AlignHCenter);
76
mAlarmType = new KComboBox(this);
77
mAlarmType->addItem(i18nc("@item:inlistbox", "Active Alarms"));
78
mAlarmType->addItem(i18nc("@item:inlistbox", "Archived Alarms"));
79
mAlarmType->addItem(i18nc("@item:inlistbox", "Alarm Templates"));
80
mAlarmType->setFixedHeight(mAlarmType->sizeHint().height());
81
mAlarmType->setWhatsThis(i18nc("@info:whatsthis", "Choose which type of data to show alarm calendars for"));
82
topLayout->addWidget(mAlarmType);
83
// No spacing between combo box and listview.
85
ResourceModel* model = ResourceModel::instance();
86
ResourceFilterModel* filterModel = new ResourceFilterModel(model, this);
87
mListView = new ResourceView(this);
88
mListView->setModel(filterModel);
89
connect(mListView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)), SLOT(selectionChanged()));
90
mListView->setContextMenuPolicy(Qt::CustomContextMenu);
91
connect(mListView, SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(contextMenuRequested(const QPoint&)));
92
mListView->setWhatsThis(i18nc("@info:whatsthis",
93
"List of available calendars of the selected type. The checked state shows whether a calendar "
94
"is enabled (checked) or disabled (unchecked). The default calendar is shown in bold."));
95
topLayout->addWidget(mListView, 1);
96
topLayout->addSpacing(KDialog::spacingHint());
98
PackedLayout* blayout = new PackedLayout(Qt::AlignHCenter);
99
blayout->setMargin(0);
100
blayout->setSpacing(KDialog::spacingHint());
101
topLayout->addLayout(blayout);
103
mAddButton = new QPushButton(i18nc("@action:button", "Add..."), this);
104
mEditButton = new QPushButton(i18nc("@action:button", "Edit..."), this);
105
mDeleteButton = new QPushButton(i18nc("@action:button", "Remove"), this);
106
blayout->addWidget(mAddButton);
107
blayout->addWidget(mEditButton);
108
blayout->addWidget(mDeleteButton);
109
mEditButton->setWhatsThis(i18nc("@info:whatsthis", "Edit the highlighted calendar"));
110
mDeleteButton->setWhatsThis(i18nc("@info:whatsthis", "<para>Remove the highlighted calendar from the list.</para>"
111
"<para>The calendar itself is left intact, and may subsequently be reinstated in the list if desired.</para>"));
112
mEditButton->setDisabled(true);
113
mDeleteButton->setDisabled(true);
114
connect(mAddButton, SIGNAL(clicked()), SLOT(addResource()));
115
connect(mEditButton, SIGNAL(clicked()), SLOT(editResource()));
116
connect(mDeleteButton, SIGNAL(clicked()), SLOT(removeResource()));
118
connect(mCalendar, SIGNAL(resourceStatusChanged(AlarmResource*, AlarmResources::Change)), SLOT(slotStatusChanged(AlarmResource*, AlarmResources::Change)));
120
connect(mAlarmType, SIGNAL(activated(int)), SLOT(alarmTypeSelected()));
121
QTimer::singleShot(0, this, SLOT(alarmTypeSelected()));
123
Preferences::connect(SIGNAL(archivedKeepDaysChanged(int)), this, SLOT(archiveDaysChanged(int)));
93
QBoxLayout* topLayout = new QVBoxLayout(this);
94
topLayout->setMargin(KDialog::spacingHint()); // use spacingHint for the margin
96
QLabel* label = new QLabel(i18nc("@title:group", "Calendars"), this);
97
topLayout->addWidget(label, 0, Qt::AlignHCenter);
99
mAlarmType = new KComboBox(this);
100
mAlarmType->addItem(i18nc("@item:inlistbox", "Active Alarms"));
101
mAlarmType->addItem(i18nc("@item:inlistbox", "Archived Alarms"));
102
mAlarmType->addItem(i18nc("@item:inlistbox", "Alarm Templates"));
103
mAlarmType->setFixedHeight(mAlarmType->sizeHint().height());
104
mAlarmType->setWhatsThis(i18nc("@info:whatsthis", "Choose which type of data to show alarm calendars for"));
105
topLayout->addWidget(mAlarmType);
106
// No spacing between combo box and listview.
109
CollectionFilterCheckListModel* model = new CollectionFilterCheckListModel(this);
110
mListView = new CollectionView(model, this);
112
ResourceModel* model = ResourceModel::instance();
113
ResourceFilterModel* filterModel = new ResourceFilterModel(model, this);
114
mListView = new ResourceView(this);
115
mListView->setModel(filterModel);
117
connect(mListView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)), SLOT(selectionChanged()));
118
mListView->setContextMenuPolicy(Qt::CustomContextMenu);
119
connect(mListView, SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(contextMenuRequested(const QPoint&)));
120
mListView->setWhatsThis(i18nc("@info:whatsthis",
121
"List of available calendars of the selected type. The checked state shows whether a calendar "
122
"is enabled (checked) or disabled (unchecked). The default calendar is shown in bold."));
123
topLayout->addWidget(mListView, 1);
124
topLayout->addSpacing(KDialog::spacingHint());
126
PackedLayout* blayout = new PackedLayout(Qt::AlignHCenter);
127
blayout->setMargin(0);
128
blayout->setSpacing(KDialog::spacingHint());
129
topLayout->addLayout(blayout);
131
mAddButton = new QPushButton(i18nc("@action:button", "Add..."), this);
132
mEditButton = new QPushButton(i18nc("@action:button", "Edit..."), this);
133
mDeleteButton = new QPushButton(i18nc("@action:button", "Remove"), this);
134
blayout->addWidget(mAddButton);
135
blayout->addWidget(mEditButton);
136
blayout->addWidget(mDeleteButton);
137
mEditButton->setWhatsThis(i18nc("@info:whatsthis", "Edit the highlighted calendar"));
138
mDeleteButton->setWhatsThis(i18nc("@info:whatsthis", "<para>Remove the highlighted calendar from the list.</para>"
139
"<para>The calendar itself is left intact, and may subsequently be reinstated in the list if desired.</para>"));
140
mEditButton->setDisabled(true);
141
mDeleteButton->setDisabled(true);
142
connect(mAddButton, SIGNAL(clicked()), SLOT(addResource()));
143
connect(mEditButton, SIGNAL(clicked()), SLOT(editResource()));
144
connect(mDeleteButton, SIGNAL(clicked()), SLOT(removeResource()));
147
connect(AkonadiModel::instance(), SIGNAL(collectionStatusChanged(const Akonadi::Collection&, AkonadiModel::Change, const QVariant&)),
148
SLOT(slotStatusChanged(const Akonadi::Collection&, AkonadiModel::Change, const QVariant&)));
149
connect(AkonadiModel::instance(), SIGNAL(collectionAdded(Akonadi::AgentInstanceCreateJob*, bool)),
150
SLOT(resourceAdded(Akonadi::AgentInstanceCreateJob*, bool)));
151
connect(AkonadiModel::instance(), SIGNAL(collectionAdded(const Akonadi::Collection&)),
152
SLOT(slotCollectionAdded(const Akonadi::Collection&)));
154
connect(mCalendar, SIGNAL(resourceStatusChanged(AlarmResource*, AlarmResources::Change)), SLOT(slotStatusChanged(AlarmResource*, AlarmResources::Change)));
157
connect(mAlarmType, SIGNAL(activated(int)), SLOT(alarmTypeSelected()));
158
QTimer::singleShot(0, this, SLOT(alarmTypeSelected()));
160
Preferences::connect(SIGNAL(archivedKeepDaysChanged(int)), this, SLOT(archiveDaysChanged(int)));
126
163
/******************************************************************************
129
166
* add appropriate whatsThis texts to the list and to the Add button.
131
168
void ResourceSelector::alarmTypeSelected()
134
switch (mAlarmType->currentIndex())
137
mCurrentAlarmType = AlarmResource::ACTIVE;
138
addTip = i18nc("@info:tooltip", "Add a new active alarm calendar");
141
mCurrentAlarmType = AlarmResource::ARCHIVED;
142
addTip = i18nc("@info:tooltip", "Add a new archived alarm calendar");
145
mCurrentAlarmType = AlarmResource::TEMPLATE;
146
addTip = i18nc("@info:tooltip", "Add a new alarm template calendar");
149
// WORKAROUND: Switch scroll bars off to avoid crash (see explanation
150
// in reinstateAlarmTypeScrollBars() description).
151
mListView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
152
mListView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
153
static_cast<ResourceFilterModel*>(mListView->model())->setFilter(mCurrentAlarmType);
154
mAddButton->setWhatsThis(addTip);
155
mAddButton->setToolTip(addTip);
156
// WORKAROUND: Switch scroll bars back on after allowing geometry to update ...
157
QTimer::singleShot(0, this, SLOT(reinstateAlarmTypeScrollBars()));
171
switch (mAlarmType->currentIndex())
174
mCurrentAlarmType = KAlarm::CalEvent::ACTIVE;
175
addTip = i18nc("@info:tooltip", "Add a new active alarm calendar");
178
mCurrentAlarmType = KAlarm::CalEvent::ARCHIVED;
179
addTip = i18nc("@info:tooltip", "Add a new archived alarm calendar");
182
mCurrentAlarmType = KAlarm::CalEvent::TEMPLATE;
183
addTip = i18nc("@info:tooltip", "Add a new alarm template calendar");
186
// WORKAROUND: Switch scroll bars off to avoid crash (see explanation
187
// in reinstateAlarmTypeScrollBars() description).
188
mListView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
189
mListView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
191
mListView->collectionModel()->setEventTypeFilter(mCurrentAlarmType);
193
static_cast<ResourceFilterModel*>(mListView->model())->setFilter(mCurrentAlarmType);
195
mAddButton->setWhatsThis(addTip);
196
mAddButton->setToolTip(addTip);
197
// WORKAROUND: Switch scroll bars back on after allowing geometry to update ...
198
QTimer::singleShot(0, this, SLOT(reinstateAlarmTypeScrollBars()));
160
201
/******************************************************************************
182
223
void ResourceSelector::addResource()
184
AlarmResourceManager* manager = mCalendar->resourceManager();
185
QStringList descs = manager->resourceTypeDescriptions();
187
QString desc = KInputDialog::getItem(i18nc("@title:window", "Calendar Configuration"),
188
i18nc("@info", "Select storage type of new calendar:"), descs, 0, false, &ok, this);
189
if (!ok || descs.isEmpty())
191
QString type = manager->resourceTypeNames()[descs.indexOf(desc)];
192
AlarmResource* resource = dynamic_cast<AlarmResource*>(manager->createResource(type));
195
KMessageBox::error(this, i18nc("@info", "Unable to create calendar of type <resource>%1</resource>.", type));
198
resource->setResourceName(i18nc("@info/plain", "%1 calendar", type));
199
resource->setAlarmType(mCurrentAlarmType);
200
resource->setActive(false); // prevent setReadOnly() declaring it as unwritable before we've tried to load it
202
// Use AutoQPointer to guard against crash on application exit while
203
// the dialogue is still open. It prevents double deletion (both on
204
// deletion of ResourceSelector, and on return from this function).
205
AutoQPointer<ResourceConfigDialog> dlg = new ResourceConfigDialog(this, resource);
206
if (dlg->exec() == QDialog::Accepted)
208
resource->setEnabled(true);
209
resource->setTimeSpec(Preferences::timeZone());
210
manager->add(resource);
211
manager->writeConfig();
212
mCalendar->resourceAdded(resource); // load the resource and connect in-process change signals
226
AgentInstanceCreateJob* job = AkonadiModel::instance()->addCollection(mCurrentAlarmType, this);
230
AlarmResourceManager* manager = mCalendar->resourceManager();
231
QStringList descs = manager->resourceTypeDescriptions();
233
QString desc = KInputDialog::getItem(i18nc("@title:window", "Calendar Configuration"),
234
i18nc("@info", "Select storage type of new calendar:"), descs, 0, false, &ok, this);
235
if (!ok || descs.isEmpty())
237
QString type = manager->resourceTypeNames()[descs.indexOf(desc)];
238
AlarmResource* resource = dynamic_cast<AlarmResource*>(manager->createResource(type));
241
KMessageBox::error(this, i18nc("@info", "Unable to create calendar of type <resource>%1</resource>.", type));
244
resource->setResourceName(i18nc("@info/plain", "%1 calendar", type));
245
resource->setAlarmType(mCurrentAlarmType);
246
resource->setActive(false); // prevent setReadOnly() declaring it as unwritable before we've tried to load it
248
// Use AutoQPointer to guard against crash on application exit while
249
// the dialogue is still open. It prevents double deletion (both on
250
// deletion of ResourceSelector, and on return from this function).
251
AutoQPointer<ResourceConfigDialog> dlg = new ResourceConfigDialog(this, resource);
252
if (dlg->exec() == QDialog::Accepted)
254
resource->setEnabled(true);
255
resource->setTimeSpec(Preferences::timeZone());
256
manager->add(resource);
257
manager->writeConfig();
258
mCalendar->resourceAdded(resource); // load the resource and connect in-process change signals
269
/******************************************************************************
270
* Called when the job started by AkonadiModel::addCollection() has completed.
272
void ResourceSelector::resourceAdded(AgentInstanceCreateJob* job, bool success)
274
int i = mAddJobs.indexOf(job);
277
// The agent has been created by addResource().
280
AgentInstance agent = job->instance();
283
// Note that we're expecting the agent's Collection to be added
287
mAddJobs.removeAt(i);
291
/******************************************************************************
292
* Called when a collection is added to the AkonadiModel.
294
void ResourceSelector::slotCollectionAdded(const Collection& collection)
296
if (collection.isValid())
298
AgentInstance agent = AgentManager::self()->instance(collection.resource());
301
int i = mAddAgents.indexOf(agent);
304
// The collection belongs to an agent created by addResource()
305
KAlarm::CalEvent::Types types = KAlarm::CalEvent::types(collection.contentMimeTypes());
306
CollectionControlModel::setEnabled(collection, types, true);
307
if (!(types & mCurrentAlarmType))
309
// The user has selected alarm types for the resource
310
// which don't include the currently displayed type.
311
// Show a collection list which includes a selected type.
313
if (types & KAlarm::CalEvent::ACTIVE)
315
else if (types & KAlarm::CalEvent::ARCHIVED)
317
else if (types & KAlarm::CalEvent::TEMPLATE)
321
mAlarmType->setCurrentIndex(index);
325
mAddAgents.removeAt(i);
221
332
/******************************************************************************
222
333
* Edit the currently selected resource.
224
335
void ResourceSelector::editResource()
226
AlarmResource* resource = currentResource();
229
bool readOnly = resource->readOnly();
230
// Use AutoQPointer to guard against crash on application exit while
231
// the dialogue is still open. It prevents double deletion (both on
232
// deletion of ResourceSelector, and on return from this function).
233
AutoQPointer<ResourceConfigDialog> dlg = new ResourceConfigDialog(this, resource);
234
if (dlg->exec() == QDialog::Accepted)
236
// Act on any changed settings.
237
// Read-only is handled automatically by AlarmResource::setReadOnly().
238
if (!readOnly && resource->readOnly() && resource->standardResource())
240
// A standard resource is being made read-only.
241
if (resource->alarmType() == AlarmResource::ACTIVE)
243
KMessageBox::sorry(this, i18nc("@info", "You cannot make your default active alarm calendar read-only."));
244
resource->setReadOnly(false);
246
else if (resource->alarmType() == AlarmResource::ARCHIVED && Preferences::archivedKeepDays())
248
// Only allow the archived alarms standard resource to be made read-only
249
// if we're not saving archived alarms.
250
KMessageBox::sorry(this, i18nc("@info", "You cannot make your default archived alarm calendar "
251
"read-only while expired alarms are configured to be kept."));
252
resource->setReadOnly(false);
254
else if (KMessageBox::warningContinueCancel(this, i18nc("@info", "Do you really want to make your default calendar read-only?"))
255
== KMessageBox::Cancel)
257
resource->setReadOnly(false);
338
Collection collection = currentResource();
339
if (collection.isValid())
341
AgentInstance instance = AgentManager::self()->instance(collection.resource());
342
if (instance.isValid())
343
instance.configure(this);
346
AlarmResource* resource = currentResource();
349
bool readOnly = resource->readOnly();
350
// Use AutoQPointer to guard against crash on application exit while
351
// the dialogue is still open. It prevents double deletion (both on
352
// deletion of ResourceSelector, and on return from this function).
353
AutoQPointer<ResourceConfigDialog> dlg = new ResourceConfigDialog(this, resource);
354
if (dlg->exec() == QDialog::Accepted)
356
// Act on any changed settings.
357
// Read-only is handled automatically by AlarmResource::setReadOnly().
358
if (!readOnly && resource->readOnly() && resource->standardResource())
360
// A standard resource is being made read-only.
361
if (resource->alarmType() == KAlarm::CalEvent::ACTIVE)
363
KMessageBox::sorry(this, i18nc("@info", "You cannot make your default active alarm calendar read-only."));
364
resource->setReadOnly(false);
366
else if (resource->alarmType() == KAlarm::CalEvent::ARCHIVED && Preferences::archivedKeepDays())
368
// Only allow the archived alarms standard resource to be made read-only
369
// if we're not saving archived alarms.
370
KMessageBox::sorry(this, i18nc("@info", "You cannot make your default archived alarm calendar "
371
"read-only while expired alarms are configured to be kept."));
372
resource->setReadOnly(false);
374
else if (KMessageBox::warningContinueCancel(this, i18nc("@info", "Do you really want to make your default calendar read-only?"))
375
== KMessageBox::Cancel)
377
resource->setReadOnly(false);
263
384
/******************************************************************************
266
387
void ResourceSelector::removeResource()
268
AlarmResource* resource = currentResource();
271
bool std = resource->standardResource();
274
// It's the standard resource for its type.
275
if (resource->alarmType() == AlarmResource::ACTIVE)
277
KMessageBox::sorry(this, i18nc("@info", "You cannot remove your default active alarm calendar."));
280
if (resource->alarmType() == AlarmResource::ARCHIVED && Preferences::archivedKeepDays())
282
// Only allow the archived alarms standard resource to be removed if
283
// we're not saving archived alarms.
284
KMessageBox::sorry(this, i18nc("@info", "You cannot remove your default archived alarm calendar "
285
"while expired alarms are configured to be kept."));
289
QString text = std ? i18nc("@info", "Do you really want to remove your default calendar (<resource>%1</resource>) from the list?", resource->resourceName())
290
: i18nc("@info", "Do you really want to remove the calendar <resource>%1</resource> from the list?", resource->resourceName());
291
if (KMessageBox::warningContinueCancel(this, text, "", KStandardGuiItem::remove()) == KMessageBox::Cancel)
390
Collection collection = currentResource();
391
if (!collection.isValid())
393
QString name = collection.name();
394
// Check if it's the standard or only resource for at least one type.
395
KAlarm::CalEvent::Types standardTypes = CollectionControlModel::standardTypes(collection, true);
396
bool std = standardTypes & KAlarm::CalEvent::ALL;
397
KAlarm::CalEvent::Type stdType = (standardTypes & KAlarm::CalEvent::ACTIVE) ? KAlarm::CalEvent::ACTIVE
398
: (standardTypes & KAlarm::CalEvent::ARCHIVED) ? KAlarm::CalEvent::ARCHIVED
399
: KAlarm::CalEvent::EMPTY;
401
AlarmResource* resource = currentResource();
404
QString name = resource->resourceName();
405
bool std = resource->standardResource();
406
// Check if it's the standard resource for its type.
407
KAlarm::CalEvent::Type stdType = std ? resource->alarmType() : KAlarm::CalEvent::EMPTY;
409
if (stdType == KAlarm::CalEvent::ACTIVE)
411
KMessageBox::sorry(this, i18nc("@info", "You cannot remove your default active alarm calendar."));
414
if (stdType == KAlarm::CalEvent::ARCHIVED && Preferences::archivedKeepDays())
416
// Only allow the archived alarms standard resource to be removed if
417
// we're not saving archived alarms.
418
KMessageBox::sorry(this, i18nc("@info", "You cannot remove your default archived alarm calendar "
419
"while expired alarms are configured to be kept."));
423
#warning Akonadi: warn if calendar also contains other alarm types than the current list type
424
#warning Akonadi: Prompt should show default calendar alarm type(s) if other than current list type
426
QString text = std ? i18nc("@info", "Do you really want to remove your default calendar (<resource>%1</resource>) from the list?", name)
427
: i18nc("@info", "Do you really want to remove the calendar <resource>%1</resource> from the list?", name);
428
if (KMessageBox::warningContinueCancel(this, text, "", KStandardGuiItem::remove()) == KMessageBox::Cancel)
294
// Remove resource from alarm and resource lists before deleting it, to avoid
295
// crashes when display updates occur immediately after it is deleted.
296
if (resource->alarmType() == AlarmResource::TEMPLATE)
297
EventListModel::templates()->removeResource(resource);
299
EventListModel::alarms()->removeResource(resource);
300
ResourceModel::instance()->removeResource(resource);
301
AlarmResourceManager* manager = mCalendar->resourceManager();
302
manager->remove(resource);
303
manager->writeConfig();
432
AkonadiModel::instance()->removeCollection(collection);
434
// Remove resource from alarm and resource lists before deleting it, to avoid
435
// crashes when display updates occur immediately after it is deleted.
436
if (resource->alarmType() == KAlarm::CalEvent::TEMPLATE)
437
EventListModel::templates()->removeResource(resource);
439
EventListModel::alarms()->removeResource(resource);
440
ResourceModel::instance()->removeResource(resource);
441
AlarmResourceManager* manager = mCalendar->resourceManager();
442
manager->remove(resource);
443
manager->writeConfig();
306
447
/******************************************************************************
320
461
void ResourceSelector::initActions(KActionCollection* actions)
322
mActionReload = new KAction(KIcon("view-refresh"), i18nc("@action Reload calendar", "Re&load"), this);
323
actions->addAction(QLatin1String("resReload"), mActionReload);
324
connect(mActionReload, SIGNAL(triggered(bool)), SLOT(reloadResource()));
325
mActionSave = new KAction(KIcon("document-save"), i18nc("@action", "&Save"), this);
326
actions->addAction(QLatin1String("resSave"), mActionSave);
327
connect(mActionSave, SIGNAL(triggered(bool)), SLOT(saveResource()));
328
mActionShowDetails = new KAction(KIcon("help-about"), i18nc("@action", "Show &Details"), this);
329
actions->addAction(QLatin1String("resDetails"), mActionShowDetails);
330
connect(mActionShowDetails, SIGNAL(triggered(bool)), SLOT(showInfo()));
331
mActionSetColour = new KAction(KIcon("color-picker"), i18nc("@action", "Set &Color..."), this);
332
actions->addAction(QLatin1String("resSetColour"), mActionSetColour);
333
connect(mActionSetColour, SIGNAL(triggered(bool)), SLOT(setColour()));
334
mActionClearColour = new KAction(i18nc("@action", "Clear C&olor"), this);
335
actions->addAction(QLatin1String("resClearColour"), mActionClearColour);
336
connect(mActionClearColour, SIGNAL(triggered(bool)), SLOT(clearColour()));
337
mActionEdit = new KAction(KIcon("document-properties"), i18nc("@action", "&Edit..."), this);
338
actions->addAction(QLatin1String("resEdit"), mActionEdit);
339
connect(mActionEdit, SIGNAL(triggered(bool)), SLOT(editResource()));
340
mActionRemove = new KAction(KIcon("edit-delete"), i18nc("@action", "&Remove"), this);
341
actions->addAction(QLatin1String("resRemove"), mActionRemove);
342
connect(mActionRemove, SIGNAL(triggered(bool)), SLOT(removeResource()));
343
mActionSetDefault = new KToggleAction(this);
344
actions->addAction(QLatin1String("resDefault"), mActionSetDefault);
345
connect(mActionSetDefault, SIGNAL(triggered(bool)), SLOT(setStandard()));
346
QAction* action = new KAction(KIcon("document-new"), i18nc("@action", "&Add..."), this);
347
actions->addAction(QLatin1String("resAdd"), action);
348
connect(action, SIGNAL(triggered(bool)), SLOT(addResource()));
349
mActionImport = new KAction(i18nc("@action", "Im&port..."), this);
350
actions->addAction(QLatin1String("resImport"), mActionImport);
351
connect(mActionImport, SIGNAL(triggered(bool)), SLOT(importCalendar()));
352
mActionExport = new KAction(i18nc("@action", "E&xport..."), this);
353
actions->addAction(QLatin1String("resExport"), mActionExport);
354
connect(mActionExport, SIGNAL(triggered(bool)), SLOT(exportCalendar()));
463
mActionReload = new KAction(KIcon("view-refresh"), i18nc("@action Reload calendar", "Re&load"), this);
464
actions->addAction(QLatin1String("resReload"), mActionReload);
465
connect(mActionReload, SIGNAL(triggered(bool)), SLOT(reloadResource()));
466
mActionSave = new KAction(KIcon("document-save"), i18nc("@action", "&Save"), this);
467
actions->addAction(QLatin1String("resSave"), mActionSave);
468
connect(mActionSave, SIGNAL(triggered(bool)), SLOT(saveResource()));
469
mActionShowDetails = new KAction(KIcon("help-about"), i18nc("@action", "Show &Details"), this);
470
actions->addAction(QLatin1String("resDetails"), mActionShowDetails);
471
connect(mActionShowDetails, SIGNAL(triggered(bool)), SLOT(showInfo()));
472
mActionSetColour = new KAction(KIcon("color-picker"), i18nc("@action", "Set &Color..."), this);
473
actions->addAction(QLatin1String("resSetColour"), mActionSetColour);
474
connect(mActionSetColour, SIGNAL(triggered(bool)), SLOT(setColour()));
475
mActionClearColour = new KAction(i18nc("@action", "Clear C&olor"), this);
476
actions->addAction(QLatin1String("resClearColour"), mActionClearColour);
477
connect(mActionClearColour, SIGNAL(triggered(bool)), SLOT(clearColour()));
478
mActionEdit = new KAction(KIcon("document-properties"), i18nc("@action", "&Edit..."), this);
479
actions->addAction(QLatin1String("resEdit"), mActionEdit);
480
connect(mActionEdit, SIGNAL(triggered(bool)), SLOT(editResource()));
481
mActionRemove = new KAction(KIcon("edit-delete"), i18nc("@action", "&Remove"), this);
482
actions->addAction(QLatin1String("resRemove"), mActionRemove);
483
connect(mActionRemove, SIGNAL(triggered(bool)), SLOT(removeResource()));
484
mActionSetDefault = new KToggleAction(this);
485
actions->addAction(QLatin1String("resDefault"), mActionSetDefault);
486
connect(mActionSetDefault, SIGNAL(triggered(bool)), SLOT(setStandard()));
487
QAction* action = new KAction(KIcon("document-new"), i18nc("@action", "&Add..."), this);
488
actions->addAction(QLatin1String("resAdd"), action);
489
connect(action, SIGNAL(triggered(bool)), SLOT(addResource()));
490
mActionImport = new KAction(i18nc("@action", "Im&port..."), this);
491
actions->addAction(QLatin1String("resImport"), mActionImport);
492
connect(mActionImport, SIGNAL(triggered(bool)), SLOT(importCalendar()));
493
mActionExport = new KAction(i18nc("@action", "E&xport..."), this);
494
actions->addAction(QLatin1String("resExport"), mActionExport);
495
connect(mActionExport, SIGNAL(triggered(bool)), SLOT(exportCalendar()));
357
498
void ResourceSelector::setContextMenu(KMenu* menu)
362
503
/******************************************************************************
363
* Display the context menu for the selected resource.
504
* Display the context menu for the selected calendar.
365
506
void ResourceSelector::contextMenuRequested(const QPoint& viewportPos)
370
bool writable = false;
372
AlarmResource* resource = 0;
373
if (mListView->selectionModel()->hasSelection())
375
QModelIndex index = mListView->indexAt(viewportPos);
377
resource = static_cast<ResourceFilterModel*>(mListView->model())->resource(index);
379
mListView->clearSelection();
383
active = resource->isEnabled();
384
type = resource->alarmType();
385
writable = resource->writable();
389
switch (mAlarmType->currentIndex())
391
case 0: type = AlarmResource::ACTIVE; break;
392
case 1: type = AlarmResource::ARCHIVED; break;
393
case 2: type = AlarmResource::TEMPLATE; break;
396
mActionReload->setEnabled(active);
397
mActionSave->setEnabled(active && writable);
398
mActionShowDetails->setEnabled(resource);
399
mActionSetColour->setEnabled(resource);
400
mActionClearColour->setEnabled(resource);
401
mActionClearColour->setVisible(resource && resource->colour().isValid());
402
mActionEdit->setEnabled(resource);
403
mActionRemove->setEnabled(resource);
404
mActionImport->setEnabled(active && writable);
405
mActionExport->setEnabled(active);
409
case AlarmResource::ACTIVE: text = i18nc("@action", "Use as &Default for Active Alarms"); break;
410
case AlarmResource::ARCHIVED: text = i18nc("@action", "Use as &Default for Archived Alarms"); break;
411
case AlarmResource::TEMPLATE: text = i18nc("@action", "Use as &Default for Alarm Templates"); break;
414
mActionSetDefault->setText(text);
415
bool standard = (resource && resource == mCalendar->getStandardResource(static_cast<AlarmResource::Type>(type)) && resource->standardResource());
416
mActionSetDefault->setChecked(active && writable && standard);
417
bool allowChange = (type == AlarmResource::ARCHIVED && !Preferences::archivedKeepDays());
418
mActionSetDefault->setEnabled(active && writable && (!standard || allowChange));
419
mContextMenu->popup(mListView->viewport()->mapToGlobal(viewportPos));
511
bool writable = false;
513
Collection collection;
515
AlarmResource* resource = 0;
517
if (mListView->selectionModel()->hasSelection())
519
QModelIndex index = mListView->indexAt(viewportPos);
522
collection = mListView->collectionModel()->collection(index);
524
resource = static_cast<ResourceFilterModel*>(mListView->model())->resource(index);
527
mListView->clearSelection();
529
KAlarm::CalEvent::Type type = currentResourceType();
531
bool haveCalendar = collection.isValid();
533
bool haveCalendar = resource;
538
active = CollectionControlModel::isEnabled(collection, type);
539
writable = CollectionControlModel::isWritable(collection, type);
540
if (!(AkonadiModel::instance()->types(collection) & type))
541
type = KAlarm::CalEvent::EMPTY;
543
active = resource->isEnabled();
544
type = resource->alarmType();
545
writable = resource->writable();
548
mActionReload->setEnabled(active);
549
mActionSave->setEnabled(active && writable);
550
mActionShowDetails->setEnabled(haveCalendar);
551
mActionSetColour->setEnabled(haveCalendar);
552
mActionClearColour->setEnabled(haveCalendar);
554
mActionClearColour->setVisible(AkonadiModel::instance()->backgroundColor(collection).isValid());
556
mActionClearColour->setVisible(resource && resource->colour().isValid());
558
mActionEdit->setEnabled(haveCalendar);
559
mActionRemove->setEnabled(haveCalendar);
560
mActionImport->setEnabled(active && writable);
561
mActionExport->setEnabled(active);
565
case KAlarm::CalEvent::ACTIVE: text = i18nc("@action", "Use as &Default for Active Alarms"); break;
566
case KAlarm::CalEvent::ARCHIVED: text = i18nc("@action", "Use as &Default for Archived Alarms"); break;
567
case KAlarm::CalEvent::TEMPLATE: text = i18nc("@action", "Use as &Default for Alarm Templates"); break;
570
mActionSetDefault->setText(text);
572
bool standard = CollectionControlModel::isStandard(collection, type);
574
bool standard = (resource && resource == mCalendar->getStandardResource(static_cast<KAlarm::CalEvent::Type>(type)) && resource->standardResource());
576
mActionSetDefault->setChecked(active && writable && standard);
577
mActionSetDefault->setEnabled(active && writable);
578
mContextMenu->popup(mListView->viewport()->mapToGlobal(viewportPos));
422
581
/******************************************************************************
462
642
void ResourceSelector::setStandard()
464
AlarmResource* resource = currentResource();
467
if (mActionSetDefault->isChecked())
469
resource->setEnabled(true);
470
mCalendar->setStandardResource(resource);
473
resource->setStandardResource(false);
645
Collection collection = currentResource();
646
if (collection.isValid())
648
KAlarm::CalEvent::Type alarmType = currentResourceType();
649
bool standard = mActionSetDefault->isChecked();
651
CollectionControlModel::setEnabled(collection, alarmType, true);
652
CollectionControlModel::setStandard(collection, alarmType, standard);
655
AlarmResource* resource = currentResource();
658
if (mActionSetDefault->isChecked())
660
resource->setEnabled(true);
661
mCalendar->setStandardResource(resource);
664
resource->setStandardResource(false);
477
669
/******************************************************************************
478
* Called when a resource status has changed.
670
* Called when a calendar status has changed.
673
void ResourceSelector::slotStatusChanged(const Collection& collection, AkonadiModel::Change change, const QVariant& value)
480
675
void ResourceSelector::slotStatusChanged(AlarmResource* resource, AlarmResources::Change change)
482
if (change == AlarmResources::WrongType && resource->isWrongAlarmType())
485
switch (resource->alarmType())
487
case AlarmResource::ACTIVE:
488
text = i18nc("@info/plain", "It is not an active alarm calendar.");
490
case AlarmResource::ARCHIVED:
491
text = i18nc("@info/plain", "It is not an archived alarm calendar.");
493
case AlarmResource::TEMPLATE:
494
text = i18nc("@info/plain", "It is not an alarm template calendar.");
499
KMessageBox::sorry(this, i18nc("@info", "<para>Calendar <resource>%1</resource> has been disabled:</para><para>%2</para>", resource->resourceName(), text));
679
if (change == AlarmResources::WrongType && resource->isWrongAlarmType())
682
switch (resource->alarmType())
684
case KAlarm::CalEvent::ACTIVE:
685
text = i18nc("@info/plain", "It is not an active alarm calendar.");
687
case KAlarm::CalEvent::ARCHIVED:
688
text = i18nc("@info/plain", "It is not an archived alarm calendar.");
690
case KAlarm::CalEvent::TEMPLATE:
691
text = i18nc("@info/plain", "It is not an alarm template calendar.");
696
KMessageBox::sorry(this, i18nc("@info", "<para>Calendar <resource>%1</resource> has been disabled:</para><para>%2</para>", resource->resourceName(), text));
503
701
/******************************************************************************
553
779
void ResourceSelector::showInfo()
555
AlarmResource* resource = currentResource();
557
KMessageBox::information(this, resource->infoText());
782
Collection collection = currentResource();
783
if (collection.isValid())
785
QString id = collection.name();
787
if (collection.hasAttribute<EntityDisplayAttribute>())
788
name = collection.attribute<EntityDisplayAttribute>()->displayName();
789
KAlarm::CalEvent::Type alarmType = currentResourceType();
790
QString calType = AgentManager::self()->instance(collection.resource()).type().name();
791
QString storage = AkonadiModel::instance()->storageType(collection);
792
QString location = collection.remoteId();
794
if (url.isLocalFile())
795
location = url.path();
796
QString perms = CollectionControlModel::isWritable(collection, alarmType, true)
797
? i18nc("@info/plain", "Read-write")
798
: i18nc("@info/plain", "Read-only");
799
bool wrongAlarmType = false; //(applies only to resourcelocaldir)
800
QString enabled = CollectionControlModel::isEnabled(collection, alarmType)
801
? i18nc("@info/plain", "Enabled")
802
: wrongAlarmType ? i18nc("@info/plain", "Disabled (wrong alarm type)")
803
: i18nc("@info/plain", "Disabled");
804
QString std = CollectionControlModel::isStandard(collection, alarmType)
805
? i18nc("@info/plain Parameter in 'Default calendar: Yes/No'", "Yes")
806
: i18nc("@info/plain Parameter in 'Default calendar: Yes/No'", "No");
807
QString text = (name.isEmpty() || name == id)
811
"%3: <filename>%4</filename><nl/>"
812
"Permissions: %5<nl/>"
814
"Default calendar: %7</para>",
815
id, calType, storage, location, perms, enabled, std)
820
"%4: <filename>%5</filename><nl/>"
821
"Permissions: %6<nl/>"
823
"Default calendar: %8</para>",
824
name, id, calType, storage, location, perms, enabled, std);
825
// Display the collection information. Because the user requested
826
// the information, don't raise a KNotify event.
827
KMessageBox::information(this, text, QString(), QString(), 0);
830
AlarmResource* resource = currentResource();
833
// Display the collection information. Because the user requested
834
// the information, don't raise a KNotify event.
835
KMessageBox::information(this, resource->infoText(), QString(), QString(), 0);
560
840
/******************************************************************************
561
841
* Return the currently selected resource in the list.
844
Collection ResourceSelector::currentResource() const
846
return mListView->collection(mListView->selectionModel()->currentIndex());
563
849
AlarmResource* ResourceSelector::currentResource() const
565
return mListView->resource(mListView->selectionModel()->currentIndex());
851
return mListView->resource(mListView->selectionModel()->currentIndex());
855
/******************************************************************************
856
* Return the currently selected resource type.
858
KAlarm::CalEvent::Type ResourceSelector::currentResourceType() const
860
switch (mAlarmType->currentIndex())
862
case 0: return KAlarm::CalEvent::ACTIVE;
863
case 1: return KAlarm::CalEvent::ARCHIVED;
864
case 2: return KAlarm::CalEvent::TEMPLATE;
865
default: return KAlarm::CalEvent::EMPTY;
568
869
void ResourceSelector::resizeEvent(QResizeEvent* re)
570
emit resized(re->oldSize(), re->size());
871
emit resized(re->oldSize(), re->size());