Eventviews

journalframe.cpp
1/*
2 This file is part of KOrganizer.
3
4 SPDX-FileCopyrightText: 2001 Cornelius Schumacher <schumacher@kde.org>
5 SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
6 SPDX-FileCopyrightText: 2007 Mike McQuaid <mike@mikemcquaid.com>
7
8 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
9*/
10
11// Journal Entry
12
13#include "journalframe.h"
14using namespace Qt::Literals::StringLiterals;
15
16#include <Akonadi/CalendarUtils>
17#include <CalendarSupport/Utils>
18
19#include <KCalendarCore/Journal>
20
21#include <KCalUtils/IncidenceFormatter>
22
23#include "calendarview_debug.h"
24#include <KLocalizedString>
25#include <QTextBrowser>
26
27#include <QEvent>
28#include <QFontDatabase>
29#include <QHBoxLayout>
30#include <QPushButton>
31
32using namespace EventViews;
33
34JournalDateView::JournalDateView(const Akonadi::CollectionCalendar::Ptr &calendar, QWidget *parent)
35 : QWidget(parent)
36 , mCalendar(calendar)
37{
38 auto layout = new QVBoxLayout(this);
39 layout->setContentsMargins({});
40 layout->setSpacing(0);
41}
42
43JournalDateView::~JournalDateView() = default;
44
45void JournalDateView::setDate(QDate date)
46{
47 mDate = date;
48 Q_EMIT setDateSignal(date);
49}
50
51void JournalDateView::clear()
52{
53 qDeleteAll(mEntries);
54 mEntries.clear();
55}
56
57// should only be called by the JournalView now.
58void JournalDateView::addJournal(const Akonadi::Item &j)
59{
61 if (pos != mEntries.end()) {
62 return;
63 }
64
65 auto container = new QWidget(this);
66 layout()->addWidget(container);
67 auto layout = new QHBoxLayout(container);
68 layout->addStretch(1);
69 auto entry = new JournalFrame(j, mCalendar, this);
70 layout->addWidget(entry, 3 /*stretch*/);
71 layout->addStretch(1);
72
73 entry->show();
74 entry->setDate(mDate);
75 entry->setIncidenceChanger(mChanger);
76
77 mEntries.insert(j.id(), entry);
78 connect(this, &JournalDateView::setIncidenceChangerSignal, entry, &JournalFrame::setIncidenceChanger);
79 connect(this, &JournalDateView::setDateSignal, entry, &JournalFrame::setDate);
80 connect(entry, &JournalFrame::deleteIncidence, this, &JournalDateView::deleteIncidence);
81 connect(entry, &JournalFrame::editIncidence, this, &JournalDateView::editIncidence);
82 connect(entry, &JournalFrame::incidenceSelected, this, &JournalDateView::incidenceSelected);
83 connect(entry,
84 qOverload<const KCalendarCore::Journal::Ptr &, bool>(&JournalFrame::printJournal),
85 this,
86 qOverload<const KCalendarCore::Journal::Ptr &, bool>(&JournalDateView::printJournal));
87}
88
89Akonadi::Item::List JournalDateView::journals() const
90{
92 l.reserve(mEntries.count());
93 for (const JournalFrame *const i : std::as_const(mEntries)) {
94 l.push_back(i->journal());
95 }
96 return l;
97}
98
99void JournalDateView::setIncidenceChanger(Akonadi::IncidenceChanger *changer)
100{
101 mChanger = changer;
102 Q_EMIT setIncidenceChangerSignal(changer);
103}
104
105void JournalDateView::emitNewJournal()
106{
107 Q_EMIT newJournal(mDate);
108}
109
110void JournalDateView::journalEdited(const Akonadi::Item &journal)
111{
113 if (pos == mEntries.end()) {
114 return;
115 }
116
117 pos.value()->setJournal(journal);
118}
119
120void JournalDateView::journalDeleted(const Akonadi::Item &journal)
121{
123 if (pos == mEntries.end()) {
124 return;
125 }
126
127 delete pos.value();
128 mEntries.remove(journal.id());
129}
130
131JournalFrame::JournalFrame(const Akonadi::Item &j, const Akonadi::CollectionCalendar::Ptr &calendar, QWidget *parent)
132 : QFrame(parent)
133 , mJournal(j)
134 , mCalendar(calendar)
135{
136 mDirty = false;
137 mWriteInProgress = false;
138 mChanger = nullptr;
139
140 auto verticalLayout = new QVBoxLayout(this);
141
142 mBrowser = new QTextBrowser(this);
143 mBrowser->viewport()->installEventFilter(this);
144 mBrowser->setFrameStyle(QFrame::NoFrame);
145 verticalLayout->addWidget(mBrowser);
146
147 auto buttonsLayout = new QHBoxLayout();
148 verticalLayout->addLayout(buttonsLayout);
149 buttonsLayout->addStretch();
150
151 mEditButton = new QPushButton(this);
152 mEditButton->setObjectName("editButton"_L1);
153 mEditButton->setText(i18n("&Edit"));
154 mEditButton->setIcon(QIcon::fromTheme(QStringLiteral("document-properties")));
155 mEditButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
156 mEditButton->setToolTip(i18nc("@info:tooltip", "Edit this journal entry"));
157 mEditButton->setWhatsThis(i18n("Opens an editor dialog for this journal entry"));
158 buttonsLayout->addWidget(mEditButton);
159 connect(mEditButton, &QPushButton::clicked, this, &JournalFrame::editItem);
160
161 mDeleteButton = new QPushButton(this);
162 mDeleteButton->setObjectName("deleteButton"_L1);
163 mDeleteButton->setText(i18n("&Delete"));
164 mDeleteButton->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
165 mDeleteButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
166 mDeleteButton->setToolTip(i18nc("@info:tooltip", "Delete this journal entry"));
167 mDeleteButton->setWhatsThis(i18n("Delete this journal entry"));
168 buttonsLayout->addWidget(mDeleteButton);
169 connect(mDeleteButton, &QPushButton::pressed, this, &JournalFrame::deleteItem);
170
171 mPrintButton = new QPushButton(this);
172 mPrintButton->setText(i18n("&Print"));
173 mPrintButton->setObjectName("printButton"_L1);
174 mPrintButton->setIcon(QIcon::fromTheme(QStringLiteral("document-print")));
175 mPrintButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
176 mPrintButton->setToolTip(i18nc("@info:tooltip", "Print this journal entry"));
177 mPrintButton->setWhatsThis(i18n("Opens a print dialog for this journal entry"));
178 buttonsLayout->addWidget(mPrintButton);
179 connect(mPrintButton, &QPushButton::clicked, this, qOverload<>(&JournalFrame::printJournal));
180
181 mPrintPreviewButton = new QPushButton(this);
182 mPrintPreviewButton->setText(i18n("Print preview"));
183 mPrintPreviewButton->setObjectName("printButton"_L1);
184 mPrintPreviewButton->setIcon(QIcon::fromTheme(QStringLiteral("document-print-preview")));
185 mPrintPreviewButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
186 mPrintPreviewButton->setToolTip(i18nc("@info:tooltip", "Print preview this journal entry"));
187 buttonsLayout->addWidget(mPrintPreviewButton);
188 connect(mPrintPreviewButton, &QAbstractButton::clicked, this, &JournalFrame::printPreviewJournal);
189
190 readJournal(mJournal);
191 mDirty = false;
192 setFrameStyle(QFrame::Box);
193 // These probably shouldn't be hardcoded
194 setStyleSheet(QStringLiteral("QFrame { border: 1px solid; border-radius: 7px; } "));
195 mBrowser->setStyleSheet(QStringLiteral("QFrame { border: 0px solid white } "));
196}
197
198JournalFrame::~JournalFrame() = default;
199
200bool JournalFrame::eventFilter(QObject *object, QEvent *event)
201{
202 Q_UNUSED(object)
203
204 // object is our QTextBrowser
205 if (!mJournal.isValid()) {
206 return false;
207 }
208
209 switch (event->type()) {
211 Q_EMIT incidenceSelected(mJournal, mDate);
212 break;
214 Q_EMIT editIncidence(mJournal);
215 break;
216 default:
217 break;
218 }
219
220 return false;
221}
222
223void JournalFrame::deleteItem()
224{
225 if (CalendarSupport::hasJournal(mJournal)) {
226 Q_EMIT deleteIncidence(mJournal);
227 }
228}
229
230void JournalFrame::editItem()
231{
232 if (CalendarSupport::hasJournal(mJournal)) {
233 Q_EMIT editIncidence(mJournal);
234 }
235}
236
237void JournalFrame::setCalendar(const Akonadi::CollectionCalendar::Ptr &calendar)
238{
239 mCalendar = calendar;
240}
241
242void JournalFrame::setDate(QDate date)
243{
244 mDate = date;
245}
246
247void JournalFrame::setJournal(const Akonadi::Item &journal)
248{
249 if (!CalendarSupport::hasJournal(journal)) {
250 return;
251 }
252
253 mJournal = journal;
254 readJournal(journal);
255
256 mDirty = false;
257}
258
259void JournalFrame::setDirty()
260{
261 mDirty = true;
262 qCDebug(CALENDARVIEW_LOG);
263}
264
265void JournalFrame::printJournal()
266{
267 Q_EMIT printJournal(Akonadi::CalendarUtils::journal(mJournal), false);
268}
269
270void JournalFrame::printPreviewJournal()
271{
272 Q_EMIT printJournal(Akonadi::CalendarUtils::journal(mJournal), true);
273}
274
275void JournalFrame::readJournal(const Akonadi::Item &j)
276{
278 mJournal = j;
280 mBrowser->clear();
282 cursor.movePosition(QTextCursor::Start);
283
284 QTextBlockFormat bodyBlock = QTextBlockFormat(cursor.blockFormat());
285 // FIXME: Do padding
286 bodyBlock.setTextIndent(2);
287 QTextCharFormat bodyFormat = QTextCharFormat(cursor.charFormat());
288 if (!journal->summary().isEmpty()) {
289 QTextCharFormat titleFormat = bodyFormat;
290 titleFormat.setFontWeight(QFont::Bold);
291 titleFormat.setFontPointSize(baseFontSize + 4);
292 cursor.insertText(journal->summary(), titleFormat);
293 cursor.insertBlock();
294 }
295 QTextCharFormat dateFormat = bodyFormat;
296 dateFormat.setFontWeight(QFont::Bold);
297 dateFormat.setFontPointSize(baseFontSize + 1);
298 cursor.insertText(KCalUtils::IncidenceFormatter::dateTimeToString(journal->dtStart(), journal->allDay()), dateFormat);
299 cursor.insertBlock();
300 cursor.insertBlock();
301 cursor.setBlockCharFormat(bodyFormat);
302 const QString description = journal->description();
303 if (journal->descriptionIsRich()) {
304 mBrowser->insertHtml(description);
305 } else {
306 mBrowser->insertPlainText(description);
307 }
308 cursor.movePosition(QTextCursor::Start);
309 mBrowser->setTextCursor(cursor);
310 mBrowser->ensureCursorVisible();
311
312 if (mCalendar) {
313 mEditButton->setEnabled(mCalendar->hasRight(Akonadi::Collection::CanChangeItem));
314 mDeleteButton->setEnabled(mCalendar->hasRight(Akonadi::Collection::CanDeleteItem));
315 }
316}
317
318#include "moc_journalframe.cpp"
Id id() const
bool isValid() const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
AKONADI_CALENDAR_EXPORT KCalendarCore::Journal::Ptr journal(const Akonadi::Item &item)
Namespace EventViews provides facilities for displaying incidences, including events,...
Definition agenda.h:33
KCALUTILS_EXPORT QString dateTimeToString(const QDateTime &date, bool dateOnly=false, bool shortfmt=true)
void clicked(bool checked)
MouseButtonPress
int pointSize() const const
QFont systemFont(SystemFont type)
virtual bool event(QEvent *e) override
QIcon fromTheme(const QString &name)
void addWidget(QWidget *w)
void push_back(parameter_type value)
void reserve(qsizetype size)
void clear()
size_type count() const const
iterator end()
iterator find(const Key &key)
iterator insert(const Key &key, const T &value)
size_type remove(const Key &key)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void setTextIndent(qreal indent)
void setFontPointSize(qreal size)
void setFontWeight(int weight)
void clear()
void ensureCursorVisible()
void insertHtml(const QString &text)
void insertPlainText(const QString &text)
void setTextCursor(const QTextCursor &cursor)
QTextCursor textCursor() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QWidget(QWidget *parent, Qt::WindowFlags f)
void setEnabled(bool)
QLayout * layout() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:07:11 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.