File indexing completed on 2025-03-09 04:56:49

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Kevin Ottens <ervin@kde.org>
0003  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004  */
0005 
0006 
0007 #include "availablesourcesview.h"
0008 
0009 #include <algorithm>
0010 
0011 #include <QAction>
0012 #include <QApplication>
0013 #include <QHeaderView>
0014 #include <QSortFilterProxyModel>
0015 #include <QToolBar>
0016 #include <QTreeView>
0017 #include <QVBoxLayout>
0018 
0019 #include <KLocalizedString>
0020 
0021 #include "presentation/metatypes.h"
0022 #include "presentation/querytreemodelbase.h"
0023 
0024 #include "widgets/datasourcedelegate.h"
0025 
0026 using namespace Widgets;
0027 
0028 AvailableSourcesView::AvailableSourcesView(QWidget *parent)
0029     : QWidget(parent),
0030       m_defaultAction(new QAction(this)),
0031       m_model(nullptr),
0032       m_sortProxy(new QSortFilterProxyModel(this)),
0033       m_sourcesView(new QTreeView(this))
0034 {
0035     m_sortProxy->setDynamicSortFilter(true);
0036     m_sortProxy->sort(0);
0037 
0038     m_sourcesView->setObjectName(QLatin1StringView("sourcesView"));
0039     m_sourcesView->header()->hide();
0040     m_sourcesView->setModel(m_sortProxy);
0041     connect(m_sourcesView->selectionModel(), &QItemSelectionModel::selectionChanged,
0042             this, &AvailableSourcesView::onSelectionChanged);
0043     connect(m_sourcesView->model(), &QAbstractItemModel::rowsInserted, m_sourcesView, &QTreeView::expand);
0044     connect(m_sourcesView->model(), &QAbstractItemModel::layoutChanged, m_sourcesView, &QTreeView::expandAll);
0045     connect(m_sourcesView->model(), &QAbstractItemModel::modelReset, m_sourcesView, &QTreeView::expandAll);
0046 
0047     auto delegate = new DataSourceDelegate(m_sourcesView);
0048     m_sourcesView->setItemDelegate(delegate);
0049 
0050     auto actionBar = new QToolBar(this);
0051     actionBar->setObjectName(QLatin1StringView("actionBar"));
0052     actionBar->setIconSize(QSize(16, 16));
0053 
0054     m_defaultAction->setObjectName(QLatin1StringView("defaultAction"));
0055     m_defaultAction->setText(i18n("Use as Default Source"));
0056     m_defaultAction->setIcon(QIcon::fromTheme(QStringLiteral("folder-favorites")));
0057     connect(m_defaultAction, &QAction::triggered, this, &AvailableSourcesView::onDefaultTriggered);
0058     actionBar->addAction(m_defaultAction);
0059 
0060     auto layout = new QVBoxLayout;
0061     layout->addWidget(m_sourcesView);
0062 
0063     auto actionBarLayout = new QHBoxLayout;
0064     actionBarLayout->setContentsMargins(0, 0, 0, 0);
0065     actionBarLayout->setAlignment(Qt::AlignRight);
0066     actionBarLayout->addWidget(actionBar);
0067     layout->addLayout(actionBarLayout);
0068     setLayout(layout);
0069 
0070     auto margins = layout->contentsMargins();
0071     margins.setBottom(0);
0072     layout->setContentsMargins(margins);
0073 
0074     auto settingsAction = new QAction(this);
0075     settingsAction->setObjectName(QLatin1StringView("settingsAction"));
0076     settingsAction->setText(i18n("Configure %1...", QApplication::applicationName()));
0077     settingsAction->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
0078     connect(settingsAction, &QAction::triggered, this, &AvailableSourcesView::onSettingsTriggered);
0079     m_actions.insert(QStringLiteral("options_configure"), settingsAction);
0080 
0081     onSelectionChanged();
0082 }
0083 
0084 QHash<QString, QAction *> AvailableSourcesView::globalActions() const
0085 {
0086     return m_actions;
0087 }
0088 
0089 QObject *AvailableSourcesView::model() const
0090 {
0091     return m_model;
0092 }
0093 
0094 void AvailableSourcesView::setModel(QObject *model)
0095 {
0096     if (model == m_model)
0097         return;
0098 
0099     m_sortProxy->setSourceModel(nullptr);
0100 
0101     m_model = model;
0102 
0103     setEnabled(m_model);
0104 
0105     if (!m_model)
0106         return;
0107 
0108     setSourceModel("sourceListModel");
0109 }
0110 
0111 void AvailableSourcesView::onSelectionChanged()
0112 {
0113     const auto selectedIndexes = m_sourcesView->selectionModel()->selectedIndexes();
0114     auto selectedSources = Domain::DataSource::List();
0115     std::transform(selectedIndexes.constBegin(), selectedIndexes.constEnd(),
0116                    std::back_inserter(selectedSources),
0117                    [] (const QModelIndex &index) {
0118                        return index.data(Presentation::QueryTreeModelBase::ObjectRole)
0119                                    .value<Domain::DataSource::Ptr>();
0120                    });
0121 
0122     m_defaultAction->setEnabled(selectedSources.size() == 1
0123                              && selectedSources.first()->contentTypes() != Domain::DataSource::NoContent);
0124 }
0125 
0126 void AvailableSourcesView::onSettingsTriggered()
0127 {
0128     QMetaObject::invokeMethod(m_model, "showConfigDialog");
0129 }
0130 
0131 void AvailableSourcesView::onDefaultTriggered()
0132 {
0133     const auto currentIndex = m_sourcesView->currentIndex();
0134     const auto index = m_sortProxy->mapToSource(currentIndex);
0135     if (index.isValid())
0136         QMetaObject::invokeMethod(m_model, "setDefaultItem",
0137                                   Q_ARG(QModelIndex, index));
0138 }
0139 
0140 void AvailableSourcesView::setSourceModel(const QByteArray &propertyName)
0141 {
0142     QVariant modelProperty = m_model->property(propertyName);
0143     if (modelProperty.canConvert<QAbstractItemModel*>())
0144         m_sortProxy->setSourceModel(modelProperty.value<QAbstractItemModel*>());
0145 }
0146 
0147 #include "moc_availablesourcesview.cpp"