File indexing completed on 2024-11-17 04:49:14
0001 /* 0002 This file is part of KOrganizer. 0003 0004 SPDX-FileCopyrightText: 2000, 2001, 2002, 2003 Cornelius Schumacher <schumacher@kde.org> 0005 SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0008 */ 0009 0010 #include "koprefsdialogplugins.h" 0011 #include "kocore.h" 0012 #include "koprefs.h" 0013 #include <CalendarSupport/KCalPrefs> 0014 #include <KLocalizedString> 0015 #include <KMessageBox> 0016 #include <KPluginFactory> 0017 #include <QAction> 0018 #include <QGroupBox> 0019 #include <QHeaderView> 0020 #include <QLabel> 0021 #include <QRadioButton> 0022 #include <QToolButton> 0023 #include <QTreeWidget> 0024 #include <QVBoxLayout> 0025 0026 class PluginItem : public QTreeWidgetItem 0027 { 0028 public: 0029 PluginItem(QTreeWidget *parent, const KPluginMetaData &service) 0030 : QTreeWidgetItem(parent, {service.name()}) 0031 , mService(service) 0032 { 0033 } 0034 0035 PluginItem(QTreeWidgetItem *parent, const KPluginMetaData &service) 0036 : QTreeWidgetItem(parent, {service.name()}) 0037 , mService(service) 0038 { 0039 } 0040 0041 KPluginMetaData service() 0042 { 0043 return mService; 0044 } 0045 0046 private: 0047 const KPluginMetaData mService; 0048 }; 0049 0050 Q_DECLARE_METATYPE(PluginItem *) 0051 0052 K_PLUGIN_CLASS_WITH_JSON(KOPrefsDialogPlugins, "korganizer_configplugins.json") 0053 0054 /** 0055 Dialog for selecting and configuring KOrganizer plugins 0056 */ 0057 KOPrefsDialogPlugins::KOPrefsDialogPlugins(QObject *parent, const KPluginMetaData &data) 0058 : KPrefsModule(KOPrefs::instance(), parent, data) 0059 , mTreeWidget(new QTreeWidget(widget())) 0060 , mDescription(new QLabel(widget())) 0061 , mPositioningGroupBox(new QGroupBox(i18nc("@title:group", "Position"), widget())) 0062 { 0063 auto topTopLayout = new QVBoxLayout(widget()); 0064 topTopLayout->setContentsMargins({}); 0065 topTopLayout->setSpacing(0); 0066 mTreeWidget->setColumnCount(2); 0067 mTreeWidget->setHeaderHidden(true); 0068 mTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); 0069 mTreeWidget->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); 0070 mTreeWidget->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); 0071 mTreeWidget->header()->setStretchLastSection(false); 0072 topTopLayout->addWidget(mTreeWidget); 0073 0074 mDescription->setAlignment(Qt::AlignVCenter); 0075 mDescription->setWordWrap(true); 0076 mDescription->setFrameShape(QLabel::Panel); 0077 mDescription->setFrameShadow(QLabel::Sunken); 0078 mDescription->setMinimumSize(QSize(0, 55)); 0079 QSizePolicy policy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); 0080 policy.setHorizontalStretch(0); 0081 policy.setVerticalStretch(0); 0082 policy.setHeightForWidth(mDescription->sizePolicy().hasHeightForWidth()); 0083 mDescription->setSizePolicy(policy); 0084 topTopLayout->addWidget(mDescription); 0085 0086 // mPositionMonthTop = new QCheckBox( 0087 // i18nc( "@option:check", "Show in the month view" ), mPositioningGroupBox ); 0088 mPositionAgendaTop = new QRadioButton(i18nc("@option:check", "Show at the top of the agenda views"), mPositioningGroupBox); 0089 mPositionAgendaBottom = new QRadioButton(i18nc("@option:check", "Show at the bottom of the agenda views"), mPositioningGroupBox); 0090 auto positioningLayout = new QVBoxLayout(mPositioningGroupBox); 0091 // positioningLayout->addWidget( mPositionMonthTop ); 0092 positioningLayout->addWidget(mPositionAgendaTop); 0093 positioningLayout->addWidget(mPositionAgendaBottom); 0094 positioningLayout->addStretch(1); 0095 topTopLayout->addWidget(mPositioningGroupBox); 0096 0097 connect(mPositionAgendaTop, &QRadioButton::clicked, this, &KOPrefsDialogPlugins::positioningChanged); 0098 connect(mPositionAgendaBottom, &QRadioButton::clicked, this, &KOPrefsDialogPlugins::positioningChanged); 0099 0100 connect(mTreeWidget, &QTreeWidget::itemSelectionChanged, this, &KOPrefsDialogPlugins::selectionChanged); 0101 connect(mTreeWidget, &QTreeWidget::itemChanged, this, &KOPrefsDialogPlugins::selectionChanged); 0102 connect(mTreeWidget, &QTreeWidget::itemClicked, this, &KOPrefsDialogPlugins::slotWidChanged); 0103 0104 load(); 0105 0106 selectionChanged(); 0107 } 0108 0109 KOPrefsDialogPlugins::~KOPrefsDialogPlugins() 0110 { 0111 delete mDecorations; 0112 } 0113 0114 void KOPrefsDialogPlugins::usrReadConfig() 0115 { 0116 mTreeWidget->clear(); 0117 auto plugins = KOCore::self()->availableCalendarDecorations(); 0118 0119 EventViews::PrefsPtr viewPrefs = KOPrefs::instance()->eventViewsPreferences(); 0120 0121 QStringList selectedPlugins = viewPrefs->selectedPlugins(); 0122 0123 mDecorations = new QTreeWidgetItem(mTreeWidget, QStringList(i18nc("@title:group", "Calendar Decorations"))); 0124 0125 for (const KPluginMetaData &plugin : plugins) { 0126 PluginItem *item = new PluginItem(mDecorations, plugin); 0127 0128 if (selectedPlugins.contains(plugin.pluginId())) { 0129 item->setCheckState(0, Qt::Checked); 0130 } else { 0131 item->setCheckState(0, Qt::Unchecked); 0132 } 0133 const QVariant variant = plugin.value(QStringLiteral("X-KDE-KOrganizer-HasSettings"), false); 0134 const bool hasSettings = (variant.isValid() && variant.toBool()); 0135 if (hasSettings) { 0136 auto but = new QToolButton(mTreeWidget); 0137 auto act = new QAction(but); 0138 const QString decoration = plugin.pluginId(); 0139 act->setData(QVariant::fromValue<PluginItem *>(item)); 0140 but->setDefaultAction(act); 0141 but->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); 0142 but->setFixedWidth(28); 0143 but->setToolTip(i18nc("@action", "Configure")); 0144 but->setAutoFillBackground(true); 0145 but->setEnabled(true); 0146 mTreeWidget->setItemWidget(item, 1, but); 0147 connect(but, &QToolButton::triggered, this, &KOPrefsDialogPlugins::configureClicked); 0148 } 0149 } 0150 0151 mDecorations->setExpanded(true); 0152 0153 const auto monthViewTop = KOPrefs::instance()->decorationsAtMonthViewTop(); 0154 mDecorationsAtMonthViewTop = QSet<QString>(monthViewTop.begin(), monthViewTop.end()); 0155 const auto agendaViewTop = viewPrefs->decorationsAtAgendaViewTop(); 0156 mDecorationsAtAgendaViewTop = QSet<QString>(agendaViewTop.begin(), agendaViewTop.end()); 0157 const auto agendaViewBottom = viewPrefs->decorationsAtAgendaViewBottom(); 0158 mDecorationsAtAgendaViewBottom = QSet<QString>(agendaViewBottom.begin(), agendaViewBottom.end()); 0159 } 0160 0161 void KOPrefsDialogPlugins::usrWriteConfig() 0162 { 0163 QStringList selectedPlugins; 0164 0165 for (int i = 0; i < mTreeWidget->topLevelItemCount(); ++i) { 0166 QTreeWidgetItem *serviceTypeGroup = mTreeWidget->topLevelItem(i); 0167 for (int j = 0; j < serviceTypeGroup->childCount(); ++j) { 0168 auto item = static_cast<PluginItem *>(serviceTypeGroup->child(j)); 0169 if (item->checkState(0) == Qt::Checked) { 0170 selectedPlugins.append(item->service().pluginId()); 0171 } 0172 } 0173 } 0174 EventViews::PrefsPtr viewPrefs = KOPrefs::instance()->eventViewsPreferences(); 0175 viewPrefs->setSelectedPlugins(selectedPlugins); 0176 0177 KOPrefs::instance()->setDecorationsAtMonthViewTop(mDecorationsAtMonthViewTop.values()); 0178 viewPrefs->setDecorationsAtAgendaViewTop(mDecorationsAtAgendaViewTop.values()); 0179 viewPrefs->setDecorationsAtAgendaViewBottom(mDecorationsAtAgendaViewBottom.values()); 0180 } 0181 0182 void KOPrefsDialogPlugins::configureClicked(QAction *action) 0183 { 0184 if (!action) { 0185 return; 0186 } 0187 0188 auto item = action->data().value<PluginItem *>(); 0189 0190 if (!item) { 0191 return; 0192 } 0193 0194 EventViews::CalendarDecoration::Decoration *plugin = KOCore::self()->loadCalendarDecoration(item->service()); 0195 0196 if (plugin) { 0197 plugin->configure(widget()); 0198 delete plugin; 0199 0200 slotWidChanged(); 0201 } else { 0202 KMessageBox::error(widget(), i18nc("@info", "Unable to configure this plugin"), QStringLiteral("PluginConfigUnable")); 0203 } 0204 } 0205 0206 void KOPrefsDialogPlugins::positioningChanged() 0207 { 0208 if (mTreeWidget->selectedItems().count() != 1) { 0209 return; 0210 } 0211 0212 PluginItem *item = dynamic_cast<PluginItem *>(mTreeWidget->selectedItems().last()); 0213 if (!item) { 0214 return; 0215 } 0216 0217 QString decoration = item->service().pluginId(); 0218 0219 /*if ( mPositionMonthTop->checkState() == Qt::Checked ) { 0220 if ( !mDecorationsAtMonthViewTop.contains( decoration ) ) { 0221 mDecorationsAtMonthViewTop.insert( decoration ); 0222 } 0223 } else { 0224 mDecorationsAtMonthViewTop.remove( decoration ); 0225 }*/ 0226 0227 if (mPositionAgendaTop->isChecked()) { 0228 if (!mDecorationsAtAgendaViewTop.contains(decoration)) { 0229 mDecorationsAtAgendaViewTop.insert(decoration); 0230 } 0231 } else { 0232 mDecorationsAtAgendaViewTop.remove(decoration); 0233 } 0234 0235 if (mPositionAgendaBottom->isChecked()) { 0236 if (!mDecorationsAtAgendaViewBottom.contains(decoration)) { 0237 mDecorationsAtAgendaViewBottom.insert(decoration); 0238 } 0239 } else { 0240 mDecorationsAtAgendaViewBottom.remove(decoration); 0241 } 0242 0243 slotWidChanged(); 0244 } 0245 0246 void KOPrefsDialogPlugins::selectionChanged() 0247 { 0248 mPositioningGroupBox->hide(); 0249 // mPositionMonthTop->setChecked( false ); 0250 mPositionAgendaTop->setChecked(false); 0251 mPositionAgendaBottom->setChecked(false); 0252 0253 if (mTreeWidget->selectedItems().count() != 1) { 0254 mDescription->setText(QString()); 0255 return; 0256 } 0257 0258 PluginItem *item = dynamic_cast<PluginItem *>(mTreeWidget->selectedItems().last()); 0259 if (!item) { 0260 mDescription->setText(QString()); 0261 return; 0262 } 0263 0264 mDescription->setText(item->service().description()); 0265 0266 bool hasPosition = false; 0267 QString decoration = item->service().pluginId(); 0268 /*if ( mDecorationsAtMonthViewTop.contains( decoration ) ) { 0269 mPositionMonthTop->setChecked( true ); 0270 hasPosition = true; 0271 }*/ 0272 if (mDecorationsAtAgendaViewTop.contains(decoration)) { 0273 mPositionAgendaTop->setChecked(true); 0274 hasPosition = true; 0275 } 0276 if (mDecorationsAtAgendaViewBottom.contains(decoration)) { 0277 mPositionAgendaBottom->setChecked(true); 0278 hasPosition = true; 0279 } 0280 0281 if (!hasPosition) { 0282 // no position has been selected, so default to Agenda Top 0283 mDecorationsAtAgendaViewTop << decoration; 0284 mPositionAgendaTop->setChecked(true); 0285 } 0286 0287 mPositioningGroupBox->setEnabled(item->checkState(0) == Qt::Checked); 0288 mPositioningGroupBox->show(); 0289 0290 slotWidChanged(); 0291 } 0292 0293 #include "koprefsdialogplugins.moc" 0294 0295 #include "moc_koprefsdialogplugins.cpp"