// SPDX-FileCopyrightText: 2021 Ernie Pasveer // // SPDX-License-Identifier: GPL-3.0-or-later #include "SeerEditorWidgetSource.h" #include "SeerUtl.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include SeerEditorWidgetSource::SeerEditorWidgetSource(QWidget* parent) : QWidget(parent) { // Construct the UI. setupUi(this); // Set the widgets. sourceArea()->show(); searchTextLineEdit->enableReturnPressedOnClear(); showSearchBar(false); // Hide the search bar. ctrl+F to show it again. showAlternateBar(false); // Hide the alternate bar. ctrl+O to show it again. showReloadBar(false); // Hide the reload file bar. Automatically shown if file gets updated. setSearchMatchCase(true); // Search with case sensitivity. _textSearchShortcut = new QShortcut(QKeySequence(tr("Ctrl+F")), this); _textSearchNextShortcut = new QShortcut(QKeySequence(tr("Ctrl+G")), this); _textSearchPrevShortcut = new QShortcut(QKeySequence(tr("Ctrl+Shift+G")), this); _textSearchReloadShortcut = new QShortcut(QKeySequence(tr("Ctrl+R")), this); _lineSearchShortcut = new QShortcut(QKeySequence(tr("Ctrl+L")), this); _alternateDirShortcut = new QShortcut(QKeySequence(tr("Ctrl+O")), this); _toggleBreakpointShortcut = new QShortcut(QKeySequence(tr("Ctrl+B")), this); setKeySettings(SeerKeySettings::populate()); // Connect things. QObject::connect(searchTextLineEdit, &QHistoryLineEdit::returnPressed, this, &SeerEditorWidgetSource::handleSearchTextLineEdit); QObject::connect(searchTextLineEdit, &QHistoryLineEdit::escapePressed, this, &SeerEditorWidgetSource::handleEscapePressed); #if QT_VERSION >= 0x060900 QObject::connect(matchCaseCheckBox, &QCheckBox::checkStateChanged, this, &SeerEditorWidgetSource::handleSearchTextLineEdit); #else QObject::connect(matchCaseCheckBox, &QCheckBox::stateChanged, this, &SeerEditorWidgetSource::handleSearchTextLineEdit); #endif QObject::connect(searchDownToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleSearchDownToolButton); QObject::connect(searchUpToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleSearchUpToolButton); QObject::connect(searchLineNumberLineEdit, &QHistoryLineEdit::returnPressed, this, &SeerEditorWidgetSource::handleSearchLineNumberLineEdit); QObject::connect(searchLineNumberLineEdit, &QHistoryLineEdit::escapePressed, this, &SeerEditorWidgetSource::handleEscapePressed); QObject::connect(searchReloadToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleReloadToolButton); QObject::connect(searchCloseToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleSearchCloseToolButton); QObject::connect(alternateCloseToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleAlternateCloseToolButton); QObject::connect(alternateFileOpenToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleAlternateFileOpenToolButton); QObject::connect(alternateLineEdit, &QHistoryLineEdit::returnPressed, this, &SeerEditorWidgetSource::handleAlternateLineEdit); QObject::connect(reloadToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleReloadToolButton); QObject::connect(reloadCloseToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleReloadCloseToolButton); QObject::connect(sourceWidget, &SeerEditorWidgetSourceArea::showSearchBar, this, qOverload(&SeerEditorWidgetSource::showSearchBar)); QObject::connect(sourceWidget, &SeerEditorWidgetSourceArea::showAlternateBar, this, &SeerEditorWidgetSource::showAlternateBar); QObject::connect(sourceWidget, &SeerEditorWidgetSourceArea::showReloadBar, this, &SeerEditorWidgetSource::showReloadBar); QObject::connect(_textSearchShortcut, &QShortcut::activated, this, &SeerEditorWidgetSource::handleTextSearchShortcut); QObject::connect(_textSearchNextShortcut, &QShortcut::activated, this, &SeerEditorWidgetSource::handleSearchDownToolButton); QObject::connect(_textSearchPrevShortcut, &QShortcut::activated, this, &SeerEditorWidgetSource::handleSearchUpToolButton); QObject::connect(_textSearchReloadShortcut, &QShortcut::activated, this, &SeerEditorWidgetSource::handleReloadToolButton); QObject::connect(_lineSearchShortcut, &QShortcut::activated, this, &SeerEditorWidgetSource::handleLineSearchShortcut); QObject::connect(_alternateDirShortcut, &QShortcut::activated, this, &SeerEditorWidgetSource::handleAlternateDirectoryShortcut); QObject::connect(_toggleBreakpointShortcut, &QShortcut::activated, this, &SeerEditorWidgetSource::handleToggleBreakpointShortcut); } SeerEditorWidgetSource::~SeerEditorWidgetSource () { } SeerEditorWidgetSourceArea* SeerEditorWidgetSource::sourceArea () { return sourceWidget; } bool SeerEditorWidgetSource::isSearchBarShown () const { return searchBarWidget->isVisible(); } bool SeerEditorWidgetSource::searchMatchCase () const { return matchCaseCheckBox->isChecked(); } bool SeerEditorWidgetSource::isAlternateBarShown () const { return alternateBarWidget->isVisible(); } void SeerEditorWidgetSource::setKeySettings (const SeerKeySettings& settings) { _keySettings = settings; if (_keySettings.has("SearchText") == true) { _textSearchShortcut->setKey(_keySettings.get("SearchText")._sequence); } if (_keySettings.has("SearchTextNext") == true) { _textSearchNextShortcut->setKey(_keySettings.get("SearchTextNext")._sequence); } if (_keySettings.has("SearchTextPrev") == true) { _textSearchPrevShortcut->setKey(_keySettings.get("SearchTextPrev")._sequence); } if (_keySettings.has("AlternateDir") == true) { _alternateDirShortcut->setKey(_keySettings.get("AlternateDir")._sequence); } if (_keySettings.has("ToggleBreakpoint") == true) { _toggleBreakpointShortcut->setKey(_keySettings.get("ToggleBreakpoint")._sequence); } } const SeerKeySettings& SeerEditorWidgetSource::keySettings () const { return _keySettings; } void SeerEditorWidgetSource::showSearchBar (bool flag) { showSearchBar(flag, ""); } void SeerEditorWidgetSource::showSearchBar (bool flag, QString field) { searchBarWidget->setVisible(flag); // If 'show', give the searchTextLineEdit or the searchTextLineEdit the focus. if (flag) { if (field == "text") { searchTextLineEdit->setFocus(Qt::MouseFocusReason); }else if (field == "line") { searchLineNumberLineEdit->setFocus(Qt::MouseFocusReason); }else{ searchTextLineEdit->setFocus(Qt::MouseFocusReason); } } } void SeerEditorWidgetSource::setSearchMatchCase (bool flag) { matchCaseCheckBox->setChecked(flag); } void SeerEditorWidgetSource::showAlternateBar (bool flag) { alternateBarWidget->setVisible(flag); if (flag) { originalLineEdit->setText(sourceArea()->fullname()); // Set the original text. rememberAlternateCheckBox->setChecked(true); // Set the default remember setting. alternateLineEdit->setFocus(Qt::MouseFocusReason); // If 'show', give the alternateLineEdit the focus. } } void SeerEditorWidgetSource::showReloadBar (bool flag) { reloadBarWidget->setVisible(flag); reloadBarWidget->setStyleSheet("QWidget { background-color : #00AA00; color : #FFFF00; }"); if (flag) { int elideLength = 50; if (sourceArea()->autoSourceReload()) { reloadFilenameLabel->setText("The file \"" + Seer::elideText(sourceArea()->file(),Qt::ElideLeft,elideLength) + "\" has changed on disk. RELOADING..."); reloadFilenameLabel->setToolTip(sourceArea()->file()); reloadToolButton->setFocus(Qt::MouseFocusReason); // Give the reload button the focus. // Schedule the reload. QTimer::singleShot(1000, this, &SeerEditorWidgetSource::handleReloadToolButton); }else{ reloadFilenameLabel->setText("The file \"" + Seer::elideText(sourceArea()->file(),Qt::ElideLeft,elideLength) + "\" has changed on disk."); reloadFilenameLabel->setToolTip(sourceArea()->file()); reloadToolButton->setFocus(Qt::MouseFocusReason); // Give the reload button the focus. } }else{ reloadFilenameLabel->setText(""); reloadFilenameLabel->setToolTip(""); } } void SeerEditorWidgetSource::handleSearchLineNumberLineEdit () { QString str = searchLineNumberLineEdit->text(); if (str == "") { showSearchBar(false); return; } int lineno = str.toInt(); if (lineno < 1) { return; } searchLineNumberLineEdit->clear(); sourceArea()->scrollToLine(lineno); } void SeerEditorWidgetSource::handleSearchTextLineEdit () { QString str = searchTextLineEdit->text(); matchesLabel->setText(""); if (str == "") { sourceArea()->clearFindText(); showSearchBar(false); return; } int nMatches = sourceArea()->findText(str, (searchMatchCase() ? QTextDocument::FindCaseSensitively : QTextDocument::FindFlags())); matchesLabel->setText(QString("(%1)").arg(nMatches)); } void SeerEditorWidgetSource::handleSearchDownToolButton () { QString str = searchTextLineEdit->text(); if (str == "") { return; } sourceArea()->find(str, (searchMatchCase() ? QTextDocument::FindCaseSensitively : QTextDocument::FindFlags())); } void SeerEditorWidgetSource::handleSearchUpToolButton () { QString str = searchTextLineEdit->text(); if (str == "") { return; } sourceArea()->find(str, (searchMatchCase() ? QTextDocument::FindCaseSensitively : QTextDocument::FindFlags()) | QTextDocument::FindBackward); } void SeerEditorWidgetSource::handleSearchCloseToolButton () { showSearchBar(false); } void SeerEditorWidgetSource::handleAlternateCloseToolButton () { showAlternateBar(false); } void SeerEditorWidgetSource::handleAlternateFileOpenToolButton () { //qDebug() << "fullname =" << sourceArea()->fullname(); //qDebug() << "file =" << sourceArea()->file(); QString filename = QFileDialog::getOpenFileName(this, "Locate File", sourceArea()->fullname(), QString("File (%1)").arg(sourceArea()->file()), nullptr, QFileDialog::DontUseNativeDialog); //qDebug() << "location =" << filename; //qDebug() << "directory=" << QFileInfo(filename).absolutePath(); if (filename != "") { alternateLineEdit->setText(QFileInfo(filename).absolutePath()); } handleAlternateLineEdit(); } void SeerEditorWidgetSource::handleAlternateLineEdit () { showAlternateBar(false); // Get the base path. QString dirname = alternateLineEdit->text(); if (dirname == "") { return; } //qDebug() << "alternate dirname=" << dirname; // Attempt to open the file. sourceArea()->open(sourceArea()->fullname(), sourceArea()->file(), dirname); // Add to global alternate list. if (rememberAlternateCheckBox->isChecked()) { emit addAlternateDirectory(dirname); } } void SeerEditorWidgetSource::handleTextSearchShortcut () { if (isSearchBarShown() == true) { showSearchBar(false, ""); }else{ showSearchBar(true, "text"); } } void SeerEditorWidgetSource::handleLineSearchShortcut () { if (isSearchBarShown() == true) { showSearchBar(false, ""); }else{ showSearchBar(true, "line"); } } void SeerEditorWidgetSource::handleAlternateDirectoryShortcut () { if (isAlternateBarShown() == true) { showAlternateBar(false); }else{ showAlternateBar(true); } } void SeerEditorWidgetSource::handleToggleBreakpointShortcut () { sourceArea()->breakpointToggle(); } void SeerEditorWidgetSource::handleReloadToolButton () { showReloadBar(false); sourceArea()->reload(); } void SeerEditorWidgetSource::handleReloadCloseToolButton () { showReloadBar(false); } void SeerEditorWidgetSource::handleEscapePressed () { showSearchBar(false, ""); }