Compare commits

..

10 Commits

Author SHA1 Message Date
Mike Williams 9389a2b7c5 design blocks: cross-editor notification of library actions 2025-02-05 12:20:17 -05:00
Mike Williams 97aa507dd4 design blocks: commonize tool control functionality 2025-02-05 10:28:59 -05:00
Mike Williams eed62789a8 design blocks: check for library existence in table dialog 2025-02-04 09:27:31 -05:00
Mike Williams 17a29794a1 pcb design blocks: add place (repeated, grouped) functionality 2025-02-04 09:27:31 -05:00
Mike Williams c49a9497ff pcb design blocks: PCB save selection as design block 2025-02-04 09:27:31 -05:00
Mike Williams 362366d6f5 pcb design blocks: create from board working-ish and block preview 2025-02-04 09:27:31 -05:00
Mike Williams 372a9c3f51 pcbnew: move extension ensurance up a level 2025-02-04 09:27:31 -05:00
Mike Williams 8c2a6fc818 pcb: don't show informational message on successful save 2025-02-04 09:27:31 -05:00
Mike Williams 7054963d90 PCB editor: add design block panel 2025-02-04 09:27:31 -05:00
Mike Williams b894e7fe91 design blocks: commonize a lot of the code in prep for PCB blocks 2025-02-04 09:27:31 -05:00
1343 changed files with 350863 additions and 4180660 deletions
-1
View File
@@ -51,7 +51,6 @@ common/pcb_keywords.cpp
include/pcb_lexer.h
fp-info-cache
qa/tests/output/**
qa/tests/cli/output/**
# demo project auxiliary files
demos/**/*-bak
+38 -9
View File
@@ -465,14 +465,26 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
const float zpos_copperTop_back = m_layerZcoordTop[B_Cu];
const float zpos_copperTop_front = m_layerZcoordTop[F_Cu];
// Fill not copper layers zpos
// Fill not copper layers zpos with a dummy position
// (m_layerZcoordTop[B_Cu]with a small margin)
// Some important layer position will be set later
for( int layer_id = 0; layer_id < PCB_LAYER_ID_COUNT; layer_id++ )
{
if( IsCopperLayer( (PCB_LAYER_ID)layer_id ) )
continue;
float zposBottom = zpos_copperTop_front + 2.0f * zpos_offset;
float zposTop = zposBottom + m_frontCopperThickness3DU;
m_layerZcoordBottom[(PCB_LAYER_ID)layer_id] = zpos_copperTop_back - 2.0f * zpos_offset;
m_layerZcoordTop[(PCB_LAYER_ID) layer_id] =
m_layerZcoordBottom[(PCB_LAYER_ID) layer_id] - m_backCopperThickness3DU;
}
// calculate z position for each technical layer
// Solder mask and Solder paste have the same Z position
for( PCB_LAYER_ID layer_id :
{ B_Adhes, B_Mask, B_Paste, F_Adhes, F_Mask, F_Paste, B_SilkS, F_SilkS } )
{
float zposTop = 0.0;
float zposBottom = 0.0;
switch( layer_id )
{
@@ -520,8 +532,8 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
break;
}
m_layerZcoordTop[(PCB_LAYER_ID)layer_id] = zposTop;
m_layerZcoordBottom[(PCB_LAYER_ID)layer_id] = zposBottom;
m_layerZcoordTop[layer_id] = zposTop;
m_layerZcoordBottom[layer_id] = zposBottom;
}
m_boardCenter = SFVEC3F( m_boardPos.x * m_biuTo3Dunits, m_boardPos.y * m_biuTo3Dunits, 0.0f );
@@ -833,10 +845,7 @@ std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetVisibleLayers() const
return ret;
const PCB_PLOT_PARAMS& plotParams = m_board->GetPlotOptions();
LSET layers = plotParams.GetLayerSelection();
for( PCB_LAYER_ID commonLayer : plotParams.GetPlotOnAllLayersSequence() )
layers.set( commonLayer );
LSET layers = plotParams.GetLayerSelection() | plotParams.GetPlotOnAllLayersSelection();
ret.set( LAYER_3D_BOARD, true );
ret.set( LAYER_3D_COPPER_TOP, layers.test( F_Cu ) );
@@ -860,6 +869,26 @@ std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetVisibleLayers() const
{
ret = preset->layers;
}
else
{
ret.set( LAYER_3D_BOARD, m_Cfg->m_Render.show_board_body );
ret.set( LAYER_3D_COPPER_TOP, m_Cfg->m_Render.show_copper_top );
ret.set( LAYER_3D_COPPER_BOTTOM, m_Cfg->m_Render.show_copper_bottom );
ret.set( LAYER_3D_SILKSCREEN_TOP, m_Cfg->m_Render.show_silkscreen_top );
ret.set( LAYER_3D_SILKSCREEN_BOTTOM, m_Cfg->m_Render.show_silkscreen_bottom );
ret.set( LAYER_3D_SOLDERMASK_TOP, m_Cfg->m_Render.show_soldermask_top );
ret.set( LAYER_3D_SOLDERMASK_BOTTOM, m_Cfg->m_Render.show_soldermask_bottom );
ret.set( LAYER_3D_SOLDERPASTE, m_Cfg->m_Render.show_solderpaste );
ret.set( LAYER_3D_ADHESIVE, m_Cfg->m_Render.show_adhesive );
ret.set( LAYER_3D_USER_COMMENTS, m_Cfg->m_Render.show_comments );
ret.set( LAYER_3D_USER_DRAWINGS, m_Cfg->m_Render.show_drawings );
ret.set( LAYER_3D_USER_ECO1, m_Cfg->m_Render.show_eco1 );
ret.set( LAYER_3D_USER_ECO2, m_Cfg->m_Render.show_eco2 );
ret.set( LAYER_FP_REFERENCES, m_Cfg->m_Render.show_fp_references );
ret.set( LAYER_FP_VALUES, m_Cfg->m_Render.show_fp_values );
ret.set( LAYER_FP_TEXT, m_Cfg->m_Render.show_fp_text );
}
return ret;
}
@@ -188,23 +188,23 @@ void BOARD_ADAPTER::addShape( const PCB_DIMENSION_BASE* aDimension, CONTAINER_2D
void BOARD_ADAPTER::addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aContainer,
PCB_LAYER_ID aLayerId,
const std::bitset<LAYER_3D_END>& aFlags )
const std::bitset<LAYER_3D_END>& aVisibilityFlags )
{
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
for( PCB_FIELD* field : aFootprint->GetFields( true /* visibleOnly */ ) )
for( PCB_FIELD* field : aFootprint->GetFields() )
{
if( !aFlags.test( LAYER_FP_TEXT ) )
continue;
if( field->GetLayer() == aLayerId && field->IsVisible() )
{
if( !aVisibilityFlags.test( LAYER_FP_TEXT ) )
continue;
else if( field->IsReference() && !aVisibilityFlags.test( LAYER_FP_REFERENCES ) )
continue;
else if( field->IsValue() && !aVisibilityFlags.test( LAYER_FP_VALUES ) )
continue;
if( field->IsReference() && !aFlags.test( LAYER_FP_REFERENCES ) )
continue;
if( field->IsValue() && !aFlags.test( LAYER_FP_VALUES ) )
continue;
if( field->GetLayer() == aLayerId )
addText( field, aContainer, field );
}
}
for( BOARD_ITEM* item : aFootprint->GraphicalItems() )
@@ -215,17 +215,19 @@ void BOARD_ADAPTER::addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2
{
PCB_TEXT* text = static_cast<PCB_TEXT*>( item );
if( !aFlags.test( LAYER_FP_TEXT ) )
continue;
if( text->GetLayer() == aLayerId && text->IsVisible() )
{
if( !aVisibilityFlags.test( LAYER_FP_TEXT ) )
continue;
else if( text->GetText() == wxT( "${REFERENCE}" )
&& !aVisibilityFlags.test( LAYER_FP_REFERENCES ) )
continue;
else if( text->GetText() == wxT( "${VALUE}" )
&& !aVisibilityFlags.test( LAYER_FP_VALUES ) )
continue;
if( text->GetText() == wxT( "${REFERENCE}" ) && !aFlags.test( LAYER_FP_REFERENCES ) )
continue;
if( text->GetText() == wxT( "${VALUE}" ) && !aFlags.test( LAYER_FP_VALUES ) )
continue;
if( text->GetLayer() == aLayerId )
addText( text, aContainer, text );
}
break;
}
@@ -281,7 +283,7 @@ void BOARD_ADAPTER::addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2
}
void BOARD_ADAPTER::createTrackWithMargin( const PCB_TRACK* aTrack,
void BOARD_ADAPTER::createTrackWithMargin( const PCB_TRACK* aTrack,
CONTAINER_2D_BASE* aDstContainer, PCB_LAYER_ID aLayer,
int aMargin )
{
@@ -791,18 +793,11 @@ void BOARD_ADAPTER::addShape( const PCB_TEXTBOX* aTextBox, CONTAINER_2D_BASE* aC
void BOARD_ADAPTER::addTable( const PCB_TABLE* aTable, CONTAINER_2D_BASE* aContainer,
const BOARD_ITEM* aOwner )
{
aTable->DrawBorders(
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB, const STROKE_PARAMS& stroke )
{
addROUND_SEGMENT_2D( aContainer, TO_SFVEC2F( ptA ), TO_SFVEC2F( ptB ),
TO_3DU( stroke.GetWidth() ), *aOwner );
} );
// JEY TODO: tables
// add borders
for( PCB_TABLECELL* cell : aTable->GetCells() )
{
if( cell->GetColSpan() > 0 && cell->GetRowSpan() > 0 )
addText( cell, aContainer, aOwner );
}
addText( cell, aContainer, aOwner );
}
+7 -69
View File
@@ -103,68 +103,6 @@ void transformFPShapesToPolySet( const FOOTPRINT* aFootprint, PCB_LAYER_ID aLaye
}
void transformFPTextToPolySet( const FOOTPRINT* aFootprint, PCB_LAYER_ID aLayer,
const std::bitset<LAYER_3D_END>& aFlags, SHAPE_POLY_SET& aBuffer,
int aMaxError, ERROR_LOC aErrorLoc )
{
for( BOARD_ITEM* item : aFootprint->GraphicalItems() )
{
if( item->GetLayer() != aLayer )
continue;
if( item->Type() == PCB_TEXT_T )
{
PCB_TEXT* text = static_cast<PCB_TEXT*>( item );
if( !aFlags.test( LAYER_FP_TEXT ) )
continue;
if( text->GetText() == wxT( "${REFERENCE}" ) && !aFlags.test( LAYER_FP_REFERENCES ) )
continue;
if( text->GetText() == wxT( "${VALUE}" ) && !aFlags.test( LAYER_FP_VALUES ) )
continue;
if( aLayer != UNDEFINED_LAYER && text->GetLayer() == aLayer )
text->TransformTextToPolySet( aBuffer, 0, aMaxError, aErrorLoc );
}
if( item->Type() == PCB_TEXTBOX_T )
{
PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( item );
if( aLayer != UNDEFINED_LAYER && textbox->GetLayer() == aLayer )
{
// border
if( textbox->IsBorderEnabled() )
{
textbox->PCB_SHAPE::TransformShapeToPolygon( aBuffer, aLayer, 0, aMaxError,
aErrorLoc );
}
// text
textbox->TransformTextToPolySet( aBuffer, 0, aMaxError, aErrorLoc );
}
}
}
for( const PCB_FIELD* field : aFootprint->GetFields( true /* visibleOnly */ ) )
{
if( !aFlags.test( LAYER_FP_TEXT ) )
continue;
if( field->IsReference() && !aFlags.test( LAYER_FP_REFERENCES ) )
continue;
if( field->IsValue() && !aFlags.test( LAYER_FP_VALUES ) )
continue;
if( field && field->GetLayer() == aLayer )
field->TransformTextToPolySet( aBuffer, 0, aMaxError, aErrorLoc );
}
}
void BOARD_ADAPTER::destroyLayers()
{
#define DELETE_AND_FREE( ptr ) \
@@ -938,7 +876,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
break;
case PCB_TABLE_T:
addTable( static_cast<PCB_TABLE*>( item ), layerContainer, item );
// JEY TODO: tables
break;
case PCB_DIM_ALIGNED_T:
@@ -1085,14 +1023,14 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
}
else
{
footprint->TransformPadsToPolySet( *layerPoly, layer, 0, maxError,
ERROR_INSIDE );
footprint->TransformPadsToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE );
}
transformFPTextToPolySet( footprint, layer, visibilityFlags, *layerPoly, maxError,
ERROR_INSIDE );
transformFPShapesToPolySet( footprint, layer, *layerPoly, maxError,
ERROR_INSIDE );
// On tech layers, use a poor circle approximation, only for texts (stroke font)
footprint->TransformFPTextToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE );
// Add the remaining things with dynamic seg count for circles
transformFPShapesToPolySet( footprint, layer, *layerPoly, maxError, ERROR_INSIDE );
}
if( cfg.show_zones || layer == F_Mask || layer == B_Mask )
@@ -1278,9 +1278,6 @@ void RENDER_3D_RAYTRACE_BASE::load3DModels( CONTAINER_3D& aDstContainer,
for( FP_3DMODEL& model : fp->Models() )
{
if( !model.m_Show || model.m_Filename.empty() )
continue;
// get it from cache
const S3DMODEL* modelPtr =
cacheMgr->GetModel( model.m_Filename, footprintBasePath, fp );
+16 -102
View File
@@ -81,35 +81,6 @@ PARAM_LAYER_PRESET_3D::PARAM_LAYER_PRESET_3D( const std::string& aPath,
m_presets( aPresetList )
{
wxASSERT( aPresetList );
#define LAYER( n, l ) m_layerToLayerNameMap[l] = n; m_layerNameToLayerMap[n] = l;
LAYER( "fp_values", LAYER_FP_VALUES );
LAYER( "fp_references", LAYER_FP_REFERENCES );
LAYER( "fp_text", LAYER_FP_TEXT );
LAYER( "background_bottom", LAYER_3D_BACKGROUND_BOTTOM );
LAYER( "background_top", LAYER_3D_BACKGROUND_TOP );
LAYER( "board", LAYER_3D_BOARD );
LAYER( "copper", LAYER_3D_COPPER_TOP );
LAYER( "copper_bottom", LAYER_3D_COPPER_BOTTOM );
LAYER( "silkscreen_bottom", LAYER_3D_SILKSCREEN_BOTTOM );
LAYER( "silkscreen_top", LAYER_3D_SILKSCREEN_TOP );
LAYER( "soldermask_bottom", LAYER_3D_SOLDERMASK_BOTTOM );
LAYER( "soldermask_top", LAYER_3D_SOLDERMASK_TOP );
LAYER( "solderpaste", LAYER_3D_SOLDERPASTE );
LAYER( "adhesive", LAYER_3D_ADHESIVE );
LAYER( "user_comments", LAYER_3D_USER_COMMENTS );
LAYER( "user_drawings", LAYER_3D_USER_DRAWINGS );
LAYER( "user_eco1", LAYER_3D_USER_ECO1 );
LAYER( "user_eco2", LAYER_3D_USER_ECO2 );
LAYER( "3d_axes", LAYER_3D_AXES );
LAYER( "th_models", LAYER_3D_TH_MODELS );
LAYER( "smd_models", LAYER_3D_SMD_MODELS );
LAYER( "virtual_models", LAYER_3D_VIRTUAL_MODELS );
LAYER( "non_pos_file_models", LAYER_3D_MODELS_NOT_IN_POS );
LAYER( "dnp_models", LAYER_3D_MODELS_MARKED_DNP );
LAYER( "bounding_boxes", LAYER_3D_BOUNDING_BOXES );
LAYER( "off_board_silk", LAYER_3D_OFF_BOARD_SILK );
}
@@ -128,7 +99,7 @@ nlohmann::json PARAM_LAYER_PRESET_3D::presetsToJson()
for( int layer = 0; layer < LAYER_3D_END; ++layer )
{
if( preset.layers.test( layer ) )
layers.push_back( m_layerToLayerNameMap[layer] );
layers.push_back( layer );
}
js["layers"] = layers;
@@ -138,7 +109,7 @@ nlohmann::json PARAM_LAYER_PRESET_3D::presetsToJson()
for( const auto& [ layer, color ] : preset.colors )
{
nlohmann::json layerColor = {
{ "layer", m_layerToLayerNameMap[layer] },
{ "layer", layer },
{ "color", color.ToCSSString() }
};
@@ -173,20 +144,26 @@ void PARAM_LAYER_PRESET_3D::jsonToPresets( const nlohmann::json& aJson )
for( const nlohmann::json& layer : preset.at( "layers" ) )
{
if( layer.is_string() )
p.layers.set( m_layerNameToLayerMap[layer.get<wxString>()] );
if( layer.is_number_integer() )
{
int layerNum = layer.get<int>();
if( layerNum >= 0 && layerNum < LAYER_3D_END )
p.layers.set( layerNum );
}
}
}
if( preset.contains( "colors" ) && preset.at( "colors" ).is_array() )
{
for( const nlohmann::json& entry : preset.at( "colors" ) )
for( const nlohmann::json& layerColor : preset.at( "colors" ) )
{
if( entry.contains( "layer" ) && entry.contains( "color" )
&& entry.at( "layer" ).is_string() )
if( layerColor.contains( "layer" ) && layerColor.contains( "color" )
&& layerColor.at( "layer" ).is_number_integer() )
{
int layerNum = m_layerNameToLayerMap[entry.at( "layer" ).get<wxString>()];
p.colors[ layerNum ] = entry.at( "color" ).get<COLOR4D>();
int layerNum = layerColor.at( "layer" ).get<int>();
COLOR4D color = layerColor.at( "color" ).get<COLOR4D>();
p.colors[ layerNum ] = color;
}
}
}
@@ -198,7 +175,7 @@ void PARAM_LAYER_PRESET_3D::jsonToPresets( const nlohmann::json& aJson )
///! Update the schema version whenever a migration is required
const int viewer3dSchemaVersion = 4;
const int viewer3dSchemaVersion = 3;
EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
@@ -448,69 +425,6 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() :
Set( "render.show_eco2", *optval );
}
return true;
} );
registerMigration( 3, 4,
[&]() -> bool
{
std::map<int, wxString> legacyColorMap;
legacyColorMap[142] = "fp_values";
legacyColorMap[143] = "fp_references";
legacyColorMap[130] = "fp_text";
legacyColorMap[466] = "background_bottom";
legacyColorMap[467] = "background_top";
legacyColorMap[468] = "board";
legacyColorMap[469] = "copper";
legacyColorMap[470] = "copper_bottom";
legacyColorMap[471] = "silkscreen_bottom";
legacyColorMap[472] = "silkscreen_top";
legacyColorMap[473] = "soldermask_bottom";
legacyColorMap[474] = "soldermask_top";
legacyColorMap[475] = "solderpaste";
legacyColorMap[476] = "adhesive";
legacyColorMap[477] = "user_comments";
legacyColorMap[478] = "user_drawings";
legacyColorMap[479] = "user_eco1";
legacyColorMap[480] = "user_eco2";
legacyColorMap[481] = "th_models";
legacyColorMap[482] = "smd_models";
legacyColorMap[483] = "virtual_models";
legacyColorMap[484] = "non_pos_file_models";
legacyColorMap[485] = "dnp_models";
legacyColorMap[486] = "3d_axes";
legacyColorMap[487] = "bounding_boxes";
legacyColorMap[488] = "off_board_silk";
if( !Contains( "layer_presets" ) || !At( "layer_presets" ).is_array() )
return true;
for( nlohmann::json& preset : At( "layer_presets" ) )
{
if( preset.contains( "colors" ) && preset.at( "colors" ).is_array() )
{
for( nlohmann::json& color : preset.at( "colors" ) )
{
if( color.contains( "layer" ) && color.at( "layer" ).is_number_integer() )
color["layer"] = legacyColorMap[color["layer"].get<int>()];
}
}
if( preset.contains( "layers" ) && preset.at( "layers" ).is_array() )
{
nlohmann::json mappedLayers = nlohmann::json::array();
for( const nlohmann::json& layer : preset.at( "layers" ) )
{
if( layer.is_number_integer() )
mappedLayers.push_back( legacyColorMap[layer.get<int>()] );
}
preset["layers"] = mappedLayers;
}
}
return true;
} );
}
@@ -64,11 +64,7 @@ private:
void jsonToPresets( const nlohmann::json& aJson );
private:
std::vector<LAYER_PRESET_3D>* m_presets;
std::map<int, wxString> m_layerToLayerNameMap;
std::map<wxString, int> m_layerNameToLayerMap;
};
+33 -28
View File
@@ -140,10 +140,10 @@ APPEARANCE_CONTROLS_3D::APPEARANCE_CONTROLS_3D( EDA_3D_VIEWER_FRAME* aParent,
} );
m_cbUseBoardEditorCopperColors = new wxCheckBox( m_panelLayers, wxID_ANY,
_( "Use PCB editor copper colors" ) );
_( "Use board editor copper colors" ) );
m_cbUseBoardEditorCopperColors->SetFont( infoFont );
m_cbUseBoardEditorCopperColors->SetToolTip( _( "Use the board editor layer colors for copper "
"layers (realtime renderer only)" ) );
m_cbUseBoardEditorCopperColors->SetToolTip(
_( "Use the board editor copper colors (openGL only)" ) );
m_cbUseBoardEditorCopperColors->Bind( wxEVT_CHECKBOX,
[this]( wxCommandEvent& aEvent )
@@ -156,9 +156,10 @@ APPEARANCE_CONTROLS_3D::APPEARANCE_CONTROLS_3D( EDA_3D_VIEWER_FRAME* aParent,
m_frame->NewDisplay( true );
} );
m_panelLayersSizer->Add( m_cbUseBoardStackupColors, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 5 );
m_panelLayersSizer->Add( m_cbUseBoardStackupColors, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 7 );
m_panelLayersSizer->Add( m_cbUseBoardEditorCopperColors, 0,
wxEXPAND | wxALL, 5 );
wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 7 );
m_cbLayerPresets->SetToolTip( wxString::Format( _( "Save and restore color and visibility "
"combinations.\n"
@@ -278,7 +279,16 @@ void APPEARANCE_CONTROLS_3D::CommonSettingsChanged()
void APPEARANCE_CONTROLS_3D::ApplyLayerPreset( const wxString& aPresetName )
{
doApplyLayerPreset( aPresetName );
if( aPresetName == FOLLOW_PCB || aPresetName == FOLLOW_PLOT_SETTINGS )
{
m_frame->GetAdapter().m_Cfg->m_CurrentPreset = aPresetName;
UpdateLayerCtls();
m_frame->NewDisplay( true );
}
else if( LAYER_PRESET_3D* preset = m_frame->GetAdapter().m_Cfg->FindPreset( aPresetName ) )
{
doApplyLayerPreset( *preset );
}
// Move to front of MRU list
if( m_presetMRU.Index( aPresetName ) != wxNOT_FOUND )
@@ -721,11 +731,17 @@ void APPEARANCE_CONTROLS_3D::onLayerPresetChanged( wxCommandEvent& aEvent )
if( index == 0 )
{
doApplyLayerPreset( FOLLOW_PCB );
name = FOLLOW_PCB;
cfg->m_CurrentPreset = name;
UpdateLayerCtls();
m_frame->NewDisplay( true );
}
else if( index == 1 )
{
doApplyLayerPreset( FOLLOW_PLOT_SETTINGS );
name = FOLLOW_PLOT_SETTINGS;
cfg->m_CurrentPreset = name;
UpdateLayerCtls();
m_frame->NewDisplay( true );
}
else if( index == count - 3 )
{
@@ -811,9 +827,10 @@ void APPEARANCE_CONTROLS_3D::onLayerPresetChanged( wxCommandEvent& aEvent )
resetSelection();
return;
}
else
else if( LAYER_PRESET_3D* preset = cfg->FindPreset( m_cbLayerPresets->GetStringSelection() ) )
{
doApplyLayerPreset( m_cbLayerPresets->GetStringSelection() );
name = preset->name;
doApplyLayerPreset( *preset );
}
// Move to front of MRU list
@@ -826,28 +843,16 @@ void APPEARANCE_CONTROLS_3D::onLayerPresetChanged( wxCommandEvent& aEvent )
}
void APPEARANCE_CONTROLS_3D::doApplyLayerPreset( const wxString& aPresetName )
void APPEARANCE_CONTROLS_3D::doApplyLayerPreset( const LAYER_PRESET_3D& aPreset )
{
BOARD_ADAPTER& adapter = m_frame->GetAdapter();
if( aPresetName == FOLLOW_PCB || aPresetName == FOLLOW_PLOT_SETTINGS )
{
adapter.m_Cfg->m_CurrentPreset = aPresetName;
adapter.SetVisibleLayers( adapter.GetVisibleLayers() );
}
else if( LAYER_PRESET_3D* preset = adapter.m_Cfg->FindPreset( aPresetName ) )
{
adapter.m_Cfg->m_CurrentPreset = aPresetName;
adapter.SetVisibleLayers( preset->layers );
adapter.SetLayerColors( preset->colors );
adapter.m_Cfg->m_CurrentPreset = aPreset.name;
adapter.SetVisibleLayers( aPreset.layers );
adapter.SetLayerColors( aPreset.colors );
if( preset->name.Lower() == _( "legacy colors" ) )
adapter.m_Cfg->m_UseStackupColors = false;
}
else
{
return;
}
if( aPreset.name.Lower() == _( "legacy colors" ) )
adapter.m_Cfg->m_UseStackupColors = false;
UpdateLayerCtls();
m_frame->NewDisplay( true );
+1 -1
View File
@@ -157,7 +157,7 @@ private:
void onLayerPresetChanged( wxCommandEvent& aEvent ) override;
void doApplyLayerPreset( const wxString& aPresetName );
void doApplyLayerPreset( const LAYER_PRESET_3D& aPreset );
void onViewportChanged( wxCommandEvent& aEvent ) override;
void onUpdateViewportsCb( wxUpdateUIEvent& aEvent ) override;
@@ -11,7 +11,7 @@
APPEARANCE_CONTROLS_3D_BASE::APPEARANCE_CONTROLS_3D_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : WX_PANEL( parent, id, pos, size, style, name )
{
this->SetMinSize( wxSize( 210,360 ) );
this->SetMinSize( wxSize( 200,360 ) );
m_sizerOuter = new wxBoxSizer( wxVERTICAL );
@@ -45,7 +45,7 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size">210,360</property>
<property name="minimum_size">200,360</property>
<property name="name">APPEARANCE_CONTROLS_3D_BASE</property>
<property name="pos"></property>
<property name="size">-1,-1</property>
+3 -3
View File
@@ -286,7 +286,7 @@ wxString PANEL_PREVIEW_3D_MODEL::formatRotationValue( double aValue )
wxString PANEL_PREVIEW_3D_MODEL::formatOffsetValue( double aValue )
{
// Convert from internal units (mm) to user units
if( m_userUnits == EDA_UNITS::INCH )
if( m_userUnits == EDA_UNITS::INCHES )
aValue /= 25.4;
else if( m_userUnits == EDA_UNITS::MILS )
aValue /= 25.4 / 1e3;
@@ -511,7 +511,7 @@ void PANEL_PREVIEW_3D_MODEL::doIncrementOffset( wxSpinEvent& event, double aSign
if( wxGetMouseState().ShiftDown( ) )
step_mm = OFFSET_INCREMENT_MM_FINE;
if( m_userUnits == EDA_UNITS::MILS || m_userUnits == EDA_UNITS::INCH )
if( m_userUnits == EDA_UNITS::MILS || m_userUnits == EDA_UNITS::INCHES )
{
step_mm = 25.4*OFFSET_INCREMENT_MIL/1000;
@@ -586,7 +586,7 @@ void PANEL_PREVIEW_3D_MODEL::onMouseWheelOffset( wxMouseEvent& event )
if( event.ShiftDown( ) )
step_mm = OFFSET_INCREMENT_MM_FINE;
if( m_userUnits == EDA_UNITS::MILS || m_userUnits == EDA_UNITS::INCH )
if( m_userUnits == EDA_UNITS::MILS || m_userUnits == EDA_UNITS::INCHES )
{
step_mm = 25.4*OFFSET_INCREMENT_MIL/1000.0;
@@ -209,7 +209,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
bSizer3DButtons->Add( m_bpvBodyStyle, 0, wxTOP, 5 );
bSizer3DButtons->Add( 0, 20, 0, wxEXPAND, 5 );
bSizer3DButtons->Add( 0, 0, 1, wxEXPAND, 5 );
m_bpvLeft = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
bSizer3DButtons->Add( m_bpvLeft, 0, wxBOTTOM, 5 );
@@ -230,7 +230,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
bSizer3DButtons->Add( m_bpvBottom, 0, 0, 5 );
bSizer3DButtons->Add( 0, 20, 0, wxEXPAND, 5 );
bSizer3DButtons->Add( 0, 0, 1, wxEXPAND, 5 );
m_bpUpdate = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
m_bpUpdate->SetToolTip( _("Reload board and 3D models") );
@@ -2235,9 +2235,9 @@
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<property name="proportion">1</property>
<object class="spacer" expanded="true">
<property name="height">20</property>
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
@@ -2695,9 +2695,9 @@
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<property name="proportion">1</property>
<object class="spacer" expanded="true">
<property name="height">20</property>
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
+1 -1
View File
@@ -621,7 +621,7 @@
欠陥電気
木 王
郝弘毅
Eli Hughes
See git repo on GitLab for contributors at
https://gitlab.com/kicad/code/kicad/-/graphs/master
-24
View File
@@ -58,30 +58,6 @@ message GraphicsDefaultsResponse
kiapi.board.GraphicsDefaults defaults = 1;
}
enum BoardOriginType
{
BOT_UNKNOWN = 0;
BOT_GRID = 1;
BOT_DRILL = 2;
}
// Returns a Vector2 with the specified origin point
message GetBoardOrigin
{
kiapi.common.types.DocumentSpecifier board = 1;
BoardOriginType type = 2;
}
message SetBoardOrigin
{
kiapi.common.types.DocumentSpecifier board = 1;
BoardOriginType type = 2;
kiapi.common.types.Vector2 origin = 3;
}
/*
* Net management
*/
-39
View File
@@ -89,42 +89,6 @@ enum BoardLayer
BL_User_8 = 60;
BL_User_9 = 61;
BL_Rescue = 62;
BL_User_10 = 63;
BL_User_11 = 64;
BL_User_12 = 65;
BL_User_13 = 66;
BL_User_14 = 67;
BL_User_15 = 68;
BL_User_16 = 69;
BL_User_17 = 70;
BL_User_18 = 71;
BL_User_19 = 72;
BL_User_20 = 73;
BL_User_21 = 74;
BL_User_22 = 75;
BL_User_23 = 76;
BL_User_24 = 77;
BL_User_25 = 78;
BL_User_26 = 79;
BL_User_27 = 80;
BL_User_28 = 81;
BL_User_29 = 82;
BL_User_30 = 83;
BL_User_31 = 84;
BL_User_32 = 85;
BL_User_33 = 86;
BL_User_34 = 87;
BL_User_35 = 88;
BL_User_36 = 89;
BL_User_37 = 90;
BL_User_38 = 91;
BL_User_39 = 92;
BL_User_40 = 93;
BL_User_41 = 94;
BL_User_42 = 95;
BL_User_43 = 96;
BL_User_44 = 97;
BL_User_45 = 98;
}
message NetCode
@@ -804,9 +768,6 @@ message Field
FieldId id = 1;
string name = 2;
BoardText text = 3;
// Since 9.0.1
bool visible = 4;
}
enum FootprintMountingStyle
+2 -5
View File
@@ -291,10 +291,7 @@ message TextAttributes
bool italic = 7;
bool bold = 8;
bool underlined = 9;
// Deprecated since 9.0.1 (text items are now always visible, only Fields can be hidden)
bool visible = 10;
bool mirrored = 11;
bool multiline = 12;
bool keep_upright = 13;
@@ -308,7 +305,7 @@ message Text
kiapi.common.types.Vector2 position = 2;
kiapi.common.types.TextAttributes attributes = 3;
// Reserved for future use; base objects don't support locking right now
// Reserved for future use; base objects don't support locking right nos
//kiapi.common.types.LockedState locked = 4;
string text = 5;
@@ -321,7 +318,7 @@ message TextBox
kiapi.common.types.Vector2 bottom_right = 3;
kiapi.common.types.TextAttributes attributes = 4;
// Reserved for future use; base objects don't support locking right now
// Reserved for future use; base objects don't support locking right nos
//kiapi.common.types.LockedState locked = 5;
string text = 6;
+9 -9
View File
@@ -51,7 +51,7 @@ IMAGE_SIZE::IMAGE_SIZE()
m_outputSize = 0.0;
m_originalDPI = DEFAULT_DPI;
m_originalSizePixels = 0;
m_unit = EDA_UNITS::MM;
m_unit = EDA_UNITS::MILLIMETRES;
}
@@ -61,9 +61,9 @@ void IMAGE_SIZE::SetOutputSizeFromInitialImageSize()
m_originalDPI = std::max( 1, m_originalDPI );
// Set the m_outputSize value from the m_originalSizePixels and the selected unit
if( m_unit == EDA_UNITS::MM )
if( m_unit == EDA_UNITS::MILLIMETRES )
m_outputSize = (double)GetOriginalSizePixels() / m_originalDPI * 25.4;
else if( m_unit == EDA_UNITS::INCH )
else if( m_unit == EDA_UNITS::INCHES )
m_outputSize = (double)GetOriginalSizePixels() / m_originalDPI;
else
m_outputSize = m_originalDPI;
@@ -74,9 +74,9 @@ int IMAGE_SIZE::GetOutputDPI()
{
int outputDPI;
if( m_unit == EDA_UNITS::MM )
if( m_unit == EDA_UNITS::MILLIMETRES )
outputDPI = GetOriginalSizePixels() / ( m_outputSize / 25.4 );
else if( m_unit == EDA_UNITS::INCH )
else if( m_unit == EDA_UNITS::INCHES )
outputDPI = GetOriginalSizePixels() / m_outputSize;
else
outputDPI = KiROUND( m_outputSize );
@@ -98,11 +98,11 @@ void IMAGE_SIZE::SetUnit( EDA_UNITS aUnit )
// Convert m_outputSize to mm:
double size_mm;
if( m_unit == EDA_UNITS::MM )
if( m_unit == EDA_UNITS::MILLIMETRES )
{
size_mm = m_outputSize;
}
else if( m_unit == EDA_UNITS::INCH )
else if( m_unit == EDA_UNITS::INCHES )
{
size_mm = m_outputSize * 25.4;
}
@@ -117,11 +117,11 @@ void IMAGE_SIZE::SetUnit( EDA_UNITS aUnit )
}
// Convert m_outputSize to new value:
if( aUnit == EDA_UNITS::MM )
if( aUnit == EDA_UNITS::MILLIMETRES )
{
m_outputSize = size_mm;
}
else if( aUnit == EDA_UNITS::INCH )
else if( aUnit == EDA_UNITS::INCHES )
{
m_outputSize = size_mm / 25.4;
}
+4 -4
View File
@@ -266,9 +266,9 @@ wxString BITMAP2CMP_PANEL::formatOutputSize( double aSize )
{
wxString text;
if( getUnitFromSelection() == EDA_UNITS::MM )
if( getUnitFromSelection() == EDA_UNITS::MILLIMETRES )
text.Printf( wxS( "%.1f" ), aSize );
else if( getUnitFromSelection() == EDA_UNITS::INCH )
else if( getUnitFromSelection() == EDA_UNITS::INCHES )
text.Printf( wxS( "%.2f" ), aSize );
else
text.Printf( wxT( "%d" ), KiROUND( aSize ) );
@@ -295,10 +295,10 @@ EDA_UNITS BITMAP2CMP_PANEL::getUnitFromSelection()
// return the EDA_UNITS from the m_PixelUnit choice
switch( m_PixelUnit->GetSelection() )
{
case 1: return EDA_UNITS::INCH;
case 1: return EDA_UNITS::INCHES;
case 2: return EDA_UNITS::UNSCALED;
case 0:
default: return EDA_UNITS::MM;
default: return EDA_UNITS::MILLIMETRES;
}
}
+1 -1
View File
@@ -37,7 +37,7 @@
# KiCad.
#
# Note: This version string should follow the semantic versioning system
set( KICAD_SEMANTIC_VERSION "9.0.1-rc2" )
set( KICAD_SEMANTIC_VERSION "9.0.0-rc2" )
# Default the version to the semantic version.
# This is overridden by the git repository tag though (if using git)
-1
View File
@@ -195,7 +195,6 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
# Suppress GCC warnings about unknown/unused attributes (e.g. cdecl, [[maybe_unused, etc)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-ignored-attributes" )
endif()
# Avoid ABI warnings, specifically one about an ABI change on ppc64el from gcc5 to gcc 6.
+7 -1
View File
@@ -72,7 +72,6 @@ set( KICOMMON_SRCS
jobs/job_export_pcb_gerber.cpp
jobs/job_export_pcb_gerbers.cpp
jobs/job_export_pcb_ipc2581.cpp
jobs/job_export_pcb_ipcd356.cpp
jobs/job_export_pcb_odb.cpp
jobs/job_export_pcb_pdf.cpp
jobs/job_export_pcb_plot.cpp
@@ -349,6 +348,8 @@ set( COMMON_DLG_SRCS
dialogs/dialog_color_picker_base.cpp
dialogs/dialog_configure_paths.cpp
dialogs/dialog_configure_paths_base.cpp
dialogs/dialog_design_block_properties.cpp
dialogs/dialog_design_block_properties_base.cpp
dialogs/dialog_display_html_text_base.cpp
dialogs/dialog_edit_library_tables.cpp
dialogs/dialog_embed_files.cpp
@@ -422,6 +423,7 @@ set( COMMON_WIDGET_SRCS
widgets/bitmap_toggle.cpp
widgets/button_row_panel.cpp
widgets/color_swatch.cpp
widgets/design_block_pane.cpp
widgets/filter_combobox.cpp
widgets/font_choice.cpp
widgets/footprint_choice.cpp
@@ -446,6 +448,7 @@ set( COMMON_WIDGET_SRCS
widgets/mathplot.cpp
widgets/msgpanel.cpp
widgets/paged_dialog.cpp
widgets/panel_design_block_chooser.cpp
widgets/properties_panel.cpp
widgets/search_pane.cpp
widgets/search_pane_base.cpp
@@ -589,6 +592,7 @@ set( COMMON_SRCS
eda_item.cpp
eda_shape.cpp
eda_text.cpp
eda_tools.cpp
embedded_files.cpp
env_paths.cpp
executable_names.cpp
@@ -607,6 +611,7 @@ set( COMMON_SRCS
lib_table_grid_tricks.cpp
lib_tree_model.cpp
lib_tree_model_adapter.cpp
design_block_tree_model_adapter.cpp
marker_base.cpp
origin_transforms.cpp
printout.cpp
@@ -640,6 +645,7 @@ set( COMMON_SRCS
tool/construction_manager.cpp
tool/common_tools.cpp
tool/conditional_menu.cpp
tool/design_block_control.cpp
tool/edit_constraints.cpp
tool/edit_points.cpp
tool/editor_conditions.cpp
+6 -24
View File
@@ -100,6 +100,7 @@ static const wxChar V3DRT_BevelHeight_um[] = wxT( "V3DRT_BevelHeight_um" );
static const wxChar V3DRT_BevelExtentFactor[] = wxT( "V3DRT_BevelExtentFactor" );
static const wxChar EnableDesignBlocks[] = wxT( "EnableDesignBlocks" );
static const wxChar EnableGenerators[] = wxT( "EnableGenerators" );
static const wxChar EnableGit[] = wxT( "EnableGit" );
static const wxChar EnableLibWithText[] = wxT( "EnableLibWithText" );
static const wxChar EnableLibDir[] = wxT( "EnableLibDir" );
static const wxChar EnableEeschemaPrintCairo[] = wxT( "EnableEeschemaPrintCairo" );
@@ -124,10 +125,6 @@ static const wxChar MinParallelAngle[] = wxT( "MinParallelAngle" );
static const wxChar HoleWallPaintingMultiplier[] = wxT( "HoleWallPaintingMultiplier" );
static const wxChar MsgPanelShowUuids[] = wxT( "MsgPanelShowUuids" );
static const wxChar MaximumThreads[] = wxT( "MaximumThreads" );
static const wxChar NetInspectorBulkUpdateOptimisationThreshold[] =
wxT( "NetInspectorBulkUpdateOptimisationThreshold" );
static const wxChar ExcludeFromSimulationLineWidth[] = wxT( "ExcludeFromSimulationLineWidth" );
static const wxChar GitIconRefreshInterval[] = wxT( "GitIconRefreshInterval" );
} // namespace KEYS
@@ -258,6 +255,7 @@ ADVANCED_CFG::ADVANCED_CFG()
m_ShowRepairSchematic = false;
m_EnableDesignBlocks = true;
m_EnableGenerators = false;
m_EnableGit = false;
m_EnableLibWithText = false;
m_EnableLibDir = false;
@@ -294,7 +292,7 @@ ADVANCED_CFG::ADVANCED_CFG()
m_ResolveTextRecursionDepth = 3;
m_EnableExtensionSnaps = true;
m_ExtensionSnapTimeoutMs = 500;
m_ExtensionSnapTimeoutMs = 400;
m_ExtensionSnapActivateOnHover = true;
m_EnableSnapAnchorsDebug = false;
@@ -305,12 +303,6 @@ ADVANCED_CFG::ADVANCED_CFG()
m_MinimumMarkerSeparationDistance = 0.15;
m_NetInspectorBulkUpdateOptimisationThreshold = 25;
m_ExcludeFromSimulationLineWidth = 25;
m_GitIconRefreshInterval = 10000;
loadFromConfigFile();
}
@@ -500,6 +492,9 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::EnableAPILogging,
&m_EnableAPILogging, m_EnableAPILogging ) );
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::EnableGit,
&m_EnableGit, m_EnableGit ) );
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::EnableLibWithText,
&m_EnableLibWithText, m_EnableLibWithText ) );
@@ -588,19 +583,6 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
&m_MaximumThreads, m_MaximumThreads,
0, 500 ) );
configParams.push_back(
new PARAM_CFG_INT( true, AC_KEYS::NetInspectorBulkUpdateOptimisationThreshold,
&m_NetInspectorBulkUpdateOptimisationThreshold,
m_NetInspectorBulkUpdateOptimisationThreshold, 0, 1000 ) );
configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::ExcludeFromSimulationLineWidth,
&m_ExcludeFromSimulationLineWidth,
m_ExcludeFromSimulationLineWidth, 1, 100 ) );
configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::GitIconRefreshInterval,
&m_GitIconRefreshInterval,
m_GitIconRefreshInterval, 0, 100000 ) );
// Special case for trace mask setting...we just grab them and set them immediately
// Because we even use wxLogTrace inside of advanced config
wxString traceMasks;
-72
View File
@@ -214,42 +214,6 @@ PCB_LAYER_ID FromProtoEnum( board::types::BoardLayer aValue )
case board::types::BoardLayer::BL_User_8: return User_8;
case board::types::BoardLayer::BL_User_9: return User_9;
case board::types::BoardLayer::BL_Rescue: return Rescue;
case board::types::BoardLayer::BL_User_10: return User_10;
case board::types::BoardLayer::BL_User_11: return User_11;
case board::types::BoardLayer::BL_User_12: return User_12;
case board::types::BoardLayer::BL_User_13: return User_13;
case board::types::BoardLayer::BL_User_14: return User_14;
case board::types::BoardLayer::BL_User_15: return User_15;
case board::types::BoardLayer::BL_User_16: return User_16;
case board::types::BoardLayer::BL_User_17: return User_17;
case board::types::BoardLayer::BL_User_18: return User_18;
case board::types::BoardLayer::BL_User_19: return User_19;
case board::types::BoardLayer::BL_User_20: return User_20;
case board::types::BoardLayer::BL_User_21: return User_21;
case board::types::BoardLayer::BL_User_22: return User_22;
case board::types::BoardLayer::BL_User_23: return User_23;
case board::types::BoardLayer::BL_User_24: return User_24;
case board::types::BoardLayer::BL_User_25: return User_25;
case board::types::BoardLayer::BL_User_26: return User_26;
case board::types::BoardLayer::BL_User_27: return User_27;
case board::types::BoardLayer::BL_User_28: return User_28;
case board::types::BoardLayer::BL_User_29: return User_29;
case board::types::BoardLayer::BL_User_30: return User_30;
case board::types::BoardLayer::BL_User_31: return User_31;
case board::types::BoardLayer::BL_User_32: return User_32;
case board::types::BoardLayer::BL_User_33: return User_33;
case board::types::BoardLayer::BL_User_34: return User_34;
case board::types::BoardLayer::BL_User_35: return User_35;
case board::types::BoardLayer::BL_User_36: return User_36;
case board::types::BoardLayer::BL_User_37: return User_37;
case board::types::BoardLayer::BL_User_38: return User_38;
case board::types::BoardLayer::BL_User_39: return User_39;
case board::types::BoardLayer::BL_User_40: return User_40;
case board::types::BoardLayer::BL_User_41: return User_41;
case board::types::BoardLayer::BL_User_42: return User_42;
case board::types::BoardLayer::BL_User_43: return User_43;
case board::types::BoardLayer::BL_User_44: return User_44;
case board::types::BoardLayer::BL_User_45: return User_45;
case board::types::BoardLayer::BL_UNKNOWN: return UNDEFINED_LAYER;
default:
@@ -326,42 +290,6 @@ board::types::BoardLayer ToProtoEnum( PCB_LAYER_ID aValue )
case User_8: return board::types::BoardLayer::BL_User_8;
case User_9: return board::types::BoardLayer::BL_User_9;
case Rescue: return board::types::BoardLayer::BL_Rescue;
case User_10: return board::types::BoardLayer::BL_User_10;
case User_11: return board::types::BoardLayer::BL_User_11;
case User_12: return board::types::BoardLayer::BL_User_12;
case User_13: return board::types::BoardLayer::BL_User_13;
case User_14: return board::types::BoardLayer::BL_User_14;
case User_15: return board::types::BoardLayer::BL_User_15;
case User_16: return board::types::BoardLayer::BL_User_16;
case User_17: return board::types::BoardLayer::BL_User_17;
case User_18: return board::types::BoardLayer::BL_User_18;
case User_19: return board::types::BoardLayer::BL_User_19;
case User_20: return board::types::BoardLayer::BL_User_20;
case User_21: return board::types::BoardLayer::BL_User_21;
case User_22: return board::types::BoardLayer::BL_User_22;
case User_23: return board::types::BoardLayer::BL_User_23;
case User_24: return board::types::BoardLayer::BL_User_24;
case User_25: return board::types::BoardLayer::BL_User_25;
case User_26: return board::types::BoardLayer::BL_User_26;
case User_27: return board::types::BoardLayer::BL_User_27;
case User_28: return board::types::BoardLayer::BL_User_28;
case User_29: return board::types::BoardLayer::BL_User_29;
case User_30: return board::types::BoardLayer::BL_User_30;
case User_31: return board::types::BoardLayer::BL_User_31;
case User_32: return board::types::BoardLayer::BL_User_32;
case User_33: return board::types::BoardLayer::BL_User_33;
case User_34: return board::types::BoardLayer::BL_User_34;
case User_35: return board::types::BoardLayer::BL_User_35;
case User_36: return board::types::BoardLayer::BL_User_36;
case User_37: return board::types::BoardLayer::BL_User_37;
case User_38: return board::types::BoardLayer::BL_User_38;
case User_39: return board::types::BoardLayer::BL_User_39;
case User_40: return board::types::BoardLayer::BL_User_40;
case User_41: return board::types::BoardLayer::BL_User_41;
case User_42: return board::types::BoardLayer::BL_User_42;
case User_43: return board::types::BoardLayer::BL_User_43;
case User_44: return board::types::BoardLayer::BL_User_44;
case User_45: return board::types::BoardLayer::BL_User_45;
default:
wxCHECK_MSG( false, board::types::BoardLayer::BL_UNKNOWN,
"Unhandled case in ToProtoEnum<PCB_LAYER_ID>");
+15 -65
View File
@@ -24,7 +24,6 @@
#include <fmt/format.h>
#include <wx/dir.h>
#include <wx/log.h>
#include <wx/timer.h>
#include <wx/utils.h>
#include <api/api_plugin_manager.h>
@@ -44,9 +43,7 @@ wxDEFINE_EVENT( EDA_EVT_PLUGIN_AVAILABILITY_CHANGED, wxCommandEvent );
API_PLUGIN_MANAGER::API_PLUGIN_MANAGER( wxEvtHandler* aEvtHandler ) :
wxEvtHandler(),
m_parent( aEvtHandler ),
m_lastPid( 0 ),
m_raiseTimer( nullptr )
m_parent( aEvtHandler )
{
// Read and store pcm schema
wxFileName schemaFile( PATHS::GetStockDataPath( true ), wxS( "api.v1.schema.json" ) );
@@ -284,7 +281,7 @@ void API_PLUGIN_MANAGER::InvokeAction( const wxString& aIdentifier )
if( pythonHome )
env.env[wxS( "VIRTUAL_ENV" )] = *pythonHome;
[[maybe_unused]] long pid = manager.Execute( { pluginFile.GetFullPath() },
manager.Execute( pluginFile.GetFullPath(),
[]( int aRetVal, const wxString& aOutput, const wxString& aError )
{
wxLogTrace( traceApi,
@@ -295,36 +292,6 @@ void API_PLUGIN_MANAGER::InvokeAction( const wxString& aIdentifier )
},
&env, true );
#ifdef __WXMAC__
if( pid )
{
if( !m_raiseTimer )
{
m_raiseTimer = new wxTimer( this );
Bind( wxEVT_TIMER,
[&]( wxTimerEvent& )
{
wxString script = wxString::Format(
wxS( "tell application \"System Events\"\n"
" set plist to every process whose unix id is %ld\n"
" repeat with proc in plist\n"
" set the frontmost of proc to true\n"
" end repeat\n"
"end tell" ), m_lastPid );
wxString cmd = wxString::Format( "osascript -e '%s'", script );
wxLogTrace( traceApi, wxString::Format( "Execute: %s", cmd ) );
wxExecute( cmd );
},
m_raiseTimer->GetId() );
}
m_lastPid = pid;
m_raiseTimer->StartOnce( 250 );
}
#endif
break;
}
@@ -495,14 +462,10 @@ void API_PLUGIN_MANAGER::processNextJob( wxCommandEvent& aEvent )
env.env.erase( "PYTHONPATH" );
}
#endif
std::vector<wxString> args = {
"-m",
"venv",
"--system-site-packages",
job.env_path
};
manager.Execute( args,
manager.Execute(
wxString::Format( wxS( "-m venv --system-site-packages \"%s\"" ),
job.env_path ),
[this]( int aRetVal, const wxString& aOutput, const wxString& aError )
{
wxLogTrace( traceApi,
@@ -557,15 +520,10 @@ void API_PLUGIN_MANAGER::processNextJob( wxCommandEvent& aEvent )
}
#endif
std::vector<wxString> args = {
"-m",
"pip",
"install",
"--upgrade",
"pip"
};
wxString cmd = wxS( "-m pip install --upgrade pip" );
wxLogTrace( traceApi, "Manager: calling python %s", cmd );
manager.Execute( args,
manager.Execute( cmd,
[this]( int aRetVal, const wxString& aOutput, const wxString& aError )
{
wxLogTrace( traceApi, wxString::Format( "Manager: upgrade pip returned %d",
@@ -627,22 +585,14 @@ void API_PLUGIN_MANAGER::processNextJob( wxCommandEvent& aEvent )
if( pythonHome )
env.env[wxS( "VIRTUAL_ENV" )] = *pythonHome;
std::vector<wxString> args = {
"-m",
"pip",
"install",
"--no-input",
"--isolated",
"--only-binary",
":all:",
"--require-virtualenv",
"--exists-action",
"i",
"-r",
reqs.GetFullPath()
};
wxString cmd = wxString::Format(
wxS( "-m pip install --no-input --isolated --only-binary :all: --require-virtualenv "
"--exists-action i -r \"%s\"" ),
reqs.GetFullPath() );
manager.Execute( args,
wxLogTrace( traceApi, "Manager: calling python %s", cmd );
manager.Execute( cmd,
[this, job]( int aRetVal, const wxString& aOutput, const wxString& aError )
{
if( !aError.IsEmpty() )
+13 -3
View File
@@ -21,6 +21,10 @@
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DESIGN_BLOCK_H
#define DESIGN_BLOCK_H
#include <kicommon.h>
#include <lib_id.h>
#include <nlohmann/json.hpp>
@@ -41,6 +45,9 @@ public:
const wxString& GetSchematicFile() const { return m_schematicFile; }
void SetSchematicFile( const wxString& aFile ) { m_schematicFile = aFile; }
const wxString& GetBoardFile() const { return m_boardFile; }
void SetBoardFile( const wxString& aFile ) { m_boardFile = aFile; }
void SetFields( nlohmann::ordered_map<wxString, wxString>& aFields )
{
m_fields = std::move( aFields );
@@ -55,9 +62,12 @@ public:
private:
LIB_ID m_lib_id;
wxString m_schematicFile; ///< File name and path for schematic symbol.
wxString m_libDescription; ///< File name and path for documentation file.
wxString m_keywords; ///< Search keywords to find footprint in library.
wxString m_schematicFile; // File name and path for schematic file.
wxString m_boardFile; // File name and path for board file
wxString m_libDescription; // File name and path for documentation file.
wxString m_keywords; // Search keywords to find design block in library.
nlohmann::ordered_map<wxString, wxString> m_fields;
};
#endif
+74 -23
View File
@@ -74,10 +74,8 @@ DESIGN_BLOCK_IO_MGR::DESIGN_BLOCK_FILE_T
DESIGN_BLOCK_IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath, int aCtl )
{
if( IO_RELEASER<DESIGN_BLOCK_IO>( FindPlugin( KICAD_SEXP ) )->CanReadLibrary( aLibPath )
&& aCtl != KICTL_NONKICAD_ONLY )
{
&& aCtl != KICTL_NONKICAD_ONLY )
return KICAD_SEXP;
}
return DESIGN_BLOCK_IO_MGR::FILE_TYPE_NONE;
}
@@ -267,7 +265,10 @@ void DESIGN_BLOCK_IO::DesignBlockEnumerate( wxArrayString& aDesignBlockNames,
wxDir dir( aLibraryPath );
if( !dir.IsOpened() )
return;
{
THROW_IO_ERROR(
wxString::Format( _( "Design block '%s' does not exist." ), aLibraryPath ) );
}
wxString dirname;
wxString fileSpec = wxT( "*." ) + wxString( FILEEXT::KiCadDesignBlockPathExtension );
@@ -289,17 +290,23 @@ DESIGN_BLOCK* DESIGN_BLOCK_IO::DesignBlockLoad( const wxString& aLibraryPath,
+ FILEEXT::KiCadDesignBlockPathExtension + wxFileName::GetPathSeparator();
wxString dbSchPath = dbPath + aDesignBlockName + wxT( "." )
+ FILEEXT::KiCadSchematicFileExtension;
wxString dbPcbPath = dbPath + aDesignBlockName + wxT( "." ) + FILEEXT::KiCadPcbFileExtension;
wxString dbMetadataPath = dbPath + aDesignBlockName + wxT( "." ) + FILEEXT::JsonFileExtension;
if( !wxFileExists( dbSchPath ) )
return nullptr;
if( !wxDir::Exists( dbPath ) )
THROW_IO_ERROR( wxString::Format( _( "Design block '%s' does not exist." ), dbPath ) );
DESIGN_BLOCK* newDB = new DESIGN_BLOCK();
// Library name needs to be empty for when we fill it in with the correct library nickname
// one layer above
newDB->SetLibId( LIB_ID( wxEmptyString, aDesignBlockName ) );
newDB->SetSchematicFile( dbSchPath );
if( wxFileExists( dbSchPath ) )
newDB->SetSchematicFile( dbSchPath );
if( wxFileExists( dbPcbPath ) )
newDB->SetBoardFile( dbPcbPath );
// Parse the JSON file if it exists
if( wxFileExists( dbMetadataPath ) )
@@ -335,16 +342,27 @@ DESIGN_BLOCK* DESIGN_BLOCK_IO::DesignBlockLoad( const wxString& aLibraryPath,
}
catch( ... )
{
delete newDB;
THROW_IO_ERROR( wxString::Format(
_( "Design block metadata file '%s' could not be read." ), dbMetadataPath ) );
}
}
return newDB;
}
bool DESIGN_BLOCK_IO::DesignBlockExists( const wxString& aLibraryPath,
const wxString& aDesignBlockName,
const std::map<std::string, UTF8>* aProperties )
{
wxString dbPath = aLibraryPath + wxFileName::GetPathSeparator() + aDesignBlockName + wxT( "." )
+ FILEEXT::KiCadDesignBlockPathExtension + wxFileName::GetPathSeparator();
return wxDir::Exists( dbPath );
}
void DESIGN_BLOCK_IO::DesignBlockSave( const wxString& aLibraryPath,
const DESIGN_BLOCK* aDesignBlock,
const std::map<std::string, UTF8>* aProperties )
@@ -355,12 +373,22 @@ void DESIGN_BLOCK_IO::DesignBlockSave( const wxString& aLibra
THROW_IO_ERROR( _( "Design block does not have a valid library ID." ) );
}
wxFileName schematicFile( aDesignBlock->GetSchematicFile() );
if( aDesignBlock->GetSchematicFile().IsEmpty() && aDesignBlock->GetBoardFile().IsEmpty() )
{
THROW_IO_ERROR( _( "Design block does not have a schematic or board file." ) );
}
if( !schematicFile.FileExists() )
if( !aDesignBlock->GetSchematicFile().IsEmpty()
&& !wxFileExists( aDesignBlock->GetSchematicFile() ) )
{
THROW_IO_ERROR( wxString::Format( _( "Schematic source file '%s' does not exist." ),
schematicFile.GetFullPath() ) );
aDesignBlock->GetSchematicFile() ) );
}
if( !aDesignBlock->GetBoardFile().IsEmpty() && !wxFileExists( aDesignBlock->GetBoardFile() ) )
{
THROW_IO_ERROR( wxString::Format( _( "Board source file '%s' does not exist." ),
aDesignBlock->GetBoardFile() ) );
}
// Create the design block folder
@@ -378,23 +406,46 @@ void DESIGN_BLOCK_IO::DesignBlockSave( const wxString& aLibra
}
}
// The new schematic file name is based on the design block name, not the source sheet name
wxString dbSchematicFile = dbFolder.GetFullPath() + aDesignBlock->GetLibId().GetLibItemName()
+ wxT( "." ) + FILEEXT::KiCadSchematicFileExtension;
// If the source and destination files are the same, then we don't need to copy the file
// as we are just updating the metadata
if( schematicFile.GetFullPath() != dbSchematicFile )
if( !aDesignBlock->GetSchematicFile().IsEmpty() )
{
// Copy the source sheet file to the design block folder, under the design block name
if( !wxCopyFile( schematicFile.GetFullPath(), dbSchematicFile ) )
// The new schematic file name is based on the design block name, not the source sheet name
wxString dbSchematicFile = dbFolder.GetFullPath()
+ aDesignBlock->GetLibId().GetLibItemName() + wxT( "." )
+ FILEEXT::KiCadSchematicFileExtension;
// If the source and destination files are the same, then we don't need to copy the file
// as we are just updating the metadata
if( aDesignBlock->GetSchematicFile() != dbSchematicFile )
{
THROW_IO_ERROR( wxString::Format(
_( "Schematic file '%s' could not be saved as design block at '%s'." ),
schematicFile.GetFullPath(), dbSchematicFile ) );
// Copy the source sheet file to the design block folder, under the design block name
if( !wxCopyFile( aDesignBlock->GetSchematicFile(), dbSchematicFile ) )
{
THROW_IO_ERROR( wxString::Format(
_( "Schematic file '%s' could not be saved as design block at '%s'." ),
aDesignBlock->GetSchematicFile().GetData(), dbSchematicFile ) );
}
}
}
if( !aDesignBlock->GetBoardFile().IsEmpty() )
{
// The new Board file name is based on the design block name, not the source sheet name
wxString dbBoardFile = dbFolder.GetFullPath() + aDesignBlock->GetLibId().GetLibItemName()
+ wxT( "." ) + FILEEXT::KiCadPcbFileExtension;
// If the source and destination files are the same, then we don't need to copy the file
// as we are just updating the metadata
if( aDesignBlock->GetBoardFile() != dbBoardFile )
{
// Copy the source sheet file to the design block folder, under the design block name
if( !wxCopyFile( aDesignBlock->GetBoardFile(), dbBoardFile ) )
{
THROW_IO_ERROR( wxString::Format(
_( "Board file '%s' could not be saved as design block at '%s'." ),
aDesignBlock->GetBoardFile().GetData(), dbBoardFile ) );
}
}
}
wxString dbMetadataFile = dbFolder.GetFullPath() + aDesignBlock->GetLibId().GetLibItemName()
+ wxT( "." ) + FILEEXT::JsonFileExtension;
+1 -4
View File
@@ -76,10 +76,7 @@ public:
}
bool DesignBlockExists( const wxString& aLibraryPath, const wxString& aDesignBlockName,
const std::map<std::string, UTF8>* aProperties = nullptr )
{
return DesignBlockLoad( aLibraryPath, aDesignBlockName, true, aProperties ) != nullptr;
}
const std::map<std::string, UTF8>* aProperties = nullptr );
DESIGN_BLOCK* ImportDesignBlock( const wxString& aDesignBlockPath,
wxString& aDesignBlockNameOut,
+36 -27
View File
@@ -73,6 +73,23 @@ void DESIGN_BLOCK_LIB_TABLE_ROW::SetType( const wxString& aType )
}
bool DESIGN_BLOCK_LIB_TABLE_ROW::Refresh()
{
if( !plugin )
{
wxArrayString dummyList;
plugin.reset( DESIGN_BLOCK_IO_MGR::FindPlugin( type ) );
SetLoaded( false );
plugin->DesignBlockEnumerate( dummyList, GetFullURI( true ), true, GetProperties() );
SetLoaded( true );
return true;
}
return false;
}
DESIGN_BLOCK_LIB_TABLE::DESIGN_BLOCK_LIB_TABLE( DESIGN_BLOCK_LIB_TABLE* aFallBackTable ) :
LIB_TABLE( aFallBackTable )
{
@@ -205,8 +222,7 @@ void DESIGN_BLOCK_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
row->SetVisible();
break;
default:
in->Unexpected( tok );
default: in->Unexpected( tok );
}
in->NeedRIGHT();
@@ -254,9 +270,7 @@ bool DESIGN_BLOCK_LIB_TABLE::operator==( const DESIGN_BLOCK_LIB_TABLE& aDesignBl
{
if( (DESIGN_BLOCK_LIB_TABLE_ROW&) m_rows[i]
!= (DESIGN_BLOCK_LIB_TABLE_ROW&) aDesignBlockTable.m_rows[i] )
{
return false;
}
}
return true;
@@ -271,8 +285,8 @@ void DESIGN_BLOCK_LIB_TABLE::Format( OUTPUTFORMATTER* aOutput, int aIndentLevel
aOutput->Print( aIndentLevel, "(design_block_lib_table\n" );
aOutput->Print( aIndentLevel + 1, "(version %d)\n", m_version );
for( const LIB_TABLE_ROW& row : m_rows)
row.Format( aOutput, aIndentLevel + 1 );
for( LIB_TABLE_ROWS_CITER it = m_rows.begin(); it != m_rows.end(); ++it )
it->Format( aOutput, aIndentLevel + 1 );
aOutput->Print( aIndentLevel, ")\n" );
}
@@ -333,9 +347,9 @@ const DESIGN_BLOCK_LIB_TABLE_ROW* DESIGN_BLOCK_LIB_TABLE::FindRow( const wxStrin
if( !row )
{
THROW_IO_ERROR( wxString::Format( _( "design-block-lib-table files contain no library "
"named '%s'." ),
aNickname ) );
wxString msg = wxString::Format(
_( "design-block-lib-table files contain no library named '%s'." ), aNickname );
THROW_IO_ERROR( msg );
}
if( !row->plugin )
@@ -493,12 +507,14 @@ DESIGN_BLOCK_LIB_TABLE::DesignBlockLoadWithOptionalNickname( const LIB_ID& aDesi
// nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
else
{
std::vector<wxString> nicks = GetLogicalLibs();
// Search each library going through libraries alphabetically.
for( const wxString& library : GetLogicalLibs() )
for( unsigned i = 0; i < nicks.size(); ++i )
{
// DesignBlockLoad() returns NULL on not found, does not throw exception
// unless there's an IO_ERROR.
DESIGN_BLOCK* ret = DesignBlockLoad( library, DesignBlockname, aKeepUUID );
DESIGN_BLOCK* ret = DesignBlockLoad( nicks[i], DesignBlockname, aKeepUUID );
if( ret )
return ret;
@@ -521,8 +537,7 @@ public:
explicit PCM_DESIGN_BLOCK_LIB_TRAVERSER( const wxString& aPath, DESIGN_BLOCK_LIB_TABLE& aTable,
const wxString& aPrefix ) :
m_lib_table( aTable ),
m_path_prefix( aPath ),
m_lib_prefix( aPrefix )
m_path_prefix( aPath ), m_lib_prefix( aPrefix )
{
wxFileName f( aPath, wxS( "" ) );
m_prefix_dir_count = f.GetDirCount();
@@ -541,9 +556,8 @@ public:
FILEEXT::KiCadDesignBlockLibPathExtension ) )
&& dir.GetDirCount() >= m_prefix_dir_count + 3 )
{
wxString versionedPath;
versionedPath.Printf( wxS( "${%s}" ),
ENV_VAR::GetVersionedEnvVarName( wxS( "3RD_PARTY" ) ) );
wxString versionedPath = wxString::Format(
wxS( "${%s}" ), ENV_VAR::GetVersionedEnvVarName( wxS( "3RD_PARTY" ) ) );
wxArrayString parts = dir.GetDirs();
parts.RemoveAt( 0, m_prefix_dir_count );
@@ -554,21 +568,16 @@ public:
if( !m_lib_table.HasLibraryWithPath( libPath ) )
{
wxString name = parts.Last().substr( 0, parts.Last().length() - 7 );
wxString nickname;
nickname.Printf( wxS( "%s%s" ),
m_lib_prefix,
name );
wxString nickname = wxString::Format( wxS( "%s%s" ), m_lib_prefix, name );
if( m_lib_table.HasLibrary( nickname ) )
{
int increment = 1;
do
{
nickname.Printf( wxS( "%s%s_%d" ),
m_lib_prefix,
name,
increment++ );
nickname =
wxString::Format( wxS( "%s%s_%d" ), m_lib_prefix, name, increment );
increment++;
} while( m_lib_table.HasLibrary( nickname ) );
}
@@ -611,8 +620,8 @@ bool DESIGN_BLOCK_LIB_TABLE::LoadGlobalTable( DESIGN_BLOCK_LIB_TABLE& aTable )
SystemDirsAppend( &ss );
const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
std::optional<wxString> v = ENV_VAR::GetVersionedEnvVarValue( envVars,
wxT( "TEMPLATE_DIR" ) );
std::optional<wxString> v =
ENV_VAR::GetVersionedEnvVarValue( envVars, wxT( "TEMPLATE_DIR" ) );
if( v && !v->IsEmpty() )
ss.AddPaths( *v, 0 );
@@ -25,30 +25,34 @@
#include <project/project_file.h>
#include <wx/log.h>
#include <wx/tokenzr.h>
#include <settings/app_settings.h>
#include <string_utils.h>
#include <eda_pattern_match.h>
#include <design_block.h>
#include <design_block_lib_table.h>
#include <design_block_info.h>
#include <design_block_tree_model_adapter.h>
#include <tools/sch_design_block_control.h>
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>
DESIGN_BLOCK_TREE_MODEL_ADAPTER::Create( EDA_BASE_FRAME* aParent, LIB_TABLE* aLibs,
APP_SETTINGS_BASE::LIB_TREE& aSettings )
APP_SETTINGS_BASE::LIB_TREE& aSettings,
TOOL_INTERACTIVE* aContextMenuTool )
{
auto* adapter = new DESIGN_BLOCK_TREE_MODEL_ADAPTER( aParent, aLibs, aSettings );
adapter->m_frame = aParent;
auto* adapter = new DESIGN_BLOCK_TREE_MODEL_ADAPTER( aParent, aLibs, aSettings, aContextMenuTool );
return wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>( adapter );
}
DESIGN_BLOCK_TREE_MODEL_ADAPTER::DESIGN_BLOCK_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent,
LIB_TABLE* aLibs,
APP_SETTINGS_BASE::LIB_TREE& aSettings ) :
LIB_TREE_MODEL_ADAPTER( aParent, wxT( "pinned_design_block_libs" ), aSettings ),
LIB_TABLE* aLibs,
APP_SETTINGS_BASE::LIB_TREE& aSettings,
TOOL_INTERACTIVE* aContextMenuTool ) :
LIB_TREE_MODEL_ADAPTER( aParent,
wxT( "pinned_design_block_libs" ),
Kiface().KifaceSettings()->m_DesignBlockChooserPanel.tree ),
m_libs( (DESIGN_BLOCK_LIB_TABLE*) aLibs ),
m_frame( aParent )
m_frame( aParent ),
m_contextMenuTool( aContextMenuTool )
{
}
@@ -206,5 +210,5 @@ wxString DESIGN_BLOCK_TREE_MODEL_ADAPTER::GenerateInfo( LIB_ID const& aLibId, in
TOOL_INTERACTIVE* DESIGN_BLOCK_TREE_MODEL_ADAPTER::GetContextMenuTool()
{
return m_frame->GetToolManager()->GetTool<SCH_DESIGN_BLOCK_CONTROL>();
return m_contextMenuTool;
}
@@ -35,7 +35,8 @@ public:
*/
static wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> Create( EDA_BASE_FRAME* aParent,
LIB_TABLE* aLibs,
APP_SETTINGS_BASE::LIB_TREE& aSettings );
APP_SETTINGS_BASE::LIB_TREE& aSettings,
TOOL_INTERACTIVE* aContextMenuTool );
void AddLibraries( EDA_BASE_FRAME* aParent );
void ClearLibraries();
@@ -51,7 +52,8 @@ protected:
* Constructor; takes a set of libraries to be included in the search.
*/
DESIGN_BLOCK_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent, LIB_TABLE* aLibs,
APP_SETTINGS_BASE::LIB_TREE& aSettings );
APP_SETTINGS_BASE::LIB_TREE& aSettings,
TOOL_INTERACTIVE* aContextMenuTool );
std::vector<LIB_TREE_ITEM*> getDesignBlocks( EDA_BASE_FRAME* aParent,
const wxString& aLibName );
@@ -61,6 +63,7 @@ protected:
protected:
DESIGN_BLOCK_LIB_TABLE* m_libs;
EDA_BASE_FRAME* m_frame;
TOOL_INTERACTIVE* m_contextMenuTool;
};
#endif // DESIGN_BLOCK_TREE_MODEL_ADAPTER_H
+11 -11
View File
@@ -87,17 +87,17 @@ END_EVENT_TABLE()
DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& title,
const wxPoint& pos, const wxSize& size, long style,
const wxString& name ) :
wxDialog( aParent, id, title, pos, size, style, name ),
KIWAY_HOLDER( nullptr, KIWAY_HOLDER::DIALOG ),
m_units( EDA_UNITS::MM ),
m_useCalculatedSize( false ),
m_firstPaintEvent( true ),
m_initialFocusTarget( nullptr ),
m_isClosing( false ),
m_qmodal_loop( nullptr ),
m_qmodal_showing( false ),
m_qmodal_parent_disabler( nullptr ),
m_parentFrame( nullptr )
wxDialog( aParent, id, title, pos, size, style, name ),
KIWAY_HOLDER( nullptr, KIWAY_HOLDER::DIALOG ),
m_units( EDA_UNITS::MILLIMETRES ),
m_useCalculatedSize( false ),
m_firstPaintEvent( true ),
m_initialFocusTarget( nullptr ),
m_isClosing( false ),
m_qmodal_loop( nullptr ),
m_qmodal_showing( false ),
m_qmodal_parent_disabler( nullptr ),
m_parentFrame( nullptr )
{
KIWAY_HOLDER* kiwayHolder = nullptr;
m_initialSize = size;
@@ -24,16 +24,16 @@
#include <dialogs/dialog_design_block_properties.h>
#include <sch_edit_frame.h>
#include <wx/msgdlg.h>
#include <wx/tooltip.h>
#include <grid_tricks.h>
#include <widgets/std_bitmap_button.h>
#include <bitmaps.h>
#include <design_block.h>
DIALOG_DESIGN_BLOCK_PROPERTIES::DIALOG_DESIGN_BLOCK_PROPERTIES( SCH_EDIT_FRAME* aParent,
DESIGN_BLOCK* aDesignBlock ) :
DIALOG_DESIGN_BLOCK_PROPERTIES::DIALOG_DESIGN_BLOCK_PROPERTIES( wxWindow* aParent,
DESIGN_BLOCK* aDesignBlock ) :
DIALOG_DESIGN_BLOCK_PROPERTIES_BASE( aParent ), m_designBlock( aDesignBlock )
{
if( !m_textName->IsEmpty() )
@@ -22,6 +22,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DIALOG_DESIGN_BLOCK_PROPERTIES_H
#define DIALOG_DESIGN_BLOCK_PROPERTIES_H
#include <dialogs/dialog_design_block_properties_base.h>
#include <nlohmann/json.hpp>
@@ -31,7 +34,7 @@ class DESIGN_BLOCK;
class DIALOG_DESIGN_BLOCK_PROPERTIES : public DIALOG_DESIGN_BLOCK_PROPERTIES_BASE
{
public:
DIALOG_DESIGN_BLOCK_PROPERTIES( SCH_EDIT_FRAME* aParent, DESIGN_BLOCK* aDesignBlock );
DIALOG_DESIGN_BLOCK_PROPERTIES( wxWindow* aParent, DESIGN_BLOCK* aDesignBlock );
~DIALOG_DESIGN_BLOCK_PROPERTIES() override;
bool TransferDataToWindow() override;
@@ -50,6 +53,8 @@ public:
private:
void AdjustGridColumns( int aWidth );
DESIGN_BLOCK* m_designBlock;
DESIGN_BLOCK* m_designBlock;
nlohmann::ordered_map<wxString, wxString> m_fields;
};
#endif
@@ -23,7 +23,7 @@ DIALOG_DESIGN_BLOCK_PROPERTIES_BASE::DIALOG_DESIGN_BLOCK_PROPERTIES_BASE( wxWind
bMargins = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* sbFields;
sbFields = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Default Fields") ), wxVERTICAL );
sbFields = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxT("Default Fields") ), wxVERTICAL );
m_fieldsGrid = new WX_GRID( sbFields->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
@@ -39,8 +39,8 @@ DIALOG_DESIGN_BLOCK_PROPERTIES_BASE::DIALOG_DESIGN_BLOCK_PROPERTIES_BASE( wxWind
m_fieldsGrid->SetColSize( 1, 300 );
m_fieldsGrid->EnableDragColMove( false );
m_fieldsGrid->EnableDragColSize( true );
m_fieldsGrid->SetColLabelValue( 0, _("Name") );
m_fieldsGrid->SetColLabelValue( 1, _("Value") );
m_fieldsGrid->SetColLabelValue( 0, wxT("Name") );
m_fieldsGrid->SetColLabelValue( 1, wxT("Value") );
m_fieldsGrid->SetColLabelSize( 22 );
m_fieldsGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
@@ -94,21 +94,21 @@ DIALOG_DESIGN_BLOCK_PROPERTIES_BASE::DIALOG_DESIGN_BLOCK_PROPERTIES_BASE( wxWind
fgProperties->SetFlexibleDirection( wxBOTH );
fgProperties->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticTextName = new wxStaticText( this, wxID_ANY, _("Name:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextName = new wxStaticText( this, wxID_ANY, wxT("Name:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextName->Wrap( -1 );
fgProperties->Add( m_staticTextName, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_textName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgProperties->Add( m_textName, 0, wxEXPAND, 5 );
m_staticTextKeywords = new wxStaticText( this, wxID_ANY, _("Keywords:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextKeywords = new wxStaticText( this, wxID_ANY, wxT("Keywords:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextKeywords->Wrap( -1 );
fgProperties->Add( m_staticTextKeywords, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_textKeywords = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgProperties->Add( m_textKeywords, 0, wxEXPAND, 5 );
m_staticTextDescription = new wxStaticText( this, wxID_ANY, _("Description:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextDescription = new wxStaticText( this, wxID_ANY, wxT("Description:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextDescription->Wrap( -1 );
fgProperties->Add( m_staticTextDescription, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
@@ -15,7 +15,7 @@
<property name="encoding">UTF-8</property>
<property name="file">dialog_design_block_properties_base</property>
<property name="first_id">1000</property>
<property name="internationalize">1</property>
<property name="internationalize">0</property>
<property name="lua_skip_events">1</property>
<property name="lua_ui_table">UI</property>
<property name="name">dialog_design_block_properties_base</property>
@@ -9,7 +9,6 @@
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class STD_BITMAP_BUTTON;
class WX_GRID;
@@ -67,7 +66,7 @@ class DIALOG_DESIGN_BLOCK_PROPERTIES_BASE : public DIALOG_SHIM
public:
DIALOG_DESIGN_BLOCK_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Design Block Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_DESIGN_BLOCK_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Design Block Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_DESIGN_BLOCK_PROPERTIES_BASE();
+6 -6
View File
@@ -77,14 +77,14 @@ bool DIALOG_GRID_SETTINGS::TransferDataFromWindow()
{
double gridX = m_gridSizeX.GetDoubleValue();
if( !m_gridSizeX.Validate( 0.001, 1000.0, EDA_UNITS::MM ) )
if( !m_gridSizeX.Validate( 0.001, 1000.0, EDA_UNITS::MILLIMETRES ) )
{
wxMessageBox( _( "Grid size X out of range." ), _( "Error" ), wxOK | wxICON_ERROR );
return false;
}
if( !m_checkLinked->IsChecked()
&& !m_gridSizeY.Validate( 0.001, 1000.0, EDA_UNITS::MM ) )
&& !m_gridSizeY.Validate( 0.001, 1000.0, EDA_UNITS::MILLIMETRES ) )
{
wxMessageBox( _( "Grid size Y out of range." ), _( "Error" ), wxOK | wxICON_ERROR );
return false;
@@ -94,10 +94,10 @@ bool DIALOG_GRID_SETTINGS::TransferDataFromWindow()
m_grid.name = m_textName->GetValue();
// Grid X/Y are always stored in millimeters so we can compare them easily
m_grid.x = EDA_UNIT_UTILS::UI::StringFromValue( m_unitsProvider->GetIuScale(), EDA_UNITS::MM,
gridX );
m_grid.y = EDA_UNIT_UTILS::UI::StringFromValue( m_unitsProvider->GetIuScale(), EDA_UNITS::MM,
gridY );
m_grid.x = EDA_UNIT_UTILS::UI::StringFromValue( m_unitsProvider->GetIuScale(),
EDA_UNITS::MILLIMETRES, gridX );
m_grid.y = EDA_UNIT_UTILS::UI::StringFromValue( m_unitsProvider->GetIuScale(),
EDA_UNITS::MILLIMETRES, gridY );
return true;
}
+1 -11
View File
@@ -21,13 +21,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "kicad_manager_frame.h"
#include <dialogs/dialog_hotkey_list.h>
#include <kiface_base.h>
#include <eda_base_frame.h>
#include <panel_hotkeys_editor.h>
#include <widgets/ui_common.h>
#include <tool/tool_manager.h>
#include <wx/sizer.h>
#include <wx/button.h>
@@ -41,15 +39,7 @@ DIALOG_LIST_HOTKEYS::DIALOG_LIST_HOTKEYS( EDA_BASE_FRAME* aParent ):
m_hk_list = new PANEL_HOTKEYS_EDITOR( aParent, this, true );
wxWindow* kicadMgr_window = wxWindow::FindWindowByName( KICAD_MANAGER_FRAME_NAME );
if( KICAD_MANAGER_FRAME* kicadMgr = static_cast<KICAD_MANAGER_FRAME*>( kicadMgr_window ) )
{
ACTION_MANAGER* actionMgr = kicadMgr->GetToolManager()->GetActionManager();
for( const auto& [name, action] : actionMgr->GetActions() )
m_hk_list->ActionsList().push_back( action );
}
Kiway().GetActions( m_hk_list->ActionsList() );
kiface = Kiway().KiFACE( KIWAY::FACE_SCH );
kiface->GetActions( m_hk_list->ActionsList() );
+1 -10
View File
@@ -99,27 +99,18 @@ DIALOG_GIT_COMMIT::DIALOG_GIT_COMMIT( wxWindow* parent, git_repository* repo,
m_listCtrl->SetItem( i, 1, _( "New" ) );
m_listCtrl->SetItemImage(
i, static_cast<int>( KIGIT_COMMON::GIT_STATUS::GIT_STATUS_ADDED ) );
if( status & ( GIT_STATUS_INDEX_NEW ) )
m_listCtrl->CheckItem( i, true );
}
else if( status & ( GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_MODIFIED ) )
{
m_listCtrl->SetItem( i, 1, _( "Modified" ) );
m_listCtrl->SetItemImage(
i, static_cast<int>( KIGIT_COMMON::GIT_STATUS::GIT_STATUS_MODIFIED ) );
if( status & ( GIT_STATUS_INDEX_MODIFIED ) )
m_listCtrl->CheckItem( i, true );
}
else if( status & ( GIT_STATUS_INDEX_DELETED | GIT_STATUS_WT_DELETED ) )
{
m_listCtrl->SetItem( i, 1, _( "Deleted" ) );
m_listCtrl->SetItemImage(
i, static_cast<int>( KIGIT_COMMON::GIT_STATUS::GIT_STATUS_DELETED ) );
if( status & ( GIT_STATUS_INDEX_DELETED ) )
m_listCtrl->CheckItem( i, true );
}
else
{
@@ -229,4 +220,4 @@ std::vector<wxString> DIALOG_GIT_COMMIT::GetSelectedFiles() const
}
return selectedFiles;
}
}
+77 -57
View File
@@ -25,9 +25,6 @@
#include <confirm.h>
#include <git2.h>
#include <git/kicad_git_memory.h>
#include <git/kicad_git_common.h>
#include <git/git_repo_mixin.h>
#include <gestfich.h>
#include <cerrno>
@@ -45,6 +42,9 @@ DIALOG_GIT_REPOSITORY::DIALOG_GIT_REPOSITORY( wxWindow* aParent, git_repository*
DIALOG_GIT_REPOSITORY_BASE( aParent ),
m_repository( aRepository ),
m_prevFile( wxEmptyString ),
m_tested( 0 ),
m_failedTest( false ),
m_testError( wxEmptyString ),
m_tempRepo( false )
{
m_txtURL->SetFocus();
@@ -68,17 +68,12 @@ DIALOG_GIT_REPOSITORY::DIALOG_GIT_REPOSITORY( wxWindow* aParent, git_repository*
if( !m_txtURL->GetValue().IsEmpty() )
updateURLData();
else
m_ConnType->SetSelection( static_cast<int>( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_LOCAL ) );
SetupStandardButtons( { { wxID_HELP, _( "Test Connection" ) } } );
Layout();
finishDialogSettings();
SetupStandardButtons();
updateAuthControls();
}
Layout();
}
DIALOG_GIT_REPOSITORY::~DIALOG_GIT_REPOSITORY()
{
@@ -145,13 +140,6 @@ void DIALOG_GIT_REPOSITORY::setDefaultSSHKey()
}
void DIALOG_GIT_REPOSITORY::onCbCustom( wxCommandEvent& event )
{
updateAuthControls();
event.Skip();
}
void DIALOG_GIT_REPOSITORY::OnUpdateUI( wxUpdateUIEvent& event )
{
// event.Enable( !m_txtName->GetValue().IsEmpty() && !m_txtURL->GetValue().IsEmpty() );
@@ -173,7 +161,6 @@ void DIALOG_GIT_REPOSITORY::SetEncrypted( bool aEncrypted )
}
}
std::tuple<bool,wxString,wxString,wxString> DIALOG_GIT_REPOSITORY::isValidHTTPS( const wxString& url )
{
wxRegEx regex( R"((https?:\/\/)(([^:]+)(:([^@]+))?@)?([^\/]+\/[^\s]+))" );
@@ -241,7 +228,6 @@ void DIALOG_GIT_REPOSITORY::updateURLData()
if( valid )
{
m_fullURL = url;
m_ConnType->SetSelection( static_cast<int>( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_HTTPS ) );
SetUsername( username );
SetPassword( password );
@@ -249,6 +235,7 @@ void DIALOG_GIT_REPOSITORY::updateURLData()
if( m_txtName->GetValue().IsEmpty() )
m_txtName->SetValue( get_repo_name( repoAddress ) );
}
}
else if( url.Contains( "ssh://" ) || url.Contains( "git@" ) )
@@ -257,7 +244,6 @@ void DIALOG_GIT_REPOSITORY::updateURLData()
if( valid )
{
m_fullURL = url;
m_ConnType->SetSelection( static_cast<int>( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_SSH ) );
m_txtUsername->SetValue( username );
m_txtURL->SetValue( repoAddress );
@@ -273,11 +259,6 @@ void DIALOG_GIT_REPOSITORY::updateURLData()
void DIALOG_GIT_REPOSITORY::OnTestClick( wxCommandEvent& event )
{
if( m_txtURL->GetValue().Trim().Trim( false ).IsEmpty() )
return;
wxString error;
bool success = false;
git_remote* remote = nullptr;
git_remote_callbacks callbacks;
git_remote_init_callbacks( &callbacks, GIT_REMOTE_CALLBACKS_VERSION );
@@ -285,40 +266,81 @@ void DIALOG_GIT_REPOSITORY::OnTestClick( wxCommandEvent& event )
// We track if we have already tried to connect.
// If we have, the server may come back to offer another connection
// type, so we need to keep track of how many times we have tried.
m_tested = 0;
KIGIT_COMMON common( m_repository );
common.SetRemote( m_txtURL->GetValue() );
callbacks.credentials = credentials_cb;
common.SetPassword( m_txtPassword->GetValue() );
common.SetUsername( m_txtUsername->GetValue() );
common.SetSSHKey( m_fpSSHKey->GetFileName().GetFullPath() );
KIGIT_REPO_MIXIN repoMixin( &common );
callbacks.payload = &repoMixin;
callbacks.credentials = []( git_cred** aOut, const char* aUrl, const char* aUsername,
unsigned int aAllowedTypes, void* aPayload ) -> int
{
DIALOG_GIT_REPOSITORY* dialog = static_cast<DIALOG_GIT_REPOSITORY*>( aPayload );
if( dialog->GetRepoType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_LOCAL )
return GIT_PASSTHROUGH;
if( aAllowedTypes & GIT_CREDTYPE_USERNAME
&& !( dialog->GetTested() & GIT_CREDTYPE_USERNAME ) )
{
wxString username = dialog->GetUsername().Trim().Trim( false );
git_cred_username_new( aOut, username.ToStdString().c_str() );
dialog->GetTested() |= GIT_CREDTYPE_USERNAME;
}
else if( dialog->GetRepoType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_HTTPS
&& ( aAllowedTypes & GIT_CREDTYPE_USERPASS_PLAINTEXT )
&& !( dialog->GetTested() & GIT_CREDTYPE_USERPASS_PLAINTEXT ) )
{
wxString username = dialog->GetUsername().Trim().Trim( false );
wxString password = dialog->GetPassword().Trim().Trim( false );
git_cred_userpass_plaintext_new( aOut, username.ToStdString().c_str(),
password.ToStdString().c_str() );
dialog->GetTested() |= GIT_CREDTYPE_USERPASS_PLAINTEXT;
}
else if( dialog->GetRepoType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_SSH
&& ( aAllowedTypes & GIT_CREDTYPE_SSH_KEY )
&& !( dialog->GetTested() & GIT_CREDTYPE_SSH_KEY ) )
{
// SSH key authentication
wxString sshKey = dialog->GetRepoSSHPath();
wxString sshPubKey = sshKey + ".pub";
wxString username = dialog->GetUsername().Trim().Trim( false );
wxString password = dialog->GetPassword().Trim().Trim( false );
git_cred_ssh_key_new( aOut, username.ToStdString().c_str(),
sshPubKey.ToStdString().c_str(), sshKey.ToStdString().c_str(),
password.ToStdString().c_str() );
dialog->GetTested() |= GIT_CREDTYPE_SSH_KEY;
}
else
{
return GIT_PASSTHROUGH;
}
return GIT_OK;
};
callbacks.payload = this;
wxString txtURL = m_txtURL->GetValue();
git_remote_create_with_fetchspec( &remote, m_repository, "origin", txtURL.mbc_str(),
git_remote_create_with_fetchspec( &remote, m_repository, "origin", txtURL.ToStdString().c_str(),
"+refs/heads/*:refs/remotes/origin/*" );
KIGIT::GitRemotePtr remotePtr( remote );
if( git_remote_connect( remote, GIT_DIRECTION_FETCH, &callbacks, nullptr, nullptr ) == GIT_OK )
success = true;
if( git_remote_connect( remote, GIT_DIRECTION_FETCH, &callbacks, nullptr, nullptr ) != GIT_OK )
SetTestResult( true, git_error_last()->message );
else
error = KIGIT_COMMON::GetLastGitError();
SetTestResult( false, wxEmptyString );
git_remote_disconnect( remote );
git_remote_free( remote );
auto dlg = wxMessageDialog( this, wxEmptyString, _( "Test Connection" ),
wxOK | wxICON_INFORMATION );
auto dlg = wxMessageDialog( this, wxEmptyString, _( "Test connection" ), wxOK | wxICON_INFORMATION );
if( success )
if( !m_failedTest )
{
dlg.SetMessage( _( "Connection successful" ) );
}
else
{
dlg.SetMessage( wxString::Format( _( "Could not connect to '%s' " ),
m_txtURL->GetValue() ) );
dlg.SetExtendedMessage( error );
dlg.SetMessage( wxString::Format( _( "Could not connect to '%s' " ), m_txtURL->GetValue() ) );
dlg.SetExtendedMessage( m_testError );
}
dlg.ShowModal();
@@ -413,30 +435,28 @@ void DIALOG_GIT_REPOSITORY::updateAuthControls()
{
if( m_ConnType->GetSelection() == static_cast<int>( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_LOCAL ) )
{
m_panelAuth->Enable( false );
m_panelAuth->Show( false );
}
else
{
m_panelAuth->Enable( true );
m_panelAuth->Show( true );
if( m_ConnType->GetSelection() == static_cast<int>( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_SSH ) )
{
m_cbCustom->Enable( true );
m_fpSSHKey->Enable( m_cbCustom->IsChecked() );
m_txtUsername->Enable( m_cbCustom->IsChecked() );
m_txtPassword->Enable( m_cbCustom->IsChecked() );
m_labelPass1->SetLabel( _( "SSH key password:" ) );
m_fpSSHKey->Show( true );
m_labelSSH->Show( true );
m_labelPass1->SetLabel( _( "SSH Key Password" ) );
}
else
{
m_cbCustom->Enable( false );
m_fpSSHKey->Enable( false );
m_txtUsername->Enable( true );
m_txtPassword->Enable( true );
m_labelPass1->SetLabel( _( "Password:" ) );
m_fpSSHKey->Show( false );
m_labelSSH->Show( false );
m_labelPass1->SetLabel( _( "Password" ) );
setDefaultSSHKey();
}
}
Layout();
}
+12 -4
View File
@@ -36,6 +36,12 @@ public:
wxString aURL = wxEmptyString );
~DIALOG_GIT_REPOSITORY() override;
void SetTestResult( bool aFailed, const wxString& aError )
{
m_failedTest = aFailed;
m_testError = aError;
}
void SetRepoType( KIGIT_COMMON::GIT_CONN_TYPE aType )
{
m_ConnType->SetSelection( static_cast<int>( aType ) );
@@ -72,8 +78,6 @@ public:
return url;
}
const wxString& GetFullURL() const { return m_fullURL; }
void SetUsername( const wxString& aUsername ) { m_txtUsername->SetValue( aUsername ); }
wxString GetUsername() const { return m_txtUsername->GetValue(); }
@@ -83,6 +87,8 @@ public:
void SetRepoSSHPath( const wxString& aPath ) { m_fpSSHKey->SetFileName( aPath ); m_prevFile = aPath; }
wxString GetRepoSSHPath() const { return m_fpSSHKey->GetFileName().GetFullPath(); }
unsigned& GetTested() { return m_tested; }
void SetEncrypted( bool aEncrypted = true );
private:
@@ -94,7 +100,6 @@ private:
void OnTestClick( wxCommandEvent& event ) override;
void OnFileUpdated( wxFileDirPickerEvent& event ) override;
void onCbCustom( wxCommandEvent& event ) override;
void setDefaultSSHKey();
@@ -107,10 +112,13 @@ private:
private:
git_repository* m_repository;
wxString m_fullURL;
wxString m_prevFile;
unsigned m_tested;
bool m_failedTest;
wxString m_testError;
bool m_tempRepo;
wxString m_tempPath;
};
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// C++ code generated with wxFormBuilder (version 3.10.1-254-gc2ef7767)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -13,6 +13,7 @@ DIALOG_GIT_REPOSITORY_BASE::DIALOG_GIT_REPOSITORY_BASE( wxWindow* parent, wxWind
{
this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
wxBoxSizer* bSizerMain;
bSizerMain = new wxBoxSizer( wxVERTICAL );
m_staticText1 = new wxStaticText( this, wxID_ANY, _("Connection"), wxDefaultPosition, wxDefaultSize, 0 );
@@ -20,37 +21,31 @@ DIALOG_GIT_REPOSITORY_BASE::DIALOG_GIT_REPOSITORY_BASE( wxWindow* parent, wxWind
bSizerMain->Add( m_staticText1, 0, wxLEFT|wxTOP, 10 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizerMain->Add( m_staticline1, 0, wxALL|wxEXPAND, 5 );
bSizerMain->Add( m_staticline1, 0, wxEXPAND|wxTOP, 5 );
wxFlexGridSizer* fgSizer2;
fgSizer2 = new wxFlexGridSizer( 0, 2, 5, 0 );
fgSizer2 = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizer2->AddGrowableCol( 1 );
fgSizer2->SetFlexibleDirection( wxBOTH );
fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText3 = new wxStaticText( this, wxID_ANY, _("Name:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText3 = new wxStaticText( this, wxID_ANY, _("Name"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText3->Wrap( -1 );
m_staticText3->Hide();
fgSizer2->Add( m_staticText3, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
fgSizer2->Add( m_staticText3, 0, wxALL, 5 );
m_txtName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_txtName->Hide();
fgSizer2->Add( m_txtName, 0, wxALL|wxEXPAND, 5 );
fgSizer2->Add( m_txtName, 0, wxEXPAND|wxRIGHT, 5 );
m_staticText4 = new wxStaticText( this, wxID_ANY, _("Location:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText4 = new wxStaticText( this, wxID_ANY, _("Location"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText4->Wrap( -1 );
fgSizer2->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
fgSizer2->Add( m_staticText4, 0, wxALL, 5 );
m_txtURL = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_txtURL, 0, wxEXPAND|wxRIGHT, 5 );
fgSizer2->Add( m_txtURL, 0, wxALL|wxEXPAND, 5 );
m_staticText9 = new wxStaticText( this, wxID_ANY, _("Connection type:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText9 = new wxStaticText( this, wxID_ANY, _("Connection Type"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText9->Wrap( -1 );
m_staticText9->Hide();
fgSizer2->Add( m_staticText9, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
fgSizer2->Add( m_staticText9, 0, wxALL, 5 );
wxBoxSizer* bSizer3;
bSizer3 = new wxBoxSizer( wxHORIZONTAL );
@@ -59,84 +54,97 @@ DIALOG_GIT_REPOSITORY_BASE::DIALOG_GIT_REPOSITORY_BASE( wxWindow* parent, wxWind
int m_ConnTypeNChoices = sizeof( m_ConnTypeChoices ) / sizeof( wxString );
m_ConnType = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_ConnTypeNChoices, m_ConnTypeChoices, 0 );
m_ConnType->SetSelection( 0 );
m_ConnType->Hide();
bSizer3->Add( m_ConnType, 0, wxRIGHT, 5 );
bSizer3->Add( m_ConnType, 1, wxEXPAND|wxLEFT|wxRIGHT, 5 );
bSizer3->Add( 0, 0, 0, wxEXPAND, 5 );
bSizer3->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizer2->Add( bSizer3, 1, wxEXPAND, 5 );
bSizerMain->Add( fgSizer2, 0, wxEXPAND, 5 );
bSizerMain->Add( fgSizer2, 1, wxEXPAND, 5 );
m_panelAuth = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* m_szAuth;
m_szAuth = new wxBoxSizer( wxVERTICAL );
m_szAuth->Add( 0, 0, 1, wxEXPAND, 5 );
wxBoxSizer* bSizer11;
bSizer11 = new wxBoxSizer( wxHORIZONTAL );
m_staticText2 = new wxStaticText( m_panelAuth, wxID_ANY, _("Authentication"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText2->Wrap( -1 );
m_szAuth->Add( m_staticText2, 0, wxLEFT|wxTOP, 10 );
bSizer11->Add( m_staticText2, 0, wxLEFT|wxTOP, 10 );
bSizer11->Add( 0, 0, 1, wxEXPAND, 5 );
m_szAuth->Add( bSizer11, 0, wxEXPAND, 5 );
m_staticline2 = new wxStaticLine( m_panelAuth, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
m_szAuth->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 );
wxFlexGridSizer* fgSizer21;
fgSizer21 = new wxFlexGridSizer( 0, 2, 5, 0 );
fgSizer21->SetFlexibleDirection( wxBOTH );
fgSizer21->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
wxFlexGridSizer* fgSshSizer;
fgSshSizer = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSshSizer->AddGrowableCol( 1 );
fgSshSizer->SetFlexibleDirection( wxBOTH );
fgSshSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_cbCustom = new wxCheckBox( m_panelAuth, wxID_ANY, _("SSH private key: "), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer21->Add( m_cbCustom, 0, wxALL, 5 );
m_labelSSH = new wxStaticText( m_panelAuth, wxID_ANY, _("SSH Private Key"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelSSH->Wrap( -1 );
fgSshSizer->Add( m_labelSSH, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 5 );
wxBoxSizer* bSizer41;
bSizer41 = new wxBoxSizer( wxHORIZONTAL );
m_fpSSHKey = new wxFilePickerCtrl( m_panelAuth, wxID_ANY, wxEmptyString, _("Select SSH private key file"), _("*"), wxDefaultPosition, wxDefaultSize, wxFLP_DEFAULT_STYLE|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN );
m_fpSSHKey->SetMinSize( wxSize( 250,-1 ) );
bSizer41->Add( m_fpSSHKey, 1, wxEXPAND|wxLEFT|wxRESERVE_SPACE_EVEN_IF_HIDDEN|wxRIGHT, 5 );
fgSizer21->Add( m_fpSSHKey, 0, wxEXPAND|wxRIGHT, 5 );
m_btnTest = new wxButton( m_panelAuth, wxID_ANY, _("Test"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer41->Add( m_btnTest, 0, wxLEFT|wxRIGHT, 5 );
m_staticText11 = new wxStaticText( m_panelAuth, wxID_ANY, _("User name:"), wxDefaultPosition, wxDefaultSize, 0 );
fgSshSizer->Add( bSizer41, 1, wxEXPAND, 5 );
m_staticText11 = new wxStaticText( m_panelAuth, wxID_ANY, _("Username"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText11->Wrap( -1 );
fgSizer21->Add( m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
fgSshSizer->Add( m_staticText11, 0, wxALL, 5 );
m_txtUsername = new wxTextCtrl( m_panelAuth, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer21->Add( m_txtUsername, 0, wxEXPAND|wxRIGHT, 5 );
fgSshSizer->Add( m_txtUsername, 0, wxALL|wxEXPAND, 5 );
m_labelPass1 = new wxStaticText( m_panelAuth, wxID_ANY, _("SSH key password:"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelPass1 = new wxStaticText( m_panelAuth, wxID_ANY, _("SSH Key Password"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelPass1->Wrap( -1 );
fgSizer21->Add( m_labelPass1, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
fgSshSizer->Add( m_labelPass1, 0, wxALL, 5 );
m_txtPassword = new wxTextCtrl( m_panelAuth, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer21->Add( m_txtPassword, 0, wxEXPAND|wxRIGHT, 5 );
fgSshSizer->Add( m_txtPassword, 0, wxALL|wxEXPAND, 5 );
m_szAuth->Add( fgSizer21, 1, wxBOTTOM|wxEXPAND, 5 );
m_szAuth->Add( fgSshSizer, 1, wxEXPAND, 5 );
m_panelAuth->SetSizer( m_szAuth );
m_panelAuth->Layout();
m_szAuth->Fit( m_panelAuth );
bSizerMain->Add( m_panelAuth, 0, wxEXPAND|wxTOP, 5 );
bSizerMain->Add( 0, 0, 1, wxEXPAND, 5 );
bSizerMain->Add( m_panelAuth, 1, wxALL|wxEXPAND|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 0 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
m_sdbSizer->AddButton( m_sdbSizerOK );
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizerHelp = new wxButton( this, wxID_HELP );
m_sdbSizer->AddButton( m_sdbSizerHelp );
m_sdbSizer->Realize();
bSizerMain->Add( m_sdbSizer, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 );
bSizerMain->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 5 );
this->SetSizer( bSizerMain );
this->Layout();
bSizerMain->Fit( this );
this->Centre( wxBOTH );
@@ -145,9 +153,8 @@ DIALOG_GIT_REPOSITORY_BASE::DIALOG_GIT_REPOSITORY_BASE( wxWindow* parent, wxWind
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnUpdateUI ) );
m_txtURL->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnLocationExit ), NULL, this );
m_ConnType->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnSelectConnType ), NULL, this );
m_cbCustom->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::onCbCustom ), NULL, this );
m_fpSSHKey->Connect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnFileUpdated ), NULL, this );
m_sdbSizerHelp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnTestClick ), NULL, this );
m_btnTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnTestClick ), NULL, this );
m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnOKClick ), NULL, this );
}
@@ -158,9 +165,8 @@ DIALOG_GIT_REPOSITORY_BASE::~DIALOG_GIT_REPOSITORY_BASE()
this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnUpdateUI ) );
m_txtURL->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnLocationExit ), NULL, this );
m_ConnType->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnSelectConnType ), NULL, this );
m_cbCustom->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::onCbCustom ), NULL, this );
m_fpSSHKey->Disconnect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnFileUpdated ), NULL, this );
m_sdbSizerHelp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnTestClick ), NULL, this );
m_btnTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnTestClick ), NULL, this );
m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GIT_REPOSITORY_BASE::OnOKClick ), NULL, this );
}
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// C++ code generated with wxFormBuilder (version 3.10.1-254-gc2ef7767)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -21,14 +21,17 @@
#include <wx/textctrl.h>
#include <wx/choice.h>
#include <wx/sizer.h>
#include <wx/checkbox.h>
#include <wx/filepicker.h>
#include <wx/panel.h>
#include <wx/button.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/panel.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_GIT_REPOSITORY_BASE
///////////////////////////////////////////////////////////////////////////////
@@ -37,7 +40,6 @@ class DIALOG_GIT_REPOSITORY_BASE : public DIALOG_SHIM
private:
protected:
wxBoxSizer* bSizerMain;
wxStaticText* m_staticText1;
wxStaticLine* m_staticline1;
wxStaticText* m_staticText3;
@@ -49,8 +51,9 @@ class DIALOG_GIT_REPOSITORY_BASE : public DIALOG_SHIM
wxPanel* m_panelAuth;
wxStaticText* m_staticText2;
wxStaticLine* m_staticline2;
wxCheckBox* m_cbCustom;
wxStaticText* m_labelSSH;
wxFilePickerCtrl* m_fpSSHKey;
wxButton* m_btnTest;
wxStaticText* m_staticText11;
wxTextCtrl* m_txtUsername;
wxStaticText* m_labelPass1;
@@ -58,14 +61,12 @@ class DIALOG_GIT_REPOSITORY_BASE : public DIALOG_SHIM
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
wxButton* m_sdbSizerHelp;
// Virtual event handlers, override them in your derived class
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnLocationExit( wxFocusEvent& event ) { event.Skip(); }
virtual void OnSelectConnType( wxCommandEvent& event ) { event.Skip(); }
virtual void onCbCustom( wxCommandEvent& event ) { event.Skip(); }
virtual void OnFileUpdated( wxFileDirPickerEvent& event ) { event.Skip(); }
virtual void OnTestClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOKClick( wxCommandEvent& event ) { event.Skip(); }
@@ -73,7 +74,7 @@ class DIALOG_GIT_REPOSITORY_BASE : public DIALOG_SHIM
public:
DIALOG_GIT_REPOSITORY_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Git Repository"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxCAPTION|wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_GIT_REPOSITORY_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Git Repository"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 682,598 ), long style = wxCAPTION|wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_GIT_REPOSITORY_BASE();
+13 -15
View File
@@ -24,13 +24,9 @@
#include "dialog_git_switch.h"
#include <git/kicad_git_memory.h>
#include <trace_helpers.h>
#include <wx/button.h>
#include <wx/checkbox.h>
#include <wx/listctrl.h>
#include <wx/log.h>
#include <wx/event.h>
#include <wx/sizer.h>
#include <wx/timer.h>
@@ -244,42 +240,39 @@ void DIALOG_GIT_SWITCH::GetBranches()
git_reference* currentBranchReference = nullptr;
git_repository_head( &currentBranchReference, m_repository );
if( !currentBranchReference )
// Get the current branch name
if( currentBranchReference )
{
wxLogTrace( traceGit, "Failed to get current branch" );
return;
m_currentBranch = git_reference_shorthand( currentBranchReference );
git_reference_free( currentBranchReference );
}
KIGIT::GitReferencePtr currentBranch( currentBranchReference );
m_currentBranch = git_reference_shorthand( currentBranchReference );
// Initialize branch iterator
git_branch_iterator_new( &branchIterator, m_repository, GIT_BRANCH_ALL );
KIGIT::GitBranchIteratorPtr branchIteratorPtr( branchIterator );
// Iterate over local branches
git_reference* branchReference = nullptr;
while( git_branch_next( &branchReference, &branchType, branchIterator ) == 0 )
{
KIGIT::GitReferencePtr branchReferencePtr( branchReference );
// Get the branch OID
const git_oid* branchOid = git_reference_target( branchReference );
// Skip this branch if it doesn't have an OID
if( !branchOid )
{
git_reference_free( branchReference );
continue;
}
git_commit* commit = nullptr;
if( git_commit_lookup( &commit, m_repository, branchOid ) )
{
// Skip this branch if it doesn't have a commit
git_reference_free( branchReference );
continue;
}
KIGIT::GitCommitPtr commitPtr( commit );
// Retrieve commit details
BranchData branchData;
branchData.commitString = git_commit_message( commit );
@@ -287,5 +280,10 @@ void DIALOG_GIT_SWITCH::GetBranches()
branchData.isRemote = branchType == GIT_BRANCH_REMOTE;
m_branches[git_reference_shorthand( branchReference )] = branchData;
git_commit_free( commit );
git_reference_free( branchReference );
}
git_branch_iterator_free( branchIterator );
}
+274 -41
View File
@@ -24,12 +24,10 @@
#include <kiplatform/secrets.h>
#include <pgm_base.h>
#include <settings/common_settings.h>
#include <trace_helpers.h>
#include <widgets/std_bitmap_button.h>
#include <widgets/wx_grid.h>
#include <git2.h>
#include <git/kicad_git_memory.h>
#include <wx/bmpbuttn.h>
#include <wx/button.h>
#include <wx/checkbox.h>
@@ -38,6 +36,11 @@
PANEL_GIT_REPOS::PANEL_GIT_REPOS( wxWindow* aParent ) : PANEL_GIT_REPOS_BASE( aParent)
{
m_btnAddRepo->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
m_btnEditRepo->SetBitmap( KiBitmapBundle( BITMAPS::small_edit ) );
m_btnDelete->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
}
PANEL_GIT_REPOS::~PANEL_GIT_REPOS()
@@ -47,6 +50,7 @@ PANEL_GIT_REPOS::~PANEL_GIT_REPOS()
void PANEL_GIT_REPOS::ResetPanel()
{
m_grid->ClearGrid();
m_cbDefault->SetValue( true );
m_author->SetValue( wxEmptyString );
m_authorEmail->SetValue( wxEmptyString );
@@ -63,44 +67,56 @@ static std::pair<wxString, wxString> getDefaultAuthorAndEmail()
if( git_config_open_default( &config ) != 0 )
{
wxLogTrace( traceGit, "Failed to open default Git config: %s", KIGIT_COMMON::GetLastGitError() );
printf( "Failed to open default Git config: %s\n", giterr_last()->message );
return std::make_pair( name, email );
}
KIGIT::GitConfigPtr configPtr( config );
if( git_config_get_entry( &name_c, config, "user.name" ) != 0 )
{
wxLogTrace( traceGit, "Failed to get user.name from Git config: %s", KIGIT_COMMON::GetLastGitError() );
return std::make_pair( name, email );
printf( "Failed to get user.name from Git config: %s\n", giterr_last()->message );
}
KIGIT::GitConfigEntryPtr namePtr( name_c );
if( git_config_get_entry( &email_c, config, "user.email" ) != 0 )
{
wxLogTrace( traceGit, "Failed to get user.email from Git config: %s", KIGIT_COMMON::GetLastGitError() );
return std::make_pair( name, email );
printf( "Failed to get user.email from Git config: %s\n", giterr_last()->message );
}
KIGIT::GitConfigEntryPtr emailPtr( email_c );
if( name_c )
name = name_c->value;
if( email_c )
email = email_c->value;
git_config_entry_free( name_c );
git_config_entry_free( email_c );
git_config_free( config );
return std::make_pair( name, email );
}
bool PANEL_GIT_REPOS::TransferDataFromWindow()
{
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
std::vector<COMMON_SETTINGS::GIT_REPOSITORY>& repos = settings->m_Git.repositories;
repos.clear();
for( int row = 0; row < m_grid->GetNumberRows(); row++ )
{
COMMON_SETTINGS::GIT_REPOSITORY repo;
repo.active = m_grid->GetCellValue( row, COL_ACTIVE ) == "1";
repo.name = m_grid->GetCellValue( row, COL_NAME );
repo.path = m_grid->GetCellValue( row, COL_PATH );
repo.authType = m_grid->GetCellValue( row, COL_AUTH_TYPE );
repo.username = m_grid->GetCellValue( row, COL_USERNAME );
KIPLATFORM::SECRETS::StoreSecret( repo.path, repo.username,
m_grid->GetCellValue( row, COL_PASSWORD ) );
repo.ssh_path = m_grid->GetCellValue( row, COL_SSH_PATH );
repo.checkValid = m_grid->GetCellValue( row, COL_STATUS ) == "1";
repos.push_back( repo );
}
settings->m_Git.enableGit = m_enableGit->GetValue();
settings->m_Git.updatInterval = m_updateInterval->GetValue();
settings->m_Git.useDefaultAuthor = m_cbDefault->GetValue();
settings->m_Git.authorName = m_author->GetValue();
settings->m_Git.authorEmail = m_authorEmail->GetValue();
@@ -108,38 +124,153 @@ bool PANEL_GIT_REPOS::TransferDataFromWindow()
return true;
}
static bool testRepositoryConnection( COMMON_SETTINGS::GIT_REPOSITORY& repository)
{
git_libgit2_init();
git_remote_callbacks callbacks;
callbacks.version = GIT_REMOTE_CALLBACKS_VERSION;
typedef struct
{
COMMON_SETTINGS::GIT_REPOSITORY* repo;
bool success;
} callbacksPayload;
callbacksPayload cb_data( { &repository, true } ); // If we don't need authentication, then,
// we are successful
callbacks.payload = &cb_data;
callbacks.credentials =
[](git_cred** out, const char* url, const char* username, unsigned int allowed_types,
void* payload) -> int
{
// If we are asking for credentials, then, we need authentication
callbacksPayload* data = static_cast<callbacksPayload*>(payload);
data->success = false;
if( allowed_types & GIT_CREDTYPE_USERNAME )
{
data->success = true;
}
else if( data->repo->authType == "ssh" && ( allowed_types & GIT_CREDTYPE_SSH_KEY ) )
{
wxString sshKeyPath = data->repo->ssh_path;
// Check if the SSH key exists and is readable
if( wxFileExists( sshKeyPath ) && wxFile::Access( sshKeyPath, wxFile::read ) )
data->success = true;
}
else if( data->repo->authType == "password" )
{
data->success = ( allowed_types & GIT_CREDTYPE_USERPASS_PLAINTEXT );
}
return 0;
};
// Create a temporary directory to initialize the Git repository
wxString tempDirPath = wxFileName::CreateTempFileName(wxT("kigit_temp"));
if( !wxFileName::Mkdir( tempDirPath, wxS_DIR_DEFAULT ) )
{
git_libgit2_shutdown();
wxLogError( "Failed to create temporary directory for Git repository (%s): %s", tempDirPath,
wxSysErrorMsg() );
return false;
}
// Initialize the Git repository
git_repository* repo = nullptr;
int result = git_repository_init( &repo, tempDirPath.mb_str( wxConvUTF8 ), 0 );
if (result != 0)
{
git_repository_free(repo);
git_libgit2_shutdown();
wxRmdir(tempDirPath);
return false;
}
git_remote* remote = nullptr;
result = git_remote_create_anonymous( &remote, repo, tempDirPath.mb_str( wxConvUTF8 ) );
if (result != 0)
{
git_remote_free(remote);
git_repository_free(repo);
git_libgit2_shutdown();
wxRmdir(tempDirPath);
return false;
}
// We don't really care about the result of this call, the authentication callback
// will set the return values we need
git_remote_connect(remote, GIT_DIRECTION_FETCH, &callbacks, nullptr, nullptr);
git_remote_disconnect(remote);
git_remote_free(remote);
git_repository_free(repo);
git_libgit2_shutdown();
// Clean up the temporary directory
wxRmdir(tempDirPath);
return cb_data.success;
}
bool PANEL_GIT_REPOS::TransferDataToWindow()
{
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
std::pair<wxString, wxString> defaultAuthor = getDefaultAuthorAndEmail();
m_enableGit->SetValue( settings->m_Git.enableGit );
m_updateInterval->SetValue( settings->m_Git.updatInterval );
m_grid->ClearGrid();
for( COMMON_SETTINGS::GIT_REPOSITORY& repo : settings->m_Git.repositories )
{
if( repo.name.IsEmpty() || repo.path.IsEmpty() )
continue;
int row = m_grid->GetNumberRows();
m_grid->AppendRows( 1 );
m_grid->SetCellRenderer( row, COL_ACTIVE, new wxGridCellBoolRenderer() );
m_grid->SetCellEditor( row, COL_ACTIVE, new wxGridCellBoolEditor() );
m_grid->SetCellValue( row, COL_ACTIVE, repo.active ? "1" : "0" );
m_grid->SetCellValue( row, COL_NAME, repo.name );
m_grid->SetCellValue( row, COL_PATH, repo.path );
m_grid->SetCellValue( row, COL_AUTH_TYPE, repo.authType );
m_grid->SetCellValue( row, COL_USERNAME, repo.username );
wxString password;
KIPLATFORM::SECRETS::GetSecret( repo.path, repo.username, password );
m_grid->SetCellValue( row, COL_PASSWORD, password );
m_grid->SetCellValue( row, COL_SSH_PATH, repo.ssh_path );
if( repo.active )
m_grid->SetCellValue( row, 3, testRepositoryConnection( repo ) ? "C" : "NC" );
}
m_cbDefault->SetValue( settings->m_Git.useDefaultAuthor );
if( settings->m_Git.useDefaultAuthor )
{
std::pair<wxString, wxString> defaultAuthor = getDefaultAuthorAndEmail();
m_author->SetValue( defaultAuthor.first );
m_authorEmail->SetValue( defaultAuthor.second );
m_author->Disable();
m_authorEmail->Disable();
}
else
{
if( settings->m_Git.authorName.IsEmpty() )
m_author->SetValue( defaultAuthor.first );
else
m_author->SetValue( settings->m_Git.authorName );
if( settings->m_Git.authorEmail.IsEmpty() )
m_authorEmail->SetValue( defaultAuthor.second );
else
m_authorEmail->SetValue( settings->m_Git.authorEmail );
m_author->SetValue( settings->m_Git.authorName );
m_authorEmail->SetValue( settings->m_Git.authorEmail );
}
wxCommandEvent event;
onDefaultClick( event );
onEnableGitClick( event );
return true;
}
@@ -151,13 +282,115 @@ void PANEL_GIT_REPOS::onDefaultClick( wxCommandEvent& event )
m_authorEmailLabel->Enable( !m_cbDefault->GetValue() );
}
void PANEL_GIT_REPOS::onEnableGitClick( wxCommandEvent& aEvent )
void PANEL_GIT_REPOS::onGridDClick( wxGridEvent& event )
{
bool enable = m_enableGit->GetValue();
m_updateInterval->Enable( enable );
m_cbDefault->Enable( enable );
m_author->Enable( enable && !m_cbDefault->GetValue() );
m_authorEmail->Enable( enable && !m_cbDefault->GetValue() );
m_authorLabel->Enable( enable && !m_cbDefault->GetValue() );
m_authorEmailLabel->Enable( enable && !m_cbDefault->GetValue() );
if( m_grid->GetNumberRows() <= 0 )
{
wxCommandEvent evt;
onAddClick( evt );
return;
}
int row = event.GetRow();
if( row < 0 || row >= m_grid->GetNumberRows() )
return;
DIALOG_GIT_REPOSITORY dialog( this, nullptr );
dialog.SetRepoName( m_grid->GetCellValue( row, COL_NAME ) );
dialog.SetRepoURL( m_grid->GetCellValue( row, COL_PATH ) );
dialog.SetUsername( m_grid->GetCellValue( row, COL_USERNAME ) );
dialog.SetRepoSSHPath( m_grid->GetCellValue( row, COL_SSH_PATH ) );
dialog.SetPassword( m_grid->GetCellValue( row, COL_PASSWORD ) );
wxString type = m_grid->GetCellValue( row, COL_AUTH_TYPE );
if( type == "password" )
dialog.SetRepoType( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_HTTPS );
else if( type == "ssh" )
dialog.SetRepoType( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_SSH );
else
dialog.SetRepoType( KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_LOCAL);
if( dialog.ShowModal() == wxID_OK )
{
m_grid->SetCellValue( row, COL_NAME, dialog.GetRepoName() );
m_grid->SetCellValue( row, COL_PATH, dialog.GetRepoURL() );
m_grid->SetCellValue( row, COL_USERNAME, dialog.GetUsername() );
m_grid->SetCellValue( row, COL_SSH_PATH, dialog.GetRepoSSHPath() );
m_grid->SetCellValue( row, COL_PASSWORD, dialog.GetPassword() );
if( dialog.GetRepoType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_HTTPS )
{
m_grid->SetCellValue( row, COL_AUTH_TYPE, "password" );
}
else if( dialog.GetRepoType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_SSH )
{
m_grid->SetCellValue( row, COL_AUTH_TYPE, "ssh" );
}
else
{
m_grid->SetCellValue( row, COL_AUTH_TYPE, "none" );
}
}
}
void PANEL_GIT_REPOS::onAddClick( wxCommandEvent& event )
{
DIALOG_GIT_REPOSITORY dialog( m_parent, nullptr );
if( dialog.ShowModal() == wxID_OK )
{
int row = m_grid->GetNumberRows();
m_grid->AppendRows( 1 );
m_grid->SetCellValue( row, COL_NAME, dialog.GetRepoName() );
m_grid->SetCellValue( row, COL_PATH, dialog.GetRepoURL() );
m_grid->SetCellValue( row, COL_USERNAME, dialog.GetUsername() );
m_grid->SetCellValue( row, COL_SSH_PATH, dialog.GetRepoSSHPath() );
m_grid->SetCellValue( row, COL_PASSWORD, dialog.GetPassword() );
if( dialog.GetRepoType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_HTTPS )
{
m_grid->SetCellValue( row, COL_AUTH_TYPE, "password" );
}
else if( dialog.GetRepoType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_SSH )
{
m_grid->SetCellValue( row, COL_AUTH_TYPE, "ssh" );
}
else
{
m_grid->SetCellValue( row, COL_AUTH_TYPE, "none" );
}
m_grid->MakeCellVisible( row, 0 );
}
}
void PANEL_GIT_REPOS::onEditClick( wxCommandEvent& event )
{
wxGridEvent evt( m_grid->GetId(), wxEVT_GRID_CELL_LEFT_DCLICK, m_grid,
m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
onGridDClick( evt );
}
void PANEL_GIT_REPOS::onDeleteClick( wxCommandEvent& event )
{
if( !m_grid->CommitPendingChanges() || m_grid->GetNumberRows() <= 0 )
return;
int curRow = m_grid->GetGridCursorRow();
m_grid->DeleteRows( curRow );
curRow = std::max( 0, curRow - 1 );
m_grid->MakeCellVisible( curRow, m_grid->GetGridCursorCol() );
m_grid->SetGridCursor( curRow, m_grid->GetGridCursorCol() );
}
+4 -1
View File
@@ -49,7 +49,10 @@ public:
private:
void onDefaultClick( wxCommandEvent& event ) override;
void onEnableGitClick( wxCommandEvent& event ) override;
void onGridDClick( wxGridEvent& event ) override;
void onAddClick( wxCommandEvent& event ) override;
void onEditClick( wxCommandEvent& event ) override;
void onDeleteClick( wxCommandEvent& event ) override;
};
+87 -55
View File
@@ -1,10 +1,13 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// C++ code generated with wxFormBuilder (version 3.10.1-254-gc2ef7767)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "widgets/std_bitmap_button.h"
#include "widgets/wx_grid.h"
#include "panel_git_repos_base.h"
///////////////////////////////////////////////////////////////////////////
@@ -17,57 +20,9 @@ PANEL_GIT_REPOS_BASE::PANEL_GIT_REPOS_BASE( wxWindow* parent, wxWindowID id, con
wxBoxSizer* bLeftSizer;
bLeftSizer = new wxBoxSizer( wxVERTICAL );
m_enableGit = new wxCheckBox( this, wxID_ANY, _("Enable Git Tracking"), wxDefaultPosition, wxDefaultSize, 0 );
bLeftSizer->Add( m_enableGit, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 13 );
m_gitSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizerUpdate;
bSizerUpdate = new wxBoxSizer( wxVERTICAL );
m_staticText6 = new wxStaticText( this, wxID_ANY, _("Remote Tracking"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText6->Wrap( -1 );
bSizerUpdate->Add( m_staticText6, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 13 );
m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizerUpdate->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 );
wxGridBagSizer* gbUpdate;
gbUpdate = new wxGridBagSizer( 4, 5 );
gbUpdate->SetFlexibleDirection( wxBOTH );
gbUpdate->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
gbUpdate->SetEmptyCellSize( wxSize( -1,2 ) );
m_updateLabel = new wxStaticText( this, wxID_ANY, _("Update interval:"), wxDefaultPosition, wxDefaultSize, 0 );
m_updateLabel->Wrap( -1 );
gbUpdate->Add( m_updateLabel, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_updateInterval = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 60, 5 );
m_updateInterval->SetToolTip( _("Number of minutes between remote update checks. Zero disables automatic checks.") );
gbUpdate->Add( m_updateInterval, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_staticText7 = new wxStaticText( this, wxID_ANY, _("minutes"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText7->Wrap( -1 );
gbUpdate->Add( m_staticText7, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
gbUpdate->AddGrowableCol( 2 );
bSizerUpdate->Add( gbUpdate, 0, wxEXPAND|wxLEFT, 13 );
m_gitSizer->Add( bSizerUpdate, 0, wxEXPAND, 5 );
wxBoxSizer* bSizerCommitData;
bSizerCommitData = new wxBoxSizer( wxVERTICAL );
m_staticText12 = new wxStaticText( this, wxID_ANY, _("Git Commit Data"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText12->Wrap( -1 );
bSizerCommitData->Add( m_staticText12, 0, wxEXPAND|wxLEFT|wxTOP, 13 );
m_staticline31 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizerCommitData->Add( m_staticline31, 0, wxEXPAND | wxALL, 5 );
bLeftSizer->Add( m_staticText12, 0, wxEXPAND|wxLEFT|wxTOP, 10 );
wxFlexGridSizer* fgSizer1;
fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 );
@@ -105,13 +60,84 @@ PANEL_GIT_REPOS_BASE::PANEL_GIT_REPOS_BASE( wxWindow* parent, wxWindowID id, con
fgSizer1->Add( m_authorEmail, 0, wxALL|wxEXPAND, 5 );
bSizerCommitData->Add( fgSizer1, 0, wxBOTTOM|wxEXPAND|wxLEFT, 8 );
bLeftSizer->Add( fgSizer1, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 13 );
m_staticline3 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bLeftSizer->Add( m_staticline3, 0, wxEXPAND|wxBOTTOM, 5 );
m_staticText20 = new wxStaticText( this, wxID_ANY, _("Git Repositories"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText20->Wrap( -1 );
bLeftSizer->Add( m_staticText20, 0, wxEXPAND|wxLEFT|wxRIGHT, 13 );
wxBoxSizer* bAntialiasingSizer;
bAntialiasingSizer = new wxBoxSizer( wxVERTICAL );
m_grid = new WX_GRID( this, wxID_ANY, wxDefaultPosition, wxSize( 820,200 ), 0 );
// Grid
m_grid->CreateGrid( 0, 10 );
m_grid->EnableEditing( false );
m_grid->EnableGridLines( true );
m_grid->EnableDragGridSize( false );
m_grid->SetMargins( 0, 0 );
// Columns
m_grid->SetColSize( 0, 60 );
m_grid->SetColSize( 1, 200 );
m_grid->SetColSize( 2, 500 );
m_grid->SetColSize( 3, 60 );
m_grid->SetColSize( 4, 0 );
m_grid->SetColSize( 5, 0 );
m_grid->SetColSize( 6, 0 );
m_grid->SetColSize( 7, 0 );
m_grid->SetColSize( 8, 0 );
m_grid->SetColSize( 9, 0 );
m_grid->EnableDragColMove( false );
m_grid->EnableDragColSize( true );
m_grid->SetColLabelValue( 0, _("Active") );
m_grid->SetColLabelValue( 1, _("Name") );
m_grid->SetColLabelValue( 2, _("Path") );
m_grid->SetColLabelValue( 3, _("Status") );
m_grid->SetColLabelSize( 22 );
m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Rows
m_grid->EnableDragRowSize( true );
m_grid->SetRowLabelSize( 0 );
m_grid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Label Appearance
// Cell Defaults
m_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
bAntialiasingSizer->Add( m_grid, 5, wxALL|wxEXPAND, 5 );
m_gitSizer->Add( bSizerCommitData, 1, wxEXPAND, 5 );
bLeftSizer->Add( bAntialiasingSizer, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
wxBoxSizer* bButtonsSizer;
bButtonsSizer = new wxBoxSizer( wxHORIZONTAL );
m_btnAddRepo = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_btnAddRepo->SetToolTip( _("Add new repository") );
bButtonsSizer->Add( m_btnAddRepo, 0, wxALL, 5 );
m_btnEditRepo = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_btnEditRepo->SetToolTip( _("Edit repository properties") );
bButtonsSizer->Add( m_btnEditRepo, 0, wxALL, 5 );
bLeftSizer->Add( m_gitSizer, 0, wxEXPAND, 0 );
bButtonsSizer->Add( 0, 0, 1, wxEXPAND, 5 );
m_btnDelete = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_btnDelete->SetToolTip( _("Remove Git Repository") );
bButtonsSizer->Add( m_btnDelete, 0, wxBOTTOM|wxRIGHT|wxTOP, 5 );
bLeftSizer->Add( bButtonsSizer, 1, wxALL|wxEXPAND, 5 );
bPanelSizer->Add( bLeftSizer, 0, wxRIGHT, 20 );
@@ -122,14 +148,20 @@ PANEL_GIT_REPOS_BASE::PANEL_GIT_REPOS_BASE( wxWindow* parent, wxWindowID id, con
bPanelSizer->Fit( this );
// Connect Events
m_enableGit->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_GIT_REPOS_BASE::onEnableGitClick ), NULL, this );
m_cbDefault->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_GIT_REPOS_BASE::onDefaultClick ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( PANEL_GIT_REPOS_BASE::onGridDClick ), NULL, this );
m_btnAddRepo->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_GIT_REPOS_BASE::onAddClick ), NULL, this );
m_btnEditRepo->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_GIT_REPOS_BASE::onEditClick ), NULL, this );
m_btnDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_GIT_REPOS_BASE::onDeleteClick ), NULL, this );
}
PANEL_GIT_REPOS_BASE::~PANEL_GIT_REPOS_BASE()
{
// Disconnect Events
m_enableGit->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_GIT_REPOS_BASE::onEnableGitClick ), NULL, this );
m_cbDefault->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_GIT_REPOS_BASE::onDefaultClick ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( PANEL_GIT_REPOS_BASE::onGridDClick ), NULL, this );
m_btnAddRepo->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_GIT_REPOS_BASE::onAddClick ), NULL, this );
m_btnEditRepo->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_GIT_REPOS_BASE::onEditClick ), NULL, this );
m_btnDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_GIT_REPOS_BASE::onDeleteClick ), NULL, this );
}
+24 -16
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// C++ code generated with wxFormBuilder (version 3.10.1-254-gc2ef7767)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -10,19 +10,26 @@
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class STD_BITMAP_BUTTON;
class WX_GRID;
#include "widgets/resettable_panel.h"
#include <wx/string.h>
#include <wx/checkbox.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/stattext.h>
#include <wx/statline.h>
#include <wx/spinctrl.h>
#include <wx/gbsizer.h>
#include <wx/sizer.h>
#include <wx/checkbox.h>
#include <wx/textctrl.h>
#include <wx/sizer.h>
#include <wx/statline.h>
#include <wx/grid.h>
#include <wx/bmpbuttn.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/panel.h>
///////////////////////////////////////////////////////////////////////////
@@ -35,24 +42,25 @@ class PANEL_GIT_REPOS_BASE : public RESETTABLE_PANEL
private:
protected:
wxCheckBox* m_enableGit;
wxBoxSizer* m_gitSizer;
wxStaticText* m_staticText6;
wxStaticLine* m_staticline2;
wxStaticText* m_updateLabel;
wxSpinCtrl* m_updateInterval;
wxStaticText* m_staticText7;
wxStaticText* m_staticText12;
wxStaticLine* m_staticline31;
wxCheckBox* m_cbDefault;
wxStaticText* m_authorLabel;
wxTextCtrl* m_author;
wxStaticText* m_authorEmailLabel;
wxTextCtrl* m_authorEmail;
wxStaticLine* m_staticline3;
wxStaticText* m_staticText20;
WX_GRID* m_grid;
STD_BITMAP_BUTTON* m_btnAddRepo;
STD_BITMAP_BUTTON* m_btnEditRepo;
STD_BITMAP_BUTTON* m_btnDelete;
// Virtual event handlers, override them in your derived class
virtual void onEnableGitClick( wxCommandEvent& event ) { event.Skip(); }
virtual void onDefaultClick( wxCommandEvent& event ) { event.Skip(); }
virtual void onGridDClick( wxGridEvent& event ) { event.Skip(); }
virtual void onAddClick( wxCommandEvent& event ) { event.Skip(); }
virtual void onEditClick( wxCommandEvent& event ) { event.Skip(); }
virtual void onDeleteClick( wxCommandEvent& event ) { event.Skip(); }
public:
File diff suppressed because it is too large Load Diff
@@ -633,6 +633,46 @@ bool PANEL_DESIGN_BLOCK_LIB_TABLE::verifyTables()
}
}
for( DESIGN_BLOCK_LIB_TABLE* table : { global_model(), project_model() } )
{
if( !table )
continue;
for( unsigned int r = 0; r < table->GetCount(); ++r )
{
DESIGN_BLOCK_LIB_TABLE_ROW& row =
dynamic_cast<DESIGN_BLOCK_LIB_TABLE_ROW&>( table->At( r ) );
// Newly-added rows won't have set this yet
row.SetParent( table );
if( !row.GetIsEnabled() )
continue;
try
{
if( row.Refresh() )
{
if( table == global_model() )
m_parent->m_GlobalTableChanged = true;
else
m_parent->m_ProjectTableChanged = true;
}
}
catch( const IO_ERROR& ioe )
{
msg.Printf( _( "Design block library '%s' failed to load." ), row.GetNickName() );
wxWindow* topLevelParent = wxGetTopLevelParent( this );
wxMessageDialog errdlg( topLevelParent, msg + wxS( "\n" ) + ioe.What(),
_( "Error Loading Library" ) );
errdlg.ShowModal();
return true;
}
}
}
return true;
}
+6 -19
View File
@@ -36,7 +36,6 @@
#include <wx/filename.h>
#include <wx/log.h>
#include <wx/menu.h>
#include <wx/wfstream.h>
/* ---------- GRID_TRICKS for embedded files grid ---------- */
@@ -314,21 +313,13 @@ EMBEDDED_FILES::EMBEDDED_FILE* PANEL_EMBEDDED_FILES::AddEmbeddedFile( const wxSt
}
void PANEL_EMBEDDED_FILES::onAddEmbeddedFiles( wxCommandEvent& event )
void PANEL_EMBEDDED_FILES::onAddEmbeddedFile( wxCommandEvent& event )
{
// TODO: Update strings to reflect that multiple files can be selected.
wxFileDialog fileDialog( this, _( "Select a file to embed" ), wxEmptyString, wxEmptyString,
_( "All Files" ) + wxT( " (*.*)|*.*" ),
wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE );
_( "All files|*.*" ), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( fileDialog.ShowModal() == wxID_OK )
{
wxArrayString paths;
fileDialog.GetPaths( paths );
for( wxString path : paths )
AddEmbeddedFile( path );
}
AddEmbeddedFile( fileDialog.GetPath() );
}
@@ -446,10 +437,9 @@ void PANEL_EMBEDDED_FILES::onExportFiles( wxCommandEvent& event )
if( skip_file )
continue;
wxFFile ffile( fileName.GetFullPath(), wxT( "w" ) );
wxFFileOutputStream out( fileName.GetFullPath() );
if( !out.IsOk() )
if( !ffile.IsOpened() )
{
wxString msg = wxString::Format( _( "Failed to open file '%s'." ),
fileName.GetFullName() );
@@ -459,15 +449,12 @@ void PANEL_EMBEDDED_FILES::onExportFiles( wxCommandEvent& event )
continue;
}
out.Write( file->decompressedData.data(), file->decompressedData.size() );
if( !out.IsOk() || ( out.LastWrite() != file->decompressedData.size() ) )
if( !ffile.Write( file->decompressedData.data(), file->decompressedData.size() ) )
{
wxString msg = wxString::Format( _( "Failed to write file '%s'." ),
fileName.GetFullName() );
KIDIALOG errorDlg( m_parent, msg, _( "Error" ), wxOK | wxICON_ERROR );
errorDlg.ShowModal();
}
}
+1 -1
View File
@@ -68,7 +68,7 @@ public:
protected:
void onFontEmbedClick( wxCommandEvent& event ) override;
void onAddEmbeddedFiles( wxCommandEvent& event ) override;
void onAddEmbeddedFile( wxCommandEvent& event ) override;
void onDeleteEmbeddedFile( wxCommandEvent& event ) override;
void onExportFiles( wxCommandEvent& event ) override;
void onSize( wxSizeEvent& event ) override;
+4 -4
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -35,7 +35,7 @@ PANEL_EMBEDDED_FILES_BASE::PANEL_EMBEDDED_FILES_BASE( wxWindow* parent, wxWindow
m_files_grid->EnableDragColMove( false );
m_files_grid->EnableDragColSize( true );
m_files_grid->SetColLabelValue( 0, _("Filename") );
m_files_grid->SetColLabelValue( 1, _("Embedded Reference") );
m_files_grid->SetColLabelValue( 1, _("Internal Reference") );
m_files_grid->SetColLabelSize( 22 );
m_files_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
@@ -101,7 +101,7 @@ PANEL_EMBEDDED_FILES_BASE::PANEL_EMBEDDED_FILES_BASE( wxWindow* parent, wxWindow
// Connect Events
this->Connect( wxEVT_SIZE, wxSizeEventHandler( PANEL_EMBEDDED_FILES_BASE::onSize ) );
m_files_grid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( PANEL_EMBEDDED_FILES_BASE::onGridRightClick ), NULL, this );
m_browse_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_EMBEDDED_FILES_BASE::onAddEmbeddedFiles ), NULL, this );
m_browse_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_EMBEDDED_FILES_BASE::onAddEmbeddedFile ), NULL, this );
m_delete_button->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_EMBEDDED_FILES_BASE::onDeleteEmbeddedFile ), NULL, this );
m_cbEmbedFonts->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_EMBEDDED_FILES_BASE::onFontEmbedClick ), NULL, this );
m_export->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_EMBEDDED_FILES_BASE::onExportFiles ), NULL, this );
@@ -112,7 +112,7 @@ PANEL_EMBEDDED_FILES_BASE::~PANEL_EMBEDDED_FILES_BASE()
// Disconnect Events
this->Disconnect( wxEVT_SIZE, wxSizeEventHandler( PANEL_EMBEDDED_FILES_BASE::onSize ) );
m_files_grid->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( PANEL_EMBEDDED_FILES_BASE::onGridRightClick ), NULL, this );
m_browse_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_EMBEDDED_FILES_BASE::onAddEmbeddedFiles ), NULL, this );
m_browse_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_EMBEDDED_FILES_BASE::onAddEmbeddedFile ), NULL, this );
m_delete_button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_EMBEDDED_FILES_BASE::onDeleteEmbeddedFile ), NULL, this );
m_cbEmbedFonts->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_EMBEDDED_FILES_BASE::onFontEmbedClick ), NULL, this );
m_export->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_EMBEDDED_FILES_BASE::onExportFiles ), NULL, this );
+2 -2
View File
@@ -98,7 +98,7 @@
<property name="close_button">1</property>
<property name="col_label_horiz_alignment">wxALIGN_CENTER</property>
<property name="col_label_size">22</property>
<property name="col_label_values">&quot;Filename&quot; &quot;Embedded Reference&quot;</property>
<property name="col_label_values">&quot;Filename&quot; &quot;Internal Reference&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTER</property>
<property name="cols">2</property>
<property name="column_sizes">440,180</property>
@@ -243,7 +243,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">onAddEmbeddedFiles</event>
<event name="OnButtonClick">onAddEmbeddedFile</event>
</object>
</object>
<object class="sizeritem" expanded="false">
+2 -2
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -47,7 +47,7 @@ class PANEL_EMBEDDED_FILES_BASE : public wxPanel
// Virtual event handlers, override them in your derived class
virtual void onSize( wxSizeEvent& event ) { event.Skip(); }
virtual void onGridRightClick( wxGridEvent& event ) { event.Skip(); }
virtual void onAddEmbeddedFiles( wxCommandEvent& event ) { event.Skip(); }
virtual void onAddEmbeddedFile( wxCommandEvent& event ) { event.Skip(); }
virtual void onDeleteEmbeddedFile( wxCommandEvent& event ) { event.Skip(); }
virtual void onFontEmbedClick( wxCommandEvent& event ) { event.Skip(); }
virtual void onExportFiles( wxCommandEvent& event ) { event.Skip(); }
+1 -1
View File
@@ -136,7 +136,7 @@ void PANEL_PLUGIN_SETTINGS::validatePythonInterpreter()
PYTHON_MANAGER manager( pythonExe.GetFullPath() );
manager.Execute( { wxS( "--version" ) },
manager.Execute( wxS( "--version" ),
[&]( int aRetCode, const wxString& aStdOut, const wxString& aStdErr )
{
wxString msg;
@@ -421,6 +421,8 @@ void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_BITMAP* aItem ) const
m_out->Print( "(comment %s)", m_out->Quotew( aItem->m_Info ).c_str() );
// Write image in png readable format
m_out->Print( "(data" );
wxMemoryOutputStream stream;
aItem->m_ImageBitmap->SaveImageData( stream );
+12 -16
View File
@@ -24,7 +24,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "kicad_manager_frame.h"
#include <eda_base_frame.h>
#include <advanced_config.h>
@@ -174,7 +173,7 @@ EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType, const wxS
wxFrame( aParent, wxID_ANY, aTitle, aPos, aSize, aStyle, aFrameName ),
TOOLS_HOLDER(),
KIWAY_HOLDER( aKiway, KIWAY_HOLDER::FRAME ),
UNITS_PROVIDER( aIuScale, EDA_UNITS::MM )
UNITS_PROVIDER( aIuScale, EDA_UNITS::MILLIMETRES )
{
commonInit( aFrameType );
}
@@ -1089,15 +1088,7 @@ void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParent
KIFACE* kiface = nullptr;
std::vector<int> expand;
wxWindow* kicadMgr_window = wxWindow::FindWindowByName( KICAD_MANAGER_FRAME_NAME );
if( KICAD_MANAGER_FRAME* kicadMgr = static_cast<KICAD_MANAGER_FRAME*>( kicadMgr_window ) )
{
ACTION_MANAGER* actionMgr = kicadMgr->GetToolManager()->GetActionManager();
for( const auto& [name, action] : actionMgr->GetActions() )
hotkeysPanel->ActionsList().push_back( action );
}
Kiway().GetActions( hotkeysPanel->ActionsList() );
book->AddLazyPage(
[]( wxWindow* aParent ) -> wxWindow*
@@ -1114,11 +1105,16 @@ void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParent
book->AddPage( hotkeysPanel, _( "Hotkeys" ) );
book->AddLazyPage(
[]( wxWindow* aParent ) -> wxWindow*
{
return new PANEL_GIT_REPOS( aParent );
}, _( "Version Control" ) );
// This currently allows pre-defined repositories that we
// don't use, so keep it disabled at the moment
if( ADVANCED_CFG::GetCfg().m_EnableGit && false )
{
book->AddLazyPage(
[]( wxWindow* aParent ) -> wxWindow*
{
return new PANEL_GIT_REPOS( aParent );
}, _( "Version Control" ) );
}
#ifdef KICAD_USE_SENTRY
book->AddLazyPage(
+15 -16
View File
@@ -96,10 +96,9 @@ EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
long aStyle, const wxString& aFrameName,
const EDA_IU_SCALE& aIuScale ) :
KIWAY_PLAYER( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName,
aIuScale ),
m_socketServer( nullptr ),
m_lastToolbarIconSize( 0 )
KIWAY_PLAYER( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName, aIuScale ),
m_socketServer( nullptr ),
m_lastToolbarIconSize( 0 )
{
m_mainToolBar = nullptr;
m_drawToolBar = nullptr;
@@ -126,7 +125,7 @@ EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
m_propertiesPanel = nullptr;
m_netInspectorPanel = nullptr;
SetUserUnits( EDA_UNITS::MM );
SetUserUnits( EDA_UNITS::MILLIMETRES );
m_auimgr.SetFlags( wxAUI_MGR_DEFAULT );
@@ -177,8 +176,7 @@ EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
EDA_DRAW_FRAME::~EDA_DRAW_FRAME()
{
if( !m_openGLFailureOccured )
saveCanvasTypeSetting( m_canvasType );
saveCanvasTypeSetting( m_canvasType );
delete m_actions;
delete m_toolManager;
@@ -285,7 +283,8 @@ void EDA_DRAW_FRAME::ToggleUserUnits()
}
else
{
SetUserUnits( GetUserUnits() == EDA_UNITS::INCH ? EDA_UNITS::MM : EDA_UNITS::INCH );
SetUserUnits( GetUserUnits() == EDA_UNITS::INCHES ? EDA_UNITS::MILLIMETRES
: EDA_UNITS::INCHES );
unitsChangeRefresh();
wxCommandEvent e( EDA_EVT_UNITS_CHANGED );
@@ -649,10 +648,10 @@ void EDA_DRAW_FRAME::DisplayUnitsMsg()
switch( GetUserUnits() )
{
case EDA_UNITS::INCH: msg = _( "inches" ); break;
case EDA_UNITS::MILS: msg = _( "mils" ); break;
case EDA_UNITS::MM: msg = _( "mm" ); break;
default: msg = _( "Units" ); break;
case EDA_UNITS::INCHES: msg = _( "inches" ); break;
case EDA_UNITS::MILS: msg = _( "mils" ); break;
case EDA_UNITS::MILLIMETRES: msg = _( "mm" ); break;
default: msg = _( "Units" ); break;
}
SetStatusText( msg, 5 );
@@ -1277,9 +1276,9 @@ void EDA_DRAW_FRAME::setupUnits( APP_SETTINGS_BASE* aCfg )
switch( static_cast<EDA_UNITS>( aCfg->m_System.units ) )
{
default:
case EDA_UNITS::MM: m_toolManager->RunAction( ACTIONS::millimetersUnits ); break;
case EDA_UNITS::INCH: m_toolManager->RunAction( ACTIONS::inchesUnits ); break;
case EDA_UNITS::MILS: m_toolManager->RunAction( ACTIONS::milsUnits ); break;
case EDA_UNITS::MILLIMETRES: m_toolManager->RunAction( ACTIONS::millimetersUnits ); break;
case EDA_UNITS::INCHES: m_toolManager->RunAction( ACTIONS::inchesUnits ); break;
case EDA_UNITS::MILS: m_toolManager->RunAction( ACTIONS::milsUnits ); break;
}
}
@@ -1296,7 +1295,7 @@ void EDA_DRAW_FRAME::GetUnitPair( EDA_UNITS& aPrimaryUnit, EDA_UNITS& aSecondary
if( cmnTool )
aSecondaryUnits = cmnTool->GetLastMetricUnits();
else
aSecondaryUnits = EDA_UNITS::MM;
aSecondaryUnits = EDA_UNITS::MILLIMETRES;
}
else
{
+16 -9
View File
@@ -48,7 +48,7 @@
#include <font/outline_font.h>
#include <geometry/shape_poly_set.h>
#include <properties/property_validators.h>
#include <ctl_flags.h>
#include <ctl_flags.h> // for CTL_OMIT_HIDE definition
#include <api/api_enums.h>
#include <api/api_utils.h>
#include <api/common/types/base_types.pb.h>
@@ -93,10 +93,9 @@ GR_TEXT_V_ALIGN_T EDA_TEXT::MapVertJustify( int aVertJustify )
EDA_TEXT::EDA_TEXT( const EDA_IU_SCALE& aIuScale, const wxString& aText ) :
m_IuScale( aIuScale ),
m_text( aText ),
m_render_cache_font( nullptr ),
m_visible( true )
m_IuScale( aIuScale ),
m_render_cache_font( nullptr )
{
SetTextSize( VECTOR2I( EDA_UNIT_UTILS::Mils2IU( m_IuScale, DEFAULT_SIZE_TEXT ),
EDA_UNIT_UTILS::Mils2IU( m_IuScale, DEFAULT_SIZE_TEXT ) ) );
@@ -123,7 +122,6 @@ EDA_TEXT::EDA_TEXT( const EDA_TEXT& aText ) :
m_attributes = aText.m_attributes;
m_pos = aText.m_pos;
m_visible = aText.m_visible;
m_render_cache_font = aText.m_render_cache_font;
m_render_cache_text = aText.m_render_cache_text;
@@ -159,7 +157,6 @@ EDA_TEXT& EDA_TEXT::operator=( const EDA_TEXT& aText )
m_attributes = aText.m_attributes;
m_pos = aText.m_pos;
m_visible = aText.m_visible;
m_render_cache_font = aText.m_render_cache_font;
m_render_cache_text = aText.m_render_cache_text;
@@ -210,7 +207,7 @@ void EDA_TEXT::Serialize( google::protobuf::Any &aContainer ) const
attrs->set_italic( IsItalic() );
attrs->set_bold( IsBold() );
attrs->set_underlined( GetAttributes().m_Underlined );
attrs->set_visible( true );
attrs->set_visible( IsVisible() );
attrs->set_mirrored( IsMirrored() );
attrs->set_multiline( IsMultilineAllowed() );
attrs->set_keep_upright( IsKeepUpright() );
@@ -239,6 +236,7 @@ bool EDA_TEXT::Deserialize( const google::protobuf::Any &aContainer )
attrs.m_Bold = text.attributes().bold();
attrs.m_Italic = text.attributes().italic();
attrs.m_Underlined = text.attributes().underlined();
attrs.m_Visible = text.attributes().visible();
attrs.m_Mirrored = text.attributes().mirrored();
attrs.m_Multiline = text.attributes().multiline();
attrs.m_KeepUpright = text.attributes().keep_upright();
@@ -378,7 +376,7 @@ void EDA_TEXT::SetBoldFlag( bool aBold )
void EDA_TEXT::SetVisible( bool aVisible )
{
m_visible = aVisible;
m_attributes.m_Visible = aVisible;
ClearRenderCache();
}
@@ -1038,7 +1036,8 @@ void EDA_TEXT::SetFontIndex( int aIdx )
bool EDA_TEXT::IsDefaultFormatting() const
{
return ( !IsMirrored()
return ( IsVisible()
&& !IsMirrored()
&& GetHorizJustify() == GR_TEXT_H_ALIGN_CENTER
&& GetVertJustify() == GR_TEXT_V_ALIGN_CENTER
&& GetTextThickness() == 0
@@ -1110,8 +1109,13 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aControlBits ) const
aFormatter->Print( ")" ); // (justify
}
if( !( aControlBits & CTL_OMIT_HIDE ) && !IsVisible() )
KICAD_FORMAT::FormatBool( aFormatter, "hide", true );
if( !( aControlBits & CTL_OMIT_HYPERLINK ) && HasHyperlink() )
{
aFormatter->Print( "(href %s)", aFormatter->Quotew( GetHyperlink() ).c_str() );
}
aFormatter->Print( ")" ); // (effects
}
@@ -1371,6 +1375,9 @@ static struct EDA_TEXT_DESC
propMgr.AddProperty( new PROPERTY<EDA_TEXT, bool>( _HKI( "Mirrored" ),
&EDA_TEXT::SetMirrored, &EDA_TEXT::IsMirrored ),
textProps );
propMgr.AddProperty( new PROPERTY<EDA_TEXT, bool>( _HKI( "Visible" ),
&EDA_TEXT::SetVisible, &EDA_TEXT::IsVisible ),
textProps );
propMgr.AddProperty( new PROPERTY<EDA_TEXT, int>( _HKI( "Width" ),
&EDA_TEXT::SetTextWidth, &EDA_TEXT::GetTextWidth,
PROPERTY_DISPLAY::PT_SIZE ),
+55
View File
@@ -0,0 +1,55 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 CERN (www.cern.ch)
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <eda_tools.h>
#include <wx/textfile.h>
bool IsFileFromEDATool( const wxFileName& aFileName, const EDA_TOOLS aTool )
{
wxTextFile textFile;
if( textFile.Open( aFileName.GetFullPath() ) )
{
switch( aTool )
{
case EDA_TOOLS::EAGLE:
if( textFile.GetLineCount() > 2
&& textFile[1].StartsWith( wxT( "<!DOCTYPE eagle SYSTEM" ) )
&& textFile[2].StartsWith( wxT( "<eagle version" ) ) )
{
textFile.Close();
return true;
}
break;
default: break;
}
textFile.Close();
}
return false;
}
+105 -49
View File
@@ -48,7 +48,7 @@ bool EDA_UNIT_UTILS::IsImperialUnit( EDA_UNITS aUnit )
{
switch( aUnit )
{
case EDA_UNITS::INCH:
case EDA_UNITS::INCHES:
case EDA_UNITS::MILS:
return true;
@@ -62,9 +62,9 @@ bool EDA_UNIT_UTILS::IsMetricUnit( EDA_UNITS aUnit )
{
switch( aUnit )
{
case EDA_UNITS::UM:
case EDA_UNITS::MM:
case EDA_UNITS::CM:
case EDA_UNITS::MICROMETRES:
case EDA_UNITS::MILLIMETRES:
case EDA_UNITS::CENTIMETRES:
return true;
default:
@@ -106,15 +106,15 @@ bool EDA_UNIT_UTILS::FetchUnitsFromString( const wxString& aTextValue, EDA_UNITS
//check for um, μm (µ is MICRO SIGN) and µm (µ is GREEK SMALL LETTER MU) for micrometre
if( unit == wxT( "um" ) || unit == wxT( "\u00B5m" ) || unit == wxT( "\u03BCm" ) )
aUnits = EDA_UNITS::UM;
aUnits = EDA_UNITS::MICROMETRES;
else if( unit == wxT( "mm" ) )
aUnits = EDA_UNITS::MM;
aUnits = EDA_UNITS::MILLIMETRES;
if( unit == wxT( "cm" ) )
aUnits = EDA_UNITS::CM;
aUnits = EDA_UNITS::CENTIMETRES;
else if( unit == wxT( "mi" ) || unit == wxT( "th" ) ) // "mils" or "thou"
aUnits = EDA_UNITS::MILS;
else if( unit == wxT( "in" ) || unit == wxT( "\"" ) )
aUnits = EDA_UNITS::INCH;
aUnits = EDA_UNITS::INCHES;
else if( unit == wxT( "de" ) || unit == wxT( "ra" ) ) // "deg" or "rad"
aUnits = EDA_UNITS::DEGREES;
else
@@ -130,15 +130,15 @@ wxString EDA_UNIT_UTILS::GetText( EDA_UNITS aUnits, EDA_DATA_TYPE aType )
switch( aUnits )
{
case EDA_UNITS::UM: label = wxT( " \u00B5m" ); break; //00B5 for µ
case EDA_UNITS::MM: label = wxT( " mm" ); break;
case EDA_UNITS::CM: label = wxT( " cm" ); break;
case EDA_UNITS::DEGREES: label = wxT( "°" ); break;
case EDA_UNITS::MILS: label = wxT( " mils" ); break;
case EDA_UNITS::INCH: label = wxT( " in" ); break;
case EDA_UNITS::PERCENT: label = wxT( "%" ); break;
case EDA_UNITS::UNSCALED: break;
default: UNIMPLEMENTED_FOR( wxS( "Unknown units" ) ); break;
case EDA_UNITS::MICROMETRES: label = wxT( " \u00B5m" ); break; //00B5 for µ
case EDA_UNITS::MILLIMETRES: label = wxT( " mm" ); break;
case EDA_UNITS::CENTIMETRES: label = wxT( " cm" ); break;
case EDA_UNITS::DEGREES: label = wxT( "°" ); break;
case EDA_UNITS::MILS: label = wxT( " mils" ); break;
case EDA_UNITS::INCHES: label = wxT( " in" ); break;
case EDA_UNITS::PERCENT: label = wxT( "%" ); break;
case EDA_UNITS::UNSCALED: break;
default: UNIMPLEMENTED_FOR( wxS( "Unknown units" ) ); break;
}
switch( aType )
@@ -263,13 +263,26 @@ double EDA_UNIT_UTILS::UI::ToUserUnit( const EDA_IU_SCALE& aIuScale, EDA_UNITS a
{
switch( aUnit )
{
case EDA_UNITS::UM: return IU_TO_MM( aValue, aIuScale ) * 1000;
case EDA_UNITS::MM: return IU_TO_MM( aValue, aIuScale );
case EDA_UNITS::CM: return IU_TO_MM( aValue, aIuScale ) / 10;
case EDA_UNITS::MILS: return IU_TO_MILS( aValue, aIuScale );
case EDA_UNITS::INCH: return IU_TO_IN( aValue, aIuScale );
case EDA_UNITS::DEGREES: return aValue;
default: return aValue;
case EDA_UNITS::MICROMETRES:
return IU_TO_MM( aValue, aIuScale ) * 1000;
case EDA_UNITS::MILLIMETRES:
return IU_TO_MM( aValue, aIuScale );
case EDA_UNITS::CENTIMETRES:
return IU_TO_MM( aValue, aIuScale ) / 10;
case EDA_UNITS::MILS:
return IU_TO_MILS( aValue, aIuScale );
case EDA_UNITS::INCHES:
return IU_TO_IN( aValue, aIuScale );
case EDA_UNITS::DEGREES:
return aValue;
default:
return aValue;
}
}
@@ -304,10 +317,21 @@ wxString EDA_UNIT_UTILS::UI::StringFromValue( const EDA_IU_SCALE& aIuScale, EDA_
switch( aUnits )
{
case EDA_UNITS::MILS: format = is_eeschema ? wxT( "%.3f" ) : wxT( "%.5f" ); break;
case EDA_UNITS::INCH: format = is_eeschema ? wxT( "%.6f" ) : wxT( "%.8f" ); break;
case EDA_UNITS::DEGREES: format = wxT( "%.4f" ); break;
default: format = wxT( "%.10f" ); break;
case EDA_UNITS::MILS:
format = is_eeschema ? wxT( "%.3f" ) : wxT( "%.5f" );
break;
case EDA_UNITS::INCHES:
format = is_eeschema ? wxT( "%.6f" ) : wxT( "%.8f" );
break;
case EDA_UNITS::DEGREES:
format = wxT( "%.4f" );
break;
default:
format = wxT( "%.10f" );
break;
}
wxString text;
@@ -390,13 +414,34 @@ wxString EDA_UNIT_UTILS::UI::MessageTextFromValue( const EDA_IU_SCALE& aIuScale,
switch( aUnits )
{
default:
case EDA_UNITS::UM: format = is_eeschema ? wxT( "%.0f" ) : wxT( "%.1f" ); break;
case EDA_UNITS::MM: format = is_eeschema ? wxT( "%.2f" ) : wxT( "%.4f" ); break;
case EDA_UNITS::CM: format = is_eeschema ? wxT( "%.3f" ) : wxT( "%.5f" ); break;
case EDA_UNITS::MILS: format = is_eeschema ? wxT( "%.0f" ) : wxT( "%.2f" ); break;
case EDA_UNITS::INCH: format = is_eeschema ? wxT( "%.3f" ) : wxT( "%.4f" ); break;
case EDA_UNITS::DEGREES: format = wxT( "%.3f" ); break;
case EDA_UNITS::UNSCALED: format = wxT( "%.0f" ); break;
case EDA_UNITS::MICROMETRES:
format = is_eeschema ? wxT( "%.0f" ) : wxT( "%.1f" );
break;
case EDA_UNITS::MILLIMETRES:
format = is_eeschema ? wxT( "%.2f" ) : wxT( "%.4f" );
break;
case EDA_UNITS::CENTIMETRES:
format = is_eeschema ? wxT( "%.3f" ) : wxT( "%.5f" );
break;
case EDA_UNITS::MILS:
format = is_eeschema ? wxT( "%.0f" ) : wxT( "%.2f" );
break;
case EDA_UNITS::INCHES:
format = is_eeschema ? wxT( "%.3f" ) : wxT( "%.4f" );
break;
case EDA_UNITS::DEGREES:
// 3 digits in mantissa should be good for rotation in degree
format = wxT( "%.3f" );
break;
case EDA_UNITS::UNSCALED:
format = wxT( "%.0f" );
break;
}
text.Printf( format, value );
@@ -444,15 +489,26 @@ double EDA_UNIT_UTILS::UI::FromUserUnit( const EDA_IU_SCALE& aIuScale, EDA_UNITS
{
switch( aUnits )
{
case EDA_UNITS::UM: return MM_TO_IU( aValue / 1000.0, aIuScale );
case EDA_UNITS::MM: return MM_TO_IU( aValue, aIuScale );
case EDA_UNITS::CM: return MM_TO_IU( aValue * 10, aIuScale );
case EDA_UNITS::MILS: return MILS_TO_IU( aValue, aIuScale );
case EDA_UNITS::INCH: return IN_TO_IU( aValue, aIuScale );
case EDA_UNITS::MICROMETRES:
return MM_TO_IU( aValue / 1000.0, aIuScale );
case EDA_UNITS::MILLIMETRES:
return MM_TO_IU( aValue, aIuScale );
case EDA_UNITS::CENTIMETRES:
return MM_TO_IU( aValue * 10, aIuScale );
case EDA_UNITS::MILS:
return MILS_TO_IU( aValue, aIuScale );
case EDA_UNITS::INCHES:
return IN_TO_IU( aValue, aIuScale );
default:
case EDA_UNITS::DEGREES:
case EDA_UNITS::UNSCALED:
case EDA_UNITS::PERCENT: return aValue;
case EDA_UNITS::PERCENT:
return aValue;
}
}
@@ -528,24 +584,24 @@ double EDA_UNIT_UTILS::UI::DoubleValueFromString( const EDA_IU_SCALE& aIuScale,
// Check the optional unit designator (2 ch significant)
wxString unit( buf.Mid( brk_point ).Strip( wxString::leading ).Left( 2 ).Lower() );
if( aUnits == EDA_UNITS::UM
|| aUnits == EDA_UNITS::MM
|| aUnits == EDA_UNITS::CM
if( aUnits == EDA_UNITS::MICROMETRES
|| aUnits == EDA_UNITS::MILLIMETRES
|| aUnits == EDA_UNITS::CENTIMETRES
|| aUnits == EDA_UNITS::MILS
|| aUnits == EDA_UNITS::INCH )
|| aUnits == EDA_UNITS::INCHES )
{
//check for um, μm (µ is MICRO SIGN) and µm (µ is GREEK SMALL LETTER MU) for micrometre
if( unit == wxT( "um" ) || unit == wxT( "\u00B5m" ) || unit == wxT( "\u03BCm" ) )
{
aUnits = EDA_UNITS::UM;
aUnits = EDA_UNITS::MICROMETRES;
}
else if( unit == wxT( "mm" ) )
{
aUnits = EDA_UNITS::MM;
aUnits = EDA_UNITS::MILLIMETRES;
}
else if( unit == wxT( "cm" ) )
{
aUnits = EDA_UNITS::CM;
aUnits = EDA_UNITS::CENTIMETRES;
}
else if( unit == wxT( "mi" ) || unit == wxT( "th" ) )
{
@@ -553,7 +609,7 @@ double EDA_UNIT_UTILS::UI::DoubleValueFromString( const EDA_IU_SCALE& aIuScale,
}
else if( unit == wxT( "in" ) || unit == wxT( "\"" ) )
{
aUnits = EDA_UNITS::INCH;
aUnits = EDA_UNITS::INCHES;
}
else if( unit == wxT( "oz" ) ) // 1 oz = 1.37 mils
{
+3 -26
View File
@@ -127,10 +127,10 @@ void EMBEDDED_FILES::RemoveFile( const wxString& name, bool aErase )
if( it != m_files.end() )
{
m_files.erase( it );
if( aErase )
delete it->second;
m_files.erase( it );
}
}
@@ -162,13 +162,6 @@ void EMBEDDED_FILES::WriteEmbeddedFiles( OUTPUTFORMATTER& aOut, bool aWriteData
{
const EMBEDDED_FILE& file = *entry;
// Skip empty files
if( file.compressedEncodedData.empty() )
{
wxLogDebug( wxT( "Error: Embedded file '%s' is empty" ), file.name );
continue;
}
aOut.Print( "(file " );
aOut.Print( "(name %s)", aOut.Quotew( file.name ).c_str() );
@@ -383,23 +376,7 @@ void EMBEDDED_FILES_PARSER::ParseEmbedded( EMBEDDED_FILES* aFiles )
break;
case T_data:
try
{
NeedBAR();
}
catch( const PARSE_ERROR& e )
{
// No data in the file -- due to bug in writer for 9.0.0
if( curTok == T_RIGHT )
break;
else
throw e;
}
catch( ... )
{
throw;
}
NeedBAR();
token = NextTok();
file->compressedEncodedData.reserve( 1 << 17 );
+1 -1
View File
@@ -78,7 +78,7 @@ bool FILENAME_RESOLVER::Set3DConfigDir( const wxString& aConfigDir )
}
bool FILENAME_RESOLVER::SetProject( const PROJECT* aProject, bool* flgChanged )
bool FILENAME_RESOLVER::SetProject( PROJECT* aProject, bool* flgChanged )
{
m_project = aProject;
+8 -6
View File
@@ -68,16 +68,18 @@ public:
std::unique_ptr<MARKUP::NODE> root;
};
typedef std::pair<wxString, ENTRY> CACHE_ENTRY;
MARKUP_CACHE( size_t aMaxSize ) :
m_maxSize( aMaxSize )
{
}
ENTRY& Put( const wxString& aQuery, ENTRY&& aResult )
ENTRY& Put( const CACHE_ENTRY::first_type& aQuery, ENTRY&& aResult )
{
auto it = m_cache.find( aQuery );
m_cacheMru.emplace_front( std::make_pair( aQuery, std::move( aResult ) ) );
m_cacheMru.emplace_front( CACHE_ENTRY( aQuery, std::move( aResult ) ) );
if( it != m_cache.end() )
{
@@ -98,7 +100,7 @@ public:
return m_cacheMru.begin()->second;
}
ENTRY* Get( const wxString& aQuery )
ENTRY* Get( const CACHE_ENTRY::first_type& aQuery )
{
auto it = m_cache.find( aQuery );
@@ -117,9 +119,9 @@ public:
}
private:
size_t m_maxSize;
std::list<std::pair<wxString, ENTRY>> m_cacheMru;
std::unordered_map<wxString, std::list<std::pair<wxString, ENTRY>>::iterator> m_cache;
size_t m_maxSize;
std::list<CACHE_ENTRY> m_cacheMru;
std::unordered_map<wxString, std::list<CACHE_ENTRY>::iterator> m_cache;
};
+5 -6
View File
@@ -299,7 +299,6 @@ struct GLYPH_CACHE_KEY {
bool fakeItalic;
bool fakeBold;
bool mirror;
bool supersub;
EDA_ANGLE angle;
bool operator==(const GLYPH_CACHE_KEY& rhs ) const
@@ -311,7 +310,6 @@ struct GLYPH_CACHE_KEY {
&& fakeItalic == rhs.fakeItalic
&& fakeBold == rhs.fakeBold
&& mirror == rhs.mirror
&& supersub == rhs.supersub
&& angle == rhs.angle;
}
};
@@ -325,7 +323,7 @@ namespace std
std::size_t operator()( const GLYPH_CACHE_KEY& k ) const
{
return hash_val( k.face, k.codepoint, k.scale.x, k.scale.y, k.forDrawingSheet,
k.fakeItalic, k.fakeBold, k.mirror, k.supersub, k.angle.AsDegrees() );
k.fakeItalic, k.fakeBold, k.mirror, k.angle.AsDegrees() );
}
};
}
@@ -341,10 +339,11 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
VECTOR2D glyphSize = aSize;
FT_Face face = m_face;
double scaler = faceSize();
bool supersub = IsSuperscript( aTextStyle ) || IsSubscript( aTextStyle );
if( supersub )
if( IsSubscript( aTextStyle ) || IsSuperscript( aTextStyle ) )
{
scaler = subscriptSize();
}
// set glyph resolution so that FT_Load_Glyph() results are good enough for decomposing
FT_Set_Char_Size( face, 0, scaler, GLYPH_RESOLUTION, 0 );
@@ -383,7 +382,7 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
if( aGlyphs )
{
GLYPH_CACHE_KEY key = { face, glyphInfo[i].codepoint, scaleFactor, m_forDrawingSheet,
m_fakeItal, m_fakeBold, aMirror, supersub, aAngle };
m_fakeItal, m_fakeBold, aMirror, aAngle };
GLYPH_DATA& glyphData = s_glyphCache[ key ];
if( glyphData.m_Contours.empty() )
+5
View File
@@ -32,6 +32,7 @@ TEXT_ATTRIBUTES::TEXT_ATTRIBUTES( KIFONT::FONT* aFont ) :
m_Bold( false ),
m_Underlined( false ),
m_Color( KIGFX::COLOR4D::UNSPECIFIED ),
m_Visible( true ),
m_Mirrored( false ),
m_Multiline( true ),
m_KeepUpright( false ),
@@ -92,6 +93,9 @@ int TEXT_ATTRIBUTES::Compare( const TEXT_ATTRIBUTES& aRhs ) const
if( retv )
return retv;
if( m_Visible != aRhs.m_Visible )
return m_Visible - aRhs.m_Visible;
if( m_Mirrored != aRhs.m_Mirrored )
return m_Mirrored - aRhs.m_Mirrored;
@@ -121,6 +125,7 @@ std::ostream& operator<<( std::ostream& aStream, const TEXT_ATTRIBUTES& aAttribu
<< "Bold: " << aAttributes.m_Bold << std::endl
<< "Underline: " << aAttributes.m_Underlined << std::endl
<< "Color: " << aAttributes.m_Color << std::endl
<< "Visible " << aAttributes.m_Visible << std::endl
<< "Mirrored " << aAttributes.m_Mirrored << std::endl
<< "Multilined: " << aAttributes.m_Multiline << std::endl
<< "Size: " << aAttributes.m_Size << std::endl
+47 -110
View File
@@ -409,138 +409,75 @@ bool CopyDirectory( const wxString& aSourceDir, const wxString& aDestDir, wxStri
bool CopyFilesOrDirectory( const wxString& aSourcePath, const wxString& aDestDir, wxString& aErrors,
int& aFileCopiedCount, const std::vector<wxString>& aExclusions )
int& fileCopiedCount, const std::vector<wxString>& aExclusions )
{
// Parse source path and determine if it's a directory
wxFileName sourceFn( aSourcePath );
wxString sourcePath = sourceFn.GetFullPath();
bool isSourceDirectory = wxFileName::DirExists( sourcePath );
wxString baseDestDir = aDestDir;
wxDir dir( sourceFn.GetPath() );
wxFileName destFn( aDestDir );
auto performCopy = [&]( const wxString& src, const wxString& dest ) -> bool
if( !dir.IsOpened() )
{
if( wxCopyFile( src, dest ) )
{
aFileCopiedCount++;
return true;
}
aErrors += wxString::Format( _( "Could not copy file: %s to %s" ), src, dest );
aErrors += wxString::Format( _( "Could not open source directory: %s" ),
sourceFn.GetPath() );
aErrors += wxT( "\n" );
return false;
};
}
auto processEntries = [&]( const wxString& srcDir, const wxString& pattern,
const wxString& destDir ) -> bool
if( !wxFileName::Mkdir( aDestDir, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
{
wxDir dir( srcDir );
aErrors += wxString::Format( _( "Could not create destination directory: %s" ),
aDestDir );
aErrors += wxT( "\n" );
return false;
}
if( !dir.IsOpened() )
wxString filename = sourceFn.GetFullName();
bool cont = dir.GetFirst( &filename, sourceFn.GetFullName(), wxDIR_FILES | wxDIR_DIRS );
while( cont )
{
wxString sourcePath = sourceFn.GetPath() + wxFileName::GetPathSeparator() + filename;
wxString destPath = aDestDir + wxFileName::GetPathSeparator() + filename;
bool exclude = filename.Matches( wxT( "~*.lck" ) );
for( const wxString& exclusion : aExclusions )
exclude |= sourcePath.Matches( exclusion );
if( exclude )
{
aErrors += wxString::Format( _( "Could not open source directory: %s" ), srcDir );
aErrors += wxT( "\n" );
return false;
}
wxString filename;
bool success = true;
// Find all entries matching pattern (files + directories + hidden items)
bool cont = dir.GetFirst( &filename, pattern, wxDIR_FILES | wxDIR_DIRS | wxDIR_HIDDEN );
while( cont )
{
const wxString entrySrc = srcDir + wxFileName::GetPathSeparator() + filename;
const wxString entryDest = destDir + wxFileName::GetPathSeparator() + filename;
// Apply exclusion filters
bool exclude =
filename.Matches( wxT( "~*.lck" ) ) || filename.Matches( wxT( "*.lck" ) );
for( const auto& exclusion : aExclusions )
{
if( entrySrc.Matches( exclusion ) )
{
exclude = true;
break;
}
}
if( !exclude )
{
if( wxFileName::DirExists( entrySrc ) )
{
// Recursively process subdirectories
if( !CopyFilesOrDirectory( entrySrc, destDir, aErrors, aFileCopiedCount,
aExclusions ) )
{
aErrors += wxString::Format( _( "Could not copy directory: %s to %s" ),
entrySrc, entryDest );
aErrors += wxT( "\n" );
success = false;
}
}
else
{
// Copy individual files
if( !performCopy( entrySrc, entryDest ) )
{
success = false;
}
}
}
cont = dir.GetNext( &filename );
continue;
}
return success;
};
// Avoid infinite recursion on "*"
if( sourcePath == aSourcePath )
break;
// If copying a directory, append its name to destination path
if( isSourceDirectory )
{
wxString sourceDirName = sourceFn.GetFullName();
baseDestDir = wxFileName( aDestDir, sourceDirName ).GetFullPath();
}
// Create destination directory hierarchy
if( !wxFileName::Mkdir( baseDestDir, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
{
aErrors +=
wxString::Format( _( "Could not create destination directory: %s" ), baseDestDir );
aErrors += wxT( "\n" );
return false;
}
// Execute appropriate copy operation based on source type
if( !isSourceDirectory )
{
const wxString fileName = sourceFn.GetFullName();
// Handle wildcard patterns in filenames
if( fileName.Contains( '*' ) || fileName.Contains( '?' ) )
if( wxFileName::DirExists( sourcePath ) )
{
const wxString dirPath = sourceFn.GetPath();
if( !wxFileName::DirExists( dirPath ) )
// Recursively copy subdirectories
if( !CopyFilesOrDirectory( sourcePath, destPath, aErrors, fileCopiedCount,
aExclusions ) )
{
aErrors += wxString::Format( _( "Source directory does not exist: %s" ), dirPath );
aErrors += wxT( "\n" );
return false;
}
// Process all matching files in source directory
return processEntries( dirPath, fileName, baseDestDir );
}
else
{
// Copy files
if( !wxCopyFile( sourcePath, destPath ) )
{
aErrors += wxString::Format( _( "Could not copy file: %s to %s" ), sourcePath,
destPath );
fileCopiedCount++;
return false;
}
}
// Single file copy operation
return performCopy( sourcePath, wxFileName( baseDestDir, fileName ).GetFullPath() );
cont = dir.GetNext( &filename );
}
// Full directory copy operation
return processEntries( sourcePath, wxEmptyString, baseDestDir );
return true;
}
+6 -5
View File
@@ -22,7 +22,6 @@
*/
#include "git_add_to_index_handler.h"
#include <git/kicad_git_memory.h>
#include <iterator>
@@ -54,14 +53,15 @@ bool GIT_ADD_TO_INDEX_HANDLER::AddToIndex( const wxString& aFilePath )
return false;
}
KIGIT::GitIndexPtr indexPtr( index );
if( git_index_find( &at_pos, index, aFilePath.ToUTF8().data() ) == GIT_OK )
{
git_index_free( index );
wxLogError( "%s already in index", aFilePath );
return false;
}
git_index_free( index );
// Add file to index if not already there
m_filesToAdd.push_back( aFilePath );
@@ -82,8 +82,6 @@ bool GIT_ADD_TO_INDEX_HANDLER::PerformAddToIndex()
return false;
}
KIGIT::GitIndexPtr indexPtr( index );
for( auto& file : m_filesToAdd )
{
if( git_index_add_bypath( index, file.ToUTF8().data() ) != 0 )
@@ -101,8 +99,11 @@ bool GIT_ADD_TO_INDEX_HANDLER::PerformAddToIndex()
m_filesFailedToAdd.clear();
std::copy( m_filesToAdd.begin(), m_filesToAdd.end(),
std::back_inserter( m_filesFailedToAdd ) );
git_index_free( index );
return false;
}
git_index_free( index );
return true;
}
+8 -20
View File
@@ -24,31 +24,23 @@
#include "git_clone_handler.h"
#include <git/kicad_git_common.h>
#include <git/kicad_git_memory.h>
#include <trace_helpers.h>
#include <git2.h>
#include <wx/filename.h>
#include <wx/log.h>
GIT_CLONE_HANDLER::GIT_CLONE_HANDLER( KIGIT_COMMON* aCommon ) : KIGIT_REPO_MIXIN( aCommon )
GIT_CLONE_HANDLER::GIT_CLONE_HANDLER() : KIGIT_COMMON( nullptr )
{}
GIT_CLONE_HANDLER::~GIT_CLONE_HANDLER()
{}
{
if( m_repo )
git_repository_free( m_repo );
}
bool GIT_CLONE_HANDLER::PerformClone()
{
std::unique_lock<std::mutex> lock( GetCommon()->m_gitActionMutex, std::try_to_lock );
if( !lock.owns_lock() )
{
wxLogTrace( traceGit, "GIT_CLONE_HANDLER::PerformClone() could not lock" );
return false;
}
wxFileName clonePath( m_clonePath );
if( !clonePath.DirExists() )
@@ -70,20 +62,16 @@ bool GIT_CLONE_HANDLER::PerformClone()
cloneOptions.fetch_opts.callbacks.credentials = credentials_cb;
cloneOptions.fetch_opts.callbacks.payload = this;
TestedTypes() = 0;
m_testedTypes = 0;
ResetNextKey();
git_repository* newRepo = nullptr;
wxString remote = GetCommon()->m_remote;
if( git_clone( &newRepo, remote.mbc_str(), m_clonePath.mbc_str(),
if( git_clone( &m_repo, m_URL.ToStdString().c_str(), m_clonePath.ToStdString().c_str(),
&cloneOptions ) != 0 )
{
AddErrorString( wxString::Format( _( "Could not clone repository '%s'" ), remote ) );
AddErrorString( wxString::Format( _( "Could not clone repository '%s'" ), m_URL ) );
return false;
}
GetCommon()->SetRepo( newRepo );
if( m_progressReporter )
m_progressReporter->Hide();
+8 -7
View File
@@ -24,29 +24,30 @@
#ifndef GIT_CLONE_HANDLER_H_
#define GIT_CLONE_HANDLER_H_
#include "kicad_git_common.h"
#include "git_repo_mixin.h"
#include "git_progress.h"
#include <git/kicad_git_common.h>
#include <git/git_progress.h>
class GIT_CLONE_HANDLER : public KIGIT_REPO_MIXIN
class GIT_CLONE_HANDLER : public KIGIT_COMMON, public GIT_PROGRESS
{
public:
GIT_CLONE_HANDLER( KIGIT_COMMON* aCommon );
GIT_CLONE_HANDLER();
~GIT_CLONE_HANDLER();
bool PerformClone();
void SetURL( const wxString& aURL ) { m_URL = aURL; }
wxString GetURL() const { return m_URL; }
void SetBranch( const wxString& aBranch ) { m_branch = aBranch; }
wxString GetBranch() const { return m_branch; }
void SetClonePath( const wxString& aPath ) { m_clonePath = aPath; }
wxString GetClonePath() const { return m_clonePath; }
void SetRemote( const wxString& aRemote ) { GetCommon()->m_remote = aRemote; }
void UpdateProgress( int aCurrent, int aTotal, const wxString& aMessage ) override;
private:
wxString m_URL;
wxString m_branch;
wxString m_clonePath;
};
-2
View File
@@ -62,8 +62,6 @@ public:
}
}
virtual void UpdateProgress( int aCurrent, int aTotal, const wxString& aMessage ) {};
protected:
int m_previousProgress;
+105 -312
View File
@@ -23,53 +23,31 @@
#include "git_pull_handler.h"
#include <git/kicad_git_common.h>
#include <git/kicad_git_memory.h>
#include <trace_helpers.h>
#include <wx/log.h>
#include <iostream>
#include <time.h>
#include <memory>
GIT_PULL_HANDLER::GIT_PULL_HANDLER( KIGIT_COMMON* aCommon ) : KIGIT_REPO_MIXIN( aCommon )
{
}
GIT_PULL_HANDLER::GIT_PULL_HANDLER( KIGIT_COMMON* aRepo ) : KIGIT_COMMON( *aRepo )
{}
GIT_PULL_HANDLER::~GIT_PULL_HANDLER()
{}
bool GIT_PULL_HANDLER::PerformFetch()
{
}
bool GIT_PULL_HANDLER::PerformFetch( bool aSkipLock )
{
if( !GetRepo() )
{
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformFetch() - No repository found" );
return false;
}
std::unique_lock<std::mutex> lock( GetCommon()->m_gitActionMutex, std::try_to_lock );
if( !aSkipLock && !lock.owns_lock() )
{
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformFetch() - Could not lock mutex" );
return false;
}
// Fetch updates from remote repository
// Fetch updates from remote repository
git_remote* remote = nullptr;
if( git_remote_lookup( &remote, GetRepo(), "origin" ) != 0 )
if( git_remote_lookup( &remote, m_repo, "origin" ) != 0 )
{
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformFetch() - Failed to lookup remote 'origin'" );
AddErrorString( wxString::Format( _( "Could not lookup remote '%s'" ), "origin" ) );
return false;
}
KIGIT::GitRemotePtr remotePtr( remote );
git_remote_callbacks remoteCallbacks;
git_remote_init_callbacks( &remoteCallbacks, GIT_REMOTE_CALLBACKS_VERSION );
remoteCallbacks.sideband_progress = progress_cb;
@@ -77,14 +55,14 @@ bool GIT_PULL_HANDLER::PerformFetch( bool aSkipLock )
remoteCallbacks.credentials = credentials_cb;
remoteCallbacks.payload = this;
TestedTypes() = 0;
m_testedTypes = 0;
ResetNextKey();
if( git_remote_connect( remote, GIT_DIRECTION_FETCH, &remoteCallbacks, nullptr, nullptr ) )
{
wxString errorMsg = KIGIT_COMMON::GetLastGitError();
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformFetch() - Failed to connect to remote: %s", errorMsg );
AddErrorString( wxString::Format( _( "Could not connect to remote '%s': %s" ), "origin", errorMsg ) );
git_remote_free( remote );
AddErrorString( wxString::Format( _( "Could not connect to remote '%s': %s" ), "origin",
git_error_last()->message ) );
return false;
}
@@ -94,35 +72,28 @@ bool GIT_PULL_HANDLER::PerformFetch( bool aSkipLock )
if( git_remote_fetch( remote, nullptr, &fetchOptions, nullptr ) )
{
wxString errorMsg = KIGIT_COMMON::GetLastGitError();
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformFetch() - Failed to fetch from remote: %s", errorMsg );
AddErrorString( wxString::Format( _( "Could not fetch data from remote '%s': %s" ), "origin", errorMsg ) );
git_remote_free( remote );
AddErrorString( wxString::Format( _( "Could not fetch data from remote '%s': %s" ),
"origin", git_error_last()->message ) );
return false;
}
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformFetch() - Fetch completed successfully" );
git_remote_free( remote );
return true;
}
PullResult GIT_PULL_HANDLER::PerformPull()
{
PullResult result = PullResult::Success;
std::unique_lock<std::mutex> lock( GetCommon()->m_gitActionMutex, std::try_to_lock );
PullResult result = PullResult::Success;
if( !lock.owns_lock() )
{
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformPull() - Could not lock mutex" );
return PullResult::Error;
}
if( !PerformFetch( true ) )
if( !PerformFetch() )
return PullResult::Error;
git_oid pull_merge_oid = {};
if( git_repository_fetchhead_foreach( GetRepo(), fetchhead_foreach_cb,
&pull_merge_oid ) )
if( git_repository_fetchhead_foreach( m_repo, fetchhead_foreach_cb, &pull_merge_oid ) )
{
AddErrorString( _( "Could not read 'FETCH_HEAD'" ) );
return PullResult::Error;
@@ -130,23 +101,26 @@ PullResult GIT_PULL_HANDLER::PerformPull()
git_annotated_commit* fetchhead_commit;
if( git_annotated_commit_lookup( &fetchhead_commit, GetRepo(), &pull_merge_oid ) )
if( git_annotated_commit_lookup( &fetchhead_commit, m_repo, &pull_merge_oid ) )
{
AddErrorString( _( "Could not lookup commit" ) );
return PullResult::Error;
}
KIGIT::GitAnnotatedCommitPtr fetchheadCommitPtr( fetchhead_commit );
const git_annotated_commit* merge_commits[] = { fetchhead_commit };
git_merge_analysis_t merge_analysis;
git_merge_preference_t merge_preference = GIT_MERGE_PREFERENCE_NONE;
const git_annotated_commit* merge_commits[] = { fetchhead_commit };
git_merge_analysis_t merge_analysis;
git_merge_preference_t merge_preference = GIT_MERGE_PREFERENCE_NONE;
if( git_merge_analysis( &merge_analysis, &merge_preference, GetRepo(), merge_commits, 1 ) )
if( git_merge_analysis( &merge_analysis, &merge_preference, m_repo, merge_commits, 1 ) )
{
AddErrorString( _( "Could not analyze merge" ) );
git_annotated_commit_free( fetchhead_commit );
return PullResult::Error;
}
if( !( merge_analysis & GIT_MERGE_ANALYSIS_NORMAL ) )
git_annotated_commit_free( fetchhead_commit );
if( merge_analysis & GIT_MERGE_ANALYSIS_UNBORN )
{
AddErrorString( _( "Invalid HEAD. Cannot merge." ) );
@@ -156,27 +130,23 @@ PullResult GIT_PULL_HANDLER::PerformPull()
// Nothing to do if the repository is up to date
if( merge_analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE )
{
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformPull() - Repository is up to date" );
git_repository_state_cleanup( GetRepo() );
git_repository_state_cleanup( m_repo );
return PullResult::UpToDate;
}
// Fast-forward is easy, just update the local reference
if( merge_analysis & GIT_MERGE_ANALYSIS_FASTFORWARD )
{
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformPull() - Fast-forward merge" );
return handleFastForward();
}
if( merge_analysis & GIT_MERGE_ANALYSIS_NORMAL )
{
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformPull() - Normal merge" );
PullResult ret = handleRebase( merge_commits, 1 );
// PullResult ret = handleMerge( merge_commits, 1 );
PullResult ret = handleMerge( merge_commits, 1 );
git_annotated_commit_free( fetchhead_commit );
return ret;
}
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformPull() - Merge needs resolution" );
//TODO: handle merges when they need to be resolved
return result;
@@ -191,9 +161,6 @@ GIT_PULL_HANDLER::GetFetchResults() const
std::string GIT_PULL_HANDLER::getFirstLineFromCommitMessage( const std::string& aMessage )
{
if( aMessage.empty() )
return aMessage;
size_t firstLineEnd = aMessage.find_first_of( '\n' );
if( firstLineEnd != std::string::npos )
@@ -205,180 +172,91 @@ std::string GIT_PULL_HANDLER::getFirstLineFromCommitMessage( const std::string&
std::string GIT_PULL_HANDLER::getFormattedCommitDate( const git_time& aTime )
{
char dateBuffer[64];
char dateBuffer[64];
time_t time = static_cast<time_t>( aTime.time );
struct tm timeInfo;
#ifdef _WIN32
localtime_s( &timeInfo, &time );
#else
gmtime_r( &time, &timeInfo );
#endif
strftime( dateBuffer, sizeof( dateBuffer ), "%Y-%b-%d %H:%M:%S", &timeInfo );
strftime( dateBuffer, sizeof( dateBuffer ), "%Y-%b-%d %H:%M:%S", gmtime( &time ) );
return dateBuffer;
}
PullResult GIT_PULL_HANDLER::handleFastForward()
{
git_reference* rawRef = nullptr;
// Update local references with fetched data
git_reference* updatedRef = nullptr;
// Get the current HEAD reference
if( git_repository_head( &rawRef, GetRepo() ) )
{
AddErrorString( _( "Could not get repository head" ) );
return PullResult::Error;
}
KIGIT::GitReferencePtr headRef( rawRef );
git_oid updatedRefOid;
const char* currentBranchName = git_reference_name( rawRef );
wxString remoteBranchName = wxString::Format( "refs/remotes/origin/%s",
currentBranchName + strlen( "refs/heads/" ) );
// Get the OID of the updated reference (remote-tracking branch)
if( git_reference_name_to_id( &updatedRefOid, GetRepo(), remoteBranchName.c_str() ) != GIT_OK )
{
AddErrorString( wxString::Format( _( "Could not get reference OID for reference '%s'" ),
remoteBranchName ) );
return PullResult::Error;
}
// Get the target commit object
git_commit* targetCommit = nullptr;
if( git_commit_lookup( &targetCommit, GetRepo(), &updatedRefOid ) != GIT_OK )
{
AddErrorString( _( "Could not look up target commit" ) );
return PullResult::Error;
}
KIGIT::GitCommitPtr targetCommitPtr( targetCommit );
// Get the tree from the target commit
git_tree* targetTree = nullptr;
if( git_commit_tree( &targetTree, targetCommit ) != GIT_OK )
{
git_commit_free( targetCommit );
AddErrorString( _( "Could not get tree from target commit" ) );
return PullResult::Error;
}
KIGIT::GitTreePtr targetTreePtr( targetTree );
// Perform a checkout to update the working directory
git_checkout_options checkoutOptions;
git_checkout_init_options( &checkoutOptions, GIT_CHECKOUT_OPTIONS_VERSION );
auto notify_cb = []( git_checkout_notify_t why, const char* path, const git_diff_file* baseline,
const git_diff_file* target, const git_diff_file* workdir, void* payload ) -> int
{
switch( why )
if( git_repository_head( &updatedRef, m_repo ) )
{
case GIT_CHECKOUT_NOTIFY_CONFLICT:
wxLogTrace( traceGit, "Checkout conflict: %s", path ? path : "unknown" );
break;
case GIT_CHECKOUT_NOTIFY_DIRTY:
wxLogTrace( traceGit, "Checkout dirty: %s", path ? path : "unknown" );
break;
case GIT_CHECKOUT_NOTIFY_UPDATED:
wxLogTrace( traceGit, "Checkout updated: %s", path ? path : "unknown" );
break;
case GIT_CHECKOUT_NOTIFY_UNTRACKED:
wxLogTrace( traceGit, "Checkout untracked: %s", path ? path : "unknown" );
break;
case GIT_CHECKOUT_NOTIFY_IGNORED:
wxLogTrace( traceGit, "Checkout ignored: %s", path ? path : "unknown" );
break;
default:
break;
}
return 0;
};
checkoutOptions.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_ALLOW_CONFLICTS;
checkoutOptions.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
checkoutOptions.notify_cb = notify_cb;
if( git_checkout_tree( GetRepo(), reinterpret_cast<git_object*>( targetTree ), &checkoutOptions ) != GIT_OK )
{
AddErrorString( _( "Failed to perform checkout operation." ) );
return PullResult::Error;
}
git_reference* updatedRef = nullptr;
// Update the current branch to point to the new commit
if (git_reference_set_target(&updatedRef, rawRef, &updatedRefOid, nullptr) != GIT_OK)
{
AddErrorString( wxString::Format( _( "Failed to update reference '%s' to point to '%s'" ), currentBranchName,
git_oid_tostr_s( &updatedRefOid ) ) );
return PullResult::Error;
}
KIGIT::GitReferencePtr updatedRefPtr( updatedRef );
// Clean up the repository state
if( git_repository_state_cleanup( GetRepo() ) != GIT_OK )
{
AddErrorString( _( "Failed to clean up repository state after fast-forward." ) );
return PullResult::Error;
}
git_revwalk* revWalker = nullptr;
// Collect commit details for updated references
if( git_revwalk_new( &revWalker, GetRepo() ) != GIT_OK )
{
AddErrorString( _( "Failed to initialize revision walker." ) );
return PullResult::Error;
}
KIGIT::GitRevWalkPtr revWalkerPtr( revWalker );
git_revwalk_sorting( revWalker, GIT_SORT_TIME );
if( git_revwalk_push_glob( revWalker, currentBranchName ) != GIT_OK )
{
AddErrorString( _( "Failed to push reference to revision walker." ) );
return PullResult::Error;
}
std::pair<std::string, std::vector<CommitDetails>>& branchCommits = m_fetchResults.emplace_back();
branchCommits.first = currentBranchName;
git_oid commitOid;
while( git_revwalk_next( &commitOid, revWalker ) == GIT_OK )
{
git_commit* commit = nullptr;
if( git_commit_lookup( &commit, GetRepo(), &commitOid ) )
{
AddErrorString( wxString::Format( _( "Could not lookup commit '%s'" ),
git_oid_tostr_s( &commitOid ) ) );
AddErrorString( _( "Could not get repository head" ) );
return PullResult::Error;
}
KIGIT::GitCommitPtr commitPtr( commit );
const char* updatedRefName = git_reference_name( updatedRef );
git_reference_free( updatedRef );
CommitDetails details;
details.m_sha = git_oid_tostr_s( &commitOid );
details.m_firstLine = getFirstLineFromCommitMessage( git_commit_message( commit ) );
details.m_author = git_commit_author( commit )->name;
details.m_date = getFormattedCommitDate( git_commit_author( commit )->when );
git_oid updatedRefOid;
branchCommits.second.push_back( details );
}
if( git_reference_name_to_id( &updatedRefOid, m_repo, updatedRefName ) )
{
AddErrorString( wxString::Format( _( "Could not get reference OID for reference '%s'" ),
updatedRefName ) );
return PullResult::Error;
}
return PullResult::FastForward;
git_checkout_options checkoutOptions;
git_checkout_init_options( &checkoutOptions, GIT_CHECKOUT_OPTIONS_VERSION );
checkoutOptions.checkout_strategy = GIT_CHECKOUT_SAFE;
if( git_checkout_head( m_repo, &checkoutOptions ) )
{
AddErrorString( _( "Failed to perform checkout operation." ) );
return PullResult::Error;
}
// Collect commit details for updated references
git_revwalk* revWalker = nullptr;
git_revwalk_new( &revWalker, m_repo );
git_revwalk_sorting( revWalker, GIT_SORT_TIME );
git_revwalk_push_glob( revWalker, updatedRefName );
git_oid commitOid;
while( git_revwalk_next( &commitOid, revWalker ) == 0 )
{
git_commit* commit = nullptr;
if( git_commit_lookup( &commit, m_repo, &commitOid ) )
{
AddErrorString( wxString::Format( _( "Could not lookup commit '{}'" ),
git_oid_tostr_s( &commitOid ) ) );
git_revwalk_free( revWalker );
return PullResult::Error;
}
CommitDetails details;
details.m_sha = git_oid_tostr_s( &commitOid );
details.m_firstLine = getFirstLineFromCommitMessage( git_commit_message( commit ) );
details.m_author = git_commit_author( commit )->name;
details.m_date = getFormattedCommitDate( git_commit_author( commit )->when );
std::pair<std::string, std::vector<CommitDetails>>& branchCommits =
m_fetchResults.emplace_back();
branchCommits.first = updatedRefName;
branchCommits.second.push_back( details );
//TODO: log these to the parent
git_commit_free( commit );
}
git_revwalk_free( revWalker );
git_repository_state_cleanup( m_repo );
return PullResult::FastForward;
}
PullResult GIT_PULL_HANDLER::handleMerge( const git_annotated_commit** aMergeHeads,
size_t aMergeHeadsCount )
{
git_merge_options merge_opts;
git_merge_options merge_opts;
git_merge_options_init( &merge_opts, GIT_MERGE_OPTIONS_VERSION );
git_checkout_options checkout_opts;
@@ -386,7 +264,7 @@ PullResult GIT_PULL_HANDLER::handleMerge( const git_annotated_commit** aMergeHea
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
if( git_merge( GetRepo(), aMergeHeads, aMergeHeadsCount, &merge_opts, &checkout_opts ) )
if( git_merge( m_repo, aMergeHeads, aMergeHeadsCount, &merge_opts, &checkout_opts ) )
{
AddErrorString( _( "Could not merge commits" ) );
return PullResult::Error;
@@ -395,14 +273,12 @@ PullResult GIT_PULL_HANDLER::handleMerge( const git_annotated_commit** aMergeHea
// Get the repository index
git_index* index = nullptr;
if( git_repository_index( &index, GetRepo() ) )
if( git_repository_index( &index, m_repo ) )
{
AddErrorString( _( "Could not get repository index" ) );
return PullResult::Error;
}
KIGIT::GitIndexPtr indexPtr( index );
// Check for conflicts
git_index_conflict_iterator* conflicts = nullptr;
@@ -412,11 +288,9 @@ PullResult GIT_PULL_HANDLER::handleMerge( const git_annotated_commit** aMergeHea
return PullResult::Error;
}
KIGIT::GitIndexConflictIteratorPtr conflictsPtr( conflicts );
const git_index_entry* ancestor = nullptr;
const git_index_entry* our = nullptr;
const git_index_entry* their = nullptr;
const git_index_entry* ancestor = nullptr;
const git_index_entry* our = nullptr;
const git_index_entry* their = nullptr;
std::vector<ConflictData> conflict_data;
while( git_index_conflict_next( &ancestor, &our, &their, conflicts ) == 0 )
@@ -475,95 +349,14 @@ PullResult GIT_PULL_HANDLER::handleMerge( const git_annotated_commit** aMergeHea
git_index_write( index );
}
git_index_conflict_iterator_free( conflicts );
git_index_free( index );
return conflict_data.empty() ? PullResult::Success : PullResult::MergeFailed;
}
PullResult GIT_PULL_HANDLER::handleRebase( const git_annotated_commit** aMergeHeads, size_t aMergeHeadsCount )
{
// Get the current branch reference
git_reference* head_ref = nullptr;
if( git_repository_head( &head_ref, GetRepo() ) )
{
wxString errorMsg = KIGIT_COMMON::GetLastGitError();
wxLogTrace( traceGit, "GIT_PULL_HANDLER::handleRebase() - Failed to get HEAD: %s", errorMsg );
return PullResult::Error;
}
KIGIT::GitReferencePtr headRefPtr(head_ref);
// Initialize rebase operation
git_rebase* rebase = nullptr;
git_rebase_options rebase_opts = GIT_REBASE_OPTIONS_INIT;
rebase_opts.checkout_options.checkout_strategy = GIT_CHECKOUT_SAFE;
if( git_rebase_init( &rebase, GetRepo(), nullptr, nullptr, aMergeHeads[0], &rebase_opts ) )
{
wxString errorMsg = KIGIT_COMMON::GetLastGitError();
wxLogTrace( traceGit, "GIT_PULL_HANDLER::handleRebase() - Failed to initialize rebase: %s", errorMsg );
return PullResult::Error;
}
KIGIT::GitRebasePtr rebasePtr( rebase );
git_rebase_operation* operation = nullptr;
while( git_rebase_next( &operation, rebase ) != GIT_ITEROVER )
{
// Check for conflicts
git_index* index = nullptr;
if( git_repository_index( &index, GetRepo() ) )
{
wxLogTrace( traceGit, "GIT_PULL_HANDLER::handleRebase() - Failed to get index: %s",
KIGIT_COMMON::GetLastGitError() );
return PullResult::Error;
}
KIGIT::GitIndexPtr indexPtr( index );
if( git_index_has_conflicts( index ) )
{
// Abort the rebase if there are conflicts because we need to merge manually
git_rebase_abort( rebase );
AddErrorString( _( "Conflicts detected during rebase" ) );
return PullResult::MergeFailed;
}
git_oid commit_id;
git_signature* committer = nullptr;
if( git_signature_default( &committer, GetRepo() ) )
{
wxLogTrace( traceGit, "GIT_PULL_HANDLER::handleRebase() - Failed to create signature: %s",
KIGIT_COMMON::GetLastGitError() );
return PullResult::Error;
}
KIGIT::GitSignaturePtr committerPtr( committer );
if( git_rebase_commit( &commit_id, rebase, nullptr, committer, nullptr, nullptr ) != GIT_OK )
{
wxString errorMsg = KIGIT_COMMON::GetLastGitError();
wxLogTrace( traceGit, "GIT_PULL_HANDLER::handleRebase() - Failed to commit operation: %s", errorMsg );
git_rebase_abort( rebase );
return PullResult::Error;
}
}
// Finish the rebase
if( git_rebase_finish( rebase, nullptr ) )
{
wxLogTrace( traceGit, "GIT_PULL_HANDLER::handleRebase() - Failed to finish rebase: %s",
KIGIT_COMMON::GetLastGitError() );
return PullResult::Error;
}
wxLogTrace( traceGit, "GIT_PULL_HANDLER::handleRebase() - Rebase completed successfully" );
git_repository_state_cleanup( GetRepo() );
return PullResult::Success;
}
void GIT_PULL_HANDLER::UpdateProgress( int aCurrent, int aTotal, const wxString& aMessage )
{
ReportProgress( aCurrent, aTotal, aMessage );
}
+26 -17
View File
@@ -21,15 +21,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _GIT_PULL_HANDLER_H_
#define _GIT_PULL_HANDLER_H_
#include <git/git_repo_mixin.h>
#ifndef GITPULLHANDLER_HPP
#define GITPULLHANDLER_HPP
#include <git2.h>
#include <functional>
#include <vector>
#include <string>
#include <wx/string.h>
#include <git2.h>
#include "kicad_git_common.h"
#include <git/git_progress.h>
// Structure to store commit details
struct CommitDetails
@@ -63,29 +65,36 @@ struct ConflictData
};
class GIT_PULL_HANDLER : public KIGIT_REPO_MIXIN
class GIT_PULL_HANDLER : public KIGIT_COMMON, public GIT_PROGRESS
{
public:
GIT_PULL_HANDLER( KIGIT_COMMON* aCommon );
~GIT_PULL_HANDLER();
bool PerformFetch( bool aSkipLock = false );
PullResult PerformPull();
bool PerformFetch();
const std::vector<std::pair<std::string, std::vector<CommitDetails>>>& GetFetchResults() const;
// Implementation for progress updates
// Set the callback function for conflict resolution
void SetConflictCallback(
std::function<int( std::vector<ConflictData>& aConflicts )> aCallback )
{
m_conflictCallback = aCallback;
}
void UpdateProgress( int aCurrent, int aTotal, const wxString& aMessage ) override;
private:
std::vector<std::pair<std::string, std::vector<CommitDetails>>> m_fetchResults;
std::string getFirstLineFromCommitMessage( const std::string& aMessage );
std::string getFormattedCommitDate( const git_time& aTime );
PullResult handleFastForward();
PullResult handleMerge( const git_annotated_commit** aMergeHeads, size_t aMergeHeadsCount );
PullResult handleRebase( const git_annotated_commit** aMergeHeads, size_t aMergeHeadsCount );
std::string getFormattedCommitDate( const git_time& aTime );private:
PullResult handleFastForward();
PullResult handleMerge( const git_annotated_commit** aMergeHeads, size_t aMergeHeadsCount);
std::vector<std::pair<std::string, std::vector<CommitDetails>>> m_fetchResults;
std::function<int( std::vector<ConflictData>& aConflicts )> m_conflictCallback;
};
#endif // _GIT_PULL_HANDLER_H_
#endif // GITPULLHANDLER_HPP
+11 -45
View File
@@ -23,58 +23,43 @@
#include "git_push_handler.h"
#include <git/kicad_git_common.h>
#include <git/kicad_git_memory.h>
#include <trace_helpers.h>
#include <iostream>
#include <wx/log.h>
GIT_PUSH_HANDLER::GIT_PUSH_HANDLER( KIGIT_COMMON* aRepo ) : KIGIT_REPO_MIXIN( aRepo )
GIT_PUSH_HANDLER::GIT_PUSH_HANDLER( KIGIT_COMMON* aRepo ) : KIGIT_COMMON( *aRepo )
{}
GIT_PUSH_HANDLER::~GIT_PUSH_HANDLER()
{}
PushResult GIT_PUSH_HANDLER::PerformPush()
{
std::unique_lock<std::mutex> lock( GetCommon()->m_gitActionMutex, std::try_to_lock );
if(!lock.owns_lock())
{
wxLogTrace(traceGit, "GIT_PUSH_HANDLER::PerformPush: Could not lock mutex");
return PushResult::Error;
}
PushResult result = PushResult::Success;
// Fetch updates from remote repository
git_remote* remote = nullptr;
if(git_remote_lookup(&remote, GetRepo(), "origin") != 0)
if( git_remote_lookup( &remote, m_repo, "origin" ) != 0 )
{
AddErrorString(_("Could not lookup remote"));
AddErrorString( _( "Could not lookup remote" ) );
return PushResult::Error;
}
KIGIT::GitRemotePtr remotePtr(remote);
git_remote_callbacks remoteCallbacks;
git_remote_init_callbacks(&remoteCallbacks, GIT_REMOTE_CALLBACKS_VERSION);
git_remote_init_callbacks( &remoteCallbacks, GIT_REMOTE_CALLBACKS_VERSION );
remoteCallbacks.sideband_progress = progress_cb;
remoteCallbacks.transfer_progress = transfer_progress_cb;
remoteCallbacks.update_tips = update_cb;
remoteCallbacks.push_transfer_progress = push_transfer_progress_cb;
remoteCallbacks.credentials = credentials_cb;
remoteCallbacks.payload = this;
TestedTypes() = 0;
ResetNextKey();
if( git_remote_connect( remote, GIT_DIRECTION_PUSH, &remoteCallbacks, nullptr, nullptr ) )
{
git_remote_free( remote );
AddErrorString( wxString::Format( _( "Could not connect to remote: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
git_error_last()->message ) );
return PushResult::Error;
}
@@ -82,33 +67,14 @@ PushResult GIT_PUSH_HANDLER::PerformPush()
git_push_init_options( &pushOptions, GIT_PUSH_OPTIONS_VERSION );
pushOptions.callbacks = remoteCallbacks;
// Get the current HEAD reference
git_reference* head = nullptr;
if( git_repository_head( &head, GetRepo() ) != 0 )
{
git_remote_disconnect( remote );
AddErrorString( _( "Could not get repository head" ) );
return PushResult::Error;
}
KIGIT::GitReferencePtr headPtr( head );
// Create refspec for current branch
const char* refs[1];
refs[0] = git_reference_name( head );
const git_strarray refspecs = { (char**) refs, 1 };
if( git_remote_push( remote, &refspecs, &pushOptions ) )
if( git_remote_push( remote, nullptr, &pushOptions ) )
{
git_remote_free( remote );
AddErrorString( wxString::Format( _( "Could not push to remote: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
git_remote_disconnect( remote );
git_error_last()->message ) );
return PushResult::Error;
}
git_remote_disconnect( remote );
return result;
}
+15 -15
View File
@@ -21,37 +21,37 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _GIT_PUSH_HANDLER_H_
#define _GIT_PUSH_HANDLER_H_
#ifndef GITPUSHHANDLER_HPP
#define GITPUSHHANDLER_HPP
#include <git2.h>
#include <functional>
#include <vector>
#include <string>
#include "kicad_git_common.h"
#include <git/git_progress.h>
#include <git/git_repo_mixin.h>
#include <git/kicad_git_errors.h>
#include <wx/string.h>
class KIGIT_COMMON;
// Enum for result codes
enum class PushResult
{
Success,
Error
Error,
UpToDate
};
class GIT_PUSH_HANDLER : public KIGIT_REPO_MIXIN
class GIT_PUSH_HANDLER : public KIGIT_COMMON, public GIT_PROGRESS
{
public:
GIT_PUSH_HANDLER( KIGIT_COMMON* aCommon );
GIT_PUSH_HANDLER( KIGIT_COMMON* aRepo );
~GIT_PUSH_HANDLER();
PushResult PerformPush();
// Virtual method for progress reporting
virtual void ReportProgress(int aCurrent, int aTotal, const wxString& aMessage) {}
void UpdateProgress( int aCurrent, int aTotal, const wxString& aMessage ) override;
private:
// Implementation of GIT_PROGRESS's virtual method
void UpdateProgress(int aCurrent, int aTotal, const wxString& aMessage) override;
};
#endif // _GIT_PUSH_HANDLER_H_
#endif // GITPUSHHANDLER_HPP
+5 -5
View File
@@ -24,7 +24,6 @@
#include <wx/string.h>
#include <wx/log.h>
#include <git/kicad_git_memory.h>
#include "git_remove_from_index_handler.h"
GIT_REMOVE_FROM_INDEX_HANDLER::GIT_REMOVE_FROM_INDEX_HANDLER( git_repository* aRepository )
@@ -52,14 +51,15 @@ bool GIT_REMOVE_FROM_INDEX_HANDLER::RemoveFromIndex( const wxString& aFilePath )
return false;
}
KIGIT::GitIndexPtr indexPtr( index );
if( git_index_find( &at_pos, index, aFilePath.ToUTF8().data() ) != 0 )
{
git_index_free( index );
wxLogError( "Failed to find index entry for %s", aFilePath );
return false;
}
git_index_free( index );
m_filesToRemove.push_back( aFilePath );
return true;
}
@@ -78,8 +78,6 @@ void GIT_REMOVE_FROM_INDEX_HANDLER::PerformRemoveFromIndex()
return;
}
KIGIT::GitIndexPtr indexPtr( index );
if( git_index_remove_bypath( index, file.ToUTF8().data() ) != 0 )
{
wxLogError( "Failed to remove index entry for %s", file );
@@ -97,5 +95,7 @@ void GIT_REMOVE_FROM_INDEX_HANDLER::PerformRemoveFromIndex()
wxLogError( "Failed to write index tree" );
return;
}
git_index_free( index );
}
}
-188
View File
@@ -1,188 +0,0 @@
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
#ifndef GIT_REPO_MIXIN_H
#define GIT_REPO_MIXIN_H
#include "kicad_git_common.h"
#include "kicad_git_errors.h"
#include "git_progress.h"
class KIGIT_REPO_MIXIN: public KIGIT_ERRORS, public GIT_PROGRESS
{
public:
KIGIT_REPO_MIXIN( KIGIT_COMMON* aCommon ) : m_common( aCommon )
{
// Ensure m_common is initialized
wxASSERT( aCommon != nullptr );
}
virtual ~KIGIT_REPO_MIXIN()
{
// Non-owning, don't delete
}
/**
* @brief Get the current branch name
* @return The current branch name
*/
wxString GetCurrentBranchName() const
{
return m_common->GetCurrentBranchName();
}
/**
* @brief Get a list of branch names
* @return A vector of branch names
*/
std::vector<wxString> GetBranchNames() const
{
return m_common->GetBranchNames();
}
/**
* @brief Get a list of project directories
* @return A vector of project directories
*/
std::vector<wxString> GetProjectDirs()
{
return m_common->GetProjectDirs();
}
/**
* @brief Get a pointer to the git repository
* @return A pointer to the git repository
*/
git_repository* GetRepo() const
{
return m_common->GetRepo();
}
/**
* @brief Get a pair of sets of files that differ locally from the remote repository
* @return A pair of sets of files that differ locally from the remote repository
*/
std::pair<std::set<wxString>, std::set<wxString>> GetDifferentFiles() const
{
return m_common->GetDifferentFiles();
}
/**
* @brief Get the common object
* @return The common object
*/
KIGIT_COMMON* GetCommon() const
{
return m_common;
}
/**
* @brief Reset the next public key to test
*/
void ResetNextKey() { m_common->ResetNextKey(); }
/**
* @brief Get the next public key
* @return The next public key
*/
wxString GetNextPublicKey()
{
return m_common->GetNextPublicKey();
}
/**
* @brief Get the connection type
* @return The connection type
*/
KIGIT_COMMON::GIT_CONN_TYPE GetConnType() const
{
return m_common->GetConnType();
}
/**
* @brief Get the username
* @return The username
*/
wxString GetUsername() const
{
return m_common->GetUsername();
}
/**
* @brief Get the password
* @return The password
*/
wxString GetPassword() const
{
return m_common->GetPassword();
}
/**
* @brief Set the username
* @param aUsername The username
*/
void SetUsername( const wxString& aUsername )
{
m_common->SetUsername( aUsername );
}
/**
* @brief Set the password
* @param aPassword The password
*/
void SetPassword( const wxString& aPassword )
{
m_common->SetPassword( aPassword );
}
/**
* @brief Set the SSH key
* @param aSSHKey The SSH key
*/
void SetSSHKey( const wxString& aSSHKey )
{
m_common->SetSSHKey( aSSHKey );
}
/**
* @brief Get the remote name
* @return The remote name
*/
wxString GetRemotename() const
{
return m_common->GetRemotename();
}
/**
* @brief Get the git root directory
* @return The git root directory
*/
wxString GetGitRootDirectory() const
{
return m_common->GetGitRootDirectory();
}
/**
* @brief Return the connection types that have been tested for authentication
* @return The connection types that have been tested for authentication
*/
unsigned& TestedTypes() { return m_common->TestedTypes(); }
private:
KIGIT_COMMON* m_common;
};
#endif // GIT_REPO_MIXIN_H
+123 -343
View File
@@ -22,15 +22,9 @@
*/
#include "kicad_git_common.h"
#include "kicad_git_memory.h"
#include "git_repo_mixin.h"
#include <git/git_progress.h>
#include <git/kicad_git_compat.h>
#include <kiplatform/secrets.h>
#include <trace_helpers.h>
#include <git2.h>
#include <wx/filename.h>
#include <wx/log.h>
#include <wx/textfile.h>
@@ -39,25 +33,9 @@
#include <vector>
KIGIT_COMMON::KIGIT_COMMON( git_repository* aRepo ) :
m_repo( aRepo ), m_connType( GIT_CONN_TYPE::GIT_CONN_LOCAL ), m_testedTypes( 0 ),
m_nextPublicKey( 0 )
m_repo( aRepo ), m_connType( GIT_CONN_TYPE::GIT_CONN_LOCAL ), m_testedTypes( 0 )
{}
KIGIT_COMMON::KIGIT_COMMON( const KIGIT_COMMON& aOther ) :
// Initialize base class and member variables
m_repo( aOther.m_repo ),
m_connType( aOther.m_connType ),
m_remote( aOther.m_remote ),
m_hostname( aOther.m_hostname ),
m_username( aOther.m_username ),
m_password( aOther.m_password ),
m_testedTypes( aOther.m_testedTypes ),
// The mutex is default-initialized, not copied
m_gitActionMutex(),
m_publicKeys( aOther.m_publicKeys ),
m_nextPublicKey( aOther.m_nextPublicKey )
{
}
KIGIT_COMMON::~KIGIT_COMMON()
{}
@@ -70,7 +48,6 @@ git_repository* KIGIT_COMMON::GetRepo() const
wxString KIGIT_COMMON::GetCurrentBranchName() const
{
wxCHECK( m_repo, wxEmptyString );
git_reference* head = nullptr;
int retval = git_repository_head( &head, m_repo );
@@ -78,33 +55,31 @@ wxString KIGIT_COMMON::GetCurrentBranchName() const
if( retval && retval != GIT_EUNBORNBRANCH && retval != GIT_ENOTFOUND )
return wxEmptyString;
KIGIT::GitReferencePtr headPtr( head );
git_reference* branch;
git_reference *branch;
if( git_reference_resolve( &branch, head ) )
{
wxLogTrace( traceGit, "Failed to resolve branch" );
git_reference_free( head );
return wxEmptyString;
}
KIGIT::GitReferencePtr branchPtr( branch );
const char* branchName = "";
git_reference_free( head );
const char* branchName = "";
if( git_branch_name( &branchName, branch ) )
{
wxLogTrace( traceGit, "Failed to get branch name" );
git_reference_free( branch );
return wxEmptyString;
}
git_reference_free( branch );
return wxString( branchName );
}
std::vector<wxString> KIGIT_COMMON::GetBranchNames() const
{
if( !m_repo )
return {};
std::vector<wxString> branchNames;
std::map<git_time_t, wxString> branchNamesMap;
wxString firstName;
@@ -112,45 +87,38 @@ std::vector<wxString> KIGIT_COMMON::GetBranchNames() const
git_branch_iterator* branchIterator = nullptr;
if( git_branch_iterator_new( &branchIterator, m_repo, GIT_BRANCH_LOCAL ) )
{
wxLogTrace( traceGit, "Failed to get branch iterator" );
return branchNames;
}
KIGIT::GitBranchIteratorPtr branchIteratorPtr( branchIterator );
git_reference* branchReference = nullptr;
git_branch_t branchType;
git_reference* branchReference = nullptr;
git_branch_t branchType;
while( git_branch_next( &branchReference, &branchType, branchIterator ) != GIT_ITEROVER )
{
const char* branchName = "";
KIGIT::GitReferencePtr branchReferencePtr( branchReference );
if( git_branch_name( &branchName, branchReference ) )
{
wxLogTrace( traceGit, "Failed to get branch name in iter loop" );
continue;
}
const git_oid* commitId = git_reference_target( branchReference );
git_commit* commit = nullptr;
if( git_commit_lookup( &commit, m_repo, commitId ) )
{
wxLogTrace( traceGit, "Failed to get commit in iter loop" );
continue;
}
KIGIT::GitCommitPtr commitPtr( commit );
git_time_t commitTime = git_commit_time( commit );
git_time_t commitTime = git_commit_time( commit );
if( git_branch_is_head( branchReference ) )
firstName = branchName;
else
branchNamesMap.emplace( commitTime, branchName );
git_commit_free( commit );
git_reference_free( branchReference );
}
git_branch_iterator_free( branchIterator );
// Add the current branch to the top of the list
if( !firstName.IsEmpty() )
branchNames.push_back( firstName );
@@ -165,7 +133,6 @@ std::vector<wxString> KIGIT_COMMON::GetBranchNames() const
std::vector<wxString> KIGIT_COMMON::GetProjectDirs()
{
wxCHECK( m_repo, {} );
std::vector<wxString> projDirs;
git_oid oid;
@@ -174,26 +141,22 @@ std::vector<wxString> KIGIT_COMMON::GetProjectDirs()
if( git_reference_name_to_id( &oid, m_repo, "HEAD" ) != GIT_OK )
{
wxLogTrace( traceGit, "An error occurred: %s", KIGIT_COMMON::GetLastGitError() );
wxLogError( "An error occurred: %s", git_error_last()->message );
return projDirs;
}
if( git_commit_lookup( &commit, m_repo, &oid ) != GIT_OK )
{
wxLogTrace( traceGit, "An error occurred: %s", KIGIT_COMMON::GetLastGitError() );
wxLogError( "An error occurred: %s", git_error_last()->message );
return projDirs;
}
KIGIT::GitCommitPtr commitPtr( commit );
if( git_commit_tree( &tree, commit ) != GIT_OK )
{
wxLogTrace( traceGit, "An error occurred: %s", KIGIT_COMMON::GetLastGitError() );
wxLogError( "An error occurred: %s", git_error_last()->message );
return projDirs;
}
KIGIT::GitTreePtr treePtr( tree );
// Define callback
git_tree_walk(
tree, GIT_TREEWALK_PRE,
@@ -214,6 +177,9 @@ std::vector<wxString> KIGIT_COMMON::GetProjectDirs()
},
&projDirs );
git_tree_free( tree );
git_commit_free( commit );
std::sort( projDirs.begin(), projDirs.end(),
[]( const wxString& a, const wxString& b )
{
@@ -233,33 +199,21 @@ std::vector<wxString> KIGIT_COMMON::GetProjectDirs()
std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles() const
{
auto get_modified_files = [&]( const git_oid* from_oid, const git_oid* to_oid ) -> std::set<wxString>
auto get_modified_files = [&]( git_oid* from_oid, git_oid* to_oid ) -> std::set<wxString>
{
std::set<wxString> modified_set;
git_revwalk* walker = nullptr;
if( !m_repo || !from_oid )
return modified_set;
if( git_revwalk_new( &walker, m_repo ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to create revwalker: %s", KIGIT_COMMON::GetLastGitError() );
return modified_set;
}
KIGIT::GitRevWalkPtr walkerPtr( walker );
if( git_revwalk_push( walker, from_oid ) != GIT_OK )
if( ( git_revwalk_push( walker, from_oid ) != GIT_OK )
|| ( git_revwalk_hide( walker, to_oid ) != GIT_OK ) )
{
wxLogTrace( traceGit, "Failed to set from commit: %s", KIGIT_COMMON::GetLastGitError() );
git_revwalk_free( walker );
return modified_set;
}
if( to_oid && git_revwalk_hide( walker, to_oid ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to set end commit (maybe new repo): %s", KIGIT_COMMON::GetLastGitError() );
}
git_oid oid;
git_commit* commit;
@@ -267,65 +221,46 @@ std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles
while( git_revwalk_next( &oid, walker ) == GIT_OK )
{
if( git_commit_lookup( &commit, m_repo, &oid ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to lookup commit: %s", KIGIT_COMMON::GetLastGitError() );
continue;
}
KIGIT::GitCommitPtr commitPtr( commit );
git_tree *tree, *parent_tree = nullptr;
if( git_commit_tree( &tree, commit ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to get commit tree: %s", KIGIT_COMMON::GetLastGitError() );
git_commit_free( commit );
continue;
}
KIGIT::GitTreePtr treePtr( tree );
// get parent commit tree to diff against
if( !git_commit_parentcount( commit ) )
{
git_tree_walk(
tree, GIT_TREEWALK_PRE,
[]( const char* root, const git_tree_entry* entry, void* payload )
{
std::set<wxString>* modified_set_internal = static_cast<std::set<wxString>*>( payload );
wxString filePath = wxString::Format( "%s%s", root, git_tree_entry_name( entry ) );
modified_set_internal->insert( filePath );
return 0; // continue walking
},
&modified_set );
git_tree_free( tree );
git_commit_free( commit );
continue;
}
git_commit* parent;
if( git_commit_parent( &parent, commit, 0 ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to get parent commit: %s", KIGIT_COMMON::GetLastGitError() );
git_tree_free( tree );
git_commit_free( commit );
continue;
}
KIGIT::GitCommitPtr parentPtr( parent );
if( git_commit_tree( &parent_tree, parent ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to get parent commit tree: %s", KIGIT_COMMON::GetLastGitError() );
git_tree_free( tree );
git_commit_free( commit );
git_commit_free( parent );
continue;
}
KIGIT::GitTreePtr parentTreePtr( parent_tree );
git_diff* diff;
git_diff_options diff_opts;
git_diff_init_options( &diff_opts, GIT_DIFF_OPTIONS_VERSION );
if( !m_repo || !parent_tree || !tree )
continue;
if( git_diff_tree_to_tree( &diff, m_repo, parent_tree, tree, &diff_opts ) == GIT_OK )
{
size_t num_deltas = git_diff_num_deltas( diff );
@@ -338,13 +273,14 @@ std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles
git_diff_free( diff );
}
else
{
wxLogTrace( traceGit, "Failed to diff trees: %s", KIGIT_COMMON::GetLastGitError() );
}
git_tree_free( parent_tree );
git_commit_free( parent );
git_tree_free( tree );
git_commit_free( commit );
}
wxLogTrace( traceGit, "Finished walking commits with end: %s", KIGIT_COMMON::GetLastGitError() );
git_revwalk_free( walker );
return modified_set;
};
@@ -358,24 +294,22 @@ std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles
git_reference* remote_head = nullptr;
if( git_repository_head( &head, m_repo ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to get modified HEAD" );
return modified_files;
}
KIGIT::GitReferencePtr headPtr( head );
if( git_branch_upstream( &remote_head, head ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to get modified remote HEAD" );
git_reference_free( head );
return modified_files;
}
KIGIT::GitReferencePtr remoteHeadPtr( remote_head );
const git_oid* head_oid = git_reference_target( head );
const git_oid* remote_oid = git_reference_target( remote_head );
git_oid head_oid = *git_reference_target( head );
git_oid remote_oid = *git_reference_target( remote_head );
modified_files.first = get_modified_files( head_oid, remote_oid );
modified_files.second = get_modified_files( remote_oid, head_oid );
git_reference_free( head );
git_reference_free( remote_head );
modified_files.first = get_modified_files( &head_oid, &remote_oid );
modified_files.second = get_modified_files( &remote_oid, &head_oid );
return modified_files;
}
@@ -390,42 +324,29 @@ bool KIGIT_COMMON::HasLocalCommits() const
git_reference* remote_head = nullptr;
if( git_repository_head( &head, m_repo ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to get HEAD: %s", KIGIT_COMMON::GetLastGitError() );
return false;
}
KIGIT::GitReferencePtr headPtr( head );
if( git_branch_upstream( &remote_head, head ) != GIT_OK )
{
// No remote branch, so we have local commits (new repo?)
wxLogTrace( traceGit, "Failed to get remote HEAD: %s", KIGIT_COMMON::GetLastGitError() );
return true;
git_reference_free( head );
return false;
}
KIGIT::GitReferencePtr remoteHeadPtr( remote_head );
const git_oid* head_oid = git_reference_target( head );
const git_oid* remote_oid = git_reference_target( remote_head );
git_revwalk* walker = nullptr;
git_oid head_oid = *git_reference_target( head );
git_oid remote_oid = *git_reference_target( remote_head );
git_reference_free( head );
git_reference_free( remote_head );
git_revwalk* walker = nullptr;
if( git_revwalk_new( &walker, m_repo ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to create revwalker: %s", KIGIT_COMMON::GetLastGitError() );
return false;
}
KIGIT::GitRevWalkPtr walkerPtr( walker );
if( !head_oid || git_revwalk_push( walker, head_oid ) != GIT_OK )
if( ( git_revwalk_push( walker, &head_oid ) != GIT_OK )
|| ( git_revwalk_hide( walker, &remote_oid ) != GIT_OK ) )
{
wxLogTrace( traceGit, "Failed to push commits: %s", KIGIT_COMMON::GetLastGitError() );
return false;
}
if( remote_oid && git_revwalk_hide( walker, remote_oid ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to push/hide commits: %s", KIGIT_COMMON::GetLastGitError() );
git_revwalk_free( walker );
return false;
}
@@ -434,27 +355,24 @@ bool KIGIT_COMMON::HasLocalCommits() const
// If we can't walk to the next commit, then we are at or behind the remote
if( git_revwalk_next( &oid, walker ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to walk to next commit: %s", KIGIT_COMMON::GetLastGitError() );
git_revwalk_free( walker );
return false;
}
git_revwalk_free( walker );
return true;
}
bool KIGIT_COMMON::HasPushAndPullRemote() const
{
wxCHECK( m_repo, false );
git_remote* remote = nullptr;
if( git_remote_lookup( &remote, m_repo, "origin" ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to get remote for haspushpull" );
return false;
}
KIGIT::GitRemotePtr remotePtr( remote );
// Get the URLs associated with the remote
const char* fetch_url = git_remote_url( remote );
const char* push_url = git_remote_pushurl( remote );
@@ -462,80 +380,40 @@ bool KIGIT_COMMON::HasPushAndPullRemote() const
// If no push URL is set, libgit2 defaults to using the fetch URL for pushing
if( !push_url )
{
wxLogTrace( traceGit, "No push URL set, using fetch URL" );
push_url = fetch_url;
}
// Clean up the remote object
git_remote_free( remote );
// Check if both URLs are valid (i.e., not NULL)
return fetch_url && push_url;
}
wxString KIGIT_COMMON::GetRemotename() const
{
wxCHECK( m_repo, wxEmptyString );
wxString retval;
git_reference* head = nullptr;
git_reference* upstream = nullptr;
if( git_repository_head( &head, m_repo ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to get remote name: %s", KIGIT_COMMON::GetLastGitError() );
return retval;
}
KIGIT::GitReferencePtr headPtr( head );
if( git_branch_upstream( &upstream, head ) != GIT_OK )
if( git_branch_upstream( &upstream, head ) == GIT_OK )
{
wxLogTrace( traceGit, "Failed to get upstream branch: %s", KIGIT_COMMON::GetLastGitError() );
git_strarray remotes = { nullptr, 0 };
git_buf remote_name = GIT_BUF_INIT_CONST( nullptr, 0 );
if( git_remote_list( &remotes, m_repo ) == GIT_OK )
if( git_branch_remote_name( &remote_name, m_repo, git_reference_name( upstream ) ) == GIT_OK )
{
if( remotes.count == 1 )
retval = remotes.strings[0];
git_strarray_dispose( &remotes );
}
else
{
wxLogTrace( traceGit, "Failed to list remotes: %s", KIGIT_COMMON::GetLastGitError() );
// If we can't get the remote name from the upstream branch or the list of remotes,
// just return the default remote name
git_remote* remote = nullptr;
if( git_remote_lookup( &remote, m_repo, "origin" ) == GIT_OK )
{
retval = git_remote_name( remote );
git_remote_free( remote );
}
else
{
wxLogTrace( traceGit, "Failed to get remote name from default remote: %s",
KIGIT_COMMON::GetLastGitError() );
}
retval = remote_name.ptr;
git_buf_dispose( &remote_name );
}
return retval;
git_reference_free( upstream );
}
KIGIT::GitReferencePtr upstreamPtr( upstream );
git_buf remote_name = GIT_BUF_INIT_CONST( nullptr, 0 );
if( git_branch_remote_name( &remote_name, m_repo, git_reference_name( upstream ) ) == GIT_OK )
{
retval = remote_name.ptr;
git_buf_dispose( &remote_name );
}
else
{
wxLogTrace( traceGit,
"Failed to get remote name from upstream branch: %s",
KIGIT_COMMON::GetLastGitError() );
}
git_reference_free( head );
return retval;
}
@@ -551,17 +429,6 @@ void KIGIT_COMMON::SetSSHKey( const wxString& aKey )
}
wxString KIGIT_COMMON::GetGitRootDirectory() const
{
if( !m_repo )
return wxEmptyString;
const char *path = git_repository_path( m_repo );
wxString retval = path;
return retval;
}
void KIGIT_COMMON::updatePublicKeys()
{
m_publicKeys.clear();
@@ -633,8 +500,6 @@ void KIGIT_COMMON::updatePublicKeys()
void KIGIT_COMMON::UpdateCurrentBranchInfo()
{
wxCHECK( m_repo, /* void */ );
// We want to get the current branch's upstream url as well as the stored password
// if one exists given the url and username.
@@ -658,26 +523,6 @@ void KIGIT_COMMON::UpdateCurrentBranchInfo()
updatePublicKeys();
}
KIGIT_COMMON::GIT_CONN_TYPE KIGIT_COMMON::GetConnType() const
{
wxString remote = m_remote;
if( remote.IsEmpty() )
remote = GetRemotename();
if( remote.StartsWith( "https://" ) || remote.StartsWith( "http://" ) )
{
return GIT_CONN_TYPE::GIT_CONN_HTTPS;
}
else if( remote.StartsWith( "ssh://" ) || remote.StartsWith( "git@" ) || remote.StartsWith( "git+ssh://" )
|| remote.EndsWith( ".git" ) )
{
return GIT_CONN_TYPE::GIT_CONN_SSH;
}
return GIT_CONN_TYPE::GIT_CONN_LOCAL;
}
void KIGIT_COMMON::updateConnectionType()
{
if( m_remote.StartsWith( "https://" ) || m_remote.StartsWith( "http://" ) )
@@ -747,62 +592,6 @@ void KIGIT_COMMON::updateConnectionType()
}
int KIGIT_COMMON::HandleSSHKeyAuthentication( git_cred** aOut, const wxString& aUsername )
{
if( !( m_testedTypes & KIGIT_CREDENTIAL_SSH_AGENT ) )
return HandleSSHAgentAuthentication( aOut, aUsername );
// SSH key authentication with password
wxString sshKey = GetNextPublicKey();
if( sshKey.IsEmpty() )
{
wxLogTrace( traceGit, "Finished testing all possible ssh keys" );
m_testedTypes |= GIT_CREDENTIAL_SSH_KEY;
return GIT_PASSTHROUGH;
}
wxString sshPubKey = sshKey + ".pub";
wxString password = GetPassword();
wxLogTrace( traceGit, "Testing %s\n", sshKey );
if( git_credential_ssh_key_new( aOut, aUsername.mbc_str(), sshPubKey.mbc_str(), sshKey.mbc_str(),
password.mbc_str() ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to create SSH key credential for %s: %s",
aUsername, KIGIT_COMMON::GetLastGitError() );
return GIT_PASSTHROUGH;
}
return GIT_OK;
}
int KIGIT_COMMON::HandlePlaintextAuthentication( git_cred** aOut, const wxString& aUsername )
{
wxString password = GetPassword();
git_credential_userpass_plaintext_new( aOut, aUsername.mbc_str(), password.mbc_str() );
m_testedTypes |= GIT_CREDENTIAL_USERPASS_PLAINTEXT;
return GIT_OK;
}
int KIGIT_COMMON::HandleSSHAgentAuthentication( git_cred** aOut, const wxString& aUsername )
{
if( git_credential_ssh_key_from_agent( aOut, aUsername.mbc_str() ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to create SSH agent credential for %s: %s",
aUsername, KIGIT_COMMON::GetLastGitError() );
return GIT_PASSTHROUGH;
}
m_testedTypes |= KIGIT_CREDENTIAL_SSH_AGENT;
return GIT_OK;
}
extern "C" int fetchhead_foreach_cb( const char*, const char*,
const git_oid* aOID, unsigned int aIsMerge, void* aPayload )
{
@@ -813,18 +602,18 @@ extern "C" int fetchhead_foreach_cb( const char*, const char*,
}
extern "C" void clone_progress_cb( const char* aStr, size_t aLen, size_t aTotal, void* aPayload )
extern "C" void clone_progress_cb( const char* aStr, size_t aLen, size_t aTotal, void* data )
{
KIGIT_REPO_MIXIN* parent = reinterpret_cast<KIGIT_REPO_MIXIN*>( aPayload );
KIGIT_COMMON* parent = (KIGIT_COMMON*) data;
wxString progressMessage( aStr );
parent->UpdateProgress( aLen, aTotal, progressMessage );
}
extern "C" int progress_cb( const char* str, int len, void* aPayload )
extern "C" int progress_cb( const char* str, int len, void* data )
{
KIGIT_REPO_MIXIN* parent = reinterpret_cast<KIGIT_REPO_MIXIN*>( aPayload );
KIGIT_COMMON* parent = (KIGIT_COMMON*) data;
wxString progressMessage( str, len );
parent->UpdateProgress( 0, 0, progressMessage );
@@ -835,11 +624,10 @@ extern "C" int progress_cb( const char* str, int len, void* aPayload )
extern "C" int transfer_progress_cb( const git_transfer_progress* aStats, void* aPayload )
{
KIGIT_REPO_MIXIN* parent = reinterpret_cast<KIGIT_REPO_MIXIN*>( aPayload );
wxString progressMessage = wxString::Format( _( "Received %u of %u objects" ),
aStats->received_objects,
aStats->total_objects );
KIGIT_COMMON* parent = (KIGIT_COMMON*) aPayload;
wxString progressMessage = wxString::Format( _( "Received %u of %u objects" ),
aStats->received_objects,
aStats->total_objects );
parent->UpdateProgress( aStats->received_objects, aStats->total_objects, progressMessage );
@@ -854,8 +642,8 @@ extern "C" int update_cb( const char* aRefname, const git_oid* aFirst, const git
char a_str[cstring_len + 1];
char b_str[cstring_len + 1];
KIGIT_REPO_MIXIN* parent = reinterpret_cast<KIGIT_REPO_MIXIN*>( aPayload );
wxString status;
KIGIT_COMMON* parent = (KIGIT_COMMON*) aPayload;
wxString status;
git_oid_tostr( b_str, cstring_len, aSecond );
@@ -882,15 +670,15 @@ extern "C" int update_cb( const char* aRefname, const git_oid* aFirst, const git
extern "C" int push_transfer_progress_cb( unsigned int aCurrent, unsigned int aTotal, size_t aBytes,
void* aPayload )
{
long long progress = 100;
KIGIT_REPO_MIXIN* parent = reinterpret_cast<KIGIT_REPO_MIXIN*>( aPayload );
int64_t progress = 100;
KIGIT_COMMON* parent = (KIGIT_COMMON*) aPayload;
if( aTotal != 0 )
{
progress = ( aCurrent * 100ll ) / aTotal;
progress = ( aCurrent * 100 ) / aTotal;
}
wxString progressMessage = wxString::Format( _( "Writing objects: %lld%% (%u/%u), %zu bytes" ),
wxString progressMessage = wxString::Format( _( "Writing objects: %d%% (%d/%d), %d bytes" ),
progress, aCurrent, aTotal, aBytes );
parent->UpdateProgress( aCurrent, aTotal, progressMessage );
@@ -900,8 +688,8 @@ extern "C" int push_transfer_progress_cb( unsigned int aCurrent, unsigned int aT
extern "C" int push_update_reference_cb( const char* aRefname, const char* aStatus, void* aPayload )
{
KIGIT_REPO_MIXIN* parent = reinterpret_cast<KIGIT_REPO_MIXIN*>( aPayload );
wxString status( aStatus );
KIGIT_COMMON* parent = (KIGIT_COMMON*) aPayload;
wxString status( aStatus );
if( !status.IsEmpty() )
{
@@ -921,62 +709,54 @@ extern "C" int push_update_reference_cb( const char* aRefname, const char* aStat
extern "C" int credentials_cb( git_cred** aOut, const char* aUrl, const char* aUsername,
unsigned int aAllowedTypes, void* aPayload )
{
KIGIT_REPO_MIXIN* parent = reinterpret_cast<KIGIT_REPO_MIXIN*>( aPayload );
KIGIT_COMMON* common = parent->GetCommon();
wxLogTrace( traceGit, "Credentials callback for %s, testing %d", aUrl, aAllowedTypes );
KIGIT_COMMON* parent = static_cast<KIGIT_COMMON*>( aPayload );
if( parent->GetConnType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_LOCAL )
{
wxLogTrace( traceGit, "Local repository, no credentials needed" );
return GIT_PASSTHROUGH;
}
if( aAllowedTypes & GIT_CREDENTIAL_USERNAME
&& !( parent->TestedTypes() & GIT_CREDENTIAL_USERNAME ) )
if( aAllowedTypes & GIT_CREDTYPE_USERNAME
&& !( parent->TestedTypes() & GIT_CREDTYPE_USERNAME ) )
{
wxString username = parent->GetUsername().Trim().Trim( false );
wxLogTrace( traceGit, "Username credential for %s at %s with allowed type %d",
username, aUrl, aAllowedTypes );
if( git_credential_username_new( aOut, username.ToStdString().c_str() ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to create username credential for %s: %s",
username, KIGIT_COMMON::GetLastGitError() );
}
else
{
wxLogTrace( traceGit, "Created username credential for %s", username );
}
parent->TestedTypes() |= GIT_CREDENTIAL_USERNAME;
git_cred_username_new( aOut, username.ToStdString().c_str() );
parent->TestedTypes() |= GIT_CREDTYPE_USERNAME;
}
else if( parent->GetConnType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_HTTPS
&& ( aAllowedTypes & GIT_CREDENTIAL_USERPASS_PLAINTEXT )
&& !( parent->TestedTypes() & GIT_CREDENTIAL_USERPASS_PLAINTEXT ) )
&& ( aAllowedTypes & GIT_CREDTYPE_USERPASS_PLAINTEXT )
&& !( parent->TestedTypes() & GIT_CREDTYPE_USERPASS_PLAINTEXT ) )
{
// Plaintext authentication
wxLogTrace( traceGit, "Plaintext authentication for %s at %s with allowed type %d",
parent->GetUsername(), aUrl, aAllowedTypes );
return common->HandlePlaintextAuthentication( aOut, parent->GetUsername() );
wxString username = parent->GetUsername().Trim().Trim( false );
wxString password = parent->GetPassword().Trim().Trim( false );
git_cred_userpass_plaintext_new( aOut, username.ToStdString().c_str(),
password.ToStdString().c_str() );
parent->TestedTypes() |= GIT_CREDTYPE_USERPASS_PLAINTEXT;
}
else if( parent->GetConnType() == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_SSH
&& ( aAllowedTypes & GIT_CREDENTIAL_SSH_KEY )
&& !( parent->TestedTypes() & GIT_CREDENTIAL_SSH_KEY ) )
&& ( aAllowedTypes & GIT_CREDTYPE_SSH_KEY )
&& !( parent->TestedTypes() & GIT_CREDTYPE_SSH_KEY ) )
{
// SSH key authentication
return common->HandleSSHKeyAuthentication( aOut, parent->GetUsername() );
wxString sshKey = parent->GetNextPublicKey();
if( sshKey.IsEmpty() )
{
parent->TestedTypes() |= GIT_CREDTYPE_SSH_KEY;
return GIT_PASSTHROUGH;
}
wxString sshPubKey = sshKey + ".pub";
wxString username = parent->GetUsername().Trim().Trim( false );
wxString password = parent->GetPassword().Trim().Trim( false );
git_cred_ssh_key_new( aOut, username.ToStdString().c_str(),
sshPubKey.ToStdString().c_str(),
sshKey.ToStdString().c_str(),
password.ToStdString().c_str() );
}
else
{
// If we didn't find anything to try, then we don't have a callback set that the
// server likes
if( !parent->TestedTypes() )
return GIT_PASSTHROUGH;
git_error_clear();
git_error_set_str( GIT_ERROR_NET, _( "Unable to authenticate" ).mbc_str() );
// Otherwise, we did try something but we failed, so return an authentication error
return GIT_EAUTH;
return GIT_PASSTHROUGH;
}
return GIT_OK;
+13 -40
View File
@@ -27,17 +27,15 @@
#include <git/kicad_git_errors.h>
#include <git2.h>
#include <mutex>
#include <set>
#include <wx/string.h>
class KIGIT_COMMON
class KIGIT_COMMON : public KIGIT_ERRORS
{
public:
KIGIT_COMMON( git_repository* aRepo );
KIGIT_COMMON( const KIGIT_COMMON& aOther );
~KIGIT_COMMON();
git_repository* GetRepo() const;
@@ -51,6 +49,8 @@ public:
std::vector<wxString> GetBranchNames() const;
virtual void UpdateProgress( int aCurrent, int aTotal, const wxString& aMessage ) {};
/**
* Return a vector of project files in the repository. Sorted by the depth of
* the project file in the directory tree
@@ -76,7 +76,6 @@ public:
GIT_STATUS_BEHIND, // File changed in remote repository but not in local
GIT_STATUS_AHEAD, // File changed in local repository but not in remote
GIT_STATUS_CONFLICTED,
GIT_STATUS_IGNORED,
GIT_STATUS_LAST
};
@@ -90,12 +89,19 @@ public:
wxString GetUsername() const { return m_username; }
wxString GetPassword() const { return m_password; }
GIT_CONN_TYPE GetConnType() const;
GIT_CONN_TYPE GetConnType() const { return m_connType; }
void SetUsername( const wxString& aUsername ) { m_username = aUsername; }
void SetPassword( const wxString& aPassword ) { m_password = aPassword; }
void SetSSHKey( const wxString& aSSHKey );
void SetConnType( GIT_CONN_TYPE aConnType ) { m_connType = aConnType; }
void SetConnType( unsigned aConnType )
{
if( aConnType < static_cast<unsigned>( GIT_CONN_TYPE::GIT_CONN_LAST ) )
m_connType = static_cast<GIT_CONN_TYPE>( aConnType );
}
// Holds a temporary variable that can be used by the authentication callback
// to remember which types of authentication have been tested so that we
// don't loop forever.
@@ -110,8 +116,6 @@ public:
// Updates the password and remote information for the repository given the current branch
void UpdateCurrentBranchInfo();
wxString GetGitRootDirectory() const;
wxString GetRemotename() const;
void ResetNextKey() { m_nextPublicKey = 0; }
@@ -124,28 +128,6 @@ public:
return m_publicKeys[m_nextPublicKey++];
}
void SetRemote( const wxString& aRemote )
{
m_remote = aRemote;
updateConnectionType();
}
int HandleSSHKeyAuthentication( git_cred** aOut, const wxString& aUsername );
int HandlePlaintextAuthentication( git_cred** aOut, const wxString& aUsername );
int HandleSSHAgentAuthentication( git_cred** aOut, const wxString& aUsername );
static wxString GetLastGitError()
{
const git_error* error = git_error_last();
if( error == nullptr )
return wxString( "No error" );
return wxString( error->message );
}
protected:
git_repository* m_repo;
@@ -157,13 +139,6 @@ protected:
unsigned m_testedTypes;
std::mutex m_gitActionMutex;
// Make git handlers friends so they can access the mutex
friend class GIT_PUSH_HANDLER;
friend class GIT_PULL_HANDLER;
friend class GIT_CLONE_HANDLER;
private:
void updatePublicKeys();
void updateConnectionType();
@@ -171,12 +146,10 @@ private:
std::vector<wxString> m_publicKeys;
int m_nextPublicKey;
// Create a dummy flag to tell if we have tested ssh agent credentials separately
// from the ssh key credentials
static const unsigned KIGIT_CREDENTIAL_SSH_AGENT = 1 << sizeof( m_testedTypes - 1 );
};
extern "C" int progress_cb( const char* str, int len, void* data );
extern "C" int progress_cb( const char* str, int len, void* data );
extern "C" void clone_progress_cb( const char* str, size_t len, size_t total, void* data );
extern "C" int transfer_progress_cb( const git_transfer_progress* aStats, void* aPayload );
extern "C" int update_cb( const char* aRefname, const git_oid* aFirst, const git_oid* aSecond,
-4
View File
@@ -31,8 +31,4 @@
#define GIT_BUF_INIT { NULL, 0, 0 }
#endif
#if LIBGIT2_VER_MAJOR > 1 || ( LIBGIT2_VER_MAJOR == 1 && LIBGIT2_VER_MINOR >= 8 )
#include <git2/sys/errors.h>
#endif
#endif // KICAD_GIT_COMPAT_H_
-263
View File
@@ -1,263 +0,0 @@
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
#ifndef KICAD_GIT_MEMORY_H
#define KICAD_GIT_MEMORY_H
#include <memory>
#include <git2.h>
namespace KIGIT
{
/**
* @brief A unique pointer for git_repository objects with automatic cleanup.
*/
using GitRepositoryPtr = std::unique_ptr<git_repository,
decltype([](git_repository* aRepo) {
git_repository_free(aRepo);
})>;
/**
* @brief A unique pointer for git_reference objects with automatic cleanup.
*/
using GitReferencePtr = std::unique_ptr<git_reference,
decltype([](git_reference* aRef) {
git_reference_free(aRef);
})>;
/**
* @brief A unique pointer for git_object objects with automatic cleanup.
*/
using GitObjectPtr = std::unique_ptr<git_object,
decltype([](git_object* aObject) {
git_object_free(aObject);
})>;
/**
* @brief A unique pointer for git_commit objects with automatic cleanup.
*/
using GitCommitPtr = std::unique_ptr<git_commit,
decltype([](git_commit* aCommit) {
git_commit_free(aCommit);
})>;
/**
* @brief A unique pointer for git_tree objects with automatic cleanup.
*/
using GitTreePtr = std::unique_ptr<git_tree,
decltype([](git_tree* aTree) {
git_tree_free(aTree);
})>;
/**
* @brief A unique pointer for git_index objects with automatic cleanup.
*/
using GitIndexPtr = std::unique_ptr<git_index,
decltype([](git_index* aIndex) {
git_index_free(aIndex);
})>;
/**
* @brief A unique pointer for git_rebase objects with automatic cleanup.
*/
using GitRebasePtr = std::unique_ptr<git_rebase,
decltype([](git_rebase* aRebase) {
git_rebase_free(aRebase);
})>;
/**
* @brief A unique pointer for git_revwalk objects with automatic cleanup.
*/
using GitRevWalkPtr = std::unique_ptr<git_revwalk,
decltype([](git_revwalk* aWalker) {
git_revwalk_free(aWalker);
})>;
/**
* @brief A unique pointer for git_diff objects with automatic cleanup.
*/
using GitDiffPtr = std::unique_ptr<git_diff,
decltype([](git_diff* aDiff) {
git_diff_free(aDiff);
})>;
/**
* @brief A unique pointer for git_signature objects with automatic cleanup.
*/
using GitSignaturePtr = std::unique_ptr<git_signature,
decltype([](git_signature* aSignature) {
git_signature_free(aSignature);
})>;
/**
* @brief A unique pointer for git_config objects with automatic cleanup.
*/
using GitConfigPtr = std::unique_ptr<git_config,
decltype([](git_config* aConfig) {
git_config_free(aConfig);
})>;
/**
* @brief A unique pointer for git_remote objects with automatic cleanup.
*/
using GitRemotePtr = std::unique_ptr<git_remote,
decltype([](git_remote* aRemote) {
git_remote_free(aRemote);
})>;
/**
* @brief A unique pointer for git_annotated_commit objects with automatic cleanup.
*/
using GitAnnotatedCommitPtr = std::unique_ptr<git_annotated_commit,
decltype([](git_annotated_commit* aCommit) {
git_annotated_commit_free(aCommit);
})>;
/**
* @brief A unique pointer for git_oid objects with automatic cleanup.
*/
using GitOidPtr = std::unique_ptr<git_oid,
decltype([](git_oid* aOid) {
delete aOid;
})>;
/**
* @brief A unique pointer for git_buf objects with automatic cleanup.
*/
using GitBufPtr = std::unique_ptr<git_buf,
decltype([](git_buf* aBuf) {
git_buf_free(aBuf);
})>;
/**
* @brief A unique pointer for git_blame objects with automatic cleanup.
*/
using GitBlamePtr = std::unique_ptr<git_blame,
decltype([](git_blame* aBlame) {
git_blame_free(aBlame);
})>;
/**
* @brief A unique pointer for git_blob objects with automatic cleanup.
*/
using GitBlobPtr = std::unique_ptr<git_blob,
decltype([](git_blob* aBlob) {
git_blob_free(aBlob);
})>;
/**
* @brief A unique pointer for git_branch_iterator objects with automatic cleanup.
*/
using GitBranchIteratorPtr = std::unique_ptr<git_branch_iterator,
decltype([](git_branch_iterator* aIter) {
git_branch_iterator_free(aIter);
})>;
/**
* @brief A unique pointer for git_config_entry objects with automatic cleanup.
*/
using GitConfigEntryPtr = std::unique_ptr<git_config_entry,
decltype([](git_config_entry* aEntry) {
git_config_entry_free(aEntry);
})>;
/**
* @brief A unique pointer for git_config_iterator objects with automatic cleanup.
*/
using GitConfigIteratorPtr = std::unique_ptr<git_config_iterator,
decltype([](git_config_iterator* aIter) {
git_config_iterator_free(aIter);
})>;
/**
* @brief A unique pointer for git_credential objects with automatic cleanup.
*/
using GitCredentialPtr = std::unique_ptr<git_credential,
decltype([](git_credential* aCred) {
git_credential_free(aCred);
})>;
/**
* @brief A unique pointer for git_oidarray objects with automatic cleanup.
*/
using GitOidArrayPtr = std::unique_ptr<git_oidarray,
decltype([](git_oidarray* aArray) {
git_oidarray_free(aArray);
})>;
/**
* @brief A unique pointer for git_strarray objects with automatic cleanup.
*/
using GitStrArrayPtr = std::unique_ptr<git_strarray,
decltype([](git_strarray* aArray) {
git_strarray_free(aArray);
})>;
/**
* @brief A unique pointer for git_describe_result objects with automatic cleanup.
*/
using GitDescribeResultPtr = std::unique_ptr<git_describe_result,
decltype([](git_describe_result* aResult) {
git_describe_result_free(aResult);
})>;
/**
* @brief A unique pointer for git_diff_stats objects with automatic cleanup.
*/
using GitDiffStatsPtr = std::unique_ptr<git_diff_stats,
decltype([](git_diff_stats* aStats) {
git_diff_stats_free(aStats);
})>;
/**
* @brief A unique pointer for git_filter_list objects with automatic cleanup.
*/
using GitFilterListPtr = std::unique_ptr<git_filter_list,
decltype([](git_filter_list* aFilters) {
git_filter_list_free(aFilters);
})>;
/**
* @brief A unique pointer for git_indexer objects with automatic cleanup.
*/
using GitIndexerPtr = std::unique_ptr<git_indexer,
decltype([](git_indexer* aIdx) {
git_indexer_free(aIdx);
})>;
/**
* @brief A unique pointer for git_index_iterator objects with automatic cleanup.
*/
using GitIndexIteratorPtr = std::unique_ptr<git_index_iterator,
decltype([](git_index_iterator* aIterator) {
git_index_iterator_free(aIterator);
})>;
/**
* @brief A unique pointer for git_index_conflict_iterator objects with automatic cleanup.
*/
using GitIndexConflictIteratorPtr = std::unique_ptr<git_index_conflict_iterator,
decltype([](git_index_conflict_iterator* aIterator) {
git_index_conflict_iterator_free(aIterator);
})>;
/**
* @brief A unique pointer for git_status_list objects with automatic cleanup.
*/
using GitStatusListPtr = std::unique_ptr<git_status_list,
decltype([](git_status_list* aList) {
git_status_list_free(aList);
})>;
} // namespace KIGIT
#endif // KICAD_GIT_MEMORY_H
+1 -1
View File
@@ -323,7 +323,7 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags )
ret = hash_board_item( table, aFlags );
hash_combine( ret, table->StrokeExternal() );
hash_combine( ret, table->StrokeHeaderSeparator() );
hash_combine( ret, table->StrokeHeader() );
hash_combine( ret, table->StrokeColumns() );
hash_combine( ret, table->StrokeRows() );
+1 -1
View File
@@ -49,7 +49,7 @@ static PSEUDO_ACTION* g_gesturePseudoActions[] = {
new PSEUDO_ACTION( _( "Finish Drawing" ), PSEUDO_WXK_DBLCLICK ),
new PSEUDO_ACTION( _( "Add to Selection" ), MD_SHIFT + PSEUDO_WXK_CLICK ),
new PSEUDO_ACTION( _( "Highlight Net" ), MD_CTRL + PSEUDO_WXK_CLICK ),
new PSEUDO_ACTION( _( "Remove from Selection" ), MD_CTRL + MD_SHIFT + PSEUDO_WXK_CLICK ),
new PSEUDO_ACTION( _( "Remove from Selection" ), MD_SHIFT + MD_CTRL + PSEUDO_WXK_CLICK ),
new PSEUDO_ACTION( _( "Ignore Grid Snaps" ), MD_CTRL ),
new PSEUDO_ACTION( _( "Ignore Other Snaps" ), MD_SHIFT ),
};
+6 -6
View File
@@ -1006,10 +1006,10 @@ double DXF_IMPORT_PLUGIN::getCurrentUnitScale()
switch( m_currentUnit )
{
case DXF_IMPORT_UNITS::INCH: scale = 25.4; break;
case DXF_IMPORT_UNITS::INCHES: scale = 25.4; break;
case DXF_IMPORT_UNITS::FEET: scale = 304.8; break;
case DXF_IMPORT_UNITS::MM: scale = 1.0; break;
case DXF_IMPORT_UNITS::CM: scale = 10.0; break;
case DXF_IMPORT_UNITS::MILLIMETERS: scale = 1.0; break;
case DXF_IMPORT_UNITS::CENTIMETERS: scale = 10.0; break;
case DXF_IMPORT_UNITS::METERS: scale = 1000.0; break;
case DXF_IMPORT_UNITS::MICROINCHES: scale = 2.54e-5; break;
case DXF_IMPORT_UNITS::MILS: scale = 0.0254; break;
@@ -1065,10 +1065,10 @@ void DXF_IMPORT_PLUGIN::setVariableInt( const std::string& key, int value, int c
switch( value )
{
case 1: m_currentUnit = DXF_IMPORT_UNITS::INCH; break;
case 1: m_currentUnit = DXF_IMPORT_UNITS::INCHES; break;
case 2: m_currentUnit = DXF_IMPORT_UNITS::FEET; break;
case 4: m_currentUnit = DXF_IMPORT_UNITS::MM; break;
case 5: m_currentUnit = DXF_IMPORT_UNITS::CM; break;
case 4: m_currentUnit = DXF_IMPORT_UNITS::MILLIMETERS; break;
case 5: m_currentUnit = DXF_IMPORT_UNITS::CENTIMETERS; break;
case 6: m_currentUnit = DXF_IMPORT_UNITS::METERS; break;
case 8: m_currentUnit = DXF_IMPORT_UNITS::MICROINCHES; break;
case 9: m_currentUnit = DXF_IMPORT_UNITS::MILS; break;
+3 -3
View File
@@ -182,10 +182,10 @@ public:
enum class DXF_IMPORT_UNITS
{
DEFAULT = 0,
INCH = 1,
INCHES = 1,
FEET = 2,
MM = 4,
CM = 5,
MILLIMETERS = 4,
CENTIMETERS = 5,
METERS = 6,
MICROINCHES = 8,
MILS = 9,
+1 -3
View File
@@ -201,9 +201,7 @@ public:
IMPORTED_POLYGON( const std::vector<VECTOR2D>& aVertices, const IMPORTED_STROKE& aStroke,
bool aFilled, const COLOR4D& aFillColor ) :
m_vertices( aVertices ),
m_stroke( aStroke ),
m_filled( aFilled ),
m_fillColor( aFillColor )
m_stroke( aStroke ), m_filled( aFilled ), m_fillColor( aFillColor )
{
}
+2 -6
View File
@@ -195,12 +195,8 @@ bool SVG_IMPORT_PLUGIN::Import()
// *not* closed so create a filled, closed shape for the fill, and an unfilled,
// open shape for the outline
static IMPORTED_STROKE noStroke( -1, LINE_STYLE::SOLID, COLOR4D::UNSPECIFIED );
const bool closed = true;
DrawPath( path->pts, path->npts, closed, noStroke, true, fillColor );
if( stroke.GetWidth() > 0 )
DrawPath( path->pts, path->npts, !closed, stroke, false, COLOR4D::UNSPECIFIED );
DrawPath( path->pts, path->npts, true, noStroke, true, fillColor );
DrawPath( path->pts, path->npts, false, stroke, false, COLOR4D::UNSPECIFIED );
}
else
{
+9 -20
View File
@@ -47,11 +47,6 @@ std::string FormatPath( const std::vector<std::string>& aVectorPath )
}
ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE()
{
}
ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const wxString& aFilePath )
{
// Open file
@@ -96,12 +91,6 @@ ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const wxString& aFilePath )
ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const void* aBuffer, size_t aLen )
{
InitFromBuffer( aBuffer, aLen );
}
void ALTIUM_COMPOUND_FILE::InitFromBuffer( const void* aBuffer, size_t aLen )
{
m_buffer.resize( aLen );
memcpy( m_buffer.data(), aBuffer, aLen );
@@ -117,11 +106,10 @@ void ALTIUM_COMPOUND_FILE::InitFromBuffer( const void* aBuffer, size_t aLen )
}
bool ALTIUM_COMPOUND_FILE::DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe,
ALTIUM_COMPOUND_FILE* aOutput )
std::unique_ptr<ALTIUM_COMPOUND_FILE>
ALTIUM_COMPOUND_FILE::DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe )
{
wxCHECK( aOutput, false );
wxCHECK( cfe.size >= 1, false );
wxCHECK( cfe.size >= 1, nullptr );
size_t streamSize = cfe.size;
wxMemoryBuffer buffer( streamSize );
@@ -142,13 +130,14 @@ bool ALTIUM_COMPOUND_FILE::DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& c
decodedPcbLibStream << zlibInputStream;
wxStreamBuffer* outStream = decodedPcbLibStream.GetOutputStreamBuffer();
aOutput->InitFromBuffer( outStream->GetBufferStart(), outStream->GetIntPosition() );
return true;
return std::make_unique<ALTIUM_COMPOUND_FILE>( outStream->GetBufferStart(),
outStream->GetIntPosition() );
}
else if( buffer[0] == 0x00 )
{
aOutput->InitFromBuffer( static_cast<uint8_t*>( buffer.GetData() ) + 1, streamSize - 1 );
return true;
return std::make_unique<ALTIUM_COMPOUND_FILE>(
reinterpret_cast<uint8_t*>( buffer.GetData() ) + 1, streamSize - 1 );
}
else
{
@@ -156,7 +145,7 @@ bool ALTIUM_COMPOUND_FILE::DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& c
buffer[0], buffer[1], buffer[2], buffer[3], buffer[4] ) );
}
return false;
return nullptr;
}
+1 -13
View File
@@ -70,9 +70,6 @@ class ALTIUM_COMPOUND_FILE
friend class ALTIUM_PCB_COMPOUND_FILE;
public:
/// Create an uninitialized file for two-step initialization (e.g. with InitFromBuffer)
ALTIUM_COMPOUND_FILE();
/**
* Open a CFB file. Constructor might throw an IO_ERROR.
*
@@ -93,18 +90,9 @@ public:
ALTIUM_COMPOUND_FILE& operator=( const ALTIUM_COMPOUND_FILE& temp_obj ) = delete;
~ALTIUM_COMPOUND_FILE() = default;
/**
* Load a CFB file from memory; may throw an IO_ERROR.
* Data is copied.
*
* @param aBuffer data buffer
* @param aLen data length
*/
void InitFromBuffer( const void* aBuffer, size_t aLen );
const CFB::CompoundFileReader& GetCompoundFileReader() const { return *m_reader; }
bool DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe, ALTIUM_COMPOUND_FILE* aOutput );
std::unique_ptr<ALTIUM_COMPOUND_FILE> DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe );
const CFB::COMPOUND_FILE_ENTRY* FindStream( const std::vector<std::string>& aStreamPath ) const;
+11 -12
View File
@@ -39,7 +39,6 @@
#include <functional>
#include <cstdio>
#include <array>
constexpr auto DEFAULT_ALIGNMENT = ETEXT::BOTTOM_LEFT;
@@ -229,10 +228,10 @@ ECOORD::ECOORD( const wxString& aValue, enum ECOORD::EAGLE_UNIT aUnit )
{
// This array is used to adjust the fraction part value basing on the number of digits
// in the fraction.
static std::array<int, 9> DIVIDERS = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
constexpr int DIVIDERS[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
constexpr unsigned int DIVIDERS_MAX_IDX = sizeof( DIVIDERS ) / sizeof( DIVIDERS[0] ) - 1;
int integer, pre_fraction, post_fraction;
long long unsigned fraction;
int integer, fraction, pre_fraction, post_fraction;
// The following check is needed to handle correctly negative fractions where the integer
// part == 0.
@@ -240,7 +239,7 @@ ECOORD::ECOORD( const wxString& aValue, enum ECOORD::EAGLE_UNIT aUnit )
// %n is used to find out how many digits contains the fraction part, e.g. 0.001 contains 3
// digits.
int ret = sscanf( aValue.c_str(), "%d.%n%llu%n", &integer, &pre_fraction, &fraction,
int ret = sscanf( aValue.c_str(), "%d.%n%d%n", &integer, &pre_fraction, &fraction,
&post_fraction );
if( ret == 0 )
@@ -256,11 +255,11 @@ ECOORD::ECOORD( const wxString& aValue, enum ECOORD::EAGLE_UNIT aUnit )
// adjust the number of digits if necessary as we cannot handle anything smaller than
// nanometers (rounding).
if( digits >= static_cast<int>( DIVIDERS.size() ) )
if( (unsigned) digits > DIVIDERS_MAX_IDX )
{
long long unsigned denom = pow( 10, digits - DIVIDERS.size() + 1 );
digits = DIVIDERS.size() - 1;
fraction /= denom;
int diff = digits - DIVIDERS_MAX_IDX;
digits = DIVIDERS_MAX_IDX;
fraction /= DIVIDERS[diff];
}
int frac_value = ConvertToNm( fraction, aUnit ) / DIVIDERS[digits];
@@ -1262,13 +1261,13 @@ EPOLYGON::EPOLYGON( wxXmlNode* aPolygon, IO_BASE* aIo ) :
opt_wxString s = parseOptionalAttribute<wxString>( aPolygon, "pour" );
// default pour to solid fill
pour = EPOLYGON::ESOLID;
pour = EPOLYGON::SOLID;
// (solid | hatch | cutout)
if( s == "hatch" )
pour = EPOLYGON::EHATCH;
pour = EPOLYGON::HATCH;
else if( s == "cutout" )
pour = EPOLYGON::ECUTOUT;
pour = EPOLYGON::CUTOUT;
orphans = parseOptionalAttribute<bool>( aPolygon, "orphans" );
thermals = parseOptionalAttribute<bool>( aPolygon, "thermals" );
+3 -3
View File
@@ -1168,9 +1168,9 @@ struct EPOLYGON : public EAGLE_BASE
static const int max_priority = 6;
enum { // for pour
ESOLID,
EHATCH,
ECUTOUT,
SOLID,
HATCH,
CUTOUT,
};
int pour;
+1 -1
View File
@@ -76,7 +76,7 @@ bool IO_BASE::CanReadLibrary( const wxString& aFileName ) const
{
const std::vector<std::string>& exts = desc.m_FileExtensions;
wxString fileExt = wxFileName( aFileName ).GetExt().Lower();
wxString fileExt = wxFileName( aFileName ).GetExt().MakeLower();
for( const std::string& ext : exts )
{
+1 -1
View File
@@ -146,7 +146,7 @@ wxString JOB::GetFullOutputPath( PROJECT* aProject ) const
}
}
return outPath;
return m_outputPath;
}
+20 -21
View File
@@ -25,20 +25,20 @@
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_3D::FORMAT,
{
{ JOB_EXPORT_PCB_3D::FORMAT::UNKNOWN, nullptr },
{ JOB_EXPORT_PCB_3D::FORMAT::STEP, "step" },
{ JOB_EXPORT_PCB_3D::FORMAT::BREP, "brep" },
{ JOB_EXPORT_PCB_3D::FORMAT::GLB, "step" },
{ JOB_EXPORT_PCB_3D::FORMAT::VRML, "vrml" },
{ JOB_EXPORT_PCB_3D::FORMAT::XAO, "xao" },
{ JOB_EXPORT_PCB_3D::FORMAT::PLY, "ply" },
{ JOB_EXPORT_PCB_3D::FORMAT::STL, "stl" },
{ JOB_EXPORT_PCB_3D::FORMAT::STEP, "step" },
{ JOB_EXPORT_PCB_3D::FORMAT::BREP, "brep" },
{ JOB_EXPORT_PCB_3D::FORMAT::GLB, "step" },
{ JOB_EXPORT_PCB_3D::FORMAT::VRML, "vrml" },
{ JOB_EXPORT_PCB_3D::FORMAT::XAO, "xao" },
{ JOB_EXPORT_PCB_3D::FORMAT::PLY, "ply" },
{ JOB_EXPORT_PCB_3D::FORMAT::STL, "stl" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_3D::VRML_UNITS,
{
{ JOB_EXPORT_PCB_3D::VRML_UNITS::INCH, "in" },
{ JOB_EXPORT_PCB_3D::VRML_UNITS::INCHES, "in" },
{ JOB_EXPORT_PCB_3D::VRML_UNITS::METERS, "m" },
{ JOB_EXPORT_PCB_3D::VRML_UNITS::MM, "mm" },
{ JOB_EXPORT_PCB_3D::VRML_UNITS::MILLIMETERS, "mm" },
{ JOB_EXPORT_PCB_3D::VRML_UNITS::TENTHS, "tenths" },
} )
@@ -74,13 +74,13 @@ wxString EXPORTER_STEP_PARAMS::GetFormatName() const
JOB_EXPORT_PCB_3D::JOB_EXPORT_PCB_3D() :
JOB( "3d", false ),
m_hasUserOrigin( false ),
m_filename(),
m_format( JOB_EXPORT_PCB_3D::FORMAT::UNKNOWN ),
m_vrmlUnits( JOB_EXPORT_PCB_3D::VRML_UNITS::METERS ),
m_vrmlModelDir( wxEmptyString ),
m_vrmlRelativePaths( false )
JOB( "3d", false ),
m_hasUserOrigin( false ),
m_filename(),
m_format( JOB_EXPORT_PCB_3D::FORMAT::UNKNOWN ),
m_vrmlUnits( JOB_EXPORT_PCB_3D::VRML_UNITS::METERS ),
m_vrmlModelDir( wxEmptyString ),
m_vrmlRelativePaths( false )
{
m_params.emplace_back(
new JOB_PARAM<bool>( "overwrite", &m_3dparams.m_Overwrite, m_3dparams.m_Overwrite ) );
@@ -154,15 +154,14 @@ wxString JOB_EXPORT_PCB_3D::GetSettingsDialogTitle() const
void JOB_EXPORT_PCB_3D::SetStepFormat( EXPORTER_STEP_PARAMS::FORMAT aFormat )
{
m_3dparams.m_Format = aFormat;
switch( m_3dparams.m_Format )
{
case EXPORTER_STEP_PARAMS::FORMAT::STEP: m_format = JOB_EXPORT_PCB_3D::FORMAT::STEP; break;
case EXPORTER_STEP_PARAMS::FORMAT::GLB: m_format = JOB_EXPORT_PCB_3D::FORMAT::GLB; break;
case EXPORTER_STEP_PARAMS::FORMAT::XAO: m_format = JOB_EXPORT_PCB_3D::FORMAT::XAO; break;
case EXPORTER_STEP_PARAMS::FORMAT::GLB: m_format = JOB_EXPORT_PCB_3D::FORMAT::GLB; break;
case EXPORTER_STEP_PARAMS::FORMAT::XAO: m_format = JOB_EXPORT_PCB_3D::FORMAT::XAO; break;
case EXPORTER_STEP_PARAMS::FORMAT::BREP: m_format = JOB_EXPORT_PCB_3D::FORMAT::BREP; break;
case EXPORTER_STEP_PARAMS::FORMAT::PLY: m_format = JOB_EXPORT_PCB_3D::FORMAT::PLY; break;
case EXPORTER_STEP_PARAMS::FORMAT::STL: m_format = JOB_EXPORT_PCB_3D::FORMAT::STL; break;
case EXPORTER_STEP_PARAMS::FORMAT::PLY: m_format = JOB_EXPORT_PCB_3D::FORMAT::PLY; break;
case EXPORTER_STEP_PARAMS::FORMAT::STL: m_format = JOB_EXPORT_PCB_3D::FORMAT::STL; break;
}
}
+6 -7
View File
@@ -125,24 +125,23 @@ public:
enum class VRML_UNITS
{
INCH, // Do not use IN: it conflicts with a Windows header
MM,
INCHES,
MILLIMETERS,
METERS,
TENTHS // inches
};
public:
bool m_hasUserOrigin;
wxString m_filename;
JOB_EXPORT_PCB_3D::FORMAT m_format;
/// Despite the name; also used for other formats
EXPORTER_STEP_PARAMS m_3dparams;
EXPORTER_STEP_PARAMS m_3dparams;
VRML_UNITS m_vrmlUnits;
wxString m_vrmlModelDir;
bool m_vrmlRelativePaths;
VRML_UNITS m_vrmlUnits;
wxString m_vrmlModelDir;
bool m_vrmlRelativePaths;
};
#endif
+16 -16
View File
@@ -36,8 +36,8 @@ NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN,
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_DRILL::DRILL_UNITS,
{
{ JOB_EXPORT_PCB_DRILL::DRILL_UNITS::INCH, "in" },
{ JOB_EXPORT_PCB_DRILL::DRILL_UNITS::MM, "mm" },
{ JOB_EXPORT_PCB_DRILL::DRILL_UNITS::INCHES, "in" },
{ JOB_EXPORT_PCB_DRILL::DRILL_UNITS::MILLIMETERS, "mm" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT,
@@ -58,19 +58,19 @@ NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_DRILL::MAP_FORMAT,
} )
JOB_EXPORT_PCB_DRILL::JOB_EXPORT_PCB_DRILL() :
JOB( "drill", true ),
m_filename(),
m_excellonMirrorY( false ),
m_excellonMinimalHeader( false ),
m_excellonCombinePTHNPTH( true ),
m_excellonOvalDrillRoute( false ),
m_format( DRILL_FORMAT::EXCELLON ),
m_drillOrigin( DRILL_ORIGIN::ABS ),
m_drillUnits( DRILL_UNITS::INCH ),
m_zeroFormat( ZEROS_FORMAT::DECIMAL ),
m_mapFormat( MAP_FORMAT::PDF ),
m_gerberPrecision( 5 ),
m_generateMap( false )
JOB( "drill", true ),
m_filename(),
m_excellonMirrorY( false ),
m_excellonMinimalHeader( false ),
m_excellonCombinePTHNPTH( true ),
m_excellonOvalDrillRoute( false ),
m_format( DRILL_FORMAT::EXCELLON ),
m_drillOrigin( DRILL_ORIGIN::ABS ),
m_drillUnits( DRILL_UNITS::INCHES ),
m_zeroFormat( ZEROS_FORMAT::DECIMAL ),
m_mapFormat( MAP_FORMAT::PDF ),
m_gerberPrecision( 5 ),
m_generateMap( false )
{
m_params.emplace_back( new JOB_PARAM<bool>( "excellon.mirror_y",
&m_excellonMirrorY,
@@ -129,5 +129,5 @@ wxString JOB_EXPORT_PCB_DRILL::GetSettingsDialogTitle() const
return _( "Export Drill Data Job Settings" );
}
REGISTER_JOB( pcb_export_drill, _HKI( "PCB: Export Drill Data" ), KIWAY::FACE_PCB,
REGISTER_JOB( pcb_export_drill, _HKI( "PCB: Export drill data" ), KIWAY::FACE_PCB,
JOB_EXPORT_PCB_DRILL );

Some files were not shown because too many files have changed in this diff Show More