File: screenbrightnessdisplaymodel.cpp

package info (click to toggle)
powerdevil 4%3A6.5.4-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,680 kB
  • sloc: cpp: 13,284; xml: 1,911; python: 1,204; sh: 19; makefile: 10
file content (171 lines) | stat: -rw-r--r-- 5,731 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
 * SPDX-FileCopyrightText: 2024 Jakob Petsovits <jpetso@petsovits.com>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "screenbrightnessdisplaymodel.h"

#include <ranges>

ScreenBrightnessDisplayModel::ScreenBrightnessDisplayModel(QObject *parent)
    : QAbstractListModel(parent)
{
}

int ScreenBrightnessDisplayModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)

    return m_shownDisplayNames.count();
}

QVariant ScreenBrightnessDisplayModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() >= m_shownDisplayNames.size()) {
        return QVariant();
    }
    const QString &displayName = m_shownDisplayNames[index.row()];

    switch (role) {
    case DisplayNameRole:
        return displayName;
    case LabelRole:
        return m_displays[displayName].label;
    case IsInternalRole:
        return m_displays[displayName].isInternal;
    case BrightnessRole:
        return m_displays[displayName].brightness;
    case MaxBrightnessRole:
        return m_displays[displayName].maxBrightness;
    }
    return QVariant();
}

QHash<int, QByteArray> ScreenBrightnessDisplayModel::roleNames() const
{
    return QHash<int, QByteArray>{
        {DisplayNameRole, "displayName"},
        {LabelRole, "label"},
        {IsInternalRole, "isInternal"},
        {BrightnessRole, "brightness"},
        {MaxBrightnessRole, "maxBrightness"},
    };
}

QModelIndex ScreenBrightnessDisplayModel::displayIndex(const QString &displayName) const
{
    int row = m_shownDisplayNames.indexOf(displayName);
    return row == -1 ? QModelIndex() : QAbstractListModel::createIndex(row, 0);
}

void ScreenBrightnessDisplayModel::setKnownDisplayNames(const QStringList &displayNames)
{
    m_knownDisplayNames = displayNames;
    updateRows();
}

void ScreenBrightnessDisplayModel::setDisplayData(const QString &displayName, const QString &label, bool isInternal, int brightness, int maxBrightness)
{
    if (!m_knownDisplayNames.contains(displayName)) {
        return;
    }

    m_displays[displayName] = Data{
        .displayName = displayName,
        .label = label,
        .brightness = brightness,
        .maxBrightness = maxBrightness,
        .isInternal = isInternal,
    };

    if (QModelIndex modelIndex = displayIndex(displayName); modelIndex.isValid()) {
        Q_EMIT dataChanged(modelIndex, modelIndex, {LabelRole, IsInternalRole, BrightnessRole, MaxBrightnessRole});
    } else {
        updateRows();
    }
}

void ScreenBrightnessDisplayModel::updateRows()
{
    QMap<QString, Data> filteredDisplays = m_displays;

    // Purge data for displays that were removed from the list of known display names.
    for (const QString &displayName : std::ranges::subrange(m_displays.keyBegin(), m_displays.keyEnd())) {
        if (!m_knownDisplayNames.contains(displayName)) {
            filteredDisplays.remove(displayName);
        }
    }

    // Iterate through m_knownDisplayNames and ensure that m_shownDisplayNames contains a subset
    // of displays (including displays whose data was set) in the same order.
    int row = 0;
    for (const QString &displayName : std::as_const(m_knownDisplayNames)) {
        const bool hasDisplayData = filteredDisplays.contains(displayName);

        if (row < m_shownDisplayNames.size() && m_shownDisplayNames[row] == displayName) {
            // This display name is already at the expected row index in m_shownDisplayNames.
            // Advance to the next row, or remove the row if its display data is missing.
            if (hasDisplayData) {
                ++row;
            } else {
                beginRemoveRows(QModelIndex(), row, row);
                m_shownDisplayNames.remove(row);
                endRemoveRows();
            }
            continue;
        }

        if (hasDisplayData) {
            // This display name needs to be inserted with the current (expected) row index.
            beginInsertRows(QModelIndex(), row, row);
            m_shownDisplayNames.insert(row, displayName);
            endInsertRows();
            ++row;
        }
    }

    // Any remaining elements in m_shownDisplayNames are not in m_knownDisplayNames, or were
    // not located in the correct row so they were pushed back by a newly inserted duplicate.
    if (row < m_shownDisplayNames.size()) {
        beginRemoveRows(QModelIndex(), row, m_shownDisplayNames.size() - 1);
        m_shownDisplayNames.resize(row);
        endRemoveRows();
    }

    m_displays = std::move(filteredDisplays);
}

QStringList ScreenBrightnessDisplayModel::knownDisplayNamesWithMissingData() const
{
    QStringList result;
    for (const QString &displayName : std::as_const(m_knownDisplayNames)) {
        if (!m_displays.contains(displayName)) {
            result.append(displayName);
        }
    }
    return result;
}

void ScreenBrightnessDisplayModel::onBrightnessChanged(const QString &displayName, int value)
{
    if (auto it = m_displays.find(displayName); it != m_displays.end()) {
        it->brightness = value;
        if (QModelIndex modelIndex = displayIndex(displayName); modelIndex.isValid()) {
            Q_EMIT dataChanged(modelIndex, modelIndex, {BrightnessRole});
        }
    }
}

void ScreenBrightnessDisplayModel::onBrightnessRangeChanged(const QString &displayName, int max, int value)
{
    if (auto it = m_displays.find(displayName); it != m_displays.end()) {
        it->maxBrightness = max;
        it->brightness = value;
        if (QModelIndex modelIndex = displayIndex(displayName); modelIndex.isValid()) {
            Q_EMIT dataChanged(modelIndex, modelIndex, {MaxBrightnessRole, BrightnessRole});
        }
    }
}

#include "moc_screenbrightnessdisplaymodel.cpp"