2
* Copyright (C) 2011 Tuomo Penttinen, all rights reserved.
4
* Author: Tuomo Penttinen <tp@herqq.org>
6
* This file is part of an application named HUpnpAvSimpleTestApp
7
* used for demonstrating how to use the Herqq UPnP A/V (HUPnPAv) library.
9
* HUpnpAvSimpleTestApp is free software: you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation, either version 3 of the License, or
12
* (at your option) any later version.
14
* HUpnpAvSimpleTestApp is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with HUpnpAvSimpleTestApp. If not, see <http://www.gnu.org/licenses/>.
23
#include "controlpoint_navigator.h"
24
#include "controlpoint_navigatoritem.h"
26
#include <HUpnpAv/HContainer>
27
#include <HUpnpAv/HProtocolInfo>
28
#include <HUpnpAv/HMediaBrowser>
29
#include <HUpnpAv/HCdsDataSource>
30
#include <HUpnpAv/HMediaServerAdapter>
31
#include <HUpnpAv/HMediaRendererAdapter>
32
#include <HUpnpAv/HContentDirectoryAdapter>
34
#include <HUpnpCore/HClientService>
40
using namespace Herqq::Upnp;
41
using namespace Herqq::Upnp::Av;
43
ControlPointNavigator::ControlPointNavigator(QObject* parent) :
44
QAbstractItemModel(parent),
45
m_rootItem(new RootItem()), m_renderersItem(), m_serversItem()
47
m_renderersItem = new ContainerItem("Media Renderers", m_rootItem);
48
m_rootItem->appendChild(m_renderersItem);
50
m_serversItem = new ContainerItem("Media Servers", m_rootItem);
51
m_rootItem->appendChild(m_serversItem);
54
ControlPointNavigator::~ControlPointNavigator()
59
void ControlPointNavigator::mediaRendererOnline(HMediaRendererAdapter* mediaRenderer)
61
HClientAdapterOp<qint32> op = mediaRenderer->getCurrentConnections();
69
SIGNAL(connectionReady(Herqq::Upnp::Av::HMediaRendererAdapter*, qint32)),
71
SLOT(connectionReady(Herqq::Upnp::Av::HMediaRendererAdapter*, qint32)));
72
Q_ASSERT(ok); Q_UNUSED(ok)
76
SIGNAL(error(Herqq::Upnp::Av::HMediaRendererAdapter*,
77
Herqq::Upnp::HClientAdapterOp<qint32>)),
79
SLOT(error(Herqq::Upnp::Av::HMediaRendererAdapter*,
80
Herqq::Upnp::HClientAdapterOp<qint32>)));
83
RendererItem* rendererItem = new RendererItem(mediaRenderer, m_renderersItem);
86
QModelIndex(), m_rootItem->childCount(), m_rootItem->childCount());
88
m_renderersItem->appendChild(rendererItem);
93
void ControlPointNavigator::error(Herqq::Upnp::Av::HMediaRendererAdapter*,
94
const Herqq::Upnp::HClientAdapterOp<qint32>& op)
99
void ControlPointNavigator::connectionReady(HMediaRendererAdapter* source, qint32 id)
101
RendererItem* parentItem = 0;
102
for(qint32 i = 0; i < m_renderersItem->childCount(); ++i)
104
RendererItem* deviceItem =
105
static_cast<RendererItem*>(m_renderersItem->child(i));
107
if (deviceItem->renderer() == source)
109
parentItem = deviceItem;
116
HConnection* connection = source->connection(id);
117
ConnectionItem* connectionItem = new ConnectionItem(connection, parentItem);
120
connection, SIGNAL(destroyed(QObject*)),
121
this, SLOT(connectionDestroyed(QObject*)));
122
Q_ASSERT(ok); Q_UNUSED(ok)
125
QModelIndex(), m_rootItem->childCount(), m_rootItem->childCount());
127
parentItem->appendChild(connectionItem);
133
void ControlPointNavigator::connectionDestroyed(QObject* conn)
135
for(qint32 i = 0; i < m_renderersItem->childCount(); ++i)
137
RendererItem* rendererItem =
138
static_cast<RendererItem*>(m_renderersItem->child(i));
140
for (int j = 0; j < rendererItem->childCount(); ++j)
142
ConnectionItem* conItem =
143
static_cast<ConnectionItem*>(rendererItem->child(j));
145
if (!conItem->connection() || conItem->connection() == conn)
147
beginRemoveRows(index(j, 0, renderersIndex()), j, j);
148
rendererItem->removeChild(j);
156
void ControlPointNavigator::mediaRendererOffline(HMediaRendererAdapter* device)
158
for(qint32 i = 0; i < m_renderersItem->childCount(); ++i)
160
RendererItem* rendererItem =
161
static_cast<RendererItem*>(m_renderersItem->child(i));
163
if (rendererItem->renderer() == device)
165
beginRemoveRows(renderersIndex(), i, i);
166
m_renderersItem->removeChild(i);
173
HMediaBrowser* ControlPointNavigator::mediaServerOnline(HMediaServerAdapter* device)
175
HMediaBrowser* browser = new HMediaBrowser(this);
176
if (!browser->reset(device->contentDirectory(), false))
183
SIGNAL(objectsBrowsed(Herqq::Upnp::Av::HMediaBrowser*,QSet<QString>)),
185
SLOT(objectsBrowsed(Herqq::Upnp::Av::HMediaBrowser*,QSet<QString>)));
186
Q_ASSERT(ok); Q_UNUSED(ok)
190
SIGNAL(browseFailed(Herqq::Upnp::Av::HMediaBrowser*)),
192
SLOT(browseFailed(Herqq::Upnp::Av::HMediaBrowser*)));
193
Q_ASSERT(ok); Q_UNUSED(ok)
195
if (!browser->browseRoot())
197
delete browser; browser = 0;
201
ContentDirectoryItem* cdItem =
202
new ContentDirectoryItem(browser, m_serversItem);
204
beginInsertRows(QModelIndex(), m_rootItem->childCount(), m_rootItem->childCount());
205
m_serversItem->appendChild(cdItem);
212
CdsContainerItem* ControlPointNavigator::findParentContainer(
213
CdsContainerItem* parent, const QString& id)
215
for (int i = 0; i < parent->childCount(); ++i)
217
CdsContainerItem* item = static_cast<CdsContainerItem*>(parent->child(i));
218
if (item->container()->id() == id)
224
item = findParentContainer(item, id);
236
bool hasContainerItem(const CdsContainerItem* item, const HContainer* container)
238
for(int i = 0; i < item->childCount(); ++i)
240
const CdsContainerItem* cdsContainerItem =
241
dynamic_cast<const CdsContainerItem*>(item->child(i));
243
if (cdsContainerItem && cdsContainerItem->container() == container)
247
else if (hasContainerItem(cdsContainerItem, container))
256
void ControlPointNavigator::objectsBrowsed(
257
HMediaBrowser* browser, const QSet<QString>& ids)
259
HCdsDataSource* dataSource = browser->dataSource();
261
ContentDirectoryItem* cdsItem = 0;
262
for(int i = 0; i < m_serversItem->childCount(); ++i)
264
cdsItem = static_cast<ContentDirectoryItem*>(m_serversItem->child(i));
265
if (cdsItem->browser() == browser)
272
foreach(const QString& id, ids)
274
HContainer* container = dataSource->findContainer(id);
282
CdsContainerItem* rootItem =
283
static_cast<CdsContainerItem*>(cdsItem->child(0));
285
if (hasContainerItem(rootItem, container))
290
if ("0" == container->parentId())
292
CdsContainerItem* newContainerItem =
293
new CdsContainerItem(container, dataSource, rootItem);
295
rootItem->appendChild(newContainerItem);
299
CdsContainerItem* item =
300
findParentContainer(rootItem, container->parentId());
304
CdsContainerItem* newContainerItem =
305
new CdsContainerItem(container, dataSource, item);
307
item->appendChild(newContainerItem);
313
CdsContainerItem* newContainerItem =
314
new CdsContainerItem(container, dataSource, cdsItem);
316
cdsItem->appendChild(newContainerItem);
320
beginInsertRows(QModelIndex(), m_rootItem->childCount(), m_rootItem->childCount());
324
void ControlPointNavigator::browseFailed(HMediaBrowser*)
328
void ControlPointNavigator::mediaServerOffline(HMediaServerAdapter* device)
330
for(qint32 i = 0; i < m_serversItem->childCount(); ++i)
332
ContentDirectoryItem* cdItem =
333
static_cast<ContentDirectoryItem*>(m_serversItem->child(i));
335
if (cdItem->browser()->contentDirectory()->service()->parentDevice() == device->device())
337
beginRemoveRows(serversIndex(), i, i);
338
m_serversItem->removeChild(i);
345
int ControlPointNavigator::columnCount(const QModelIndex& parent) const
347
if (parent.isValid())
349
return static_cast<ControlPointNavigatorItem*>(
350
parent.internalPointer())->columnCount();
354
return m_rootItem->columnCount();
358
QVariant ControlPointNavigator::data(const QModelIndex& index, int role) const
360
if (!index.isValid())
365
if (role != Qt::DisplayRole)
370
ControlPointNavigatorItem* item =
371
static_cast<ControlPointNavigatorItem*>(index.internalPointer());
375
return item->data(index.column());
378
Qt::ItemFlags ControlPointNavigator::flags(const QModelIndex& index) const
380
if (!index.isValid())
385
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
388
QVariant ControlPointNavigator::headerData(
389
int section, Qt::Orientation orientation, int role) const
391
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
393
return m_rootItem->data(section);
399
QModelIndex ControlPointNavigator::index(
400
int row, int column, const QModelIndex& parent) const
402
if (!hasIndex(row, column, parent))
404
return QModelIndex();
407
ControlPointNavigatorItem* parentItem = 0;
408
if (!parent.isValid())
410
parentItem = m_rootItem;
415
static_cast<ControlPointNavigatorItem*>(parent.internalPointer());
417
Q_ASSERT(parentItem);
419
ControlPointNavigatorItem* childItem = parentItem->child(row);
422
return createIndex(row, column, childItem);
426
return QModelIndex();
430
QModelIndex ControlPointNavigator::parent(const QModelIndex& itemIndex) const
432
if (!itemIndex.isValid() || !itemIndex.internalPointer())
434
return QModelIndex();
437
ControlPointNavigatorItem* childItem =
438
static_cast<ControlPointNavigatorItem*>(itemIndex.internalPointer());
440
ControlPointNavigatorItem* parentItem = childItem->parent();
441
Q_ASSERT(parentItem);
443
if (parentItem == m_rootItem)
445
return QModelIndex();
448
return createIndex(0, 0, parentItem);
451
int ControlPointNavigator::rowCount(const QModelIndex& parent) const
453
ControlPointNavigatorItem* parentItem = 0;
455
if (parent.column() > 0)
460
if (!parent.isValid())
462
parentItem = m_rootItem;
467
static_cast<ControlPointNavigatorItem*>(parent.internalPointer());
470
Q_ASSERT(parentItem);
472
return parentItem->childCount();