1 /*
2  * SPDX-FileCopyrightText: 2014 Sandro Knauß <knauss@kolabsys.com>
3  *
4  * SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
5  */
6 
7 #include "noteeditdialog.h"
8 
9 #include <Akonadi/CollectionComboBox>
10 #include <Akonadi/Notes/NoteUtils>
11 
12 #include <KPIMTextEdit/RichTextEditor>
13 #include <KPIMTextEdit/RichTextEditorWidget>
14 
15 #include <KConfigGroup>
16 #include <KLocalizedString>
17 #include <KSharedConfig>
18 
19 #include <QDialogButtonBox>
20 #include <QLabel>
21 #include <QLineEdit>
22 #include <QPushButton>
23 #include <QVBoxLayout>
24 
25 using namespace CalendarSupport;
26 
27 QAbstractItemModel *NoteEditDialog::_k_noteEditStubModel = nullptr;
28 
NoteEditDialog(QWidget * parent)29 NoteEditDialog::NoteEditDialog(QWidget *parent)
30     : QDialog(parent)
31 {
32     setAttribute(Qt::WA_DeleteOnClose);
33     setWindowTitle(i18nc("@title:window", "Create Note"));
34     auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
35     auto mainWidget = new QWidget(this);
36     auto mainLayout = new QVBoxLayout(this);
37     mainLayout->addWidget(mainWidget);
38     connect(buttonBox, &QDialogButtonBox::accepted, this, &NoteEditDialog::accept);
39     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
40     mainLayout->addWidget(buttonBox);
41 
42     buttonBox->button(QDialogButtonBox::Cancel)->setText(i18nc("@action:button", "Cancel"));
43 
44     mOkButton = buttonBox->button(QDialogButtonBox::Ok);
45     mOkButton->setObjectName(QStringLiteral("save-button"));
46     mOkButton->setDefault(true);
47     mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return);
48     mOkButton->setText(i18nc("@action:button", "Save"));
49     mOkButton->setIcon(QIcon::fromTheme(QStringLiteral("view-pim-notes")));
50     mOkButton->setEnabled(false);
51 
52     auto layout = new QGridLayout(mainWidget);
53     layout->setContentsMargins(0, 0, 0, 0);
54     auto hbox = new QHBoxLayout;
55     hbox->setContentsMargins(0, 0, 0, 0);
56     hbox->setSpacing(2);
57 
58     mNoteTitle = new QLineEdit(this);
59     mNoteTitle->setClearButtonEnabled(true);
60     mNoteTitle->setObjectName(QStringLiteral("notetitle"));
61     mNoteTitle->setFocus();
62     connect(mNoteTitle, &QLineEdit::textChanged, this, &NoteEditDialog::slotUpdateButtons);
63 
64     mCollectionCombobox = new Akonadi::CollectionComboBox(_k_noteEditStubModel, this);
65     mCollectionCombobox->setAccessRightsFilter(Akonadi::Collection::CanCreateItem);
66     mCollectionCombobox->setMinimumWidth(250);
67     mCollectionCombobox->setMimeTypeFilter(QStringList() << Akonadi::NoteUtils::noteMimeType());
68     mCollectionCombobox->setObjectName(QStringLiteral("akonadicombobox"));
69 #ifndef QT_NO_ACCESSIBILITY
70     mCollectionCombobox->setAccessibleDescription(i18nc("@info", "Calendar where the new note will be stored."));
71 #endif
72     mCollectionCombobox->setToolTip(i18nc("@info:tooltip", "Calendar where the new note will be stored."));
73     connect(mCollectionCombobox, qOverload<int>(&Akonadi::CollectionComboBox::currentIndexChanged), this, &NoteEditDialog::slotCollectionChanged);
74     connect(mCollectionCombobox, qOverload<int>(&Akonadi::CollectionComboBox::activated), this, &NoteEditDialog::slotCollectionChanged);
75 
76     mNoteText = new KPIMTextEdit::RichTextEditorWidget(parent);
77     mNoteText->setObjectName(QStringLiteral("notetext"));
78     connect(mNoteText->editor(), &KPIMTextEdit::RichTextEditor::textChanged, this, &NoteEditDialog::slotUpdateButtons);
79 
80     // First line
81     hbox->addWidget(mNoteTitle);
82     hbox->addSpacing(5);
83     hbox->addWidget(mCollectionCombobox);
84 
85     auto lab = new QLabel(i18nc("@label specify the title for this note", "Title:"), this);
86     layout->addWidget(lab, 0, 0);
87     layout->addLayout(hbox, 0, 1);
88 
89     // Second Line
90     lab = new QLabel(i18nc("@label specify the text for this note", "Text:"), this);
91     layout->addWidget(lab, 1, 0);
92     layout->setAlignment(lab, Qt::AlignTop);
93     layout->addWidget(mNoteText, 1, 1);
94 
95     readConfig();
96 }
97 
~NoteEditDialog()98 NoteEditDialog::~NoteEditDialog()
99 {
100     disconnect(mNoteText->editor(), &KPIMTextEdit::RichTextEditor::textChanged, this, &NoteEditDialog::slotUpdateButtons);
101     writeConfig();
102 }
103 
readConfig()104 void NoteEditDialog::readConfig()
105 {
106     KConfigGroup group(KSharedConfig::openStateConfig(), "NoteEditDialog");
107 
108     const QSize size = group.readEntry("Size", QSize(500, 300));
109     if (size.isValid()) {
110         resize(size);
111     }
112 }
113 
writeConfig()114 void NoteEditDialog::writeConfig()
115 {
116     KConfigGroup group(KSharedConfig::openStateConfig(), "NoteEditDialog");
117     group.writeEntry("Size", size());
118     group.sync();
119 }
120 
slotUpdateButtons()121 void NoteEditDialog::slotUpdateButtons()
122 {
123     if (mNoteTitle->text().trimmed().isEmpty() && mNoteText->isEmpty()) {
124         mOkButton->setEnabled(false);
125     } else {
126         mOkButton->setEnabled(true);
127     }
128 }
129 
collection() const130 Akonadi::Collection NoteEditDialog::collection() const
131 {
132     return mCollection;
133 }
134 
slotCollectionChanged(int index)135 void NoteEditDialog::slotCollectionChanged(int index)
136 {
137     Q_UNUSED(index)
138     setCollection(mCollectionCombobox->currentCollection());
139 }
140 
setCollection(const Akonadi::Collection & value)141 void NoteEditDialog::setCollection(const Akonadi::Collection &value)
142 {
143     if (mCollection != value) {
144         mCollection = value;
145         Q_EMIT collectionChanged(mCollection);
146     }
147 }
148 
accept()149 void NoteEditDialog::accept()
150 {
151     QDialog::accept();
152     const Akonadi::Collection collection = mCollectionCombobox->currentCollection();
153     if (!collection.isValid()) {
154         return;
155     }
156 
157     if (mNoteTitle->text().isEmpty() && mNoteText->isEmpty()) {
158         return;
159     }
160 
161     Akonadi::NoteUtils::NoteMessageWrapper note(mItem.payload<KMime::Message::Ptr>());
162     note.setTitle(mNoteTitle->text());
163     if (mNoteText->acceptRichText()) {
164         note.setText(mNoteText->editor()->toHtml(), Qt::RichText);
165     } else {
166         note.setText(mNoteText->editor()->toPlainText(), Qt::PlainText);
167     }
168     mItem.setPayload<KMime::Message::Ptr>(note.message());
169     Q_EMIT createNote(mItem, collection);
170 }
171 
load(const Akonadi::Item & item)172 void NoteEditDialog::load(const Akonadi::Item &item)
173 {
174     mItem = item;
175     Akonadi::NoteUtils::NoteMessageWrapper note(item.payload<KMime::Message::Ptr>());
176     mNoteText->editor()->setHtml(note.text());
177     if (note.textFormat() == Qt::RichText) {
178         mNoteText->setAcceptRichText(true);
179     } else {
180         mNoteText->setAcceptRichText(false);
181     }
182     mNoteTitle->setText(note.title());
183 }
184 
note() const185 KMime::Message::Ptr NoteEditDialog::note() const
186 {
187     if (mItem.hasPayload<KMime::Message::Ptr>()) {
188         return mItem.payload<KMime::Message::Ptr>();
189     } else {
190         return KMime::Message::Ptr();
191     }
192 }
193