implement text search and replace functionality

This commit is contained in:
Axel Kohlmeyer
2024-08-24 11:39:54 -04:00
parent 72873b0dca
commit 1b3652583b
10 changed files with 225 additions and 3 deletions

View File

@ -130,6 +130,8 @@ set(PROJECT_SOURCES
chartviewer.h
codeeditor.cpp
codeeditor.h
findandreplace.cpp
findandreplace.h
helpers.cpp
highlighter.cpp
highlighter.h

View File

@ -0,0 +1,148 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "findandreplace.h"
#include "codeeditor.h"
#include "lammpsgui.h"
#include <QApplication>
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QIcon>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QShortcut>
#include <QSizePolicy>
#include <QTextCursor>
/* ---------------------------------------------------------------------- */
FindAndReplace::FindAndReplace(CodeEditor *_editor, QWidget *parent) :
QDialog(parent), editor(_editor), search(nullptr), replace(nullptr), withcase(nullptr),
wrap(nullptr), whole(nullptr)
{
auto *layout = new QGridLayout;
search = new QLineEdit;
replace = new QLineEdit;
withcase = new QCheckBox("Match case");
wrap = new QCheckBox("Wrap around");
whole = new QCheckBox("Whole word");
auto *next = new QPushButton("Next");
auto *replone = new QPushButton("Replace");
auto *replall = new QPushButton("Replace All");
auto *done = new QPushButton("Done");
layout->addWidget(new QLabel("Find:"), 0, 0, Qt::AlignRight);
layout->addWidget(search, 0, 1, 1, 2, Qt::AlignLeft);
layout->addWidget(new QLabel("Replace with:"), 1, 0, Qt::AlignRight);
layout->addWidget(replace, 1, 1, 1, 2, Qt::AlignLeft);
layout->addWidget(withcase, 2, 0, Qt::AlignLeft);
layout->addWidget(wrap, 2, 1, Qt::AlignLeft);
layout->addWidget(whole, 2, 2, Qt::AlignLeft);
wrap->setChecked(true);
auto *buttons = new QHBoxLayout;
buttons->addWidget(next);
buttons->addWidget(replone);
buttons->addWidget(replall);
buttons->addWidget(done);
layout->addLayout(buttons, 3, 0, 1, 3, Qt::AlignHCenter);
connect(next, &QPushButton::released, this, &FindAndReplace::find_next);
connect(replone, &QPushButton::released, this, &FindAndReplace::replace_next);
connect(replall, &QPushButton::released, this, &FindAndReplace::replace_all);
connect(done, &QPushButton::released, this, &QDialog::accept);
auto action = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q), this);
connect(action, &QShortcut::activated, this, &FindAndReplace::quit);
setLayout(layout);
setWindowIcon(QIcon(":/icons/lammps-icon-128x128.png"));
setWindowTitle("LAMMPS-GUI - Find and Replace");
}
/* ---------------------------------------------------------------------- */
void FindAndReplace::find_next()
{
auto text = search->text();
int find_flags = 0;
if (withcase->isChecked()) find_flags |= QTextDocument::FindCaseSensitively;
if (whole->isChecked()) find_flags |= QTextDocument::FindWholeWords;
if (!text.isEmpty()) {
if (!editor->find(text, (QTextDocument::FindFlag)find_flags) && wrap->isChecked()) {
// nothing found from the current position to the end, reposition cursor and beginning
editor->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
editor->find(text, (QTextDocument::FindFlag)find_flags);
}
}
}
/* ---------------------------------------------------------------------- */
void FindAndReplace::replace_next()
{
auto text = search->text();
if (text.isEmpty()) return;
auto cursor = editor->textCursor();
auto flag = withcase->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive;
// if selected text at cursor location matches search text, replace
if (QString::compare(cursor.selectedText(), search->text(), flag) == 0)
cursor.insertText(replace->text());
find_next();
}
/* ---------------------------------------------------------------------- */
void FindAndReplace::replace_all()
{
auto text = search->text();
if (text.isEmpty()) return;
// drop selection if we have one
auto cursor = editor->textCursor();
if (cursor.hasSelection()) cursor.movePosition(QTextCursor::Left);
find_next();
cursor = editor->textCursor();
// keep replacing until find_next() does not find anything anymore
while (cursor.hasSelection()) {
cursor.insertText(replace->text());
find_next();
cursor = editor->textCursor();
}
}
/* ---------------------------------------------------------------------- */
void FindAndReplace::quit()
{
LammpsGui *main = nullptr;
for (QWidget *widget : QApplication::topLevelWidgets())
if (widget->objectName() == "LammpsGui") main = dynamic_cast<LammpsGui *>(widget);
if (main) main->quit();
}
// Local Variables:
// c-basic-offset: 4
// End:

View File

@ -0,0 +1,46 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifndef FIND_AND_REPLACE_H
#define FIND_AND_REPLACE_H
#include "codeeditor.h"
#include <QDialog>
class QLineEdit;
class QCheckBox;
class FindAndReplace : public QDialog {
Q_OBJECT
public:
explicit FindAndReplace(CodeEditor *_editor, QWidget *parent = nullptr);
~FindAndReplace() = default;
private slots:
void find_next();
void replace_next();
void replace_all();
void quit();
private:
CodeEditor *editor;
QLineEdit *search, *replace;
QCheckBox *withcase, *wrap, *whole;
};
#endif
// Local Variables:
// c-basic-offset: 4
// End:

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -34,7 +34,8 @@ class ImageViewer : public QDialog {
Q_OBJECT
public:
explicit ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidget *parent = nullptr);
explicit ImageViewer(const QString &fileName, LammpsWrapper *_lammps,
QWidget *parent = nullptr);
private slots:
void saveAs();

View File

@ -58,7 +58,7 @@
<description>
Added search and replace functionality.
Converged command line argument parsing using Qt facilities
Dark mode compatible
Added dark mode adjustments
</description>
</release>
<release version="1.6.8" timestamp="1723581926">

View File

@ -15,6 +15,7 @@
#include "chartviewer.h"
#include "fileviewer.h"
#include "findandreplace.h"
#include "helpers.h"
#include "highlighter.h"
#include "imageviewer.h"
@ -206,6 +207,7 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) :
connect(ui->actionPaste, &QAction::triggered, this, &LammpsGui::paste);
connect(ui->actionUndo, &QAction::triggered, this, &LammpsGui::undo);
connect(ui->actionRedo, &QAction::triggered, this, &LammpsGui::redo);
connect(ui->actionSearchAndReplace, &QAction::triggered, this, &LammpsGui::findandreplace);
connect(ui->actionRun_Buffer, &QAction::triggered, this, &LammpsGui::run_buffer);
connect(ui->actionRun_File, &QAction::triggered, this, &LammpsGui::run_file);
connect(ui->actionStop_LAMMPS, &QAction::triggered, this, &LammpsGui::stop_run);
@ -1863,6 +1865,14 @@ void LammpsGui::edit_variables()
}
}
void LammpsGui::findandreplace()
{
FindAndReplace find(ui->textEdit, this);
find.setFont(font());
find.setObjectName("find");
find.exec();
}
void LammpsGui::preferences()
{
QSettings settings;

View File

@ -115,6 +115,7 @@ private slots:
void paste();
void undo();
void redo();
void findandreplace();
void run_buffer() { do_run(true); }
void run_file() { do_run(false); }

View File

@ -58,6 +58,7 @@
<file>icons/preferences-desktop.png</file>
<file>icons/process-stop.png</file>
<file>icons/run-file.png</file>
<file>icons/search.png</file>
<file>icons/system-box.png</file>
<file>icons/system-help.png</file>
<file>icons/system-run.png</file>

View File

@ -62,6 +62,8 @@
<addaction name="actionCut"/>
<addaction name="actionPaste"/>
<addaction name="separator"/>
<addaction name="actionSearchAndReplace"/>
<addaction name="separator"/>
<addaction name="actionPreferences"/>
<addaction name="actionDefaults"/>
</widget>
@ -312,12 +314,23 @@
<string>Ctrl+Shift+H</string>
</property>
</action>
<action name="actionSearchAndReplace">
<property name="icon">
<iconset theme=":/icons/search.png"/>
</property>
<property name="text">
<string>&amp;Find and Replace...</string>
</property>
<property name="shortcut">
<string>Ctrl+F</string>
</property>
</action>
<action name="actionPreferences">
<property name="icon">
<iconset theme=":/icons/preferences-desktop.png"/>
</property>
<property name="text">
<string>Pre&amp;ferences...</string>
<string>P&amp;references...</string>
</property>
<property name="shortcut">
<string>Ctrl+P</string>