Warning, file /pim/mailcommon/src/collectionpage/collectiongeneralpage.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002   SPDX-FileCopyrightText: 2009-2024 Laurent Montel <montel@kde.org>
0003 
0004   SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "collectiongeneralpage.h"
0008 #include "collectiongeneralwidget.h"
0009 #include <KStatefulBrush>
0010 #include <PimCommonAkonadi/CollectionTypeUtil>
0011 
0012 #include "folder/foldersettings.h"
0013 #include "kernel/mailkernel.h"
0014 #include <Akonadi/CollectionAnnotationsAttribute>
0015 #include <PimCommonAkonadi/ContentTypeWidget>
0016 #include <PimCommonAkonadi/IncidencesForWidget>
0017 
0018 #include <Akonadi/AgentManager>
0019 #include <Akonadi/AttributeFactory>
0020 #include <Akonadi/Collection>
0021 #include <Akonadi/CollectionModifyJob>
0022 #include <Akonadi/EntityDisplayAttribute>
0023 #include <PimCommon/PimUtil>
0024 
0025 #include <KLineEditEventHandler>
0026 #include <PimCommonAkonadi/ImapResourceCapabilitiesManager>
0027 
0028 #include <KColorScheme>
0029 #include <KLocalizedString>
0030 #include <KMessageBox>
0031 
0032 #include <QCheckBox>
0033 #include <QFormLayout>
0034 #include <QLineEdit>
0035 #include <QVBoxLayout>
0036 
0037 using namespace Akonadi;
0038 using namespace MailCommon;
0039 
0040 CollectionGeneralPage::CollectionGeneralPage(QWidget *parent)
0041     : CollectionPropertiesPage(parent)
0042 {
0043     setObjectName(QLatin1StringView("MailCommon::CollectionGeneralPage"));
0044     setPageTitle(i18nc("@title:tab General settings for a folder.", "General"));
0045 }
0046 
0047 CollectionGeneralPage::~CollectionGeneralPage() = default;
0048 
0049 void CollectionGeneralPage::init(const Akonadi::Collection &collection)
0050 {
0051     mIsLocalSystemFolder = CommonKernel->isSystemFolderCollection(collection) || Kernel::folderIsInbox(collection);
0052 
0053     mIsResourceFolder = (collection.parentCollection() == Akonadi::Collection::root());
0054     auto topLayout = new QVBoxLayout(this);
0055 
0056     mCollectionGeneralWidget = new CollectionGeneralWidget(this);
0057     topLayout->addWidget(mCollectionGeneralWidget);
0058     auto innerLayout = qobject_cast<QFormLayout *>(mCollectionGeneralWidget->layout());
0059 
0060     // Mustn't be able to edit details for a non-resource, system folder.
0061     if ((!mIsLocalSystemFolder || mIsResourceFolder) && !mFolderCollection->isReadOnly()) {
0062         mNameEdit = new QLineEdit(this);
0063         KLineEditEventHandler::catchReturnKey(mNameEdit);
0064         connect(mNameEdit, &QLineEdit::textChanged, this, &CollectionGeneralPage::slotNameChanged);
0065         innerLayout->insertRow(0, i18nc("@label:textbox Name of the folder.", "Folder &Name:"), mNameEdit);
0066     }
0067 
0068     // Only do make this settable, if the IMAP resource is enabled
0069     // and it's not the personal folders (those must not be changed)
0070     const QString collectionResource = collection.resource();
0071     if (CommonKernel->imapResourceManager()->hasAnnotationSupport(collectionResource)) {
0072         PimCommon::CollectionTypeUtil::FolderContentsType contentsType = PimCommon::CollectionTypeUtil::ContentsTypeMail;
0073 
0074         const auto *annotationAttribute = collection.attribute<Akonadi::CollectionAnnotationsAttribute>();
0075 
0076         const QMap<QByteArray, QByteArray> annotations = (annotationAttribute ? annotationAttribute->annotations() : QMap<QByteArray, QByteArray>());
0077 
0078         const bool sharedSeen = (annotations.value(PimCommon::CollectionTypeUtil::kolabSharedSeen()) == "true");
0079 
0080         PimCommon::CollectionTypeUtil collectionUtil;
0081         const PimCommon::CollectionTypeUtil::IncidencesFor incidencesFor =
0082             collectionUtil.incidencesForFromString(QLatin1StringView(annotations.value(PimCommon::CollectionTypeUtil::kolabIncidencesFor())));
0083 
0084         const PimCommon::CollectionTypeUtil::FolderContentsType folderType =
0085             collectionUtil.typeFromKolabName(annotations.value(PimCommon::CollectionTypeUtil::kolabFolderType()));
0086 
0087         mContentsComboBox = new PimCommon::ContentTypeWidget(this);
0088         innerLayout->addRow(PimCommon::ContentTypeWidget::labelName(), mContentsComboBox);
0089         mContentsComboBox->setCurrentIndex(contentsType);
0090 
0091         connect(mContentsComboBox, &PimCommon::ContentTypeWidget::activated, this, &CollectionGeneralPage::slotFolderContentsSelectionChanged);
0092 
0093         if (mFolderCollection->isReadOnly() || mIsResourceFolder) {
0094             mContentsComboBox->setEnabled(false);
0095         }
0096 
0097         // Kolab incidences-for annotation.
0098         // Show incidences-for combobox if the contents type can be changed (new folder),
0099         // or if it's set to calendar or task (existing folder)
0100         const bool folderTypeComboboxEnabled =
0101             (folderType == PimCommon::CollectionTypeUtil::ContentsTypeCalendar || folderType == PimCommon::CollectionTypeUtil::ContentsTypeTask);
0102         if (folderTypeComboboxEnabled) {
0103             mIncidencesForComboBox = new PimCommon::IncidencesForWidget(this);
0104             innerLayout->addRow(PimCommon::IncidencesForWidget::labelName(), mIncidencesForComboBox);
0105 
0106             mIncidencesForComboBox->setCurrentIndex(incidencesFor);
0107         }
0108 
0109         mSharedSeenFlagsCheckBox = new QCheckBox(this);
0110         mSharedSeenFlagsCheckBox->setText(i18n("Share unread state with all users"));
0111         mSharedSeenFlagsCheckBox->setChecked(sharedSeen);
0112         mSharedSeenFlagsCheckBox->setWhatsThis(
0113             i18n("If enabled, the unread state of messages in this folder will be "
0114                  "the same for all users having access to this folder. If disabled "
0115                  "(the default), every user with access to this folder has their "
0116                  "own unread state."));
0117         innerLayout->addRow(QString(), mSharedSeenFlagsCheckBox);
0118     }
0119 
0120     topLayout->addStretch(100); // eat all superfluous space
0121 }
0122 
0123 void CollectionGeneralPage::load(const Akonadi::Collection &collection)
0124 {
0125     mFolderCollection = FolderSettings::forCollection(collection);
0126     init(collection);
0127 
0128     mCollectionGeneralWidget->load(collection);
0129     if (mNameEdit) {
0130         const QString displayName = collection.displayName();
0131 
0132         if (!mIsLocalSystemFolder || mIsResourceFolder) {
0133             mNameEdit->setText(displayName);
0134         }
0135     }
0136 
0137     if (mContentsComboBox) {
0138         const auto *annotationsAttribute = collection.attribute<Akonadi::CollectionAnnotationsAttribute>();
0139 
0140         if (annotationsAttribute) {
0141             const QMap<QByteArray, QByteArray> annotations = annotationsAttribute->annotations();
0142             if (annotations.contains(PimCommon::CollectionTypeUtil::kolabFolderType())) {
0143                 PimCommon::CollectionTypeUtil collectionUtil;
0144                 mContentsComboBox->setCurrentItem(collectionUtil.typeNameFromKolabType(annotations[PimCommon::CollectionTypeUtil::kolabFolderType()]));
0145             }
0146         }
0147     }
0148 }
0149 
0150 void CollectionGeneralPage::save(Collection &collection)
0151 {
0152     if (mNameEdit) {
0153         if (!mIsLocalSystemFolder) {
0154             const QString nameFolder(mNameEdit->text().trimmed());
0155             bool canRenameFolder = !(nameFolder.startsWith(QLatin1Char('.')) || nameFolder.endsWith(QLatin1Char('.')) || nameFolder.contains(QLatin1Char('/'))
0156                                      || nameFolder.isEmpty());
0157 
0158             if (mIsResourceFolder && (PimCommon::Util::isImapResource(collection.resource()))) {
0159                 collection.setName(nameFolder);
0160                 Akonadi::AgentInstance instance = Akonadi::AgentManager::self()->instance(collection.resource());
0161                 instance.setName(nameFolder);
0162             } else if (canRenameFolder) {
0163                 if (collection.hasAttribute<Akonadi::EntityDisplayAttribute>()
0164                     && !collection.attribute<Akonadi::EntityDisplayAttribute>()->displayName().isEmpty()) {
0165                     collection.attribute<Akonadi::EntityDisplayAttribute>()->setDisplayName(nameFolder);
0166                 } else if (!nameFolder.isEmpty()) {
0167                     collection.setName(nameFolder);
0168                 }
0169             }
0170         }
0171     }
0172     mCollectionGeneralWidget->save(collection);
0173 
0174     auto *annotationsAttribute = collection.attribute<Akonadi::CollectionAnnotationsAttribute>(Collection::AddIfMissing);
0175 
0176     QMap<QByteArray, QByteArray> annotations = annotationsAttribute->annotations();
0177     if (mSharedSeenFlagsCheckBox && mSharedSeenFlagsCheckBox->isEnabled()) {
0178         annotations[PimCommon::CollectionTypeUtil::kolabSharedSeen()] = mSharedSeenFlagsCheckBox->isChecked() ? "true" : "false";
0179     }
0180 
0181     PimCommon::CollectionTypeUtil collectionUtil;
0182     if (mIncidencesForComboBox && mIncidencesForComboBox->isEnabled()) {
0183         annotations[PimCommon::CollectionTypeUtil::kolabIncidencesFor()] =
0184             collectionUtil.incidencesForToString(static_cast<PimCommon::CollectionTypeUtil::IncidencesFor>(mIncidencesForComboBox->currentIndex())).toLatin1();
0185     }
0186 
0187     if (mContentsComboBox) {
0188         const PimCommon::CollectionTypeUtil::FolderContentsType type = collectionUtil.contentsTypeFromString(mContentsComboBox->currentText());
0189 
0190         const QByteArray kolabName = collectionUtil.kolabNameFromType(type);
0191         if (!kolabName.isEmpty()) {
0192             const QString iconName = collectionUtil.iconNameFromContentsType(type);
0193             auto *attribute = collection.attribute<Akonadi::EntityDisplayAttribute>(Akonadi::Collection::AddIfMissing);
0194             attribute->setIconName(iconName);
0195             new Akonadi::CollectionModifyJob(collection);
0196             annotations[PimCommon::CollectionTypeUtil::kolabFolderType()] = kolabName;
0197         }
0198     }
0199     if (annotations.isEmpty()) {
0200         collection.removeAttribute<Akonadi::CollectionAnnotationsAttribute>();
0201     } else {
0202         annotationsAttribute->setAnnotations(annotations);
0203     }
0204 }
0205 
0206 void CollectionGeneralPage::slotFolderContentsSelectionChanged(int)
0207 {
0208     PimCommon::CollectionTypeUtil collectionUtil;
0209     const PimCommon::CollectionTypeUtil::FolderContentsType type = collectionUtil.contentsTypeFromString(mContentsComboBox->currentText());
0210 
0211     if (type != PimCommon::CollectionTypeUtil::ContentsTypeMail) {
0212         const QString message = i18n(
0213             "You have configured this folder to contain groupware information. "
0214             "That means that this folder will disappear once the configuration "
0215             "dialog is closed.");
0216 
0217         KMessageBox::information(this, message);
0218     }
0219 
0220     const bool enable = (type == PimCommon::CollectionTypeUtil::ContentsTypeCalendar || type == PimCommon::CollectionTypeUtil::ContentsTypeTask);
0221 
0222     if (mIncidencesForComboBox) {
0223         mIncidencesForComboBox->setEnabled(enable);
0224     }
0225 }
0226 
0227 void CollectionGeneralPage::slotNameChanged(const QString &name)
0228 {
0229 #ifndef QT_NO_STYLE_STYLESHEET
0230     QString styleSheet;
0231     if (name.startsWith(QLatin1Char('.')) || name.endsWith(QLatin1Char('.')) || name.contains(QLatin1Char('/')) || name.trimmed().isEmpty()) {
0232         if (mColorName.isEmpty()) {
0233             const KColorScheme::BackgroundRole bgColorScheme(KColorScheme::NegativeBackground);
0234             KStatefulBrush bgBrush(KColorScheme::View, bgColorScheme);
0235             mColorName = bgBrush.brush(palette()).color().name();
0236         }
0237         styleSheet = QStringLiteral("QLineEdit{ background-color:%1 }").arg(mColorName);
0238     }
0239     setStyleSheet(styleSheet);
0240 #endif
0241 }
0242 
0243 #include "moc_collectiongeneralpage.cpp"