KiCad PCB EDA Suite
grid_text_helpers.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
5 * @author Jon Evans <[email protected]>
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <string_utils.h>
22#include <wx/stc/stc.h>
24#include <scintilla_tricks.h>
25
26
27//-------- GRID_CELL_ESCAPED_TEXT_RENDERER ------------------------------------------------------
28//
29
31 wxGridCellStringRenderer()
32{
33}
34
35void GRID_CELL_ESCAPED_TEXT_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC,
36 const wxRect& aRect, int aRow, int aCol,
37 bool isSelected )
38{
39 wxString unescaped = UnescapeString( aGrid.GetCellValue( aRow, aCol ) );
40
41 wxRect rect = aRect;
42 rect.Inflate( -1 );
43
44 // erase background
45 wxGridCellRenderer::Draw( aGrid, aAttr, aDC, aRect, aRow, aCol, isSelected );
46
47 SetTextColoursAndFont( aGrid, aAttr, aDC, isSelected );
48 aGrid.DrawTextRectangle( aDC, unescaped, rect, wxALIGN_LEFT, wxALIGN_CENTRE );
49}
50
51
52wxSize GRID_CELL_ESCAPED_TEXT_RENDERER::GetBestSize( wxGrid & aGrid, wxGridCellAttr & aAttr,
53 wxDC & aDC, int aRow, int aCol )
54{
55 wxString unescaped = UnescapeString( aGrid.GetCellValue( aRow, aCol ) );
56 return wxGridCellStringRenderer::DoGetBestSize( aAttr, aDC, unescaped );
57}
58
59
60//-------- GRID_CELL_STC_EDITOR -----------------------------------------------------------------
61//
62
64 std::function<void( wxStyledTextEvent&,
65 SCINTILLA_TRICKS* )> aOnChar ) :
66 m_scintillaTricks( nullptr ),
67 m_ignoreCase( aIgnoreCase ),
68 m_onChar( aOnChar )
69{ }
70
71
72void GRID_CELL_STC_EDITOR::Create( wxWindow* aParent, wxWindowID aId, wxEvtHandler* aEventHandler )
73{
74 m_control = new wxStyledTextCtrl( aParent );
75
76 stc_ctrl()->SetTabIndents( false );
77 stc_ctrl()->SetBackSpaceUnIndents( false );
78 stc_ctrl()->SetViewEOL( false );
79 stc_ctrl()->SetViewWhiteSpace( false );
80 stc_ctrl()->SetIndentationGuides( false );
81 stc_ctrl()->SetMarginWidth( 0, 0 ); // Symbol margin
82 stc_ctrl()->SetMarginWidth( 1, 0 ); // Line-number margin
83 stc_ctrl()->SetEOLMode( wxSTC_EOL_LF );
84 stc_ctrl()->AutoCompSetMaxWidth( 25 );
85 stc_ctrl()->AutoCompSetIgnoreCase( m_ignoreCase );
86 stc_ctrl()->UsePopUp( 0 );
87
88 // A hack which causes Scintilla to auto-size the text editor canvas
89 // See: https://github.com/jacobslusser/ScintillaNET/issues/216
90 stc_ctrl()->SetScrollWidth( 1 );
91 stc_ctrl()->SetScrollWidthTracking( true );
92
94 stc_ctrl(), wxEmptyString, true,
95 [this]()
96 {
97 stc_ctrl()->AutoCompComplete();
98 },
99 [this]( wxStyledTextEvent& aEvent )
100 {
101 m_onChar( aEvent, m_scintillaTricks );
102 } );
103
104 stc_ctrl()->Bind( wxEVT_KILL_FOCUS, &GRID_CELL_STC_EDITOR::onFocusLoss, this );
105
106 wxGridCellEditor::Create( aParent, aId, aEventHandler );
107}
108
109
110wxStyledTextCtrl* GRID_CELL_STC_EDITOR::stc_ctrl() const
111{
112 return static_cast<wxStyledTextCtrl*>( m_control );
113}
114
115
117{
118 return stc_ctrl()->GetText();
119}
120
121
122void GRID_CELL_STC_EDITOR::Show( bool aShow, wxGridCellAttr* aAttr )
123{
124 if( !aShow )
125 stc_ctrl()->AutoCompCancel();
126
127 wxGridCellEditor::Show( aShow, aAttr );
128}
129
130
131void GRID_CELL_STC_EDITOR::BeginEdit( int aRow, int aCol, wxGrid* aGrid )
132{
133 auto evtHandler = static_cast<wxGridCellEditorEvtHandler*>( m_control->GetEventHandler()
134 );
135
136 // Don't immediately end if we get a kill focus event within BeginEdit
137 evtHandler->SetInSetFocus( true );
138
139 m_value = aGrid->GetTable()->GetValue( aRow, aCol );
140
141 stc_ctrl()->SetFocus();
142 stc_ctrl()->SetText( m_value );
143 stc_ctrl()->SelectAll();
144}
145
146
147bool GRID_CELL_STC_EDITOR::EndEdit( int, int, const wxGrid*, const wxString&, wxString *aNewVal )
148{
149 const wxString value = stc_ctrl()->GetText();
150
151 if( value == m_value )
152 return false;
153
154 m_value = value;
155
156 if( aNewVal )
157 *aNewVal = value;
158
159 return true;
160}
161
162
163void GRID_CELL_STC_EDITOR::ApplyEdit( int aRow, int aCol, wxGrid* aGrid )
164{
165 aGrid->GetTable()->SetValue( aRow, aCol, m_value );
166}
167
168
169void GRID_CELL_STC_EDITOR::onFocusLoss( wxFocusEvent& aEvent )
170{
171 if( stc_ctrl() )
172 stc_ctrl()->AutoCompCancel();
173
174 aEvent.Skip();
175}
wxSize GetBestSize(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, int row, int col) override
void Draw(wxGrid &aGrid, wxGridCellAttr &aAttr, wxDC &aDC, const wxRect &aRect, int aRow, int aCol, bool isSelected) override
void ApplyEdit(int aRow, int aCol, wxGrid *aGrid) override
void onFocusLoss(wxFocusEvent &aEvent)
GRID_CELL_STC_EDITOR(bool aIgnoreCase, std::function< void(wxStyledTextEvent &, SCINTILLA_TRICKS *)> aOnChar)
bool EndEdit(int aRow, int aCol, const wxGrid *, const wxString &, wxString *aNewVal) override
void BeginEdit(int aRow, int aCol, wxGrid *aGrid) override
wxString GetValue() const override
void Create(wxWindow *aParent, wxWindowID aId, wxEvtHandler *aEventHandler) override
void Show(bool aShow, wxGridCellAttr *aAttr=nullptr) override
wxStyledTextCtrl * stc_ctrl() const
std::function< void(wxStyledTextEvent &, SCINTILLA_TRICKS *)> m_onChar
SCINTILLA_TRICKS * m_scintillaTricks
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
wxString UnescapeString(const wxString &aSource)