/* * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "toolsgeneralwidget.h" #include "ui_toolsgeneralwidget.h" #include "../mainwindow.h" #include "../settings.h" #include "../iconsmanager.h" #include "utils.h" #include "utils/escape.h" #include "utils/parsearg.h" #include "../systemconsts.h" #include #include #include #include ToolsGeneralWidget::ToolsGeneralWidget(const QString &name, const QString &group, QWidget *parent) : SettingsWidget(name,group,parent), ui(new Ui::ToolsGeneralWidget) { ui->setupUi(this); ui->cbInput->addItems( { tr("None"), tr("Current Selection"), tr("Whole Document"), }); ui->cbOutput->addItems( { tr("None"), tr("Tools Output"), tr("Replace Current Selection"), tr("Repalce Whole Document"), }); ui->cbMacros->setModel(&mMacroInfoModel); QItemSelectionModel *m=ui->lstTools->selectionModel(); ui->lstTools->setModel(&mToolsModel); delete m; mCurrentEditingRow = -1; showEditPanel(false); connect(ui->lstTools, &QAbstractItemView::doubleClicked, this, &ToolsGeneralWidget::editTool); connect(ui->txtProgram,&QLineEdit::textChanged, this, &ToolsGeneralWidget::updateDemo); connect(ui->txtParameters,&QLineEdit::textChanged, this, &ToolsGeneralWidget::updateDemo); connect(ui->txtTitle,&QLineEdit::textChanged, this, &ToolsGeneralWidget::onEdited); connect(ui->txtProgram,&QLineEdit::textChanged, this, &ToolsGeneralWidget::onEdited); connect(ui->txtParameters,&QLineEdit::textChanged, this, &ToolsGeneralWidget::onEdited); connect(ui->txtDirectory,&QLineEdit::textChanged, this, &ToolsGeneralWidget::onEdited); connect(ui->cbInput, qOverload(&QComboBox::currentIndexChanged), this, &ToolsGeneralWidget::onEdited); connect(ui->cbOutput, qOverload(&QComboBox::currentIndexChanged), this, &ToolsGeneralWidget::onEdited); connect(ui->chkUTF8, &QCheckBox::stateChanged, this, &ToolsGeneralWidget::onEdited); } ToolsGeneralWidget::~ToolsGeneralWidget() { delete ui; } void ToolsGeneralWidget::editTool(const QModelIndex &index) { if (mCurrentEditingRow>=0) return; if (!index.isValid()) return; prepareEdit(index.row()); } void ToolsGeneralWidget::finishEditing(bool askSave) { auto action = finally([this]{ cleanEditor(); }); if (mCurrentEditingRow == -1) return; if (!mEdited) return; if (ui->txtTitle->text().isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("Title shouldn't be empty!")); return; } if (askSave && QMessageBox::question(this, tr("Save Changes?"), tr("Do you want to save changes to \"%1\"?").arg(ui->txtTitle->text()), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) != QMessageBox::Yes) { return; } PToolItem item = mToolsModel.getTool(mCurrentEditingRow); item->workingDirectory = ui->txtDirectory->text(); item->parameters = ui->txtParameters->text(); item->program = ui->txtProgram->text(); item->title = ui->txtTitle->text(); item->inputOrigin = static_cast(ui->cbInput->currentIndex()); item->outputTarget = static_cast(ui->cbOutput->currentIndex()); item->isUTF8 = ui->chkUTF8->isChecked(); mToolsModel.updateTool(mCurrentEditingRow, item); } void ToolsGeneralWidget::cleanEditor() { mEdited = false; mCurrentEditingRow = -1; showEditPanel(false); } void ToolsGeneralWidget::prepareEdit(int row) { mCurrentEditingRow = row; PToolItem item = mToolsModel.getTool(row); ui->txtDirectory->setText(item->workingDirectory); ui->txtParameters->setText(item->parameters); ui->txtProgram->setText(item->program); ui->txtTitle->setText(item->title); ui->cbInput->setCurrentIndex(static_cast(item->inputOrigin)); ui->cbOutput->setCurrentIndex(static_cast(item->outputTarget)); ui->chkUTF8->setChecked(item->isUTF8); showEditPanel(true); ui->txtTitle->setFocus(); mEdited = false; } void ToolsGeneralWidget::showEditPanel(bool isShow) { ui->panelEdit->setVisible(isShow); ui->panelEditButtons->setVisible(!isShow); ui->lstTools->setEnabled(!isShow); } void ToolsGeneralWidget::onEdited() { mEdited=true; } void ToolsGeneralWidget::updateDemo() { QMap macros = devCppMacroVariables(); ui->txtDemo->setText(escapeCommandForPlatformShell( parseMacros(ui->txtProgram->text(), macros), parseArguments(ui->txtParameters->text(), macros, true) )); } ToolsModel::ToolsModel(QObject *parent):QAbstractListModel(parent) { } const QList &ToolsModel::tools() const { return mTools; } void ToolsModel::setTools(const QList &newTools) { beginResetModel(); mTools = newTools; endResetModel(); } void ToolsModel::addTool(PToolItem item) { beginInsertRows(QModelIndex(),mTools.count(),mTools.count()); mTools.append(item); endInsertRows(); } PToolItem ToolsModel::getTool(int row) { return mTools[row]; } void ToolsModel::updateTool(int row, PToolItem item) { mTools[row] = item; QModelIndex index=createIndex(row, 0); emit dataChanged(index, index); } void ToolsModel::removeTool(int row) { beginRemoveRows(QModelIndex(),row,row); mTools.removeAt(row); endRemoveRows(); } int ToolsModel::rowCount(const QModelIndex &) const { return mTools.count(); } QVariant ToolsModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (role==Qt::DisplayRole) { PToolItem item = mTools[index.row()]; return item->title; } return QVariant(); } Qt::ItemFlags ToolsModel::flags(const QModelIndex &index) const { Qt::ItemFlags flags = Qt::NoItemFlags; if (index.isValid()) { flags = Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled; } else if (index.row() == -1) { // -1 means it's a drop target? flags = Qt::ItemIsDropEnabled; } return flags ; } Qt::DropActions ToolsModel::supportedDropActions() const { return Qt::MoveAction; } bool ToolsModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { Q_UNUSED(column); mMoveTargetRow=row; if (mMoveTargetRow==-1) mMoveTargetRow=mTools.length(); return QAbstractListModel::dropMimeData(data,action,row,0,parent); } bool ToolsModel::insertRows(int /* row */, int /*count*/, const QModelIndex &/*parent*/) { return true; } bool ToolsModel::removeRows(int row, int count, const QModelIndex &/*parent*/) { int sourceRow = row; int destinationChild = mMoveTargetRow; mMoveTargetRow=-1; if (sourceRow < 0 || sourceRow + count - 1 >= mTools.count() || destinationChild < 0 || destinationChild > mTools.count() || sourceRow == destinationChild || count <= 0) { return false; } if (!beginMoveRows(QModelIndex(), sourceRow, sourceRow + count - 1, QModelIndex(), destinationChild)) return false; int fromRow = sourceRow; if (destinationChild < sourceRow) fromRow += count - 1; else destinationChild--; while (count--) mTools.move(fromRow, destinationChild); endMoveRows(); return true; } void ToolsGeneralWidget::on_btnAdd_clicked() { ui->lstTools->setCurrentIndex(QModelIndex()); PToolItem item = std::make_shared(); item->id=QUuid::createUuid().toString(); item->title = tr("untitled"); item->inputOrigin = ToolItemInputOrigin::None; item->outputTarget = ToolItemOutputTarget::RedirectToToolsOutputPanel; item->isUTF8 = false; mToolsModel.addTool(item); int row = mToolsModel.tools().count() - 1; QModelIndex index=mToolsModel.index(row); ui->lstTools->setCurrentIndex(index); prepareEdit(row); } void ToolsGeneralWidget::on_btnEditOk_clicked() { finishEditing(false); } void ToolsGeneralWidget::on_btnEditCancel_clicked() { cleanEditor(); } void ToolsGeneralWidget::doLoad() { mToolsModel.setTools(pMainWindow->toolsManager()->tools()); } void ToolsGeneralWidget::doSave() { finishEditing(true); pMainWindow->toolsManager()->setTools(mToolsModel.tools()); pMainWindow->toolsManager()->save(); pMainWindow->updateTools(); } void ToolsGeneralWidget::updateIcons(const QSize &) { pIconsManager->setIcon(ui->btnAdd,IconsManager::ACTION_MISC_ADD); pIconsManager->setIcon(ui->btnEdit, IconsManager::ACTION_MISC_RENAME); pIconsManager->setIcon(ui->btnRemove,IconsManager::ACTION_MISC_REMOVE); pIconsManager->setIcon(ui->btnBrowseProgram,IconsManager::ACTION_FILE_LOCATE); pIconsManager->setIcon(ui->btnBrowseWorkingDirectory,IconsManager::ACTION_FILE_OPEN_FOLDER); } void ToolsGeneralWidget::on_btnRemove_clicked() { cleanEditor(); QModelIndex index = ui->lstTools->currentIndex(); if (index.isValid()) { mToolsModel.removeTool(index.row()); } } void ToolsGeneralWidget::on_btnInsertMacro_clicked() { ui->txtParameters->setText( ui->txtParameters->text() + ui->cbMacros->currentData(Qt::UserRole).toString()); } void ToolsGeneralWidget::on_btnBrowseWorkingDirectory_clicked() { QString folder = QFileDialog::getExistingDirectory(this,tr("Choose Folder")); if (!folder.isEmpty()) { ui->txtDirectory->setText(folder); } } void ToolsGeneralWidget::on_btnBrowseProgram_clicked() { QString fileName = QFileDialog::getOpenFileName( this, tr("Select program"), pSettings->dirs().appDir(), pSystemConsts->executableFileFilter()); if (!fileName.isEmpty() ) { QString appPath = includeTrailingPathDelimiter(pSettings->dirs().appDir()); if (fileName.startsWith(appPath)) fileName = QString("") + QDir::separator() + fileName.mid(appPath.length()); ui->txtProgram->setText(fileName); } } void ToolsGeneralWidget::on_btnEdit_clicked() { const QModelIndex& index = ui->lstTools->currentIndex(); if (index.isValid()) editTool(index); }