KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_executecommand_job_settings.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) 2024 Mark Roszko <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
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
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
24#include <scintilla_tricks.h>
25#include <grid_tricks.h>
26#include <project.h>
27#include <env_vars.h>
28#include <common.h>
29#include <widgets/ui_common.h>
30#include <wx/regex.h>
31
32
34 PROJECT* aProject ) :
36 m_job( aJob ),
37 m_project( aProject ),
38 m_lastFocusedInput( nullptr ),
39 m_scintillaTricks( nullptr )
40{
41 m_textCtrlCommand->SetWrapMode( wxSTC_WRAP_CHAR );
42
44
45 m_scintillaTricks = new SCINTILLA_TRICKS( m_textCtrlCommand, wxT( "{}" ), false,
46 // onAcceptFn
47 [this]( wxKeyEvent& aEvent )
48 {
49 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
50 },
51
52 // onCharFn
53 [this]( wxStyledTextEvent& aEvent )
54 {
55 m_scintillaTricks->DoTextVarAutocomplete(
56 // getTokensFn
57 [this]( const wxString& xRef, wxArrayString* tokens )
58 {
60 tokens->Add( OUTPUT_TMP_PATH_VAR_NAME );
61
62 if( m_project )
63 {
64 for( const auto& [varName, varValue] : m_project->GetTextVars() )
65 {
66 if( tokens->Index( varName ) == wxNOT_FOUND )
67 tokens->Add( varName );
68 }
69 }
70 } );
71 } );
72
73 // add Cut, Copy, and Paste to wxGrids
74 m_path_subs_grid->PushEventHandler( new GRID_TRICKS( m_path_subs_grid ) );
75
77
79
80 m_textCtrlCommand->Bind( wxEVT_SET_FOCUS,
81 [this]( wxFocusEvent& aEvent )
82 {
84 aEvent.Skip();
85 } );
86
87 m_textCtrlOutputPath->Bind( wxEVT_SET_FOCUS,
88 [this]( wxFocusEvent& aEvent )
89 {
91 aEvent.Skip();
92 } );
93
94 m_path_subs_grid->Bind( wxEVT_GRID_CELL_LEFT_DCLICK, &DIALOG_EXECUTECOMMAND_JOB_SETTINGS::onVarGridDClick, this );
95
97
98 // keep the grid at 10 rows, it scrolls for more
99 m_path_subs_grid->SetMinSize( wxSize( -1, m_path_subs_grid->GetDefaultRowSize() * 10 ) );
100
101 m_path_subs_grid->SetColLabelValue( 0, _( "Name" ) );
102 m_path_subs_grid->SetColLabelValue( 1, _( "Value" ) );
103
105
107}
108
109
111{
112 delete m_scintillaTricks;
113 m_scintillaTricks = nullptr;
114
115 // Delete the GRID_TRICKS.
116 m_path_subs_grid->PopEventHandler( true );
117}
118
119
121{
122 m_job->m_command = m_textCtrlCommand->GetValue();
123 m_job->m_ignoreExitcode = m_cbIgnoreExitCode->GetValue();
124 m_job->m_recordOutput = m_cbRecordOutput->GetValue();
125 m_job->SetConfiguredOutputPath( m_textCtrlOutputPath->GetValue() );
126
127 return true;
128}
129
130
132{
133 m_textCtrlCommand->SetValue( m_job->m_command );
134 m_cbIgnoreExitCode->SetValue( m_job->m_ignoreExitcode );
135 m_cbRecordOutput->SetValue( m_job->m_recordOutput );
136
137 m_textCtrlOutputPath->SetValue( m_job->GetConfiguredOutputPath() );
138 m_textCtrlOutputPath->Enable( m_cbRecordOutput->GetValue() );
139
142
143 return true;
144}
145
146
148{
149 m_textCtrlOutputPath->Enable( m_cbRecordOutput->GetValue() );
150}
151
152
154{
157 aEvent.Skip();
158}
159
160
165
166
168{
169 int row = aEvent.GetRow();
170
171 if( row < 0 || row >= m_path_subs_grid->GetNumberRows() )
172 return;
173
174 wxString token = m_path_subs_grid->GetCellValue( row, 0 );
175
177 m_textCtrlOutputPath->WriteText( token );
178 else
179 m_textCtrlCommand->ReplaceSelection( token );
180}
181
182
184{
185 wxRegEx re( ".*?(\\$\\{(.+?)\\})|(\\$\\((.+?)\\)).*?", wxRE_ADVANCED );
186 wxASSERT( re.IsValid() ); // wxRE_ADVANCED is required.
187
188 std::set<wxString> unique;
189 wxString src = m_textCtrlCommand->GetValue();
190
191 // clear the table
192 m_path_subs_grid->ClearRows();
193
194 // all configured path and environment variables
195 wxArrayString envTokens;
197
198 for( const wxString& token : envTokens )
199 unique.insert( token );
200
201 // project text variables
202 if( m_project )
203 {
204 for( const auto& [varName, varValue] : m_project->GetTextVars() )
205 unique.insert( varName );
206 }
207
208 // variables referenced in the command, including undefined ones
209 while( re.Matches( src ) )
210 {
211 wxString envvar = re.GetMatch( src, 2 );
212
213 // if not ${...} form then must be $(...)
214 if( envvar.IsEmpty() )
215 envvar = re.GetMatch( src, 4 );
216
217 // ignore duplicates
218 unique.insert( envvar );
219
220 // delete the last match and search again
221 src.Replace( re.GetMatch( src, 0 ), wxEmptyString );
222 }
223
224 // Make sure these variables shows up even if not used yet.
225 unique.insert( OUTPUT_TMP_PATH_VAR_NAME );
226 unique.insert( PROJECT_VAR_NAME );
227
228 for( const wxString& evName : unique )
229 {
230 int row = m_path_subs_grid->GetNumberRows();
231 m_path_subs_grid->AppendRows( 1 );
232
233 m_path_subs_grid->SetCellValue( row, 0, wxT( "${" ) + evName + wxT( "}" ) );
234 m_path_subs_grid->SetCellEditor( row, 0, new GRID_CELL_READONLY_TEXT_EDITOR() );
235
236 wxString evValue;
237
238 if( evName.IsSameAs( OUTPUT_TMP_PATH_VAR_NAME ) )
239 {
240 evValue = _( "<value set at runtime>" );
241 m_path_subs_grid->SetCellFont( row, 1, m_path_subs_grid->GetCellFont( row, 1 ).Italic() );
242 }
243 else
244 {
245 // resolve the same way the job runner will
246 wxString token = wxT( "${" ) + evName + wxT( "}" );
247 evValue = ExpandEnvVarSubstitutions( token, m_project );
248
249 if( evValue == token )
250 evValue = wxEmptyString;
251 }
252
253 m_path_subs_grid->SetCellValue( row, 1, evValue );
254 m_path_subs_grid->SetCellEditor( row, 1, new GRID_CELL_READONLY_TEXT_EDITOR() );
255 }
256
257 adjustPathSubsGridColumns( m_path_subs_grid->GetRect().GetWidth() );
258}
259
260
262{
263 // Account for scroll bars
264 aWidth -= ( m_path_subs_grid->GetSize().x - m_path_subs_grid->GetClientSize().x );
265
266 m_path_subs_grid->AutoSizeColumn( 0 );
267 m_path_subs_grid->SetColSize( 0, std::max( 200, m_path_subs_grid->GetColSize( 0 ) ) );
268 m_path_subs_grid->SetColSize( 1, std::max( 300, aWidth - m_path_subs_grid->GetColSize( 0 ) ) );
269}
270
271
273{
274 adjustPathSubsGridColumns( event.GetSize().GetX() );
275
276 event.Skip();
277}
278
279
DIALOG_EXECUTECOMMAND_JOB_SETTINGS_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Execute Command Job Settings"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
DIALOG_EXECUTECOMMAND_JOB_SETTINGS(wxWindow *aParent, JOB_SPECIAL_EXECUTE *aJob, PROJECT *aProject)
void populateEnvironReadOnlyTable()
Fill the variable table with the available variables and any referenced in the command,...
void updateExpandedPreview()
Show the command with variables expanded as the job runner will run it.
void OnRecordOutputClicked(wxCommandEvent &event) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition grid_tricks.h:57
Container for project specific data.
Definition project.h:63
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition common.cpp:776
#define _(s)
Functions related to environment variables, including help functions.
#define OUTPUT_TMP_PATH_VAR_NAME
KICOMMON_API void GetEnvVarAutocompleteTokens(wxArrayString *aVars)
Return autocomplete tokens for environment variables for Scintilla.
Definition env_vars.cpp:68
KICOMMON_API wxFont GetMonospacedUIFont(int aRelativeSize=0)
Definition ui_common.cpp:93
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
Definition project.h:38
Functions to provide common constants and other functions to assist in making a consistent UI.