/** * * 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("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("replace_text"); m_pCaseInsensitiveCheck = getChild("case_text"); m_pCaseInsensitiveCheck->setCommitCallback(boost::bind(&LLFloaterSearchReplace::refreshHighlight, this)); m_pSearchUpCheck = getChild("find_previous"); LLButton* pSearchBtn = getChild("search_btn"); pSearchBtn->setCommitCallback(boost::bind(&LLFloaterSearchReplace::onSearchClick, this)); setDefaultBtn(pSearchBtn); LLButton* pReplaceBtn = getChild("replace_btn"); pReplaceBtn->setCommitCallback(boost::bind(&LLFloaterSearchReplace::onReplaceClick, this)); LLButton* pReplaceAllBtn = getChild("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("replace_btn")->setEnabled( (pEditor) && (!pEditor->getReadOnly()) ); getChild("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(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(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("search_replace"); if ( (!pSelf) || (!pEditor) ) return NULL; LLFloater *pDependeeNew = NULL, *pDependeeOld = pSelf->getDependee(); LLView* pView = pEditor->getParent(); while (pView) { pDependeeNew = dynamic_cast(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("search_replace"); } LLTextEditor* LLFloaterSearchReplace::getEditor() const { return dynamic_cast(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("replace_btn")->setEnabled(can_replace); getChild("replace_all_btn")->setEnabled(can_replace); } // ============================================================================