Skip to content

Commit f3b83ef

Browse files
committed
Merge PTZListModel and PTZPresetListModel
Merging the two models together simplifies the overall data model and makes it trivial to switch the view displayed in the presets list. Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
1 parent 40c39da commit f3b83ef

8 files changed

Lines changed: 160 additions & 197 deletions

CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ target_sources(
9797
src/ptz-controls.cpp
9898
src/ptz-device.cpp
9999
src/ptz-list-model.cpp
100-
src/ptz-preset-model.cpp
101100
src/settings.cpp
102101
src/ptz-visca.cpp
103102
src/ptz-visca-udp.cpp
@@ -110,7 +109,6 @@ target_sources(
110109
src/ptz-controls.hpp
111110
src/ptz-device.hpp
112111
src/ptz-list-model.hpp
113-
src/ptz-preset-model.hpp
114112
src/settings.hpp
115113
src/ptz-visca.hpp
116114
src/ptz-visca-udp.hpp

src/ptz-controls.cpp

Lines changed: 24 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,11 @@ PTZControls::PTZControls(QWidget *parent) : QFrame(parent), ui(new Ui::PTZContro
179179
connect(selectionModel, &QItemSelectionModel::currentChanged, this, &PTZControls::currentChanged);
180180
connect(&accel_timer, &QTimer::timeout, this, &PTZControls::accelTimerHandler);
181181

182+
ui->presetListView->setModel(&ptzDeviceList);
183+
ui->presetListView->setRootIndex(ptzDeviceList.index(0, 0));
184+
selectionModel = ui->presetListView->selectionModel();
185+
connect(selectionModel, &QItemSelectionModel::currentChanged, this, &PTZControls::presetUpdateActions);
186+
182187
connect(ui->panTiltTouch, &TouchControl::positionChanged, [this](double p, double t) { setPanTilt(p, t); });
183188

184189
/* Right-click on the dock's Home button → "Save current position as
@@ -942,16 +947,7 @@ void PTZControls::currentChanged(QModelIndex current, QModelIndex previous)
942947
zoom_speed = zoom_accel = 0.0;
943948
focus_speed = focus_accel = 0.0;
944949

945-
auto ptz = ptzDeviceList.getDevice(current);
946-
if (ptz) {
947-
ui->presetListView->setModel(ptz->presetModel());
948-
presetUpdateActions();
949-
auto *selectionModel = ui->presetListView->selectionModel();
950-
if (selectionModel)
951-
connect(selectionModel, &QItemSelectionModel::currentChanged, this,
952-
&PTZControls::presetUpdateActions);
953-
}
954-
950+
ui->presetListView->setRootIndex(current);
955951
updateMoveControls();
956952
}
957953

@@ -988,9 +984,8 @@ int PTZControls::presetIndexToId(QModelIndex index)
988984
void PTZControls::presetUpdateActions()
989985
{
990986
auto index = ui->presetListView->currentIndex();
991-
auto model = ui->presetListView->model();
992-
int count = model ? model->rowCount() : 0;
993-
ui->actionPresetAdd->setEnabled(model != nullptr);
987+
int count = ptzDeviceList.rowCount(ptzDeviceList.parent(index));
988+
ui->actionPresetAdd->setEnabled(ui->cameraList->currentIndex().isValid());
994989
ui->actionPresetRemove->setEnabled(index.isValid());
995990
ui->actionPresetMoveUp->setEnabled(index.isValid() && count > 1 && index.row() > 0);
996991
ui->actionPresetMoveDown->setEnabled(index.isValid() && count > 1 && index.row() < count - 1);
@@ -1095,12 +1090,10 @@ void PTZControls::on_actionProperties_triggered()
10951090

10961091
void PTZControls::on_actionPresetAdd_triggered()
10971092
{
1098-
auto model = ui->presetListView->model();
1099-
if (!model)
1100-
return;
1101-
auto row = model->rowCount();
1102-
model->insertRows(row, 1);
1103-
QModelIndex index = model->index(row, 0);
1093+
auto parent = ui->cameraList->currentIndex();
1094+
auto row = ptzDeviceList.rowCount(parent);
1095+
ptzDeviceList.insertRows(row, 1, parent);
1096+
QModelIndex index = ptzDeviceList.index(row, 0, parent);
11041097
if (index.isValid()) {
11051098
ui->presetListView->setCurrentIndex(index);
11061099
ui->presetListView->edit(index);
@@ -1110,60 +1103,56 @@ void PTZControls::on_actionPresetAdd_triggered()
11101103

11111104
void PTZControls::on_actionPresetRemove_triggered()
11121105
{
1113-
auto model = ui->presetListView->model();
11141106
auto index = ui->presetListView->currentIndex();
1115-
if (!model || !index.isValid())
1107+
if (!index.isValid())
11161108
return;
1117-
model->removeRows(index.row(), 1);
1109+
ptzDeviceList.removeRows(index.row(), 1, ui->cameraList->currentIndex());
11181110
presetUpdateActions();
11191111
}
11201112

11211113
void PTZControls::on_actionPresetMoveUp_triggered()
11221114
{
1123-
auto model = ui->presetListView->model();
11241115
auto index = ui->presetListView->currentIndex();
1125-
if (!model || !index.isValid())
1116+
auto parent = ui->cameraList->currentIndex();
1117+
if (!index.isValid())
11261118
return;
1127-
model->moveRow(QModelIndex(), index.row(), QModelIndex(), index.row() - 1);
1119+
ptzDeviceList.moveRow(parent, index.row(), parent, index.row() - 1);
11281120
presetUpdateActions();
11291121
}
11301122

11311123
void PTZControls::on_actionPresetMoveDown_triggered()
11321124
{
1133-
auto model = ui->presetListView->model();
11341125
auto index = ui->presetListView->currentIndex();
1135-
if (!model || !index.isValid())
1126+
auto parent = ui->cameraList->currentIndex();
1127+
if (!index.isValid())
11361128
return;
1137-
model->moveRow(QModelIndex(), index.row(), QModelIndex(), index.row() + 2);
1129+
ptzDeviceList.moveRow(parent, index.row(), parent, index.row() + 2);
11381130
presetUpdateActions();
11391131
}
11401132

11411133
void PTZControls::on_actionPresetRename_triggered()
11421134
{
1143-
auto model = ui->presetListView->model();
11441135
auto index = ui->presetListView->currentIndex();
1145-
if (!model || !index.isValid())
1136+
if (!index.isValid())
11461137
return;
11471138
ui->presetListView->edit(index);
11481139
}
11491140

11501141
void PTZControls::on_actionPresetSave_triggered()
11511142
{
1152-
auto model = ui->presetListView->model();
11531143
auto index = ui->presetListView->currentIndex();
1154-
if (!model || !index.isValid())
1144+
if (!index.isValid())
11551145
return;
11561146
presetSet(presetIndexToId(index));
11571147
}
11581148

11591149
void PTZControls::on_actionPresetClear_triggered()
11601150
{
1161-
auto model = ui->presetListView->model();
11621151
auto index = ui->presetListView->currentIndex();
1163-
if (!model || !index.isValid())
1152+
if (!index.isValid())
11641153
return;
11651154
presetReset(presetIndexToId(index));
1166-
ui->presetListView->model()->setData(index, "");
1155+
ptzDeviceList.setData(index, "");
11671156
}
11681157

11691158
PTZDeviceListDelegate::PTZDeviceListDelegate(QObject *parent) : QStyledItemDelegate(parent)

src/ptz-device.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <obs.hpp>
99
#include "ptz-device.hpp"
1010
#include "ptz-list-model.hpp"
11-
#include "ptz-preset-model.hpp"
1211
#include "ptz.h"
1312
#include "protocol-helpers.hpp"
1413

@@ -44,7 +43,6 @@
4443

4544
PTZDevice::PTZDevice(OBSData config) : QObject()
4645
{
47-
m_presetsModel.ptz = this;
4846
/* Create and populate the proc handler methods */
4947
handler = proc_handler_create();
5048
if (!handler) {

src/ptz-device.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include <qt-wrappers.hpp>
1313
#include <util/platform.h>
1414
#include "ptz.h"
15-
#include "ptz-preset-model.hpp"
1615

1716
#define ptz_log(level, format, ...) \
1817
blog(level, "[%s/%.12s] " format, this->type.c_str(), QT_TO_UTF8(this->objectName()), ##__VA_ARGS__)
@@ -54,7 +53,6 @@ class PTZDevice : public QObject {
5453
size_t m_maxPresets = 16;
5554
QMap<size_t, QVariantMap> m_presets;
5655
QList<size_t> m_presetsDisplayOrder;
57-
PTZPresetListModel m_presetsModel;
5856
void sanitizePreset(size_t id);
5957

6058
void setConnected(bool connected);
@@ -175,7 +173,6 @@ protected slots:
175173
void preset_clear(calldata_t *cd);
176174

177175
public:
178-
virtual QAbstractListModel *presetModel() { return &m_presetsModel; }
179176
bool isLocked() const { return locked; };
180177
bool isConnected() const { return connected; }
181178
void setLock(bool state) { locked = state; }

src/ptz-list-model.cpp

Lines changed: 127 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ void PTZListModel::renameDevice(QString new_name, QString prev_name)
3535
ptz->setObjectName(new_name);
3636
}
3737

38-
PTZListModel::PTZListModel()
38+
PTZListModel::PTZListModel() : QAbstractItemModel()
3939
{
4040
signal_handler_t *sh = obs_get_signal_handler();
4141
signal_handler_connect(sh, "source_rename", source_rename_cb, this);
@@ -47,25 +47,131 @@ PTZListModel::~PTZListModel()
4747
//signal_handler_disconnect(sh, "source_rename", source_rename_cb, this);
4848
}
4949

50+
QModelIndex PTZListModel::index(int row, int column, const QModelIndex &parent) const
51+
{
52+
if (!checkIndex(parent))
53+
return QModelIndex();
54+
55+
/* Presets are children of the device */
56+
auto ptz = getDevice(parent);
57+
if (ptz)
58+
return createIndex(row, column, ptz);
59+
return createIndex(row, column);
60+
}
61+
62+
QModelIndex PTZListModel::parent(const QModelIndex &child) const
63+
{
64+
/* If the internal pointer is set, then this is a preset index */
65+
auto ptz = static_cast<PTZDevice*>(child.internalPointer());
66+
if (ptz) {
67+
int row = devices.indexOf(ptz);
68+
if (row >= 0)
69+
return createIndex(row, 0);
70+
}
71+
72+
return QModelIndex();
73+
}
74+
5075
int PTZListModel::rowCount(const QModelIndex &parent) const
5176
{
52-
Q_UNUSED(parent);
77+
auto ptz = getDevice(parent);
78+
if (ptz)
79+
return ptz->presetCount(); /* Return size of preset list */
5380
return (int)devices.size();
5481
}
5582

5683
Qt::ItemFlags PTZListModel::flags(const QModelIndex &index) const
5784
{
5885
if (!index.isValid())
5986
return Qt::ItemIsEnabled;
60-
return QAbstractListModel::flags(index) | Qt::ItemIsEditable;
87+
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
88+
}
89+
90+
bool PTZListModel::insertRows(int row, int count, const QModelIndex &parent)
91+
{
92+
auto ptz = getDevice(parent);
93+
if (!ptz)
94+
return false;
95+
if (row < 0 || row > ptz->presetCount())
96+
return false;
97+
98+
beginInsertRows(parent, row, count);
99+
for (int i = 0; i < count; i++)
100+
ptz->newPreset(row++);
101+
endInsertRows();
102+
return true;
103+
}
104+
105+
bool PTZListModel::removeRows(int row, int count, const QModelIndex &parent)
106+
{
107+
auto ptz = getDevice(parent);
108+
if (!ptz)
109+
return false;
110+
if (row < 0 || row >= ptz->presetCount())
111+
return false;
112+
beginRemoveRows(parent, row, count);
113+
for (int i = 0; i < count; i++)
114+
ptz->removePresetAtDisplayRow(row);
115+
endRemoveRows();
116+
return true;
117+
}
118+
119+
bool PTZListModel::moveRows(const QModelIndex &srcParent, int srcRow, int count, const QModelIndex &destParent,
120+
int destChild)
121+
{
122+
if (!checkIndex(srcParent) || srcParent != destParent)
123+
return false;
124+
auto ptz = getDevice(srcParent);
125+
if (!ptz)
126+
return false;
127+
if (srcRow < 0 || srcRow >= rowCount())
128+
return false;
129+
if (destChild < 0 || destChild > rowCount())
130+
return false;
131+
if (count != 1)
132+
return false;
133+
134+
if (!beginMoveRows(srcParent, srcRow, srcRow + count - 1, destParent, destChild))
135+
return false;
136+
ptz->movePreset(srcRow, destChild);
137+
endMoveRows();
138+
return true;
61139
}
62140

63141
QVariant PTZListModel::data(const QModelIndex &index, int role) const
64142
{
65143
if (!index.isValid())
66144
return QVariant();
67145

68-
auto ptz = getDevice(index);
146+
/* If the parent is a PTZDevice, then return a preset */
147+
auto ptz = getDevice(parent(index));
148+
if (ptz) {
149+
auto id = ptz->presetAtDisplayRow(index.row());
150+
if (id < 0)
151+
return QVariant();
152+
if (role == Qt::DisplayRole) {
153+
auto name = ptz->presetName(id);
154+
if (name == "")
155+
name = QString(obs_module_text("PTZ.PresetNum")).arg(id);
156+
return name;
157+
}
158+
if (role == Qt::ToolTipRole) {
159+
auto token = ptz->presetToken(id);
160+
if (token != "")
161+
return QString(obs_module_text("PTZ.Preset.Tooltip")).arg("'" + token + "'");
162+
return QString(obs_module_text("PTZ.Preset.Tooltip")).arg(id);
163+
}
164+
if (role == Qt::EditRole)
165+
return ptz->presetName(id);
166+
if (role == Qt::UserRole)
167+
return id;
168+
if (role == Qt::SizeHintRole)
169+
return QSize(0, 20);
170+
171+
return QVariant();
172+
}
173+
174+
ptz = getDevice(index);
69175
if (!ptz)
70176
return QVariant();
71177

@@ -95,7 +201,22 @@ QVariant PTZListModel::data(const QModelIndex &index, int role) const
95201

96202
bool PTZListModel::setData(const QModelIndex &index, const QVariant &value, int role)
97203
{
98-
auto ptz = getDevice(index);
204+
/* If the parent is a PTZDevice, then return a preset */
205+
auto ptz = getDevice(parent(index));
206+
if (ptz) {
207+
auto id = ptz->presetAtDisplayRow(index.row());
208+
if (id < 0)
209+
return false;
210+
211+
if (role == Qt::EditRole) {
212+
ptz->setPresetName(id, value.toString());
213+
emit dataChanged(index, index);
214+
return true;
215+
}
216+
return false;
217+
}
218+
219+
ptz = getDevice(index);
99220
if (!ptz)
100221
return false;
101222

@@ -129,7 +250,7 @@ void PTZListModel::onSceneChanged()
129250

130251
PTZDevice *PTZListModel::getDevice(const QModelIndex &index) const
131252
{
132-
if (!index.isValid() || index.model() != this)
253+
if (!checkIndex(index) || index.internalPointer() != nullptr)
133254
return nullptr;
134255
return devices.value(index.row());
135256
}

src/ptz-list-model.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
#pragma once
88

99
#include <QObject>
10-
#include <QAbstractListModel>
10+
#include <QAbstractItemModel>
1111
#include <QHash>
1212
#include <QList>
1313
#include "ptz.h"
1414

1515
class PTZDevice;
1616

17-
class PTZListModel : public QAbstractListModel {
17+
class PTZListModel : public QAbstractItemModel {
1818
Q_OBJECT
1919

2020
private:
@@ -33,7 +33,14 @@ class PTZListModel : public QAbstractListModel {
3333

3434
PTZListModel();
3535
~PTZListModel();
36+
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
37+
QModelIndex parent(const QModelIndex &child) const override;
3638
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
39+
int columnCount(const QModelIndex &) const override { return 1; };
40+
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
41+
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
42+
bool moveRows(const QModelIndex &srcParent, int srcRow, int count, const QModelIndex &destParent,
43+
int destChild) override;
3744
QVariant data(const QModelIndex &index, int role) const override;
3845
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
3946
void do_reset();

0 commit comments

Comments
 (0)