AGL-style PulseAudio mixer app
[apps/mixer.git] / app / pacontrolmodel.cpp
1 /*
2  * Copyright (C) 2016 Konsulko Group
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "pacontrolmodel.h"
18 #include "pac.h"
19
20 PaControl::PaControl(const quint32 &cindex, const QString &desc, const quint32 &type, const quint32 &channel, const QString &cdesc, const quint32 &volume)
21         : m_cindex(cindex), m_desc(desc), m_type(type), m_channel(channel), m_cdesc(cdesc), m_volume(volume)
22 {
23 }
24
25 quint32 PaControl::cindex() const
26 {
27         return m_cindex;
28 }
29
30 QString PaControl::desc() const
31 {
32         return m_desc;
33 }
34
35 quint32 PaControl::type() const
36 {
37         return m_type;
38 }
39
40 quint32 PaControl::channel() const
41 {
42         return m_channel;
43 }
44
45 QString PaControl::cdesc() const
46 {
47         return m_cdesc;
48 }
49
50
51 quint32 PaControl::volume() const
52 {
53         return m_volume;
54 }
55
56 // FIXME: Not all of these should be editable roles
57 void PaControl::setCIndex(const QVariant &cindex)
58 {
59         m_cindex = cindex.toUInt();
60 }
61
62 void PaControl::setDesc(const QVariant &desc)
63 {
64         m_desc = desc.toString();
65 }
66
67 void PaControl::setType(const QVariant &type)
68 {
69         m_type = type.toUInt();
70 }
71
72 void PaControl::setChannel(const QVariant &channel)
73 {
74         m_channel = channel.toUInt();
75 }
76
77 void PaControl::setCDesc(const QVariant &cdesc)
78 {
79         m_cdesc = cdesc.toString();
80 }
81
82 void PaControl::setVolume(pa_context *pa_ctx, const QVariant &volume)
83 {
84         if (volume != m_volume) {
85                 m_volume = volume.toUInt();
86                 pac_set_volume(pa_ctx, type(), cindex(), channel(), m_volume);
87         }
88 }
89
90 PaControlModel::PaControlModel(QObject *parent)
91         : QAbstractListModel(parent)
92 {
93         pa_ctx = pac_init(this, "Mixer");
94 }
95
96 void PaControlModel::addControl(const PaControl &control)
97 {
98         beginInsertRows(QModelIndex(), rowCount(), rowCount());
99         m_controls << control;
100         endInsertRows();
101 }
102
103 void add_one_control(void *ctx, int cindex, const char *desc, int type, int channel, const char *cdesc, int volume)
104 {
105         // Get the PaControlModel object from the opaque pointer context
106         PaControlModel *pacm = static_cast<PaControlModel*>(ctx);
107         pacm->addControl(PaControl(cindex, desc, type, channel, cdesc, volume));
108 }
109
110 int PaControlModel::rowCount(const QModelIndex & parent) const {
111         Q_UNUSED(parent);
112         return m_controls.count();
113 }
114
115 bool PaControlModel::setData(const QModelIndex &index, const QVariant &value, int role) {
116         if (index.row() < 0 || index.row() >= m_controls.count())
117                 return false;
118         PaControl &control = m_controls[index.row()];
119         if (role == CIndexRole)
120                 control.setCIndex(value);
121         else if (role == DescRole)
122                 control.setDesc(value);
123         else if (role == TypeRole)
124                 control.setType(value);
125         else if (role == ChannelRole)
126                 control.setChannel(value);
127         else if (role == CDescRole)
128                 control.setCDesc(value);
129         else if (role == VolumeRole)
130                 control.setVolume(pa_ctx, value);
131         emit dataChanged(index, index);
132         return true;
133 }
134
135 QVariant PaControlModel::data(const QModelIndex & index, int role) const {
136         if (index.row() < 0 || index.row() >= m_controls.count())
137                 return QVariant();
138
139         const PaControl &control = m_controls[index.row()];
140         if (role == CIndexRole)
141                 return control.cindex();
142         else if (role == DescRole)
143                 return control.desc();
144         else if (role == TypeRole)
145                 return control.type();
146         else if (role == ChannelRole)
147                 return control.channel();
148         else if (role == CDescRole)
149                 return control.cdesc();
150         else if (role == VolumeRole)
151                 return control.volume();
152         return QVariant();
153 }
154
155 Qt::ItemFlags PaControlModel::flags(const QModelIndex &index) const
156 {
157         if (!index.isValid())
158                 return Qt::ItemIsEnabled;
159
160         return QAbstractListModel::flags(index) | Qt::ItemIsEditable;
161 }
162
163 QHash<int, QByteArray> PaControlModel::roleNames() const {
164         QHash<int, QByteArray> roles;
165         roles[CIndexRole] = "cindex";
166         roles[DescRole] = "desc";
167         roles[TypeRole] = "type";
168         roles[ChannelRole] = "channel";
169         roles[CDescRole] = "cdesc";
170         roles[VolumeRole] = "volume";
171         return roles;
172 }