File indexing completed on 2025-01-05 04:58:23

0001 /*
0002    SPDX-FileCopyrightText: 2010 Thomas McGuire <mcguire@kde.org>
0003    SPDX-FileCopyrightText: 2014-2024 Laurent Montel <montel@kde.org>
0004 
0005    SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006 */
0007 
0008 #include "annotationdialog.h"
0009 #include <TextCustomEditor/PlainTextEditorWidget>
0010 
0011 #include <Akonadi/EntityAnnotationsAttribute>
0012 #include <Akonadi/Item>
0013 #include <Akonadi/ItemModifyJob>
0014 #include <KLocalizedString>
0015 #include <KMessageBox>
0016 #include <KSharedConfig>
0017 #include <KStandardGuiItem>
0018 
0019 #include <QComboBox>
0020 #include <QIcon>
0021 
0022 #include <KConfigGroup>
0023 #include <KWindowConfig>
0024 #include <QDialogButtonBox>
0025 #include <QLabel>
0026 #include <QPushButton>
0027 #include <QVBoxLayout>
0028 #include <QWindow>
0029 
0030 using namespace PimCommon;
0031 
0032 class Q_DECL_HIDDEN AnnotationEditDialog::AnnotationEditDialogPrivate
0033 {
0034 public:
0035     AnnotationEditDialogPrivate() = default;
0036 
0037     Akonadi::Item mItem;
0038     TextCustomEditor::PlainTextEditorWidget *mTextEdit = nullptr;
0039     QComboBox *mNoteType = nullptr;
0040     bool mHasAnnotation = false;
0041 };
0042 
0043 namespace
0044 {
0045 static const char myConfigAnnotationEditDialog[] = "AnnotationEditDialog";
0046 }
0047 
0048 AnnotationEditDialog::AnnotationEditDialog(const Akonadi::Item &item, QWidget *parent)
0049     : QDialog(parent)
0050     , d(new AnnotationEditDialogPrivate)
0051 {
0052     d->mItem = item;
0053     // check for correct key?
0054     d->mHasAnnotation = item.hasAttribute<Akonadi::EntityAnnotationsAttribute>();
0055     auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
0056     auto mainWidget = new QWidget(this);
0057     auto mainLayout = new QVBoxLayout(this);
0058     mainLayout->addWidget(mainWidget);
0059     QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
0060     okButton->setDefault(true);
0061     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0062     connect(buttonBox, &QDialogButtonBox::accepted, this, &AnnotationEditDialog::slotAccepted);
0063     connect(buttonBox, &QDialogButtonBox::rejected, this, &AnnotationEditDialog::reject);
0064 
0065     if (d->mHasAnnotation) {
0066         setWindowTitle(i18nc("@title:window", "Edit Note"));
0067         auto user1Button = new QPushButton;
0068         buttonBox->addButton(user1Button, QDialogButtonBox::ActionRole);
0069         user1Button->setText(i18nc("@action:button", "Delete Note"));
0070         user1Button->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
0071         connect(user1Button, &QPushButton::clicked, this, &AnnotationEditDialog::slotDeleteNote);
0072     } else {
0073         setWindowTitle(i18nc("@title:window", "Add Note"));
0074     }
0075 
0076     buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
0077 
0078     auto label = new QLabel(i18n("Enter the text that should be stored as a note to the mail:"));
0079     auto vbox = new QVBoxLayout(mainWidget);
0080     vbox->setContentsMargins({});
0081     d->mTextEdit = new TextCustomEditor::PlainTextEditorWidget(this);
0082     vbox->addWidget(label);
0083     vbox->addWidget(d->mTextEdit);
0084     d->mTextEdit->setFocus();
0085 
0086     auto hbox = new QHBoxLayout;
0087     hbox->addStretch();
0088     label = new QLabel(i18nc("@label:listbox", "Note type:"));
0089     hbox->addWidget(label);
0090     d->mNoteType = new QComboBox;
0091     hbox->addWidget(d->mNoteType);
0092     d->mNoteType->addItem(i18nc("@item:inlistbox", "Private note"), QByteArrayLiteral("/private/comment"));
0093     d->mNoteType->addItem(i18nc("@item:inlistbox", "Shared note"), QByteArrayLiteral("/shared/comment"));
0094 
0095     vbox->addLayout(hbox);
0096     if (d->mHasAnnotation && item.attribute<Akonadi::EntityAnnotationsAttribute>()) {
0097         if (item.attribute<Akonadi::EntityAnnotationsAttribute>()->contains("/private/comment")) {
0098             d->mNoteType->setCurrentIndex(d->mNoteType->findData(QStringLiteral("/private/comment")));
0099             d->mTextEdit->setPlainText(item.attribute<Akonadi::EntityAnnotationsAttribute>()->value("/private/comment"));
0100         } else {
0101             d->mNoteType->setCurrentIndex(d->mNoteType->findData(QStringLiteral("/shared/comment")));
0102             d->mTextEdit->setPlainText(item.attribute<Akonadi::EntityAnnotationsAttribute>()->value("/shared/comment"));
0103         }
0104     }
0105     mainLayout->addWidget(buttonBox);
0106     readConfig();
0107 }
0108 
0109 AnnotationEditDialog::~AnnotationEditDialog()
0110 {
0111     writeConfig();
0112 }
0113 
0114 void AnnotationEditDialog::slotAccepted()
0115 {
0116     bool textIsEmpty = d->mTextEdit->isEmpty();
0117     if (!textIsEmpty) {
0118         d->mItem.removeAttribute<Akonadi::EntityAnnotationsAttribute>();
0119         auto annotation = d->mItem.attribute<Akonadi::EntityAnnotationsAttribute>(Akonadi::Item::AddIfMissing);
0120         QMap<QByteArray, QByteArray> map;
0121         map.insert(d->mNoteType->itemData(d->mNoteType->currentIndex()).toByteArray(), d->mTextEdit->toPlainText().toUtf8());
0122         annotation->setAnnotations(map);
0123         d->mItem.addAttribute(annotation);
0124     } else if (d->mHasAnnotation) {
0125         d->mItem.removeAttribute<Akonadi::EntityAnnotationsAttribute>();
0126     }
0127     new Akonadi::ItemModifyJob(d->mItem);
0128     accept();
0129 }
0130 
0131 void AnnotationEditDialog::slotDeleteNote()
0132 {
0133     const int answer = KMessageBox::warningContinueCancel(this,
0134                                                           i18n("Do you really want to delete this note?"),
0135                                                           i18nc("@title:window", "Delete Note"),
0136                                                           KStandardGuiItem::del());
0137     if (answer == KMessageBox::Continue) {
0138         d->mItem.removeAttribute<Akonadi::EntityAnnotationsAttribute>();
0139         new Akonadi::ItemModifyJob(d->mItem);
0140         accept();
0141     }
0142 }
0143 
0144 void AnnotationEditDialog::writeConfig()
0145 {
0146     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myConfigAnnotationEditDialog));
0147     KWindowConfig::saveWindowSize(windowHandle(), group);
0148 }
0149 
0150 void AnnotationEditDialog::readConfig()
0151 {
0152     create(); // ensure a window is created
0153     windowHandle()->resize(QSize(400, 300));
0154     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myConfigAnnotationEditDialog));
0155     KWindowConfig::restoreWindowSize(windowHandle(), group);
0156     resize(windowHandle()->size()); // workaround for QTBUG-40584
0157 }
0158 
0159 #include "moc_annotationdialog.cpp"