LibreOffice Module fpicker (master) 1
autocmpledit.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
10#include <vcl/event.hxx>
11#include "autocmpledit.hxx"
12
13AutocompleteEdit::AutocompleteEdit(std::unique_ptr<weld::Entry> xEntry)
14 : m_xEntry(std::move(xEntry))
15 , m_aChangedIdle("fpicker::AutocompleteEdit m_aChangedIdle")
16 , m_nLastCharCode(0)
17{
18 m_xEntry->connect_changed(LINK(this, AutocompleteEdit, ChangedHdl));
19 m_xEntry->connect_key_press(LINK(this, AutocompleteEdit, KeyInputHdl));
20
22}
23
24IMPL_LINK(AutocompleteEdit, KeyInputHdl, const KeyEvent&, rKEvt, bool)
25{
26 m_nLastCharCode = rKEvt.GetKeyCode().GetCode();
27 return false;
28}
29
31{
32 m_aChangeHdl.Call(*m_xEntry);
33
34 switch (m_nLastCharCode)
35 {
36 case css::awt::Key::DELETE_WORD_BACKWARD:
37 case css::awt::Key::DELETE_WORD_FORWARD:
38 case css::awt::Key::DELETE_TO_BEGIN_OF_LINE:
39 case css::awt::Key::DELETE_TO_END_OF_LINE:
40 case KEY_BACKSPACE:
41 case KEY_DELETE:
42 m_aChangedIdle.Stop();
43 break;
44 default:
45 m_aChangedIdle.Start(); //launch this to happen on idle after cursor position will have been set
46 break;
47 }
48}
49
50void AutocompleteEdit::AddEntry( const OUString& rEntry )
51{
52 m_aEntries.push_back( rEntry );
53}
54
56{
57 m_aEntries.clear();
58 m_aMatching.clear();
59}
60
61IMPL_LINK_NOARG(AutocompleteEdit, TryAutoComplete, Timer *, void)
62{
63 OUString aCurText = m_xEntry->get_text();
64
65 int nStartPos, nEndPos;
66 m_xEntry->get_selection_bounds(nStartPos, nEndPos);
67 if (std::max(nStartPos, nEndPos) != aCurText.getLength())
68 return;
69
70 auto nLen = std::min(nStartPos, nEndPos);
71 aCurText = aCurText.copy( 0, nLen );
72 if( aCurText.isEmpty() )
73 return;
74
75 if( !m_aEntries.empty() )
76 {
77 if( Match( aCurText ) )
78 {
79 m_xEntry->set_text(m_aMatching[0]);
80 auto nNewLen = m_aMatching[0].getLength();
81 m_xEntry->select_region(nLen, nNewLen);
82 }
83 }
84}
85
86bool AutocompleteEdit::Match( std::u16string_view rText )
87{
88 bool bRet = false;
89
90 m_aMatching.clear();
91
92 for(const OUString & rEntry : m_aEntries)
93 {
94 if( rEntry.startsWithIgnoreAsciiCase( rText ) )
95 {
96 m_aMatching.push_back( rEntry );
97 bRet = true;
98 }
99 }
100
101 return bRet;
102}
103
104/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
IMPL_LINK(AutocompleteEdit, KeyInputHdl, const KeyEvent &, rKEvt, bool)
IMPL_LINK_NOARG(AutocompleteEdit, ChangedHdl, weld::Entry &, void)
std::vector< OUString > m_aEntries
AutocompleteEdit(std::unique_ptr< weld::Entry > xEntry)
std::unique_ptr< weld::Entry > m_xEntry
bool Match(std::u16string_view rText)
void AddEntry(const OUString &rEntry)
std::vector< OUString > m_aMatching
void SetInvokeHandler(const Link< Timer *, void > &rLink)
constexpr sal_uInt16 KEY_DELETE
constexpr sal_uInt16 KEY_BACKSPACE