alarmlistview.cpp 9.33 KB
Newer Older
1
/*
2
 *  alarmlistview.cpp  -  widget showing list of alarms
3
 *  Program:  kalarm
4
 *  SPDX-FileCopyrightText: 2007-2020 David Jarvie <djarvie@kde.org>
5
 *
6
 *  SPDX-License-Identifier: GPL-2.0-or-later
7 8
 */

Laurent Montel's avatar
Laurent Montel committed
9
#include "alarmlistview.h"
10

11
#include "resources/resourcedatamodelbase.h"
David Jarvie's avatar
David Jarvie committed
12 13
#include "resources/eventmodel.h"

14 15
#include <KSharedConfig>
#include <KConfigGroup>
16

17
#include <QHeaderView>
18 19
#include <QMenu>
#include <QAction>
20
#include <QApplication>
21 22


23
AlarmListView::AlarmListView(const QByteArray& configGroup, QWidget* parent)
David Jarvie's avatar
David Jarvie committed
24 25
    : EventListView(parent)
    , mConfigGroup(configGroup)
26
{
27
    setEditOnSingleClick(true);
28
    connect(header(), &QHeaderView::sectionMoved, this, &AlarmListView::saveColumnsState);
29 30
    header()->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(header(), &QWidget::customContextMenuRequested, this, &AlarmListView::headerContextMenuRequested);
31
    Preferences::connect(&Preferences::useAlarmNameChanged, this, &AlarmListView::useAlarmNameChanged);
32 33
}

34 35 36
/******************************************************************************
* Return which of the optional columns are currently shown.
* Note that the column order must be the same as in setColumnsVisible().
37 38
* Reply = array of 5 columns if not using alarm names;
*       = array of 6 columns if not using alarm names.
39
*/
40 41 42 43
QList<bool> AlarmListView::columnsVisible() const
{
    if (!model())
        return {};
44 45 46 47 48 49 50 51
    QList<bool> vis{ !header()->isSectionHidden(AlarmListModel::TimeColumn),
                     !header()->isSectionHidden(AlarmListModel::TimeToColumn),
                     !header()->isSectionHidden(AlarmListModel::RepeatColumn),
                     !header()->isSectionHidden(AlarmListModel::ColourColumn),
                     !header()->isSectionHidden(AlarmListModel::TypeColumn) };
    if (Preferences::useAlarmName())
        vis += !header()->isSectionHidden(AlarmListModel::TextColumn);
    return vis;
52 53
}

54 55
/******************************************************************************
* Set which of the optional columns are to be shown.
56 57
* 'show' = array of 5 columns if not using alarm names;
*        = array of 6 columns if not using alarm names.
58 59
* Note that the column order must be the same as in columnsVisible().
*/
60 61
void AlarmListView::setColumnsVisible(const QList<bool>& show)
{
62
    if (!model())
63
        return;
64 65 66 67 68
    const bool useName = Preferences::useAlarmName();
    QList<bool> vis{ true, false, true, true, true, !useName };
    const int colCount = useName ? 6 : 5;
    for (int i = 0;  i < colCount;  ++i)
        vis[i] = show[i];
69 70 71 72 73
    header()->setSectionHidden(AlarmListModel::TimeColumn,   !vis[0]);
    header()->setSectionHidden(AlarmListModel::TimeToColumn, !vis[1]);
    header()->setSectionHidden(AlarmListModel::RepeatColumn, !vis[2]);
    header()->setSectionHidden(AlarmListModel::ColourColumn, !vis[3]);
    header()->setSectionHidden(AlarmListModel::TypeColumn,   !vis[4]);
74 75 76
    header()->setSectionHidden(AlarmListModel::NameColumn,   !useName);
    header()->setSectionHidden(AlarmListModel::TextColumn,   !vis[5]);
    setReplaceBlankName();
77
    setSortingEnabled(false);  // sortByColumn() won't work if sorting is already enabled!
78
    sortByColumn(vis[0] ? AlarmListModel::TimeColumn : AlarmListModel::TimeToColumn, Qt::AscendingOrder);
79
}
David Jarvie's avatar
David Jarvie committed
80

81 82 83 84 85 86 87 88
/******************************************************************************
* Initialize column settings and sizing.
*/
void AlarmListView::initSections()
{
    KConfigGroup config(KSharedConfig::openConfig(), mConfigGroup.constData());
    const QByteArray settings = config.readEntry("ListHead", QByteArray());
    if (!settings.isEmpty())
89
    {
90
        header()->restoreState(settings);
91 92 93 94 95 96 97 98
        const bool useName = Preferences::useAlarmName();
        header()->setSectionHidden(AlarmListModel::NameColumn, !useName);
        if (!useName)
        {
            header()->setSectionHidden(AlarmListModel::TextColumn, false);
            setReplaceBlankName();
        }
    }
99 100 101 102 103 104
    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);
105
    header()->setSectionResizeMode(AlarmListModel::NameColumn, QHeaderView::ResizeToContents);
106 107 108 109 110 111 112 113 114
    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);
}

115
/******************************************************************************
116 117
* Called when the column order is changed.
* Save the new order for restoration on program restart.
118
*/
119
void AlarmListView::saveColumnsState()
120
{
121
    KConfigGroup config(KSharedConfig::openConfig(), mConfigGroup.constData());
122 123
    config.writeEntry("ListHead", header()->saveState());
    config.sync();
124 125
}

David Jarvie's avatar
David Jarvie committed
126
/******************************************************************************
127 128
* Called when a context menu is requested for the header.
* Allow the user to choose which columns to display.
David Jarvie's avatar
David Jarvie committed
129
*/
130
void AlarmListView::headerContextMenuRequested(const QPoint& pt)
David Jarvie's avatar
David Jarvie committed
131
{
132 133
    QAbstractItemModel* almodel = model();
    QMenu menu;
134 135
    const bool useName = Preferences::useAlarmName();
    for (int col = 0, count = header()->count();  col < count;  ++col)
136
    {
137 138
        if (col == AlarmListModel::NameColumn  &&  !useName)
            continue;
139
        const QString title = almodel->headerData(col, Qt::Horizontal, ResourceDataModelBase::ColumnTitleRole).toString();
140 141 142 143 144 145
        if (!title.isEmpty())
        {
            QAction* act = menu.addAction(title);
            act->setData(col);
            act->setCheckable(true);
            act->setChecked(!header()->isSectionHidden(col));
146 147 148 149
            if (col == AlarmListModel::NameColumn)
                act->setEnabled(false);    // don't allow name column to be hidden if name is used
            else if (col == AlarmListModel::TextColumn  &&  !useName)
                act->setEnabled(false);    // don't allow text column to be hidden if name not used
150 151 152 153
            else
                QObject::connect(act, &QAction::triggered,
                                 this, [this, &menu, act] { showHideColumn(menu, act); });
        }
154
    }
155 156
    enableTimeColumns(&menu);
    menu.exec(header()->mapToGlobal(pt));
157 158
}

159 160 161 162 163 164 165 166 167 168
/******************************************************************************
* Called when the 'use alarm name' setting has changed.
*/
void AlarmListView::useAlarmNameChanged(bool use)
{
    header()->setSectionHidden(AlarmListModel::NameColumn, !use);
    header()->setSectionHidden(AlarmListModel::TextColumn, use);
    setReplaceBlankName();
}

169 170 171 172
/******************************************************************************
* Show or hide a column according to the header context menu.
*/
void AlarmListView::showHideColumn(QMenu& menu, QAction* act)
173
{
174 175 176 177 178 179 180
    int col = act->data().toInt();
    if (col < 0  ||  col >= header()->count())
        return;
    bool show = act->isChecked();
    header()->setSectionHidden(col, !show);
    if (col == AlarmListModel::TimeColumn  ||  col == AlarmListModel::TimeToColumn)
        enableTimeColumns(&menu);
181 182
    if (col == AlarmListModel::TextColumn)
        setReplaceBlankName();
183
    saveColumnsState();
184 185 186
    Q_EMIT columnsVisibleChanged();
}

187 188 189 190 191 192 193 194 195 196 197
/******************************************************************************
* Set whether to replace a blank alarm name with the alarm text.
*/
void AlarmListView::setReplaceBlankName()
{
    bool textHidden = header()->isSectionHidden(AlarmListModel::TextColumn);
    AlarmListModel* almodel = qobject_cast<AlarmListModel*>(model());
    if (almodel)
        almodel->setReplaceBlankName(textHidden);
}

198 199 200 201 202 203 204 205
/******************************************************************************
* Disable Time or Time To in the context menu if the other one is not
* selected to be displayed, to ensure that at least one is always shown.
*/
void AlarmListView::enableTimeColumns(QMenu* menu)
{
    bool timeShown   = !header()->isSectionHidden(AlarmListModel::TimeColumn);
    bool timeToShown = !header()->isSectionHidden(AlarmListModel::TimeToColumn);
David Jarvie's avatar
David Jarvie committed
206
    const QList<QAction*> actions = menu->actions();
207 208 209
    if (!timeToShown)
    {
        header()->setSectionHidden(AlarmListModel::TimeColumn, false);
David Jarvie's avatar
David Jarvie committed
210
        for (QAction* act : actions)
211 212 213 214 215 216 217 218 219
        {
            if (act->data().toInt() == AlarmListModel::TimeColumn)
            {
                act->setEnabled(false);
                break;
            }
        }
    }
    else if (!timeShown)
220
    {
221
        header()->setSectionHidden(AlarmListModel::TimeToColumn, false);
David Jarvie's avatar
David Jarvie committed
222
        for (QAction* act : actions)
223 224 225 226 227 228 229
        {
            if (act->data().toInt() == AlarmListModel::TimeToColumn)
            {
                act->setEnabled(false);
                break;
            }
        }
230
    }
231
}
Laurent Montel's avatar
Laurent Montel committed
232

233
// vim: et sw=4: