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
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 Tue Mar 26 2024 11:20:24 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.