File indexing completed on 2024-05-12 05:14:57

0001 /*
0002  *  resourceselector.cpp  -  calendar resource selection widget
0003  *  Program:  kalarm
0004  *  SPDX-FileCopyrightText: 2006-2022 David Jarvie <djarvie@kde.org>
0005  *  Based on KOrganizer's ResourceView class and KAddressBook's ResourceSelection class,
0006  *  SPDX-FileCopyrightText: 2003, 2004 Cornelius Schumacher <schumacher@kde.org>
0007  *  SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
0008  *  SPDX-FileCopyrightText: 2004 Tobias Koenig <tokoe@kde.org>
0009  *
0010  *  SPDX-License-Identifier: GPL-2.0-or-later
0011  */
0012 
0013 #include "resourceselector.h"
0014 
0015 #include "functions.h"
0016 #include "kalarmapp.h"
0017 #include "mainwindow.h"
0018 #include "preferences.h"
0019 #include "resourcescalendar.h"
0020 #include "resources/datamodel.h"
0021 #include "resources/resourcecreator.h"
0022 #include "resources/resourcedatamodelbase.h"
0023 #include "resources/resourcemodel.h"
0024 #include "resources/resources.h"
0025 #include "lib/messagebox.h"
0026 #include "lib/packedlayout.h"
0027 #include "kalarm_debug.h"
0028 
0029 #include <KLocalizedString>
0030 #include <KActionCollection>
0031 #include <KToggleAction>
0032 
0033 #include <QAction>
0034 #include <QLabel>
0035 #include <QPushButton>
0036 #include <QTimer>
0037 #include <QResizeEvent>
0038 #include <QApplication>
0039 #include <QColorDialog>
0040 #include <QComboBox>
0041 #include <QMenu>
0042 
0043 
0044 ResourceSelector::ResourceSelector(MainWindow* parentWindow, QWidget* parent)
0045     : QFrame(parent)
0046     , mMainWindow(parentWindow)
0047 {
0048     QBoxLayout* topLayout = new QVBoxLayout(this);
0049 
0050     QLabel* label = new QLabel(i18nc("@title:group", "Calendars"), this);
0051     topLayout->addWidget(label, 0, Qt::AlignHCenter);
0052 
0053     mAlarmType = new QComboBox(this);
0054     mAlarmType->addItem(i18nc("@item:inlistbox", "Active Alarms"));
0055     mAlarmType->addItem(i18nc("@item:inlistbox", "Archived Alarms"));
0056     mAlarmType->addItem(i18nc("@item:inlistbox", "Alarm Templates"));
0057     mAlarmType->setWhatsThis(i18nc("@info:whatsthis", "Choose which type of data to show alarm calendars for"));
0058     topLayout->addWidget(mAlarmType);
0059     // No spacing between combo box and listview.
0060 
0061     ResourceFilterCheckListModel* model = DataModel::createResourceFilterCheckListModel(this);
0062     mListView = new ResourceView(model, this);
0063     connect(mListView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ResourceSelector::selectionChanged);
0064     mListView->setContextMenuPolicy(Qt::CustomContextMenu);
0065     connect(mListView, &ResourceView::customContextMenuRequested, this, &ResourceSelector::contextMenuRequested);
0066     connect(mListView, &ResourceView::rowCountChanged, this, &ResourceSelector::resizeToList);
0067     mListView->setWhatsThis(i18nc("@info:whatsthis",
0068                                   "List of available calendars of the selected type. The checked state shows whether a calendar "
0069                                  "is enabled (checked) or disabled (unchecked). The default calendar is shown in bold."));
0070     topLayout->addWidget(mListView, 1);
0071 
0072     PackedLayout* blayout = new PackedLayout(Qt::AlignHCenter);
0073     blayout->setContentsMargins(0, 0, 0, 0);
0074     topLayout->addLayout(blayout);
0075 
0076     mAddButton    = new QPushButton(i18nc("@action:button", "Add..."), this);
0077     mEditButton   = new QPushButton(i18nc("@action:button", "Edit..."), this);
0078     mDeleteButton = new QPushButton(i18nc("@action:button", "Remove"), this);
0079     blayout->addWidget(mAddButton);
0080     blayout->addWidget(mEditButton);
0081     blayout->addWidget(mDeleteButton);
0082     mEditButton->setToolTip(i18nc("@info:tooltip", "Reconfigure the selected calendar"));
0083     mEditButton->setWhatsThis(i18nc("@info:whatsthis", "Edit the highlighted calendar's configuration"));
0084     mDeleteButton->setToolTip(i18nc("@info:tooltip", "Remove the selected calendar from the list"));
0085     mDeleteButton->setWhatsThis(xi18nc("@info:whatsthis", "<para>Remove the highlighted calendar from the list.</para>"
0086                                      "<para>The calendar itself is left intact, and may subsequently be reinstated in the list if desired.</para>"));
0087     mEditButton->setDisabled(true);
0088     mDeleteButton->setDisabled(true);
0089     connect(mAddButton, &QPushButton::clicked, this, &ResourceSelector::addResource);
0090     connect(mEditButton, &QPushButton::clicked, this, &ResourceSelector::editResource);
0091     connect(mDeleteButton, &QPushButton::clicked, this, &ResourceSelector::removeResource);
0092 
0093     connect(mAlarmType, &QComboBox::activated, this, &ResourceSelector::alarmTypeSelected);
0094     QTimer::singleShot(0, this, &ResourceSelector::alarmTypeSelected);   //NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
0095 
0096     Preferences::connect(&Preferences::archivedKeepDaysChanged, this, &ResourceSelector::archiveDaysChanged);
0097 }
0098 
0099 /******************************************************************************
0100 * Called when an alarm type has been selected.
0101 * Filter the resource list to show resources of the selected alarm type, and
0102 * add appropriate whatsThis texts to the list and to the Add button.
0103 */
0104 void ResourceSelector::alarmTypeSelected()
0105 {
0106     QString addTip;
0107     switch (mAlarmType->currentIndex())
0108     {
0109         case 0:
0110             mCurrentAlarmType = CalEvent::ACTIVE;
0111             addTip = i18nc("@info:tooltip", "Add a new active alarm calendar");
0112             break;
0113         case 1:
0114             mCurrentAlarmType = CalEvent::ARCHIVED;
0115             addTip = i18nc("@info:tooltip", "Add a new archived alarm calendar");
0116             break;
0117         case 2:
0118             mCurrentAlarmType = CalEvent::TEMPLATE;
0119             addTip = i18nc("@info:tooltip", "Add a new alarm template calendar");
0120             break;
0121     }
0122     // WORKAROUND: Switch scroll bars off to avoid crash (see explanation
0123     // in reinstateAlarmTypeScrollBars() description).
0124     mListView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0125     mListView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0126     mListView->resourceModel()->setEventTypeFilter(mCurrentAlarmType);
0127     mAddButton->setWhatsThis(addTip);
0128     mAddButton->setToolTip(addTip);
0129     // WORKAROUND: Switch scroll bars back on after allowing geometry to update ...
0130     QTimer::singleShot(0, this, &ResourceSelector::reinstateAlarmTypeScrollBars);   //NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks)
0131 
0132     selectionChanged();   // enable/disable buttons
0133 }
0134 
0135 /******************************************************************************
0136 * WORKAROUND for crash due to presumed Qt bug.
0137 * Switch scroll bars off. This is to avoid a crash which can very occasionally
0138 * happen when changing from a list of calendars which requires vertical scroll
0139 * bars, to a list whose text is very slightly wider but which doesn't require
0140 * scroll bars at all. (The suspicion is that the width is such that it would
0141 * require horizontal scroll bars if the vertical scroll bars were still
0142 * present.) Presumably due to a Qt bug, this can result in a recursive call to
0143 * ResourceView::viewportEvent() with a Resize event.
0144 *
0145 * The crash only occurs if the ResourceSelector happens to have exactly (within
0146 * one pixel) the "right" width to create the crash.
0147 */
0148 void ResourceSelector::reinstateAlarmTypeScrollBars()
0149 {
0150     mListView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0151     mListView->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0152 }
0153 
0154 /******************************************************************************
0155 * Prompt the user for a new resource to add to the list.
0156 */
0157 void ResourceSelector::addResource()
0158 {
0159     ResourceCreator* creator = DataModel::createResourceCreator(mCurrentAlarmType, this);
0160     connect(creator, &ResourceCreator::resourceAdded, this, &ResourceSelector::slotResourceAdded);
0161     creator->createResource();
0162 }
0163 
0164 /******************************************************************************
0165 * Called when a resource is added to the calendar data model, after being
0166 * created by addResource().
0167 */
0168 void ResourceSelector::slotResourceAdded(Resource& resource, CalEvent::Type alarmType)
0169 {
0170     const CalEvent::Types types = resource.alarmTypes();
0171     resource.setEnabled(types);
0172     if (!(types & alarmType))
0173     {
0174         // The user has selected alarm types for the resource which don't
0175         // include the currently displayed type.
0176         // Show a resource list which includes a selected type.
0177         int index = -1;
0178         if (types & CalEvent::ACTIVE)
0179             index = 0;
0180         else if (types & CalEvent::ARCHIVED)
0181             index = 1;
0182         else if (types & CalEvent::TEMPLATE)
0183             index = 2;
0184         if (index >= 0)
0185         {
0186             mAlarmType->setCurrentIndex(index);
0187             alarmTypeSelected();
0188         }
0189     }
0190 }
0191 
0192 /******************************************************************************
0193 * Edit the currently selected resource.
0194 */
0195 void ResourceSelector::editResource()
0196 {
0197     currentResource().editResource(this);
0198 }
0199 
0200 /******************************************************************************
0201 * Update the backend storage format for the currently selected resource in the
0202 * displayed list.
0203 */
0204 void ResourceSelector::updateResource()
0205 {
0206     Resource resource = currentResource();
0207     if (!resource.isValid())
0208         return;
0209     DataModel::updateCalendarToCurrentFormat(resource, true, this);
0210 }
0211 
0212 /******************************************************************************
0213 * Remove the currently selected resource from the displayed list.
0214 */
0215 void ResourceSelector::removeResource()
0216 {
0217     Resource resource = currentResource();
0218     if (!resource.isValid())
0219         return;
0220     qCDebug(KALARM_LOG) << "ResourceSelector::removeResource:" << resource.displayName();
0221     const QString name = resource.displayName();
0222     // Check if it's the standard or only resource for at least one type.
0223     const CalEvent::Types allTypes      = resource.alarmTypes();
0224     const CalEvent::Types standardTypes = Resources::standardTypes(resource, true);
0225     const CalEvent::Type  currentType   = currentResourceType();
0226     const CalEvent::Type  stdType = (standardTypes & CalEvent::ACTIVE)   ? CalEvent::ACTIVE
0227                                   : (standardTypes & CalEvent::ARCHIVED) ? CalEvent::ARCHIVED
0228                                   : CalEvent::EMPTY;
0229     if (stdType == CalEvent::ACTIVE)
0230     {
0231         KAMessageBox::error(this, i18nc("@info", "You cannot remove your default active alarm calendar."));
0232         return;
0233     }
0234     if (stdType == CalEvent::ARCHIVED  &&  Preferences::archivedKeepDays())
0235     {
0236         // Only allow the archived alarms standard resource to be removed if
0237         // we're not saving archived alarms.
0238         KAMessageBox::error(this, i18nc("@info", "You cannot remove your default archived alarm calendar "
0239                                         "while expired alarms are configured to be kept."));
0240         return;
0241     }
0242     QString text;
0243     if (standardTypes)
0244     {
0245         // It's a standard resource for at least one alarm type
0246         if (allTypes != currentType)
0247         {
0248             // It also contains alarm types other than the currently displayed type
0249             const QString stdTypes = ResourceDataModelBase::typeListForDisplay(standardTypes);
0250             QString otherTypes;
0251             const CalEvent::Types nonStandardTypes(allTypes & ~standardTypes);
0252             if (nonStandardTypes != currentType)
0253                 otherTypes = xi18nc("@info", "<para>It also contains:%1</para>", ResourceDataModelBase::typeListForDisplay(nonStandardTypes));
0254             text = xi18nc("@info", "<para><resource>%1</resource> is the default calendar for:%2</para>%3"
0255                                   "<para>Do you really want to remove it from all calendar lists?</para>", name, stdTypes, otherTypes);
0256         }
0257         else
0258             text = xi18nc("@info", "Do you really want to remove your default calendar (<resource>%1</resource>) from the list?", name);
0259     }
0260     else if (allTypes != currentType)
0261         text = xi18nc("@info", "<para><resource>%1</resource> contains:%2</para><para>Do you really want to remove it from all calendar lists?</para>",
0262                      name, ResourceDataModelBase::typeListForDisplay(allTypes));
0263     else
0264         text = xi18nc("@info", "Do you really want to remove the calendar <resource>%1</resource> from the list?", name);
0265     if (KAMessageBox::warningContinueCancel(this, text, QString(), KStandardGuiItem::remove()) == KMessageBox::Cancel)
0266         return;
0267 
0268     resource.removeResource();
0269 }
0270 
0271 /******************************************************************************
0272 * Called when the current selection changes, to enable/disable the
0273 * Delete and Edit buttons accordingly.
0274 */
0275 void ResourceSelector::selectionChanged()
0276 {
0277     bool state = !mListView->selectionModel()->selectedRows().isEmpty();
0278     mDeleteButton->setEnabled(state);
0279     mEditButton->setEnabled(state);
0280 }
0281 
0282 /******************************************************************************
0283 * Initialise the button and context menu actions.
0284 */
0285 void ResourceSelector::initActions(KActionCollection* actions)
0286 {
0287     if (mActionReload)
0288         return;   // this function can only be called once
0289     mActionReload      = new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")), i18nc("@action Reload calendar", "Reload"), this);
0290     actions->addAction(QStringLiteral("resReload"), mActionReload);
0291     connect(mActionReload, &QAction::triggered, this, &ResourceSelector::reloadResource);
0292     mActionShowDetails = new QAction(QIcon::fromTheme(QStringLiteral("help-about")), i18nc("@action", "Show Details"), this);
0293     actions->addAction(QStringLiteral("resDetails"), mActionShowDetails);
0294     connect(mActionShowDetails, &QAction::triggered, this, &ResourceSelector::showInfo);
0295     mActionSetColour   = new QAction(QIcon::fromTheme(QStringLiteral("color-picker")), i18nc("@action", "Set Color..."), this);
0296     actions->addAction(QStringLiteral("resSetColour"), mActionSetColour);
0297     connect(mActionSetColour, &QAction::triggered, this, &ResourceSelector::setColour);
0298     mActionClearColour   = new QAction(i18nc("@action", "Clear Color"), this);
0299     actions->addAction(QStringLiteral("resClearColour"), mActionClearColour);
0300     connect(mActionClearColour, &QAction::triggered, this, &ResourceSelector::clearColour);
0301     mActionEdit        = new QAction(QIcon::fromTheme(QStringLiteral("document-properties")), i18nc("@action", "Edit..."), this);
0302     actions->addAction(QStringLiteral("resEdit"), mActionEdit);
0303     connect(mActionEdit, &QAction::triggered, this, &ResourceSelector::editResource);
0304     mActionUpdate      = new QAction(i18nc("@action", "Update Calendar Format"), this);
0305     actions->addAction(QStringLiteral("resUpdate"), mActionUpdate);
0306     connect(mActionUpdate, &QAction::triggered, this, &ResourceSelector::updateResource);
0307     mActionRemove      = new QAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18nc("@action", "Remove"), this);
0308     actions->addAction(QStringLiteral("resRemove"), mActionRemove);
0309     connect(mActionRemove, &QAction::triggered, this, &ResourceSelector::removeResource);
0310     mActionSetDefault  = new KToggleAction(this);
0311     actions->addAction(QStringLiteral("resDefault"), mActionSetDefault);
0312     connect(mActionSetDefault, &KToggleAction::triggered, this, &ResourceSelector::setStandard);
0313     QAction* action    = new QAction(QIcon::fromTheme(QStringLiteral("document-new")), i18nc("@action", "Add..."), this);
0314     actions->addAction(QStringLiteral("resAdd"), action);
0315     connect(action, &QAction::triggered, this, &ResourceSelector::addResource);
0316     mActionImport      = new QAction(i18nc("@action", "Import..."), this);
0317     actions->addAction(QStringLiteral("resImport"), mActionImport);
0318     connect(mActionImport, &QAction::triggered, this, &ResourceSelector::importCalendar);
0319     mActionExport      = new QAction(i18nc("@action", "Export..."), this);
0320     actions->addAction(QStringLiteral("resExport"), mActionExport);
0321     connect(mActionExport, &QAction::triggered, this, &ResourceSelector::exportCalendar);
0322 }
0323 
0324 /******************************************************************************
0325 * Display the context menu for the selected calendar.
0326 */
0327 void ResourceSelector::contextMenuRequested(const QPoint& viewportPos)
0328 {
0329     mContextMenu = mMainWindow->resourceContextMenu();
0330     if (!mContextMenu)
0331         return;
0332     bool active    = false;
0333     bool writable  = false;
0334     bool updatable = false;
0335     Resource resource;
0336     if (mListView->selectionModel()->hasSelection())
0337     {
0338         const QModelIndex index = mListView->indexAt(viewportPos);
0339         if (index.isValid())
0340             resource = mListView->resourceModel()->resource(index);
0341         else
0342             mListView->clearSelection();
0343     }
0344     CalEvent::Type type = currentResourceType();
0345     bool haveCalendar = resource.isValid();
0346     if (haveCalendar)
0347     {
0348         active = resource.isEnabled(type);
0349         const int rw = resource.writableStatus(type);
0350         writable = (rw > 0);
0351         const KACalendar::Compat compatibility = resource.compatibility();
0352         if (!rw
0353         &&  (compatibility & ~KACalendar::Converted)
0354         &&  !(compatibility & ~(KACalendar::Convertible | KACalendar::Converted)))
0355             updatable = true; // the calendar format is convertible to the current KAlarm format
0356         if (!(resource.alarmTypes() & type))
0357             type = CalEvent::EMPTY;
0358     }
0359     mActionReload->setEnabled(active);
0360     mActionShowDetails->setEnabled(haveCalendar);
0361     mActionSetColour->setEnabled(haveCalendar);
0362     mActionClearColour->setEnabled(haveCalendar);
0363     mActionClearColour->setVisible(resource.backgroundColour().isValid());
0364     mActionEdit->setEnabled(haveCalendar);
0365     mActionUpdate->setEnabled(updatable);
0366     mActionRemove->setEnabled(haveCalendar);
0367     mActionImport->setEnabled(active && writable);
0368     mActionExport->setEnabled(active);
0369     QString text;
0370     switch (type)
0371     {
0372         case CalEvent::ACTIVE:   text = i18nc("@action", "Use as Default for Active Alarms");  break;
0373         case CalEvent::ARCHIVED: text = i18nc("@action", "Use as Default for Archived Alarms");  break;
0374         case CalEvent::TEMPLATE: text = i18nc("@action", "Use as Default for Alarm Templates");  break;
0375         default:  break;
0376     }
0377     mActionSetDefault->setText(text);
0378     bool standard = Resources::isStandard(resource, type);
0379     mActionSetDefault->setChecked(active && writable && standard);
0380     mActionSetDefault->setEnabled(active && writable);
0381     mContextMenu->popup(mListView->viewport()->mapToGlobal(viewportPos));
0382 }
0383 
0384 /******************************************************************************
0385 * Called from the context menu to reload the selected resource.
0386 */
0387 void ResourceSelector::reloadResource()
0388 {
0389     Resource resource = currentResource();
0390     if (resource.isValid())
0391         DataModel::reload(resource);
0392 }
0393 
0394 /******************************************************************************
0395 * Called from the context menu to save the selected resource.
0396 */
0397 void ResourceSelector::saveResource()
0398 {
0399     // Save resource is not applicable to Akonadi
0400 }
0401 
0402 /******************************************************************************
0403 * Called when the length of time archived alarms are to be stored changes.
0404 * If expired alarms are now to be stored, this also sets any single archived
0405 * alarm resource to be the default.
0406 */
0407 void ResourceSelector::archiveDaysChanged(int days)
0408 {
0409     if (days)
0410     {
0411         const Resource resource = Resources::getStandard(CalEvent::ARCHIVED, true);
0412         if (resource.isValid())
0413             theApp()->purgeNewArchivedDefault(resource);
0414     }
0415 }
0416 
0417 /******************************************************************************
0418 * Called from the context menu to set the selected resource as the default
0419 * for its alarm type. The resource is automatically made active.
0420 */
0421 void ResourceSelector::setStandard()
0422 {
0423     Resource resource = currentResource();
0424     if (resource.isValid())
0425     {
0426         CalEvent::Type alarmType = currentResourceType();
0427         bool standard = mActionSetDefault->isChecked();
0428         if (standard)
0429             resource.setEnabled(alarmType, true);
0430         Resources::setStandard(resource, alarmType, standard);
0431         if (alarmType == CalEvent::ARCHIVED)
0432             theApp()->purgeNewArchivedDefault(resource);
0433     }
0434 }
0435 
0436 
0437 /******************************************************************************
0438 * Called from the context menu to merge alarms from an external calendar into
0439 * the selected resource (if any).
0440 */
0441 void ResourceSelector::importCalendar()
0442 {
0443     Resource resource = currentResource();
0444     KAlarm::importAlarms(resource, this);
0445 }
0446 
0447 /******************************************************************************
0448 * Called from the context menu to copy the selected resource's alarms to an
0449 * external calendar.
0450 */
0451 void ResourceSelector::exportCalendar()
0452 {
0453     const Resource resource = currentResource();
0454     if (resource.isValid())
0455         KAlarm::exportAlarms(ResourcesCalendar::events(resource), this);
0456 }
0457 
0458 /******************************************************************************
0459 * Called from the context menu to set a colour for the selected resource.
0460 */
0461 void ResourceSelector::setColour()
0462 {
0463     Resource resource = currentResource();
0464     if (resource.isValid())
0465     {
0466         QColor colour = resource.backgroundColour();
0467         if (!colour.isValid())
0468             colour = QApplication::palette().color(QPalette::Base);
0469         colour = QColorDialog::getColor(colour, this);
0470         if (colour.isValid())
0471             resource.setBackgroundColour(colour);
0472     }
0473 }
0474 
0475 /******************************************************************************
0476 * Called from the context menu to clear the display colour for the selected
0477 * resource.
0478 */
0479 void ResourceSelector::clearColour()
0480 {
0481     Resource resource = currentResource();
0482     if (resource.isValid())
0483         resource.setBackgroundColour(QColor());
0484 }
0485 
0486 /******************************************************************************
0487 * Called from the context menu to display information for the selected resource.
0488 */
0489 void ResourceSelector::showInfo()
0490 {
0491     const Resource resource = currentResource();
0492     if (resource.isValid())
0493     {
0494         const QString name             = resource.displayName();
0495         const QString id               = resource.configName();   // resource name
0496         const QString calType          = resource.storageTypeString(true);
0497         const CalEvent::Type alarmType = currentResourceType();
0498         const QString storage          = resource.storageTypeString(false);
0499         const QString location         = resource.displayLocation();
0500         const CalEvent::Types altypes  = resource.alarmTypes();
0501         QStringList alarmTypes;
0502         if (altypes & CalEvent::ACTIVE)
0503             alarmTypes << i18nc("@info", "Active alarms");
0504         if (altypes & CalEvent::ARCHIVED)
0505             alarmTypes << i18nc("@info", "Archived alarms");
0506         if (altypes & CalEvent::TEMPLATE)
0507             alarmTypes << i18nc("@info", "Alarm templates");
0508         const QString alarmTypeString = alarmTypes.join(i18nc("@info List separator", ", "));
0509         QString perms = ResourceDataModelBase::readOnlyTooltip(resource);
0510         if (perms.isEmpty())
0511             perms = i18nc("@info", "Read-write");
0512         const QString enabled = resource.isEnabled(alarmType)
0513                            ? i18nc("@info", "Enabled")
0514                            : i18nc("@info", "Disabled");
0515         const QString std = Resources::isStandard(resource, alarmType)
0516                            ? i18nc("@info Parameter in 'Default calendar: Yes/No'", "Yes")
0517                            : i18nc("@info Parameter in 'Default calendar: Yes/No'", "No");
0518         const QString text = xi18nc("@info",
0519                                     "<title>%1</title>"
0520                                     "<para>ID: %2<nl/>"
0521                                     "Calendar type: %3<nl/>"
0522                                     "Contents: %4<nl/>"
0523                                     "%5: <filename>%6</filename><nl/>"
0524                                     "Permissions: %7<nl/>"
0525                                     "Status: %8<nl/>"
0526                                     "Default calendar: %9</para>",
0527                                     name, id, calType, alarmTypeString, storage, location, perms, enabled, std);
0528         // Display the resource information. Because the user requested
0529         // the information, don't raise a KNotify event.
0530         KAMessageBox::information(this, text, QString(), QString(), KMessageBox::Options());
0531     }
0532 }
0533 
0534 /******************************************************************************
0535 * Return the currently selected resource in the list.
0536 */
0537 Resource ResourceSelector::currentResource() const
0538 {
0539     return mListView->resource(mListView->selectionModel()->currentIndex());
0540 }
0541 
0542 /******************************************************************************
0543 * Return the currently selected resource type.
0544 */
0545 CalEvent::Type ResourceSelector::currentResourceType() const
0546 {
0547     switch (mAlarmType->currentIndex())
0548     {
0549         case 0:  return CalEvent::ACTIVE;
0550         case 1:  return CalEvent::ARCHIVED;
0551         case 2:  return CalEvent::TEMPLATE;
0552         default:  return CalEvent::EMPTY;
0553     }
0554 }
0555 
0556 /******************************************************************************
0557 * Called when the size hint for the list view has changed.
0558 * Resize the list view and this widget to fit the new list view size hint.
0559 */
0560 void ResourceSelector::resizeToList()
0561 {
0562     if (mResizeToList)
0563     {
0564         const int change = mListView->sizeHint().height() - mListView->height();
0565         mListView->resize(mListView->width(), mListView->height() + change);
0566         resize(width(), height() + change);
0567     }
0568 }
0569 
0570 void ResourceSelector::resizeEvent(QResizeEvent* re)
0571 {
0572     Q_EMIT resized(re->oldSize(), re->size());
0573 }
0574 
0575 #include "moc_resourceselector.cpp"
0576 
0577 // vim: et sw=4: