LibreOffice Module vcl (master)  1
quickselectionengine.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
21 #include <vcl/event.hxx>
22 #include <vcl/timer.hxx>
23 #include <vcl/i18nhelp.hxx>
24 #include <vcl/svapp.hxx>
25 #include <vcl/settings.hxx>
26 #include <sal/log.hxx>
27 
28 #include <optional>
29 
30 namespace vcl
31 {
32 
34  {
37  ::std::optional< sal_Unicode > aSingleSearchChar;
39 
41  :rEntryList( _entryList )
42  {
43  aSearchTimeout.SetTimeout( 2500 );
44  aSearchTimeout.SetInvokeHandler( LINK( this, QuickSelectionEngine_Data, SearchStringTimeout ) );
45  aSearchTimeout.SetDebugName( "vcl::QuickSelectionEngine_Data aSearchTimeout" );
46  }
47 
49  {
50  aSearchTimeout.Stop();
51  }
52 
53  DECL_LINK( SearchStringTimeout, Timer*, void );
54  };
55 
56  namespace
57  {
58  void lcl_reset( QuickSelectionEngine_Data& _data )
59  {
60  _data.sCurrentSearchString.clear();
61  _data.aSingleSearchChar.reset();
62  _data.aSearchTimeout.Stop();
63  }
64  }
65 
66  IMPL_LINK_NOARG( QuickSelectionEngine_Data, SearchStringTimeout, Timer*, void )
67  {
68  lcl_reset( *this );
69  }
70 
71  static StringEntryIdentifier findMatchingEntry( const OUString& _searchString, QuickSelectionEngine_Data const & _engineData )
72  {
74  // TODO: do we really need the Window's settings here? The original code used it ...
75 
76  OUString sEntryText;
77  // get the "current + 1" entry
78  StringEntryIdentifier pSearchEntry = _engineData.rEntryList.CurrentEntry( sEntryText );
79  if ( pSearchEntry )
80  pSearchEntry = _engineData.rEntryList.NextEntry( pSearchEntry, sEntryText );
81  // loop 'til we find another matching entry
82  StringEntryIdentifier pStartedWith = pSearchEntry;
83  while ( pSearchEntry )
84  {
85  if ( rI18nHelper.MatchString( _searchString, sEntryText ) )
86  break;
87 
88  pSearchEntry = _engineData.rEntryList.NextEntry( pSearchEntry, sEntryText );
89  if ( pSearchEntry == pStartedWith )
90  pSearchEntry = nullptr;
91  }
92 
93  return pSearchEntry;
94  }
95 
97  :m_pData( new QuickSelectionEngine_Data( _entryList ) )
98  {
99  }
100 
102  {
103  }
104 
106  {
107  sal_Unicode c = _keyEvent.GetCharCode();
108 
109  if ( ( c >= 32 ) && ( c != 127 ) && !_keyEvent.GetKeyCode().IsMod2() )
110  {
111  m_pData->sCurrentSearchString += OUStringChar(c);
112  SAL_INFO( "vcl", "QuickSelectionEngine::HandleKeyEvent: searching for " << m_pData->sCurrentSearchString );
113 
114  if ( m_pData->sCurrentSearchString.getLength() == 1 )
115  { // first character in the search -> remember
116  m_pData->aSingleSearchChar = c;
117  }
118  else if ( m_pData->sCurrentSearchString.getLength() > 1 )
119  {
120  if ( !!m_pData->aSingleSearchChar && ( *m_pData->aSingleSearchChar != c ) )
121  // we already have a "single char", but the current one is different -> reset
122  m_pData->aSingleSearchChar.reset();
123  }
124 
125  OUString aSearchTemp( m_pData->sCurrentSearchString );
126 
127  StringEntryIdentifier pMatchingEntry = findMatchingEntry( aSearchTemp, *m_pData );
128  SAL_INFO( "vcl", "QuickSelectionEngine::HandleKeyEvent: found " << pMatchingEntry );
129  if ( !pMatchingEntry && (aSearchTemp.getLength() > 1) && !!m_pData->aSingleSearchChar )
130  {
131  // if there's only one letter in the search string, use a different search mode
132  aSearchTemp = OUString(*m_pData->aSingleSearchChar);
133  pMatchingEntry = findMatchingEntry( aSearchTemp, *m_pData );
134  }
135 
136  if ( pMatchingEntry )
137  {
138  m_pData->rEntryList.SelectEntry( pMatchingEntry );
139  m_pData->aSearchTimeout.Start();
140  }
141  else
142  {
143  lcl_reset( *m_pData );
144  }
145 
146  return true;
147  }
148  return false;
149  }
150 
152  {
153  lcl_reset( *m_pData );
154  }
155 
156 } // namespace vcl
157 
158 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool HandleKeyEvent(const KeyEvent &_rKEvt)
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:733
virtual StringEntryIdentifier CurrentEntry(OUString &_out_entryText) const =0
returns the current entry in the list of searchable strings.
bool MatchString(const OUString &rStr1, const OUString &rStr2) const
Definition: i18nhelp.cxx:124
::std::unique_ptr< QuickSelectionEngine_Data > m_pData
sal_uInt16 sal_Unicode
FmFilterData * m_pData
const void * StringEntryIdentifier
DECL_LINK(SearchStringTimeout, Timer *, void)
ISearchableStringList & rEntryList
void SetDebugName(const char *pDebugName)
Definition: task.hxx:82
QuickSelectionEngine(ISearchableStringList &_entryList)
::std::optional< sal_Unicode > aSingleSearchChar
void SetTimeout(sal_uInt64 nTimeoutMs)
Definition: timer.cxx:90
const vcl::I18nHelper & GetLocaleI18nHelper() const
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:57
virtual StringEntryIdentifier NextEntry(StringEntryIdentifier _currentEntry, OUString &_out_entryText) const =0
returns the next entry in the list.
static StringEntryIdentifier findMatchingEntry(const OUString &_searchString, QuickSelectionEngine_Data const &_engineData)
void Stop()
Definition: scheduler.cxx:590
#define SAL_INFO(area, stream)
sal_Unicode GetCharCode() const
Definition: event.hxx:56
void SetInvokeHandler(const Link< Timer *, void > &rLink)
Definition: timer.hxx:56
Definition: timer.hxx:26
QuickSelectionEngine_Data(ISearchableStringList &_entryList)
IMPL_LINK_NOARG(QuickSelectionEngine_Data, SearchStringTimeout, Timer *, void)
bool IsMod2() const
Definition: keycod.hxx:58