Phonon

objectdescriptionmodel.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) version 3, or any
8 later version accepted by the membership of KDE e.V. (or its
9 successor approved by the membership of KDE e.V.), Nokia Corporation
10 (or its successors, if any) and the KDE Free Qt Foundation, which shall
11 act as a proxy defined in Section 6 of version 3 of the license.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library. If not, see <http://www.gnu.org/licenses/>.
20
21*/
22
23#include "objectdescriptionmodel.h"
24#include "objectdescriptionmodel_p.h"
25#include "phonondefs_p.h"
26#include "platform_p.h"
27#include "objectdescription.h"
28#include "phononnamespace_p.h"
29#include "factory_p.h"
30#include <QIcon>
31#include <QPainter>
32#include <QList>
33#include <QMimeData>
34#include <QStringList>
35
36#ifndef QT_NO_PHONON_OBJECTDESCRIPTIONMODEL
37
38// If this wasn't so terrible ...
39// ObjectDescriptionModel is a template class. Moc however cannot handle
40// templates so the solution done here is to *manually* do whatever moc does.
41
42static const uint qt_meta_data_Phonon__ObjectDescriptionModel[] = {
43
44 // content:
45 7, // revision
46 0, // classname
47 0, 0, // classinfo
48 0, 0, // methods
49 0, 0, // properties
50 0, 0, // enums/sets
51 0, 0, // constructors
52 0, // flags
53 0, // signalCount
54
55 0 // eod
56};
57
58#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
59 #define P_STATIC_META_STRINGDATA(name, string, stringlen, stringlenplustwo) \
60 struct qt_meta_stringdata_Phonon__ObjectDescriptionModel_##name##_t { QByteArrayData data[1]; char stringdata[stringlenplustwo]; }; \
61 static const qt_meta_stringdata_Phonon__ObjectDescriptionModel_##name##_t qt_meta_stringdata_Phonon__ObjectDescriptionModel_##name = { \
62 { \
63 Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(stringlen, offsetof(qt_meta_stringdata_Phonon__ObjectDescriptionModel_ ## name ## _t, stringdata) + 0 - 0 * sizeof(QByteArrayData)) \
64 }, \
65 string \
66 };
67#else
68 #define P_STATIC_META_STRINGDATA(name, string, stringlen, stringlenplustwo) \
69 struct qt_meta_stringdata_Phonon__ObjectDescriptionModel_##name##_t { const uint offsetsAndSize[2]; char stringdata[stringlenplustwo]; }; \
70 static const qt_meta_stringdata_Phonon__ObjectDescriptionModel_##name##_t qt_meta_stringdata_Phonon__ObjectDescriptionModel_##name = { \
71 { \
72 uint(offsetof(qt_meta_stringdata_Phonon__ObjectDescriptionModel_ ## name ## _t, stringdata)), stringlen \
73 }, \
74 string \
75 };
76#endif
77
78 P_STATIC_META_STRINGDATA(AudioOutputDeviceType, "Phonon::AudioOutputDeviceModel\0", 30, 32)
79 P_STATIC_META_STRINGDATA(AudioCaptureDeviceType, "Phonon::AudioCaptureDeviceModel\0", 31, 33)
80 P_STATIC_META_STRINGDATA(VideoCaptureDeviceType, "Phonon::VideoCaptureDeviceModel\0", 31, 33)
81 P_STATIC_META_STRINGDATA(EffectType, "Phonon::EffectModel\0", 19, 21)
82 P_STATIC_META_STRINGDATA(AudioChannelType, "Phonon::AudioChannelModel\0", 25, 27)
83 P_STATIC_META_STRINGDATA(SubtitleType, "Phonon::SubtitleModel\0", 21, 23)
84
85 #undef P_STATIC_META_STRINGDATA
86
87#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
88 #define OBJECT_DESCRIPTION_MODEL_STATIC_META_OBJECT(X) { \
89 &QAbstractListModel::staticMetaObject, \
90 qt_meta_stringdata_Phonon__ObjectDescriptionModel_##X.data, \
91 qt_meta_data_Phonon__ObjectDescriptionModel, \
92 nullptr, nullptr, nullptr }
93#else
94 #define OBJECT_DESCRIPTION_MODEL_STATIC_META_OBJECT(X) { \
95 &QAbstractListModel::staticMetaObject, \
96 qt_meta_stringdata_Phonon__ObjectDescriptionModel_##X.offsetsAndSize, \
97 qt_meta_data_Phonon__ObjectDescriptionModel, \
98 nullptr, nullptr, nullptr }
99#endif
100
101namespace Phonon
102{
103
105 OBJECT_DESCRIPTION_MODEL_STATIC_META_OBJECT(AudioOutputDeviceType)
106};
108 OBJECT_DESCRIPTION_MODEL_STATIC_META_OBJECT(AudioCaptureDeviceType)
109};
111 OBJECT_DESCRIPTION_MODEL_STATIC_META_OBJECT(VideoCaptureDeviceType)
112};
114 OBJECT_DESCRIPTION_MODEL_STATIC_META_OBJECT(EffectType)
115};
117 OBJECT_DESCRIPTION_MODEL_STATIC_META_OBJECT(AudioChannelType)
118};
120 OBJECT_DESCRIPTION_MODEL_STATIC_META_OBJECT(SubtitleType)
121};
122
123template<ObjectDescriptionType type>
125{
126 return &staticMetaObject;
127}
128
129template<ObjectDescriptionType type>
131{
132 qWarning("WARNING: Phonon4Qt5 has not been verified to successfully qt_metacast ObjectDescriptionModels.");
133 if (!_clname) {
134 return nullptr;
135 }
136 if (!strcmp(_clname, ObjectDescriptionModel<type>::staticMetaObject.className())) {
137 return static_cast<void *>(const_cast<ObjectDescriptionModel<type> *>(this));
138 }
139 return QAbstractListModel::qt_metacast(_clname);
140}
141
142/*
143template<ObjectDescriptionType type>
144int ObjectDescriptionModel<type>::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
145{
146 return QAbstractListModel::qt_metacall(_c, _id, _a);
147}
148*/
149
151{
152 if (parent.isValid())
153 return 0;
154
155 return d->data.size();
156}
157
159{
160 if (!index.isValid() || index.row() >= d->data.size() || index.column() != 0)
161 return QVariant();
162
163 switch(role)
164 {
165 case Qt::EditRole:
166 case Qt::DisplayRole:
167 return d->data.at(index.row())->name();
168 break;
169 case Qt::ToolTipRole:
170 return d->data.at(index.row())->description();
171 break;
173 {
174 /* Returns an icon if available. Paint a subicon representing the entity (platform
175 * plugin or backend) which discovered this object, if it is specified */
176 QVariant icon = d->data.at(index.row())->property("icon");
177 QVariant discovererIcon = d->data.at(index.row())->property("discovererIcon");
178 if (icon.isValid()) {
179 if (icon.type() == QVariant::String) {
180 icon = Platform::icon(icon.toString());
181 }
182 if (discovererIcon.type() == QVariant::String) {
183 discovererIcon = Platform::icon(discovererIcon.toString());
184 }
185 if (icon.type() == QVariant::Icon) {
186 if (discovererIcon.type() == QVariant::Icon) {
187 // Insert the subicon in the top-right corner of the icon
188 QPixmap pixmap = icon.value<QIcon>().pixmap(QSize(64, 64));
189 QPixmap subPixmap = discovererIcon.value<QIcon>().pixmap(QSize(22, 22));
190 QPainter painter(&pixmap);
191 painter.drawPixmap(42, 0, subPixmap);
192 return QIcon(pixmap);
193 } else {
194 return icon;
195 }
196 }
197 }
198 }
199 return QVariant();
200 default:
201 return QVariant();
202}
203}
204
206{
207 if(!index.isValid() || index.row() >= d->data.size() || index.column() != 0) {
209 }
210
211 QVariant available = d->data.at(index.row())->property("available");
212 if (available.isValid() && available.type() == QVariant::Bool && !available.toBool()) {
214 }
216}
217
219{
220 QList<int> ret;
221 for (int i = 0; i < d->data.size(); ++i) {
222 ret.append(d->data.at(i)->index());
223 }
224 return ret;
225}
226
228{
229 return d->data.at(positionIndex)->index();
230}
231
232QMimeData *ObjectDescriptionModelData::mimeData(ObjectDescriptionType type, const QModelIndexList &indexes) const
233{
235 QByteArray encodedData;
236 QDataStream stream(&encodedData, QIODevice::WriteOnly);
237 QModelIndexList::const_iterator end = indexes.constEnd();
238 QModelIndexList::const_iterator index = indexes.constBegin();
239 for(; index!=end; ++index) {
240 if ((*index).isValid()) {
241 stream << d->data.at((*index).row())->index();
242 }
243 }
244 //pDebug() << Q_FUNC_INFO << "setting mimeData to" << mimeTypes(type).first() << "=>" << encodedData.toHex();
245 mimeData->setData(mimeTypes(type).first(), encodedData);
246 return mimeData;
247}
248
250{
251 if (!index.isValid() || index.row() >= d->data.size() || index.row() < 1 || index.column() != 0)
252 return;
253
254 emit d->model->layoutAboutToBeChanged();
255 QModelIndex above = index.sibling(index.row() - 1, index.column());
256#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
257 d->data.swapItemsAt(index.row(), above.row());
258#else
259 d->data.swap(index.row(), above.row());
260#endif
261 QModelIndexList from, to;
262 from << index << above;
263 to << above << index;
264 d->model->changePersistentIndexList(from, to);
265 emit d->model->layoutChanged();
266}
267
269{
270 if (!index.isValid() || index.row() >= d->data.size() - 1 || index.column() != 0)
271 return;
272
273 emit d->model->layoutAboutToBeChanged();
274 QModelIndex below = index.sibling(index.row() + 1, index.column());
275#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
276 d->data.swapItemsAt(index.row(), below.row());
277#else
278 d->data.swap(index.row(), below.row());
279#endif
280 QModelIndexList from, to;
281 from << index << below;
282 to << below << index;
283 d->model->changePersistentIndexList(from, to);
284 emit d->model->layoutChanged();
285}
286
287ObjectDescriptionModelData::ObjectDescriptionModelData(QAbstractListModel *model)
288 : d(new ObjectDescriptionModelDataPrivate(model))
289{
290}
291
292ObjectDescriptionModelData::~ObjectDescriptionModelData()
293{
294 delete d;
295}
296
297void ObjectDescriptionModelData::setModelData(const QList<QExplicitlySharedDataPointer<ObjectDescriptionData> > &newData)
298{
299 d->model->beginResetModel();
300 d->data = newData;
301 d->model->endResetModel();
302}
303
304QList<QExplicitlySharedDataPointer<ObjectDescriptionData> > ObjectDescriptionModelData::modelData() const
305{
306 return d->data;
307}
308
309QExplicitlySharedDataPointer<ObjectDescriptionData> ObjectDescriptionModelData::modelData(const QModelIndex &index) const
310{
311 if (!index.isValid() || index.row() >= d->data.size() || index.column() != 0) {
312 return QExplicitlySharedDataPointer<ObjectDescriptionData>(new ObjectDescriptionData(nullptr));
313 }
314 return d->data.at(index.row());
315}
316
317Qt::DropActions ObjectDescriptionModelData::supportedDropActions() const
318{
319 //pDebug() << Q_FUNC_INFO;
320 return Qt::MoveAction;
321}
322
323bool ObjectDescriptionModelData::dropMimeData(ObjectDescriptionType type, const QMimeData *data, Qt::DropAction action,
324 int row, int column, const QModelIndex &parent)
325{
326 Q_UNUSED(action);
327 Q_UNUSED(column);
328 Q_UNUSED(parent);
329 //pDebug() << Q_FUNC_INFO << data << action << row << column << parent;
330
331 QString format = mimeTypes(type).first();
332 if (!data->hasFormat(format)) {
333 return false;
334 }
335
336 if (row == -1) {
337 row = d->data.size();
338 }
339
340 QByteArray encodedData = data->data(format);
341 QDataStream stream(&encodedData, QIODevice::ReadOnly);
343 while (!stream.atEnd()) {
344 int otherIndex;
345 stream >> otherIndex;
346 ObjectDescriptionData *obj = ObjectDescriptionData::fromIndex(type, otherIndex);
347
348 if (obj->isValid()) {
349 toInsert << QExplicitlySharedDataPointer<ObjectDescriptionData>(obj);
350 } else {
351 delete obj;
352 }
353 }
354 d->model->beginInsertRows(QModelIndex(), row, row + toInsert.size() - 1);
355 for (int i = 0 ; i < toInsert.count(); ++i) {
356 d->data.insert(row, toInsert.at(i));
357 }
358 d->model->endInsertRows();
359 return true;
360}
361
362
363bool ObjectDescriptionModelData::removeRows(int row, int count, const QModelIndex &parent)
364{
365 //pDebug() << Q_FUNC_INFO << row << count << parent;
366 if (parent.isValid() || row + count > d->data.size()) {
367 return false;
368 }
369 d->model->beginRemoveRows(parent, row, row + count - 1);
370 for (;count > 0; --count) {
371 d->data.removeAt(row);
372 }
373 d->model->endRemoveRows();
374 return true;
375}
376
377/*
378template<ObjectDescriptionType type>
379bool ObjectDescriptionModel<type>::insertRows(int row, int count, const QModelIndex &parent)
380{
381 pDebug() << Q_FUNC_INFO << row << count << parent;
382 if (parent.isValid() || row < 0 || row > d->data.size()) {
383 return false;
384 }
385 beginInsertRows(parent, row, row + count - 1);
386 for (;count > 0; --count) {
387 d->data.insert(row, ObjectDescription<type>());
388 }
389 endInsertRows();
390 return true;
391}
392*/
393
394QStringList ObjectDescriptionModelData::mimeTypes(ObjectDescriptionType type) const
395{
396 return QStringList(QLatin1String("application/x-phonon-objectdescription") + QString::number(static_cast<int>(type)));
397}
398
399#if !defined(Q_CC_MSVC) || _MSC_VER > 1300 || defined(Q_CC_INTEL) || defined(Q_CC_MINGW)
400#define INSTANTIATE_META_FUNCTIONS(type) \
401template const QMetaObject *ObjectDescriptionModel<type>::metaObject() const; \
402template void *ObjectDescriptionModel<type>::qt_metacast(const char *)
403
404INSTANTIATE_META_FUNCTIONS(AudioOutputDeviceType);
405INSTANTIATE_META_FUNCTIONS(AudioCaptureDeviceType);
406INSTANTIATE_META_FUNCTIONS(VideoCaptureDeviceType);
407INSTANTIATE_META_FUNCTIONS(EffectType);
408INSTANTIATE_META_FUNCTIONS(AudioChannelType);
409INSTANTIATE_META_FUNCTIONS(SubtitleType);
410#endif
411/*INSTANTIATE_META_FUNCTIONS(VideoOutputDeviceType);
412INSTANTIATE_META_FUNCTIONS(AudioCodecType);
413INSTANTIATE_META_FUNCTIONS(VideoCodecType);
414INSTANTIATE_META_FUNCTIONS(ContainerFormatType);
415INSTANTIATE_META_FUNCTIONS(VisualizationType);
416*/
417} // namespace Phonon
418
419#endif //QT_NO_PHONON_OBJECTDESCRIPTIONMODEL
Qt::ItemFlags flags(const QModelIndex &index) const
Reimplemented to show unavailable devices as disabled (but still selectable).
int rowCount(const QModelIndex &parent=QModelIndex()) const
Returns the number of rows in the model.
int tupleIndexAtPositionIndex(int positionIndex) const
Returns the ObjectDescription::index for the tuple at the given position positionIndex.
void moveDown(const QModelIndex &index)
Moves the item at the given index down.
QMimeData * mimeData(ObjectDescriptionType type, const QModelIndexList &indexes) const
Returns the MIME data that dropMimeData() can use to create new items.
QList< int > tupleIndexOrder() const
Returns a list of indexes in the same order as they are in the model.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
Returns data from the item with the given index for the specified role.
void moveUp(const QModelIndex &index)
Moves the item at the given index up.
The ObjectDescriptionModel class provides a model from a list of ObjectDescription objects.
PHONON_TEMPLATE_CLASS_MEMBER_EXPORT const QMetaObject * metaObject() const override
static PHONON_TEMPLATE_CLASS_MEMBER_EXPORT const QMetaObject staticMetaObject
PHONON_TEMPLATE_CLASS_MEMBER_EXPORT void * qt_metacast(const char *_clname) override
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
qsizetype count() const const
T & first()
qsizetype size() const const
void setData(const QString &mimeType, const QByteArray &data)
int column() const const
bool isValid() const const
int row() const const
QModelIndex sibling(int row, int column) const const
void drawPixmap(const QPoint &point, const QPixmap &pixmap)
QString number(double n, char format, int precision)
typedef DropActions
EditRole
typedef ItemFlags
Type type() const const
void * data()
bool isValid() const const
bool toBool() const const
QString toString() const const
T value() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:10:22 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.