File indexing completed on 2024-12-15 04:51:47

0001 /*
0002    SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #include "createnewnotejob.h"
0007 #include "attributes/showfoldernotesattribute.h"
0008 #include "dialog/selectednotefolderdialog.h"
0009 #include "noteshared_debug.h"
0010 #include "notesharedglobalconfig.h"
0011 #include <Akonadi/NoteUtils>
0012 
0013 #include <Akonadi/Collection>
0014 #include <Akonadi/CollectionFetchJob>
0015 #include <Akonadi/CollectionModifyJob>
0016 #include <Akonadi/EntityDisplayAttribute>
0017 #include <Akonadi/Item>
0018 #include <Akonadi/ItemCreateJob>
0019 
0020 #include <KMime/KMimeMessage>
0021 
0022 #include <KLocalizedString>
0023 #include <KMessageBox>
0024 #include <QLocale>
0025 
0026 #include <QPointer>
0027 
0028 using namespace NoteShared;
0029 
0030 CreateNewNoteJob::CreateNewNoteJob(QObject *parent, QWidget *widget)
0031     : QObject(parent)
0032     , mWidget(widget)
0033 {
0034     connect(this, &CreateNewNoteJob::selectNewCollection, this, &CreateNewNoteJob::slotSelectNewCollection);
0035 }
0036 
0037 CreateNewNoteJob::~CreateNewNoteJob() = default;
0038 
0039 void CreateNewNoteJob::slotSelectNewCollection()
0040 {
0041     createFetchCollectionJob(false);
0042 }
0043 
0044 void CreateNewNoteJob::setNote(const QString &name, const QString &text)
0045 {
0046     mTitle = name;
0047     mText = text;
0048 }
0049 
0050 void CreateNewNoteJob::setRichText(bool richText)
0051 {
0052     mRichText = richText;
0053 }
0054 
0055 void CreateNewNoteJob::start()
0056 {
0057     createFetchCollectionJob(true);
0058 }
0059 
0060 void CreateNewNoteJob::createFetchCollectionJob(bool useSettings)
0061 {
0062     Akonadi::Collection col;
0063     Akonadi::Collection::Id id = -1;
0064     if (useSettings) {
0065         id = NoteShared::NoteSharedGlobalConfig::self()->defaultFolder();
0066     } else {
0067         NoteShared::NoteSharedGlobalConfig::self()->setDefaultFolder(id);
0068     }
0069     if (id == -1) {
0070         QPointer<SelectedNotefolderDialog> dlg = new SelectedNotefolderDialog(mWidget);
0071         if (dlg->exec()) {
0072             col = dlg->selectedCollection();
0073         } else {
0074             deleteLater();
0075             return;
0076         }
0077         if (dlg->useFolderByDefault()) {
0078             NoteShared::NoteSharedGlobalConfig::self()->setDefaultFolder(col.id());
0079             NoteShared::NoteSharedGlobalConfig::self()->save();
0080         }
0081         delete dlg;
0082     } else {
0083         col = Akonadi::Collection(id);
0084     }
0085     NoteShared::NoteSharedGlobalConfig::self()->save();
0086     auto fetchCollection = new Akonadi::CollectionFetchJob(col, Akonadi::CollectionFetchJob::Base);
0087     connect(fetchCollection, &Akonadi::CollectionFetchJob::result, this, &CreateNewNoteJob::slotFetchCollection);
0088 }
0089 
0090 void CreateNewNoteJob::slotFetchCollection(KJob *job)
0091 {
0092     if (job->error()) {
0093         qCDebug(NOTESHARED_LOG) << " Error during fetch: " << job->errorString();
0094         const int answer = KMessageBox::warningTwoActions(nullptr,
0095                                                           i18n("An error occurred during fetching. Do you want to select a new default collection?"),
0096                                                           QString(),
0097                                                           KGuiItem(i18nc("@action:button", "Select New Default")),
0098                                                           KGuiItem(i18nc("@action:button", "Ignore"), QStringLiteral("dialog-cancel")));
0099         if (answer == KMessageBox::ButtonCode::PrimaryAction) {
0100             Q_EMIT selectNewCollection();
0101         } else {
0102             deleteLater();
0103         }
0104         return;
0105     }
0106     auto fetchCollection = qobject_cast<Akonadi::CollectionFetchJob *>(job);
0107     if (fetchCollection->collections().isEmpty()) {
0108         qCDebug(NOTESHARED_LOG) << "No collection fetched";
0109         const int answer = KMessageBox::warningTwoActions(nullptr,
0110                                                           i18n("An error occurred during fetching. Do you want to select a new default collection?"),
0111                                                           QString(),
0112                                                           KGuiItem(i18nc("@action:button", "Select New Default")),
0113                                                           KGuiItem(i18nc("@action:button", "Ignore"), QStringLiteral("dialog-cancel")));
0114         if (answer == KMessageBox::ButtonCode::PrimaryAction) {
0115             Q_EMIT selectNewCollection();
0116         } else {
0117             deleteLater();
0118         }
0119         return;
0120     }
0121     Akonadi::Collection col = fetchCollection->collections().at(0);
0122     if (col.isValid()) {
0123         if (!col.hasAttribute<NoteShared::ShowFolderNotesAttribute>()) {
0124             const int answer =
0125                 KMessageBox::warningTwoActions(nullptr,
0126                                                i18n("Collection is hidden. New note will be stored but not displayed. Do you want to show collection?"),
0127                                                QString(),
0128                                                KGuiItem(i18nc("@action::button", "Show Collection")),
0129                                                KGuiItem(i18nc("@action::button", "Do Not Show"), QStringLiteral("dialog-cancel")));
0130             if (answer == KMessageBox::ButtonCode::PrimaryAction) {
0131                 col.addAttribute(new NoteShared::ShowFolderNotesAttribute());
0132                 auto modifyJob = new Akonadi::CollectionModifyJob(col);
0133                 connect(modifyJob, &Akonadi::CollectionModifyJob::result, this, &CreateNewNoteJob::slotCollectionModifyFinished);
0134             }
0135         }
0136         Akonadi::Item newItem;
0137         newItem.setMimeType(Akonadi::NoteUtils::noteMimeType());
0138 
0139         KMime::Message::Ptr newPage = KMime::Message::Ptr(new KMime::Message());
0140 
0141         QString title;
0142         if (mTitle.isEmpty()) {
0143             const QDateTime currentDateTime = QDateTime::currentDateTime();
0144             title = NoteShared::NoteSharedGlobalConfig::self()->defaultTitle();
0145             title.replace(QStringLiteral("%t"), QLocale().toString(currentDateTime.time()));
0146             title.replace(QStringLiteral("%d"), QLocale().toString(currentDateTime.date(), QLocale::ShortFormat));
0147             title.replace(QStringLiteral("%l"), QLocale().toString(currentDateTime.date(), QLocale::LongFormat));
0148         } else {
0149             title = mTitle;
0150         }
0151         QByteArray encoding("utf-8");
0152 
0153         newPage->subject(true)->fromUnicodeString(title, encoding);
0154         newPage->contentType(true)->setMimeType(mRichText ? "text/html" : "text/plain");
0155         newPage->contentType()->setCharset("utf-8");
0156         newPage->contentTransferEncoding(true)->setEncoding(KMime::Headers::CEquPr);
0157         newPage->date(true)->setDateTime(QDateTime::currentDateTime());
0158         newPage->from(true)->fromUnicodeString(QStringLiteral("knotes@kde4"), encoding);
0159         // Need a non-empty body part so that the serializer regards this as a valid message.
0160         newPage->mainBodyPart()->fromUnicodeString(mText.isEmpty() ? QStringLiteral(" ") : mText);
0161 
0162         newPage->assemble();
0163 
0164         newItem.setPayload(newPage);
0165 
0166         auto eda = new Akonadi::EntityDisplayAttribute();
0167 
0168         eda->setIconName(QStringLiteral("text-plain"));
0169         newItem.addAttribute(eda);
0170 
0171         auto createJob = new Akonadi::ItemCreateJob(newItem, col, this);
0172         connect(createJob, &Akonadi::ItemCreateJob::result, this, &CreateNewNoteJob::slotNoteCreationFinished);
0173     } else {
0174         deleteLater();
0175     }
0176 }
0177 
0178 void CreateNewNoteJob::slotNoteCreationFinished(KJob *job)
0179 {
0180     if (job->error()) {
0181         qCWarning(NOTESHARED_LOG) << job->errorString();
0182         NoteShared::NoteSharedGlobalConfig::self()->setDefaultFolder(-1);
0183         NoteShared::NoteSharedGlobalConfig::self()->save();
0184         KMessageBox::error(mWidget, i18n("Note was not created."), i18n("Create new note"));
0185     }
0186     deleteLater();
0187 }
0188 
0189 void CreateNewNoteJob::slotCollectionModifyFinished(KJob *job)
0190 {
0191     if (job->error()) {
0192         qCWarning(NOTESHARED_LOG) << job->errorString();
0193     }
0194 }
0195 
0196 #include "moc_createnewnotejob.cpp"