Commit 780a97fb authored by David Jarvie's avatar David Jarvie
Browse files

Merge branch 'release/20.04'

parents 6e96b772 9fff6cba
......@@ -6,8 +6,9 @@ KAlarm Change Log
+ Show alarm calendars sorted by name in calendars list.
+ Refactor AlarmCalendar to split out resources and display calendars.
=== Version 2.14.1 (KDE Applications 20.04.1) --- 9 May 2020 ===
=== Version 2.14.1 (KDE Applications 20.04.1) --- 11 May 2020 ===
+ Correctly interpret resource IDs in command line and DBus calls.
+ Fix sizing and reconfiguration of columns in alarm and template lists.
=== Version 2.14.0 (KDE Applications 20.04) --- 27 March 2020 ===
+ Warn user if archiving but no default archived alarms calendar is set.
......
/*
* alarmlistview.cpp - widget showing list of alarms
* Program: kalarm
* Copyright © 2007,2008,2010,2019 David Jarvie <djarvie@kde.org>
* Copyright © 2007-2020 David Jarvie <djarvie@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -37,30 +37,7 @@ AlarmListView::AlarmListView(const QByteArray& configGroup, QWidget* parent)
, mConfigGroup(configGroup)
{
setEditOnSingleClick(true);
connect(header(), &QHeaderView::sectionMoved, this, &AlarmListView::sectionMoved);
}
void AlarmListView::setModel(QAbstractItemModel* model)
{
EventListView::setModel(model);
KConfigGroup config(KSharedConfig::openConfig(), mConfigGroup.constData());
const QByteArray settings = config.readEntry("ListHead", QByteArray());
if (!settings.isEmpty())
header()->restoreState(settings);
header()->setSectionsMovable(true);
header()->setStretchLastSection(false);
header()->setSectionResizeMode(AlarmListModel::TimeColumn, QHeaderView::ResizeToContents);
header()->setSectionResizeMode(AlarmListModel::TimeToColumn, QHeaderView::ResizeToContents);
header()->setSectionResizeMode(AlarmListModel::RepeatColumn, QHeaderView::ResizeToContents);
header()->setSectionResizeMode(AlarmListModel::ColourColumn, QHeaderView::Fixed);
header()->setSectionResizeMode(AlarmListModel::TypeColumn, QHeaderView::Fixed);
header()->setSectionResizeMode(AlarmListModel::TextColumn, QHeaderView::Stretch);
header()->setStretchLastSection(true); // necessary to ensure ResizeToContents columns do resize to contents!
const int minWidth = viewOptions().fontMetrics.lineSpacing() * 3 / 4;
header()->setMinimumSectionSize(minWidth);
const int margin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin);
header()->resizeSection(AlarmListModel::ColourColumn, minWidth);
header()->resizeSection(AlarmListModel::TypeColumn, AlarmListModel::iconWidth() + 2*margin + 2);
connect(header(), &QHeaderView::sectionMoved, this, &AlarmListView::saveColumnsState);
header()->setContextMenuPolicy(Qt::CustomContextMenu);
connect(header(), &QWidget::customContextMenuRequested, this, &AlarmListView::headerContextMenuRequested);
}
......@@ -97,11 +74,35 @@ void AlarmListView::setColumnsVisible(const QList<bool>& show)
sortByColumn(vis[0] ? AlarmListModel::TimeColumn : AlarmListModel::TimeToColumn, Qt::AscendingOrder);
}
/******************************************************************************
* Initialize column settings and sizing.
*/
void AlarmListView::initSections()
{
KConfigGroup config(KSharedConfig::openConfig(), mConfigGroup.constData());
const QByteArray settings = config.readEntry("ListHead", QByteArray());
if (!settings.isEmpty())
header()->restoreState(settings);
header()->setSectionsMovable(true);
header()->setSectionResizeMode(AlarmListModel::TimeColumn, QHeaderView::ResizeToContents);
header()->setSectionResizeMode(AlarmListModel::TimeToColumn, QHeaderView::ResizeToContents);
header()->setSectionResizeMode(AlarmListModel::RepeatColumn, QHeaderView::ResizeToContents);
header()->setSectionResizeMode(AlarmListModel::ColourColumn, QHeaderView::Fixed);
header()->setSectionResizeMode(AlarmListModel::TypeColumn, QHeaderView::Fixed);
header()->setSectionResizeMode(AlarmListModel::TextColumn, QHeaderView::Stretch);
header()->setStretchLastSection(true); // necessary to ensure ResizeToContents columns do resize to contents!
const int minWidth = viewOptions().fontMetrics.lineSpacing() * 3 / 4;
header()->setMinimumSectionSize(minWidth);
const int margin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin);
header()->resizeSection(AlarmListModel::ColourColumn, minWidth);
header()->resizeSection(AlarmListModel::TypeColumn, AlarmListModel::iconWidth() + 2*margin + 2);
}
/******************************************************************************
* Called when the column order is changed.
* Save the new order for restoration on program restart.
*/
void AlarmListView::sectionMoved()
void AlarmListView::saveColumnsState()
{
KConfigGroup config(KSharedConfig::openConfig(), mConfigGroup.constData());
config.writeEntry("ListHead", header()->saveState());
......@@ -149,6 +150,7 @@ void AlarmListView::showHideColumn(QMenu& menu, QAction* act)
header()->setSectionHidden(col, !show);
if (col == AlarmListModel::TimeColumn || col == AlarmListModel::TimeToColumn)
enableTimeColumns(&menu);
saveColumnsState();
Q_EMIT columnsVisibleChanged();
}
......
/*
* alarmlistview.h - widget showing list of alarms
* Program: kalarm
* Copyright © 2007,2019 David Jarvie <djarvie@kde.org>
* Copyright © 2007-2020 David Jarvie <djarvie@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -28,25 +28,27 @@
class AlarmListView : public EventListView
{
Q_OBJECT
public:
explicit AlarmListView(const QByteArray& configGroup, QWidget* parent = nullptr);
void setModel(QAbstractItemModel*) override;
QList<bool> columnsVisible() const;
void setColumnsVisible(const QList<bool>& show);
Q_OBJECT
public:
explicit AlarmListView(const QByteArray& configGroup, QWidget* parent = nullptr);
QList<bool> columnsVisible() const;
void setColumnsVisible(const QList<bool>& show);
Q_SIGNALS:
void columnsVisibleChanged();
Q_SIGNALS:
void columnsVisibleChanged();
private Q_SLOTS:
void sectionMoved();
void headerContextMenuRequested(const QPoint&);
protected Q_SLOTS:
void initSections() override;
private:
void showHideColumn(QMenu&, QAction*);
void enableTimeColumns(QMenu*);
private Q_SLOTS:
void saveColumnsState();
void headerContextMenuRequested(const QPoint&);
QByteArray mConfigGroup;
private:
void showHideColumn(QMenu&, QAction*);
void enableTimeColumns(QMenu*);
QByteArray mConfigGroup;
};
#endif // ALARMLISTVIEW_H
......
......@@ -102,7 +102,6 @@ inline uint qHash(const EventId& eid, uint seed)
uint h1 = qHash(eid.eventId(), seed);
uint h2 = qHash(eid.resourceId(), seed);
return ((h1 << 16) | (h1 >> 16)) ^ h2 ^ seed;
}
inline QDebug operator<<(QDebug s, const EventId& id)
......
/*
* eventlistview.cpp - base class for widget showing list of alarms
* Program: kalarm
* Copyright © 2007-2019 David Jarvie <djarvie@kde.org>
* Copyright © 2007-2020 David Jarvie <djarvie@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -44,6 +44,15 @@ EventListView::EventListView(QWidget* parent)
setWhatsThis(i18nc("@info:whatsthis", "List of scheduled alarms"));
}
void EventListView::setModel(QAbstractItemModel* model)
{
EventListModel* elm = qobject_cast<EventListModel*>(model);
Q_ASSERT(elm); // model must be derived from EventListModel
QTreeView::setModel(model);
connect(elm, &EventListModel::haveEventsStatus, this, &EventListView::initSections);
}
/******************************************************************************
* Return the source data model.
*/
......@@ -146,6 +155,12 @@ void EventListView::findNext(bool forward)
mFind->findNext(forward);
}
void EventListView::resizeEvent(QResizeEvent* se)
{
QTreeView::resizeEvent(se);
initSections();
}
/******************************************************************************
* Called when a ToolTip or WhatsThis event occurs.
*/
......
/*
* eventlistview.h - base class for widget showing list of alarms
* Program: kalarm
* Copyright © 2007-2019 David Jarvie <djarvie@kde.org>
* Copyright © 2007-2020 David Jarvie <djarvie@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -33,39 +33,45 @@ using namespace KAlarmCal;
class EventListView : public QTreeView
{
Q_OBJECT
public:
explicit EventListView(QWidget* parent = nullptr);
EventListModel* itemModel() const;
KAEvent event(int row) const;
KAEvent event(const QModelIndex&) const;
void select(const QModelIndex&, bool scrollToIndex = false);
void clearSelection();
QModelIndex selectedIndex() const;
KAEvent selectedEvent() const;
QVector<KAEvent> selectedEvents() const;
void setEditOnSingleClick(bool e) { mEditOnSingleClick = e; }
bool editOnSingleClick() const { return mEditOnSingleClick; }
public Q_SLOTS:
virtual void slotFind();
virtual void slotFindNext() { findNext(true); }
virtual void slotFindPrev() { findNext(false); }
Q_SIGNALS:
void contextMenuRequested(const QPoint& globalPos);
void findActive(bool);
protected:
bool viewportEvent(QEvent*) override;
void contextMenuEvent(QContextMenuEvent*) override;
private:
void findNext(bool forward);
Find* mFind {nullptr};
bool mEditOnSingleClick {false};
using QObject::event; // prevent "hidden" warning
Q_OBJECT
public:
explicit EventListView(QWidget* parent = nullptr);
void setModel(QAbstractItemModel*) override;
EventListModel* itemModel() const;
KAEvent event(int row) const;
KAEvent event(const QModelIndex&) const;
void select(const QModelIndex&, bool scrollToIndex = false);
void clearSelection();
QModelIndex selectedIndex() const;
KAEvent selectedEvent() const;
QVector<KAEvent> selectedEvents() const;
void setEditOnSingleClick(bool e) { mEditOnSingleClick = e; }
bool editOnSingleClick() const { return mEditOnSingleClick; }
public Q_SLOTS:
virtual void slotFind();
virtual void slotFindNext() { findNext(true); }
virtual void slotFindPrev() { findNext(false); }
Q_SIGNALS:
void contextMenuRequested(const QPoint& globalPos);
void findActive(bool);
protected:
void resizeEvent(QResizeEvent*) override;
bool viewportEvent(QEvent*) override;
void contextMenuEvent(QContextMenuEvent*) override;
protected Q_SLOTS:
virtual void initSections() = 0;
private:
void findNext(bool forward);
Find* mFind {nullptr};
bool mEditOnSingleClick {false};
using QObject::event; // prevent "hidden" warning
};
class EventListDelegate : public QItemDelegate
......
......@@ -42,10 +42,10 @@ EventListModel::EventListModel(CalEvent::Types types, QObject* parent)
setSourceModel(new KDescendantsProxyModel(this));
setSortRole(ResourceDataModelBase::SortRole);
setDynamicSortFilter(true);
connect(this, &QAbstractItemModel::rowsInserted, this, &EventListModel::slotRowsInserted);
connect(this, &QAbstractItemModel::rowsRemoved, this, &EventListModel::slotRowsRemoved);
connect(sourceModel(), &QAbstractItemModel::rowsInserted, this, &EventListModel::slotRowsInserted);
connect(sourceModel(), &QAbstractItemModel::rowsRemoved, this, &EventListModel::slotRowsRemoved);
connect(Resources::instance(), &Resources::resourcePopulated,
this, &QSortFilterProxyModel::invalidate);
this, &EventListModel::slotResourcePopulated);
connect(Resources::instance(), &Resources::settingsChanged,
this, &EventListModel::resourceSettingsChanged);
}
......@@ -128,6 +128,10 @@ QVariant EventListModel::headerData(int section, Qt::Orientation orientation, in
return static_cast<KDescendantsProxyModel*>(sourceModel())->sourceModel()->headerData(section, orientation, role + mHeaderDataRoleOffset);
}
/******************************************************************************
* Determine whether a source model item is included in this model.
* This also determines whether it is counted in rowCount().
*/
bool EventListModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
{
// Get the resource which contains this event.
......@@ -161,6 +165,25 @@ bool EventListModel::filterAcceptsColumn(int sourceColumn, const QModelIndex& so
return QSortFilterProxyModel::filterAcceptsColumn(sourceColumn, sourceParent);
}
/******************************************************************************
* Called when a Resource has been initially populated.
*/
void EventListModel::slotResourcePopulated(Resource& resource)
{
if (!(resource.enabledTypes() & mAlarmTypes))
return; // the resource isn't included in this model
invalidate();
// Note that during initialisation, rows are inserted into the source model
// before they are added to the Resource. Until they have been added to the
// Resource, they will be filtered out by filterAcceptsRow() (and therefore
// omitted by rowCount()), because Resource::event(eventId) will not find
// them. The resourcePopulated() signal is emitted once they have been
// added to the Resource, so we need to re-process them now.
slotRowsInserted();
}
/******************************************************************************
* Called when rows have been inserted into the model.
*/
......
......@@ -96,6 +96,7 @@ protected:
bool filterAcceptsColumn(int sourceColumn, const QModelIndex &sourceParent) const override;
private Q_SLOTS:
void slotResourcePopulated(Resource&);
void slotRowsInserted();
void slotRowsRemoved();
void resourceSettingsChanged(Resource&, ResourceType::Changes);
......
/*
* templatelistview.cpp - widget showing list of alarm templates
* Program: kalarm
* Copyright © 2007-2019 David Jarvie <djarvie@kde.org>
* Copyright © 2007-2020 David Jarvie <djarvie@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -36,9 +36,11 @@ TemplateListView::TemplateListView(QWidget* parent)
setWhatsThis(i18nc("@info:whatsthis", "The list of alarm templates"));
}
void TemplateListView::setModel(QAbstractItemModel* model)
/******************************************************************************
* Initialize column settings and sizing.
*/
void TemplateListView::initSections()
{
EventListView::setModel(model);
header()->setSectionsMovable(false);
header()->setStretchLastSection(true);
header()->setSectionResizeMode(TemplateListModel::TypeColumn, QHeaderView::Fixed);
......
/*
* templatelistview.h - widget showing list of alarm templates
* Program: kalarm
* Copyright © 2007,2008 by David Jarvie <djarvie@kde.org>
* Copyright © 2007-2020 David Jarvie <djarvie@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -28,19 +28,22 @@
class TemplateListView : public EventListView
{
Q_OBJECT
public:
explicit TemplateListView(QWidget* parent = nullptr);
void setModel(QAbstractItemModel*) override;
Q_OBJECT
public:
explicit TemplateListView(QWidget* parent = nullptr);
protected Q_SLOTS:
void initSections() override;
};
class TemplateListDelegate : public EventListDelegate
{
Q_OBJECT
public:
explicit TemplateListDelegate(TemplateListView* parent = nullptr)
: EventListDelegate(parent) {}
void edit(KAEvent*, EventListView*) override;
Q_OBJECT
public:
explicit TemplateListDelegate(TemplateListView* parent = nullptr)
: EventListDelegate(parent) {}
void edit(KAEvent*, EventListView*) override;
};
#endif // TEMPLATELISTVIEW_H
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment