KiCad PCB EDA Suite
pcbnew/dialogs/dialog_global_edit_text_and_graphics.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) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU 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, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <string_utils.h>
26#include <board_commit.h>
27#include <pcb_edit_frame.h>
30#include <pcbnew.h>
31#include <board.h>
33#include <footprint.h>
34#include <pcb_group.h>
35#include <pcb_dimension.h>
36#include <fp_shape.h>
37#include <pcb_text.h>
38#include <widgets/unit_binder.h>
39#include <widgets/font_choice.h>
40#include <tool/tool_manager.h>
45
46// Columns of layer classes grid
47enum
48{
56};
57
58enum
59{
67};
68
69
71static bool g_modifyValues;
76static bool g_filterByLayer;
77static int g_layerFilter;
79static wxString g_referenceFilter;
81static wxString g_footprintFilter;
82static bool g_filterSelected = false;
83
84
86{
91
96
97public:
100
101protected:
102 void onActionButtonChange( wxCommandEvent& event ) override;
103 void onSpecifiedValueUpdateUI( wxUpdateUIEvent& event ) override;
104 void onDimensionItemCheckbox( wxCommandEvent& aEvent ) override;
105
106 void OnLayerFilterSelect( wxCommandEvent& event ) override
107 {
108 m_layerFilterOpt->SetValue( true );
109 }
110 void OnReferenceFilterText( wxCommandEvent& event ) override
111 {
112 m_referenceFilterOpt->SetValue( true );
113 }
114 void OnFootprintFilterText( wxCommandEvent& event ) override
115 {
116 m_footprintFilterOpt->SetValue( true );
117 }
118
119 bool TransferDataToWindow() override;
120 bool TransferDataFromWindow() override;
121
122 void visitItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem );
123 void processItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem );
124};
125
126
129 m_lineWidth( parent, m_lineWidthLabel, m_LineWidthCtrl, m_lineWidthUnits ),
130 m_textWidth( parent, m_SizeXlabel, m_SizeXCtrl, m_SizeXunit ),
131 m_textHeight( parent, m_SizeYlabel, m_SizeYCtrl, m_SizeYunit ),
132 m_thickness( parent, m_ThicknessLabel, m_ThicknessCtrl, m_ThicknessUnit )
133{
134 m_parent = parent;
135 m_brdSettings = &m_parent->GetDesignSettings();
136 m_isBoardEditor = dynamic_cast<PCB_EDIT_FRAME*>( m_parent ) != nullptr;
137
138 if( !m_isBoardEditor )
139 {
140 m_otherFields->SetLabel( _( "Other text items" ) );
141 m_footprintGraphics->SetLabel( _( "Graphic items" ) );
142 m_footprintDimensions->SetLabel( _( "Dimension items" ) );
143
144 m_boardText->Show( false );
145 m_boardGraphics->Show( false );
146
147 m_referenceFilterOpt->Show( false );
148 m_referenceFilter->Show( false );
149 m_footprintFilterOpt->Show( false );
150 m_footprintFilter->Show( false );
151 }
152
156
161
162 m_grid->SetCellHighlightPenWidth( 0 );
163 m_grid->SetDefaultCellFont( KIUI::GetInfoFont( this ) );
164
166
168}
169
170
172{
173 g_modifyReferences = m_references->GetValue();
174 g_modifyValues = m_values->GetValue();
177
178 if( m_isBoardEditor )
179 {
180 g_modifyBoardText = m_boardText->GetValue();
182 }
183
184 g_filterByLayer = m_layerFilterOpt->GetValue();
186
187 if( m_isBoardEditor )
188 {
193 }
194
196}
197
198
200{
202 m_selection = selTool->GetSelection();
203
204 m_references->SetValue( g_modifyReferences );
205 m_values->SetValue( g_modifyValues );
208
209 if( m_isBoardEditor )
210 {
211 m_boardText->SetValue( g_modifyBoardText );
213 }
214
215 if( m_layerFilter->SetLayerSelection( g_layerFilter ) != wxNOT_FOUND )
217
218 if( m_isBoardEditor )
219 {
220 // SetValue() generates events, ChangeValue() does not
221 m_referenceFilter->ChangeValue( g_referenceFilter );
223 m_footprintFilter->ChangeValue( g_footprintFilter );
225 }
226
228
230
232 m_fontCtrl->SetStringSelection( INDETERMINATE_ACTION );
233
237 m_bold->Set3StateValue( wxCHK_UNDETERMINED );
238 m_italic->Set3StateValue( wxCHK_UNDETERMINED );
239 m_keepUpright->Set3StateValue( wxCHK_UNDETERMINED );
240 m_visible->Set3StateValue( wxCHK_UNDETERMINED );
242
243#define SET_INT_VALUE( aRow, aCol, aValue ) \
244 m_grid->SetCellValue( aRow, aCol, m_parent->StringFromValue( aValue, true ) )
245
246#define SET_BOOL_VALUE( aRow, aCol, aValue ) \
247 attr = new wxGridCellAttr; \
248 attr->SetRenderer( new wxGridCellBoolRenderer() ); \
249 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); \
250 attr->SetReadOnly(); \
251 m_grid->SetAttr( aRow, aCol, attr ); \
252 m_grid->SetCellValue( aRow, aCol, ( aValue ) ? wxT( "1" ) : wxT( "" ) )
253
254 const BOARD_DESIGN_SETTINGS& bds = m_parent->GetBoard()->GetDesignSettings();
255 wxGridCellAttr* attr;
256
257 m_grid->SetCellValue( ROW_SILK, COL_CLASS_NAME, _( "Silk Layers" ) );
258 m_grid->SetCellValue( ROW_COPPER, COL_CLASS_NAME, _( "Copper Layers" ) );
259 m_grid->SetCellValue( ROW_EDGES, COL_CLASS_NAME, _( "Edge Cuts" ) );
260 m_grid->SetCellValue( ROW_COURTYARD, COL_CLASS_NAME, _( "Courtyards" ) );
261 m_grid->SetCellValue( ROW_FAB, COL_CLASS_NAME, _( "Fab Layers" ) );
262 m_grid->SetCellValue( ROW_OTHERS, COL_CLASS_NAME, _( "Other Layers" ) );
263
264 m_grid->SetCellValue( ROW_HEADER, COL_LINE_THICKNESS, _( "Line Thickness" ) );
271
272 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_WIDTH, _( "Text Width" ) );
277
278 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_HEIGHT, _( "Text Height" ) );
283
284 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_THICKNESS, _( "Text Thickness" ) );
289
290 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_ITALIC, _( "Italic" ) );
295
296 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_UPRIGHT, _( "Upright" ) );
301
302 return true;
303
304#undef SET_INT_VALUE
305#undef SET_BOOL_VALUE
306}
307
308
310{
311 // Update the UNIT_BINDER controls if the action to take is changed
312 bool enable = m_setToSpecifiedValues->GetValue();
313
314 m_lineWidth.Enable( enable );
315 m_textWidth.Enable( enable );
316 m_textHeight.Enable( enable );
317 m_thickness.Enable( enable );
318}
319
320
322{
323 // Update the UI for the elements inside the use specified values sizer
324 event.Enable( m_setToSpecifiedValues->GetValue() );
325}
326
327
329{
330 if( m_footprintDimensions->GetValue() || m_boardDimensions->GetValue() )
331 m_setToLayerDefaults->SetLabel( _( "Set to layer and dimension default values:" ) );
332 else
333 m_setToLayerDefaults->SetLabel( _( "Set to layer default values:" ) );
334}
335
336
338{
339 aCommit.Modify( aItem );
340
341 EDA_TEXT* edaText = dynamic_cast<EDA_TEXT*>( aItem );
342 FP_TEXT* fpText = dynamic_cast<FP_TEXT*>( aItem );
343 PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem );
344 PCB_DIMENSION_BASE* dimension = dynamic_cast<PCB_DIMENSION_BASE*>( aItem );
345
346 if( m_setToSpecifiedValues->GetValue() )
347 {
350
351 if( edaText )
352 {
354 edaText->SetTextSize( VECTOR2I( m_textWidth.GetValue(), edaText->GetTextSize().y ) );
355
357 edaText->SetTextSize( VECTOR2I( edaText->GetTextSize().x, m_textHeight.GetValue() ) );
358
361
362 if( m_bold->Get3StateValue() != wxCHK_UNDETERMINED )
363 edaText->SetBold( m_bold->GetValue() );
364
365 if( m_italic->Get3StateValue() != wxCHK_UNDETERMINED )
366 edaText->SetItalic( m_italic->GetValue() );
367
368 // Must come after setting bold & italic
369 if( m_fontCtrl->GetStringSelection() != INDETERMINATE_ACTION )
370 {
371 edaText->SetFont( m_fontCtrl->GetFontSelection( edaText->IsBold(),
372 edaText->IsItalic() ) );
373 }
374 else if(( m_italic->Get3StateValue() != wxCHK_UNDETERMINED
375 || m_bold->Get3StateValue() != wxCHK_UNDETERMINED ) )
376 {
377 wxString fontName = edaText->GetFontName();
378
379 if( !edaText->GetFontName().IsEmpty() )
380 {
381 edaText->SetFont( KIFONT::FONT::GetFont( edaText->GetFontName(),
382 edaText->IsBold(),
383 edaText->IsItalic() ) );
384 }
385 }
386
387 if( m_visible->Get3StateValue() != wxCHK_UNDETERMINED )
388 edaText->SetVisible( m_visible->GetValue() );
389 }
390
391 if( fpText )
392 {
393 if( m_keepUpright->Get3StateValue() != wxCHK_UNDETERMINED )
394 fpText->SetKeepUpright( m_keepUpright->GetValue() );
395 }
396
398 {
399 if( shape )
400 {
401 STROKE_PARAMS stroke = shape->GetStroke();
402 stroke.SetWidth( m_lineWidth.GetValue() );
403 shape->SetStroke( stroke );
404 }
405
406 if( dimension )
407 dimension->SetLineThickness( m_lineWidth.GetValue() );
408 }
409 }
410 else
411 {
412 PCB_LAYER_ID layer = aItem->GetLayer();
413
414 if( edaText )
415 {
416 edaText->SetTextSize( m_brdSettings->GetTextSize( layer ) );
417 edaText->SetTextThickness( m_brdSettings->GetTextThickness( layer ) );
418 edaText->SetItalic( m_brdSettings->GetTextItalic( layer ) );
419 }
420
421 if( fpText )
422 fpText->SetKeepUpright( m_brdSettings->GetTextUpright( layer ) );
423
424 if( shape )
425 {
426 STROKE_PARAMS stroke = shape->GetStroke();
427 stroke.SetWidth( m_brdSettings->GetLineThickness( layer ) );
428 shape->SetStroke( stroke );
429 }
430
431 if( dimension )
432 {
433 dimension->SetLineThickness( m_brdSettings->GetLineThickness( layer ) );
440 dimension->Update(); // refresh text & geometry
441 }
442 }
443}
444
445
447{
448 if( m_selectedItemsFilter->GetValue() )
449 {
450 BOARD_ITEM* candidate = aItem;
451
452 if( !candidate->IsSelected() )
453 {
454 if( candidate->GetParent() && candidate->GetParent()->Type() == PCB_FOOTPRINT_T )
455 candidate = candidate->GetParent();
456 }
457
458 if( !candidate->IsSelected() )
459 {
460 candidate = candidate->GetParentGroup();
461
462 while( candidate && !candidate->IsSelected() )
463 candidate = candidate->GetParentGroup();
464
465 if( !candidate )
466 return;
467 }
468 }
469
471 {
472 if( aItem->GetLayer() != m_layerFilter->GetLayerSelection() )
473 return;
474 }
475
476 if( m_isBoardEditor )
477 {
478 if( m_referenceFilterOpt->GetValue() && !m_referenceFilter->GetValue().IsEmpty() )
479 {
480 FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( aItem->GetParent() );
481
482 if( fp )
483 {
484 if( !WildCompareString( m_referenceFilter->GetValue(), fp->GetReference(), false ) )
485 return;
486 }
487 }
488
489 if( m_footprintFilterOpt->GetValue() && !m_footprintFilter->GetValue().IsEmpty() )
490 {
491 FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( aItem->GetParent() );
492
493 if( fp )
494 {
495 if( !WildCompareString( m_footprintFilter->GetValue(), fp->GetFPID().Format(), false ) )
496 return;
497 }
498 }
499 }
500
501 processItem( aCommit, aItem );
502}
503
504
506{
509 {
510 return false;
511 }
512
513 BOARD_COMMIT commit( m_parent );
514
515 // Go through the footprints
516 for( FOOTPRINT* fp : m_parent->GetBoard()->Footprints() )
517 {
518 if( m_references->GetValue() )
519 visitItem( commit, &fp->Reference() );
520
521 if( m_values->GetValue() )
522 visitItem( commit, &fp->Value() );
523
524 // Go through all other footprint items
525 for( BOARD_ITEM* boardItem : fp->GraphicalItems() )
526 {
527 KICAD_T itemType = boardItem->Type();
528
529 if( itemType == PCB_FP_TEXT_T || itemType == PCB_FP_TEXTBOX_T )
530 {
531 if( m_otherFields->GetValue() )
532 visitItem( commit, boardItem );
533 }
534 else if( BaseType( itemType ) == PCB_DIMENSION_T )
535 {
536 if( m_footprintDimensions->GetValue() )
537 visitItem( commit, boardItem );
538 }
539 else if( itemType == PCB_FP_SHAPE_T )
540 {
541 if( m_footprintGraphics->GetValue() )
542 visitItem( commit, boardItem );
543 }
544 }
545 }
546
547 if( m_isBoardEditor )
548 {
549 // Go through the PCB text & graphic items
550 for( BOARD_ITEM* boardItem : m_parent->GetBoard()->Drawings() )
551 {
552 KICAD_T itemType = boardItem->Type();
553
554 if( itemType == PCB_TEXT_T || itemType == PCB_TEXTBOX_T )
555 {
556 if( m_boardText->GetValue() )
557 visitItem( commit, boardItem );
558 }
559 else if( BaseType( itemType ) == PCB_DIMENSION_T )
560 {
561 if( m_boardDimensions->GetValue() )
562 visitItem( commit, boardItem );
563 }
564 else if( itemType == PCB_SHAPE_T || BaseType( itemType ) == PCB_DIMENSION_T )
565 {
566 if( m_boardGraphics->GetValue() )
567 visitItem( commit, boardItem );
568 }
569 }
570 }
571
572 commit.Push( wxT( "Edit text and graphics properties" ) );
574
575 return true;
576}
577
578
580{
581 PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
583
584 dlg.ShowModal();
585 return 0;
586}
587
588
590{
591 FOOTPRINT_EDIT_FRAME* editFrame = getEditFrame<FOOTPRINT_EDIT_FRAME>();
593
594 dlg.ShowModal();
595 return 0;
596}
597
598
@ LAYER_CLASS_OTHERS
@ LAYER_CLASS_FAB
@ LAYER_CLASS_COURTYARD
@ LAYER_CLASS_SILK
@ LAYER_CLASS_COPPER
@ LAYER_CLASS_EDGES
Container for design settings for a BOARD object.
DIM_PRECISION m_DimensionPrecision
Number of digits after the decimal.
DIM_UNITS_FORMAT m_DimensionUnitsFormat
bool GetTextUpright(PCB_LAYER_ID aLayer) const
int GetTextThickness(PCB_LAYER_ID aLayer) const
Return the default text thickness from the layer class for the given layer.
bool m_TextUpright[LAYER_CLASS_COUNT]
bool GetTextItalic(PCB_LAYER_ID aLayer) const
int m_TextThickness[LAYER_CLASS_COUNT]
int m_LineThickness[LAYER_CLASS_COUNT]
VECTOR2I GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
VECTOR2I m_TextSize[LAYER_CLASS_COUNT]
bool m_TextItalic[LAYER_CLASS_COUNT]
DIM_TEXT_POSITION m_DimensionTextPosition
DIM_UNITS_MODE m_DimensionUnitsMode
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:70
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:192
PCB_GROUP * GetParentGroup() const
Definition: board_item.h:84
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:226
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:175
COMMIT & Modify(EDA_ITEM *aItem)
Create an undo entry for an item that has been already modified.
Definition: commit.h:103
void visitItem(const SCH_SHEET_PATH &aSheetPath, SCH_ITEM *aItem)
void processItem(const SCH_SHEET_PATH &aSheetPath, SCH_ITEM *aItem)
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...
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
bool IsSelected() const
Definition: eda_item.h:106
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:72
wxString GetFontName() const
Definition: eda_text.cpp:759
bool IsItalic() const
Definition: eda_text.h:130
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:219
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:187
void SetBold(bool aBold)
Definition: eda_text.cpp:211
bool IsBold() const
Definition: eda_text.h:133
void SetKeepUpright(bool aKeepUpright)
Definition: eda_text.cpp:258
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:349
void SetItalic(bool aItalic)
Definition: eda_text.cpp:203
void SetFont(KIFONT::FONT *aFont)
Definition: eda_text.cpp:333
VECTOR2I GetTextSize() const
Definition: eda_text.h:196
KIFONT::FONT * GetFontSelection(bool aBold, bool aItalic) const
const LIB_ID & GetFPID() const
Definition: footprint.h:212
const wxString & GetReference() const
Definition: footprint.h:519
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
Definition: font.cpp:138
int SetLayerSelection(int layer)
bool SetLayersHotkeys(bool value)
UTF8 Format() const
Definition: lib_id.cpp:117
Common, abstract interface for edit frames.
Abstract dimension API.
void Update()
Update the dimension's cached text and geometry.
void SetUnitsFormat(const DIM_UNITS_FORMAT aFormat)
void SetSuppressZeroes(bool aSuppress)
void SetTextPositionMode(DIM_TEXT_POSITION aMode)
void SetLineThickness(int aWidth)
void SetPrecision(DIM_PRECISION aPrecision)
void SetUnitsMode(DIM_UNITS_MODE aMode)
void SetKeepTextAligned(bool aKeepAligned)
The main frame for Pcbnew.
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
void SetUndefinedLayerName(const wxString &aName)
The selection tool: currently supports:
PCB_SELECTION & GetSelection()
STROKE_PARAMS GetStroke() const override
Definition: pcb_shape.h:71
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:72
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
Simple container to manage line stroke parameters.
Definition: stroke_params.h:88
void SetWidth(int aWidth)
Definition: stroke_params.h:99
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:54
Generic, UI-independent tool event.
Definition: tool_event.h:156
virtual long long int GetValue()
Return the current value in Internal Units.
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
bool IsIndeterminate() const
Return true if the control holds the indeterminate value (for instance, if it represents a multiple s...
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED)
Validate the control against the given range, informing the user of any errors found.
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
#define _(s)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ UNDEFINED_LAYER
Definition: layer_ids.h:60
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:932
wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:156
#define SET_INT_VALUE(aRow, aCol, aValue)
#define SET_BOOL_VALUE(aRow, aCol, aValue)
#define TEXTS_MAX_SIZE
Maximum text size in internal units (10 inches)
Definition: pcbnew.h:32
#define TEXTS_MIN_SIZE
Minimum text size in internal units (1 mil)
Definition: pcbnew.h:31
bool WildCompareString(const wxString &pattern, const wxString &string_to_tst, bool case_sensitive)
Compare a string against wild card (* and ?) pattern using the usual rules.
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition: typeinfo.h:253
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_FP_SHAPE_T
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
@ PCB_FP_TEXTBOX_T
class FP_TEXTBOX, wrapped text in a footprint
Definition: typeinfo.h:93
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:91
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:90
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ PCB_FP_TEXT_T
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition: typeinfo.h:105
#define INDETERMINATE_ACTION
Definition: ui_common.h:43