6#include "SpeakersModel.h" 
    9#include "NewstuffModel.h" 
   14class SpeakersModelItem
 
   23    static bool lessThan(
const SpeakersModelItem &one, 
const SpeakersModelItem &two);
 
   26class SpeakersModelPrivate
 
   29    SpeakersModel *m_parent = 
nullptr;
 
   31    QList<SpeakersModelItem> m_speakers;
 
   33    NewstuffModel m_newstuffModel;
 
   35    explicit SpeakersModelPrivate(SpeakersModel *parent);
 
   39    void handleInstallationProgress(
int row, qreal progress);
 
   41    void handleInstallation(
int);
 
   43    QHash<int, QByteArray> m_roleNames;
 
   46SpeakersModelItem::SpeakersModelItem()
 
   52bool SpeakersModelItem::lessThan(
const SpeakersModelItem &one, 
const SpeakersModelItem &two)
 
   54    return one.m_file.fileName() < two.m_file.fileName();
 
   57SpeakersModelPrivate::SpeakersModelPrivate(SpeakersModel *parent)
 
   60    m_newstuffModel.setTargetDirectory(MarbleDirs::localPath() + 
QLatin1StringView(
"/audio/speakers"));
 
   61    m_newstuffModel.setProvider(QStringLiteral(
"http://edu.kde.org/marble/newstuff/speakers.xml"));
 
   62    QObject::connect(&m_newstuffModel, SIGNAL(modelReset()), m_parent, SLOT(fillModel()));
 
   63    QObject::connect(&m_newstuffModel, SIGNAL(installationProgressed(
int, qreal)), m_parent, SLOT(handleInstallationProgress(
int, qreal)));
 
   64    QObject::connect(&m_newstuffModel, SIGNAL(installationFinished(
int)), m_parent, SLOT(handleInstallation(
int)));
 
   67void SpeakersModelPrivate::fillModel()
 
   72    for (
const QString &baseDir : baseDirs) {
 
   78            SpeakersModelItem item;
 
   84    for (
int i = 0; i < m_newstuffModel.rowCount(); ++i) {
 
   88        for (
int j = 0; j < m_speakers.size() && !exists; ++j) {
 
   89            SpeakersModelItem &item = m_speakers[j];
 
   90            if (item.m_file.fileName() == name) {
 
   91                item.m_newstuffIndex = i;
 
   97            SpeakersModelItem item;
 
   98            QString const path = QStringLiteral(
"%1/audio/speakers/%2");
 
  100            item.m_newstuffIndex = i;
 
  105    std::sort(m_speakers.begin(), m_speakers.end(), SpeakersModelItem::lessThan);
 
  106    m_parent->beginResetModel();
 
  107    m_parent->endResetModel();
 
  108    Q_EMIT m_parent->countChanged();
 
  111void SpeakersModelPrivate::handleInstallation(
int row)
 
  113    for (
int j = 0; j < m_speakers.size(); ++j) {
 
  114        if (m_speakers[j].m_newstuffIndex == row) {
 
  115            m_speakers[j].m_file.refresh();
 
  117            Q_EMIT m_parent->dataChanged(affected, affected);
 
  118            Q_EMIT m_parent->installationFinished(j);
 
  123void SpeakersModelPrivate::handleInstallationProgress(
int row, qreal progress)
 
  125    for (
int j = 0; j < m_speakers.size(); ++j) {
 
  126        if (m_speakers[j].m_newstuffIndex == row) {
 
  127            Q_EMIT m_parent->installationProgressed(j, progress);
 
  132SpeakersModel::SpeakersModel(
QObject *parent)
 
  134    , d(new SpeakersModelPrivate(this))
 
  137    roles[Path] = 
"path";
 
  138    roles[Name] = 
"name";
 
  139    roles[IsLocal] = 
"isLocal";
 
  140    roles[IsRemote] = 
"isRemote";
 
  141    d->m_roleNames = roles;
 
  146SpeakersModel::~SpeakersModel()
 
  151int SpeakersModel::rowCount(
const QModelIndex &parent)
 const 
  154        return d->m_speakers.size();
 
  162    if (index.
isValid() && index.
row() >= 0 && index.
row() < d->m_speakers.size()) {
 
  165            return d->m_speakers.at(index.
row()).m_file.fileName();
 
  167            return d->m_speakers.at(index.
row()).m_file.absoluteFilePath();
 
  169            return d->m_speakers.at(index.
row()).m_file.fileName();
 
  171            return d->m_speakers.at(index.
row()).m_file.exists();
 
  173            return d->m_speakers.at(index.
row()).m_newstuffIndex >= 0;
 
  182    return d->m_roleNames;
 
  185int SpeakersModel::indexOf(
const QString &name)
 
  187    for (
int i = 0; i < d->m_speakers.size(); ++i) {
 
  188        if (d->m_speakers[i].m_file.absoluteFilePath() == name || d->m_speakers[i].m_file.fileName() == name) {
 
  195QString SpeakersModel::path(
int index)
 
  197    if (index >= 0 && index <= d->m_speakers.size()) {
 
  198        return d->m_speakers[index].m_file.absoluteFilePath();
 
  203void SpeakersModel::install(
int index)
 
  205    if (index >= 0 && index < d->m_speakers.size()) {
 
  206        if (d->m_speakers[index].m_newstuffIndex >= 0) {
 
  207            d->m_newstuffModel.install(d->m_speakers[index].m_newstuffIndex);
 
  212bool SpeakersModel::isLocal(
int idx)
 const 
  214    return data(index(idx), IsLocal).toBool();
 
  217bool SpeakersModel::isRemote(
int idx)
 const 
  219    return data(index(idx), IsRemote).toBool();
 
  222int SpeakersModel::count()
 const 
  229#include "moc_SpeakersModel.cpp" 
QString path(const QString &relativePath)
 
QString name(StandardAction id)
 
Binds a QML item to a specific geodetic location in screen coordinates.
 
QFileInfoList entryInfoList(Filters filters, SortFlags sort) const const
 
bool isValid() const const
 
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
 
QString arg(Args &&... args) const const
 
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)