phoenix-firestorm/indra/newview/llfloatersearchreplace.cpp

231 lines
6.8 KiB
C++

/**
*
* Copyright (c) 2010-2013, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
*
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*
*/
#include "llviewerprecompiledheaders.h"
#include "llcheckboxctrl.h"
#include "llfloaterreg.h"
#include "llfloatersearchreplace.h"
#include "lllineeditor.h"
#include "llmultifloater.h"
#include "lltexteditor.h"
#include "llviewermenu.h"
// ============================================================================
// LLFloaterSearchReplace class
//
LLFloaterSearchReplace::LLFloaterSearchReplace(const LLSD& sdKey)
: LLFloater(sdKey)
, m_pSearchEditor(NULL)
, m_pReplaceEditor(NULL)
, m_pCaseInsensitiveCheck(NULL)
, m_pSearchUpCheck(NULL)
{
}
LLFloaterSearchReplace::~LLFloaterSearchReplace()
{
}
BOOL LLFloaterSearchReplace::postBuild()
{
m_pSearchEditor = getChild<LLLineEditor>("search_text");
m_pSearchEditor->setCommitCallback(boost::bind(&LLFloaterSearchReplace::onSearchClick, this));
m_pSearchEditor->setCommitOnFocusLost(false);
m_pSearchEditor->setKeystrokeCallback(boost::bind(&LLFloaterSearchReplace::refreshHighlight, this), NULL);
m_pReplaceEditor = getChild<LLLineEditor>("replace_text");
m_pCaseInsensitiveCheck = getChild<LLCheckBoxCtrl>("case_text");
m_pCaseInsensitiveCheck->setCommitCallback(boost::bind(&LLFloaterSearchReplace::refreshHighlight, this));
m_pSearchUpCheck = getChild<LLCheckBoxCtrl>("find_previous");
LLButton* pSearchBtn = getChild<LLButton>("search_btn");
pSearchBtn->setCommitCallback(boost::bind(&LLFloaterSearchReplace::onSearchClick, this));
setDefaultBtn(pSearchBtn);
LLButton* pReplaceBtn = getChild<LLButton>("replace_btn");
pReplaceBtn->setCommitCallback(boost::bind(&LLFloaterSearchReplace::onReplaceClick, this));
LLButton* pReplaceAllBtn = getChild<LLButton>("replace_all_btn");
pReplaceAllBtn->setCommitCallback(boost::bind(&LLFloaterSearchReplace::onReplaceAllClick, this));
return TRUE;
}
void LLFloaterSearchReplace::onOpen(const LLSD& sdKey)
{
LLTextEditor* pEditor = getEditor();
if (pEditor)
{
// HACK-Catznip: hasSelection() is inaccessible but canCopy() is (currently) a synonym *sighs*
if (pEditor->canCopy())
{
m_pSearchEditor->setText(pEditor->getSelectionString());
m_pSearchEditor->setCursorToEnd();
}
pEditor->setHighlightWord(m_pSearchEditor->getText(), m_pCaseInsensitiveCheck->get());
m_pReplaceEditor->setEnabled( (pEditor) && (!pEditor->getReadOnly()) );
getChild<LLButton>("replace_btn")->setEnabled( (pEditor) && (!pEditor->getReadOnly()) );
getChild<LLButton>("replace_all_btn")->setEnabled( (pEditor) && (!pEditor->getReadOnly()) );
}
m_pSearchEditor->setFocus(TRUE);
}
void LLFloaterSearchReplace::onClose(bool fQuiting)
{
LLTextEditor* pEditor = getEditor();
if (pEditor)
{
pEditor->clearHighlights();
}
}
bool LLFloaterSearchReplace::hasAccelerators() const
{
const LLView* pView = dynamic_cast<LLTextEditor*>(m_EditorHandle.get());
while (pView)
{
if (pView->hasAccelerators())
return true;
pView = pView->getParent();
}
return false;
}
BOOL LLFloaterSearchReplace::handleKeyHere(KEY key, MASK mask)
{
// Pass this on to the editor we're operating on (or any view up along its hierarchy) if we don't handle the key ourselves
// (allows Ctrl-F to work when the floater itself has focus - see changeset 0c8947e5f433)
BOOL handled = LLFloater::handleKeyHere(key, mask);
if (!handled)
{
// Check if one of our children currently has keyboard focus and if so route edit accellerators to it
if (gFocusMgr.childHasKeyboardFocus(this))
{
LLView* pEditView = dynamic_cast<LLView*>(LLEditMenuHandler::gEditMenuHandler);
if ( (pEditView) && (pEditView->hasAncestor(this)) && (gEditMenu) && (gEditMenu->handleAcceleratorKey(key, mask)) )
{
return TRUE;
}
}
LLView* pView = m_EditorHandle.get();
while (pView)
{
if ( (pView->hasAccelerators()) && (pView->handleKeyHere(key, mask)) )
return TRUE;
pView = pView->getParent();
}
}
return handled;
}
//static
LLFloaterSearchReplace* LLFloaterSearchReplace::show(LLTextEditor* pEditor)
{
LLFloaterSearchReplace* pSelf = LLFloaterReg::getTypedInstance<LLFloaterSearchReplace>("search_replace");
if ( (!pSelf) || (!pEditor) )
return NULL;
LLFloater *pDependeeNew = NULL, *pDependeeOld = pSelf->getDependee();
LLView* pView = pEditor->getParent();
while (pView)
{
pDependeeNew = dynamic_cast<LLFloater*>(pView);
if (pDependeeNew)
{
if (pDependeeNew != pDependeeOld)
{
if (pDependeeOld)
{
if (pSelf->getEditor())
pSelf->getEditor()->clearHighlights();
pDependeeOld->removeDependentFloater(pSelf);
}
if (!pDependeeNew->getHost())
pDependeeNew->addDependentFloater(pSelf);
else
pDependeeNew->getHost()->addDependentFloater(pSelf);
}
break;
}
pView = pView->getParent();
}
pSelf->m_EditorHandle = pEditor->getHandle();
pSelf->openFloater();
return pSelf;
}
//static
LLFloaterSearchReplace* LLFloaterSearchReplace::findInstance()
{
return LLFloaterReg::findTypedInstance<LLFloaterSearchReplace>("search_replace");
}
LLTextEditor* LLFloaterSearchReplace::getEditor() const
{
return dynamic_cast<LLTextEditor*>(m_EditorHandle.get());
}
void LLFloaterSearchReplace::refreshHighlight()
{
LLTextEditor* pEditor = getEditor();
if (pEditor)
{
pEditor->setHighlightWord(m_pSearchEditor->getText(), m_pCaseInsensitiveCheck->get());
}
}
void LLFloaterSearchReplace::onSearchClick()
{
LLTextEditor* pEditor = getEditor();
if (pEditor)
{
pEditor->selectNext(m_pSearchEditor->getText(), m_pCaseInsensitiveCheck->get(), TRUE, m_pSearchUpCheck->get());
}
}
void LLFloaterSearchReplace::onReplaceClick()
{
LLTextEditor* pEditor = getEditor();
if (pEditor)
{
pEditor->replaceText(m_pSearchEditor->getText(), m_pReplaceEditor->getText(), m_pCaseInsensitiveCheck->get(), TRUE, m_pSearchUpCheck->get());
}
}
void LLFloaterSearchReplace::onReplaceAllClick()
{
LLTextEditor* pEditor = getEditor();
if (pEditor)
{
pEditor->replaceTextAll(m_pSearchEditor->getText(), m_pReplaceEditor->getText(), m_pCaseInsensitiveCheck->get());
}
}
void LLFloaterSearchReplace::setCanReplace(bool can_replace)
{
m_pReplaceEditor->setEnabled(can_replace);
getChild<LLButton>("replace_btn")->setEnabled(can_replace);
getChild<LLButton>("replace_all_btn")->setEnabled(can_replace);
}
// ============================================================================