/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
void FmSearchDialog::initCommon( const Reference< XResultSet >& _rxCursor )
{ // init the engine
DBG_ASSERT( m_pSearchEngine, "FmSearchDialog::initCommon: have no engine!" );
m_pSearchEngine->SetProgressHandler(LINK(this, FmSearchDialog, OnSearchProgress));
// some layout changes according to available CJK options if (!SvtCJKOptions::IsJapaneseFindEnabled())
{ // hide the options for the japanese search
m_pSoundsLikeCJK->hide();
m_pSoundsLikeCJKSettings->hide();
}
if (!SvtCJKOptions::IsCJKFontEnabled())
{
m_pHalfFullFormsCJK->hide();
// never ignore the width (ignoring is expensive) if the option is not available at all
m_pSearchEngine->SetIgnoreWidthCJK( false );
}
// some initial record texts
m_pftRecord->set_label( OUString::number(_rxCursor->getRow()) );
m_pbClose->set_tooltip_text(OUString());
}
// fill the listboxes // method of field comparison const TranslateId aResIds[] = {
RID_STR_SEARCH_ANYWHERE,
RID_STR_SEARCH_BEGINNING,
RID_STR_SEARCH_END,
RID_STR_SEARCH_WHOLE
}; for (autoconst & pResId : aResIds)
m_plbPosition->append_text(CuiResId(pResId));
m_plbPosition->set_active(MATCHING_ANYWHERE);
// the field listbox if (!strVisibleFields.empty())
{
sal_Int32 nPos {0}; do {
m_plbField->append_text(OUString(o3tl::getToken(strVisibleFields, 0, ';', nPos)));
} while (nPos>=0);
}
m_pConfig.reset( new FmSearchConfigItem );
LoadParams();
m_pcmbSearchText->set_entry_text(sInitialText); // if the Edit-line has changed the text (e.g. because it contains // control characters, as can be the case with memo fields), I use // an empty OUString.
OUString sRealSetText = m_pcmbSearchText->get_active_text(); if (sRealSetText != sInitialText)
m_pcmbSearchText->set_entry_text(OUString());
OnSearchTextModified(*m_pcmbSearchText);
// initial
EnableSearchUI(true);
if ( m_prbSearchForText->get_active() )
m_pcmbSearchText->grab_focus();
}
short FmSearchDialog::run()
{ short nRet = weld::GenericDialogController::run();
m_pSearchEngine->CancelSearch(); return nRet;
}
IMPL_LINK(FmSearchDialog, OnToggledFieldRadios, weld::Toggleable&, rButton, void)
{ if (!rButton.get_active()) return;
// en- or disable field list box accordingly if (m_prbSingleField->get_active())
{
m_plbField->set_sensitive(true);
m_pSearchEngine->RebuildUsedFields(m_plbField->get_active());
} else
{
m_plbField->set_sensitive(false);
m_pSearchEngine->RebuildUsedFields(-1);
}
}
IMPL_LINK_NOARG(FmSearchDialog, OnClickedSearchAgain, weld::Button&, void)
{ if (m_pbClose->get_sensitive())
{ // the button has the function 'search'
OUString strThisRoundText = m_pcmbSearchText->get_active_text(); // to history
m_pcmbSearchText->remove_text(strThisRoundText);
m_pcmbSearchText->insert_text(0, strThisRoundText); // the remove/insert makes sure that a) the OUString does not appear twice and // that b) the last searched strings are at the beginning and limit the list length while (m_pcmbSearchText->get_count() > MAX_HISTORY_ENTRIES)
m_pcmbSearchText->remove(m_pcmbSearchText->get_count()-1);
// take out the 'overflow' hint
m_pftHint->set_label(OUString());
if (m_pcbStartOver->get_active())
{
m_pcbStartOver->set_active(false);
EnableSearchUI(false); if (m_prbSearchForText->get_active())
m_pSearchEngine->StartOver(strThisRoundText); else
m_pSearchEngine->StartOverSpecial(m_prbSearchForNull->get_active());
} else
{
EnableSearchUI(false); if (m_prbSearchForText->get_active())
m_pSearchEngine->SearchNext(strThisRoundText); else
m_pSearchEngine->SearchNextSpecial(m_prbSearchForNull->get_active());
} // tdf#155308: explicitly keep the focus by default for non gtk renderings
m_pbSearchAgain->grab_focus();
} else
{ // the button has the function 'cancel' // the CancelButton is usually only disabled, when working in a thread or with reschedule
m_pSearchEngine->CancelSearch(); // the ProgressHandler is called when it's really finished, here it's only a demand
}
}
// formatter or case -> pass on to the engine if (&rBox == m_pcbUseFormat.get())
m_pSearchEngine->SetFormatterUsing(bChecked); elseif (&rBox == m_pcbCase.get())
m_pSearchEngine->SetCaseSensitive(bChecked); // direction -> pass on and reset the checkbox-text for StartOver elseif (&rBox == m_pcbBackwards.get())
{
m_pcbStartOver->set_label( CuiResId( bChecked ? RID_STR_FROM_BOTTOM : RID_STR_FROM_TOP ) );
m_pSearchEngine->SetDirection(!bChecked);
} // similarity-search or regular expression elseif ((&rBox == m_pcbApprox.get()) || (&rBox == m_pcbRegular.get()) || (&rBox == m_pcbWildCard.get()))
{
weld::CheckButton* pBoxes[] = { m_pcbWildCard.get(), m_pcbRegular.get(), m_pcbApprox.get() }; for (weld::CheckButton* pBoxe : pBoxes)
{ if (pBoxe != &rBox)
{ if (bChecked)
pBoxe->set_sensitive(false); else
pBoxe->set_sensitive(true);
}
}
// pass on to the engine
m_pSearchEngine->SetWildcard(m_pcbWildCard->get_sensitive() && m_pcbWildCard->get_active());
m_pSearchEngine->SetRegular(m_pcbRegular->get_sensitive() && m_pcbRegular->get_active());
m_pSearchEngine->SetLevenshtein(m_pcbApprox->get_sensitive() && m_pcbApprox->get_active()); // (disabled boxes have to be passed to the engine as sal_False)
// adjust the Position-Listbox (which is not allowed during Wildcard-search) if (&rBox == m_pcbWildCard.get())
{ if (bChecked)
{
m_pftPosition->set_sensitive(false);
m_plbPosition->set_sensitive(false);
} else
{
m_pftPosition->set_sensitive(true);
m_plbPosition->set_sensitive(true);
}
}
// and the button for similarity-search if (&rBox == m_pcbApprox.get())
{ if (bChecked)
m_ppbApproxSettings->set_sensitive(true); else
m_ppbApproxSettings->set_sensitive(false);
}
} elseif (&rBox == m_pHalfFullFormsCJK.get())
{ // forward to the search engine
m_pSearchEngine->SetIgnoreWidthCJK( !bChecked );
} elseif (&rBox == m_pSoundsLikeCJK.get())
{
m_pSoundsLikeCJKSettings->set_sensitive(bChecked);
// two other buttons which depend on this one bool bEnable = ( m_prbSearchForText->get_active()
&& !m_pSoundsLikeCJK->get_active()
)
|| !SvtCJKOptions::IsJapaneseFindEnabled();
m_pcbCase->set_sensitive(bEnable);
m_pHalfFullFormsCJK->set_sensitive(bEnable);
// forward to the search engine
m_pSearchEngine->SetTransliteration( bChecked );
}
}
sal_uInt32 nResult = m_lnkContextSupplier.Call(fmscContext);
DBG_ASSERT(nResult > 0, "FmSearchDialog::InitContext : ContextSupplier didn't give me any controls !");
// put the field names into the respective listbox
m_plbField->clear();
if (!fmscContext.sFieldDisplayNames.isEmpty())
{ // use the display names if supplied
DBG_ASSERT(comphelper::string::getTokenCount(fmscContext.sFieldDisplayNames, ';') == comphelper::string::getTokenCount(fmscContext.strUsedFields, ';'), "FmSearchDialog::InitContext : invalid context description supplied !");
sal_Int32 nPos {0}; do {
m_plbField->append_text(fmscContext.sFieldDisplayNames.getToken(0, ';', nPos));
} while (nPos>=0);
} elseif (!fmscContext.strUsedFields.isEmpty())
{ // else use the field names
sal_Int32 nPos {0}; do {
m_plbField->append_text(fmscContext.strUsedFields.getToken(0, ';', nPos));
} while (nPos>=0);
}
if (nContext < static_cast<sal_Int32>(m_arrContextFields.size()) && !m_arrContextFields[nContext].isEmpty())
{
m_plbField->set_active_text(m_arrContextFields[nContext]);
} else
{
m_plbField->set_active(0); if (m_prbSingleField->get_active() && (m_plbField->get_count() > 1))
m_plbField->grab_focus();
}
void FmSearchDialog::EnableSearchUI(bool bEnable)
{ // the search button has two functions -> adjust its text accordingly
OUString sButtonText( bEnable ? m_sSearch : m_sCancel );
m_pbSearchAgain->set_label(sButtonText);
if ( !bEnable )
{ // this means we're preparing for starting a search // In this case, EnableSearchForDependees disabled the search button // But as we're about to use it for cancelling the search, we really need to enable it, again
m_pbSearchAgain->set_sensitive(true);
}
}
void FmSearchDialog::OnFound(const css::uno::Any& aCursorPos, sal_Int16 nFieldPos)
{
FmFoundRecordInformation friInfo;
friInfo.nContext = m_plbForm->get_active(); // if I don't do a search in a context, this has an invalid value - but then it doesn't matter anyway
friInfo.aPosition = aCursorPos; if (m_prbAllFields->get_active())
friInfo.nFieldPos = nFieldPos; else
friInfo.nFieldPos = m_plbField->get_active(); // this of course implies that I have really searched in the field that is selected in the listbox, // which is made sure in RebuildUsedFields
m_lnkFoundHandler.Call(friInfo);
m_pcmbSearchText->grab_focus();
}
IMPL_LINK(FmSearchDialog, OnSearchProgress, const FmSearchProgress*, pProgress, void)
{
SolarMutexGuard aGuard; // make this single method thread-safe (it's an overkill to block the whole application for this, // but we don't have another safety concept at the moment)
case FmSearchProgress::State::ProgressCounting:
m_pftHint->set_label(CuiResId(RID_STR_SEARCH_COUNTING));
m_pftRecord->set_label(OUString::number(pProgress->nCurrentRecord)); break;
case FmSearchProgress::State::Successful:
OnFound(pProgress->aBookmark, static_cast<sal_Int16>(pProgress->nFieldIndex));
EnableSearchUI(true); break;
case FmSearchProgress::State::Error: case FmSearchProgress::State::NothingFound:
{
TranslateId pErrorId = (FmSearchProgress::State::Error == pProgress->aSearchState)
? RID_STR_SEARCH_GENERAL_ERROR
: RID_STR_SEARCH_NORECORD;
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
VclMessageType::Warning, VclButtonsType::Ok, CuiResId(pErrorId)));
xBox->run();
[[fallthrough]];
} case FmSearchProgress::State::Canceled:
EnableSearchUI(true); if (m_lnkCanceledNotFoundHdl.IsSet())
{
FmFoundRecordInformation friInfo;
friInfo.nContext = m_plbForm->get_active(); // if I don't do a search in a context, this has an invalid value - but then it doesn't matter anyway
friInfo.aPosition = pProgress->aBookmark;
m_lnkCanceledNotFoundHdl.Call(friInfo);
} break;
}
for (auto& historystr : aParams.aHistory)
m_pcmbSearchText->append_text(historystr);
// I do the settings at my UI-elements and then I simply call the respective change-handler, // that way the data is handed on to the SearchEngine and all dependent settings are done
// current field int nInitialField = m_plbField->find_text( aParams.sSingleSearchField ); if (nInitialField == -1)
nInitialField = 0;
m_plbField->set_active(nInitialField);
OnFieldSelected(*m_plbField); // all fields/single field (AFTER selecting the field because OnToggledFieldRadios expects a valid value there) if (aParams.bAllFields)
{
m_prbSingleField->set_active(false);
m_prbAllFields->set_active(true);
OnToggledFieldRadios(*m_prbAllFields); // OnToggledFieldRadios also calls to RebuildUsedFields
} else
{
m_prbAllFields->set_active(false);
m_prbSingleField->set_active(true);
OnToggledFieldRadios(*m_prbSingleField);
}
weld::CheckButton* pToCheck = nullptr; if (aParams.bWildcard)
pToCheck = m_pcbWildCard.get(); if (aParams.bRegular)
pToCheck = m_pcbRegular.get(); if (aParams.bApproxSearch)
pToCheck = m_pcbApprox.get(); if (aParams.bSoundsLikeCJK)
pToCheck = m_pSoundsLikeCJK.get(); if (pToCheck)
{
pToCheck->set_active(true);
OnCheckBoxToggled(*pToCheck);
}
// set Levenshtein-parameters directly at the SearchEngine
m_pSearchEngine->SetLevRelaxed(aParams.bLevRelaxed);
m_pSearchEngine->SetLevOther(aParams.nLevOther);
m_pSearchEngine->SetLevShorter(aParams.nLevShorter);
m_pSearchEngine->SetLevLonger(aParams.nLevLonger);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.