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"
14
15#include <Akonadi/CalendarUtils>
16#include <CalendarSupport/Utils>
17
18#include <KCalendarCore/Journal>
19
20#include <KCalUtils/IncidenceFormatter>
21
22#include "calendarview_debug.h"
23#include <KLocalizedString>
24#include <QTextBrowser>
25
26#include <QEvent>
27#include <QFontDatabase>
28#include <QHBoxLayout>
29#include <QPushButton>
30
31using namespace EventViews;
32
33JournalDateView::JournalDateView(const Akonadi::CollectionCalendar::Ptr &calendar, QWidget *parent)
34 : QWidget(parent)
35 , mCalendar(calendar)
36{
37 auto layout = new QVBoxLayout(this);
38 layout->setContentsMargins(0, 0, 0, 0);
39 layout->setSpacing(0);
40}
41
42JournalDateView::~JournalDateView() = default;
43
44void JournalDateView::setDate(QDate date)
45{
46 mDate = date;
47 Q_EMIT setDateSignal(date);
48}
49
50void JournalDateView::clear()
51{
52 qDeleteAll(mEntries);
53 mEntries.clear();
54}
55
56// should only be called by the JournalView now.
57void JournalDateView::addJournal(const Akonadi::Item &j)
58{
60 if (pos != mEntries.end()) {
61 return;
62 }
63
64 auto container = new QWidget(this);
65 layout()->addWidget(container);
66 auto layout = new QHBoxLayout(container);
67 layout->addStretch(1);
68 auto entry = new JournalFrame(j, mCalendar, this);
69 layout->addWidget(entry, 3 /*stretch*/);
70 layout->addStretch(1);
71
72 entry->show();
73 entry->setDate(mDate);
74 entry->setIncidenceChanger(mChanger);
75
76 mEntries.insert(j.id(), entry);
77 connect(this, &JournalDateView::setIncidenceChangerSignal, entry, &JournalFrame::setIncidenceChanger);
78 connect(this, &JournalDateView::setDateSignal, entry, &JournalFrame::setDate);
79 connect(entry, &JournalFrame::deleteIncidence, this, &JournalDateView::deleteIncidence);
80 connect(entry, &JournalFrame::editIncidence, this, &JournalDateView::editIncidence);
81 connect(entry, &JournalFrame::incidenceSelected, this, &JournalDateView::incidenceSelected);
82 connect(entry,
83 qOverload<const KCalendarCore::Journal::Ptr &, bool>(&JournalFrame::printJournal),
84 this,
85 qOverload<const KCalendarCore::Journal::Ptr &, bool>(&JournalDateView::printJournal));
86}
87
88Akonadi::Item::List JournalDateView::journals() const
89{
91 l.reserve(mEntries.count());
92 for (const JournalFrame *const i : std::as_const(mEntries)) {
93 l.push_back(i->journal());
94 }
95 return l;
96}
97
98void JournalDateView::setIncidenceChanger(Akonadi::IncidenceChanger *changer)
99{
100 mChanger = changer;
101 Q_EMIT setIncidenceChangerSignal(changer);
102}
103
104void JournalDateView::emitNewJournal()
105{
106 Q_EMIT newJournal(mDate);
107}
108
109void JournalDateView::journalEdited(const Akonadi::Item &journal)
110{
112 if (pos == mEntries.end()) {
113 return;
114 }
115
116 pos.value()->setJournal(journal);
117}
118
119void JournalDateView::journalDeleted(const Akonadi::Item &journal)
120{
122 if (pos == mEntries.end()) {
123 return;
124 }
125
126 delete pos.value();
127 mEntries.remove(journal.id());
128}
129
130JournalFrame::JournalFrame(const Akonadi::Item &j, const Akonadi::CollectionCalendar::Ptr &calendar, QWidget *parent)
131 : QFrame(parent)
132 , mJournal(j)
133 , mCalendar(calendar)
134{
135 mDirty = false;
136 mWriteInProgress = false;
137 mChanger = nullptr;
138
139 auto verticalLayout = new QVBoxLayout(this);
140
141 mBrowser = new QTextBrowser(this);
142 mBrowser->viewport()->installEventFilter(this);
143 mBrowser->setFrameStyle(QFrame::NoFrame);
144 verticalLayout->addWidget(mBrowser);
145
146 auto buttonsLayout = new QHBoxLayout();
147 verticalLayout->addLayout(buttonsLayout);
148 buttonsLayout->addStretch();
149
150 mEditButton = new QPushButton(this);
151 mEditButton->setObjectName(QLatin1StringView("editButton"));
152 mEditButton->setText(i18n("&Edit"));
153 mEditButton->setIcon(QIcon::fromTheme(QStringLiteral("document-properties")));
154 mEditButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
155 mEditButton->setToolTip(i18n("Edit this journal entry"));
156 mEditButton->setWhatsThis(i18n("Opens an editor dialog for this journal entry"));
157 buttonsLayout->addWidget(mEditButton);
158 connect(mEditButton, &QPushButton::clicked, this, &JournalFrame::editItem);
159
160 mDeleteButton = new QPushButton(this);
161 mDeleteButton->setObjectName(QLatin1StringView("deleteButton"));
162 mDeleteButton->setText(i18n("&Delete"));
163 mDeleteButton->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
164 mDeleteButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
165 mDeleteButton->setToolTip(i18n("Delete this journal entry"));
166 mDeleteButton->setWhatsThis(i18n("Delete this journal entry"));
167 buttonsLayout->addWidget(mDeleteButton);
168 connect(mDeleteButton, &QPushButton::pressed, this, &JournalFrame::deleteItem);
169
170 mPrintButton = new QPushButton(this);
171 mPrintButton->setText(i18n("&Print"));
172 mPrintButton->setObjectName(QLatin1StringView("printButton"));
173 mPrintButton->setIcon(QIcon::fromTheme(QStringLiteral("document-print")));
174 mPrintButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
175 mPrintButton->setToolTip(i18n("Print this journal entry"));
176 mPrintButton->setWhatsThis(i18n("Opens a print dialog for this journal entry"));
177 buttonsLayout->addWidget(mPrintButton);
178 connect(mPrintButton, &QPushButton::clicked, this, qOverload<>(&JournalFrame::printJournal));
179
180 mPrintPreviewButton = new QPushButton(this);
181 mPrintPreviewButton->setText(i18n("Print preview"));
182 mPrintPreviewButton->setObjectName(QLatin1StringView("printButton"));
183 mPrintPreviewButton->setIcon(QIcon::fromTheme(QStringLiteral("document-print-preview")));
184 mPrintPreviewButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
185 mPrintPreviewButton->setToolTip(i18n("Print preview this journal entry"));
186 buttonsLayout->addWidget(mPrintPreviewButton);
187 connect(mPrintPreviewButton, &QAbstractButton::clicked, this, &JournalFrame::printPreviewJournal);
188
189 readJournal(mJournal);
190 mDirty = false;
191 setFrameStyle(QFrame::Box);
192 // These probably shouldn't be hardcoded
193 setStyleSheet(QStringLiteral("QFrame { border: 1px solid; border-radius: 7px; } "));
194 mBrowser->setStyleSheet(QStringLiteral("QFrame { border: 0px solid white } "));
195}
196
197JournalFrame::~JournalFrame() = default;
198
199bool JournalFrame::eventFilter(QObject *object, QEvent *event)
200{
201 Q_UNUSED(object)
202
203 // object is our QTextBrowser
204 if (!mJournal.isValid()) {
205 return false;
206 }
207
208 switch (event->type()) {
210 Q_EMIT incidenceSelected(mJournal, mDate);
211 break;
213 Q_EMIT editIncidence(mJournal);
214 break;
215 default:
216 break;
217 }
218
219 return false;
220}
221
222void JournalFrame::deleteItem()
223{
224 if (CalendarSupport::hasJournal(mJournal)) {
225 Q_EMIT deleteIncidence(mJournal);
226 }
227}
228
229void JournalFrame::editItem()
230{
231 if (CalendarSupport::hasJournal(mJournal)) {
232 Q_EMIT editIncidence(mJournal);
233 }
234}
235
236void JournalFrame::setCalendar(const Akonadi::CollectionCalendar::Ptr &calendar)
237{
238 mCalendar = calendar;
239}
240
241void JournalFrame::setDate(QDate date)
242{
243 mDate = date;
244}
245
246void JournalFrame::setJournal(const Akonadi::Item &journal)
247{
248 if (!CalendarSupport::hasJournal(journal)) {
249 return;
250 }
251
252 mJournal = journal;
253 readJournal(journal);
254
255 mDirty = false;
256}
257
258void JournalFrame::setDirty()
259{
260 mDirty = true;
261 qCDebug(CALENDARVIEW_LOG);
262}
263
264void JournalFrame::printJournal()
265{
266 Q_EMIT printJournal(Akonadi::CalendarUtils::journal(mJournal), false);
267}
268
269void JournalFrame::printPreviewJournal()
270{
271 Q_EMIT printJournal(Akonadi::CalendarUtils::journal(mJournal), true);
272}
273
274void JournalFrame::readJournal(const Akonadi::Item &j)
275{
277 mJournal = j;
279 mBrowser->clear();
281 cursor.movePosition(QTextCursor::Start);
282
283 QTextBlockFormat bodyBlock = QTextBlockFormat(cursor.blockFormat());
284 // FIXME: Do padding
285 bodyBlock.setTextIndent(2);
286 QTextCharFormat bodyFormat = QTextCharFormat(cursor.charFormat());
287 if (!journal->summary().isEmpty()) {
288 QTextCharFormat titleFormat = bodyFormat;
289 titleFormat.setFontWeight(QFont::Bold);
290 titleFormat.setFontPointSize(baseFontSize + 4);
291 cursor.insertText(journal->summary(), titleFormat);
292 cursor.insertBlock();
293 }
294 QTextCharFormat dateFormat = bodyFormat;
295 dateFormat.setFontWeight(QFont::Bold);
296 dateFormat.setFontPointSize(baseFontSize + 1);
297 cursor.insertText(KCalUtils::IncidenceFormatter::dateTimeToString(journal->dtStart(), journal->allDay()), dateFormat);
298 cursor.insertBlock();
299 cursor.insertBlock();
300 cursor.setBlockCharFormat(bodyFormat);
301 const QString description = journal->description();
302 if (journal->descriptionIsRich()) {
303 mBrowser->insertHtml(description);
304 } else {
305 mBrowser->insertPlainText(description);
306 }
307 cursor.movePosition(QTextCursor::Start);
308 mBrowser->setTextCursor(cursor);
309 mBrowser->ensureCursorVisible();
310
311 if (mCalendar) {
312 mEditButton->setEnabled(mCalendar->hasRight(Akonadi::Collection::CanChangeItem));
313 mDeleteButton->setEnabled(mCalendar->hasRight(Akonadi::Collection::CanDeleteItem));
314 }
315}
316
317#include "moc_journalframe.cpp"
Id id() const
bool isValid() const
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 Tue Mar 26 2024 11:12:29 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.