Commit 29ec6af9 authored by Kåre Särs's avatar Kåre Särs
Browse files

build-plugin: Remove Select Target dialog

Move the filtering of targets to the Target Settings tab and remove
the now unneeded popup dialog.

Also:
- Cleanup model-data handling
- Fix ninja workaround after output optimization.
parent 206d18ef
Pipeline #158313 passed with stage
in 9 minutes and 27 seconds
......@@ -2,7 +2,7 @@ kate_add_plugin(katebuildplugin)
target_compile_definitions(katebuildplugin PRIVATE TRANSLATION_DOMAIN="katebuild-plugin")
target_link_libraries(katebuildplugin PRIVATE KF5::I18n KF5::TextEditor)
ki18n_wrap_ui(katebuildplugin build.ui SelectTargetUi.ui)
ki18n_wrap_ui(katebuildplugin build.ui)
target_sources(
katebuildplugin
......@@ -12,7 +12,7 @@ target_sources(
TargetHtmlDelegate.cpp
TargetModel.cpp
UrlInserter.cpp
SelectTargetView.cpp
TargetFilterProxyModel.cpp
plugin.qrc
)
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SelectTargetUi</class>
<widget class="QDialog" name="SelectTargetUi">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>753</width>
<height>375</height>
</rect>
</property>
<property name="windowTitle">
<string>Select build target</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTreeView" name="u_treeView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="u_label">
<property name="text">
<string>Filter</string>
</property>
<property name="buddy">
<cstring>u_filterEdit</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="u_filterEdit"/>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>u_filterEdit</tabstop>
<tabstop>u_treeView</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SelectTargetUi</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>252</x>
<y>370</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SelectTargetUi</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>320</x>
<y>370</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
/***************************************************************************
* This file is part of Kate build plugin *
* SPDX-FileCopyrightText: 2014 Kåre Särs <kare.sars@iki.fi> *
* *
* SPDX-License-Identifier: LGPL-2.0-or-later
***************************************************************************/
#include "SelectTargetView.h"
#include "TargetHtmlDelegate.h"
#include <QDebug>
#include <QKeyEvent>
#include <QSortFilterProxyModel>
#include <QTimer>
class TargetFilterProxyModel : public QSortFilterProxyModel
{
public:
TargetFilterProxyModel(QObject *parent)
: QSortFilterProxyModel(parent)
{
}
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
{
if (m_filter.isEmpty()) {
return true;
}
QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
QString name = index0.data().toString();
if (index0.internalId() == 0xffffffff) {
int i = 0;
auto childIndex = index0.model()->index(i, 0, index0);
while (childIndex.data().isValid()) {
name = childIndex.data().toString();
if (name.contains(m_filter, Qt::CaseInsensitive)) {
return true;
}
i++;
childIndex = index0.model()->index(i, 0, index0);
}
return false;
}
return name.contains(m_filter, Qt::CaseInsensitive);
}
void setFilter(const QString &filter)
{
m_filter = filter;
invalidateFilter();
}
Qt::ItemFlags flags(const QModelIndex &index) const override
{
if (!index.isValid()) {
return Qt::NoItemFlags;
}
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QString m_filter;
};
SelectTargetView::SelectTargetView(QAbstractItemModel *model, QWidget *parent)
: QDialog(parent)
{
setupUi(this);
m_proxyModel = new TargetFilterProxyModel(this);
m_proxyModel->setSourceModel(model);
u_treeView->setModel(m_proxyModel);
u_treeView->expandAll();
u_treeView->resizeColumnToContents(0);
u_treeView->setEditTriggers(QAbstractItemView::EditKeyPressed);
setFocusProxy(u_filterEdit);
connect(u_filterEdit, &QLineEdit::textChanged, this, &SelectTargetView::setFilter);
connect(u_treeView, &QTreeView::doubleClicked, this, &SelectTargetView::accept);
u_filterEdit->installEventFilter(this);
}
void SelectTargetView::setFilter(const QString &filter)
{
m_proxyModel->setFilter(filter);
u_treeView->expandAll();
}
const QModelIndex SelectTargetView::currentIndex() const
{
return m_proxyModel->mapToSource(u_treeView->currentIndex());
}
void SelectTargetView::setCurrentIndex(const QModelIndex &index)
{
u_treeView->setCurrentIndex(m_proxyModel->mapFromSource(index));
}
bool SelectTargetView::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (obj == u_filterEdit) {
if ((keyEvent->key() == Qt::Key_Up) || (keyEvent->key() == Qt::Key_Down) || (keyEvent->key() == Qt::Key_PageUp)
|| (keyEvent->key() == Qt::Key_PageDown)) {
QCoreApplication::sendEvent(u_treeView, event);
return true;
}
}
}
return QDialog::eventFilter(obj, event);
}
/***************************************************************************
* This file is part of Kate build plugin *
* SPDX-FileCopyrightText: 2022 Kåre Särs <kare.sars@iki.fi> *
* *
* SPDX-License-Identifier: LGPL-2.0-or-later
***************************************************************************/
#include "TargetFilterProxyModel.h"
#include <QDebug>
TargetFilterProxyModel::TargetFilterProxyModel(QObject *parent)
: QSortFilterProxyModel(parent)
{
}
bool TargetFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
if (m_filter.isEmpty()) {
return true;
}
QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
QString name = index0.data().toString();
if (index0.internalId() == 0xffffffff) {
int i = 0;
auto childIndex = index0.model()->index(i, 0, index0);
while (childIndex.data().isValid()) {
name = childIndex.data().toString();
if (name.contains(m_filter, Qt::CaseInsensitive)) {
return true;
}
i++;
childIndex = index0.model()->index(i, 0, index0);
}
return false;
}
return name.contains(m_filter, Qt::CaseInsensitive);
}
void TargetFilterProxyModel::setFilter(const QString &filter)
{
m_filter = filter;
invalidateFilter();
}
bool TargetFilterProxyModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
QModelIndex srcIndex = mapToSource(index);
return sourceModel()->setData(srcIndex, value, role);
}
......@@ -4,31 +4,24 @@
* *
* SPDX-License-Identifier: LGPL-2.0-or-later
***************************************************************************/
#ifndef SelectTargetView_H
#define SelectTargetView_H
#ifndef TargetFilterProxyModel_H
#define TargetFilterProxyModel_H
#include "ui_SelectTargetUi.h"
#include <QAbstractItemModel>
#include <QModelIndex>
#include <QObject>
#include <QSortFilterProxyModel>
#include <QString>
class TargetFilterProxyModel;
class SelectTargetView : public QDialog, public Ui::SelectTargetUi
class TargetFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
SelectTargetView(QAbstractItemModel *model, QWidget *parent = nullptr);
const QModelIndex currentIndex() const;
void setCurrentIndex(const QModelIndex &index);
TargetFilterProxyModel(QObject *parent = nullptr);
public Q_SLOTS:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
void setFilter(const QString &filter);
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private:
TargetFilterProxyModel *m_proxyModel;
QString m_filter;
};
#endif
......@@ -50,24 +50,7 @@ void TargetModel::setDefaultCmd(int rootRow, const QString &defCmd)
}
}
int TargetModel::getDefaultCmdIndex(int rootRow) const
{
if (rootRow < 0 || rootRow >= m_targets.size()) {
qDebug() << "rootRow not valid";
return 0;
}
auto defCmd = m_targets[rootRow].defaultCmd;
for (int i = 0; i < m_targets[rootRow].commands.size(); i++) {
if (defCmd == m_targets[rootRow].commands[i].first) {
return i;
}
}
return 0;
}
int TargetModel::addTargetSet(const QString &setName, const QString &workDir)
QModelIndex TargetModel::addTargetSet(const QString &setName, const QString &workDir)
{
// make the name unique
QString newName = setName;
......@@ -82,11 +65,12 @@ int TargetModel::addTargetSet(const QString &setName, const QString &workDir)
TargetModel::TargetSet targetSet(newName, workDir);
m_targets << targetSet;
endInsertRows();
return m_targets.count() - 1;
return index(m_targets.count() - 1, 0);
}
QModelIndex TargetModel::addCommand(int rootRow, const QString &cmdName, const QString &command)
QModelIndex TargetModel::addCommand(const QModelIndex &parentIndex, const QString &cmdName, const QString &command)
{
int rootRow = parentIndex.row();
if (rootRow < 0 || rootRow >= m_targets.size()) {
qDebug() << "rootRow not valid";
return QModelIndex();
......@@ -164,9 +148,33 @@ QModelIndex TargetModel::copyTargetOrSet(const QModelIndex &index)
return createIndex(m_targets[rootRow].commands.count() - 1, 0, rootRow);
}
QModelIndex TargetModel::defaultTarget(int targetSet)
QModelIndex TargetModel::defaultTarget(const QModelIndex &targetSet)
{
return createIndex(getDefaultCmdIndex(targetSet), 0, targetSet);
QModelIndex root = targetSet.sibling(targetSet.row(), 0);
if (root.parent().isValid()) {
// go to the parent so we know where we start
root = root.parent();
}
// This is the target-set root
auto model = root.model();
if (!model) {
qDebug() << "No model found";
return QModelIndex();
}
QModelIndex defaultIndex;
for (int i = 0; i < model->rowCount(root); ++i) {
QModelIndex childIndex = model->index(i, 0, root);
if (i == 0) {
defaultIndex = childIndex;
}
if (childIndex.data(Qt::CheckStateRole) == Qt::Checked) {
defaultIndex = childIndex;
break;
}
}
return defaultIndex;
}
void TargetModel::deleteItem(const QModelIndex &index)
......@@ -198,88 +206,93 @@ void TargetModel::deleteTargetSet(const QString &targetSet)
}
}
const QString TargetModel::command(const QModelIndex &itemIndex) const
const QString TargetModel::command(const QModelIndex &itemIndex)
{
if (!itemIndex.isValid()) {
return QString();
}
quint32 rRow = itemIndex.internalId();
int cRow = itemIndex.row();
if (rRow == TargetModel::InvalidIndex) {
rRow = cRow;
cRow = 0;
}
if (static_cast<int>(rRow) >= m_targets.count()) {
return QString();
}
// take the item from the second column
QModelIndex cmdIndex = itemIndex.siblingAtColumn(1);
if (cRow < 0 || cRow >= m_targets[static_cast<int>(rRow)].commands.count()) {
return QString();
if (!itemIndex.parent().isValid()) {
// This is the target-set root column
// execute the default target (checked or first child)
auto model = itemIndex.model();
if (!model) {
qDebug() << "No model found";
return QString();
}
for (int i = 0; i < model->rowCount(itemIndex); ++i) {
QModelIndex childIndex = model->index(i, 0, itemIndex);
if (i == 0) {
cmdIndex = childIndex.siblingAtColumn(1);
}
if (childIndex.data(Qt::CheckStateRole) == Qt::Checked) {
cmdIndex = childIndex.siblingAtColumn(1);
break;
}
}
}
return m_targets[rRow].commands[cRow].second;
return cmdIndex.data().toString();
}
const QString TargetModel::cmdName(const QModelIndex &itemIndex) const
const QString TargetModel::cmdName(const QModelIndex &itemIndex)
{
if (!itemIndex.isValid()) {
return QString();
}
quint32 rRow = itemIndex.internalId();
int cRow = itemIndex.row();
if (rRow == TargetModel::InvalidIndex) {
rRow = cRow;
cRow = 0;
}
if (static_cast<int>(rRow) >= m_targets.count()) {
return QString();
}
// take the item from the first column
QModelIndex nameIndex = itemIndex.sibling(itemIndex.row(), 0);
if (cRow < 0 || cRow >= m_targets[static_cast<int>(rRow)].commands.count()) {
return QString();
if (!itemIndex.parent().isValid()) {
// This is the target-set root column
// execute the default target (checked or first child)
auto model = itemIndex.model();
if (!model) {
qDebug() << "No model found";
return QString();
}
for (int i = 0; i < model->rowCount(itemIndex); ++i) {
QModelIndex childIndex = model->index(i, 0, itemIndex);
if (i == 0) {
nameIndex = childIndex.siblingAtColumn(0);
}
if (childIndex.data(Qt::CheckStateRole) == Qt::Checked) {
nameIndex = childIndex.siblingAtColumn(0);
break;
}
}
}
return m_targets[static_cast<int>(rRow)].commands[cRow].first;
return nameIndex.data().toString();
}
const QString TargetModel::workDir(const QModelIndex &itemIndex) const
const QString TargetModel::workDir(const QModelIndex &itemIndex)
{
if (!itemIndex.isValid()) {
return QString();
}
quint32 rRow = itemIndex.internalId();
int cRow = itemIndex.row();
if (rRow == TargetModel::InvalidIndex) {
rRow = cRow;
cRow = 0;
}
if (static_cast<int>(rRow) >= m_targets.count()) {
return QString();
}
QModelIndex workDirIndex = itemIndex.sibling(itemIndex.row(), 1);
return m_targets[static_cast<int>(rRow)].workDir;
if (itemIndex.parent().isValid()) {
workDirIndex = itemIndex.parent().siblingAtColumn(1);
}
return workDirIndex.data().toString();
}
const QString TargetModel::targetName(const QModelIndex &itemIndex) const
const QString TargetModel::targetName(const QModelIndex &itemIndex)
{
if (!itemIndex.isValid()) {
return QString();
}
quint32 rRow = itemIndex.internalId();
int cRow = itemIndex.row();
if (rRow == TargetModel::InvalidIndex) {
rRow = cRow;
cRow = 0;
}
QModelIndex targetNameIndex = itemIndex.sibling(itemIndex.row(), 0);
if (static_cast<int>(rRow) >= m_targets.count()) {
return QString();
if (itemIndex.parent().isValid()) {
targetNameIndex = itemIndex.parent().siblingAtColumn(0);
}
return m_targets[static_cast<int>(rRow)].name;
return targetNameIndex.data().toString();
}
QVariant TargetModel::data(const QModelIndex &index, int role) const
......
......@@ -34,19 +34,17 @@ public Q_SLOTS:
/** This function clears all the target-sets */
void clear();
/** This function adds a target set and returns the row number of the newly
* inserted row */
int addTargetSet(const QString &setName, const QString &workDir);
/** This function adds a target set and returns the model-index of the newly
* inserted target-set */
QModelIndex addTargetSet(const QString &setName, const QString &workDir);
/** This function adds a new command to a target-set and returns the model index */
QModelIndex addCommand(int rootRow, const QString &cmdName, const QString &command);
QModelIndex addCommand(const QModelIndex &parentIndex, const QString &cmdName, const QString &command);
/** This function copies the target(-set) the model index points to and returns
* the model index of the copy. */
QModelIndex copyTargetOrSet(const QModelIndex &index);
/** This function returns the model index of the default command of the target-set */
QModelIndex defaultTarget(int targetSet);
/** This function deletes the index */
void deleteItem(const QModelIndex &index);
......@@ -59,11 +57,12 @@ public Q_SLOTS:
return m_targets;
}
const QString command(const QModelIndex &itemIndex) const;
const QString cmdName(const QModelIndex &itemIndex) const;
const QString workDir(const QModelIndex &itemIndex) const;
const QString targetName(const QModelIndex &itemIndex) const;
int getDefaultCmdIndex(int rootRow) const;
/** Static functions that could be in a different file */
static QModelIndex defaultTarget(const QModelIndex &targetSetIndex);
static const QString command(const QModelIndex &itemIndex);
static const QString cmdName(const QModelIndex &itemIndex);
static const QString workDir(const QModelIndex &itemIndex);
static const QString targetName(const QModelIndex &itemIndex);
Q_SIGNALS:
......
......@@ -51,8 +51,6 @@
#include <KPluginFactory>
#include <KXMLGUIFactory>
#include "SelectTargetView.h"
#include <ktexteditor_utils.h>
K_PLUGIN_FACTORY_WITH_JSON(KateBuildPluginFactory, "katebuildplugin.json", registerPlugin<KateBuildPlugin>();)
......@@ -62,7 +60,7 @@ static const QString DefConfClean;
static const QString DefTargetName = QStringLiteral("all");
static const QString DefBuildCmd = QStringLiteral("make");
static const QString DefCleanCmd = QStringLiteral("make clean");