- enhancement: Enhancement for custom tools.

This commit is contained in:
Roy Qu 2024-04-01 21:07:44 +08:00
parent a0e3339bf7
commit 9b2d3a1bd0
11 changed files with 202 additions and 128 deletions

View File

@ -113,6 +113,7 @@ Red Panda C++ Version 2.27
- fix: C++ source after ';' are treated as comments in cpu info window.
- enhancement: Support "extern template" in code parser.
- enhancement: Set shortcuts for tools menu item.
- enhancement: Enhancement for custom tools.
Red Panda C++ Version 2.26
- enhancement: Code suggestion for embedded std::vectors.

View File

@ -5174,6 +5174,11 @@ void Editor::reformat(bool doReparse)
#endif
if (newContent.isEmpty())
return;
replaceContent(QString::fromUtf8(newContent), doReparse);
}
void Editor::replaceContent(const QString &newContent, bool doReparse)
{
int oldTopPos = topPos();
QSynedit::BufferCoord mOldCaret = caretXY();
@ -5185,7 +5190,7 @@ void Editor::reformat(bool doReparse)
QSynedit::EditorOptions newOptions = oldOptions;
newOptions.setFlag(QSynedit::EditorOption::eoAutoIndent,false);
setOptions(newOptions);
replaceAll(QString::fromUtf8(newContent));
replaceAll(newContent);
setCaretXY(mOldCaret);
setTopPos(oldTopPos);
setOptions(oldOptions);
@ -5198,6 +5203,7 @@ void Editor::reformat(bool doReparse)
reparseTodo();
pMainWindow->updateEditorActions();
}
}
void Editor::checkSyntaxInBack()

View File

@ -188,6 +188,7 @@ public:
QString getPreviousWordAtPositionForSuggestion(const QSynedit::BufferCoord& p, bool &hasTypeQualifier);
QString getPreviousWordAtPositionForCompleteFunctionDefinition(const QSynedit::BufferCoord& p);
void reformat(bool doReparse=true);
void replaceContent(const QString &newContent, bool doReparse=true);
void checkSyntaxInBack();
void gotoDeclaration(const QSynedit::BufferCoord& pos);
void gotoDefinition(const QSynedit::BufferCoord& pos);

View File

@ -1214,6 +1214,65 @@ void MainWindow::onFileSaved(const QString &path, bool inProject)
//updateForEncodingInfo();
}
void MainWindow::executeTool(PToolItem item)
{
QMap<QString, QString> macros = devCppMacroVariables();
QString program = parseMacros(item->program, macros);
QString workDir = parseMacros(item->workingDirectory, macros);
QStringList params = parseArguments(item->parameters, macros, true);
Editor *e;
QByteArray inputContent;
QByteArray output;
switch(item->inputOrigin) {
case ToolItemInputOrigin::None:
break;
case ToolItemInputOrigin::CurrentSelection:
e=mEditorList->getEditor();
if (e)
inputContent=e->selText().toUtf8();
break;
case ToolItemInputOrigin::WholeDocument:
e=mEditorList->getEditor();
if (e)
inputContent=e->text().toUtf8();
break;
}
if (!fileExists(program)) {
QTemporaryFile file(QDir::tempPath()+QDir::separator()+"XXXXXX.bat");
file.setAutoRemove(false);
if (file.open()) {
file.write(escapeCommandForPlatformShell(
"cd", {"/d", localizePath(workDir)}
).toLocal8Bit() + LINE_BREAKER);
file.write(escapeCommandForPlatformShell(program, params).toLocal8Bit()
+ LINE_BREAKER);
file.close();
output = runAndGetOutput(file.fileName(), workDir, params, inputContent);
}
} else {
output = runAndGetOutput(program, workDir, params, inputContent);
}
switch(item->outputTarget) {
case ToolItemOutputTarget::RedirectToToolsOutputPanel:
clearToolsOutput();
logToolsOutput(QString::fromUtf8(output));
break;
case ToolItemOutputTarget::RedirectToNull:
break;
case ToolItemOutputTarget::RepalceWholeDocument:
e=mEditorList->getEditor();
if (e)
e->replaceContent(QString::fromUtf8(output));
break;
case ToolItemOutputTarget::ReplaceCurrentSelection:
e=mEditorList->getEditor();
if (e)
e->setSelText(QString::fromUtf8(output));
break;
}
}
int MainWindow::calIconSize(const QString &fontName, int fontPointSize)
{
QFont font(fontName,fontPointSize);
@ -3428,59 +3487,8 @@ void MainWindow::updateTools()
foreach (const PToolItem& item, mToolsManager->tools()) {
QAction* action = createShortcutCustomableAction(item->title,"tool-"+item->id);
connect(action, &QAction::triggered,
[item] (){
QMap<QString, QString> macros = devCppMacroVariables();
QString program = parseMacros(item->program, macros);
QString workDir = parseMacros(item->workingDirectory, macros);
QStringList params = parseArguments(item->parameters, macros, true);
if (!program.endsWith(".bat",Qt::CaseInsensitive)) {
QTemporaryFile file(QDir::tempPath()+QDir::separator()+"XXXXXX.bat");
file.setAutoRemove(false);
if (file.open()) {
file.write(escapeCommandForPlatformShell(
"cd", {"/d", localizePath(workDir)}
).toLocal8Bit() + LINE_BREAKER);
file.write(escapeCommandForPlatformShell(program, params).toLocal8Bit()
+ LINE_BREAKER);
file.close();
if (item->pauseAfterExit) {
QString sharedMemoryId = QUuid::createUuid().toString();
QStringList execArgs = QStringList{
QString::number(RPF_PAUSE_CONSOLE),
sharedMemoryId,
localizePath(file.fileName())
};
executeFile(
includeTrailingPathDelimiter(pSettings->dirs().appLibexecDir())+CONSOLE_PAUSER,
execArgs,
workDir, file.fileName());
} else {
executeFile(
file.fileName(),
{},
workDir, file.fileName());
}
}
} else {
if (item->pauseAfterExit) {
QString sharedMemoryId = QUuid::createUuid().toString();
QStringList execArgs = QStringList{
QString::number(RPF_PAUSE_CONSOLE),
sharedMemoryId,
localizePath(program)
};
executeFile(
includeTrailingPathDelimiter(pSettings->dirs().appLibexecDir())+CONSOLE_PAUSER,
execArgs + params,
workDir, "");
} else {
executeFile(
program,
params,
workDir, "");
}
}
[item,this] (){
executeTool(item);
});
ui->menuTools->addAction(action);
actions.append(action);

View File

@ -279,6 +279,7 @@ public slots:
void onFileSaved(const QString& path, bool inProject);
private:
void executeTool(PToolItem item);
int calIconSize(const QString &fontName, int fontPointSize);
void hideAllSearchDialogs();
void prepareSearchDialog();

View File

@ -33,6 +33,20 @@ ToolsGeneralWidget::ToolsGeneralWidget(const QString &name, const QString &group
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);
@ -54,7 +68,9 @@ ToolsGeneralWidget::ToolsGeneralWidget(const QString &name, const QString &group
this, &ToolsGeneralWidget::onEdited);
connect(ui->txtDirectory,&QLineEdit::textChanged,
this, &ToolsGeneralWidget::onEdited);
connect(ui->chkPauseConsole,&QCheckBox::stateChanged,
connect(ui->cbInput, qOverload<int>(&QComboBox::currentIndexChanged),
this, &ToolsGeneralWidget::onEdited);
connect(ui->cbOutput, qOverload<int>(&QComboBox::currentIndexChanged),
this, &ToolsGeneralWidget::onEdited);
}
@ -107,7 +123,8 @@ void ToolsGeneralWidget::finishEditing(bool askSave, const QModelIndex& itemInde
item->parameters = ui->txtParameters->text();
item->program = ui->txtProgram->text();
item->title = ui->txtTitle->text();
item->pauseAfterExit = ui->chkPauseConsole->isChecked();
item->inputOrigin = static_cast<ToolItemInputOrigin>(ui->cbInput->currentIndex());
item->outputTarget = static_cast<ToolItemOutputTarget>(ui->cbOutput->currentIndex());
mEdited=false;
}
@ -118,7 +135,8 @@ void ToolsGeneralWidget::prepareEdit(const PToolItem& item)
ui->txtParameters->setText(item->parameters);
ui->txtProgram->setText(item->program);
ui->txtTitle->setText(item->title);
ui->chkPauseConsole->setChecked(item->pauseAfterExit);
ui->cbInput->setCurrentIndex(static_cast<int>(item->inputOrigin));
ui->cbOutput->setCurrentIndex(static_cast<int>(item->outputTarget));
showEditPanel(true);
ui->txtTitle->setFocus();
mEdited = false;
@ -200,7 +218,8 @@ void ToolsGeneralWidget::on_btnAdd_clicked()
PToolItem item = std::make_shared<ToolItem>();
item->id=QUuid::createUuid().toString();
item->title = tr("untitled");
item->pauseAfterExit = false;
item->inputOrigin = ToolItemInputOrigin::None;
item->outputTarget = ToolItemOutputTarget::RedirectToToolsOutputPanel;
mToolsModel.addTool(item);
QModelIndex index=mToolsModel.index(mToolsModel.tools().count()-1);
ui->lstTools->setCurrentIndex(index);
@ -237,7 +256,7 @@ void ToolsGeneralWidget::updateIcons(const QSize &)
{
pIconsManager->setIcon(ui->btnAdd,IconsManager::ACTION_MISC_ADD);
pIconsManager->setIcon(ui->btnRemove,IconsManager::ACTION_MISC_REMOVE);
pIconsManager->setIcon(ui->btnBrowseProgram,IconsManager::ACTION_FILE_OPEN_FOLDER);
pIconsManager->setIcon(ui->btnBrowseProgram,IconsManager::ACTION_FILE_LOCATE);
pIconsManager->setIcon(ui->btnBrowseWorkingDirectory,IconsManager::ACTION_FILE_OPEN_FOLDER);
}

View File

@ -123,37 +123,7 @@
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1">
<widget class="QLineEdit" name="txtDirectory"/>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="txtParameters"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Working Directory</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="3">
<widget class="QLineEdit" name="txtDemo">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="clearButtonEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<widget class="QCheckBox" name="chkPauseConsole">
<property name="text">
<string>Pause console after the program exit</string>
</property>
</widget>
</item>
<item row="7" column="0" colspan="3">
<item row="9" column="0" colspan="3">
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
@ -194,16 +164,6 @@
</layout>
</widget>
</item>
<item row="1" column="2">
<widget class="QToolButton" name="btnBrowseProgram">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="txtTitle"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
@ -211,7 +171,27 @@
</property>
</widget>
</item>
<item row="9" column="0" colspan="3">
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Program</string>
</property>
</widget>
</item>
<item row="10" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="11" column="0" colspan="3">
<widget class="QWidget" name="widget_3" native="true">
<property name="minimumSize">
<size>
@ -262,17 +242,36 @@
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="txtTitle"/>
</item>
<item row="5" column="1" colspan="2">
<widget class="QComboBox" name="cbInput"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Title</string>
<string>Working Directory</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<item row="6" column="1" colspan="2">
<widget class="QComboBox" name="cbOutput"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Program</string>
<string>Output To</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="txtDirectory"/>
</item>
<item row="1" column="2">
<widget class="QToolButton" name="btnBrowseProgram">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
@ -286,18 +285,39 @@
<item row="1" column="1">
<widget class="QLineEdit" name="txtProgram"/>
</item>
<item row="8" column="0">
<spacer name="verticalSpacer">
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Redirect Input</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="txtParameters"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Title</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<widget class="QLineEdit" name="txtDemo">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="clearButtonEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="7" column="0" colspan="3">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</widget>
</item>
</layout>
</widget>
@ -320,8 +340,6 @@
<tabstop>txtDirectory</tabstop>
<tabstop>btnBrowseWorkingDirectory</tabstop>
<tabstop>txtParameters</tabstop>
<tabstop>chkPauseConsole</tabstop>
<tabstop>txtDemo</tabstop>
<tabstop>btnInsertMacro</tabstop>
<tabstop>cbMacros</tabstop>
<tabstop>btnEditOk</tabstop>

View File

@ -45,7 +45,8 @@ void ToolsManager::load()
#endif
item->workingDirectory = "<SOURCEPATH>";
item->parameters = "<EXENAME>";
item->pauseAfterExit = false;
item->inputOrigin = ToolItemInputOrigin::None;
item->outputTarget = ToolItemOutputTarget::RedirectToToolsOutputPanel;
mTools.append(item);
//#ifdef Q_OS_WIN
// item = std::make_shared<ToolItem>();
@ -96,7 +97,8 @@ void ToolsManager::load()
item->program = object["program"].toString();
item->workingDirectory = object["workingDirectory"].toString();
item->parameters = object["parameters"].toString();
item->pauseAfterExit = object["pauseAfterExit"].toBool();
item->outputTarget = static_cast<ToolItemOutputTarget>(object["outputTarget"].toInt(0));
item->inputOrigin= static_cast<ToolItemInputOrigin>(object["inputOrigin"].toInt(0));
mTools.append(item);
}
}
@ -120,7 +122,8 @@ void ToolsManager::save()
object["program"]=tool->program;
object["workingDirectory"] = tool->workingDirectory;
object["parameters"]=tool->parameters;
object["pauseAfterExit"]=tool->pauseAfterExit;
object["outputTarget"]=static_cast<int>(tool->outputTarget);
object["inputOrigin"]=static_cast<int>(tool->inputOrigin);
array.append(object);
}
QJsonDocument doc;

View File

@ -20,13 +20,27 @@
#include <QObject>
#include <memory>
enum class ToolItemInputOrigin {
None,
CurrentSelection,
WholeDocument
};
enum class ToolItemOutputTarget {
RedirectToNull,
RedirectToToolsOutputPanel,
ReplaceCurrentSelection,
RepalceWholeDocument,
};
struct ToolItem {
QString id;
QString title;
QString program;
QString workingDirectory;
QString parameters;
bool pauseAfterExit;
ToolItemInputOrigin inputOrigin;
ToolItemOutputTarget outputTarget;
};
using PToolItem = std::shared_ptr<ToolItem>;

View File

@ -397,6 +397,13 @@ void QSynEdit::addSelectionToUndo()
mBlockEnd,QStringList(),mActiveSelectionMode);
}
void QSynEdit::replaceAll(const QString &text)
{
mUndoList->addChange(ChangeReason::Selection,mBlockBegin,mBlockEnd,QStringList(), activeSelectionMode());
selectAll();
setSelText(text);
}
void QSynEdit::doTrimTrailingSpaces()
{
if (mDocument->count()<=0)

View File

@ -274,11 +274,6 @@ public:
void addCaretToUndo();
void addLeftTopToUndo();
void addSelectionToUndo();
void replaceAll(const QString& text) {
mUndoList->addChange(ChangeReason::Selection,mBlockBegin,mBlockEnd,QStringList(), activeSelectionMode());
selectAll();
setSelText(text);
}
void trimTrailingSpaces() {
processCommand(EditCommand::TrimTrailingSpaces);
}
@ -496,6 +491,7 @@ protected:
virtual void onCommandProcessed(EditCommand command, QChar car, void * pData);
virtual void executeCommand(EditCommand command, QChar ch, void * pData);
protected:
void replaceAll(const QString& text);
int clientWidth() const;
int clientHeight() const;
int clientTop() const;