mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
955 lines
28 KiB
C++
955 lines
28 KiB
C++
/**
|
|
* FindDialog.cpp
|
|
* Copyright (c) 2013 ROBLOX Corp. All Rights Reserved.
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "FindDialog.h"
|
|
|
|
// Qt Headers
|
|
#include <QLineEdit>
|
|
#include <QRadioButton>
|
|
#include <QCheckBox>
|
|
#include <QTextDocument>
|
|
#include <QPlainTextEdit>
|
|
#include <QPushButton>
|
|
#include <QKeyEvent>
|
|
#include <QGridLayout>
|
|
#include <QHBoxLayout>
|
|
#include <QLabel>
|
|
#include <QGroupBox>
|
|
#include <QTextBlock>
|
|
|
|
// Roblox Studio Headers
|
|
#include "RobloxMainWindow.h"
|
|
#include "UpdateUIManager.h"
|
|
#include "ScriptTextEditor.h"
|
|
#include "RobloxFindWidget.h"
|
|
#include "RobloxDocManager.h"
|
|
#include "RobloxScriptDoc.h"
|
|
|
|
FASTFLAG(StudioEmbeddedFindDialogEnabled)
|
|
|
|
BasicFindDialog::BasicFindDialog(QWidget *parent)
|
|
: QDialog(parent,Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
|
|
, m_pFindListener(0)
|
|
, m_pFindEdit(0)
|
|
, m_pFindNextButton(0)
|
|
, m_pFindPreviousButton(0)
|
|
, m_pCloseButton(0)
|
|
, m_pDownRadioButton(0)
|
|
, m_pCaseCheckBox(0)
|
|
, m_pWholeCheckBox(0)
|
|
, m_pRegExCheckBox(0)
|
|
{
|
|
setWindowFlags(Qt::WindowStaysOnTopHint | windowFlags());
|
|
}
|
|
|
|
BasicFindDialog::~BasicFindDialog()
|
|
{
|
|
m_pFindListener = NULL;
|
|
}
|
|
|
|
void BasicFindDialog::setFindListener(IFindListener* listener)
|
|
{
|
|
m_pFindListener = listener;
|
|
}
|
|
|
|
void BasicFindDialog::setFocus()
|
|
{
|
|
QDialog::setFocus();
|
|
if(isActiveWindow())
|
|
{
|
|
m_pFindEdit->setFocus();
|
|
if(m_pFindEdit->text().size() > 0)
|
|
{
|
|
m_pFindEdit->setCursorPosition(m_pFindEdit->text().size());
|
|
m_pFindEdit->selectAll();
|
|
}
|
|
}
|
|
}
|
|
|
|
void BasicFindDialog::setVisible(bool visible)
|
|
{
|
|
QDialog::setVisible(visible);
|
|
if ( visible )
|
|
{
|
|
if ( m_pFindListener )
|
|
{
|
|
if ( m_pFindListener->hasSelection() )
|
|
m_pFindEdit->setText(m_pFindListener->getSelectedText());
|
|
else
|
|
m_pFindEdit->setText(FindReplaceProvider::instance().getSearchStr());
|
|
}
|
|
|
|
m_pFindEdit->setFocus();
|
|
}
|
|
}
|
|
|
|
bool BasicFindDialog::isFindNextEnabled()
|
|
{
|
|
return (m_pFindEdit->text().size() > 0);
|
|
}
|
|
|
|
void BasicFindDialog::textToFindChanged()
|
|
{
|
|
bool bEnable = m_pFindEdit->text().size() > 0;
|
|
m_pFindNextButton->setEnabled(bEnable);
|
|
m_pFindPreviousButton->setEnabled(bEnable);
|
|
UpdateUIManager::Instance().getMainWindow().findNextAction->setEnabled(bEnable);
|
|
UpdateUIManager::Instance().getMainWindow().findPreviousAction->setEnabled(bEnable);
|
|
}
|
|
|
|
bool BasicFindDialog::getSearchParameters(bool forward,QRegExp& outRegExp,QTextDocument::FindFlags& outflags)
|
|
{
|
|
QString toSearch = m_pFindEdit->text();
|
|
FindReplaceProvider::instance().setSearchStr(toSearch);
|
|
if ( toSearch.isEmpty() )
|
|
return false;
|
|
|
|
outflags = 0;
|
|
|
|
bool down = m_pDownRadioButton->isChecked();
|
|
if( (!down && forward) || (down && !forward) )
|
|
outflags |= QTextDocument::FindBackward;
|
|
|
|
if(m_pCaseCheckBox->isChecked())
|
|
outflags |= QTextDocument::FindCaseSensitively;
|
|
if(m_pWholeCheckBox->isChecked())
|
|
outflags |= QTextDocument::FindWholeWords;
|
|
|
|
outRegExp.setPattern(toSearch);
|
|
|
|
if ( !m_pRegExCheckBox->isChecked() )
|
|
outRegExp.setPatternSyntax(QRegExp::FixedString);
|
|
outRegExp.setCaseSensitivity(m_pCaseCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
|
|
|
if ( !outRegExp.isValid() )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool BasicFindDialog::find(bool forward,bool loop)
|
|
{
|
|
QRegExp regExp;
|
|
QTextDocument::FindFlags flags;
|
|
|
|
if ( !getSearchParameters(forward,regExp,flags) )
|
|
return false;
|
|
|
|
if ( m_pFindListener )
|
|
return m_pFindListener->find(loop,regExp,flags);
|
|
else
|
|
return false;
|
|
}
|
|
|
|
void BasicFindDialog::keyPressEvent(QKeyEvent* evt)
|
|
{
|
|
QAction* previous = UpdateUIManager::Instance().getMainWindow().findPreviousAction;
|
|
if ( evt->matches(QKeySequence::FindPrevious) )
|
|
{
|
|
previous->trigger();
|
|
evt->accept();
|
|
return;
|
|
}
|
|
|
|
QAction* next = UpdateUIManager::Instance().getMainWindow().findNextAction;
|
|
if ( evt->matches(QKeySequence::FindNext) )
|
|
{
|
|
next->trigger();
|
|
evt->accept();
|
|
return;
|
|
}
|
|
|
|
QDialog::keyPressEvent(evt);
|
|
}
|
|
|
|
FindAllDialog::FindAllDialog(QWidget *parent)
|
|
: BasicFindDialog(parent),
|
|
m_pLookInComboBox(NULL)
|
|
{
|
|
initDialog();
|
|
}
|
|
|
|
void FindAllDialog::initDialog()
|
|
{
|
|
QLabel *findLabel = new QLabel("Find what: ");
|
|
m_pFindEdit = new QLineEdit;
|
|
QLabel *lookInLabel = new QLabel("Look in: ");
|
|
|
|
m_pFindAllButton = new QPushButton("Find All");
|
|
m_pFindAllButton->setEnabled(false);
|
|
m_pCloseButton = new QPushButton("Close");
|
|
|
|
//Find Options
|
|
m_pFindOptions = new QGroupBox("Find Options");
|
|
m_pFindOptions->setCheckable(true);
|
|
m_pFindOptions->setFlat(true);
|
|
|
|
m_pCaseCheckBox = new QCheckBox("Match case");
|
|
m_pWholeCheckBox = new QCheckBox("Match whole word only");
|
|
m_pRegExCheckBox = new QCheckBox("Regular expression");
|
|
|
|
QVBoxLayout *findOptionsLayout = new QVBoxLayout();
|
|
findOptionsLayout->addWidget(m_pCaseCheckBox);
|
|
findOptionsLayout->addWidget(m_pWholeCheckBox);
|
|
findOptionsLayout->addWidget(m_pRegExCheckBox);
|
|
|
|
m_pFindOptions->setLayout(findOptionsLayout);
|
|
|
|
m_pFindLayout = new QGridLayout();
|
|
m_pFindLayout->addWidget(findLabel, 0, 0);
|
|
m_pFindLayout->addWidget(m_pFindEdit, 1, 0);
|
|
m_pFindLayout->addWidget(lookInLabel, 4, 0);
|
|
|
|
QVBoxLayout *firstColLayout = new QVBoxLayout();
|
|
firstColLayout->addLayout(m_pFindLayout);
|
|
firstColLayout->addWidget(m_pFindOptions);
|
|
|
|
QVBoxLayout *buttonsLayout = new QVBoxLayout();
|
|
buttonsLayout->addWidget(m_pFindAllButton);
|
|
buttonsLayout->addWidget(m_pCloseButton);
|
|
|
|
QGridLayout *mainLayout = new QGridLayout();
|
|
mainLayout->addLayout(firstColLayout, 0, 0);
|
|
mainLayout->addLayout(buttonsLayout, 0, 1, Qt::AlignTop);
|
|
setLayout(mainLayout);
|
|
|
|
setWindowTitle("Find in all scripts");
|
|
|
|
setMaximumHeight(minimumHeight());
|
|
setMaximumWidth(minimumWidth());
|
|
|
|
connect(m_pFindAllButton, SIGNAL(clicked()), this, SLOT(findAll()));
|
|
connect(m_pFindEdit, SIGNAL(textChanged(QString)), this, SLOT(textToFindChanged()));
|
|
connect(m_pCloseButton, SIGNAL(clicked()), this, SLOT(close()));
|
|
connect(m_pFindOptions, SIGNAL(toggled(bool)), this , SLOT(onFindOptionsToggled(bool)));
|
|
}
|
|
|
|
void FindAllDialog::showEvent(QShowEvent * event)
|
|
{
|
|
// This cludgy code is added to fix a QT bug on Mac. Combobox should be
|
|
// initialized when its parent already created. Otherwise it displays a weird
|
|
// frame around drowpdown list.
|
|
m_pLookInComboBox = new QComboBox(this);
|
|
m_pLookInComboBox->addItem("All Scripts");
|
|
m_pLookInComboBox->addItem("Current Script");
|
|
m_pFindLayout->addWidget(m_pLookInComboBox, 5, 0);
|
|
|
|
BasicFindDialog::showEvent(event);
|
|
}
|
|
|
|
RobloxFindWidget::eFindFlags FindAllDialog::getCurrentFlags()
|
|
{
|
|
RobloxFindWidget::eFindFlags flagSetter = RobloxFindWidget::NO_FLAGS;
|
|
|
|
if (!m_pFindOptions->isChecked())
|
|
return flagSetter;
|
|
|
|
if (m_pCaseCheckBox->isChecked())
|
|
flagSetter = flagSetter | RobloxFindWidget::MATCH_CASE;
|
|
|
|
if (m_pWholeCheckBox->isChecked())
|
|
flagSetter = flagSetter | RobloxFindWidget::MATCH_WORD;
|
|
|
|
if (m_pRegExCheckBox->isChecked())
|
|
flagSetter = flagSetter | RobloxFindWidget::REG_EXP;
|
|
|
|
return flagSetter;
|
|
}
|
|
|
|
void FindAllDialog::findAll()
|
|
{
|
|
FindReplaceProvider::instance().setSearchStr(m_pFindEdit->text());
|
|
RobloxFindWidget::singleton().findAll(m_pFindEdit->text(), (m_pLookInComboBox->currentIndex() == 0), getCurrentFlags());
|
|
close();
|
|
}
|
|
|
|
void FindAllDialog::textToFindChanged()
|
|
{
|
|
m_pFindAllButton->setEnabled(m_pFindEdit->text().size() > 0);
|
|
}
|
|
|
|
void FindAllDialog::onFindOptionsToggled(bool on)
|
|
{
|
|
m_pFindOptions->setMinimumWidth(m_pFindOptions->width());
|
|
|
|
m_pCaseCheckBox->setVisible(on);
|
|
m_pWholeCheckBox->setVisible(on);
|
|
m_pRegExCheckBox->setVisible(on);
|
|
|
|
//Need to adjust size but children have not resized yet
|
|
QMetaObject::invokeMethod(this, "adjustSize", Qt::QueuedConnection);
|
|
}
|
|
|
|
void FindAllDialog::setFindAllRunning(bool value)
|
|
{
|
|
if (value)
|
|
{
|
|
m_pFindAllButton->setText("Stop");
|
|
disconnect(m_pFindAllButton, SIGNAL(clicked()), this, SLOT(findAll()));
|
|
connect(m_pFindAllButton, SIGNAL(clicked()), &RobloxFindWidget::singleton(), SLOT(stopPopulatingItems()));
|
|
}
|
|
else
|
|
{
|
|
m_pFindAllButton->setText("Find All");
|
|
disconnect(m_pFindAllButton, SIGNAL(clicked()), &RobloxFindWidget::singleton(), SLOT(stopPopulatingItems()));
|
|
connect(m_pFindAllButton, SIGNAL(clicked()), this, SLOT(findAll()));
|
|
}
|
|
}
|
|
|
|
|
|
FindDialog::FindDialog(QWidget *parent)
|
|
: BasicFindDialog(parent)
|
|
{
|
|
initDialog();
|
|
}
|
|
|
|
void FindDialog::initDialog()
|
|
{
|
|
QLabel *findLabel = new QLabel("Find what: ");
|
|
m_pFindEdit = new QLineEdit;
|
|
|
|
m_pFindNextButton = new QPushButton("Find Next");
|
|
m_pFindNextButton->setEnabled(false);
|
|
m_pFindPreviousButton = new QPushButton("Find Previous");
|
|
m_pFindPreviousButton->setEnabled(false);
|
|
m_pCloseButton = new QPushButton("Close");
|
|
|
|
m_pCaseCheckBox = new QCheckBox("Match case");
|
|
m_pWholeCheckBox = new QCheckBox("Match whole word only");
|
|
m_pRegExCheckBox = new QCheckBox("Regular expression");
|
|
|
|
QGroupBox *directionBox = new QGroupBox("Direction");
|
|
QRadioButton *upRadioButton = new QRadioButton("Up");
|
|
m_pDownRadioButton = new QRadioButton("Down");
|
|
QHBoxLayout *directionLayout = new QHBoxLayout();
|
|
directionLayout->addWidget(upRadioButton);
|
|
directionLayout->addWidget(m_pDownRadioButton);
|
|
directionBox->setLayout(directionLayout);
|
|
|
|
m_pDownRadioButton->setChecked(true);
|
|
|
|
QGridLayout *findLayout = new QGridLayout();
|
|
findLayout->addWidget(findLabel, 0, 0);
|
|
findLayout->addWidget(m_pFindEdit, 0, 1);
|
|
|
|
QVBoxLayout *conditionsLayout = new QVBoxLayout();
|
|
conditionsLayout->addWidget(m_pWholeCheckBox);
|
|
conditionsLayout->addWidget(m_pCaseCheckBox);
|
|
conditionsLayout->addWidget(m_pRegExCheckBox);
|
|
|
|
QHBoxLayout *secondRowLayout = new QHBoxLayout();
|
|
secondRowLayout->addLayout(conditionsLayout);
|
|
secondRowLayout->addWidget(directionBox);
|
|
|
|
QVBoxLayout *firstColLayout = new QVBoxLayout();
|
|
firstColLayout->addLayout(findLayout);
|
|
firstColLayout->addLayout(secondRowLayout);
|
|
|
|
QVBoxLayout *buttonsLayout = new QVBoxLayout();
|
|
buttonsLayout->addWidget(m_pFindNextButton);
|
|
buttonsLayout->addWidget(m_pFindPreviousButton);
|
|
buttonsLayout->addWidget(m_pCloseButton);
|
|
|
|
QGridLayout *mainLayout = new QGridLayout();
|
|
mainLayout->addLayout(firstColLayout, 0, 0);
|
|
mainLayout->addLayout(buttonsLayout, 0, 1, Qt::AlignTop);
|
|
setLayout(mainLayout);
|
|
|
|
setWindowTitle("Find");
|
|
|
|
connect(m_pFindEdit, SIGNAL(textChanged(QString)), this, SLOT(textToFindChanged()));
|
|
connect(m_pFindNextButton, SIGNAL(clicked()), this, SLOT(findNext()));
|
|
connect(m_pFindPreviousButton, SIGNAL(clicked()), this, SLOT(findPrevious()));
|
|
connect(m_pCloseButton, SIGNAL(clicked()), this, SLOT(close()));
|
|
}
|
|
|
|
ReplaceDialog::ReplaceDialog(QWidget *parent)
|
|
: BasicFindDialog(parent)
|
|
{
|
|
initDialog();
|
|
}
|
|
|
|
void ReplaceDialog::initDialog()
|
|
{
|
|
QLabel *findLabel = new QLabel("Find what: ");
|
|
m_pFindEdit = new QLineEdit;
|
|
|
|
QLabel *replaceLabel = new QLabel("Replace with: ");
|
|
m_pReplaceEdit = new QLineEdit;
|
|
|
|
m_pFindNextButton = new QPushButton("Find Next");
|
|
m_pFindNextButton->setEnabled(false);
|
|
m_pFindPreviousButton = new QPushButton("Find Previous");
|
|
m_pFindPreviousButton->setEnabled(false);
|
|
m_pReplaceButton = new QPushButton("Replace");
|
|
m_pReplaceButton->setEnabled(false);
|
|
m_pReplaceAllButton = new QPushButton("Replace All");
|
|
m_pReplaceAllButton->setEnabled(false);
|
|
m_pCloseButton = new QPushButton("Close");
|
|
|
|
m_pCaseCheckBox = new QCheckBox("Match case");
|
|
m_pWholeCheckBox = new QCheckBox("Match whole word only");
|
|
m_pRegExCheckBox = new QCheckBox("Regular expression");
|
|
|
|
QGroupBox *directionBox = new QGroupBox("Direction");
|
|
QRadioButton *upRadioButton = new QRadioButton("Up");
|
|
m_pDownRadioButton = new QRadioButton("Down");
|
|
QHBoxLayout *directionLayout = new QHBoxLayout();
|
|
directionLayout->addWidget(upRadioButton);
|
|
directionLayout->addWidget(m_pDownRadioButton);
|
|
directionBox->setLayout(directionLayout);
|
|
|
|
m_pDownRadioButton->setChecked(true);
|
|
|
|
QGridLayout *findLayout = new QGridLayout();
|
|
findLayout->addWidget(findLabel, 0, 0);
|
|
findLayout->addWidget(m_pFindEdit, 0, 1);
|
|
findLayout->addWidget(replaceLabel, 1, 0);
|
|
findLayout->addWidget(m_pReplaceEdit, 1, 1);
|
|
|
|
QVBoxLayout *conditionsLayout = new QVBoxLayout();
|
|
conditionsLayout->addWidget(m_pWholeCheckBox);
|
|
conditionsLayout->addWidget(m_pCaseCheckBox);
|
|
conditionsLayout->addWidget(m_pRegExCheckBox);
|
|
|
|
QHBoxLayout *secondRowLayout = new QHBoxLayout();
|
|
secondRowLayout->addLayout(conditionsLayout);
|
|
secondRowLayout->addWidget(directionBox);
|
|
|
|
QVBoxLayout *firstColLayout = new QVBoxLayout();
|
|
firstColLayout->addLayout(findLayout);
|
|
firstColLayout->addLayout(secondRowLayout);
|
|
|
|
QVBoxLayout *buttonsLayout = new QVBoxLayout();
|
|
buttonsLayout->addWidget(m_pFindNextButton);
|
|
buttonsLayout->addWidget(m_pFindPreviousButton);
|
|
buttonsLayout->addWidget(m_pReplaceButton);
|
|
buttonsLayout->addWidget(m_pReplaceAllButton);
|
|
buttonsLayout->addWidget(m_pCloseButton);
|
|
|
|
QGridLayout *mainLayout = new QGridLayout();
|
|
mainLayout->addLayout(firstColLayout, 0, 0);
|
|
mainLayout->addLayout(buttonsLayout, 0, 1, Qt::AlignTop);
|
|
setLayout(mainLayout);
|
|
|
|
setWindowTitle("Replace");
|
|
|
|
connect(m_pFindEdit, SIGNAL(textChanged(QString)), this, SLOT(textToFindChanged()));
|
|
connect(m_pFindNextButton, SIGNAL(clicked()), this, SLOT(findNext()));
|
|
connect(m_pFindPreviousButton, SIGNAL(clicked()), this, SLOT(findPrevious()));
|
|
connect(m_pCloseButton, SIGNAL(clicked()), this, SLOT(close()));
|
|
connect(m_pReplaceButton, SIGNAL(clicked()), this, SLOT(replace()));
|
|
connect(m_pReplaceAllButton, SIGNAL(clicked()), this, SLOT(replaceAll()));
|
|
}
|
|
|
|
void ReplaceDialog::replace()
|
|
{
|
|
if ( !m_pFindListener )
|
|
return;
|
|
|
|
QRegExp regExp;
|
|
QTextDocument::FindFlags flags;
|
|
|
|
if ( !getSearchParameters(true,regExp,flags) )
|
|
return;
|
|
|
|
if ( m_pFindListener->hasSelection() && isSelectionValid() )
|
|
m_pFindListener->replace(m_pReplaceEdit->text(),regExp,flags);
|
|
|
|
find(true,true);
|
|
}
|
|
|
|
void ReplaceDialog::replaceAll()
|
|
{
|
|
if ( !m_pFindListener )
|
|
return;
|
|
|
|
QRegExp regExp;
|
|
QTextDocument::FindFlags flags;
|
|
|
|
if ( !getSearchParameters(true,regExp,flags) )
|
|
return;
|
|
|
|
m_pFindListener->goToStart(flags);
|
|
|
|
while ( find(true,false) )
|
|
m_pFindListener->replace(m_pReplaceEdit->text(),regExp,flags);
|
|
}
|
|
|
|
void ReplaceDialog::textToFindChanged()
|
|
{
|
|
bool bEnable = m_pFindEdit->text().size() > 0;
|
|
m_pFindNextButton->setEnabled(bEnable);
|
|
m_pFindPreviousButton->setEnabled(bEnable);
|
|
m_pReplaceButton->setEnabled(bEnable);
|
|
m_pReplaceAllButton->setEnabled(bEnable);
|
|
}
|
|
|
|
bool ReplaceDialog::isSelectionValid()
|
|
{
|
|
QString selectedText = m_pFindListener->getSelectedText();
|
|
if ( !selectedText.isEmpty() )
|
|
{
|
|
QString toSearch = m_pFindEdit->text();
|
|
if ( !toSearch.isEmpty() )
|
|
{
|
|
QRegExp reg(toSearch);
|
|
if ( !m_pRegExCheckBox->isChecked() )
|
|
reg.setPatternSyntax(QRegExp::FixedString);
|
|
|
|
reg.setCaseSensitivity(m_pCaseCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
|
|
|
//selection and replacement string should be matching
|
|
if ( selectedText.indexOf(reg) == 0 )
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
FindReplaceProvider& FindReplaceProvider::instance()
|
|
{
|
|
static FindReplaceProvider inst;
|
|
return inst;
|
|
}
|
|
|
|
FindReplaceProvider::FindReplaceProvider()
|
|
: m_pEmbeddedFindReplaceWidget(NULL)
|
|
, m_pFindDialog(NULL)
|
|
, m_pReplaceDialog(NULL)
|
|
, m_pFindAllDialog(NULL)
|
|
, m_pGotoLineDialog(NULL)
|
|
{
|
|
if (FFlag::StudioEmbeddedFindDialogEnabled)
|
|
{
|
|
m_pEmbeddedFindReplaceWidget = new EmbeddedFindReplaceWidget(&UpdateUIManager::Instance().getMainWindow());
|
|
m_pEmbeddedFindReplaceWidget->hide();
|
|
}
|
|
else
|
|
{
|
|
m_pFindDialog = new FindDialog(&UpdateUIManager::Instance().getMainWindow());
|
|
m_pFindDialog->hide();
|
|
|
|
m_pReplaceDialog = new ReplaceDialog(&UpdateUIManager::Instance().getMainWindow());
|
|
m_pReplaceDialog->hide();
|
|
}
|
|
|
|
m_pFindAllDialog = new FindAllDialog(&UpdateUIManager::Instance().getMainWindow());
|
|
m_pFindAllDialog->hide();
|
|
|
|
m_pGotoLineDialog = new GoToLineDialog(&UpdateUIManager::Instance().getMainWindow());
|
|
m_pGotoLineDialog->hide();
|
|
}
|
|
|
|
FindReplaceProvider::~FindReplaceProvider()
|
|
{
|
|
m_pFindDialog = NULL; // Will be deleted by parent i.e. main window
|
|
m_pReplaceDialog = NULL; // Will be deleted by parent i.e. main window
|
|
m_pFindAllDialog = NULL;
|
|
m_pGotoLineDialog = NULL;
|
|
m_pEmbeddedFindReplaceWidget = NULL;
|
|
}
|
|
|
|
void FindReplaceProvider::setFindListener(IFindListener* listener)
|
|
{
|
|
if (m_pFindDialog)
|
|
m_pFindDialog->setFindListener(listener);
|
|
|
|
if (m_pReplaceDialog)
|
|
m_pReplaceDialog->setFindListener(listener);
|
|
|
|
if (m_pFindAllDialog)
|
|
m_pFindAllDialog->setFindListener(listener);
|
|
|
|
if (m_pGotoLineDialog)
|
|
m_pGotoLineDialog->setFindListener(listener);
|
|
|
|
if (FFlag::StudioEmbeddedFindDialogEnabled)
|
|
m_pEmbeddedFindReplaceWidget->setFindListener(listener);
|
|
}
|
|
|
|
bool FindReplaceProvider::isFindNextEnabled()
|
|
{
|
|
return (m_pFindDialog->isFindNextEnabled() || m_pReplaceDialog->isFindNextEnabled());
|
|
}
|
|
|
|
void FindReplaceProvider::find(bool forward)
|
|
{
|
|
if(m_pReplaceDialog->isVisible())
|
|
m_pReplaceDialog->find(forward,true);
|
|
else
|
|
m_pFindDialog->find(forward,true);
|
|
}
|
|
|
|
|
|
GoToLineDialog::GoToLineDialog(QWidget *parent)
|
|
: QDialog(parent)
|
|
{
|
|
initDialog();
|
|
}
|
|
|
|
void GoToLineDialog::initDialog()
|
|
{
|
|
setModal(true);
|
|
setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint);
|
|
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
|
|
|
m_pLineNumberLabel = new QLabel("Line number:");
|
|
|
|
m_pNumberValidator = new QIntValidator(this);
|
|
m_pNumberValidator->setBottom(0);
|
|
|
|
m_pLineNumberEdit = new QLineEdit;
|
|
m_pLineNumberEdit->setValidator(m_pNumberValidator);
|
|
|
|
m_pOkButton = new QPushButton("OK");
|
|
m_pCancelButton = new QPushButton("Cancel");
|
|
|
|
QHBoxLayout *pushButtons = new QHBoxLayout();
|
|
pushButtons->addStretch();
|
|
pushButtons->addWidget(m_pOkButton);
|
|
pushButtons->addWidget(m_pCancelButton);
|
|
|
|
QVBoxLayout *mainLayout = new QVBoxLayout();
|
|
mainLayout->addWidget(m_pLineNumberLabel);
|
|
mainLayout->addWidget(m_pLineNumberEdit);
|
|
mainLayout->addLayout(pushButtons);
|
|
|
|
setLayout(mainLayout);
|
|
|
|
setWindowTitle("Go to line");
|
|
|
|
connect(m_pLineNumberEdit, SIGNAL(returnPressed()), this, SLOT(goToLine()));
|
|
connect(m_pOkButton, SIGNAL(clicked()), this, SLOT(goToLine()));
|
|
connect(m_pCancelButton, SIGNAL(clicked()), this, SLOT(close()));
|
|
}
|
|
|
|
void GoToLineDialog::activate(int currentLine, int totalLines)
|
|
{
|
|
lineCount = totalLines;
|
|
m_pLineNumberLabel->setText(QString("Line number (1-%1):").arg(lineCount));
|
|
|
|
m_pLineNumberEdit->setText(QString::number(currentLine));
|
|
|
|
show();
|
|
activateWindow();
|
|
m_pLineNumberEdit->setFocus();
|
|
m_pLineNumberEdit->selectAll();
|
|
}
|
|
|
|
void GoToLineDialog::goToLine()
|
|
{
|
|
if (m_pFindListener)
|
|
m_pFindListener->moveCursorToLine(qMin(m_pLineNumberEdit->text().toInt() - 1, lineCount - 1));
|
|
close();
|
|
}
|
|
|
|
|
|
EmbeddedFindReplaceWidget::EmbeddedFindReplaceWidget(QWidget *parent)
|
|
: QDialog(parent)
|
|
, m_replaceVisible(false)
|
|
{
|
|
initDialog();
|
|
}
|
|
|
|
void EmbeddedFindReplaceWidget::activate(bool showReplace)
|
|
{
|
|
if (showReplace != m_replaceVisible)
|
|
toggleReplaceVisible();
|
|
|
|
show();
|
|
activateWindow();
|
|
setFocus();
|
|
|
|
m_pFindComboBox->lineEdit()->selectAll();
|
|
}
|
|
|
|
|
|
void EmbeddedFindReplaceWidget::initDialog()
|
|
{
|
|
setWindowFlags(Qt::Window | Qt::Dialog | Qt::FramelessWindowHint);
|
|
|
|
setStyleSheet("background-color: #f3f3f3");
|
|
|
|
setMinimumWidth(280);
|
|
setMaximumHeight(0);
|
|
|
|
QString pushButtonStyleSheet = STRINGIFY(
|
|
|
|
QPushButton
|
|
{
|
|
border: 0px;
|
|
}
|
|
|
|
QPushButton:hover
|
|
{
|
|
background: #E4EEFE;
|
|
}
|
|
|
|
QPushButton:checked
|
|
{
|
|
border: 1px solid #B8B8B8;
|
|
background: #DBDBDB;
|
|
}
|
|
);
|
|
|
|
QString comboBoxStyleSheet = STRINGIFY(
|
|
QComboBox
|
|
{
|
|
border: 0px;
|
|
}
|
|
);
|
|
|
|
m_pFindComboBox = new QComboBox();
|
|
m_pFindComboBox->setEditable(true);
|
|
m_pFindComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
|
m_pFindComboBox->lineEdit()->setPlaceholderText("Find...");
|
|
m_pFindComboBox->setAutoCompletion(false);
|
|
|
|
setFocusProxy(m_pFindComboBox);
|
|
|
|
m_pReplaceComboBox = new QComboBox();
|
|
m_pReplaceComboBox->setEditable(true);
|
|
m_pReplaceComboBox->hide();
|
|
m_pReplaceComboBox->lineEdit()->setPlaceholderText("Replace...");
|
|
m_pReplaceComboBox->setAutoCompletion(false);
|
|
|
|
m_pToggleReplaceButton = new QPushButton(QIcon(":/16x16/images/Studio 2.0 icons/16x16/expand_gray_16.png"), "");
|
|
m_pToggleReplaceButton->setFixedSize(18, 18);
|
|
m_pToggleReplaceButton->setStyleSheet(pushButtonStyleSheet);
|
|
m_pToggleReplaceButton->setAutoDefault(false);
|
|
|
|
m_pFindNextButton = new QPushButton(QIcon(":/16x16/images/Studio 2.0 icons/16x16/arrowright_black_16.png"), "");
|
|
m_pFindNextButton->setFixedSize(18, 18);
|
|
m_pFindNextButton->setStyleSheet(pushButtonStyleSheet);
|
|
m_pFindNextButton->setAutoDefault(true);
|
|
m_pFindNextButton->setToolTip("Find Next");
|
|
|
|
m_pFindPreviousButton = new QPushButton(QIcon(":/16x16/images/Studio 2.0 icons/16x16/arrowleft_black_16.png"), "");
|
|
m_pFindPreviousButton->setFixedSize(18, 18);
|
|
m_pFindPreviousButton->setStyleSheet(pushButtonStyleSheet);
|
|
m_pFindPreviousButton->setAutoDefault(false);
|
|
m_pFindPreviousButton->setToolTip("Find Previous");
|
|
|
|
m_pCloseDialogButton = new QPushButton(QIcon(":/16x16/images/Studio 2.0 icons/16x16/delete_x_16_b.png"), "");
|
|
m_pCloseDialogButton->setFixedSize(18, 18);
|
|
m_pCloseDialogButton->setStyleSheet(pushButtonStyleSheet);
|
|
m_pCloseDialogButton->setAutoDefault(false);
|
|
m_pCloseDialogButton->setToolTip("Close");
|
|
|
|
m_pReplaceNextButton = new QPushButton(QIcon(":/16x16/images/Studio 2.0 icons/16x16/replace.png"), "");
|
|
m_pReplaceNextButton->setFixedSize(18, 18);
|
|
m_pReplaceNextButton->setStyleSheet(pushButtonStyleSheet);
|
|
m_pReplaceNextButton->hide();
|
|
m_pReplaceNextButton->setAutoDefault(false);
|
|
m_pReplaceNextButton->setToolTip("Replace Next");
|
|
|
|
m_pReplaceAllButton = new QPushButton(QIcon(":/16x16/images/Studio 2.0 icons/16x16/replace_all.png"), "");
|
|
m_pReplaceAllButton->setFixedSize(18, 18);
|
|
m_pReplaceAllButton->setStyleSheet(pushButtonStyleSheet);
|
|
m_pReplaceAllButton->hide();
|
|
m_pReplaceAllButton->setAutoDefault(false);
|
|
m_pReplaceAllButton->setToolTip("Replace All");
|
|
|
|
m_pMatchCaseButton = new QPushButton(QIcon(":/16x16/images/Studio 2.0 icons/16x16/match_case.png"), "");
|
|
m_pMatchCaseButton->setFixedSize(18, 18);
|
|
m_pMatchCaseButton->setStyleSheet(pushButtonStyleSheet);
|
|
m_pMatchCaseButton->setCheckable(true);
|
|
m_pMatchCaseButton->setAutoDefault(false);
|
|
m_pMatchCaseButton->setToolTip("Match Case");
|
|
|
|
m_pMatchWholeWordButton = new QPushButton(QIcon(":/16x16/images/Studio 2.0 icons/16x16/match_whole_word.png"), "");
|
|
m_pMatchWholeWordButton->setFixedSize(18, 18);
|
|
m_pMatchWholeWordButton->setStyleSheet(pushButtonStyleSheet);
|
|
m_pMatchWholeWordButton->setCheckable(true);
|
|
m_pMatchWholeWordButton->setAutoDefault(false);
|
|
m_pMatchWholeWordButton->setToolTip("Match Whole Word");
|
|
|
|
m_pRegularExpressionButton = new QPushButton(QIcon(":/16x16/images/Studio 2.0 icons/16x16/regexp.png"), "");
|
|
m_pRegularExpressionButton->setFixedSize(18, 18);
|
|
m_pRegularExpressionButton->setStyleSheet(pushButtonStyleSheet);
|
|
m_pRegularExpressionButton->setCheckable(true);
|
|
m_pRegularExpressionButton->setAutoDefault(false);
|
|
m_pRegularExpressionButton->setToolTip("Regular Expression");
|
|
|
|
m_pNumberOfResultsFound = new QLabel();
|
|
m_pNumberOfResultsFound->setText("");
|
|
|
|
QBrush colorBrush(QColor(128, 128, 128, 255));
|
|
QPalette palette;
|
|
palette.setBrush(QPalette::Inactive, QPalette::WindowText, colorBrush);
|
|
palette.setBrush(QPalette::Active, QPalette::WindowText, colorBrush);
|
|
|
|
m_pNumberOfResultsFound->setPalette(palette);
|
|
|
|
QFrame* bottomFrame = new QFrame();
|
|
bottomFrame->setStyleSheet("background-color: #c4c4c4");
|
|
bottomFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
bottomFrame->setFixedHeight(4);
|
|
|
|
QSpacerItem* spacer1 = new QSpacerItem(2, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
|
|
QSpacerItem* spacer2 = new QSpacerItem(2, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
|
|
|
|
QGridLayout* mainLayout = new QGridLayout();
|
|
|
|
mainLayout->setSpacing(2);
|
|
mainLayout->setContentsMargins(QMargins(0, 4, 0, 0));
|
|
|
|
mainLayout->addItem(spacer1, 1, 0);
|
|
mainLayout->addWidget(m_pToggleReplaceButton, 1, 1);
|
|
mainLayout->addWidget(m_pFindComboBox, 1, 2, 1, 4);
|
|
mainLayout->addWidget(m_pFindPreviousButton, 1, 6);
|
|
mainLayout->addWidget(m_pFindNextButton, 1, 7);
|
|
mainLayout->addWidget(m_pCloseDialogButton, 1, 8);
|
|
mainLayout->addItem(spacer2, 1, 9);
|
|
|
|
mainLayout->addWidget(m_pReplaceComboBox, 2, 2, 1, 4);
|
|
mainLayout->addWidget(m_pReplaceNextButton, 2, 6);
|
|
mainLayout->addWidget(m_pReplaceAllButton, 2, 7);
|
|
|
|
mainLayout->addWidget(m_pMatchCaseButton, 3, 2);
|
|
mainLayout->addWidget(m_pMatchWholeWordButton, 3, 3);
|
|
mainLayout->addWidget(m_pRegularExpressionButton, 3, 4);
|
|
mainLayout->addWidget(m_pNumberOfResultsFound, 3, 5);
|
|
|
|
mainLayout->addWidget(bottomFrame, 4, 0, 1, 10);
|
|
|
|
setLayout(mainLayout);
|
|
|
|
connect(m_pCloseDialogButton, SIGNAL(pressed()), this, SLOT(onCloseDialog()));
|
|
connect(m_pFindComboBox->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(find()));
|
|
|
|
connect(m_pMatchCaseButton, SIGNAL(clicked()), this, SLOT(find()));
|
|
connect(m_pMatchWholeWordButton, SIGNAL(clicked()), this, SLOT(find()));
|
|
connect(m_pRegularExpressionButton, SIGNAL(clicked()), this, SLOT(find()));
|
|
connect(m_pToggleReplaceButton, SIGNAL(pressed()), this, SLOT(toggleReplaceVisible()));
|
|
|
|
connect(m_pFindPreviousButton, SIGNAL(pressed()), this, SLOT(findPrevious()));
|
|
connect(m_pFindNextButton, SIGNAL(pressed()), this, SLOT(findNext()));
|
|
connect(m_pReplaceNextButton, SIGNAL(pressed()), this, SLOT(replaceNext()));
|
|
connect(m_pReplaceAllButton, SIGNAL(pressed()), this, SLOT(replaceAll()));
|
|
}
|
|
|
|
void EmbeddedFindReplaceWidget::keyPressEvent(QKeyEvent* evt)
|
|
{
|
|
QKeySequence key = QKeySequence(evt->modifiers()|evt->key());
|
|
|
|
QAction* previous = UpdateUIManager::Instance().getMainWindow().findPreviousAction;
|
|
if (previous && key == previous->shortcut())
|
|
{
|
|
previous->trigger();
|
|
evt->accept();
|
|
return;
|
|
}
|
|
|
|
QAction* next = UpdateUIManager::Instance().getMainWindow().findNextAction;
|
|
if (next && key == next->shortcut())
|
|
{
|
|
next->trigger();
|
|
evt->accept();
|
|
return;
|
|
}
|
|
|
|
if (evt->key() == Qt::Key_Enter ||
|
|
evt->key() == Qt::Key_Return)
|
|
{
|
|
if (m_pFindComboBox->hasFocus())
|
|
findNext();
|
|
else if (m_pReplaceComboBox->hasFocus())
|
|
replaceNext();
|
|
|
|
evt->accept();
|
|
return;
|
|
}
|
|
|
|
if (evt->key() == Qt::Key_Escape)
|
|
{
|
|
onCloseDialog();
|
|
evt->accept();
|
|
return;
|
|
}
|
|
|
|
QWidget::keyPressEvent(evt);
|
|
}
|
|
|
|
void EmbeddedFindReplaceWidget::setNumberOfFoundResults(int number)
|
|
{
|
|
if (number == -1)
|
|
{
|
|
m_pNumberOfResultsFound->setText("");
|
|
return;
|
|
}
|
|
|
|
m_pNumberOfResultsFound->setText(QString(" %1 occurrences found").arg(number));
|
|
}
|
|
|
|
QRegExp EmbeddedFindReplaceWidget::getSearchString()
|
|
{
|
|
QRegExp rx(m_pFindComboBox->lineEdit()->text());
|
|
|
|
if (!m_pRegularExpressionButton->isChecked())
|
|
rx.setPatternSyntax(QRegExp::FixedString);
|
|
|
|
rx.setCaseSensitivity(m_pMatchCaseButton->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
|
|
|
return rx;
|
|
}
|
|
|
|
void EmbeddedFindReplaceWidget::toggleReplaceVisible()
|
|
{
|
|
m_replaceVisible = !m_replaceVisible;
|
|
|
|
QString toggleButtonIconLocation = m_replaceVisible ? "collapse_gray_16.png" : "expand_gray_16.png";
|
|
m_pToggleReplaceButton->setIcon(QIcon(":/16x16/images/Studio 2.0 icons/16x16/" + toggleButtonIconLocation));
|
|
|
|
m_pReplaceComboBox->setVisible(m_replaceVisible);
|
|
m_pReplaceNextButton->setVisible(m_replaceVisible);
|
|
m_pReplaceAllButton->setVisible(m_replaceVisible);
|
|
|
|
adjustSize();
|
|
}
|
|
|
|
void EmbeddedFindReplaceWidget::updateFindPosition(QPoint position, QSize size)
|
|
{
|
|
this->setGeometry(position.x() + size.width() - geometry().width(), position.y(), geometry().width(), geometry().height());
|
|
}
|
|
|
|
void EmbeddedFindReplaceWidget::find()
|
|
{
|
|
QTextDocument::FindFlags flags = m_pMatchWholeWordButton->isChecked() ?
|
|
QTextDocument::FindWholeWords :
|
|
(QTextDocument::FindFlags)0;
|
|
|
|
m_pFindListener->find(false, getSearchString(), flags);
|
|
}
|
|
|
|
void EmbeddedFindReplaceWidget::findNext()
|
|
{
|
|
m_pFindListener->moveNext(true);
|
|
}
|
|
|
|
void EmbeddedFindReplaceWidget::findPrevious()
|
|
{
|
|
m_pFindListener->moveNext(false);
|
|
}
|
|
|
|
void EmbeddedFindReplaceWidget::replaceNext()
|
|
{
|
|
m_pFindListener->replaceNext(getSearchString(), m_pReplaceComboBox->lineEdit()->text());
|
|
}
|
|
|
|
void EmbeddedFindReplaceWidget::replaceAll()
|
|
{
|
|
m_pFindListener->replaceAll(getSearchString(), m_pReplaceComboBox->lineEdit()->text());
|
|
}
|
|
|
|
void EmbeddedFindReplaceWidget::onCloseDialog()
|
|
{
|
|
m_pFindComboBox->lineEdit()->setText("");
|
|
close();
|
|
}
|