File indexing completed on 2024-04-28 05:48:39
0001 // 0002 // Description: Widget for configuring build targets 0003 // 0004 // SPDX-FileCopyrightText: 2011-2022 Kåre Särs <kare.sars@iki.fi> 0005 // 0006 // SPDX-License-Identifier: LGPL-2.0-only 0007 0008 #include "targets.h" 0009 #include <KLocalizedString> 0010 #include <QApplication> 0011 #include <QDebug> 0012 #include <QEvent> 0013 #include <QHeaderView> 0014 #include <QIcon> 0015 #include <QKeyEvent> 0016 0017 TargetsUi::TargetsUi(QObject *view, QWidget *parent) 0018 : QWidget(parent) 0019 { 0020 proxyModel.setSourceModel(&targetsModel); 0021 0022 targetFilterEdit = new QLineEdit(this); 0023 targetFilterEdit->setPlaceholderText(i18n("Filter targets, use arrow keys to select, Enter to execute")); 0024 targetFilterEdit->setClearButtonEnabled(true); 0025 0026 newTarget = new QToolButton(this); 0027 newTarget->setToolTip(i18n("Create new set of targets")); 0028 newTarget->setIcon(QIcon::fromTheme(QStringLiteral("document-new"))); 0029 0030 copyTarget = new QToolButton(this); 0031 copyTarget->setToolTip(i18n("Copy command or target set")); 0032 copyTarget->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"))); 0033 0034 deleteTarget = new QToolButton(this); 0035 deleteTarget->setToolTip(i18n("Delete current target or current set of targets")); 0036 deleteTarget->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete"))); 0037 0038 addButton = new QToolButton(this); 0039 addButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); 0040 addButton->setToolTip(i18n("Add new target")); 0041 0042 buildButton = new QToolButton(this); 0043 buildButton->setIcon(QIcon::fromTheme(QStringLiteral("run-build"))); 0044 buildButton->setToolTip(i18n("Build selected target")); 0045 0046 runButton = new QToolButton(this); 0047 runButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"))); 0048 runButton->setToolTip(i18n("Build and run selected target")); 0049 0050 moveTargetUp = new QToolButton(this); 0051 moveTargetUp->setIcon(QIcon::fromTheme(QStringLiteral("go-up"))); 0052 moveTargetUp->setToolTip(i18n("Move selected target up")); 0053 0054 moveTargetDown = new QToolButton(this); 0055 moveTargetDown->setIcon(QIcon::fromTheme(QStringLiteral("go-down"))); 0056 moveTargetDown->setToolTip(i18n("Move selected target down")); 0057 0058 targetsView = new QTreeView(this); 0059 targetsView->setAlternatingRowColors(true); 0060 0061 targetsView->setModel(&proxyModel); 0062 m_delegate = new TargetHtmlDelegate(view); 0063 targetsView->setItemDelegate(m_delegate); 0064 targetsView->setSelectionBehavior(QAbstractItemView::SelectItems); 0065 targetsView->setEditTriggers(QAbstractItemView::AnyKeyPressed | QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed); 0066 targetsView->expandAll(); 0067 targetsView->header()->setStretchLastSection(false); 0068 targetsView->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); 0069 targetsView->header()->setSectionResizeMode(1, QHeaderView::Stretch); 0070 targetsView->header()->setSectionResizeMode(2, QHeaderView::Stretch); 0071 QHBoxLayout *tLayout = new QHBoxLayout(); 0072 0073 tLayout->addWidget(targetFilterEdit); 0074 tLayout->addWidget(buildButton); 0075 tLayout->addWidget(runButton); 0076 tLayout->addSpacing(15); 0077 tLayout->addWidget(addButton); 0078 tLayout->addWidget(newTarget); 0079 tLayout->addWidget(copyTarget); 0080 tLayout->addWidget(moveTargetUp); 0081 tLayout->addWidget(moveTargetDown); 0082 tLayout->addWidget(deleteTarget); 0083 int leftMargin = QApplication::style()->pixelMetric(QStyle::PM_LayoutLeftMargin); 0084 tLayout->setContentsMargins(leftMargin, 0, 0, 0); 0085 0086 QVBoxLayout *layout = new QVBoxLayout(this); 0087 layout->addLayout(tLayout); 0088 layout->addWidget(targetsView); 0089 layout->setContentsMargins(0, 0, 0, 0); 0090 0091 connect(targetsView->selectionModel(), &QItemSelectionModel::currentChanged, this, &TargetsUi::targetActivated); 0092 0093 connect(targetsView->selectionModel(), &QItemSelectionModel::currentChanged, this, &TargetsUi::updateTargetsButtonStates); 0094 connect(&targetsModel, &QAbstractItemModel::dataChanged, this, &TargetsUi::updateTargetsButtonStates); 0095 connect(&targetsModel, &QAbstractItemModel::rowsMoved, this, &TargetsUi::updateTargetsButtonStates); 0096 0097 connect(targetFilterEdit, &QLineEdit::textChanged, this, [this](const QString &text) { 0098 proxyModel.setFilter(text); 0099 targetsView->expandAll(); 0100 targetsView->scrollTo(targetsView->currentIndex()); 0101 }); 0102 0103 targetsView->installEventFilter(this); 0104 targetFilterEdit->installEventFilter(this); 0105 } 0106 0107 void TargetsUi::targetActivated(const QModelIndex &index) 0108 { 0109 // qDebug() << index; 0110 if (!index.isValid()) { 0111 return; 0112 } 0113 QModelIndex rootItem = index; 0114 if (rootItem.parent().isValid()) { 0115 rootItem = rootItem.parent(); 0116 } 0117 } 0118 0119 void TargetsUi::updateTargetsButtonStates() 0120 { 0121 QModelIndex currentIndex = targetsView->currentIndex(); 0122 if (!currentIndex.isValid()) { 0123 buildButton->setEnabled(false); 0124 runButton->setEnabled(false); 0125 moveTargetUp->setEnabled(false); 0126 moveTargetDown->setEnabled(false); 0127 return; 0128 } 0129 0130 moveTargetUp->setEnabled(currentIndex.row() > 0); 0131 0132 // If this is a root item 0133 if (!currentIndex.parent().isValid()) { 0134 // move down button 0135 int rows = targetsView->model()->rowCount(); 0136 moveTargetDown->setEnabled(currentIndex.row() < rows - 1); 0137 0138 // try it's first child to see if we can build/run 0139 currentIndex = targetsView->model()->index(0, 0, currentIndex.siblingAtColumn(0)); 0140 if (!currentIndex.isValid()) { 0141 buildButton->setEnabled(false); 0142 runButton->setEnabled(false); 0143 return; 0144 } 0145 } else { 0146 int rows = targetsView->model()->rowCount(currentIndex.parent()); 0147 moveTargetDown->setEnabled(currentIndex.row() < rows - 1); 0148 } 0149 0150 const bool hasBuildCmd = !currentIndex.siblingAtColumn(1).data().toString().isEmpty(); 0151 const bool hasRunCmd = !currentIndex.siblingAtColumn(2).data().toString().isEmpty(); 0152 buildButton->setEnabled(hasBuildCmd); 0153 // Run button can be enabled even if there is no build command 0154 runButton->setEnabled(hasRunCmd); 0155 } 0156 0157 bool TargetsUi::eventFilter(QObject *obj, QEvent *event) 0158 { 0159 if (event->type() == QEvent::KeyPress) { 0160 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); 0161 if (obj == targetsView) { 0162 if (((keyEvent->key() == Qt::Key_Return) || (keyEvent->key() == Qt::Key_Enter)) && m_delegate && !m_delegate->isEditing()) { 0163 Q_EMIT enterPressed(); 0164 return true; 0165 } 0166 } 0167 if (obj == targetFilterEdit) { 0168 switch (keyEvent->key()) { 0169 case Qt::Key_Up: 0170 case Qt::Key_Down: 0171 case Qt::Key_PageUp: 0172 case Qt::Key_PageDown: 0173 case Qt::Key_Return: 0174 case Qt::Key_Enter: 0175 QCoreApplication::sendEvent(targetsView, event); 0176 return true; 0177 case Qt::Key_Left: 0178 case Qt::Key_Right: 0179 case Qt::Key_F2: 0180 // NOTE: I failed to find a generic "platform edit key" shortcut, but it seems 0181 // Key_F2 is hard-coded on non-OSX and Return/Enter on OSX in: 0182 // void QAbstractItemView::keyPressEvent(QKeyEvent *event) 0183 if (targetFilterEdit->text().isEmpty()) { 0184 QCoreApplication::sendEvent(targetsView, event); 0185 return true; 0186 } 0187 break; 0188 } 0189 } 0190 } 0191 return QWidget::eventFilter(obj, event); 0192 } 0193 0194 #include "moc_targets.cpp"