work on ical

This commit is contained in:
Martin Rotter 2024-03-12 14:39:35 +01:00
parent 03ddb5efd2
commit 07de8e7e32
9 changed files with 152 additions and 23 deletions

View file

@ -27,8 +27,8 @@
MessagesModel::MessagesModel(QObject* parent) MessagesModel::MessagesModel(QObject* parent)
: QSqlQueryModel(parent), m_view(nullptr), m_cache(new MessagesModelCache(this)), : QSqlQueryModel(parent), m_view(nullptr), m_cache(new MessagesModelCache(this)),
m_messageHighlighter(MessageHighlighter::NoHighlighting), m_customDateFormat(QString()), m_messageHighlighter(MessageHighlighter::NoHighlighting), m_customDateFormat(QString()),
m_customTimeFormat(QString()), m_newerArticlesRelativeTime(-1), m_selectedItem(nullptr), m_customTimeFormat(QString()), m_customFormatForDatesOnly(QString()), m_newerArticlesRelativeTime(-1),
m_unreadIconType(MessageUnreadIcon::Dot), m_selectedItem(nullptr), m_unreadIconType(MessageUnreadIcon::Dot),
m_multilineListItems(qApp->settings()->value(GROUP(Messages), SETTING(Messages::MultilineArticleList)).toBool()) { m_multilineListItems(qApp->settings()->value(GROUP(Messages), SETTING(Messages::MultilineArticleList)).toBool()) {
updateFeedIconsDisplay(); updateFeedIconsDisplay();
updateDateFormat(); updateDateFormat();
@ -257,6 +257,14 @@ void MessagesModel::updateDateFormat() {
m_customTimeFormat = QString(); m_customTimeFormat = QString();
} }
if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::UseCustomFormatForDatesOnly)).toBool()) {
m_customFormatForDatesOnly =
qApp->settings()->value(GROUP(Messages), SETTING(Messages::CustomFormatForDatesOnly)).toString();
}
else {
m_customFormatForDatesOnly = QString();
}
m_newerArticlesRelativeTime = m_newerArticlesRelativeTime =
qApp->settings()->value(GROUP(Messages), SETTING(Messages::RelativeTimeForNewerArticles)).toInt(); qApp->settings()->value(GROUP(Messages), SETTING(Messages::RelativeTimeForNewerArticles)).toInt();
} }
@ -339,12 +347,17 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const {
int index_column = idx.column(); int index_column = idx.column();
if (index_column == MSG_DB_DCREATED_INDEX) { if (index_column == MSG_DB_DCREATED_INDEX) {
QDateTime dt = TextFactory::parseDateTime(QSqlQueryModel::data(idx, Qt::ItemDataRole::EditRole).value<qint64>()) QDateTime utc_dt =
.toLocalTime(); TextFactory::parseDateTime(QSqlQueryModel::data(idx, Qt::ItemDataRole::EditRole).value<qint64>());
QDateTime dt = utc_dt.toLocalTime();
if (dt.date() == QDate::currentDate() && !m_customTimeFormat.isEmpty()) { if (dt.date() == QDate::currentDate() && !m_customTimeFormat.isEmpty()) {
return dt.toString(m_customTimeFormat); return dt.toString(m_customTimeFormat);
} }
else if (!m_customFormatForDatesOnly.isEmpty() && utc_dt.time().hour() == 0 && utc_dt.time().minute() == 0 &&
utc_dt.time().second() == 0) {
return dt.toString(m_customFormatForDatesOnly);
}
else if (m_newerArticlesRelativeTime > 0 && else if (m_newerArticlesRelativeTime > 0 &&
dt.daysTo(QDateTime::currentDateTime()) <= m_newerArticlesRelativeTime) { dt.daysTo(QDateTime::currentDateTime()) <= m_newerArticlesRelativeTime) {
auto secs_difference = dt.secsTo(QDateTime::currentDateTime()); auto secs_difference = dt.secsTo(QDateTime::currentDateTime());

View file

@ -105,6 +105,7 @@ class MessagesModel : public QSqlQueryModel, public MessagesModelSqlLayer {
MessageHighlighter m_messageHighlighter; MessageHighlighter m_messageHighlighter;
QString m_customDateFormat; QString m_customDateFormat;
QString m_customTimeFormat; QString m_customTimeFormat;
QString m_customFormatForDatesOnly;
int m_newerArticlesRelativeTime; int m_newerArticlesRelativeTime;
RootItem* m_selectedItem; RootItem* m_selectedItem;
QList<QString> m_headerData; QList<QString> m_headerData;

View file

@ -95,10 +95,20 @@ SettingsFeedsMessages::SettingsFeedsMessages(Settings* settings, QWidget* parent
m_ui->m_cmbMessagesDateTimeFormat, m_ui->m_cmbMessagesDateTimeFormat,
&QComboBox::setEnabled); &QComboBox::setEnabled);
connect(m_ui->m_checkMessagesTimeFormat, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_cmbFastAutoUpdate, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_cmbFastAutoUpdate, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkMessagesTimeFormat, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkMessagesTimeFormat, &QCheckBox::toggled, m_ui->m_cmbMessagesTimeFormat, &QComboBox::setEnabled); connect(m_ui->m_checkMessagesTimeFormat, &QCheckBox::toggled, m_ui->m_cmbMessagesTimeFormat, &QComboBox::setEnabled);
connect(m_ui->m_checkMessagesDateTimeFormatForDatesOnly,
&QCheckBox::toggled,
this,
&SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkMessagesDateTimeFormatForDatesOnly,
&QCheckBox::toggled,
m_ui->m_cmbMessagesDateTimeFormatForDatesOnly,
&QComboBox::setEnabled);
connect(m_ui->m_checkRemoveReadMessagesOnExit, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkRemoveReadMessagesOnExit, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkBringToForegroundAfterMsgOpened, connect(m_ui->m_checkBringToForegroundAfterMsgOpened,
&QCheckBox::toggled, &QCheckBox::toggled,
@ -161,7 +171,12 @@ SettingsFeedsMessages::SettingsFeedsMessages(Settings* settings, QWidget* parent
&QComboBox::currentTextChanged, &QComboBox::currentTextChanged,
this, this,
&SettingsFeedsMessages::dirtifySettings); &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_cmbMessagesTimeFormat, &QComboBox::currentTextChanged, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_cmbMessagesTimeFormat, &QComboBox::currentTextChanged, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_cmbMessagesDateTimeFormatForDatesOnly,
&QComboBox::currentTextChanged,
this,
&SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_cbFixupArticleDatetime, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_cbFixupArticleDatetime, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
@ -185,6 +200,7 @@ SettingsFeedsMessages::SettingsFeedsMessages(Settings* settings, QWidget* parent
emit m_ui->m_cmbMessagesDateTimeFormat->currentTextChanged({}); emit m_ui->m_cmbMessagesDateTimeFormat->currentTextChanged({});
emit m_ui->m_cmbMessagesTimeFormat->currentTextChanged({}); emit m_ui->m_cmbMessagesTimeFormat->currentTextChanged({});
emit m_ui->m_cmbMessagesDateTimeFormatForDatesOnly->currentTextChanged({});
connect(m_ui->m_btnChangeMessagesFont, &QPushButton::clicked, this, [&]() { connect(m_ui->m_btnChangeMessagesFont, &QPushButton::clicked, this, [&]() {
changeFont(*m_ui->m_lblMessagesFont); changeFont(*m_ui->m_lblMessagesFont);
@ -220,6 +236,7 @@ void SettingsFeedsMessages::initializeMessageDateFormats() {
m_ui->m_cmbMessagesDateTimeFormat->addItems(patterns); m_ui->m_cmbMessagesDateTimeFormat->addItems(patterns);
m_ui->m_cmbMessagesTimeFormat->addItems(patterns); m_ui->m_cmbMessagesTimeFormat->addItems(patterns);
m_ui->m_cmbMessagesDateTimeFormatForDatesOnly->addItems(patterns);
for (int i = 0; i < patterns.size(); i++) { for (int i = 0; i < patterns.size(); i++) {
m_ui->m_cmbMessagesDateTimeFormat->setItemData(i, m_ui->m_cmbMessagesDateTimeFormat->setItemData(i,
@ -228,6 +245,9 @@ void SettingsFeedsMessages::initializeMessageDateFormats() {
m_ui->m_cmbMessagesTimeFormat->setItemData(i, m_ui->m_cmbMessagesTimeFormat->setItemData(i,
QDateTime::currentDateTime().toString(patterns.at(i)), QDateTime::currentDateTime().toString(patterns.at(i)),
Qt::ItemDataRole::ToolTipRole); Qt::ItemDataRole::ToolTipRole);
m_ui->m_cmbMessagesDateTimeFormatForDatesOnly->setItemData(i,
QDateTime::currentDateTime().toString(patterns.at(i)),
Qt::ItemDataRole::ToolTipRole);
} }
} }
@ -322,6 +342,11 @@ void SettingsFeedsMessages::loadSettings() {
m_ui->m_cmbMessagesTimeFormat m_ui->m_cmbMessagesTimeFormat
->setCurrentText(settings()->value(GROUP(Messages), SETTING(Messages::CustomTimeFormat)).toString()); ->setCurrentText(settings()->value(GROUP(Messages), SETTING(Messages::CustomTimeFormat)).toString());
m_ui->m_checkMessagesDateTimeFormatForDatesOnly
->setChecked(settings()->value(GROUP(Messages), SETTING(Messages::UseCustomFormatForDatesOnly)).toBool());
m_ui->m_cmbMessagesDateTimeFormatForDatesOnly
->setCurrentText(settings()->value(GROUP(Messages), SETTING(Messages::CustomFormatForDatesOnly)).toString());
QFont fon; QFont fon;
fon.fromString(settings()->value(GROUP(Messages), SETTING(Messages::PreviewerFontStandard)).toString()); fon.fromString(settings()->value(GROUP(Messages), SETTING(Messages::PreviewerFontStandard)).toString());
@ -434,12 +459,20 @@ void SettingsFeedsMessages::saveSettings() {
settings()->setValue(GROUP(Messages), settings()->setValue(GROUP(Messages),
Messages::AlwaysDisplayItemPreview, Messages::AlwaysDisplayItemPreview,
m_ui->m_cbArticleViewerAlwaysVisible->isChecked()); m_ui->m_cbArticleViewerAlwaysVisible->isChecked());
settings()->setValue(GROUP(Messages), Messages::UseCustomDate, m_ui->m_checkMessagesDateTimeFormat->isChecked()); settings()->setValue(GROUP(Messages), Messages::UseCustomDate, m_ui->m_checkMessagesDateTimeFormat->isChecked());
settings()->setValue(GROUP(Messages), Messages::UseCustomTime, m_ui->m_checkMessagesTimeFormat->isChecked()); settings()->setValue(GROUP(Messages), Messages::UseCustomTime, m_ui->m_checkMessagesTimeFormat->isChecked());
settings()->setValue(GROUP(Messages), Messages::CustomDateFormat, m_ui->m_cmbMessagesDateTimeFormat->currentText()); settings()->setValue(GROUP(Messages), Messages::CustomDateFormat, m_ui->m_cmbMessagesDateTimeFormat->currentText());
settings()->setValue(GROUP(Messages), Messages::CustomTimeFormat, m_ui->m_cmbMessagesTimeFormat->currentText()); settings()->setValue(GROUP(Messages), Messages::CustomTimeFormat, m_ui->m_cmbMessagesTimeFormat->currentText());
settings()->setValue(GROUP(Messages),
Messages::UseCustomFormatForDatesOnly,
m_ui->m_checkMessagesDateTimeFormatForDatesOnly->isChecked());
settings()->setValue(GROUP(Messages),
Messages::CustomFormatForDatesOnly,
m_ui->m_cmbMessagesDateTimeFormatForDatesOnly->currentText());
// Save fonts. // Save fonts.
settings()->setValue(GROUP(Messages), Messages::PreviewerFontStandard, m_ui->m_lblMessagesFont->font().toString()); settings()->setValue(GROUP(Messages), Messages::PreviewerFontStandard, m_ui->m_lblMessagesFont->font().toString());
settings()->setValue(GROUP(Messages), Messages::ListFont, m_ui->m_lblMessageListFont->font().toString()); settings()->setValue(GROUP(Messages), Messages::ListFont, m_ui->m_lblMessageListFont->font().toString());

View file

@ -14,7 +14,7 @@
<item> <item>
<widget class="QTabWidget" name="m_tabFeedsMessages"> <widget class="QTabWidget" name="m_tabFeedsMessages">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>3</number>
</property> </property>
<widget class="QWidget" name="m_tabFeeds"> <widget class="QWidget" name="m_tabFeeds">
<attribute name="title"> <attribute name="title">
@ -428,6 +428,19 @@
<string>Articles list</string> <string>Articles list</string>
</attribute> </attribute>
<layout class="QFormLayout" name="formLayout_5"> <layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Unread article icon type</string>
</property>
<property name="buddy">
<cstring>m_cmbUnreadIconType</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="m_cmbUnreadIconType"/>
</item>
<item row="1" column="0" colspan="2"> <item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="m_checkKeppMessagesInTheMiddle"> <widget class="QCheckBox" name="m_checkKeppMessagesInTheMiddle">
<property name="text"> <property name="text">
@ -536,7 +549,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="0"> <item row="8" column="0">
<widget class="QCheckBox" name="m_checkMessagesTimeFormat"> <widget class="QCheckBox" name="m_checkMessagesTimeFormat">
<property name="text"> <property name="text">
<string>Custom date/time format for today's articles</string> <string>Custom date/time format for today's articles</string>
@ -549,7 +562,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1"> <item row="8" column="1">
<widget class="QComboBox" name="m_cmbMessagesTimeFormat"> <widget class="QComboBox" name="m_cmbMessagesTimeFormat">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
@ -562,14 +575,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="0"> <item row="9" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Show relative time for articles not older than</string> <string>Show relative time for articles not older than</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1"> <item row="9" column="1">
<widget class="QSpinBox" name="m_spinRelativeArticleTime"> <widget class="QSpinBox" name="m_spinRelativeArticleTime">
<property name="minimum"> <property name="minimum">
<number>-1</number> <number>-1</number>
@ -579,7 +592,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="0"> <item row="10" column="0">
<widget class="QGroupBox" name="m_gbArticleListFont"> <widget class="QGroupBox" name="m_gbArticleListFont">
<property name="title"> <property name="title">
<string>Article list font</string> <string>Article list font</string>
@ -611,16 +624,29 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="7" column="1">
<widget class="QComboBox" name="m_cmbUnreadIconType"/> <widget class="QComboBox" name="m_cmbMessagesDateTimeFormatForDatesOnly">
</item> <property name="minimumSize">
<item row="0" column="0"> <size>
<widget class="QLabel" name="label_5"> <width>150</width>
<property name="text"> <height>0</height>
<string>Unread article icon type</string> </size>
</property> </property>
<property name="buddy"> <property name="editable">
<cstring>m_cmbUnreadIconType</cstring> <bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="m_checkMessagesDateTimeFormatForDatesOnly">
<property name="text">
<string>Use custom date/time format for dates-only</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>

View file

@ -191,6 +191,12 @@ DVALUE(bool) Messages::UseCustomDateDef = false;
DKEY Messages::CustomDateFormat = "custom_date_format"; DKEY Messages::CustomDateFormat = "custom_date_format";
DVALUE(char*) Messages::CustomDateFormatDef = ""; DVALUE(char*) Messages::CustomDateFormatDef = "";
DKEY Messages::CustomFormatForDatesOnly = "custom_date_format_for_dates_only";
DVALUE(char*) Messages::CustomFormatForDatesOnlyDef = "";
DKEY Messages::UseCustomFormatForDatesOnly = "use_custom_date_for_dates_only";
DVALUE(bool) Messages::UseCustomFormatForDatesOnlyDef = false;
DKEY Messages::RelativeTimeForNewerArticles = "relative_time_for_new_articles"; DKEY Messages::RelativeTimeForNewerArticles = "relative_time_for_new_articles";
DVALUE(int) Messages::RelativeTimeForNewerArticlesDef = -1; DVALUE(int) Messages::RelativeTimeForNewerArticlesDef = -1;

View file

@ -191,6 +191,12 @@ namespace Messages {
KEY UseCustomTime; KEY UseCustomTime;
VALUE(bool) UseCustomTimeDef; VALUE(bool) UseCustomTimeDef;
KEY CustomFormatForDatesOnly;
VALUE(char*) CustomFormatForDatesOnlyDef;
KEY UseCustomFormatForDatesOnly;
VALUE(bool) UseCustomFormatForDatesOnlyDef;
KEY RelativeTimeForNewerArticles; KEY RelativeTimeForNewerArticles;
VALUE(int) RelativeTimeForNewerArticlesDef; VALUE(int) RelativeTimeForNewerArticlesDef;

View file

@ -81,6 +81,11 @@ bool TextFactory::couldBeHtml(const QString& string) {
QDateTime TextFactory::parseDateTime(const QString& date_time) { QDateTime TextFactory::parseDateTime(const QString& date_time) {
const QString input_date = date_time.simplified(); const QString input_date = date_time.simplified();
if (input_date.isEmpty()) {
return QDateTime();
}
QDateTime dt; QDateTime dt;
QTime time_zone_offset; QTime time_zone_offset;
const QLocale locale(QLocale::Language::C); const QLocale locale(QLocale::Language::C);

View file

@ -2,6 +2,7 @@
#include "services/standard/parsers/icalparser.h" #include "services/standard/parsers/icalparser.h"
#include "3rd-party/boolinq/boolinq.h"
#include "definitions/definitions.h" #include "definitions/definitions.h"
#include "exceptions/applicationexception.h" #include "exceptions/applicationexception.h"
#include "exceptions/feedrecognizedbutfailedexception.h" #include "exceptions/feedrecognizedbutfailedexception.h"
@ -122,7 +123,7 @@ QDateTime IcalParser::objMessageDateCreated(const QVariant& msg_element) const {
const IcalendarComponent& comp_base = msg_element.value<IcalendarComponent>(); const IcalendarComponent& comp_base = msg_element.value<IcalendarComponent>();
const EventComponent& comp = static_cast<const EventComponent&>(comp_base); const EventComponent& comp = static_cast<const EventComponent&>(comp_base);
return comp.created(); return comp.startsOn();
} }
QString IcalParser::objMessageId(const QVariant& msg_element) const { QString IcalParser::objMessageId(const QVariant& msg_element) const {
@ -161,7 +162,7 @@ void Icalendar::setTitle(const QString& title) {
} }
void Icalendar::processLines(const QString& data) { void Icalendar::processLines(const QString& data) {
QRegularExpression regex("^BEGIN:(\\w+)\\r$(.+?)^(BEGIN|END):\\w+", QRegularExpression regex("^BEGIN:(\\w+)\\r$(.+?)(?=^BEGIN|^END)",
QRegularExpression::PatternOption::MultilineOption | QRegularExpression::PatternOption::MultilineOption |
QRegularExpression::PatternOption::DotMatchesEverythingOption); QRegularExpression::PatternOption::DotMatchesEverythingOption);
@ -199,7 +200,7 @@ void Icalendar::processComponentEvent(const QString& body) {
} }
QVariantMap Icalendar::tokenizeBody(const QString& body) const { QVariantMap Icalendar::tokenizeBody(const QString& body) const {
QRegularExpression regex("^(?=[A-Z-]+:)", QRegularExpression::PatternOption::MultilineOption); QRegularExpression regex("^(?=[A-Z-]+(?:;[A-Z]+=[A-Z]+)?:)", QRegularExpression::PatternOption::MultilineOption);
auto all_matches = body.split(regex); auto all_matches = body.split(regex);
QVariantMap res; QVariantMap res;
@ -234,6 +235,30 @@ void IcalendarComponent::setProperties(const QVariantMap& properties) {
m_properties = properties; m_properties = properties;
} }
QVariant IcalendarComponent::getPropertyValue(const QString& property_name) const {
if (m_properties.contains(property_name)) {
return m_properties.value(property_name);
}
QStringList keys = m_properties.keys();
auto linq = boolinq::from(keys);
QString found_key = linq.firstOrDefault([&](const QString& ky) {
int index_sep = ky.indexOf(';');
return ky.startsWith(property_name) && index_sep == property_name.size();
});
return m_properties.value(found_key);
}
QDateTime EventComponent::startsOn() const {
return TextFactory::parseDateTime(getPropertyValue(QSL("DTSTART")).toString());
}
QDateTime EventComponent::endsOn() const {
return TextFactory::parseDateTime(m_properties.value(QSL("DTEND")).toString());
}
QString EventComponent::title() const { QString EventComponent::title() const {
return m_properties.value(QSL("SUMMARY")).toString(); return m_properties.value(QSL("SUMMARY")).toString();
} }
@ -246,6 +271,10 @@ QString EventComponent::organizer() const {
return m_properties.value(QSL("ORGANIZER")).toString(); return m_properties.value(QSL("ORGANIZER")).toString();
} }
QString EventComponent::location() const {
return m_properties.value(QSL("LOCATION")).toString();
}
QString EventComponent::description() const { QString EventComponent::description() const {
return m_properties.value(QSL("DESCRIPTION")).toString(); return m_properties.value(QSL("DESCRIPTION")).toString();
} }
@ -253,3 +282,7 @@ QString EventComponent::description() const {
QDateTime EventComponent::created() const { QDateTime EventComponent::created() const {
return TextFactory::parseDateTime(m_properties.value(QSL("CREATED")).toString()); return TextFactory::parseDateTime(m_properties.value(QSL("CREATED")).toString());
} }
QDateTime EventComponent::lastModified() const {
return TextFactory::parseDateTime(m_properties.value(QSL("LAST-MODIFIED")).toString());
}

View file

@ -13,6 +13,8 @@ class IcalendarComponent {
void setProperties(const QVariantMap& properties); void setProperties(const QVariantMap& properties);
protected: protected:
QVariant getPropertyValue(const QString& property_name) const;
QVariantMap m_properties; QVariantMap m_properties;
}; };
@ -20,11 +22,15 @@ Q_DECLARE_METATYPE(IcalendarComponent)
class EventComponent : public IcalendarComponent { class EventComponent : public IcalendarComponent {
public: public:
QDateTime startsOn() const;
QDateTime endsOn() const;
QString title() const; QString title() const;
QString url() const; QString url() const;
QString organizer() const; QString organizer() const;
QString location() const;
QString description() const; QString description() const;
QDateTime created() const; QDateTime created() const;
QDateTime lastModified() const;
}; };
Q_DECLARE_METATYPE(EventComponent) Q_DECLARE_METATYPE(EventComponent)