28#include <simgear/props/props_io.hxx>
29#include <simgear/structure/exception.hxx>
30#include <simgear/misc/sg_path.hxx>
32#include <simgear/package/Package.hxx>
33#include <simgear/package/Install.hxx>
49 p->onCatalogStatusChanged(
catalog);
61 simgear::pkg::RootRef& rootRef) :
62 QAbstractListModel(pr),
63 m_packageRoot(rootRef)
66 m_packageRoot->addDelegate(m_delegate);
73 m_packageRoot->removeDelegate(m_delegate);
78 CatalogList updatedCatalogs = m_packageRoot->allCatalogs();
79 std::sort(updatedCatalogs.begin(), updatedCatalogs.end(),
80 [](
const CatalogRef& catA,
const CatalogRef& catB)
82 return catA->name() < catB->name();
85 if (updatedCatalogs == m_catalogs)
89 m_catalogs = updatedCatalogs;
98 return static_cast<int>(m_catalogs.size());
103 const auto cat = m_catalogs.at(
static_cast<size_t>(index.row()));
104 if (role == Qt::DisplayRole) {
105 QString
name = QString::fromStdString(cat->name());
107 if (cat->isEnabled()) {
108 desc = QString::fromStdString(cat->description()).simplified();
110 switch (cat->status()) {
111 case Delegate::FAIL_NOT_FOUND:
112 desc = tr(
"The catalog data was not found on the server at the expected location (URL)");
114 case Delegate::FAIL_VERSION:
115 desc = tr(
"The catalog is not compatible with the version of FlightGear");
117 case Delegate::FAIL_HTTP_FORBIDDEN:
118 desc = tr(
"The catalog server is blocking access from some reason (forbidden)");
121 desc = tr(
"disabled due to an internal error");
124 return tr(
"%1 - %2").arg(
name).arg(desc);
126 return QString::fromStdString(cat->description());
128 return QString::fromStdString(cat->name());
129 }
else if (role == Qt::ToolTipRole) {
130 return QString::fromStdString(cat->url());
132 return QUrl(QString::fromStdString(cat->url()));
134 return QString::fromStdString(cat->id());
136 return static_cast<quint32
>(cat->packages().size());
138 return static_cast<quint32
>(cat->installedPackages().size());
140 return translateStatusForCatalog(cat);
142 return (cat == m_newlyAddedCatalog);
144 return cat->isUserEnabled();
152 auto cat = m_catalogs.at(
static_cast<size_t>(index.row()));
154 cat->setUserEnabled(value.toBool());
162 Qt::ItemFlags r = Qt::ItemIsSelectable;
163 const auto cat = m_catalogs.at(
static_cast<size_t>(index.row()));
164 if (cat->isEnabled()) {
165 r |= Qt::ItemIsEnabled;
172 QHash<int, QByteArray> result = QAbstractListModel::roleNames();
185 if ((index < 0) || (index >=
static_cast<int>(m_catalogs.size()))) {
189 const std::string removeId = m_catalogs.at(
static_cast<size_t>(index))->id();
190 m_packageRoot->removeCatalogById(removeId);
196 if ((index < 0) || (index >=
static_cast<int>(m_catalogs.size()))) {
199 m_catalogs.at(
static_cast<size_t>(index))->refresh();
205 CatalogRef cat = Catalog::createFromUrl(m_packageRoot, http->getDefaultCatalogUrl());
206 if (showAddFeedback) {
207 m_newlyAddedCatalog = cat;
217 if (m_newlyAddedCatalog) {
218 qWarning() << Q_FUNC_INFO <<
"already adding a catalog";
222 m_newlyAddedCatalog = Catalog::createFromUrl(m_packageRoot, url.toString().toStdString());
228int CatalogListModel::indexOf(QUrl url)
230 std::string urlString = url.toString().toStdString();
231 auto it = std::find_if(m_catalogs.begin(), m_catalogs.end(),
232 [urlString](simgear::pkg::CatalogRef cat) { return cat->url() == urlString;});
233 if (it == m_catalogs.end())
236 return static_cast<int>(std::distance(m_catalogs.begin(), it));
241 if (!m_newlyAddedCatalog) {
242 qWarning() << Q_FUNC_INFO <<
"no catalog add in progress";
246 auto it = std::find(m_catalogs.begin(), m_catalogs.end(), m_newlyAddedCatalog);
247 if (it == m_catalogs.end()) {
248 qWarning() << Q_FUNC_INFO <<
"couldn't find new catalog in m_catalogs" << QString::fromStdString(m_newlyAddedCatalog->url());
254 const int row =
static_cast<int>(std::distance(m_catalogs.begin(), it));
255 m_newlyAddedCatalog.clear();
258 emit dataChanged(index(row), index(row));
263 if (!m_newlyAddedCatalog)
266 m_packageRoot->removeCatalog(m_newlyAddedCatalog);
268 m_newlyAddedCatalog.clear();
277 return m_newlyAddedCatalog.get() !=
nullptr;
282 if (cat ==
nullptr) {
292 if (cat->status() == Delegate::FAIL_NOT_FOUND) {
294 if (cat->url() == http->getDefaultCatalogUrl()) {
295 cat->setUrl(http->getDefaultCatalogFallbackUrl());
301 if (cat == m_newlyAddedCatalog) {
308 auto it = std::find(m_catalogs.begin(), m_catalogs.end(), cat);
309 if (it == m_catalogs.end())
312 int row = std::distance(m_catalogs.begin(), it);
313 emit dataChanged(index(row), index(row));
318 switch (cat->status()) {
319 case Delegate::STATUS_SUCCESS:
320 case Delegate::STATUS_REFRESHED:
324 case Delegate::STATUS_IN_PROGRESS:
return Refreshing;
328 case Delegate::FAIL_VALIDATION:
329 case Delegate::FAIL_EXTRACT:
338 if (!m_newlyAddedCatalog.get()) {
342 return translateStatusForCatalog(m_newlyAddedCatalog);
const int CatalogNameRole
const int CatalogDescriptionRole
const int CatalogInstallCountRole
const int CatalogIsNewlyAdded
const int CatalogPackageCountRole
const int CatalogStatusRole
void installProgress(InstallRef, unsigned int, unsigned int) override
void finishInstall(InstallRef, StatusCode) override
void startInstall(InstallRef) override
void catalogRefreshed(CatalogRef catalog, StatusCode) override
CatalogDelegate(CatalogListModel *outer)
Q_INVOKABLE void abandonAddCatalog()
Q_INVOKABLE void finalizeAddCatalog()
int rowCount(const QModelIndex &parent) const override
Qt::ItemFlags flags(const QModelIndex &index) const override
CatalogListModel(QObject *pr, const simgear::pkg::RootRef &root)
QVariant data(const QModelIndex &index, int role) const override
void isAddingCatalogChanged()
void onCatalogStatusChanged(simgear::pkg::Catalog *cat)
CatalogStatus statusOfAddingCatalog
Q_INVOKABLE void refreshCatalog(int index)
Q_INVOKABLE void installDefaultCatalog(bool showAddFeedback)
QHash< int, QByteArray > roleNames() const override
Q_INVOKABLE void addCatalogByUrl(QUrl url)
Q_INVOKABLE void removeCatalog(int index)
bool setData(const QModelIndex &index, const QVariant &value, int role) override
void statusOfAddingCatalogChanged()
void addSentryBreadcrumb(const std::string &, const std::string &)