Compare commits

..

1 Commits

Author SHA1 Message Date
eurofun1
266e5cbbd5 Merge branch 'pns-drag-rot' into 'master'
PNS: rotation during component dragging

Closes #9672

See merge request kicad/code/kicad!2270
2025-09-03 12:01:35 +00:00
721 changed files with 217002 additions and 285761 deletions

View File

@ -8,7 +8,6 @@ win64_build:
interruptible: false
image: registry.gitlab.com/kicad/kicad-ci/windows-build-image/ltsc2022-msvc:latest
variables:
VCPKG_BINARY_SOURCES: 'nuget,gitlab,readwrite'
# Switch the compressor to fastzip and reduce the compression level
FF_USE_FASTZIP: "true"
CACHE_COMPRESSION_LEVEL: "fast"
@ -24,7 +23,6 @@ win64_build:
script:
- C:\builder\build.ps1 -Env -Arch x64
- $vcpkgCache=Join-Path -Path (Get-Location) -ChildPath ".vcpkgCache";$env:VCPKG_DEFAULT_BINARY_CACHE=$vcpkgCache;New-Item -ItemType Directory -Force -Path $vcpkgCache
- nuget.exe sources add -Name gitlab -Source "https://gitlab.com/api/v4/projects/27426693/packages/nuget/index.json" -UserName gitlab-ci-token -Password $env:CI_JOB_TOKEN
- mkdir -p build/windows -Force
- cd build/windows
- cmake `
@ -36,11 +34,11 @@ win64_build:
-DKICAD_BUILD_PNS_DEBUG_TOOL=ON `
-DKICAD_USE_3DCONNEXION=ON `
-DVCPKG_BUILD_TYPE=debug `
-DVCPKG_INSTALL_OPTIONS="--x-abi-tools-use-exact-versions" `
-DVCPKG_OVERLAY_TRIPLETS="$Env:CI_PROJECT_DIR/tools/custom_vcpkg_triplets" `
../../
- cmake --build . 2>&1 | tee compilation_log.txt
- cd ../../
after_script:
- Get-Content -Path C:\builder\vcpkg\buildtrees\wxpython-33\python3-tool-post-install-err.log
artifacts:
# Only save the artifacts that are needed for running the tests in the next stage
# and the compilation log. The entire build directory is too large to save as an

View File

@ -368,12 +368,11 @@ private:
void createTrackWithMargin( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayer, int aMargin = 0 );
// Generate the pad shape on board layers. The pad hole is not generated by createPadWithMargin
void createPadWithMargin( const PAD *aPad, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayer, const VECTOR2I& aMargin ) const;
// Generate the hole shape of aPad, stored in aDstContainer
void createPadHoleShape( const PAD* aPad, CONTAINER_2D_BASE* aDstContainer, int aInflateValue );
void createPadWithHole( const PAD* aPad, CONTAINER_2D_BASE* aDstContainer,
int aInflateValue );
void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId );

View File

@ -474,12 +474,12 @@ void BOARD_ADAPTER::createPadWithMargin( const PAD* aPad, CONTAINER_2D_BASE* aCo
}
void BOARD_ADAPTER::createPadHoleShape( const PAD* aPad, CONTAINER_2D_BASE* aDstContainer,
int aInflateValue )
void BOARD_ADAPTER::createPadWithHole( const PAD* aPad, CONTAINER_2D_BASE* aDstContainer,
int aInflateValue )
{
if( !aPad->HasHole() )
{
wxLogTrace( m_logTrace, wxT( "BOARD_ADAPTER::createPadHole pad has no hole" ) );
wxLogTrace( m_logTrace, wxT( "BOARD_ADAPTER::createPadWithHole - found an invalid pad" ) );
return;
}

View File

@ -507,32 +507,27 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
{
for( PAD* pad : footprint->Pads() )
{
// Note: holes of NPTH are already built by GetBoardPolygonOutlines
if( !pad->HasHole() )
const VECTOR2I padHole = pad->GetDrillSize();
if( !padHole.x ) // Not drilled pad like SMD pad
continue;
// The hole in the body is inflated by copper thickness, if not plated, no copper
int inflate = 0;
if( pad->GetAttribute() != PAD_ATTRIB::NPTH )
inflate = KiROUND( GetHolePlatingThickness() / 2.0 );
m_holeCount++;
double holeDiameter = ( pad->GetDrillSize().x + pad->GetDrillSize().y ) / 2.0;
m_averageHoleDiameter += static_cast<float>( holeDiameter * m_biuTo3Dunits );
if( pad->GetAttribute() == PAD_ATTRIB::NPTH )
{
// Ensure the silk drawings are clipped to the NPTH hole, like other pad/via holes
// even if the clip to board body is not activated (remember NPTH holes are part of
// the board body)
createPadHoleShape( pad, &m_TH_ODs, 0 );
continue;
}
// The hole in the body is inflated by copper thickness
int inflate = KiROUND( GetHolePlatingThickness() / 2.0 );
createPadHoleShape( pad, &m_TH_ODs, inflate );
createPadWithHole( pad, &m_TH_ODs, inflate );
if( cfg.clip_silk_on_via_annuli )
createPadHoleShape( pad, &m_viaAnnuli, inflate );
createPadWithHole( pad, &m_viaAnnuli, inflate );
createPadHoleShape( pad, &m_TH_IDs, 0 );
createPadWithHole( pad, &m_TH_IDs, 0 );
}
}
@ -544,7 +539,9 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
{
for( PAD* pad : footprint->Pads() )
{
if( !pad->HasHole() )
const VECTOR2I padHole = pad->GetDrillSize();
if( !padHole.x ) // Not drilled pad like SMD pad
continue;
// The hole in the body is inflated by copper thickness.

View File

@ -35,22 +35,14 @@
#include <advanced_config.h>
#include <build_version.h>
#include <board.h>
#include <pad.h>
#include <pcb_field.h>
#include <reporter.h>
#include <gal/opengl/gl_context_mgr.h>
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
#include <bitmaps.h>
#include <kiway_holder.h>
#include <kiway.h>
#include <macros.h>
#include <pgm_base.h>
#include <settings/settings_manager.h>
#include <tool/tool_dispatcher.h>
#include <string_utils.h>
#include <mail_type.h>
#include <kiway_express.h>
#include <fmt/format.h>
#include <widgets/wx_busy_indicator.h>
@ -100,12 +92,28 @@ END_EVENT_TABLE()
EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttribs,
BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera,
S3D_CACHE* a3DCachePointer ) :
HIDPI_GL_3D_CANVAS( EDA_DRAW_PANEL_GAL::GetVcSettings(), aCamera, aParent, aGLAttribs,
EDA_3D_CANVAS_ID, wxDefaultPosition,
wxDefaultSize, wxFULL_REPAINT_ON_RESIZE ),
m_editing_timeout_timer( this, wxID_HIGHEST + 1 ),
m_redraw_trigger_timer( this, wxID_HIGHEST + 2 ),
m_boardAdapter( aBoardAdapter )
HIDPI_GL_3D_CANVAS( EDA_DRAW_PANEL_GAL::GetVcSettings(), aCamera, aParent, aGLAttribs,
EDA_3D_CANVAS_ID, wxDefaultPosition,
wxDefaultSize, wxFULL_REPAINT_ON_RESIZE ),
m_eventDispatcher( nullptr ),
m_parentStatusBar( nullptr ),
m_parentInfoBar( nullptr ),
m_glRC( nullptr ),
m_is_opengl_initialized( false ),
m_is_opengl_version_supported( true ),
m_editing_timeout_timer( this, wxID_HIGHEST + 1 ),
m_redraw_trigger_timer( this, wxID_HIGHEST + 2 ),
m_render_pivot( false ),
m_camera_moving_speed( 1.0f ),
m_strtime_camera_movement( 0 ),
m_animation_enabled( true ),
m_moving_speed_multiplier( 3 ),
m_boardAdapter( aBoardAdapter ),
m_3d_render( nullptr ),
m_opengl_supports_raytracing( true ),
m_render_raytracing_was_requested( false ),
m_accelerator3DShapes( nullptr ),
m_currentRollOverItem( nullptr )
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::EDA_3D_CANVAS" ) );
@ -473,10 +481,8 @@ void EDA_3D_CANVAS::DoRePaint()
if( m_camera_is_moving )
{
const int64_t curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
// Convert microseconds to seconds as float and apply speed multiplier
curtime_delta_s = static_cast<float>( static_cast<double>( curtime_delta ) / 1e6 )
* m_camera_moving_speed;
const int64_t curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
curtime_delta_s = ( curtime_delta / 1e6 ) * m_camera_moving_speed;
m_camera.Interpolate( curtime_delta_s );
if( curtime_delta_s > 1.0f )
@ -745,8 +751,7 @@ void EDA_3D_CANVAS::RenderToFrameBuffer( unsigned char* buffer, int width, int h
if( m_camera_is_moving )
{
const int64_t curtime_delta = GetRunningMicroSecs() - m_strtime_camera_movement;
curtime_delta_s = static_cast<float>( static_cast<double>( curtime_delta ) / 1e6 )
* m_camera_moving_speed;
curtime_delta_s = ( curtime_delta / 1e6 ) * m_camera_moving_speed;
m_camera.Interpolate( curtime_delta_s );
if( curtime_delta_s > 1.0f )
@ -882,7 +887,7 @@ void EDA_3D_CANVAS::OnZoomGesture( wxZoomGestureEvent& aEvent )
m_camera.Pan( aEvent.GetPosition() );
m_camera.SetCurMousePosition( aEvent.GetPosition() );
m_camera.Zoom( static_cast<float>( aEvent.GetZoomFactor() / m_gestureLastZoomFactor ) );
m_camera.Zoom( aEvent.GetZoomFactor() / m_gestureLastZoomFactor );
m_gestureLastZoomFactor = aEvent.GetZoomFactor();
@ -925,7 +930,7 @@ void EDA_3D_CANVAS::OnRotateGesture( wxRotateGestureEvent& aEvent )
if( m_camera_is_moving )
return;
m_camera.RotateScreen( static_cast<float>( m_gestureLastAngle - aEvent.GetRotationAngle() ) );
m_camera.RotateScreen( m_gestureLastAngle - aEvent.GetRotationAngle() );
m_gestureLastAngle = aEvent.GetRotationAngle();
DisplayStatus();
@ -1061,45 +1066,9 @@ void EDA_3D_CANVAS::OnLeftDown( wxMouseEvent& event )
{
RAY mouseRay = getRayAtCurrentMousePosition();
BOARD_ITEM* intersectedBoardItem = m_3d_render_raytracing->IntersectBoardItem( mouseRay );
BOARD_ITEM *intersectedBoardItem = m_3d_render_raytracing->IntersectBoardItem( mouseRay );
if( intersectedBoardItem )
{
FOOTPRINT* footprint = nullptr;
switch( intersectedBoardItem->Type() )
{
case PCB_FOOTPRINT_T:
footprint = static_cast<FOOTPRINT*>( intersectedBoardItem );
break;
case PCB_PAD_T:
footprint = static_cast<PAD*>( intersectedBoardItem )->GetParentFootprint();
break;
case PCB_FIELD_T:
footprint = static_cast<PCB_FIELD*>( intersectedBoardItem )->GetParentFootprint();
break;
default:
break;
}
if( footprint )
{
std::string command =
fmt::format( "$SELECT: 0,F{}",
EscapeString( footprint->GetReference(), CTX_IPC ).ToStdString() );
EDA_3D_VIEWER_FRAME* frame = static_cast<EDA_3D_VIEWER_FRAME*>( GetParent() );
if( frame )
{
frame->Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_SELECTION, command, frame );
frame->Kiway().ExpressMail( FRAME_SCH, MAIL_SELECTION, command, frame );
}
}
}
// !TODO: send a selection item to pcbnew, eg: via kiway?
}
}
@ -1119,14 +1088,14 @@ void EDA_3D_CANVAS::OnLeftUp( wxMouseEvent& event )
int logicalW = logicalSize.GetWidth();
int logicalH = logicalSize.GetHeight();
int gizmo_x = 0, gizmo_y = 0, gizmo_width = 0, gizmo_height = 0;
int gizmo_x, gizmo_y, gizmo_width, gizmo_height;
std::tie( gizmo_x, gizmo_y, gizmo_width, gizmo_height ) = m_3d_render_opengl->getGizmoViewport();
float scaleX = static_cast<float>( static_cast<double>( gizmo_width ) / static_cast<double>( logicalW ) );
float scaleY = static_cast<float>( static_cast<double>( gizmo_height ) / static_cast<double>( logicalH ) );
float scaleX = static_cast<float>( gizmo_width ) / logicalW;
float scaleY = static_cast<float>( gizmo_height ) / logicalH;
int scaledMouseX = static_cast<int>( static_cast<float>( event.GetX() ) * scaleX );
int scaledMouseY = static_cast<int>( static_cast<float>( logicalH - event.GetY() ) * scaleY );
int scaledMouseX = static_cast<int>( event.GetX() * scaleX );
int scaledMouseY = static_cast<int>( ( logicalH - event.GetY() ) * scaleY );
m_3d_render_opengl->handleGizmoMouseInput( scaledMouseX, scaledMouseY );
Refresh();
@ -1260,7 +1229,7 @@ void EDA_3D_CANVAS::request_start_moving_camera( float aMovingSpeed, bool aRende
// Map speed multiplier option to actual multiplier value
// [1,2,3,4,5] -> [0.25, 0.5, 1, 2, 4]
aMovingSpeed *= static_cast<float>( ( 1 << m_moving_speed_multiplier ) ) / 8.0f;
aMovingSpeed *= ( 1 << m_moving_speed_multiplier ) / 8.0f;
m_render_pivot = aRenderPivot;
m_camera_moving_speed = aMovingSpeed;
@ -1280,7 +1249,7 @@ void EDA_3D_CANVAS::move_pivot_based_on_cur_mouse_position()
{
RAY mouseRay = getRayAtCurrentMousePosition();
float hit_t = 0.0f;
float hit_t;
// Test it with the board bounding box
if( m_boardAdapter.GetBBox().Intersect( mouseRay, &hit_t ) )

View File

@ -42,7 +42,7 @@ class RENDER_3D_RAYTRACE_GL;
class RENDER_3D_OPENGL;
#define EDA_3D_CANVAS_ID (wxID_HIGHEST + 1321)
#define EDA_3D_CANVAS_ID wxID_HIGHEST + 1321
/**
* Implement a canvas based on a wxGLCanvas
@ -61,7 +61,7 @@ public:
EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttribs, BOARD_ADAPTER& aSettings,
CAMERA& aCamera, S3D_CACHE* a3DCachePointer );
~EDA_3D_CANVAS() override;
~EDA_3D_CANVAS();
/**
* Set a dispatcher that processes events and forwards them to tools.
@ -302,36 +302,36 @@ private:
RAY getRayAtCurrentMousePosition();
private:
TOOL_DISPATCHER* m_eventDispatcher = nullptr;
wxStatusBar* m_parentStatusBar = nullptr; // Parent statusbar to report progress
WX_INFOBAR* m_parentInfoBar = nullptr;
TOOL_DISPATCHER* m_eventDispatcher;
wxStatusBar* m_parentStatusBar; // Parent statusbar to report progress
WX_INFOBAR* m_parentInfoBar;
wxGLContext* m_glRC = nullptr; // Current OpenGL context
bool m_is_opengl_initialized = false;
bool m_is_opengl_version_supported = true;
wxGLContext* m_glRC; // Current OpenGL context
bool m_is_opengl_initialized;
bool m_is_opengl_version_supported;
wxTimer m_editing_timeout_timer; // Expires after some time signaling that
// the mouse / keyboard movements are over
wxTimer m_redraw_trigger_timer; // Used to schedule a redraw event
std::atomic_flag m_is_currently_painting = ATOMIC_FLAG_INIT; // Avoid drawing twice at the same time
std::atomic_flag m_is_currently_painting; // Avoid drawing twice at the same time
bool m_render_pivot = false; // Render the pivot while camera moving
float m_camera_moving_speed = 1.0f; // 1.0f will be 1:1
int64_t m_strtime_camera_movement = 0; // Ticktime of camera movement start
bool m_animation_enabled = true; // Camera animation enabled
int m_moving_speed_multiplier = 3; // Camera animation speed multiplier option
bool m_render_pivot; // Render the pivot while camera moving
float m_camera_moving_speed; // 1.0f will be 1:1
int64_t m_strtime_camera_movement; // Ticktime of camera movement start
bool m_animation_enabled; // Camera animation enabled
int m_moving_speed_multiplier; // Camera animation speed multiplier option
BOARD_ADAPTER& m_boardAdapter; // Pre-computed 3D info and settings
RENDER_3D_BASE* m_3d_render = nullptr;
RENDER_3D_BASE* m_3d_render;
RENDER_3D_RAYTRACE_GL* m_3d_render_raytracing;
RENDER_3D_OPENGL* m_3d_render_opengl;
bool m_opengl_supports_raytracing = true;
bool m_render_raytracing_was_requested = false;
bool m_opengl_supports_raytracing;
bool m_render_raytracing_was_requested;
ACCELERATOR_3D* m_accelerator3DShapes = nullptr; // used for mouse over searching
ACCELERATOR_3D* m_accelerator3DShapes; // used for mouse over searching
BOARD_ITEM* m_currentRollOverItem = nullptr;
BOARD_ITEM* m_currentRollOverItem;
bool m_render3dmousePivot = false; // Render the 3dmouse pivot
SFVEC3F m_3dmousePivotPos; // The position of the 3dmouse pivot

View File

@ -26,7 +26,6 @@
#include "render_3d_opengl.h"
#include <board.h>
#include <footprint.h>
#include <pcb_track.h>
#include "../../3d_math.h"
#include "convert_basic_shapes_to_polygon.h"
#include <lset.h>
@ -727,54 +726,6 @@ void RENDER_3D_OPENGL::generateCylinder( const SFVEC2F& aCenter, float aInnerRad
}
void RENDER_3D_OPENGL::generateDisk( const SFVEC2F& aCenter, float aRadius, float aZ,
unsigned int aNr_sides_per_circle, TRIANGLE_DISPLAY_LIST* aDstLayer,
bool aTop )
{
const float delta = 2.0f * glm::pi<float>() / (float) aNr_sides_per_circle;
for( unsigned int i = 0; i < aNr_sides_per_circle; ++i )
{
float a0 = delta * i;
float a1 = delta * ( i + 1 );
const SFVEC3F p0( aCenter.x + cosf( a0 ) * aRadius,
aCenter.y + sinf( a0 ) * aRadius, aZ );
const SFVEC3F p1( aCenter.x + cosf( a1 ) * aRadius,
aCenter.y + sinf( a1 ) * aRadius, aZ );
const SFVEC3F c( aCenter.x, aCenter.y, aZ );
if( aTop )
aDstLayer->m_layer_top_triangles->AddTriangle( p1, p0, c );
else
aDstLayer->m_layer_bot_triangles->AddTriangle( p0, p1, c );
}
}
void RENDER_3D_OPENGL::generateDimple( const SFVEC2F& aCenter, float aRadius, float aZ,
float aDepth, unsigned int aNr_sides_per_circle,
TRIANGLE_DISPLAY_LIST* aDstLayer, bool aTop )
{
const float delta = 2.0f * glm::pi<float>() / (float) aNr_sides_per_circle;
const SFVEC3F c( aCenter.x, aCenter.y, aTop ? aZ - aDepth : aZ + aDepth );
for( unsigned int i = 0; i < aNr_sides_per_circle; ++i )
{
float a0 = delta * i;
float a1 = delta * ( i + 1 );
const SFVEC3F p0( aCenter.x + cosf( a0 ) * aRadius,
aCenter.y + sinf( a0 ) * aRadius, aZ );
const SFVEC3F p1( aCenter.x + cosf( a1 ) * aRadius,
aCenter.y + sinf( a1 ) * aRadius, aZ );
if( aTop )
aDstLayer->m_layer_top_triangles->AddTriangle( p0, p1, c );
else
aDstLayer->m_layer_bot_triangles->AddTriangle( p1, p0, c );
}
}
void RENDER_3D_OPENGL::generateViasAndPads()
{
if( !m_boardAdapter.GetBoard() )
@ -868,7 +819,10 @@ void RENDER_3D_OPENGL::generateViasAndPads()
{
if( pad->GetAttribute() != PAD_ATTRIB::NPTH )
{
if( !pad->HasHole() )
const VECTOR2I drillsize = pad->GetDrillSize();
const bool hasHole = drillsize.x && drillsize.y;
if( !hasHole )
continue;
pad->TransformHoleToPolygon( tht_outer_holes_poly, platingThickness,
@ -931,63 +885,6 @@ void RENDER_3D_OPENGL::generateViasAndPads()
delete layerTriangles;
}
}
TRIANGLE_DISPLAY_LIST* frontCover = new TRIANGLE_DISPLAY_LIST( m_boardAdapter.GetViaCount() );
TRIANGLE_DISPLAY_LIST* backCover = new TRIANGLE_DISPLAY_LIST( m_boardAdapter.GetViaCount() );
for( const PCB_TRACK* track : m_boardAdapter.GetBoard()->Tracks() )
{
if( track->Type() != PCB_VIA_T )
continue;
const PCB_VIA* via = static_cast<const PCB_VIA*>( track );
const float holediameter = via->GetDrillValue() * m_boardAdapter.BiuTo3dUnits();
const float hole_radius = holediameter / 2.0f + 2.0 * platingThickness3d;
const SFVEC2F center( via->GetStart().x * m_boardAdapter.BiuTo3dUnits(),
-via->GetStart().y * m_boardAdapter.BiuTo3dUnits() );
unsigned int seg = m_boardAdapter.GetCircleSegmentCount( via->GetDrillValue() );
PCB_LAYER_ID top_layer, bottom_layer;
via->LayerPair( &top_layer, &bottom_layer );
float ztop, zbot, dummy;
getLayerZPos( top_layer, ztop, dummy );
getLayerZPos( bottom_layer, dummy, zbot );
bool frontCovering = via->GetFrontCoveringMode() == COVERING_MODE::COVERED || via->IsTented( F_Mask );
bool backCovering = via->GetBackCoveringMode() == COVERING_MODE::COVERED || via->IsTented( B_Mask );
bool frontPlugged = via->GetFrontPluggingMode() == PLUGGING_MODE::PLUGGED;
bool backPlugged = via->GetBackPluggingMode() == PLUGGING_MODE::PLUGGED;
bool filled = via->GetFillingMode() == FILLING_MODE::FILLED
|| via->GetCappingMode() == CAPPING_MODE::CAPPED;
const float depth = hole_radius * 0.3f;
if( frontCovering )
{
if( filled || !frontPlugged )
generateDisk( center, hole_radius, ztop, seg, frontCover, true );
else
generateDimple( center, hole_radius, ztop, depth, seg, frontCover, true );
}
if( backCovering )
{
if( filled || !backPlugged )
generateDisk( center, hole_radius, zbot, seg, backCover, false );
else
generateDimple( center, hole_radius, zbot, depth, seg, backCover, false );
}
}
if( frontCover->m_layer_top_triangles->GetVertexSize() > 0 )
m_viaFrontCover = new OPENGL_RENDER_LIST( *frontCover, 0, 0.0f, 0.0f );
if( backCover->m_layer_bot_triangles->GetVertexSize() > 0 )
m_viaBackCover = new OPENGL_RENDER_LIST( *backCover, 0, 0.0f, 0.0f );
delete frontCover;
delete backCover;
}

View File

@ -72,8 +72,6 @@ RENDER_3D_OPENGL::RENDER_3D_OPENGL( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdap
m_outerViaThroughHoles = nullptr;
m_microviaHoles = nullptr;
m_padHoles = nullptr;
m_viaFrontCover = nullptr;
m_viaBackCover = nullptr;
m_circleTexture = 0;
m_grid = 0;
@ -949,8 +947,6 @@ void RENDER_3D_OPENGL::freeAllLists()
DELETE_AND_FREE( m_microviaHoles )
DELETE_AND_FREE( m_padHoles )
DELETE_AND_FREE( m_viaFrontCover )
DELETE_AND_FREE( m_viaBackCover )
}
@ -972,17 +968,6 @@ void RENDER_3D_OPENGL::renderSolderMaskLayer( PCB_LAYER_ID aLayerID, float aZPos
setLayerMaterial( aLayerID );
m_board->SetItIsTransparent( true );
m_board->DrawCulled( aShowThickness, solder_mask, via_holes );
if( aLayerID == F_Mask && m_viaFrontCover )
{
m_viaFrontCover->ApplyScalePosition( aZPos, 4 * m_boardAdapter.GetNonCopperLayerThickness() );
m_viaFrontCover->DrawTop();
}
else if( aLayerID == B_Mask && m_viaBackCover )
{
m_viaBackCover->ApplyScalePosition( aZPos, 4 * m_boardAdapter.GetNonCopperLayerThickness() );
m_viaBackCover->DrawBot();
}
}
}

View File

@ -123,14 +123,6 @@ private:
float aZtop, float aZbot, unsigned int aNr_sides_per_circle,
TRIANGLE_DISPLAY_LIST* aDstLayer );
void generateDisk( const SFVEC2F& aCenter, float aRadius, float aZ,
unsigned int aNr_sides_per_circle, TRIANGLE_DISPLAY_LIST* aDstLayer,
bool aTop );
void generateDimple( const SFVEC2F& aCenter, float aRadius, float aZ, float aDepth,
unsigned int aNr_sides_per_circle, TRIANGLE_DISPLAY_LIST* aDstLayer,
bool aTop );
void generateViasAndPads();
/**
@ -244,8 +236,6 @@ private:
OPENGL_RENDER_LIST* m_microviaHoles;
OPENGL_RENDER_LIST* m_padHoles;
OPENGL_RENDER_LIST* m_viaFrontCover;
OPENGL_RENDER_LIST* m_viaBackCover;
// Caches
std::map<wxString, MODEL_3D*> m_3dModelMap;

View File

@ -277,7 +277,7 @@ void RENDER_3D_RAYTRACE_BASE::renderTracing( uint8_t* ptrPBO, REPORTER* aStatusR
BS::multi_future<void> futures;
for( size_t i = 0; i < tp.get_thread_count(); ++i )
futures.push_back( tp.submit_task( processBlocks ) );
futures.push_back( tp.submit( processBlocks ) );
futures.wait();
@ -486,12 +486,9 @@ void RENDER_3D_RAYTRACE_BASE::renderBlockTracing( uint8_t* ptrPBO, signed int iB
// Initialize ray packets
const SFVEC2UI& blockPos = m_blockPositions[iBlock];
const SFVEC2I blockPosI = SFVEC2I( blockPos.x + m_xoffset, blockPos.y + m_yoffset );
const SFVEC2F randDisp = ( m_camera.GetProjection() == PROJECTION_TYPE::ORTHO ) ?
SFVEC2F( 0.0f, 0.0f ) :
SFVEC2F( DISP_FACTOR, DISP_FACTOR );
RAYPACKET blockPacket( m_camera, (SFVEC2F) blockPosI + randDisp,
randDisp /* Displacement random factor */ );
RAYPACKET blockPacket( m_camera, (SFVEC2F) blockPosI + SFVEC2F( DISP_FACTOR, DISP_FACTOR ),
SFVEC2F( DISP_FACTOR, DISP_FACTOR ) /* Displacement random factor */ );
HITINFO_PACKET hitPacket_X0Y0[RAYPACKET_RAYS_PER_PACKET];
@ -569,7 +566,7 @@ void RENDER_3D_RAYTRACE_BASE::renderBlockTracing( uint8_t* ptrPBO, signed int iB
HITINFO_PACKET_init( hitPacket_AA_X1Y1 );
RAYPACKET blockPacket_AA_X1Y1( m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f, 0.5f ),
randDisp );
SFVEC2F( DISP_FACTOR, DISP_FACTOR ) );
if( !m_accelerator->Intersect( blockPacket_AA_X1Y1, hitPacket_AA_X1Y1 ) )
{
@ -606,16 +603,16 @@ void RENDER_3D_RAYTRACE_BASE::renderBlockTracing( uint8_t* ptrPBO, signed int iB
RAY blockRayPck_AA_X1Y1_half[RAYPACKET_RAYS_PER_PACKET];
RAYPACKET_InitRays_with2DDisplacement(
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f - randDisp.x, randDisp.y ),
randDisp, blockRayPck_AA_X1Y0 );
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f - DISP_FACTOR, DISP_FACTOR ),
SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y0 );
RAYPACKET_InitRays_with2DDisplacement(
m_camera, (SFVEC2F) blockPosI + SFVEC2F( randDisp.x, 0.5f - randDisp.y ),
randDisp, blockRayPck_AA_X0Y1 );
m_camera, (SFVEC2F) blockPosI + SFVEC2F( DISP_FACTOR, 0.5f - DISP_FACTOR ),
SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X0Y1 );
RAYPACKET_InitRays_with2DDisplacement(
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.25f - randDisp.x, 0.25f - randDisp.y ),
randDisp, blockRayPck_AA_X1Y1_half );
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.25f - DISP_FACTOR, 0.25f - DISP_FACTOR ),
SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y1_half );
renderAntiAliasPackets( bgColor, hitPacket_X0Y0, hitPacket_AA_X1Y1, blockRayPck_AA_X1Y0,
hitColor_AA_X1Y0 );

View File

@ -6,12 +6,7 @@
},
{
"environment": "vcpkg",
"VcPkgDir": "D:/vcpkg/",
"VCPKG_BINARY_SOURCES": "nuget,kicad-gitlab,read"
},
{
"environment": "swig",
"SwigExePath": "D:/swigwin-4.1.1/swig.exe"
"VcPkgDir": "D:/vcpkg/"
}
],
"configurations": [
@ -19,7 +14,7 @@
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64", "vcpkg", "swig"],
"inheritEnvironments": [ "msvc_x64_x64", "vcpkg" ],
"buildRoot": "${env.BuildDir}\\${name}",
"installRoot": "${env.InstallDir}\\${name}",
"cmakeCommandArgs": "",
@ -35,21 +30,6 @@
"name": "KICAD_WIN32_DPI_AWARE",
"value": "ON",
"type": "BOOL"
},
{
"name": "SWIG_EXECUTABLE",
"value": "${env.SwigExePath}",
"type": "STRING"
},
{
"name": "VCPKG_OVERLAY_TRIPLETS",
"value": "${workspaceRoot}/tools/custom_vcpkg_triplets",
"type": "STRING"
},
{
"name": "VCPKG_INSTALL_OPTIONS",
"value": "--x-abi-tools-use-exact-versions",
"type": "STRING"
}
],
"cmakeToolchain": "${env.VcPkgDir}/scripts/buildsystems/vcpkg.cmake"
@ -58,7 +38,7 @@
"name": "x64-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"inheritEnvironments": [ "msvc_x64_x64", "vcpkg", "swig"],
"inheritEnvironments": [ "msvc_x64_x64", "vcpkg" ],
"buildRoot": "${env.BuildDir}\\${name}",
"installRoot": "${env.InstallDir}\\${name}",
"cmakeCommandArgs": "",
@ -74,21 +54,6 @@
"name": "KICAD_WIN32_DPI_AWARE",
"value": "ON",
"type": "BOOL"
},
{
"name": "SWIG_EXECUTABLE",
"value": "${env.SwigExePath}",
"type": "STRING"
},
{
"name": "VCPKG_OVERLAY_TRIPLETS",
"value": "${workspaceRoot}/tools/custom_vcpkg_triplets",
"type": "STRING"
},
{
"name": "VCPKG_INSTALL_OPTIONS",
"value": "--x-abi-tools-use-exact-versions",
"type": "STRING"
}
],
"cmakeToolchain": "${env.VcPkgDir}/scripts/buildsystems/vcpkg.cmake"

View File

@ -130,9 +130,6 @@ set( KICOMMON_SRCS
project/project_local_settings.cpp
project/time_domain_parameters.cpp
text_eval/text_eval_wrapper.cpp
text_eval/text_eval_parser.cpp
# This is basically a settings object, but for the toolbar
tool/ui/toolbar_configuration.cpp
@ -633,8 +630,7 @@ set( COMMON_GIT_SRCS
git/project_git_utils.cpp
git/kicad_git_common.cpp
git/kicad_git_errors.cpp
git/git_backend.cpp
git/libgit_backend.cpp
git/project_git_utils.cpp
)
set( COMMON_SRCS
@ -1018,13 +1014,6 @@ generate_lemon_grammar(
libeval_compiler/grammar.lemon
)
generate_lemon_grammar(
kicommon
text_eval
text_eval/text_eval_wrapper.cpp
text_eval/text_eval.lemon
)
# auto-generate stroke_params_lexer.h and stroke_params_keywords.cpp
# Called twice one for common and one for gal, to ensure the files are created
# on all devel tools ( Linux and msys2 )

View File

@ -24,7 +24,6 @@
#include "clipboard.h"
#include <wx/clipbrd.h>
#include <wx/dataobj.h>
#include <wx/image.h>
#include <wx/log.h>
#include <wx/string.h>
@ -91,10 +90,10 @@ std::unique_ptr<wxImage> GetImageFromClipboard()
{
if( wxTheClipboard->IsSupported( wxDF_BITMAP ) )
{
wxBitmapDataObject data;
wxImageDataObject data;
if( wxTheClipboard->GetData( data ) )
{
image = std::make_unique<wxImage>( data.GetBitmap().ConvertToImage() );
image = std::make_unique<wxImage>( data.GetImage() );
}
}
else if( wxTheClipboard->IsSupported( wxDF_FILENAME ) )

View File

@ -190,7 +190,7 @@ void DESIGN_BLOCK_LIST_IMPL::loadDesignBlocks()
};
for( size_t ii = 0; ii < num_elements; ++ii )
returns[ii] = tp.submit_task( db_thread );
returns[ii] = tp.submit( db_thread );
for( const std::future<size_t>& ret : returns )
{

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -26,6 +26,25 @@ WX_TEXT_ENTRY_DIALOG_BASE::WX_TEXT_ENTRY_DIALOG_BASE( wxWindow* parent, wxWindow
m_ContentSizer->Add( m_textCtrl, 0, wxEXPAND|wxALL, 5 );
wxBoxSizer* bSizer3;
bSizer3 = new wxBoxSizer( wxHORIZONTAL );
m_choiceLabel = new wxStaticText( this, wxID_ANY, _("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 );
m_choiceLabel->Wrap( -1 );
m_choiceLabel->Hide();
bSizer3->Add( m_choiceLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
wxArrayString m_choiceChoices;
m_choice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceChoices, 0 );
m_choice->SetSelection( 0 );
m_choice->Hide();
bSizer3->Add( m_choice, 3, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_ContentSizer->Add( bSizer3, 1, wxEXPAND, 5 );
m_mainSizer->Add( m_ContentSizer, 1, wxALL|wxEXPAND, 5 );

View File

@ -1,36 +1,34 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="18"/>
<FileVersion major="1" minor="17"/>
<object class="Project" expanded="true">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
<property name="cpp_class_decoration"></property>
<property name="cpp_disconnect_events">1</property>
<property name="cpp_event_generation">connect</property>
<property name="cpp_help_provider">none</property>
<property name="cpp_namespace"></property>
<property name="cpp_precompiled_header"></property>
<property name="cpp_use_array_enum">0</property>
<property name="cpp_use_enum">0</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">dialog_text_entry_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="lua_skip_events">1</property>
<property name="lua_ui_table">UI</property>
<property name="name">dialog_text_entry_base</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="php_disconnect_events">0</property>
<property name="php_disconnect_mode">source_name</property>
<property name="php_skip_events">1</property>
<property name="python_disconnect_events">0</property>
<property name="python_disconnect_mode">source_name</property>
<property name="python_image_path_wrapper_function_name"></property>
<property name="python_indent_with_spaces"></property>
<property name="python_skip_events">1</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<property name="use_native_eol">0</property>
<object class="Dialog" expanded="true">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
@ -82,10 +80,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
@ -144,10 +142,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
@ -171,7 +169,7 @@
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="maxlength">0</property>
<property name="maxlength"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">300,-1</property>
@ -200,6 +198,144 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bSizer3</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">1</property>
<property name="id">wxID_ANY</property>
<property name="label">MyLabel</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_choiceLabel</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
<property name="proportion">3</property>
<object class="wxChoice" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices"></property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">1</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_choice</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="selection">0</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="false">

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -18,12 +18,14 @@
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/textctrl.h>
#include <wx/choice.h>
#include <wx/sizer.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class WX_TEXT_ENTRY_DIALOG_BASE
///////////////////////////////////////////////////////////////////////////////
@ -35,6 +37,8 @@ class WX_TEXT_ENTRY_DIALOG_BASE : public DIALOG_SHIM
wxBoxSizer* m_mainSizer;
wxStaticText* m_label;
wxTextCtrl* m_textCtrl;
wxStaticText* m_choiceLabel;
wxChoice* m_choice;
wxStdDialogButtonSizer* m_sdbSizer1;
wxButton* m_sdbSizer1OK;
wxButton* m_sdbSizer1Cancel;

View File

@ -167,7 +167,9 @@ void PANEL_EMBEDDED_FILES::resizeGrid()
bool PANEL_EMBEDDED_FILES::TransferDataToWindow()
{
m_files_grid->ClearGrid();
m_files_grid->ClearRows();
if( m_files_grid->GetNumberRows() > 0 )
m_files_grid->DeleteRows( 0, m_files_grid->GetNumberRows() );
int ii = 0;

View File

@ -87,10 +87,6 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
m_stealsFocus( true ),
m_statusPopup( nullptr )
{
#ifdef _WIN32
// need to fix broken cairo rendering on Windows with wx 3.3
SetDoubleBuffered( false );
#endif
m_PaintEventCounter = std::make_unique<PROF_COUNTER>( "Draw panel paint events" );
if( Pgm().GetCommonSettings()->m_Appearance.show_scrollbars )

View File

@ -1059,35 +1059,32 @@ std::vector<wxWindow*> EDA_DRAW_FRAME::findDialogs()
}
void EDA_DRAW_FRAME::FocusOnLocation( const VECTOR2I& aPos, bool aAllowScroll )
void EDA_DRAW_FRAME::FocusOnLocation( const VECTOR2I& aPos )
{
bool centerView = false;
bool centerView = false;
BOX2D r = GetCanvas()->GetView()->GetViewport();
// Center if we're off the current view, or within 10% of its edge
r.Inflate( - r.GetWidth() / 10.0 );
if( !r.Contains( aPos ) )
centerView = true;
std::vector<BOX2D> dialogScreenRects;
if( aAllowScroll )
for( wxWindow* dialog : findDialogs() )
{
BOX2D r = GetCanvas()->GetView()->GetViewport();
dialogScreenRects.emplace_back( ToVECTOR2D( GetCanvas()->ScreenToClient( dialog->GetScreenPosition() ) ),
ToVECTOR2D( dialog->GetSize() ) );
}
// Center if we're off the current view, or within 10% of its edge
r.Inflate( - r.GetWidth() / 10.0 );
// Center if we're behind an obscuring dialog, or within 10% of its edge
for( BOX2D rect : dialogScreenRects )
{
rect.Inflate( rect.GetWidth() / 10 );
if( !r.Contains( aPos ) )
if( rect.Contains( GetCanvas()->GetView()->ToScreen( aPos ) ) )
centerView = true;
for( wxWindow* dialog : findDialogs() )
{
dialogScreenRects.emplace_back( ToVECTOR2D( GetCanvas()->ScreenToClient( dialog->GetScreenPosition() ) ),
ToVECTOR2D( dialog->GetSize() ) );
}
// Center if we're behind an obscuring dialog, or within 10% of its edge
for( BOX2D rect : dialogScreenRects )
{
rect.Inflate( rect.GetWidth() / 10 );
if( rect.Contains( GetCanvas()->GetView()->ToScreen( aPos ) ) )
centerView = true;
}
}
if( centerView )

View File

@ -1382,15 +1382,6 @@ bool EDA_SHAPE::hitTest( const VECTOR2I& aPosition, int aAccuracy ) const
return poly.Collide( aPosition, maxdist );
}
else if( m_cornerRadius > 0 )
{
ROUNDRECT rr( SHAPE_RECT( GetStart(), GetRectangleWidth(), GetRectangleHeight() ), m_cornerRadius );
SHAPE_POLY_SET poly;
rr.TransformToPolygon( poly );
if( poly.CollideEdge( aPosition, nullptr, maxdist ) )
return true;
}
else
{
std::vector<VECTOR2I> pts = GetRectCorners();
@ -1402,13 +1393,13 @@ bool EDA_SHAPE::hitTest( const VECTOR2I& aPosition, int aAccuracy ) const
{
return true;
}
if( IsHatchedFill() && GetHatching().Collide( aPosition, maxdist ) )
return true;
return false;
}
if( IsHatchedFill() && GetHatching().Collide( aPosition, maxdist ) )
return true;
return false;
case SHAPE_T::POLY:
if( IsFilledForHitTesting() )
{
@ -1450,40 +1441,6 @@ bool EDA_SHAPE::hitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
BOX2I bbox = getBoundingBox();
auto checkOutline =
[&]( const SHAPE_LINE_CHAIN& outline )
{
int count = (int) outline.GetPointCount();
for( int ii = 0; ii < count; ii++ )
{
VECTOR2I vertex = outline.GetPoint( ii );
// Test if the point is within aRect
if( arect.Contains( vertex ) )
return true;
if( ii + 1 < count )
{
VECTOR2I vertexNext = outline.GetPoint( ii + 1 );
// Test if this edge intersects aRect
if( arect.Intersects( vertex, vertexNext ) )
return true;
}
else if( outline.IsClosed() )
{
VECTOR2I vertexNext = outline.GetPoint( 0 );
// Test if this edge intersects aRect
if( arect.Intersects( vertex, vertexNext ) )
return true;
}
}
return false;
};
switch( m_shape )
{
case SHAPE_T::CIRCLE:
@ -1530,17 +1487,6 @@ bool EDA_SHAPE::hitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
{
return arect.Contains( bbox );
}
else if( m_cornerRadius > 0 )
{
ROUNDRECT rr( SHAPE_RECT( GetStart(), GetRectangleWidth(), GetRectangleHeight() ), m_cornerRadius );
SHAPE_POLY_SET poly;
rr.TransformToPolygon( poly );
// Account for the width of the line
arect.Inflate( GetWidth() / 2 );
return checkOutline( poly.Outline( 0 ) );
}
else
{
std::vector<VECTOR2I> pts = GetRectCorners();
@ -1582,8 +1528,34 @@ bool EDA_SHAPE::hitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
for( int ii = 0; ii < m_poly.OutlineCount(); ++ii )
{
if( checkOutline( m_poly.Outline( ii ) ) )
return true;
const SHAPE_LINE_CHAIN& poly = m_poly.Outline( ii );
int count = (int) poly.GetPointCount();
for( int jj = 0; jj < count; jj++ )
{
VECTOR2I vertex = poly.GetPoint( jj );
// Test if the point is within aRect
if( arect.Contains( vertex ) )
return true;
if( jj + 1 < count )
{
VECTOR2I vertexNext = poly.GetPoint( jj + 1 );
// Test if this edge intersects aRect
if( arect.Intersects( vertex, vertexNext ) )
return true;
}
else if( poly.IsClosed() )
{
VECTOR2I vertexNext = poly.GetPoint( 0 );
// Test if this edge intersects aRect
if( arect.Intersects( vertex, vertexNext ) )
return true;
}
}
}
return false;

View File

@ -35,7 +35,6 @@
#include <font/glyph.h>
#include <gr_text.h>
#include <string_utils.h> // for UnescapeString
#include <text_eval/text_eval_wrapper.h>
#include <math/util.h> // for KiROUND
#include <math/vector2d.h>
#include <core/kicad_algo.h>
@ -639,14 +638,6 @@ void EDA_TEXT::cacheShownText()
}
wxString EDA_TEXT::EvaluateText( const wxString& aText ) const
{
static EXPRESSION_EVALUATOR evaluator;
return evaluator.Evaluate( aText );
}
KIFONT::FONT* EDA_TEXT::GetDrawFont( const RENDER_SETTINGS* aSettings ) const
{
KIFONT::FONT* font = GetFont();

View File

@ -1364,11 +1364,6 @@ CAIRO_GAL::CAIRO_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
m_currentTarget = TARGET_NONCACHED;
SetTarget( TARGET_NONCACHED );
#ifdef _WIN32
// need to fix broken cairo rendering on Windows with wx 3.3
SetDoubleBuffered( false );
#endif
m_bitmapBuffer = nullptr;
m_wxOutput = nullptr;

View File

@ -22,13 +22,16 @@
*/
#include "git_add_to_index_handler.h"
#include "git_backend.h"
#include <git/kicad_git_memory.h>
#include <iterator>
#include <wx/string.h>
#include <wx/log.h>
GIT_ADD_TO_INDEX_HANDLER::GIT_ADD_TO_INDEX_HANDLER( git_repository* aRepository ) :
KIGIT_COMMON( aRepository )
GIT_ADD_TO_INDEX_HANDLER::GIT_ADD_TO_INDEX_HANDLER( git_repository* aRepository )
{
m_repository = aRepository;
m_filesToAdd.clear();
}
@ -40,11 +43,66 @@ GIT_ADD_TO_INDEX_HANDLER::~GIT_ADD_TO_INDEX_HANDLER()
bool GIT_ADD_TO_INDEX_HANDLER::AddToIndex( const wxString& aFilePath )
{
return GetGitBackend()->AddToIndex( this, aFilePath );
// Test if file is currently in the index
git_index* index = nullptr;
size_t at_pos = 0;
if( git_repository_index( &index, m_repository ) != 0 )
{
wxLogError( "Failed to get repository index" );
return false;
}
KIGIT::GitIndexPtr indexPtr( index );
if( git_index_find( &at_pos, index, aFilePath.ToUTF8().data() ) == GIT_OK )
{
wxLogError( "%s already in index", aFilePath );
return false;
}
// Add file to index if not already there
m_filesToAdd.push_back( aFilePath );
return true;
}
bool GIT_ADD_TO_INDEX_HANDLER::PerformAddToIndex()
{
return GetGitBackend()->PerformAddToIndex( this );
git_index* index = nullptr;
m_filesFailedToAdd.clear();
if( git_repository_index( &index, m_repository ) != 0 )
{
wxLogError( "Failed to get repository index" );
std::copy( m_filesToAdd.begin(), m_filesToAdd.end(), std::back_inserter( m_filesFailedToAdd ) );
return false;
}
KIGIT::GitIndexPtr indexPtr( index );
for( auto& file : m_filesToAdd )
{
if( git_index_add_bypath( index, file.ToUTF8().data() ) != 0 )
{
wxLogError( "Failed to add %s to index", file );
m_filesFailedToAdd.push_back( file );
continue;
}
}
if( git_index_write( index ) != 0 )
{
wxLogError( "Failed to write index" );
m_filesFailedToAdd.clear();
std::copy( m_filesToAdd.begin(), m_filesToAdd.end(),
std::back_inserter( m_filesFailedToAdd ) );
return false;
}
return true;
}

View File

@ -24,13 +24,12 @@
#ifndef GIT_ADD_TO_INDEX_HANDLER_H_
#define GIT_ADD_TO_INDEX_HANDLER_H_
#include <git/kicad_git_common.h>
#include <git2.h>
#include <vector>
#include <wx/string.h>
class LIBGIT_BACKEND;
class wxString;
class GIT_ADD_TO_INDEX_HANDLER : public KIGIT_COMMON
class GIT_ADD_TO_INDEX_HANDLER
{
public:
GIT_ADD_TO_INDEX_HANDLER( git_repository* aRepository );
@ -41,7 +40,8 @@ public:
bool PerformAddToIndex();
private:
friend class LIBGIT_BACKEND;
git_repository* m_repository;
std::vector<wxString> m_filesToAdd;
std::vector<wxString> m_filesFailedToAdd;
};

View File

@ -1,36 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* 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 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, you may find one here:
* http://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "git_backend.h"
static GIT_BACKEND* s_backend = nullptr;
GIT_BACKEND* GetGitBackend()
{
return s_backend;
}
void SetGitBackend( GIT_BACKEND* aBackend )
{
s_backend = aBackend;
}

View File

@ -1,127 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* 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 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, you may find one here:
* http://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef GIT_BACKEND_H_
#define GIT_BACKEND_H_
#include <map>
#include <set>
#include <vector>
#include <wx/string.h>
class GIT_CLONE_HANDLER;
class GIT_COMMIT_HANDLER;
class GIT_PUSH_HANDLER;
class GIT_STATUS_HANDLER;
class GIT_ADD_TO_INDEX_HANDLER;
class GIT_REMOVE_FROM_INDEX_HANDLER;
class GIT_CONFIG_HANDLER;
class GIT_INIT_HANDLER;
class GIT_BRANCH_HANDLER;
class GIT_PULL_HANDLER;
class GIT_REVERT_HANDLER;
struct RemoteConfig;
struct git_repository;
enum class InitResult;
enum class BranchResult;
enum class PullResult;
struct FileStatus;
enum class PushResult;
// Commit result shared across backend and handlers
enum class CommitResult
{
Success,
Error,
Cancelled
};
class GIT_BACKEND
{
public:
virtual ~GIT_BACKEND() = default;
virtual void Init() = 0;
virtual void Shutdown() = 0;
// Whether the libgit2 library is available/initialized enough for use
virtual bool IsLibraryAvailable() = 0;
virtual bool Clone( GIT_CLONE_HANDLER* aHandler ) = 0;
virtual CommitResult Commit( GIT_COMMIT_HANDLER* aHandler,
const std::vector<wxString>& aFiles,
const wxString& aMessage,
const wxString& aAuthorName,
const wxString& aAuthorEmail ) = 0;
virtual PushResult Push( GIT_PUSH_HANDLER* aHandler ) = 0;
virtual bool HasChangedFiles( GIT_STATUS_HANDLER* aHandler ) = 0;
virtual std::map<wxString, FileStatus> GetFileStatus( GIT_STATUS_HANDLER* aHandler,
const wxString& aPathspec ) = 0;
virtual wxString GetCurrentBranchName( GIT_STATUS_HANDLER* aHandler ) = 0;
virtual void UpdateRemoteStatus( GIT_STATUS_HANDLER* aHandler,
const std::set<wxString>& aLocalChanges,
const std::set<wxString>& aRemoteChanges,
std::map<wxString, FileStatus>& aFileStatus ) = 0;
virtual wxString GetWorkingDirectory( GIT_STATUS_HANDLER* aHandler ) = 0;
virtual wxString GetWorkingDirectory( GIT_CONFIG_HANDLER* aHandler ) = 0;
virtual bool GetConfigString( GIT_CONFIG_HANDLER* aHandler, const wxString& aKey,
wxString& aValue ) = 0;
virtual bool IsRepository( GIT_INIT_HANDLER* aHandler, const wxString& aPath ) = 0;
virtual InitResult InitializeRepository( GIT_INIT_HANDLER* aHandler, const wxString& aPath ) = 0;
virtual bool SetupRemote( GIT_INIT_HANDLER* aHandler, const RemoteConfig& aConfig ) = 0;
virtual BranchResult SwitchToBranch( GIT_BRANCH_HANDLER* aHandler, const wxString& aBranchName ) = 0;
virtual bool BranchExists( GIT_BRANCH_HANDLER* aHandler, const wxString& aBranchName ) = 0;
virtual bool PerformFetch( GIT_PULL_HANDLER* aHandler, bool aSkipLock ) = 0;
virtual PullResult PerformPull( GIT_PULL_HANDLER* aHandler ) = 0;
virtual void PerformRevert( GIT_REVERT_HANDLER* aHandler ) = 0;
virtual git_repository* GetRepositoryForFile( const char* aFilename ) = 0;
virtual int CreateBranch( git_repository* aRepo, const wxString& aBranchName ) = 0;
virtual bool RemoveVCS( git_repository*& aRepo, const wxString& aProjectPath,
bool aRemoveGitDir, wxString* aErrors ) = 0;
virtual bool AddToIndex( GIT_ADD_TO_INDEX_HANDLER* aHandler, const wxString& aFilePath ) = 0;
virtual bool PerformAddToIndex( GIT_ADD_TO_INDEX_HANDLER* aHandler ) = 0;
virtual bool RemoveFromIndex( GIT_REMOVE_FROM_INDEX_HANDLER* aHandler, const wxString& aFilePath ) = 0;
virtual void PerformRemoveFromIndex( GIT_REMOVE_FROM_INDEX_HANDLER* aHandler ) = 0;
};
GIT_BACKEND* GetGitBackend();
void SetGitBackend( GIT_BACKEND* aBackend );
#endif

View File

@ -22,7 +22,6 @@
*/
#include "git_branch_handler.h"
#include "git_backend.h"
#include <git/kicad_git_common.h>
#include <git/kicad_git_memory.h>
#include <trace_helpers.h>
@ -36,12 +35,89 @@ GIT_BRANCH_HANDLER::~GIT_BRANCH_HANDLER()
bool GIT_BRANCH_HANDLER::BranchExists( const wxString& aBranchName )
{
return GetGitBackend()->BranchExists( this, aBranchName );
git_repository* repo = GetRepo();
if( !repo )
return false;
git_reference* branchRef = nullptr;
bool exists = LookupBranchReference( aBranchName, &branchRef );
if( branchRef )
git_reference_free( branchRef );
return exists;
}
bool GIT_BRANCH_HANDLER::LookupBranchReference( const wxString& aBranchName, git_reference** aReference )
{
git_repository* repo = GetRepo();
if( !repo )
return false;
// Try direct lookup first
if( git_reference_lookup( aReference, repo, aBranchName.mb_str() ) == GIT_OK )
return true;
// Try dwim (Do What I Mean) lookup for short branch names
if( git_reference_dwim( aReference, repo, aBranchName.mb_str() ) == GIT_OK )
return true;
return false;
}
BranchResult GIT_BRANCH_HANDLER::SwitchToBranch( const wxString& aBranchName )
{
return GetGitBackend()->SwitchToBranch( this, aBranchName );
git_repository* repo = GetRepo();
if( !repo )
{
AddErrorString( _( "No repository available" ) );
return BranchResult::Error;
}
// Look up the branch reference
git_reference* branchRef = nullptr;
if( !LookupBranchReference( aBranchName, &branchRef ) )
{
AddErrorString( wxString::Format( _( "Failed to lookup branch '%s': %s" ),
aBranchName, KIGIT_COMMON::GetLastGitError() ) );
return BranchResult::BranchNotFound;
}
KIGIT::GitReferencePtr branchRefPtr( branchRef );
const char* branchRefName = git_reference_name( branchRef );
git_object* branchObj = nullptr;
if( git_revparse_single( &branchObj, repo, aBranchName.mb_str() ) != GIT_OK )
{
AddErrorString( wxString::Format( _( "Failed to find branch head for '%s': %s" ),
aBranchName, KIGIT_COMMON::GetLastGitError() ) );
return BranchResult::Error;
}
KIGIT::GitObjectPtr branchObjPtr( branchObj );
// Switch to the branch
if( git_checkout_tree( repo, branchObj, nullptr ) != GIT_OK )
{
AddErrorString( wxString::Format( _( "Failed to switch to branch '%s': %s" ),
aBranchName, KIGIT_COMMON::GetLastGitError() ) );
return BranchResult::CheckoutFailed;
}
// Update the HEAD reference
if( git_repository_set_head( repo, branchRefName ) != GIT_OK )
{
AddErrorString( wxString::Format( _( "Failed to update HEAD reference for branch '%s': %s" ),
aBranchName, KIGIT_COMMON::GetLastGitError() ) );
return BranchResult::Error;
}
wxLogTrace( traceGit, "Successfully switched to branch '%s'", aBranchName );
return BranchResult::Success;
}
void GIT_BRANCH_HANDLER::UpdateProgress( int aCurrent, int aTotal, const wxString& aMessage )

View File

@ -57,6 +57,15 @@ public:
bool BranchExists( const wxString& aBranchName );
void UpdateProgress( int aCurrent, int aTotal, const wxString& aMessage ) override;
private:
/**
* Look up a branch reference by name
* @param aBranchName Name of the branch
* @param aReference Output parameter for the reference
* @return True if successful, false otherwise
*/
bool LookupBranchReference( const wxString& aBranchName, git_reference** aReference );
};
#endif // GIT_BRANCH_HANDLER_H

View File

@ -23,8 +23,13 @@
#include "git_clone_handler.h"
#include <git/kicad_git_common.h>
#include <git/kicad_git_memory.h>
#include <trace_helpers.h>
#include "git_backend.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 )
{}
@ -36,7 +41,55 @@ GIT_CLONE_HANDLER::~GIT_CLONE_HANDLER()
bool GIT_CLONE_HANDLER::PerformClone()
{
return GetGitBackend()->Clone( this );
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() )
{
if( !clonePath.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
{
AddErrorString( wxString::Format( _( "Could not create directory '%s'" ),
m_clonePath ) );
return false;
}
}
git_clone_options cloneOptions;
git_clone_init_options( &cloneOptions, GIT_CLONE_OPTIONS_VERSION );
cloneOptions.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
cloneOptions.checkout_opts.progress_cb = clone_progress_cb;
cloneOptions.checkout_opts.progress_payload = this;
cloneOptions.fetch_opts.callbacks.transfer_progress = transfer_progress_cb;
cloneOptions.fetch_opts.callbacks.credentials = credentials_cb;
cloneOptions.fetch_opts.callbacks.payload = this;
TestedTypes() = 0;
ResetNextKey();
git_repository* newRepo = nullptr;
wxString remote = GetCommon()->m_remote;
if( git_clone( &newRepo, remote.mbc_str(), m_clonePath.mbc_str(),
&cloneOptions ) != 0 )
{
AddErrorString( wxString::Format( _( "Could not clone repository '%s'" ), remote ) );
return false;
}
GetCommon()->SetRepo( newRepo );
if( m_progressReporter )
m_progressReporter->Hide();
m_previousProgress = 0;
return true;
}

View File

@ -22,7 +22,8 @@
*/
#include "git_commit_handler.h"
#include "git_backend.h"
#include <git/kicad_git_memory.h>
#include <wx/log.h>
GIT_COMMIT_HANDLER::GIT_COMMIT_HANDLER( git_repository* aRepo ) :
KIGIT_COMMON( aRepo )
@ -33,13 +34,121 @@ GIT_COMMIT_HANDLER::~GIT_COMMIT_HANDLER()
{}
CommitResult
GIT_COMMIT_HANDLER::CommitResult
GIT_COMMIT_HANDLER::PerformCommit( const std::vector<wxString>& aFiles,
const wxString& aMessage,
const wxString& aAuthorName,
const wxString& aAuthorEmail )
{
return GetGitBackend()->Commit( this, aFiles, aMessage, aAuthorName, aAuthorEmail );
git_repository* repo = GetRepo();
if( !repo )
return CommitResult::Error;
git_index* index = nullptr;
if( git_repository_index( &index, repo ) != 0 )
{
AddErrorString( wxString::Format( _( "Failed to get repository index: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
return CommitResult::Error;
}
KIGIT::GitIndexPtr indexPtr( index );
for( const wxString& file : aFiles )
{
if( git_index_add_bypath( index, file.mb_str() ) != 0 )
{
AddErrorString( wxString::Format( _( "Failed to add file to index: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
return CommitResult::Error;
}
}
if( git_index_write( index ) != 0 )
{
AddErrorString( wxString::Format( _( "Failed to write index: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
return CommitResult::Error;
}
git_oid tree_id;
if( git_index_write_tree( &tree_id, index ) != 0 )
{
AddErrorString( wxString::Format( _( "Failed to write tree: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
return CommitResult::Error;
}
git_tree* tree = nullptr;
if( git_tree_lookup( &tree, repo, &tree_id ) != 0 )
{
AddErrorString( wxString::Format( _( "Failed to lookup tree: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
return CommitResult::Error;
}
KIGIT::GitTreePtr treePtr( tree );
git_commit* parent = nullptr;
if( git_repository_head_unborn( repo ) == 0 )
{
git_reference* headRef = nullptr;
if( git_repository_head( &headRef, repo ) != 0 )
{
AddErrorString( wxString::Format( _( "Failed to get HEAD reference: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
return CommitResult::Error;
}
KIGIT::GitReferencePtr headRefPtr( headRef );
if( git_reference_peel( (git_object**) &parent, headRef, GIT_OBJECT_COMMIT ) != 0 )
{
AddErrorString( wxString::Format( _( "Failed to get commit: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
return CommitResult::Error;
}
}
KIGIT::GitCommitPtr parentPtr( parent );
git_signature* author = nullptr;
if( git_signature_now( &author, aAuthorName.mb_str(), aAuthorEmail.mb_str() ) != 0 )
{
AddErrorString( wxString::Format( _( "Failed to create author signature: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
return CommitResult::Error;
}
KIGIT::GitSignaturePtr authorPtr( author );
git_oid oid;
size_t parentsCount = parent ? 1 : 0;
#if( LIBGIT2_VER_MAJOR == 1 && LIBGIT2_VER_MINOR == 8 \
&& ( LIBGIT2_VER_REVISION < 2 || LIBGIT2_VER_REVISION == 3 ) )
git_commit* const parents[1] = { parent };
git_commit** const parentsPtr = parent ? parents : nullptr;
#else
const git_commit* parents[1] = { parent };
const git_commit** parentsPtr = parent ? parents : nullptr;
#endif
if( git_commit_create( &oid, repo, "HEAD", author, author, nullptr,
aMessage.mb_str(), tree, parentsCount, parentsPtr ) != 0 )
{
AddErrorString( wxString::Format( _( "Failed to create commit: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
return CommitResult::Error;
}
return CommitResult::Success;
}

View File

@ -27,20 +27,25 @@
// Define a class to handle git commit operations
#include <git/kicad_git_common.h>
#include "git_backend.h"
#include <git2.h>
#include <string>
#include <vector>
#include <wx/string.h>
class LIBGIT_BACKEND;
class GIT_COMMIT_HANDLER : public KIGIT_COMMON
{
public:
GIT_COMMIT_HANDLER( git_repository* aRepo );
virtual ~GIT_COMMIT_HANDLER();
enum class CommitResult
{
Success,
Error,
Cancelled
};
CommitResult PerformCommit( const std::vector<wxString>& aFiles,
const wxString& aMessage,
const wxString& aAuthorName,
@ -49,7 +54,6 @@ public:
wxString GetErrorString() const;
private:
friend class LIBGIT_BACKEND;
void AddErrorString( const wxString& aErrorString );
wxString m_errorString;

View File

@ -22,7 +22,6 @@
*/
#include "git_config_handler.h"
#include "git_backend.h"
#include <git/kicad_git_common.h>
#include <git/kicad_git_memory.h>
#include <pgm_base.h>
@ -60,12 +59,48 @@ GitUserConfig GIT_CONFIG_HANDLER::GetUserConfig()
wxString GIT_CONFIG_HANDLER::GetWorkingDirectory()
{
return GetGitBackend()->GetWorkingDirectory( this );
git_repository* repo = GetRepo();
if( !repo )
return wxEmptyString;
const char* workdir = git_repository_workdir( repo );
if( !workdir )
return wxEmptyString;
return wxString( workdir );
}
bool GIT_CONFIG_HANDLER::GetConfigString( const wxString& aKey, wxString& aValue )
{
return GetGitBackend()->GetConfigString( this, aKey, aValue );
git_repository* repo = GetRepo();
if( !repo )
return false;
git_config* config = nullptr;
if( git_repository_config( &config, repo ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to get repository config: %s", KIGIT_COMMON::GetLastGitError() );
return false;
}
KIGIT::GitConfigPtr configPtr( config );
git_config_entry* entry = nullptr;
int result = git_config_get_entry( &entry, config, aKey.mb_str() );
KIGIT::GitConfigEntryPtr entryPtr( entry );
if( result != GIT_OK || entry == nullptr )
{
wxLogTrace( traceGit, "Config key '%s' not found", aKey );
return false;
}
aValue = wxString( entry->value );
return true;
}
void GIT_CONFIG_HANDLER::UpdateProgress( int aCurrent, int aTotal, const wxString& aMessage )

View File

@ -22,7 +22,6 @@
*/
#include "git_init_handler.h"
#include "git_backend.h"
#include <git/kicad_git_common.h>
#include <git/kicad_git_memory.h>
#include <trace_helpers.h>
@ -36,17 +35,118 @@ GIT_INIT_HANDLER::~GIT_INIT_HANDLER()
bool GIT_INIT_HANDLER::IsRepository( const wxString& aPath )
{
return GetGitBackend()->IsRepository( this, aPath );
git_repository* repo = nullptr;
int error = git_repository_open( &repo, aPath.mb_str() );
if( error == 0 )
{
git_repository_free( repo );
return true;
}
return false;
}
InitResult GIT_INIT_HANDLER::InitializeRepository( const wxString& aPath )
{
return GetGitBackend()->InitializeRepository( this, aPath );
// Check if directory is already a git repository
if( IsRepository( aPath ) )
{
return InitResult::AlreadyExists;
}
git_repository* repo = nullptr;
if( git_repository_init( &repo, aPath.mb_str(), 0 ) != GIT_OK )
{
if( repo )
git_repository_free( repo );
AddErrorString( wxString::Format( _( "Failed to initialize Git repository: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
return InitResult::Error;
}
// Update the common repository pointer
GetCommon()->SetRepo( repo );
wxLogTrace( traceGit, "Successfully initialized Git repository at %s", aPath );
return InitResult::Success;
}
bool GIT_INIT_HANDLER::SetupRemote( const RemoteConfig& aConfig )
{
return GetGitBackend()->SetupRemote( this, aConfig );
// This is an optional step
if( aConfig.url.IsEmpty() )
return true;
git_repository* repo = GetRepo();
if( !repo )
{
AddErrorString( _( "No repository available to set up remote" ) );
return false;
}
// Update connection settings in common
GetCommon()->SetUsername( aConfig.username );
GetCommon()->SetPassword( aConfig.password );
GetCommon()->SetSSHKey( aConfig.sshKey );
git_remote* remote = nullptr;
wxString fullURL;
// Build the full URL based on connection type
if( aConfig.connType == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_SSH )
{
fullURL = aConfig.username + "@" + aConfig.url;
}
else if( aConfig.connType == KIGIT_COMMON::GIT_CONN_TYPE::GIT_CONN_HTTPS )
{
fullURL = aConfig.url.StartsWith( "https" ) ? "https://" : "http://";
if( !aConfig.username.empty() )
{
fullURL.append( aConfig.username );
if( !aConfig.password.empty() )
{
fullURL.append( wxS( ":" ) );
fullURL.append( aConfig.password );
}
fullURL.append( wxS( "@" ) );
}
// Extract the bare URL (without protocol prefix)
wxString bareURL = aConfig.url;
if( bareURL.StartsWith( "https://" ) )
bareURL = bareURL.Mid( 8 );
else if( bareURL.StartsWith( "http://" ) )
bareURL = bareURL.Mid( 7 );
fullURL.append( bareURL );
}
else
{
fullURL = aConfig.url;
}
int error = git_remote_create_with_fetchspec( &remote, repo, "origin",
fullURL.ToStdString().c_str(),
"+refs/heads/*:refs/remotes/origin/*" );
KIGIT::GitRemotePtr remotePtr( remote );
if( error != GIT_OK )
{
AddErrorString( wxString::Format( _( "Failed to create remote: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
return false;
}
wxLogTrace( traceGit, "Successfully set up remote origin" );
return true;
}
void GIT_INIT_HANDLER::UpdateProgress( int aCurrent, int aTotal, const wxString& aMessage )

View File

@ -22,22 +22,188 @@
*/
#include "git_pull_handler.h"
#include "git_backend.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()
{}
{
}
bool GIT_PULL_HANDLER::PerformFetch( bool aSkipLock )
{
return GetGitBackend()->PerformFetch( this, 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
git_remote* remote = nullptr;
if( git_remote_lookup( &remote, GetRepo(), "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;
remoteCallbacks.transfer_progress = transfer_progress_cb;
remoteCallbacks.credentials = credentials_cb;
remoteCallbacks.payload = this;
GetCommon()->SetCancelled( false );
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 ) );
return false;
}
git_fetch_options fetchOptions;
git_fetch_init_options( &fetchOptions, GIT_FETCH_OPTIONS_VERSION );
fetchOptions.callbacks = remoteCallbacks;
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 ) );
return false;
}
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformFetch() - Fetch completed successfully" );
return true;
}
PullResult GIT_PULL_HANDLER::PerformPull()
{
return GetGitBackend()->PerformPull( this );
PullResult result = PullResult::Success;
std::unique_lock<std::mutex> lock( GetCommon()->m_gitActionMutex, std::try_to_lock );
if( !lock.owns_lock() )
{
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformPull() - Could not lock mutex" );
return PullResult::Error;
}
if( !PerformFetch( true ) )
return PullResult::Error;
git_oid pull_merge_oid = {};
if( git_repository_fetchhead_foreach( GetRepo(), fetchhead_foreach_cb,
&pull_merge_oid ) )
{
AddErrorString( _( "Could not read 'FETCH_HEAD'" ) );
return PullResult::Error;
}
git_annotated_commit* fetchhead_commit;
if( git_annotated_commit_lookup( &fetchhead_commit, GetRepo(), &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;
if( git_merge_analysis( &merge_analysis, &merge_preference, GetRepo(), merge_commits, 1 ) )
{
AddErrorString( _( "Could not analyze merge" ) );
return PullResult::Error;
}
if( merge_analysis & GIT_MERGE_ANALYSIS_UNBORN )
{
AddErrorString( _( "Invalid HEAD. Cannot merge." ) );
return PullResult::MergeFailed;
}
// 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() );
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" );
// Check git config to determine if we should rebase or merge
git_config* config = nullptr;
if( git_repository_config( &config, GetRepo() ) != GIT_OK )
{
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformPull() - Failed to get repository config" );
AddErrorString( _( "Could not access repository configuration" ) );
return PullResult::Error;
}
KIGIT::GitConfigPtr configPtr( config );
// Check for pull.rebase config
int rebase_value = 0;
int ret = git_config_get_bool( &rebase_value, config, "pull.rebase" );
// If pull.rebase is set to true, use rebase; otherwise use merge
if( ret == GIT_OK && rebase_value )
{
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformPull() - Using rebase based on config" );
return handleRebase( merge_commits, 1 );
}
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformPull() - Using merge based on config" );
return handleMerge( merge_commits, 1 );
}
wxLogTrace( traceGit, "GIT_PULL_HANDLER::PerformPull() - Merge needs resolution" );
//TODO: handle merges when they need to be resolved
return result;
}
const std::vector<std::pair<std::string, std::vector<CommitDetails>>>&
@ -46,7 +212,384 @@ GIT_PULL_HANDLER::GetFetchResults() const
return m_fetchResults;
}
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 )
return aMessage.substr( 0, firstLineEnd );
return aMessage;
}
std::string GIT_PULL_HANDLER::getFormattedCommitDate( const git_time& aTime )
{
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 );
return dateBuffer;
}
PullResult GIT_PULL_HANDLER::handleFastForward()
{
git_reference* rawRef = 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 );
const char* branch_shorthand = git_reference_shorthand( rawRef );
wxString remote_name = GetRemotename();
wxString remoteBranchName = wxString::Format( "refs/remotes/%s/%s",
remote_name, branch_shorthand );
// 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 )
{
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 ) ) );
return PullResult::Error;
}
KIGIT::GitCommitPtr commitPtr( commit );
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 );
branchCommits.second.push_back( details );
}
return PullResult::FastForward;
}
PullResult GIT_PULL_HANDLER::handleMerge( const git_annotated_commit** aMergeHeads,
size_t aMergeHeadsCount )
{
git_merge_options merge_opts;
git_merge_options_init( &merge_opts, GIT_MERGE_OPTIONS_VERSION );
git_checkout_options checkout_opts;
git_checkout_init_options( &checkout_opts, GIT_CHECKOUT_OPTIONS_VERSION );
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
if( git_merge( GetRepo(), aMergeHeads, aMergeHeadsCount, &merge_opts, &checkout_opts ) )
{
AddErrorString( _( "Could not merge commits" ) );
return PullResult::Error;
}
// Get the repository index
git_index* index = nullptr;
if( git_repository_index( &index, GetRepo() ) )
{
AddErrorString( _( "Could not get repository index" ) );
return PullResult::Error;
}
KIGIT::GitIndexPtr indexPtr( index );
// Check for conflicts
git_index_conflict_iterator* conflicts = nullptr;
if( git_index_conflict_iterator_new( &conflicts, index ) )
{
AddErrorString( _( "Could not get conflict iterator" ) );
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;
std::vector<ConflictData> conflict_data;
while( git_index_conflict_next( &ancestor, &our, &their, conflicts ) == 0 )
{
// Case 3: Both files have changed
if( ancestor && our && their )
{
ConflictData conflict_datum;
conflict_datum.filename = our->path;
conflict_datum.our_oid = our->id;
conflict_datum.their_oid = their->id;
conflict_datum.our_commit_time = our->mtime.seconds;
conflict_datum.their_commit_time = their->mtime.seconds;
conflict_datum.our_status = _( "Changed" );
conflict_datum.their_status = _( "Changed" );
conflict_datum.use_ours = true;
conflict_data.push_back( conflict_datum );
}
// Case 4: File added in both ours and theirs
else if( !ancestor && our && their )
{
ConflictData conflict_datum;
conflict_datum.filename = our->path;
conflict_datum.our_oid = our->id;
conflict_datum.their_oid = their->id;
conflict_datum.our_commit_time = our->mtime.seconds;
conflict_datum.their_commit_time = their->mtime.seconds;
conflict_datum.our_status = _( "Added" );
conflict_datum.their_status = _( "Added" );
conflict_datum.use_ours = true;
conflict_data.push_back( conflict_datum );
}
// Case 1: Remote file has changed or been added, local file has not
else if( their && !our )
{
// Accept their changes
git_index_add( index, their );
}
// Case 2: Local file has changed or been added, remote file has not
else if( our && !their )
{
// Accept our changes
git_index_add( index, our );
}
else
{
wxLogError( wxS( "Unexpected conflict state" ) );
}
}
if( conflict_data.empty() )
{
git_index_conflict_cleanup( index );
git_index_write( 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 );
}

View File

@ -29,6 +29,7 @@
#include <vector>
#include <string>
#include <wx/string.h>
#include <git2.h>
// Structure to store commit details
struct CommitDetails
@ -49,12 +50,22 @@ enum class PullResult : int
FastForward
};
class LIBGIT_BACKEND;
struct ConflictData
{
std::string filename;
std::string our_status;
std::string their_status;
git_oid our_oid;
git_oid their_oid;
git_time_t our_commit_time;
git_time_t their_commit_time;
bool use_ours; // Flag indicating user's choice (true = ours, false = theirs)
};
class GIT_PULL_HANDLER : public KIGIT_REPO_MIXIN
{
public:
friend class LIBGIT_BACKEND;
GIT_PULL_HANDLER( KIGIT_COMMON* aCommon );
~GIT_PULL_HANDLER();
@ -66,8 +77,15 @@ public:
// Implementation for progress updates
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 );
};
#endif // _GIT_PULL_HANDLER_H_

View File

@ -22,8 +22,13 @@
*/
#include "git_push_handler.h"
#include <git/kicad_git_common.h>
#include <git/kicad_git_memory.h>
#include <trace_helpers.h>
#include "git_backend.h"
#include <iostream>
#include <wx/log.h>
GIT_PUSH_HANDLER::GIT_PUSH_HANDLER( KIGIT_COMMON* aRepo ) : KIGIT_REPO_MIXIN( aRepo )
{}
@ -33,7 +38,79 @@ GIT_PUSH_HANDLER::~GIT_PUSH_HANDLER()
PushResult GIT_PUSH_HANDLER::PerformPush()
{
return GetGitBackend()->Push( this );
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)
{
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);
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;
GetCommon()->SetCancelled( false );
TestedTypes() = 0;
ResetNextKey();
if( git_remote_connect( remote, GIT_DIRECTION_PUSH, &remoteCallbacks, nullptr, nullptr ) )
{
AddErrorString( wxString::Format( _( "Could not connect to remote: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
return PushResult::Error;
}
git_push_options pushOptions;
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 ) )
{
AddErrorString( wxString::Format( _( "Could not push to remote: %s" ),
KIGIT_COMMON::GetLastGitError() ) );
git_remote_disconnect( remote );
return PushResult::Error;
}
git_remote_disconnect( remote );
return result;
}

View File

@ -21,14 +21,15 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "git_remove_from_index_handler.h"
#include "git_backend.h"
#include <wx/string.h>
#include <wx/log.h>
GIT_REMOVE_FROM_INDEX_HANDLER::GIT_REMOVE_FROM_INDEX_HANDLER( git_repository* aRepository ) :
KIGIT_COMMON( aRepository )
#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 )
{
m_repository = aRepository;
m_filesToRemove.clear();
}
@ -40,11 +41,61 @@ GIT_REMOVE_FROM_INDEX_HANDLER::~GIT_REMOVE_FROM_INDEX_HANDLER()
bool GIT_REMOVE_FROM_INDEX_HANDLER::RemoveFromIndex( const wxString& aFilePath )
{
return GetGitBackend()->RemoveFromIndex( this, aFilePath );
// Test if file is currently in the index
git_index* index = nullptr;
size_t at_pos = 0;
if( git_repository_index( &index, m_repository ) != 0 )
{
wxLogError( "Failed to get repository index" );
return false;
}
KIGIT::GitIndexPtr indexPtr( index );
if( git_index_find( &at_pos, index, aFilePath.ToUTF8().data() ) != 0 )
{
wxLogError( "Failed to find index entry for %s", aFilePath );
return false;
}
m_filesToRemove.push_back( aFilePath );
return true;
}
void GIT_REMOVE_FROM_INDEX_HANDLER::PerformRemoveFromIndex()
{
GetGitBackend()->PerformRemoveFromIndex( this );
for( auto& file : m_filesToRemove )
{
git_index* index = nullptr;
git_oid oid;
if( git_repository_index( &index, m_repository ) != 0 )
{
wxLogError( "Failed to get repository index" );
return;
}
KIGIT::GitIndexPtr indexPtr( index );
if( git_index_remove_bypath( index, file.ToUTF8().data() ) != 0 )
{
wxLogError( "Failed to remove index entry for %s", file );
return;
}
if( git_index_write( index ) != 0 )
{
wxLogError( "Failed to write index" );
return;
}
if( git_index_write_tree( &oid, index ) != 0 )
{
wxLogError( "Failed to write index tree" );
return;
}
}
}

View File

@ -24,13 +24,12 @@
#ifndef GIT_REMOVE_FROM_INDEX_HANDLER_H_
#define GIT_REMOVE_FROM_INDEX_HANDLER_H_
#include <git/kicad_git_common.h>
#include <git2.h>
#include <vector>
#include <wx/string.h>
class LIBGIT_BACKEND;
class wxString;
class GIT_REMOVE_FROM_INDEX_HANDLER : public KIGIT_COMMON
class GIT_REMOVE_FROM_INDEX_HANDLER
{
public:
GIT_REMOVE_FROM_INDEX_HANDLER( git_repository* aRepository );
@ -42,7 +41,7 @@ public:
private:
friend class LIBGIT_BACKEND;
git_repository* m_repository;
std::vector<wxString> m_filesToRemove;
};

View File

@ -22,7 +22,11 @@
*/
#include "git_revert_handler.h"
#include "git_backend.h"
#include <wx/log.h>
#include <wx/string.h>
#include <trace_helpers.h>
GIT_REVERT_HANDLER::GIT_REVERT_HANDLER( git_repository* aRepository )
@ -42,8 +46,74 @@ bool GIT_REVERT_HANDLER::Revert( const wxString& aFilePath )
return true;
}
void GIT_REVERT_HANDLER::PerformRevert()
static void checkout_progress_cb( const char *path, size_t cur, size_t tot, void *payload )
{
GetGitBackend()->PerformRevert( this );
wxLogTrace( traceGit, wxS( "checkout_progress_cb: %s %zu/%zu" ), path, cur, tot );
}
static int checkout_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 )
{
GIT_REVERT_HANDLER* handler = static_cast<GIT_REVERT_HANDLER*>(payload);
if( why & ( GIT_CHECKOUT_NOTIFY_CONFLICT | GIT_CHECKOUT_NOTIFY_IGNORED
| GIT_CHECKOUT_NOTIFY_UPDATED ) )
handler->PushFailedFile( path );
return 0;
}
void GIT_REVERT_HANDLER::PerformRevert()
{
git_object* head_commit = NULL;
git_checkout_options opts;
git_checkout_init_options( &opts, GIT_CHECKOUT_OPTIONS_VERSION );
// Get the HEAD commit
if( git_revparse_single( &head_commit, m_repository, "HEAD" ) != 0 )
{
// Handle error. If we cannot get the HEAD, then there's no point proceeding.
return;
}
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
char** paths = new char*[m_filesToRevert.size()];
for( size_t ii = 0; ii < m_filesToRevert.size(); ii++ )
{
// Set paths to the specific file
paths[ii] = wxStrdup( m_filesToRevert[ii].ToUTF8() );
}
git_strarray arr = { paths, m_filesToRevert.size() };
opts.paths = arr;
opts.progress_cb = checkout_progress_cb;
opts.notify_cb = checkout_notify_cb;
opts.notify_payload = static_cast<void*>( this );
// Attempt to checkout the file(s)
if( git_checkout_tree(m_repository, head_commit, &opts ) != 0 )
{
const git_error *e = git_error_last();
if( e )
{
wxLogTrace( traceGit, wxS( "Checkout failed: %d: %s" ), e->klass, e->message );
}
}
// Free the HEAD commit
for( size_t ii = 0; ii < m_filesToRevert.size(); ii++ )
delete( paths[ii] );
delete[] paths;
git_object_free( head_commit );
}

View File

@ -27,10 +27,6 @@
#include <git2.h>
#include <vector>
#include <wx/string.h>
// TEMPORARY HACKFIX INCLUDE FOR STD::VECTOR EXPORT OUT OF KICOMMON ON WINDOWS
#include <settings/parameters.h>
class LIBGIT_BACKEND;
class GIT_REVERT_HANDLER
{
@ -48,7 +44,6 @@ public:
}
private:
friend class LIBGIT_BACKEND;
git_repository* m_repository;
std::vector<wxString> m_filesToRevert;

View File

@ -22,8 +22,10 @@
*/
#include "git_status_handler.h"
#include <git/kicad_git_common.h>
#include <git/kicad_git_memory.h>
#include <trace_helpers.h>
#include "git_backend.h"
#include <wx/log.h>
GIT_STATUS_HANDLER::GIT_STATUS_HANDLER( KIGIT_COMMON* aCommon ) : KIGIT_REPO_MIXIN( aCommon )
{}
@ -33,29 +35,171 @@ GIT_STATUS_HANDLER::~GIT_STATUS_HANDLER()
bool GIT_STATUS_HANDLER::HasChangedFiles()
{
return GetGitBackend()->HasChangedFiles( this );
git_repository* repo = GetRepo();
if( !repo )
return false;
git_status_options opts;
git_status_init_options( &opts, GIT_STATUS_OPTIONS_VERSION );
opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED | GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX
| GIT_STATUS_OPT_SORT_CASE_SENSITIVELY;
git_status_list* status_list = nullptr;
if( git_status_list_new( &status_list, repo, &opts ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to get status list: %s", KIGIT_COMMON::GetLastGitError() );
return false;
}
KIGIT::GitStatusListPtr status_list_ptr( status_list );
bool hasChanges = ( git_status_list_entrycount( status_list ) > 0 );
return hasChanges;
}
std::map<wxString, FileStatus> GIT_STATUS_HANDLER::GetFileStatus( const wxString& aPathspec )
{
return GetGitBackend()->GetFileStatus( this, aPathspec );
std::map<wxString, FileStatus> fileStatusMap;
git_repository* repo = GetRepo();
if( !repo )
return fileStatusMap;
git_status_options status_options;
git_status_init_options( &status_options, GIT_STATUS_OPTIONS_VERSION );
status_options.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
status_options.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED | GIT_STATUS_OPT_INCLUDE_UNMODIFIED;
// Set up pathspec if provided
std::string pathspec_str;
std::vector<const char*> pathspec_ptrs;
if( !aPathspec.IsEmpty() )
{
pathspec_str = aPathspec.ToStdString();
pathspec_ptrs.push_back( pathspec_str.c_str() );
status_options.pathspec.strings = const_cast<char**>( pathspec_ptrs.data() );
status_options.pathspec.count = pathspec_ptrs.size();
}
git_status_list* status_list = nullptr;
if( git_status_list_new( &status_list, repo, &status_options ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to get git status list: %s", KIGIT_COMMON::GetLastGitError() );
return fileStatusMap;
}
KIGIT::GitStatusListPtr statusListPtr( status_list );
size_t count = git_status_list_entrycount( status_list );
wxString repoWorkDir( git_repository_workdir( repo ) );
for( size_t ii = 0; ii < count; ++ii )
{
const git_status_entry* entry = git_status_byindex( status_list, ii );
std::string path( entry->head_to_index ? entry->head_to_index->old_file.path
: entry->index_to_workdir->old_file.path );
wxString absPath = repoWorkDir + path;
FileStatus fileStatus;
fileStatus.filePath = absPath;
fileStatus.gitStatus = entry->status;
fileStatus.status = ConvertStatus( entry->status );
fileStatusMap[absPath] = fileStatus;
}
return fileStatusMap;
}
wxString GIT_STATUS_HANDLER::GetCurrentBranchName()
{
return GetGitBackend()->GetCurrentBranchName( this );
git_repository* repo = GetRepo();
if( !repo )
return wxEmptyString;
git_reference* currentBranchReference = nullptr;
int rc = git_repository_head( &currentBranchReference, repo );
KIGIT::GitReferencePtr currentBranchReferencePtr( currentBranchReference );
if( currentBranchReference )
{
return git_reference_shorthand( currentBranchReference );
}
else if( rc == GIT_EUNBORNBRANCH )
{
// Unborn branch - could return empty or a default name
return wxEmptyString;
}
else
{
wxLogTrace( traceGit, "Failed to lookup current branch: %s", KIGIT_COMMON::GetLastGitError() );
return wxEmptyString;
}
}
void GIT_STATUS_HANDLER::UpdateRemoteStatus( const std::set<wxString>& aLocalChanges,
const std::set<wxString>& aRemoteChanges,
std::map<wxString, FileStatus>& aFileStatus )
const std::set<wxString>& aRemoteChanges,
std::map<wxString, FileStatus>& aFileStatus )
{
GetGitBackend()->UpdateRemoteStatus( this, aLocalChanges, aRemoteChanges, aFileStatus );
git_repository* repo = GetRepo();
if( !repo )
return;
wxString repoWorkDir( git_repository_workdir( repo ) );
// Update status based on local/remote changes
for( auto& [absPath, fileStatus] : aFileStatus )
{
// Convert absolute path to relative path for comparison
wxString relativePath = absPath;
if( relativePath.StartsWith( repoWorkDir ) )
{
relativePath = relativePath.Mid( repoWorkDir.length() );
#ifdef _WIN32
relativePath.Replace( wxS( "\\" ), wxS( "/" ) );
#endif
}
std::string relativePathStd = relativePath.ToStdString();
// Only update if the file is not already modified/added/deleted
if( fileStatus.status == KIGIT_COMMON::GIT_STATUS::GIT_STATUS_CURRENT )
{
if( aLocalChanges.count( relativePathStd ) )
{
fileStatus.status = KIGIT_COMMON::GIT_STATUS::GIT_STATUS_AHEAD;
}
else if( aRemoteChanges.count( relativePathStd ) )
{
fileStatus.status = KIGIT_COMMON::GIT_STATUS::GIT_STATUS_BEHIND;
}
}
}
}
wxString GIT_STATUS_HANDLER::GetWorkingDirectory()
{
return GetGitBackend()->GetWorkingDirectory( this );
git_repository* repo = GetRepo();
if( !repo )
return wxEmptyString;
const char* workdir = git_repository_workdir( repo );
if( !workdir )
return wxEmptyString;
return wxString( workdir );
}
KIGIT_COMMON::GIT_STATUS GIT_STATUS_HANDLER::ConvertStatus( unsigned int aGitStatus )

View File

@ -29,8 +29,6 @@
#include <map>
#include <set>
class LIBGIT_BACKEND;
struct FileStatus
{
wxString filePath;
@ -82,7 +80,6 @@ public:
void UpdateProgress( int aCurrent, int aTotal, const wxString& aMessage ) override;
private:
friend class LIBGIT_BACKEND;
/**
* Convert git status flags to KIGIT_COMMON::GIT_STATUS
* @param aGitStatus Raw git status flags

View File

@ -33,8 +33,6 @@
#include <wx/string.h>
class LIBGIT_BACKEND;
class KIGIT_COMMON
{
@ -176,7 +174,6 @@ protected:
friend class GIT_PUSH_HANDLER;
friend class GIT_PULL_HANDLER;
friend class GIT_CLONE_HANDLER;
friend class LIBGIT_BACKEND;
friend class PROJECT_TREE_PANE;
private:

File diff suppressed because it is too large Load Diff

View File

@ -1,100 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* 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 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, you may find one here:
* http://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef LIBGIT_BACKEND_H_
#define LIBGIT_BACKEND_H_
#include "git_backend.h"
// Forward declarations to avoid exposing libgit2 headers
struct git_annotated_commit;
class LIBGIT_BACKEND : public GIT_BACKEND
{
public:
void Init() override;
void Shutdown() override;
bool IsLibraryAvailable() override;
bool Clone( GIT_CLONE_HANDLER* aHandler ) override;
CommitResult Commit( GIT_COMMIT_HANDLER* aHandler,
const std::vector<wxString>& aFiles,
const wxString& aMessage,
const wxString& aAuthorName,
const wxString& aAuthorEmail ) override;
PushResult Push( GIT_PUSH_HANDLER* aHandler ) override;
bool HasChangedFiles( GIT_STATUS_HANDLER* aHandler ) override;
std::map<wxString, FileStatus> GetFileStatus( GIT_STATUS_HANDLER* aHandler,
const wxString& aPathspec ) override;
wxString GetCurrentBranchName( GIT_STATUS_HANDLER* aHandler ) override;
void UpdateRemoteStatus( GIT_STATUS_HANDLER* aHandler,
const std::set<wxString>& aLocalChanges,
const std::set<wxString>& aRemoteChanges,
std::map<wxString, FileStatus>& aFileStatus ) override;
wxString GetWorkingDirectory( GIT_STATUS_HANDLER* aHandler ) override;
wxString GetWorkingDirectory( GIT_CONFIG_HANDLER* aHandler ) override;
bool GetConfigString( GIT_CONFIG_HANDLER* aHandler, const wxString& aKey,
wxString& aValue ) override;
bool IsRepository( GIT_INIT_HANDLER* aHandler, const wxString& aPath ) override;
InitResult InitializeRepository( GIT_INIT_HANDLER* aHandler, const wxString& aPath ) override;
bool SetupRemote( GIT_INIT_HANDLER* aHandler, const RemoteConfig& aConfig ) override;
BranchResult SwitchToBranch( GIT_BRANCH_HANDLER* aHandler, const wxString& aBranchName ) override;
bool BranchExists( GIT_BRANCH_HANDLER* aHandler, const wxString& aBranchName ) override;
bool PerformFetch( GIT_PULL_HANDLER* aHandler, bool aSkipLock ) override;
PullResult PerformPull( GIT_PULL_HANDLER* aHandler ) override;
void PerformRevert( GIT_REVERT_HANDLER* aHandler ) override;
git_repository* GetRepositoryForFile( const char* aFilename ) override;
int CreateBranch( git_repository* aRepo, const wxString& aBranchName ) override;
bool RemoveVCS( git_repository*& aRepo, const wxString& aProjectPath,
bool aRemoveGitDir, wxString* aErrors ) override;
bool AddToIndex( GIT_ADD_TO_INDEX_HANDLER* aHandler, const wxString& aFilePath ) override;
bool PerformAddToIndex( GIT_ADD_TO_INDEX_HANDLER* aHandler ) override;
bool RemoveFromIndex( GIT_REMOVE_FROM_INDEX_HANDLER* aHandler, const wxString& aFilePath ) override;
void PerformRemoveFromIndex( GIT_REMOVE_FROM_INDEX_HANDLER* aHandler ) override;
private:
PullResult handleFastForward( GIT_PULL_HANDLER* aHandler );
PullResult handleMerge( GIT_PULL_HANDLER* aHandler, const git_annotated_commit** aMergeHeads,
size_t aMergeHeadsCount );
PullResult handleRebase( GIT_PULL_HANDLER* aHandler, const git_annotated_commit** aMergeHeads,
size_t aMergeHeadsCount );
};
#endif

View File

@ -22,58 +22,105 @@
*/
#include "project_git_utils.h"
#include "git_backend.h"
#include <wx/string.h>
#include <string_utils.h>
#include "kicad_git_common.h"
#include "kicad_git_memory.h"
#include <git/kicad_git_compat.h>
#include <trace_helpers.h>
#include <wx/log.h>
#include <wx/filename.h>
#include <gestfich.h>
namespace KIGIT
{
git_repository* PROJECT_GIT_UTILS::GetRepositoryForFile( const char* aFilename )
{
return GetGitBackend()->GetRepositoryForFile( aFilename );
git_repository* repo = nullptr;
git_buf repo_path = GIT_BUF_INIT;
if( git_repository_discover( &repo_path, aFilename, 0, nullptr ) != GIT_OK )
{
wxLogTrace( traceGit, "Can't repo discover %s: %s", aFilename,
KIGIT_COMMON::GetLastGitError() );
return nullptr;
}
KIGIT::GitBufPtr repo_path_ptr( &repo_path );
if( git_repository_open( &repo, repo_path.ptr ) != GIT_OK )
{
wxLogTrace( traceGit, "Can't open repo for %s: %s", repo_path.ptr,
KIGIT_COMMON::GetLastGitError() );
return nullptr;
}
return repo;
}
int PROJECT_GIT_UTILS::CreateBranch( git_repository* aRepo, const wxString& aBranchName )
{
return GetGitBackend()->CreateBranch( aRepo, aBranchName );
git_oid head_oid;
if( int error = git_reference_name_to_id( &head_oid, aRepo, "HEAD" ); error != GIT_OK )
{
wxLogTrace( traceGit, "Failed to lookup HEAD reference: %s",
KIGIT_COMMON::GetLastGitError() );
return error;
}
git_commit* commit = nullptr;
if( int error = git_commit_lookup( &commit, aRepo, &head_oid ); error != GIT_OK )
{
wxLogTrace( traceGit, "Failed to lookup commit: %s",
KIGIT_COMMON::GetLastGitError() );
return error;
}
KIGIT::GitCommitPtr commitPtr( commit );
git_reference* branchRef = nullptr;
if( int error = git_branch_create( &branchRef, aRepo, aBranchName.mb_str(), commit, 0 ); error != GIT_OK )
{
wxLogTrace( traceGit, "Failed to create branch: %s",
KIGIT_COMMON::GetLastGitError() );
return error;
}
git_reference_free( branchRef );
return 0;
}
bool PROJECT_GIT_UTILS::RemoveVCS( git_repository*& aRepo, const wxString& aProjectPath,
bool aRemoveGitDir, wxString* aErrors )
{
return GetGitBackend()->RemoveVCS( aRepo, aProjectPath, aRemoveGitDir, aErrors );
}
wxString PROJECT_GIT_UTILS::GetCurrentHash( const wxString& aProjectFile, bool aShort )
{
wxString result = wxT( "no hash" );
git_repository* repo = PROJECT_GIT_UTILS::GetRepositoryForFile( TO_UTF8( aProjectFile ) );
if( repo )
if( aRepo )
{
git_reference* head = nullptr;
if( git_repository_head( &head, repo ) == 0 )
{
const git_oid* oid = git_reference_target( head );
if( oid )
{
char buf[41];
size_t len = aShort ? 8 : 41;
git_oid_tostr( buf, len, oid );
result = wxString::FromUTF8( buf );
}
git_reference_free( head );
}
git_repository_free( repo );
git_repository_free( aRepo );
aRepo = nullptr;
}
return result;
if( aRemoveGitDir )
{
wxFileName gitDir( aProjectPath, wxEmptyString );
gitDir.AppendDir( ".git" );
if( gitDir.DirExists() )
{
wxString errors;
if( !RmDirRecursive( gitDir.GetPath(), &errors ) )
{
if( aErrors )
*aErrors = errors;
wxLogTrace( traceGit, "Failed to remove .git directory: %s", errors );
return false;
}
}
}
wxLogTrace( traceGit, "Successfully removed VCS from project" );
return true;
}
} // namespace KIGIT
} // namespace KIGIT

View File

@ -51,16 +51,6 @@ public:
*/
static int CreateBranch( git_repository* aRepo, const wxString& aBranchName );
/**
* Return the current HEAD commit hash for the repository containing aProjectFile.
*
* @param aProjectFile Absolute path to any file within the repository (typically the
* project file path).
* @param aShort If true, return the short (8 char) hash, otherwise full hash.
* @return wxString containing the hash or "no hash" if unavailable.
*/
static wxString GetCurrentHash( const wxString& aProjectFile, bool aShort );
/**
* Remove version control from a directory by freeing the repository and
* optionally removing the .git directory.

View File

@ -29,7 +29,6 @@
#include <trigo.h>
#include <math/util.h> // for KiROUND
#include <font/font.h>
#include <text_eval/text_eval_wrapper.h>
#include <callback_gal.h>
@ -101,15 +100,8 @@ int GRTextWidth( const wxString& aText, KIFONT::FONT* aFont, const VECTOR2I& aSi
{
if( !aFont )
aFont = KIFONT::FONT::GetFont();
wxString evaluated( aText );
if( evaluated.Contains( wxS( "@{" ) ) )
{
EXPRESSION_EVALUATOR evaluator;
evaluated = evaluator.Evaluate( evaluated );
}
return KiROUND( aFont->StringBoundaryLimits( evaluated, aSize, aThickness, aBold, aItalic,
return KiROUND( aFont->StringBoundaryLimits( aText, aSize, aThickness, aBold, aItalic,
aFontMetrics ).x );
}
@ -122,13 +114,6 @@ void GRPrintText( wxDC* aDC, const VECTOR2I& aPos, const COLOR4D& aColor, const
{
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
bool fill_mode = true;
wxString evaluatedText( aText );
if( evaluatedText.Contains( wxS( "@{" ) ) )
{
EXPRESSION_EVALUATOR evaluator;
evaluatedText = evaluator.Evaluate( evaluatedText );
}
if( !aFont )
aFont = KIFONT::FONT::GetFont();
@ -171,7 +156,7 @@ void GRPrintText( wxDC* aDC, const VECTOR2I& aPos, const COLOR4D& aColor, const
attributes.m_Valign = aV_justify;
attributes.m_Size = aSize;
aFont->Draw( &callback_gal, evaluatedText, aPos, attributes, aFontMetrics );
aFont->Draw( &callback_gal, aText, aPos, attributes, aFontMetrics );
}

View File

@ -40,7 +40,6 @@
#include <wx/txtstrm.h>
#include <wx/wfstream.h>
#include <tool/tool_action.h>
#include <tool/tool_event.h>
/*
@ -160,10 +159,6 @@ static struct hotkey_name_descr hotkeyNameList[] =
#define MODIFIER_CMD_MAC wxT( "Cmd+" )
#define MODIFIER_CTRL_BASE wxT( "Ctrl+" )
#define MODIFIER_SHIFT wxT( "Shift+" )
#define MODIFIER_META wxT( "Meta+" )
#define MODIFIER_WIN wxT( "Win+" )
#define MODIFIER_SUPER wxT( "Super+" )
#define MODIFIER_ALTGR wxT( "AltGr+" )
wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound )
@ -180,14 +175,6 @@ wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound )
return wxString( MODIFIER_SHIFT ).BeforeFirst( '+' );
else if( aKeycode == WXK_ALT )
return wxString( MODIFIER_ALT ).BeforeFirst( '+' );
#ifdef WXK_WINDOWS_LEFT
else if( aKeycode == WXK_WINDOWS_LEFT || aKeycode == WXK_WINDOWS_RIGHT )
return wxString( MODIFIER_WIN ).BeforeFirst( '+' );
#endif
#ifdef WXK_META
else if( aKeycode == WXK_META )
return wxString( MODIFIER_META ).BeforeFirst( '+' );
#endif
// Assume keycode of 0 is "unassigned"
if( (aKeycode & MD_CTRL) != 0 )
@ -199,16 +186,7 @@ wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound )
if( (aKeycode & MD_SHIFT) != 0 )
modifier << MODIFIER_SHIFT;
if( (aKeycode & MD_META) != 0 )
modifier << MODIFIER_META;
if( (aKeycode & MD_SUPER) != 0 )
modifier << MODIFIER_WIN;
if( (aKeycode & MD_ALTGR) != 0 )
modifier << MODIFIER_ALTGR;
aKeycode &= ~MD_MODIFIER_MASK;
aKeycode &= ~( MD_CTRL | MD_ALT | MD_SHIFT );
if( (aKeycode > ' ') && (aKeycode < 0x7F ) )
{
@ -284,7 +262,7 @@ int KeyCodeFromKeyName( const wxString& keyname )
{
int ii, keycode = KEY_NON_FOUND;
// Search for modifiers: Ctrl+ Alt+ Shift+ and others
// Search for modifiers: Ctrl+ Alt+ and Shift+
// Note: on Mac OSX, the Cmd key is equiv here to Ctrl
wxString key = keyname;
wxString prefix;
@ -314,26 +292,6 @@ int KeyCodeFromKeyName( const wxString& keyname )
modifier |= MD_SHIFT;
prefix = MODIFIER_SHIFT;
}
else if( key.StartsWith( MODIFIER_META ) )
{
modifier |= MD_META;
prefix = MODIFIER_META;
}
else if( key.StartsWith( MODIFIER_WIN ) )
{
modifier |= MD_SUPER;
prefix = MODIFIER_WIN;
}
else if( key.StartsWith( MODIFIER_SUPER ) )
{
modifier |= MD_SUPER;
prefix = MODIFIER_SUPER;
}
else if( key.StartsWith( MODIFIER_ALTGR ) )
{
modifier |= MD_ALTGR;
prefix = MODIFIER_ALTGR;
}
else
{
break;

View File

@ -40,7 +40,8 @@ JOB_EXPORT_SCH_BOM::JOB_EXPORT_SCH_BOM() :
m_sortField(),
m_sortAsc( true ),
m_filterString(),
m_excludeDNP( false )
m_excludeDNP( false ),
m_includeExcludedFromBOM( false )
{
m_params.emplace_back( new JOB_PARAM<wxString>( "field_delimiter",
&m_fieldDelimiter,
@ -69,8 +70,13 @@ JOB_EXPORT_SCH_BOM::JOB_EXPORT_SCH_BOM() :
m_fieldsGroupBy ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "sort_field", &m_sortField, m_sortField ) );
m_params.emplace_back( new JOB_PARAM<bool>( "sort_asc", &m_sortAsc, m_sortAsc ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "filter_string", &m_filterString, m_filterString ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "filter_string",
&m_filterString,
m_filterString ) );
m_params.emplace_back( new JOB_PARAM<bool>( "exclude_dnp", &m_excludeDNP, m_excludeDNP ) );
m_params.emplace_back( new JOB_PARAM<bool>( "include_excluded_from_bom",
&m_includeExcludedFromBOM,
m_includeExcludedFromBOM ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "bom_preset_name",
&m_bomPresetName,

View File

@ -55,6 +55,7 @@ public:
bool m_sortAsc;
wxString m_filterString;
bool m_excludeDNP;
bool m_includeExcludedFromBOM;
};
#endif

View File

@ -19,23 +19,11 @@
#include "lib_table_grid_tricks.h"
#include "lib_table_grid.h"
#include <wx/clipbrd.h>
#include <wx/log.h>
LIB_TABLE_GRID_TRICKS::LIB_TABLE_GRID_TRICKS( WX_GRID* aGrid ) :
GRID_TRICKS( aGrid )
{
m_grid->Disconnect( wxEVT_CHAR_HOOK );
m_grid->Connect( wxEVT_CHAR_HOOK, wxCharEventHandler( LIB_TABLE_GRID_TRICKS::onCharHook ), nullptr, this );
}
LIB_TABLE_GRID_TRICKS::LIB_TABLE_GRID_TRICKS( WX_GRID* aGrid,
std::function<void( wxCommandEvent& )> aAddHandler ) :
GRID_TRICKS( aGrid, aAddHandler )
{
m_grid->Disconnect( wxEVT_CHAR_HOOK );
m_grid->Connect( wxEVT_CHAR_HOOK, wxCharEventHandler( LIB_TABLE_GRID_TRICKS::onCharHook ), nullptr, this );
}
@ -146,61 +134,6 @@ void LIB_TABLE_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
GRID_TRICKS::doPopupSelection( event );
}
}
void LIB_TABLE_GRID_TRICKS::onCharHook( wxKeyEvent& ev )
{
if( ev.GetModifiers() == wxMOD_CONTROL && ev.GetKeyCode() == 'V' && m_grid->IsCellEditControlShown() )
{
wxLogNull doNotLog;
if( wxTheClipboard->Open() )
{
if( wxTheClipboard->IsSupported( wxDF_TEXT ) || wxTheClipboard->IsSupported( wxDF_UNICODETEXT ) )
{
wxTextDataObject data;
wxTheClipboard->GetData( data );
wxString text = data.GetText();
if( !text.Contains( '\t' ) && text.Contains( ',' ) )
text.Replace( ',', '\t' );
if( text.Contains( '\t' ) || text.Contains( '\n' ) || text.Contains( '\r' ) )
{
m_grid->CancelPendingChanges();
int row = m_grid->GetGridCursorRow();
// Check if the current row already has data (has a nickname)
wxGridTableBase* table = m_grid->GetTable();
if( table && row >= 0 && row < table->GetNumberRows() )
{
// Check if the row has a nickname (indicating it has existing data)
wxString nickname = table->GetValue( row, COL_NICKNAME );
if( !nickname.IsEmpty() )
{
// Row already has data, don't allow pasting over it
wxTheClipboard->Close();
wxBell(); // Provide audio feedback
return;
}
}
m_grid->ClearSelection();
m_grid->SelectRow( row );
m_grid->SetGridCursor( row, 0 );
getSelectedArea();
paste_text( text );
wxTheClipboard->Close();
m_grid->ForceRefresh();
return;
}
}
wxTheClipboard->Close();
}
}
GRID_TRICKS::onCharHook( ev );
}
bool LIB_TABLE_GRID_TRICKS::handleDoubleClick( wxGridEvent& aEvent )

View File

@ -32,7 +32,6 @@
#include <wx/wupdlock.h>
#include <wx/settings.h>
#include <wx/dc.h>
#include <wx/log.h>
#include <string_utils.h>
@ -309,15 +308,6 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( const wxString& aSearch, bool a
const LIB_TREE_NODE* firstMatch = ShowResults();
#ifdef __WXGTK__
// Ensure the control is repainted with the updated data. Without an explicit
// refresh the Gtk port can display stale rows until the user interacts with
// them, leading to mismatched tree contents.
m_widget->Refresh();
m_widget->Update();
wxYield();
#endif
if( firstMatch )
{
wxDataViewItem item = ToItem( firstMatch );

View File

@ -1160,9 +1160,7 @@ void UOP::Exec( CONTEXT* ctx )
return;
case TR_OP_METHOD_CALL:
if( m_func )
m_func( ctx, m_ref.get() );
m_func( ctx, m_ref.get() );
return;
default:
@ -1323,8 +1321,9 @@ VALUE* UCODE::Run( CONTEXT* ctx )
}
catch(...)
{
// rules which fail outright should not be fired; return 0/false
return ctx->StoreValue( new VALUE( 0 ) );
// rules which fail outright should not be fired
std::unique_ptr<VALUE> temp_false = std::make_unique<VALUE>( 0 );
return ctx->StoreValue( temp_false.get() );
}
if( ctx->SP() == 1 )
@ -1340,7 +1339,8 @@ VALUE* UCODE::Run( CONTEXT* ctx )
wxASSERT( ctx->SP() == 1 );
// non-well-formed rules should not be fired on a release build
return ctx->StoreValue( new VALUE( 0 ) );
std::unique_ptr<VALUE> temp_false = std::make_unique<VALUE>( 0 );
return ctx->StoreValue( temp_false.get() );
}
}

View File

@ -38,7 +38,6 @@
#include <trigo.h>
#include <plotters/plotter.h>
#include <text_eval/text_eval_wrapper.h>
#include <geometry/shape_line_chain.h>
#include <bezier_curves.h>
#include <callback_gal.h>
@ -638,13 +637,6 @@ void PLOTTER::Text( const VECTOR2I& aPos,
void* aData )
{
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
wxString text( aText );
if( text.Contains( wxS( "@{" ) ) )
{
EXPRESSION_EVALUATOR evaluator;
text = evaluator.Evaluate( text );
}
SetColor( aColor );
@ -688,7 +680,7 @@ void PLOTTER::Text( const VECTOR2I& aPos,
if( !aFont )
aFont = KIFONT::FONT::GetFont( m_renderSettings->GetDefaultFont() );
aFont->Draw( &callback_gal, text, aPos, attributes, aFontMetrics );
aFont->Draw( &callback_gal, aText, aPos, attributes, aFontMetrics );
}
@ -701,13 +693,6 @@ void PLOTTER::PlotText( const VECTOR2I& aPos,
void* aData )
{
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
wxString text( aText );
if( text.Contains( wxS( "@{" ) ) )
{
EXPRESSION_EVALUATOR evaluator;
text = evaluator.Evaluate( text );
}
TEXT_ATTRIBUTES attributes = aAttributes;
int penWidth = attributes.m_StrokeWidth;
@ -740,5 +725,5 @@ void PLOTTER::PlotText( const VECTOR2I& aPos,
if( !aFont )
aFont = KIFONT::FONT::GetFont( m_renderSettings->GetDefaultFont() );
aFont->Draw( &callback_gal, text, aPos, attributes, aFontMetrics );
aFont->Draw( &callback_gal, aText, aPos, attributes, aFontMetrics );
}

View File

@ -36,8 +36,6 @@
#include <kiway.h>
#include <lockfile.h>
#include <macros.h>
#include <git/project_git_utils.h>
#include <git2.h>
#include <project.h>
#include <project/project_file.h>
#include <trace_helpers.h>
@ -47,7 +45,6 @@
#include <title_block.h>
PROJECT::PROJECT() :
m_readOnly( false ),
m_textVarsTicker( 0 ),
@ -88,16 +85,6 @@ bool PROJECT::TextVarResolver( wxString* aToken ) const
*aToken = TITLE_BLOCK::GetCurrentDate();
return true;
}
else if( aToken->IsSameAs( wxT( "VCSHASH" ) ) )
{
*aToken = KIGIT::PROJECT_GIT_UTILS::GetCurrentHash( GetProjectFullName(), false );
return true;
}
else if( aToken->IsSameAs( wxT( "VCSSHORTHASH" ) ) )
{
*aToken = KIGIT::PROJECT_GIT_UTILS::GetCurrentHash( GetProjectFullName(), true );
return true;
}
else if( GetTextVars().count( *aToken ) > 0 )
{
*aToken = GetTextVars().at( *aToken );

View File

@ -24,16 +24,6 @@
#include <properties/pg_properties.h>
#include <widgets/color_swatch.h>
#include <widgets/unit_binder.h>
#include <bitmaps.h>
#include <frame_type.h>
#include <kiway_player.h>
#include <kiway.h>
#include <wx/filedlg.h>
#include <wx/intl.h>
#include <eda_doc.h>
#include <wx/button.h>
#include <wx/bmpbuttn.h>
#include <wx/log.h>
@ -41,8 +31,6 @@ const wxString PG_UNIT_EDITOR::EDITOR_NAME = wxS( "KiCadUnitEditor" );
const wxString PG_CHECKBOX_EDITOR::EDITOR_NAME = wxS( "KiCadCheckboxEditor" );
const wxString PG_COLOR_EDITOR::EDITOR_NAME = wxS( "KiCadColorEditor" );
const wxString PG_RATIO_EDITOR::EDITOR_NAME = wxS( "KiCadRatioEditor" );
const wxString PG_FPID_EDITOR::EDITOR_NAME = wxS( "KiCadFpidEditor" );
const wxString PG_URL_EDITOR::EDITOR_NAME = wxS( "KiCadUrlEditor" );
PG_UNIT_EDITOR::PG_UNIT_EDITOR( EDA_DRAW_FRAME* aFrame ) :
@ -63,9 +51,6 @@ PG_UNIT_EDITOR::~PG_UNIT_EDITOR()
wxString PG_UNIT_EDITOR::BuildEditorName( EDA_DRAW_FRAME* aFrame )
{
if( !aFrame )
return EDITOR_NAME + "NoFrame";
return EDITOR_NAME + aFrame->GetName();
}
@ -473,164 +458,3 @@ void PG_RATIO_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl )
"properties!" ) );
}
}
PG_FPID_EDITOR::PG_FPID_EDITOR( EDA_DRAW_FRAME* aFrame ) : m_frame( aFrame )
{
m_editorName = BuildEditorName( aFrame );
}
void PG_FPID_EDITOR::UpdateFrame( EDA_DRAW_FRAME* aFrame )
{
m_frame = aFrame;
m_editorName = BuildEditorName( aFrame );
}
wxString PG_FPID_EDITOR::BuildEditorName( EDA_DRAW_FRAME* aFrame )
{
if( !aFrame )
return EDITOR_NAME + "NoFrame";
return EDITOR_NAME + aFrame->GetName();
}
wxPGWindowList PG_FPID_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
const wxPoint& aPos, const wxSize& aSize ) const
{
wxPGMultiButton* buttons = new wxPGMultiButton( aGrid, aSize );
buttons->Add( KiBitmap( BITMAPS::small_library ) );
buttons->Finalize( aGrid, aPos );
wxSize textSize = buttons->GetPrimarySize();
wxWindow* textCtrl = aGrid->GenerateEditorTextCtrl( aPos, textSize,
aProperty->GetValueAsString(), nullptr, 0,
aProperty->GetMaxLength() );
wxPGWindowList ret( textCtrl, buttons );
return ret;
}
bool PG_FPID_EDITOR::OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl,
wxEvent& aEvent ) const
{
if( aEvent.GetEventType() == wxEVT_BUTTON )
{
wxString fpid = aProperty->GetValue().GetString();
if( KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_frame ) )
{
if( frame->ShowModal( &fpid, m_frame ) )
aGrid->ChangePropertyValue( aProperty, fpid );
frame->Destroy();
}
return true;
}
return wxPGTextCtrlEditor::OnEvent( aGrid, aProperty, aCtrl, aEvent );
}
PG_URL_EDITOR::PG_URL_EDITOR( EDA_DRAW_FRAME* aFrame ) : m_frame( aFrame )
{
m_editorName = BuildEditorName( aFrame );
}
void PG_URL_EDITOR::UpdateFrame( EDA_DRAW_FRAME* aFrame )
{
m_frame = aFrame;
m_editorName = BuildEditorName( aFrame );
}
wxString PG_URL_EDITOR::BuildEditorName( EDA_DRAW_FRAME* aFrame )
{
if( !aFrame )
return EDITOR_NAME + "NoFrame";
return EDITOR_NAME + aFrame->GetName();
}
wxPGWindowList PG_URL_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
const wxPoint& aPos, const wxSize& aSize ) const
{
wxPGMultiButton* buttons = new wxPGMultiButton( aGrid, aSize );
// Use a folder icon when no datasheet is set; otherwise use a globe icon.
wxString urlValue = aProperty->GetValueAsString();
bool hasUrl = !( urlValue.IsEmpty() || urlValue == wxS( "~" ) );
buttons->Add( KiBitmap( hasUrl ? BITMAPS::www : BITMAPS::small_folder ) );
buttons->Finalize( aGrid, aPos );
wxSize textSize = buttons->GetPrimarySize();
wxWindow* textCtrl = aGrid->GenerateEditorTextCtrl( aPos, textSize,
aProperty->GetValueAsString(), nullptr, 0,
aProperty->GetMaxLength() );
wxPGWindowList ret( textCtrl, buttons );
return ret;
}
bool PG_URL_EDITOR::OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl,
wxEvent& aEvent ) const
{
if( aEvent.GetEventType() == wxEVT_BUTTON )
{
wxString filename = aProperty->GetValue().GetString();
if( filename.IsEmpty() || filename == wxS( "~" ) )
{
wxFileDialog openFileDialog( m_frame, _( "Open file" ), wxS( "" ), wxS( "" ),
_( "All Files" ) + wxS( " (*.*)|*.*" ),
wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( openFileDialog.ShowModal() == wxID_OK )
{
filename = openFileDialog.GetPath();
aGrid->ChangePropertyValue( aProperty, wxString::Format( wxS( "file://%s" ),
filename ) );
}
}
else
{
GetAssociatedDocument( m_frame, filename, &m_frame->Prj() );
}
// Update the button icon to reflect presence/absence of URL
if( wxObject* src = aEvent.GetEventObject() )
{
wxString newUrl = aProperty->GetValueAsString();
bool hasUrl = !( newUrl.IsEmpty() || newUrl == wxS( "~" ) );
auto bmp = KiBitmap( hasUrl ? BITMAPS::www : BITMAPS::small_folder );
if( wxWindow* win = wxDynamicCast( src, wxWindow ) )
{
if( wxBitmapButton* bb = wxDynamicCast( win, wxBitmapButton ) )
{
bb->SetBitmap( bmp );
}
else if( wxButton* b = wxDynamicCast( win, wxButton ) )
{
b->SetBitmap( bmp );
}
else if( wxWindow* parent = win->GetParent() )
{
if( wxPGMultiButton* buttons = wxDynamicCast( parent, wxPGMultiButton ) )
{
wxWindow* btn0 = buttons->GetButton( 0 );
if( wxBitmapButton* bb0 = wxDynamicCast( btn0, wxBitmapButton ) )
bb0->SetBitmap( bmp );
else if( wxButton* b0 = wxDynamicCast( btn0, wxButton ) )
b0->SetBitmap( bmp );
}
}
}
}
return true;
}
return wxPGTextCtrlEditor::OnEvent( aGrid, aProperty, aCtrl, aEvent );
}

View File

@ -696,9 +696,7 @@ PGPROPERTY_COLOR4D::PGPROPERTY_COLOR4D( const wxString& aLabel, const wxString&
m_backgroundColor( aBackgroundColor )
{
SetEditor( PG_COLOR_EDITOR::EDITOR_NAME );
#if wxCHECK_VERSION( 3, 3, 1 )
SetFlag( wxPGFlags::NoEditor );
#elif wxCHECK_VERSION( 3, 3, 0 )
#if wxCHECK_VERSION( 3, 3, 0 )
SetFlag( wxPGPropertyFlags::NoEditor );
#else
SetFlag( wxPG_PROP_NOEDITOR );

View File

@ -280,9 +280,6 @@ APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaV
m_params.emplace_back( new PARAM<bool>( "cross_probing.auto_highlight",
&m_CrossProbing.auto_highlight, true ) );
m_params.emplace_back( new PARAM<bool>( "cross_probing.flash_selection",
&m_CrossProbing.flash_selection, false ) );
}

View File

@ -72,7 +72,7 @@ GAL_LAYER_ID RenderLayerFromVisibilityLayer( VISIBILITY_LAYER aLayer )
case VISIBILITY_LAYER::FOOTPRINT_REFERENCES: return LAYER_FP_REFERENCES;
case VISIBILITY_LAYER::FOOTPRINT_TEXT: return LAYER_FP_TEXT;
case VISIBILITY_LAYER::FOOTPRINT_ANCHORS: return LAYER_ANCHOR;
case VISIBILITY_LAYER::LY_POINTS: return LAYER_POINTS;
case VISIBILITY_LAYER::POINTS: return LAYER_POINTS;
case VISIBILITY_LAYER::RATSNEST: return LAYER_RATSNEST;
case VISIBILITY_LAYER::DRC_WARNINGS: return LAYER_DRC_WARNING;
case VISIBILITY_LAYER::DRC_ERRORS: return LAYER_DRC_ERROR;
@ -104,7 +104,7 @@ std::optional<VISIBILITY_LAYER> VisibilityLayerFromRenderLayer( GAL_LAYER_ID aLa
case LAYER_FP_REFERENCES: return VISIBILITY_LAYER::FOOTPRINT_REFERENCES;
case LAYER_FP_TEXT: return VISIBILITY_LAYER::FOOTPRINT_TEXT;
case LAYER_ANCHOR: return VISIBILITY_LAYER::FOOTPRINT_ANCHORS;
case LAYER_POINTS: return VISIBILITY_LAYER::LY_POINTS;
case LAYER_POINTS: return VISIBILITY_LAYER::POINTS;
case LAYER_RATSNEST: return VISIBILITY_LAYER::RATSNEST;
case LAYER_DRC_WARNING: return VISIBILITY_LAYER::DRC_WARNINGS;
case LAYER_DRC_ERROR: return VISIBILITY_LAYER::DRC_ERRORS;

View File

@ -38,7 +38,6 @@
#include <fmt/chrono.h>
#include <wx/log.h>
#include <wx/regex.h>
#include <wx/tokenzr.h>
#include "locale_io.h"
@ -1504,124 +1503,3 @@ wxString NormalizeFileUri( const wxString& aFileUri )
return retv;
}
namespace
{
// Extract (prefix, numericValue) where numericValue = -1 if no numeric suffix
std::pair<wxString, long> ParseAlphaNumericPin( const wxString& pinNum )
{
wxString prefix;
long numValue = -1;
size_t numStart = pinNum.length();
for( int i = static_cast<int>( pinNum.length() ) - 1; i >= 0; --i )
{
if( !wxIsdigit( pinNum[i] ) )
{
numStart = i + 1;
break;
}
if( i == 0 )
numStart = 0; // all digits
}
if( numStart < pinNum.length() )
{
prefix = pinNum.Left( numStart );
wxString numericPart = pinNum.Mid( numStart );
numericPart.ToLong( &numValue );
}
return { prefix, numValue };
}
}
std::vector<wxString> ExpandStackedPinNotation( const wxString& aPinName, bool* aValid )
{
if( aValid )
*aValid = true;
std::vector<wxString> expanded;
const bool hasOpenBracket = aPinName.Contains( wxT( "[" ) );
const bool hasCloseBracket = aPinName.Contains( wxT( "]" ) );
if( hasOpenBracket || hasCloseBracket )
{
if( !aPinName.StartsWith( wxT( "[" ) ) || !aPinName.EndsWith( wxT( "]" ) ) )
{
if( aValid )
*aValid = false;
expanded.push_back( aPinName );
return expanded;
}
}
if( !aPinName.StartsWith( wxT( "[" ) ) || !aPinName.EndsWith( wxT( "]" ) ) )
{
expanded.push_back( aPinName );
return expanded;
}
const wxString inner = aPinName.Mid( 1, aPinName.Length() - 2 );
size_t start = 0;
while( start < inner.length() )
{
size_t comma = inner.find( ',', start );
wxString part = ( comma == wxString::npos ) ? inner.Mid( start ) : inner.Mid( start, comma - start );
part.Trim( true ).Trim( false );
if( part.empty() )
{
start = ( comma == wxString::npos ) ? inner.length() : comma + 1;
continue;
}
int dashPos = part.Find( '-' );
if( dashPos != wxNOT_FOUND )
{
wxString startTxt = part.Left( dashPos );
wxString endTxt = part.Mid( dashPos + 1 );
startTxt.Trim( true ).Trim( false );
endTxt.Trim( true ).Trim( false );
auto [startPrefix, startVal] = ParseAlphaNumericPin( startTxt );
auto [endPrefix, endVal] = ParseAlphaNumericPin( endTxt );
if( startPrefix != endPrefix || startVal == -1 || endVal == -1 || startVal > endVal )
{
if( aValid )
*aValid = false;
expanded.clear();
expanded.push_back( aPinName );
return expanded;
}
for( long ii = startVal; ii <= endVal; ++ii )
{
if( startPrefix.IsEmpty() )
expanded.emplace_back( wxString::Format( wxT( "%ld" ), ii ) );
else
expanded.emplace_back( wxString::Format( wxT( "%s%ld" ), startPrefix, ii ) );
}
}
else
{
expanded.push_back( part );
}
if( comma == wxString::npos )
break;
start = comma + 1;
}
if( expanded.empty() )
{
expanded.push_back( aPinName );
if( aValid )
*aValid = false;
}
return expanded;
}

View File

@ -1,200 +0,0 @@
%include {
#include <text_eval/text_eval_parser.h>
using namespace calc_parser;
}
%token_type {calc_parser::TOKEN_TYPE}
%token_prefix KI_EVAL_
%default_type {calc_parser::NODE*}
%extra_argument {calc_parser::DOC** pDocument}
%type document {calc_parser::DOC*}
%type content_list {calc_parser::DOC*}
%type content_item {calc_parser::NODE*}
%type calculation {calc_parser::NODE*}
%type expression {calc_parser::NODE*}
%type term {calc_parser::NODE*}
%type factor {calc_parser::NODE*}
%type variable {calc_parser::NODE*}
%type function_call {calc_parser::NODE*}
%type arg_list {std::vector<std::unique_ptr<NODE>>*}
%destructor document { delete $$; }
%destructor content_list { delete $$; }
%destructor content_item { delete $$; }
%destructor calculation { delete $$; }
%destructor expression { delete $$; }
%destructor term { delete $$; }
%destructor factor { delete $$; }
%destructor variable { delete $$; }
%destructor function_call { delete $$; }
%destructor arg_list { delete $$; }
%left LT GT LE GE EQ NE.
%left PLUS MINUS.
%left MULTIPLY DIVIDE MODULO.
%right UMINUS.
%right POWER.
%token COMMA.
%start_symbol document
// Main document structure
document(D) ::= content_list(L). {
D = L;
*pDocument = D; // Store the result in the extra argument
}
content_list(L) ::= . {
L = new DOC();
}
content_list(L) ::= content_list(L) content_item(I). {
L->AddNodeRaw(I);
}
content_item(I) ::= TEXT(T). {
I = NODE::CreateTextRaw(GetTokenString(T));
}
content_item(I) ::= calculation(C). {
I = C;
}
content_item(I) ::= variable(V). {
I = NODE::CreateCalcRaw(V);
}
calculation(C) ::= AT_OPEN expression(E) CLOSE_BRACE. {
C = NODE::CreateCalcRaw(E);
}
// Mathematical expressions with proper precedence
expression(E) ::= expression(L) LT expression(R). {
E = NODE::CreateBinOpRaw(L, '<', R);
}
expression(E) ::= expression(L) GT expression(R). {
E = NODE::CreateBinOpRaw(L, '>', R);
}
expression(E) ::= expression(L) LE expression(R). {
E = NODE::CreateBinOpRaw(L, 1, R); // Using 1 for <=
}
expression(E) ::= expression(L) GE expression(R). {
E = NODE::CreateBinOpRaw(L, 2, R); // Using 2 for >=
}
expression(E) ::= expression(L) EQ expression(R). {
E = NODE::CreateBinOpRaw(L, 3, R); // Using 3 for ==
}
expression(E) ::= expression(L) NE expression(R). {
E = NODE::CreateBinOpRaw(L, 4, R); // Using 4 for !=
}
expression(E) ::= expression(L) PLUS expression(R). {
E = NODE::CreateBinOpRaw(L, '+', R);
}
expression(E) ::= expression(L) MINUS expression(R). {
E = NODE::CreateBinOpRaw(L, '-', R);
}
expression(E) ::= term(T). {
E = T;
}
term(T) ::= term(L) MULTIPLY term(R). {
T = NODE::CreateBinOpRaw(L, '*', R);
}
term(T) ::= term(L) DIVIDE term(R). {
T = NODE::CreateBinOpRaw(L, '/', R);
}
term(T) ::= term(L) MODULO term(R). {
T = NODE::CreateBinOpRaw(L, '%', R);
}
term(T) ::= factor(F). {
T = F;
}
factor(F) ::= factor(L) POWER factor(R). {
F = NODE::CreateBinOpRaw(L, '^', R);
}
factor(F) ::= MINUS factor(R). [UMINUS] {
F = NODE::CreateBinOpRaw(NODE::CreateNumberRaw(0.0), '-', R);
}
factor(F) ::= PLUS factor(R). [UMINUS] {
F = R;
}
factor(F) ::= LPAREN expression(E) RPAREN. {
F = E;
}
factor(F) ::= NUMBER(N). {
try
{
F = NODE::CreateNumberRaw( N.isString ? std::stod( GetTokenString( N ) ) : GetTokenDouble( N ) );
}
catch (const std::exception&)
{
if (g_errorCollector)
{
g_errorCollector->AddError( fmt::format( "Invalid number format: {}", GetTokenString( N ) ) );
}
F = NODE::CreateNumberRaw( 0.0 );
}
}
factor(F) ::= STRING(S). {
F = NODE::CreateStringRaw( GetTokenString( S ) );
}
factor(F) ::= variable(V). {
F = V;
}
factor(F) ::= function_call(FC). {
F = FC;
}
function_call(FC) ::= IDENTIFIER(I) LPAREN RPAREN. {
auto empty_args = new std::vector<std::unique_ptr<NODE>>();
FC = NODE::CreateFunctionRaw(GetTokenString(I), empty_args);
}
function_call(FC) ::= IDENTIFIER(I) LPAREN arg_list(AL) RPAREN. {
FC = NODE::CreateFunctionRaw(GetTokenString(I), AL);
}
arg_list(AL) ::= expression(E). {
AL = new std::vector<std::unique_ptr<NODE>>();
AL->emplace_back(std::unique_ptr<NODE>(E));
}
arg_list(AL) ::= arg_list(AL) COMMA expression(E). {
AL->emplace_back(std::unique_ptr<NODE>(E));
}
variable(V) ::= DOLLAR_OPEN IDENTIFIER(I) CLOSE_BRACE. {
V = NODE::CreateVarRaw(GetTokenString(I));
}
%syntax_error {
if (g_errorCollector) {
g_errorCollector->AddSyntaxError();
}
}
%parse_failure {
if (g_errorCollector) {
g_errorCollector->AddParseFailure();
}
}

View File

@ -1,637 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* 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 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/>.
*/
#include <text_eval/text_eval_parser.h>
#include <fmt/format.h>
#include <array>
#include <cctype>
namespace calc_parser
{
thread_local ERROR_COLLECTOR* g_errorCollector = nullptr;
class DATE_UTILS
{
private:
static constexpr int epochYear = 1970;
static constexpr std::array<int, 12> daysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static constexpr std::array<const char*, 12> monthNames = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
};
static constexpr std::array<const char*, 12> monthAbbrev = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
static constexpr std::array<const char*, 7> weekdayNames = {
"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
};
static auto isLeapYear( int aYear ) -> bool
{
return ( aYear % 4 == 0 && aYear % 100 != 0 ) || ( aYear % 400 == 0 );
}
static auto daysInYear( int aYear ) -> int
{
return isLeapYear( aYear ) ? 366 : 365;
}
static auto daysInMonthForYear( int aMonth, int aYear ) -> int
{
if( aMonth == 2 && isLeapYear( aYear ) )
return 29;
return daysInMonth[aMonth - 1];
}
public:
static auto DaysToYmd( int aDaysSinceEpoch ) -> std::tuple<int, int, int>
{
int year = epochYear;
int remainingDays = aDaysSinceEpoch;
if( remainingDays >= 0 )
{
while( remainingDays >= daysInYear( year ) )
{
remainingDays -= daysInYear( year );
year++;
}
}
else
{
while( remainingDays < 0 )
{
year--;
remainingDays += daysInYear( year );
}
}
int month = 1;
while( month <= 12 && remainingDays >= daysInMonthForYear( month, year ) )
{
remainingDays -= daysInMonthForYear( month, year );
month++;
}
int day = remainingDays + 1;
return {year, month, day};
}
static auto YmdToDays( int aYear, int aMonth, int aDay ) -> int
{
int totalDays = 0;
if( aYear >= epochYear )
{
for( int y = epochYear; y < aYear; ++y )
totalDays += daysInYear( y );
}
else
{
for( int y = aYear; y < epochYear; ++y )
totalDays -= daysInYear( y );
}
for( int m = 1; m < aMonth; ++m )
totalDays += daysInMonthForYear( m, aYear );
totalDays += aDay - 1;
return totalDays;
}
static auto ParseDate( const std::string& aDateStr ) -> std::optional<int>
{
std::istringstream iss( aDateStr );
std::string token;
std::vector<int> parts;
char separator = 0;
bool isCjkFormat = false;
// Check for CJK date formats first (Chinese, Korean, or mixed)
bool hasChineseYear = aDateStr.find( "" ) != std::string::npos;
bool hasChineseMonth = aDateStr.find( "" ) != std::string::npos;
bool hasChineseDay = aDateStr.find( "" ) != std::string::npos;
bool hasKoreanYear = aDateStr.find( "" ) != std::string::npos;
bool hasKoreanMonth = aDateStr.find( "" ) != std::string::npos;
bool hasKoreanDay = aDateStr.find( "" ) != std::string::npos;
// Check if we have any CJK date format (pure or mixed)
if( (hasChineseYear || hasKoreanYear) &&
(hasChineseMonth || hasKoreanMonth) &&
(hasChineseDay || hasKoreanDay) )
{
// CJK format: Support pure Chinese, pure Korean, or mixed formats
isCjkFormat = true;
size_t yearPos, monthPos, dayPos;
// Find year position and marker
if( hasChineseYear )
yearPos = aDateStr.find( "" );
else
yearPos = aDateStr.find( "" );
// Find month position and marker
if( hasChineseMonth )
monthPos = aDateStr.find( "" );
else
monthPos = aDateStr.find( "" );
// Find day position and marker
if( hasChineseDay )
dayPos = aDateStr.find( "" );
else
dayPos = aDateStr.find( "" );
try
{
int year = std::stoi( aDateStr.substr( 0, yearPos ) );
int month = std::stoi( aDateStr.substr( yearPos + 3, monthPos - yearPos - 3 ) ); // 3 bytes for CJK year marker
int day = std::stoi( aDateStr.substr( monthPos + 3, dayPos - monthPos - 3 ) ); // 3 bytes for CJK month marker
parts = { year, month, day };
}
catch( ... )
{
return std::nullopt;
}
}
else if( aDateStr.find( '-' ) != std::string::npos )
separator = '-';
else if( aDateStr.find( '/' ) != std::string::npos )
separator = '/';
else if( aDateStr.find( '.' ) != std::string::npos )
separator = '.';
if( separator )
{
while( std::getline( iss, token, separator ) )
{
try
{
parts.push_back( std::stoi( token ) );
}
catch( ... )
{
return std::nullopt;
}
}
}
else if( !isCjkFormat && aDateStr.length() == 8 )
{
try
{
int dateNum = std::stoi( aDateStr );
int year = dateNum / 10000;
int month = ( dateNum / 100 ) % 100;
int day = dateNum % 100;
return YmdToDays( year, month, day );
}
catch( ... )
{
return std::nullopt;
}
}
else if( !isCjkFormat )
{
return std::nullopt;
}
if( parts.empty() || parts.size() > 3 )
return std::nullopt;
int year, month, day;
if( parts.size() == 1 )
{
year = parts[0];
month = 1;
day = 1;
}
else if( parts.size() == 2 )
{
year = parts[0];
month = parts[1];
day = 1;
}
else
{
if( isCjkFormat )
{
// CJK formats are always in YYYY年MM月DD日 or YYYY년 MM월 DD일 order
year = parts[0];
month = parts[1];
day = parts[2];
}
else if( separator == '/' && parts[0] <= 12 && parts[1] <= 31 )
{
month = parts[0];
day = parts[1];
year = parts[2];
}
else if( separator == '/' && parts[1] <= 12 )
{
day = parts[0];
month = parts[1];
year = parts[2];
}
else
{
year = parts[0];
month = parts[1];
day = parts[2];
}
}
if( month < 1 || month > 12 )
return std::nullopt;
if( day < 1 || day > daysInMonthForYear( month, year ) )
return std::nullopt;
return YmdToDays( year, month, day );
}
static auto FormatDate( int aDaysSinceEpoch, const std::string& aFormat ) -> std::string
{
auto [year, month, day] = DaysToYmd( aDaysSinceEpoch );
if( aFormat == "ISO" || aFormat == "iso" )
return fmt::format( "{:04d}-{:02d}-{:02d}", year, month, day );
else if( aFormat == "US" || aFormat == "us" )
return fmt::format( "{:02d}/{:02d}/{:04d}", month, day, year );
else if( aFormat == "EU" || aFormat == "european" )
return fmt::format( "{:02d}/{:02d}/{:04d}", day, month, year );
else if( aFormat == "long" )
return fmt::format( "{} {}, {}", monthNames[month-1], day, year );
else if( aFormat == "short" )
return fmt::format( "{} {}, {}", monthAbbrev[month-1], day, year );
else if( aFormat == "Chinese" || aFormat == "chinese" || aFormat == "CN" || aFormat == "cn" || aFormat == "中文" )
return fmt::format( "{}年{:02d}月{:02d}日", year, month, day );
else if( aFormat == "Japanese" || aFormat == "japanese" || aFormat == "JP" || aFormat == "jp" || aFormat == "日本語" )
return fmt::format( "{}年{:02d}月{:02d}日", year, month, day );
else if( aFormat == "Korean" || aFormat == "korean" || aFormat == "KR" || aFormat == "kr" || aFormat == "한국어" )
return fmt::format( "{}년 {:02d}월 {:02d}일", year, month, day );
else
return fmt::format( "{:04d}-{:02d}-{:02d}", year, month, day );
}
static auto GetWeekdayName( int aDaysSinceEpoch ) -> std::string
{
int weekday = ( ( aDaysSinceEpoch + 3 ) % 7 ); // +3 because epoch was Thursday (Monday = 0)
if( weekday < 0 )
weekday += 7;
return std::string{ weekdayNames[weekday] };
}
static auto GetCurrentDays() -> int
{
auto now = std::chrono::system_clock::now();
auto timeT = std::chrono::system_clock::to_time_t( now );
return static_cast<int>( timeT / ( 24 * 3600 ) );
}
static auto GetCurrentTimestamp() -> double
{
auto now = std::chrono::system_clock::now();
auto timeT = std::chrono::system_clock::to_time_t( now );
return static_cast<double>( timeT );
}
};
EVAL_VISITOR::EVAL_VISITOR( VariableCallback aVariableCallback, ERROR_COLLECTOR& aErrorCollector ) :
m_variableCallback( std::move( aVariableCallback ) ),
m_errors( aErrorCollector ),
m_gen( m_rd() )
{}
auto EVAL_VISITOR::operator()( const NODE& aNode ) const -> Result<Value>
{
switch( aNode.type )
{
case NodeType::Number:
return MakeValue<Value>( std::get<double>( aNode.data ) );
case NodeType::String:
return MakeValue<Value>( std::get<std::string>( aNode.data ) );
case NodeType::Var:
{
const auto& varName = std::get<std::string>( aNode.data );
// Use callback to resolve variable
if( m_variableCallback )
return m_variableCallback( varName );
return MakeError<Value>( fmt::format( "No variable resolver configured for: {}", varName ) );
}
case NodeType::BinOp:
{
const auto& binop = std::get<BIN_OP_DATA>( aNode.data );
auto leftResult = binop.left->Accept( *this );
if( !leftResult )
return leftResult;
auto rightResult = binop.right ?
binop.right->Accept( *this ) : MakeValue<Value>( 0.0 );
if( !rightResult )
return rightResult;
// Special handling for string concatenation with +
if( binop.op == '+' )
{
const auto& leftVal = leftResult.GetValue();
const auto& rightVal = rightResult.GetValue();
// If either operand is a string, concatenate
if( std::holds_alternative<std::string>( leftVal ) ||
std::holds_alternative<std::string>( rightVal ) )
{
return MakeValue<Value>( VALUE_UTILS::ConcatStrings( leftVal, rightVal ) );
}
}
// Otherwise, perform arithmetic
return VALUE_UTILS::ArithmeticOp( leftResult.GetValue(), rightResult.GetValue(), binop.op );
}
case NodeType::Function:
{
const auto& func = std::get<FUNC_DATA>( aNode.data );
return evaluateFunction( func );
}
default:
return MakeError<Value>( "Cannot evaluate this node type" );
}
}
auto EVAL_VISITOR::evaluateFunction( const FUNC_DATA& aFunc ) const -> Result<Value>
{
const auto& name = aFunc.name;
const auto& args = aFunc.args;
// Zero-argument functions
if( args.empty() )
{
if( name == "today" )
return MakeValue<Value>( static_cast<double>( DATE_UTILS::GetCurrentDays() ) );
else if( name == "now" )
return MakeValue<Value>( DATE_UTILS::GetCurrentTimestamp() );
else if( name == "random" )
{
std::uniform_real_distribution<double> dis( 0.0, 1.0 );
return MakeValue<Value>( dis( m_gen ) );
}
}
// Evaluate arguments to mixed types
std::vector<Value> argValues;
argValues.reserve( args.size() );
for( const auto& arg : args )
{
auto result = arg->Accept( *this );
if( !result )
return result;
argValues.push_back( result.GetValue() );
}
const auto argc = argValues.size();
// String formatting functions (return strings!)
if( name == "format" && argc >= 1 )
{
auto numResult = VALUE_UTILS::ToDouble( argValues[0] );
if( !numResult )
return MakeError<Value>( numResult.GetError() );
const auto value = numResult.GetValue();
int decimals = 2;
if( argc > 1 )
{
auto decResult = VALUE_UTILS::ToDouble( argValues[1] );
if( decResult )
decimals = static_cast<int>( decResult.GetValue() );
}
return MakeValue<Value>( fmt::format( "{:.{}f}", value, decimals ) );
}
else if( name == "currency" && argc >= 1 )
{
auto numResult = VALUE_UTILS::ToDouble( argValues[0] );
if( !numResult )
return MakeError<Value>( numResult.GetError() );
const auto amount = numResult.GetValue();
const auto symbol = argc > 1 ? VALUE_UTILS::ToString( argValues[1] ) : "$";
return MakeValue<Value>( fmt::format( "{}{:.2f}", symbol, amount ) );
}
else if( name == "fixed" && argc >= 1 )
{
auto numResult = VALUE_UTILS::ToDouble( argValues[0] );
if( !numResult )
return MakeError<Value>( numResult.GetError() );
const auto value = numResult.GetValue();
int decimals = 2;
if( argc > 1 )
{
auto decResult = VALUE_UTILS::ToDouble( argValues[1] );
if( decResult )
decimals = static_cast<int>( decResult.GetValue() );
}
return MakeValue<Value>( fmt::format( "{:.{}f}", value, decimals ) );
}
// Date formatting functions (return strings!)
else if( name == "dateformat" && argc >= 1 )
{
auto dateResult = VALUE_UTILS::ToDouble( argValues[0] );
if( !dateResult )
return MakeError<Value>( dateResult.GetError() );
const auto days = static_cast<int>( dateResult.GetValue() );
const auto format = argc > 1 ? VALUE_UTILS::ToString( argValues[1] ) : "ISO";
return MakeValue<Value>( DATE_UTILS::FormatDate( days, format ) );
}
else if( name == "datestring" && argc == 1 )
{
auto dateStr = VALUE_UTILS::ToString( argValues[0] );
auto daysResult = DATE_UTILS::ParseDate( dateStr );
if( !daysResult )
return MakeError<Value>( "Invalid date format: " + dateStr );
return MakeValue<Value>( static_cast<double>( daysResult.value() ) );
}
else if( name == "weekdayname" && argc == 1 )
{
auto dateResult = VALUE_UTILS::ToDouble( argValues[0] );
if( !dateResult )
return MakeError<Value>( dateResult.GetError() );
const auto days = static_cast<int>( dateResult.GetValue() );
return MakeValue<Value>( DATE_UTILS::GetWeekdayName( days ) );
}
// String functions (return strings!)
else if( name == "upper" && argc == 1 )
{
auto str = VALUE_UTILS::ToString( argValues[0] );
std::transform( str.begin(), str.end(), str.begin(), ::toupper );
return MakeValue<Value>( str );
}
else if( name == "lower" && argc == 1 )
{
auto str = VALUE_UTILS::ToString( argValues[0] );
std::transform( str.begin(), str.end(), str.begin(), ::tolower );
return MakeValue<Value>( str );
}
else if( name == "concat" && argc >= 2 )
{
std::string result;
for( const auto& val : argValues )
result += VALUE_UTILS::ToString( val );
return MakeValue<Value>( result );
}
// Conditional functions (handle mixed types)
if( name == "if" && argc == 3 )
{
// Convert only the condition to a number
auto conditionResult = VALUE_UTILS::ToDouble( argValues[0] );
if( !conditionResult )
return MakeError<Value>( conditionResult.GetError() );
const auto condition = conditionResult.GetValue() != 0.0;
return MakeValue<Value>( condition ? argValues[1] : argValues[2] );
}
// Mathematical functions (return numbers) - convert args to doubles first
std::vector<double> numArgs;
for( const auto& val : argValues )
{
auto numResult = VALUE_UTILS::ToDouble( val );
if( !numResult )
return MakeError<Value>( numResult.GetError() );
numArgs.push_back( numResult.GetValue() );
}
// Mathematical function implementations
if( name == "abs" && argc == 1 )
return MakeValue<Value>( std::abs( numArgs[0] ) );
else if( name == "sum" && argc >= 1 )
return MakeValue<Value>( std::accumulate( numArgs.begin(), numArgs.end(), 0.0 ) );
else if( name == "round" && argc >= 1 )
{
const auto value = numArgs[0];
const auto precision = argc > 1 ? static_cast<int>( numArgs[1] ) : 0;
const auto multiplier = std::pow( 10.0, precision );
return MakeValue<Value>( std::round( value * multiplier ) / multiplier );
}
else if( name == "sqrt" && argc == 1 )
{
if( numArgs[0] < 0 )
return MakeError<Value>( "Square root of negative number" );
return MakeValue<Value>( std::sqrt( numArgs[0] ) );
}
else if( name == "pow" && argc == 2 )
return MakeValue<Value>( std::pow( numArgs[0], numArgs[1] ) );
else if( name == "floor" && argc == 1 )
return MakeValue<Value>( std::floor( numArgs[0] ) );
else if( name == "ceil" && argc == 1 )
return MakeValue<Value>( std::ceil( numArgs[0] ) );
else if( name == "min" && argc >= 1 )
return MakeValue<Value>( *std::min_element( numArgs.begin(), numArgs.end() ) );
else if( name == "max" && argc >= 1 )
return MakeValue<Value>( *std::max_element( numArgs.begin(), numArgs.end() ) );
else if( name == "avg" && argc >= 1 )
{
const auto sum = std::accumulate( numArgs.begin(), numArgs.end(), 0.0 );
return MakeValue<Value>( sum / static_cast<double>( argc ) );
}
return MakeError<Value>( fmt::format( "Unknown function: {} with {} arguments", name, argc ) );
}
auto DOC_PROCESSOR::Process( const DOC& aDoc, VariableCallback aVariableCallback )
-> std::pair<std::string, bool>
{
std::string result;
auto localErrors = ERROR_COLLECTOR{};
EVAL_VISITOR evaluator{ std::move( aVariableCallback ), localErrors };
bool hadErrors = aDoc.HasErrors();
for( const auto& node : aDoc.GetNodes() )
{
switch( node->type )
{
case NodeType::Text:
result += std::get<std::string>( node->data );
break;
case NodeType::Calc:
{
const auto& calcData = std::get<BIN_OP_DATA>( node->data );
auto evalResult = calcData.left->Accept( evaluator );
if( evalResult )
result += VALUE_UTILS::ToString( evalResult.GetValue() );
else
{
// Don't add error formatting to result - errors go to error vector only
// The higher level will return original input unchanged if there are errors
hadErrors = true;
}
break;
}
default:
result += "[Unknown node type]";
hadErrors = true;
break;
}
}
return { std::move( result ), hadErrors || localErrors.HasErrors() };
}
auto DOC_PROCESSOR::ProcessWithDetails( const DOC& aDoc, VariableCallback aVariableCallback )
-> std::tuple<std::string, std::vector<std::string>, bool>
{
auto [result, hadErrors] = Process( aDoc, std::move( aVariableCallback ) );
auto allErrors = aDoc.GetErrors();
return { std::move( result ), std::move( allErrors ), hadErrors };
}
} // namespace calc_parser

File diff suppressed because it is too large Load Diff

View File

@ -953,17 +953,17 @@ TOOL_ACTION ACTIONS::unpinLibrary( TOOL_ACTION_ARGS()
.FriendlyName( _( "Unpin Library" ) )
.Tooltip( _( "No longer keep the library at the top of the list" ) ) );
TOOL_ACTION ACTIONS::showLibraryFieldsTable( TOOL_ACTION_ARGS()
.Name( "common.Control.showLibraryFieldsTable" )
TOOL_ACTION ACTIONS::showLibraryTable( TOOL_ACTION_ARGS()
.Name( "common.Control.showLibraryTable" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Library Fields Table" ) )
.FriendlyName( _( "Library Table" ) )
.Icon( BITMAPS::table ) );
TOOL_ACTION ACTIONS::showRelatedLibraryFieldsTable( TOOL_ACTION_ARGS()
.Name( "common.Control.showRelatedLibraryFieldsTable" )
TOOL_ACTION ACTIONS::showRelatedLibraryTable( TOOL_ACTION_ARGS()
.Name( "common.Control.showRelatedLibraryTable" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Library Fields Table of Related Symbols" ) )
.Tooltip( _( "Edit a table of fields of all symbols related to the selected symbol" ) )
.FriendlyName( _( "Edit Related Symbols as Table" ) )
.Tooltip( _( "Edit all symbols related to the selected symbol in a table" ) )
.Icon( BITMAPS::table ) );
TOOL_ACTION ACTIONS::showLibraryTree( TOOL_ACTION_ARGS()

View File

@ -61,8 +61,11 @@ EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation, KIGFX::VIEW *aVie
if( m_allowPoints )
{
for( EDIT_POINT& point : m_points )
// Check from the end so that we get the topmost point
for( auto r_it = m_points.rbegin(); r_it != m_points.rend(); ++r_it )
{
EDIT_POINT& point = *r_it;
if( point.WithinPoint( aLocation, size ) )
return &point;
}

View File

@ -158,43 +158,6 @@ TOOL_DISPATCHER::~TOOL_DISPATCHER()
delete st;
}
int TOOL_DISPATCHER::decodeModifiers( const wxKeyboardState* aState )
{
int mods = 0;
int wxmods = aState->GetModifiers();
// Returns the state of key modifiers (Alt, Ctrl and so on). Be carefull:
// the flag wxMOD_ALTGR is defined in wxWidgets as wxMOD_CONTROL|wxMOD_ALT
// So AltGr key cannot used as modifier key because it is the same as Alt key + Ctrl key.
#if CAN_USE_ALTGR_KEY
if( wxmods & wxMOD_ALTGR )
mods |= MD_ALTGR;
else
#endif
{
if( wxmods & wxMOD_CONTROL )
mods |= MD_CTRL;
if( wxmods & wxMOD_ALT )
mods |= MD_ALT;
}
if( wxmods & wxMOD_SHIFT )
mods |= MD_SHIFT;
#ifdef wxMOD_META
if( wxmods & wxMOD_META )
mods |= MD_META;
#endif
#ifdef wxMOD_WIN
if( wxmods & wxMOD_WIN )
mods |= MD_SUPER;
#endif
return mods;
}
void TOOL_DISPATCHER::ResetState()
{
@ -334,19 +297,7 @@ static bool isKeyModifierOnly( int aKeyCode )
{
static std::vector<enum wxKeyCode> special_keys =
{
WXK_CONTROL, WXK_RAW_CONTROL, WXK_SHIFT, WXK_ALT,
#ifdef WXK_WINDOWS_LEFT
WXK_WINDOWS_LEFT, WXK_WINDOWS_RIGHT,
#endif
#ifdef WXK_MENU
WXK_MENU,
#endif
#ifdef WXK_COMMAND
WXK_COMMAND,
#endif
#ifdef WXK_META
WXK_META,
#endif
WXK_CONTROL, WXK_RAW_CONTROL, WXK_SHIFT, WXK_ALT
};
return alg::contains( special_keys, aKeyCode );
@ -564,7 +515,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
if( !evt && me->GetWheelRotation() != 0 )
{
const unsigned modBits =
static_cast<unsigned>( mods ) & MD_MODIFIER_MASK;
static_cast<unsigned>( mods ) & ( MD_CTRL | MD_ALT | MD_SHIFT );
const bool shouldHandle = std::popcount( modBits ) > 1;
if( shouldHandle )

View File

@ -149,9 +149,6 @@ const std::string TOOL_EVENT::Format() const
{ MD_SHIFT, "shift" },
{ MD_CTRL, "ctrl" },
{ MD_ALT, "alt" },
{ MD_SUPER, "super" },
{ MD_META, "meta" },
{ MD_ALTGR, "altgr" },
{ 0, "" }
};

View File

@ -19,225 +19,54 @@
#include <widgets/font_choice.h>
#include <kiplatform/ui.h>
#include <wx/fontenum.h>
#include <font/fontconfig.h>
#include <pgm_base.h>
#include <wx/dc.h>
#include <wx/event.h>
#include <wx/fontenum.h>
#include <wx/settings.h>
#include <wx/textctrl.h>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <chrono>
#include <algorithm>
#include <cwctype>
// The "official" name of the building Kicad stroke font (always existing)
#include <font/kicad_font_name.h>
class FONT_LIST_MANAGER : public wxEvtHandler
FONT_CHOICE::FONT_CHOICE( wxWindow* aParent, int aId, wxPoint aPosition, wxSize aSize,
int nChoices, wxString* aChoices, int aStyle ) :
wxChoice( aParent, aId, aPosition, aSize, nChoices, aChoices, aStyle )
{
public:
static FONT_LIST_MANAGER& Get();
wxArrayString GetFonts() const;
void Register( FONT_CHOICE* aCtrl );
void Unregister( FONT_CHOICE* aCtrl );
m_systemFontCount = wxChoice::GetCount();
private:
FONT_LIST_MANAGER();
~FONT_LIST_MANAGER();
void Poll();
void UpdateFonts();
std::thread m_thread;
mutable std::mutex m_mutex;
std::condition_variable m_cv;
wxArrayString m_fonts;
std::vector<FONT_CHOICE*> m_controls;
std::atomic<bool> m_quit;
};
FONT_LIST_MANAGER& FONT_LIST_MANAGER::Get()
{
static FONT_LIST_MANAGER mgr;
return mgr;
}
wxArrayString FONT_LIST_MANAGER::GetFonts() const
{
std::lock_guard<std::mutex> lock( m_mutex );
return m_fonts;
}
void FONT_LIST_MANAGER::Register( FONT_CHOICE* aCtrl )
{
std::lock_guard<std::mutex> lock( m_mutex );
m_controls.push_back( aCtrl );
}
void FONT_LIST_MANAGER::Unregister( FONT_CHOICE* aCtrl )
{
std::lock_guard<std::mutex> lock( m_mutex );
auto it = std::find( m_controls.begin(), m_controls.end(), aCtrl );
if( it != m_controls.end() )
m_controls.erase( it );
}
FONT_LIST_MANAGER::FONT_LIST_MANAGER()
{
m_quit = false;
UpdateFonts();
// It appears that the polling mechanism does not work correctly
// for mingw (hangs on exit)
#ifndef __MINGW32__
m_thread = std::thread( &FONT_LIST_MANAGER::Poll, this );
#endif
}
FONT_LIST_MANAGER::~FONT_LIST_MANAGER()
{
{
std::lock_guard<std::mutex> lock( m_mutex );
m_quit = true;
}
#ifndef __MINGW32__
m_cv.notify_one();
if( m_thread.joinable() )
m_thread.join();
#endif
}
void FONT_LIST_MANAGER::Poll()
{
std::unique_lock<std::mutex> lock( m_mutex );
while( !m_quit )
{
// N.B. wait_for will unlock the mutex while waiting but lock it before continuing
// so we need to relock before continuing in the loop
m_cv.wait_for( lock, std::chrono::seconds( 30 ), [&] { return m_quit.load(); } );
if( !m_quit )
{
lock.unlock();
UpdateFonts();
lock.lock();
}
}
}
void FONT_LIST_MANAGER::UpdateFonts()
{
std::vector<std::string> fontNames;
Fontconfig()->ListFonts( fontNames, std::string( Pgm().GetLanguageTag().utf8_str() ) );
wxArrayString menuList;
// The initial list of fonts has on top 1 or 2 options
// only "KiCad Font" (KICAD_FONT_NAME)
// "Default Font" and "KiCad Font" (KICAD_FONT_NAME)
// "KiCad Font" is also a keyword, and cannot be translated.
// So rebuilt the starting list
wxChoice::Clear();
if( m_systemFontCount > 1 )
Append( _( "Default Font" ) );
Append( KICAD_FONT_NAME );
m_systemFontCount = wxChoice::GetCount();
for( const std::string& name : fontNames )
menuList.Add( wxString( name ) );
menuList.Sort();
// Check if fonts changed and update controls
{
std::lock_guard<std::mutex> lock( m_mutex );
Freeze();
Append( menuList );
KIPLATFORM::UI::LargeChoiceBoxHack( this );
Thaw();
if( menuList == m_fonts )
return;
m_fonts = menuList;
}
CallAfter( [this]() {
std::vector<FONT_CHOICE*> controlsCopy;
// Copy controls list under lock protection
{
std::lock_guard<std::mutex> lock( m_mutex );
controlsCopy = m_controls;
}
// Update controls without holding lock
for( FONT_CHOICE* ctrl : controlsCopy )
{
if( ctrl && !ctrl->IsShownOnScreen() )
ctrl->RefreshFonts();
}
} );
}
FONT_CHOICE::FONT_CHOICE( wxWindow* aParent, int aId, wxPoint aPosition, wxSize aSize,
int nChoices, wxString* aChoices, int aStyle ) :
wxOwnerDrawnComboBox( aParent, aId, wxEmptyString, aPosition, aSize, 0, nullptr, aStyle )
{
m_systemFontCount = nChoices;
m_notFound = wxS( " " ) + _( "<not found>" );
m_isFiltered = false;
m_lastText = wxEmptyString;
m_originalSelection = wxEmptyString;
FONT_LIST_MANAGER::Get().Register( this );
RefreshFonts();
// Bind only essential events to restore functionality
Bind( wxEVT_KEY_DOWN, &FONT_CHOICE::OnKeyDown, this );
Bind( wxEVT_CHAR_HOOK, &FONT_CHOICE::OnCharHook, this );
Bind( wxEVT_COMMAND_TEXT_UPDATED, &FONT_CHOICE::OnTextCtrl, this );
Bind( wxEVT_COMBOBOX_DROPDOWN, &FONT_CHOICE::OnDropDown, this );
Bind( wxEVT_COMBOBOX_CLOSEUP, &FONT_CHOICE::OnCloseUp, this );
Bind( wxEVT_SET_FOCUS, &FONT_CHOICE::OnSetFocus, this );
Bind( wxEVT_KILL_FOCUS, &FONT_CHOICE::OnKillFocus, this );
}
FONT_CHOICE::~FONT_CHOICE()
{
FONT_LIST_MANAGER::Get().Unregister( this );
}
void FONT_CHOICE::RefreshFonts()
{
wxArrayString menuList = FONT_LIST_MANAGER::Get().GetFonts();
wxString selection = GetValue();
// Store the full font list for filtering
m_fullFontList.Clear();
if( m_systemFontCount > 1 )
m_fullFontList.Add( _( "Default Font" ) );
m_fullFontList.Add( KICAD_FONT_NAME );
for( const wxString& font : menuList )
m_fullFontList.Add( font );
Freeze();
Clear();
if( m_systemFontCount > 1 )
Append( _( "Default Font" ) );
Append( KICAD_FONT_NAME );
m_systemFontCount = GetCount();
Append( menuList );
if( !selection.IsEmpty() )
SetStringSelection( selection );
m_isFiltered = false;
Thaw();
}
@ -257,6 +86,9 @@ void FONT_CHOICE::SetFontSelection( KIFONT::FONT* aFont, bool aSilentMode )
SetSelection( GetCount() - 1 );
}
}
if( !aSilentMode )
SendSelectionChangedEvent( wxEVT_CHOICE );
}
@ -286,602 +118,8 @@ KIFONT::FONT* FONT_CHOICE::GetFontSelection( bool aBold, bool aItalic, bool aFor
}
else
{
return KIFONT::FONT::GetFont( GetValue(), aBold, aItalic, nullptr,
return KIFONT::FONT::GetFont( GetStringSelection(), aBold, aItalic, nullptr,
aForDrawingSheet );
}
}
void FONT_CHOICE::OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const
{
if( item == wxNOT_FOUND )
return;
wxString name = GetString( item );
dc.SetFont( wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ) );
dc.DrawText( name, rect.x + 2, rect.y + 2 );
if( item >= m_systemFontCount )
{
wxCoord w, h;
dc.GetTextExtent( name, &w, &h );
wxFont sampleFont( wxFontInfo( dc.GetFont().GetPointSize() ).FaceName( name ) );
dc.SetFont( sampleFont );
dc.SetTextForeground( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
dc.DrawText( wxS( "AaBbCcDd123456" ), rect.x + w + 15, rect.y + 2 );
}
}
wxString FONT_CHOICE::GetStringSelection() const
{
return GetValue();
}
void FONT_CHOICE::OnKeyDown( wxKeyEvent& aEvent )
{
int keyCode = aEvent.GetKeyCode();
if( keyCode == WXK_RETURN || keyCode == WXK_NUMPAD_ENTER || keyCode == WXK_ESCAPE )
{
if( IsPopupShown() )
{
// Accept current text and close popup
Dismiss();
return;
}
}
else if( keyCode == WXK_BACK && !IsPopupShown() )
{
// Handle backspace when popup is not shown
// This allows normal character-by-character deletion instead of selecting all text
wxString currentText = GetValue();
long selStart, selEnd;
GetSelection( &selStart, &selEnd );
if( selStart != selEnd )
{
// There's a selection - delete the selected text
wxString newText = currentText.Left( selStart ) + currentText.Mid( selEnd );
m_lastText = newText; // Prevent recursive calls
ChangeValue( newText );
SetInsertionPoint( selStart );
return; // Don't skip this event
}
else if( selStart > 0 )
{
// No selection - delete character before cursor
wxString newText = currentText.Left( selStart - 1 ) + currentText.Mid( selStart );
m_lastText = newText; // Prevent recursive calls
ChangeValue( newText );
SetInsertionPoint( selStart - 1 );
return; // Don't skip this event
}
// If at beginning of text, let default behavior handle it
}
aEvent.Skip();
}
void FONT_CHOICE::OnCharHook( wxKeyEvent& aEvent )
{
int keyCode = aEvent.GetUnicodeKey();
wchar_t wc = static_cast<wchar_t>( keyCode );
// When popup is not shown, let normal text processing handle printable characters
// The OnTextCtrl method will handle filtering and autocomplete
if( !IsPopupShown() )
{
aEvent.Skip();
return;
}
if( std::iswprint( wc ) && !std::iswcntrl( wc ) )
{
// Get current text and check if there's a selection
wxString currentText = GetValue();
long selStart, selEnd;
GetSelection( &selStart, &selEnd );
wxChar newChar = (wxChar)keyCode;
wxString newText;
if( selStart != selEnd )
{
// There's a selection - replace it with the new character
newText = currentText.Left( selStart ) + newChar + currentText.Mid( selEnd );
}
else
{
// No selection - append to current insertion point
long insertionPoint = GetInsertionPoint();
newText = currentText.Left( insertionPoint ) + newChar + currentText.Mid( insertionPoint );
}
// Update the text control
m_lastText = newText; // Prevent recursive calls
ChangeValue( newText );
SetInsertionPoint( selStart + 1 ); // Position cursor after new character
// Filter the font list based on new text (will handle trimming internally)
FilterFontList( newText );
// Try autocomplete
DoAutoComplete( newText );
return; // Don't skip this event
}
switch (keyCode)
{
case WXK_BACK:
{
wxString currentText = GetValue();
long selStart, selEnd;
GetSelection( &selStart, &selEnd );
wxString newText;
long newInsertionPoint;
if( selStart != selEnd )
{
// There's a selection - delete the selected text
newText = currentText.Left( selStart ) + currentText.Mid( selEnd );
newInsertionPoint = selStart;
}
else if( selStart > 0 )
{
// No selection - delete character before cursor
newText = currentText.Left( selStart - 1 ) + currentText.Mid( selStart );
newInsertionPoint = selStart - 1;
}
else
{
return; // At beginning, can't delete
}
m_lastText = newText; // Prevent recursive calls
ChangeValue( newText );
SetInsertionPoint( newInsertionPoint );
// Check if trimmed text is empty
wxString trimmedNewText = newText;
trimmedNewText.Trim().Trim( false );
if( trimmedNewText.IsEmpty() )
{
RestoreFullFontList();
}
else
{
FilterFontList( newText );
// Don't call DoAutoComplete for backspace to avoid the loop
}
return; // Don't skip this event
}
case WXK_RETURN:
case WXK_NUMPAD_ENTER:
{
Dismiss();
return;
}
break;
case WXK_ESCAPE:
{
// Restore to original selection or default font if original doesn't exist
if( !m_originalSelection.IsEmpty() && FindBestMatch( m_originalSelection ) != wxNOT_FOUND )
{
SetStringSelection( m_originalSelection );
m_lastText = m_originalSelection;
}
else
{
// Original font doesn't exist anymore, select default font
wxString defaultFont = GetDefaultFontName();
SetStringSelection( defaultFont );
m_lastText = defaultFont;
}
// Restore full font list if filtered
if( m_isFiltered )
{
RestoreFullFontList();
}
// Only dismiss if popup is actually shown
if( IsPopupShown() )
{
Dismiss();
}
return;
}
default:
break;
}
aEvent.Skip();
}
void FONT_CHOICE::OnTextCtrl( wxCommandEvent& aEvent )
{
wxString currentText = GetValue();
// Avoid recursive calls
if( currentText == m_lastText )
{
aEvent.Skip();
return;
}
m_lastText = currentText;
// If popup is shown, OnCharHook handles the text input, so just skip
if( IsPopupShown() )
{
aEvent.Skip();
return;
}
// Trim whitespace for processing
wxString trimmedText = currentText;
trimmedText.Trim().Trim(false);
// If text is empty or all whitespace, restore full list
if( trimmedText.IsEmpty() )
{
RestoreFullFontList();
aEvent.Skip();
return;
}
// Filter the font list based on the text input
FilterFontList( currentText );
// Try to find a match for autocomplete (only when popup is not shown)
int bestMatch = FindBestMatch( trimmedText );
if( bestMatch != wxNOT_FOUND )
{
DoAutoComplete( trimmedText );
}
aEvent.Skip();
}
void FONT_CHOICE::OnDropDown( wxCommandEvent& aEvent )
{
// Store the original selection when dropdown opens
m_originalSelection = GetValue();
aEvent.Skip();
}
void FONT_CHOICE::OnCloseUp( wxCommandEvent& aEvent )
{
// When dropdown closes, we should only restore the full font list
// but NOT change the current text value unless explicitly selected
// The OnKillFocus handler will handle text validation when focus is lost
// Reset to full font list if filtered
if( m_isFiltered )
{
RestoreFullFontList();
}
aEvent.Skip();
}
void FONT_CHOICE::OnSetFocus( wxFocusEvent& aEvent )
{
// When the control gains focus, select all text so user can quickly replace it
// Only do this if we're not already showing the popup (which would indicate
// the user is actively interacting with the dropdown)
if( !GetValue().IsEmpty() && !IsPopupShown() )
{
// Use CallAfter to ensure the focus event is fully processed first
CallAfter( [this]() {
if( HasFocus() && !IsPopupShown() )
SelectAll();
} );
}
aEvent.Skip();
}
void FONT_CHOICE::OnKillFocus( wxFocusEvent& aEvent )
{
// When losing focus, deselect text and validate/correct the font name
// First, deselect any selected text
if( GetInsertionPoint() != GetLastPosition() )
{
SetInsertionPointEnd();
}
// Get current text and trim whitespace
wxString currentText = GetValue();
currentText.Trim().Trim(false);
// If text is empty, set to default font
if( currentText.IsEmpty() )
{
wxString defaultFont = GetDefaultFontName();
SetStringSelection( defaultFont );
m_lastText = defaultFont;
aEvent.Skip();
return;
}
// Try to find exact match first
if( FindBestMatch( currentText ) != wxNOT_FOUND )
{
// Exact match found, keep the current text but ensure it's properly set
SetStringSelection( currentText );
m_lastText = currentText;
aEvent.Skip();
return;
}
// No exact match, try to find best partial match
wxString partialMatch = FindBestPartialMatch( currentText );
if( !partialMatch.IsEmpty() )
{
SetStringSelection( partialMatch );
m_lastText = partialMatch;
}
else
{
// No decent partial match, fall back to default font
wxString defaultFont = GetDefaultFontName();
SetStringSelection( defaultFont );
m_lastText = defaultFont;
}
// Ensure we restore full font list if it was filtered
if( m_isFiltered )
{
RestoreFullFontList();
}
aEvent.Skip();
}
void FONT_CHOICE::DoAutoComplete( const wxString& aText )
{
if( aText.IsEmpty() )
return;
// Find the best matching font
int bestMatch = FindBestMatch( aText );
if( bestMatch == wxNOT_FOUND )
return;
wxString matchText = GetString( bestMatch );
// Only do autocomplete if the match is longer than what we typed
if( matchText.Length() > aText.Length() && matchText.Lower().StartsWith( aText.Lower() ) )
{
// Set the text with the autocompleted portion selected
m_lastText = matchText; // Update to prevent recursive calls
ChangeValue( matchText );
SetInsertionPoint( aText.Length() );
SetSelection( aText.Length(), matchText.Length() );
if( IsPopupShown() )
{
SetSelection( bestMatch );
}
}
}
void FONT_CHOICE::FilterFontList( const wxString& aFilter )
{
// Trim whitespace from filter
wxString trimmedFilter = aFilter;
trimmedFilter.Trim().Trim(false);
if( trimmedFilter.IsEmpty() )
{
RestoreFullFontList();
return;
}
wxArrayString filteredList;
// Add system fonts first
for( int i = 0; i < m_systemFontCount; i++ )
{
wxString fontName = m_fullFontList[i];
if( fontName.Lower().StartsWith( trimmedFilter.Lower() ) )
filteredList.Add( fontName );
}
// Add matching fonts from the full list
for( size_t i = m_systemFontCount; i < m_fullFontList.GetCount(); i++ )
{
wxString fontName = m_fullFontList[i];
if( fontName.Lower().StartsWith( trimmedFilter.Lower() ) )
filteredList.Add( fontName );
}
// Preserve the current text value
wxString currentText = GetValue();
// Check if we had items before and now have none - this indicates we need to force refresh
bool hadItemsBefore = GetCount() > 0;
bool haveItemsNow = filteredList.GetCount() > 0;
bool needsPopupRefresh = hadItemsBefore && !haveItemsNow && IsPopupShown();
// Update the combo box with filtered list (even if empty)
Freeze();
Clear();
if( haveItemsNow )
{
Append( filteredList );
}
// If no matches, leave the dropdown empty
m_isFiltered = true;
// Restore the text value after filtering
if( !currentText.IsEmpty() )
{
ChangeValue( currentText );
SetInsertionPointEnd();
}
Thaw();
// Handle popup display
if( needsPopupRefresh )
{
// We had items before but now have none - dismiss the popup
Dismiss();
}
else if( !IsPopupShown() && haveItemsNow )
{
// Only show popup if we have items to display and control has focus
// This prevents popup from showing during programmatic text changes
if( HasFocus() )
{
Popup();
}
}
else if( IsPopupShown() && !haveItemsNow )
{
// If popup is shown but we have no items, dismiss it
Dismiss();
}
// Force a refresh to ensure the popup displays correctly only if it's shown and has items
if( IsPopupShown() && haveItemsNow )
{
Update();
Refresh();
}
}
void FONT_CHOICE::RestoreFullFontList()
{
if( !m_isFiltered )
return;
wxString selection = GetValue();
Freeze();
Clear();
Append( m_fullFontList );
m_isFiltered = false;
if( !selection.IsEmpty() )
{
ChangeValue( selection );
SetInsertionPointEnd();
}
Thaw();
}
int FONT_CHOICE::FindBestMatch( const wxString& aText )
{
if( aText.IsEmpty() )
return wxNOT_FOUND;
// Trim whitespace from search text
wxString trimmedText = aText;
trimmedText.Trim().Trim(false);
if( trimmedText.IsEmpty() )
return wxNOT_FOUND;
wxString lowerText = trimmedText.Lower();
// Search in the full font list to find matches, then map to current list
for( size_t i = 0; i < m_fullFontList.GetCount(); i++ )
{
wxString itemText = m_fullFontList[i].Lower();
if( itemText.StartsWith( lowerText ) )
{
// Find this font in the current displayed list
wxString fullFontName = m_fullFontList[i];
for( unsigned int j = 0; j < GetCount(); j++ )
{
if( GetString( j ) == fullFontName )
return j;
}
}
}
return wxNOT_FOUND;
}
wxString FONT_CHOICE::FindBestPartialMatch( const wxString& aText )
{
if( aText.IsEmpty() )
return wxEmptyString;
// Trim whitespace from search text
wxString trimmedText = aText;
trimmedText.Trim().Trim(false);
if( trimmedText.IsEmpty() )
return wxEmptyString;
wxString testText = trimmedText;
// Try progressively shorter versions of the text by removing characters from the end
// Don't go below a minimum length of 2 characters for meaningful partial matches
while( testText.Length() >= 2 )
{
wxString lowerTestText = testText.Lower();
// Search in the full font list for a match
for( size_t i = 0; i < m_fullFontList.GetCount(); i++ )
{
wxString itemText = m_fullFontList[i].Lower();
if( itemText.StartsWith( lowerTestText ) )
{
// Found a match, return the full font name
return m_fullFontList[i];
}
}
// Remove the last character and try again
testText = testText.Left( testText.Length() - 1 );
}
// No decent partial match found (need at least 2 characters for a meaningful match)
return wxEmptyString;
}
wxString FONT_CHOICE::GetDefaultFontName() const
{
// Return KiCad font name as the default
return KICAD_FONT_NAME;
}

View File

@ -640,36 +640,15 @@ void LIB_TREE::onQueryCharHook( wxKeyEvent& aKeyStroke )
{
int hotkey = aKeyStroke.GetKeyCode();
int mods = aKeyStroke.GetModifiers();
if( aKeyStroke.GetModifiers() & wxMOD_CONTROL )
hotkey += MD_CTRL;
// the flag wxMOD_ALTGR is defined in wxWidgets as wxMOD_CONTROL|wxMOD_ALT
// So AltGr key cannot used as modifier key because it is the same as Alt key + Ctrl key.
#if CAN_USE_ALTGR_KEY
if( wxmods & wxMOD_ALTGR )
mods |= MD_ALTGR;
else
#endif
{
if( mods & wxMOD_CONTROL )
hotkey += MD_CTRL;
if( aKeyStroke.GetModifiers() & wxMOD_ALT )
hotkey += MD_ALT;
if( mods & wxMOD_ALT )
hotkey += MD_ALT;
}
if( mods & wxMOD_SHIFT )
if( aKeyStroke.GetModifiers() & wxMOD_SHIFT )
hotkey += MD_SHIFT;
#ifdef wxMOD_META
if( mods & wxMOD_META )
hotkey += MD_META;
#endif
#ifdef wxMOD_WIN
if( mods & wxMOD_WIN )
hotkey += MD_SUPER;
#endif
if( hotkey == ACTIONS::expandAll.GetHotKey()
|| hotkey == ACTIONS::expandAll.GetHotKeyAlt() )
{
@ -881,31 +860,14 @@ void LIB_TREE::onTreeCharHook( wxKeyEvent& aKeyStroke )
{
int hotkey = aKeyStroke.GetKeyCode();
int mods = aKeyStroke.GetModifiers();
if( mods & wxMOD_ALTGR )
hotkey |= MD_ALTGR;
else
{
if( mods & wxMOD_ALT )
hotkey |= MD_ALT;
if( mods & wxMOD_CONTROL )
hotkey |= MD_CTRL;
}
if( mods & wxMOD_SHIFT )
if( aKeyStroke.ShiftDown() )
hotkey |= MD_SHIFT;
#ifdef wxMOD_META
if( mods & wxMOD_META )
hotkey |= MD_META;
#endif
if( aKeyStroke.AltDown() )
hotkey |= MD_ALT;
#ifdef wxMOD_WIN
if( mods & wxMOD_WIN )
hotkey |= MD_SUPER;
#endif
if( aKeyStroke.ControlDown() )
hotkey |= MD_CTRL;
if( tool->GetManager()->GetActionManager()->RunHotKey( hotkey ) )
aKeyStroke.Skip( false );

View File

@ -235,11 +235,7 @@ void UNIT_BINDER::onComboBox( wxCommandEvent& aEvent )
const wxString value = combo->GetStringSelection();
const long long int conv = ValueFromString( *m_iuScale, m_units, value, m_dataType );
CallAfter(
[this, conv]
{
SetValue( conv );
} );
SetValue( conv );
aEvent.Skip();
}

View File

@ -670,7 +670,7 @@ long WIDGET_HOTKEY_LIST::MapKeypressToKeycode( const wxKeyEvent& aEvent )
{
long key = aEvent.GetKeyCode();
bool is_tab = aEvent.IsKeyInCategory( WXK_CATEGORY_TAB );
printf("key %lX mod %X\n", key, aEvent.GetModifiers());
if( key == WXK_ESCAPE )
{
return 0;
@ -693,35 +693,14 @@ printf("key %lX mod %X\n", key, aEvent.GetModifiers());
*/
bool keyIsLetter = key >= 'A' && key <= 'Z';
int mods = aEvent.GetModifiers();
if( ( mods & wxMOD_SHIFT ) && ( keyIsLetter || key > 256 || key == 9 || key == 32 ) )
if( aEvent.ShiftDown() && ( keyIsLetter || key > 256 || key == 9 || key == 32 ) )
key |= MD_SHIFT;
// the flag wxMOD_ALTGR is defined in wxWidgets as wxMOD_CONTROL|wxMOD_ALT
// So AltGr key cannot used as modifier key because it is the same as Alt key + Ctrl key.
#if CAN_USE_ALTGR_KEY
if( wxmods & wxMOD_ALTGR )
mods |= MD_ALTGR;
else
#endif
{
if( mods & wxMOD_CONTROL )
key |= MD_CTRL;
if( aEvent.ControlDown() )
key |= MD_CTRL;
if( mods & wxMOD_ALT )
key |= MD_ALT;
}
#ifdef wxMOD_META
if( mods & wxMOD_META )
key |= MD_META;
#endif
#ifdef wxMOD_WIN
if( mods & wxMOD_WIN )
key |= MD_SUPER;
#endif
if( aEvent.AltDown() )
key |= MD_ALT;
return key;
}

View File

@ -62,7 +62,6 @@
#include <wx/stattext.h>
#include <wx/button.h>
#include <wx/msgdlg.h>
#include <wx/ffile.h>
CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
@ -797,12 +796,7 @@ void CVPCB_MAINFRAME::DisplayStatus()
msg.Empty();
if( symbol )
{
int pc = symbol->GetPinCount();
wxLogTrace( "CVPCB_PINCOUNT", wxT( "DisplayStatus: selected '%s' pinCount=%d" ),
symbol->GetReference(), pc );
msg = wxString::Format( wxT( "%i" ), pc );
}
msg = wxString::Format( wxT( "%i" ), symbol->GetPinCount() );
if( !filters.IsEmpty() )
filters += wxT( ", " );
@ -963,12 +957,6 @@ int CVPCB_MAINFRAME::readSchematicNetlist( const std::string& aNetlist )
m_netlist.Clear();
// Trace basic payload characteristics to verify libparts are present and visible here
wxLogTrace( "CVPCB_PINCOUNT",
wxT( "readSchematicNetlist: payload size=%zu has_libparts=%d has_libpart=%d" ),
aNetlist.size(), aNetlist.find( "(libparts" ) != std::string::npos,
aNetlist.find( "(libpart" ) != std::string::npos );
try
{
netlistReader.LoadNetlist();

View File

@ -132,13 +132,7 @@ void FOOTPRINTS_LISTBOX::SetFootprints( FOOTPRINT_LIST& aList, const wxString& a
filter.FilterByFootprintFilters( aComponent->GetFootprintFilters() );
if( aFilterType & FILTERING_BY_PIN_COUNT && aComponent )
{
int pc = aComponent->GetPinCount();
wxLogTrace( "CVPCB_PINCOUNT",
wxT( "FOOTPRINTS_LISTBOX::SetFootprints: ref='%s' pinCount filter=%d" ),
aComponent->GetReference(), pc );
filter.FilterByPinCount( pc );
}
filter.FilterByPinCount( aComponent->GetPinCount() );
if( aFilterType & FILTERING_BY_LIBRARY )
filter.FilterByLibrary( aLibName );

View File

@ -122,8 +122,8 @@ set( EESCHEMA_DLGS
dialogs/dialog_label_properties_base.cpp
dialogs/dialog_lib_edit_pin_table.cpp
dialogs/dialog_lib_edit_pin_table_base.cpp
dialogs/dialog_lib_fields_table_base.cpp
dialogs/dialog_lib_fields_table.cpp
dialogs/dialog_lib_fields_base.cpp
dialogs/dialog_lib_fields.cpp
dialogs/dialog_lib_new_symbol.cpp
dialogs/dialog_lib_new_symbol_base.cpp
dialogs/dialog_lib_symbol_properties.cpp

View File

@ -1614,10 +1614,11 @@ void CONNECTION_GRAPH::resolveAllDrivers()
thread_pool& tp = GetKiCadThreadPool();
auto results = tp.submit_loop( 0, dirty_graphs.size(),
[&]( const int ii )
auto results = tp.parallelize_loop( dirty_graphs.size(),
[&]( const int a, const int b)
{
update_lambda( dirty_graphs[ii] );
for( int ii = a; ii < b; ++ii )
update_lambda( dirty_graphs[ii] );
});
results.wait();
@ -2256,10 +2257,11 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
thread_pool& tp = GetKiCadThreadPool();
auto results = tp.submit_loop( 0, m_driver_subgraphs.size(),
[&]( const int ii )
auto results = tp.parallelize_loop( m_driver_subgraphs.size(),
[&]( const int a, const int b)
{
m_driver_subgraphs[ii]->UpdateItemConnections();
for( int ii = a; ii < b; ++ii )
m_driver_subgraphs[ii]->UpdateItemConnections();
});
results.wait();
@ -2462,11 +2464,12 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
return 1;
};
auto results2 = tp.submit_loop( 0, m_driver_subgraphs.size(),
[&]( const int ii )
auto results2 = tp.parallelize_loop( m_driver_subgraphs.size(),
[&]( const int a, const int b)
{
updateItemConnectionsTask( m_driver_subgraphs[ii] );
} );
for( int ii = a; ii < b; ++ii )
updateItemConnectionsTask( m_driver_subgraphs[ii] );
});
results2.wait();
m_net_code_to_subgraphs_map.clear();

View File

@ -931,26 +931,6 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
items );
m_syncingPcbToSchSelection = false;
if( eeconfig()->m_CrossProbing.flash_selection )
{
wxLogTrace( "CROSS_PROBE_FLASH", "MAIL_SELECTION(_FORCE): flash enabled, items=%zu", items.size() );
if( items.empty() )
{
wxLogTrace( "CROSS_PROBE_FLASH", "MAIL_SELECTION(_FORCE): nothing to flash" );
}
else
{
std::vector<SCH_ITEM*> itemPtrs;
std::copy( items.begin(), items.end(), std::back_inserter( itemPtrs ) );
StartCrossProbeFlash( itemPtrs );
}
}
else
{
wxLogTrace( "CROSS_PROBE_FLASH", "MAIL_SELECTION(_FORCE): flash disabled" );
}
}
break;

View File

@ -42,7 +42,6 @@
#include <id.h>
#include <confirm.h>
#include <widgets/wx_html_report_box.h>
#include <widgets/std_bitmap_button.h>
#include <dialogs/dialog_text_entry.h>
#include <string_utils.h>
#include <kiplatform/ui.h>
@ -77,15 +76,15 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
m_running( false ),
m_ercRun( false ),
m_centerMarkerOnIdle( nullptr ),
m_crossprobe( true ),
m_scroll_on_crossprobe( true )
m_severities( 0 )
{
m_currentSchematic = &parent->Schematic();
SetName( DIALOG_ERC_WINDOW_NAME ); // Set a window name to be able to find it
KIPLATFORM::UI::SetFloatLevel( this );
m_bMenu->SetBitmap( KiBitmapBundle( BITMAPS::config ) );
if( EESCHEMA_SETTINGS* cfg = GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" ) )
m_severities = cfg->m_Appearance.erc_severities;
m_messages->SetImmediateMode();
@ -93,7 +92,7 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
m_markerTreeModel = new ERC_TREE_MODEL( parent, m_markerDataView );
m_markerDataView->AssociateModel( m_markerTreeModel );
m_markerTreeModel->Update( m_markerProvider, getSeverities() );
m_markerTreeModel->Update( m_markerProvider, m_severities );
m_ignoredList->InsertColumn( 0, wxEmptyString, wxLIST_FORMAT_LEFT, DEFAULT_SINGLE_COL_WIDTH );
@ -130,11 +129,8 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
SetFocus();
if( EESCHEMA_SETTINGS* cfg = GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" ) )
{
m_crossprobe = cfg->m_ERCDialog.crossprobe;
m_scroll_on_crossprobe = cfg->m_ERCDialog.scroll_on_crossprobe;
}
syncCheckboxes();
updateDisplayedCounts();
// Now all widgets have the size fixed, call FinishDialogSettings
finishDialogSettings();
@ -152,10 +148,7 @@ DIALOG_ERC::~DIALOG_ERC()
g_lastERCIgnored.push_back( { m_ignoredList->GetItemText( ii ), m_ignoredList->GetItemData( ii ) } );
if( EESCHEMA_SETTINGS* cfg = GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" ) )
{
cfg->m_ERCDialog.crossprobe = m_crossprobe;
cfg->m_ERCDialog.scroll_on_crossprobe = m_scroll_on_crossprobe;
}
cfg->m_Appearance.erc_severities = m_severities;
m_markerTreeModel->DecRef();
}
@ -196,59 +189,6 @@ void DIALOG_ERC::UpdateAnnotationWarning()
}
int DIALOG_ERC::getSeverities()
{
int severities = 0;
if( m_showErrors->GetValue() )
severities |= RPT_SEVERITY_ERROR;
if( m_showWarnings->GetValue() )
severities |= RPT_SEVERITY_WARNING;
if( m_showExclusions->GetValue() )
severities |= RPT_SEVERITY_EXCLUSION;
return severities;
}
void DIALOG_ERC::OnMenu( wxCommandEvent& event )
{
// Build a pop menu:
wxMenu menu;
menu.Append( 4206, _( "Cross-probe Selected Items" ),
_( "Highlight corresponding items on canvas when selected in the ERC list" ),
wxITEM_CHECK );
menu.Check( 4206, m_crossprobe );
menu.Append( 4207, _( "Center on Cross-probe" ),
_( "When cross-probing, scroll the canvas so that the item is visible" ),
wxITEM_CHECK );
menu.Check( 4207, m_scroll_on_crossprobe );
// menu_id is the selected submenu id from the popup menu or wxID_NONE
int menu_id = m_bMenu->GetPopupMenuSelectionFromUser( menu );
if( menu_id == 0 || menu_id == 4206 )
{
m_crossprobe = !m_crossprobe;
}
else if( menu_id == 1 || menu_id == 4207 )
{
m_scroll_on_crossprobe = !m_scroll_on_crossprobe;
}
}
bool DIALOG_ERC::TransferDataToWindow()
{
UpdateData();
return true;
}
bool DIALOG_ERC::updateUI()
{
// If ERC checks ever get slow enough we'll want a progress indicator...
@ -277,13 +217,6 @@ void DIALOG_ERC::Report( const wxString& aMessage )
}
void DIALOG_ERC::UpdateData()
{
m_markerTreeModel->Update( m_markerProvider, getSeverities() );
updateDisplayedCounts();
}
void DIALOG_ERC::updateDisplayedCounts()
{
int numErrors = 0;
@ -415,14 +348,30 @@ void DIALOG_ERC::OnCloseErcDialog( wxCloseEvent& aEvent )
// Dialog is mode-less so let the parent know that it needs to be destroyed.
if( !IsModal() && !IsQuasiModal() )
{
if( wxWindow* parent = GetParent() )
wxQueueEvent( parent, new wxCommandEvent( EDA_EVT_CLOSE_ERC_DIALOG, wxID_ANY ) );
wxCommandEvent* evt = new wxCommandEvent( EDA_EVT_CLOSE_ERC_DIALOG, wxID_ANY );
wxWindow* parent = GetParent();
if( parent )
wxQueueEvent( parent, evt );
}
aEvent.Skip();
}
static int RPT_SEVERITY_ALL = RPT_SEVERITY_WARNING | RPT_SEVERITY_ERROR | RPT_SEVERITY_EXCLUSION;
void DIALOG_ERC::syncCheckboxes()
{
m_showAll->SetValue( m_severities == RPT_SEVERITY_ALL );
m_showErrors->SetValue( m_severities & RPT_SEVERITY_ERROR );
m_showWarnings->SetValue( m_severities & RPT_SEVERITY_WARNING );
m_showExclusions->SetValue( m_severities & RPT_SEVERITY_EXCLUSION );
}
void DIALOG_ERC::OnLinkClicked( wxHtmlLinkEvent& event )
{
m_parent->OnAnnotate();
@ -497,7 +446,8 @@ void DIALOG_ERC::OnRunERCClick( wxCommandEvent& event )
}
if( m_cancelled )
m_messages->Report( _( "-------- ERC cancelled by user.<br><br>" ), RPT_SEVERITY_INFO );
// @spellingerror
m_messages->Report( _( "-------- ERC canceled by user.<br><br>" ), RPT_SEVERITY_INFO );
else
m_messages->Report( _( "Done.<br><br>" ), RPT_SEVERITY_INFO );
@ -558,7 +508,7 @@ void DIALOG_ERC::testErc()
}
// Update marker list:
m_markerTreeModel->Update( m_markerProvider, getSeverities() );
m_markerTreeModel->Update( m_markerProvider, m_severities );
// Display new markers from the current screen:
for( SCH_ITEM* marker : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
@ -573,12 +523,6 @@ void DIALOG_ERC::testErc()
void DIALOG_ERC::OnERCItemSelected( wxDataViewEvent& aEvent )
{
if( !m_crossprobe )
{
aEvent.Skip();
return;
}
const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
SCH_SHEET_PATH sheet;
SCH_ITEM* item = m_parent->Schematic().ResolveItem( itemID, &sheet, true );
@ -624,7 +568,7 @@ void DIALOG_ERC::OnERCItemSelected( wxDataViewEvent& aEvent )
m_parent->RedrawScreen( m_parent->GetScreen()->m_ScrollCenter, false );
}
m_parent->FocusOnItem( item, m_scroll_on_crossprobe );
m_parent->FocusOnItem( item );
redrawDrawPanel();
}
@ -818,7 +762,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
m_parent->GetCanvas()->GetView()->Update( marker );
// Update view
if( getSeverities() & RPT_SEVERITY_EXCLUSION )
if( m_severities & RPT_SEVERITY_EXCLUSION )
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
else
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->DeleteCurrentItem( false );
@ -844,7 +788,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
}
// Rebuild model and view
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, getSeverities() );
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, m_severities );
modified = true;
break;
@ -860,7 +804,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
}
// Rebuild model and view
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, getSeverities() );
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, m_severities );
modified = true;
break;
@ -886,7 +830,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
ScreenList.DeleteMarkers( MARKER_BASE::MARKER_ERC, rcItem->GetErrorCode() );
// Rebuild model and view
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, getSeverities() );
static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, m_severities );
modified = true;
}
break;
@ -1012,7 +956,7 @@ void DIALOG_ERC::ExcludeMarker( SCH_MARKER* aMarker )
m_parent->GetCanvas()->GetView()->Update( marker );
// Update view
if( getSeverities() & RPT_SEVERITY_EXCLUSION )
if( m_severities & RPT_SEVERITY_EXCLUSION )
m_markerTreeModel->ValueChanged( node );
else
m_markerTreeModel->DeleteCurrentItem( false );
@ -1032,14 +976,28 @@ void DIALOG_ERC::OnEditViolationSeverities( wxHyperlinkEvent& aEvent )
void DIALOG_ERC::OnSeverity( wxCommandEvent& aEvent )
{
if( aEvent.GetEventObject() == m_showAll )
{
m_showErrors->SetValue( true );
m_showWarnings->SetValue( aEvent.IsChecked() );
m_showExclusions->SetValue( aEvent.IsChecked() );
}
int flag = 0;
UpdateData();
if( aEvent.GetEventObject() == m_showAll )
flag = RPT_SEVERITY_ALL;
else if( aEvent.GetEventObject() == m_showErrors )
flag = RPT_SEVERITY_ERROR;
else if( aEvent.GetEventObject() == m_showWarnings )
flag = RPT_SEVERITY_WARNING;
else if( aEvent.GetEventObject() == m_showExclusions )
flag = RPT_SEVERITY_EXCLUSION;
if( aEvent.IsChecked() )
m_severities |= flag;
else if( aEvent.GetEventObject() == m_showAll )
m_severities = RPT_SEVERITY_ERROR;
else
m_severities &= ~flag;
syncCheckboxes();
m_markerTreeModel->Update( m_markerProvider, m_severities );
updateDisplayedCounts();
}

View File

@ -49,8 +49,6 @@ public:
DIALOG_ERC( SCH_EDIT_FRAME* parent );
~DIALOG_ERC();
bool TransferDataToWindow() override;
// PROGRESS_REPORTER_BASE calls
bool updateUI() override;
void AdvancePhase( const wxString& aMessage ) override;
@ -68,14 +66,10 @@ public:
*/
void ExcludeMarker( SCH_MARKER* aMarker = nullptr );
void UpdateData();
void UpdateAnnotationWarning();
private:
int getSeverities();
// from DIALOG_ERC_BASE:
void OnMenu( wxCommandEvent& aEvent ) override;
void OnCloseErcDialog( wxCloseEvent& event ) override;
void OnRunERCClick( wxCommandEvent& event ) override;
void OnDeleteOneClick( wxCommandEvent& event ) override;
@ -98,6 +92,8 @@ private:
void testErc();
bool writeReport( const wxString& aFullFileName );
void deleteAllMarkers( bool aIncludeExclusions );
void syncCheckboxes();
@ -118,8 +114,7 @@ private:
const SCH_MARKER* m_centerMarkerOnIdle;
bool m_crossprobe;
bool m_scroll_on_crossprobe;
int m_severities;
};

View File

@ -5,7 +5,6 @@
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "widgets/std_bitmap_button.h"
#include "widgets/wx_html_report_box.h"
#include "widgets/wx_infobar.h"
@ -30,24 +29,6 @@ DIALOG_ERC_BASE::DIALOG_ERC_BASE( wxWindow* parent, wxWindowID id, const wxStrin
wxBoxSizer* bMainSizer;
bMainSizer = new wxBoxSizer( wxVERTICAL );
wxGridBagSizer* gbSizerOptions;
gbSizerOptions = new wxGridBagSizer( 0, 0 );
gbSizerOptions->SetFlexibleDirection( wxBOTH );
gbSizerOptions->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_bMenu = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_bMenu->SetMinSize( wxSize( 30,30 ) );
gbSizerOptions->Add( m_bMenu, wxGBPosition( 0, 2 ), wxGBSpan( 2, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
gbSizerOptions->AddGrowableCol( 0 );
gbSizerOptions->AddGrowableCol( 1 );
gbSizerOptions->AddGrowableRow( 0 );
gbSizerOptions->AddGrowableRow( 1 );
bMainSizer->Add( gbSizerOptions, 0, wxEXPAND|wxLEFT, 5 );
m_runningResultsBook = new wxSimplebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
running = new wxPanel( m_runningResultsBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer14;
@ -214,7 +195,6 @@ DIALOG_ERC_BASE::DIALOG_ERC_BASE( wxWindow* parent, wxWindowID id, const wxStrin
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_ERC_BASE::OnCloseErcDialog ) );
m_bMenu->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ERC_BASE::OnMenu ), NULL, this );
m_messages->Connect( wxEVT_COMMAND_HTML_LINK_CLICKED, wxHtmlLinkEventHandler( DIALOG_ERC_BASE::OnLinkClicked ), NULL, this );
m_markerDataView->Connect( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler( DIALOG_ERC_BASE::OnERCItemDClick ), NULL, this );
m_markerDataView->Connect( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, wxDataViewEventHandler( DIALOG_ERC_BASE::OnERCItemRClick ), NULL, this );
@ -236,7 +216,6 @@ DIALOG_ERC_BASE::~DIALOG_ERC_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_ERC_BASE::OnCloseErcDialog ) );
m_bMenu->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ERC_BASE::OnMenu ), NULL, this );
m_messages->Disconnect( wxEVT_COMMAND_HTML_LINK_CLICKED, wxHtmlLinkEventHandler( DIALOG_ERC_BASE::OnLinkClicked ), NULL, this );
m_markerDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler( DIALOG_ERC_BASE::OnERCItemDClick ), NULL, this );
m_markerDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, wxDataViewEventHandler( DIALOG_ERC_BASE::OnERCItemRClick ), NULL, this );

View File

@ -14,7 +14,7 @@
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="file">dialog_erc_base</property>
<property name="first_id">7100</property>
<property name="first_id">1000</property>
<property name="internationalize">1</property>
<property name="lua_skip_events">1</property>
<property name="lua_ui_table">UI</property>
@ -135,101 +135,6 @@
<property name="name">bMainSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxGridBagSizer" expanded="true">
<property name="empty_cell_size"></property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">0,1</property>
<property name="growablerows">0,1</property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">gbSizerOptions</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property>
<property name="vgap">0</property>
<object class="gbsizeritem" expanded="true">
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">2</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="row">0</property>
<property name="rowspan">2</property>
<object class="wxBitmapButton" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Refresh Grouping</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">30,30</property>
<property name="moveable">1</property>
<property name="name">m_bMenu</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnMenu</event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT</property>

View File

@ -10,7 +10,6 @@
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class STD_BITMAP_BUTTON;
class WX_HTML_REPORT_BOX;
class WX_INFOBAR;
@ -21,16 +20,13 @@ class WX_INFOBAR;
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/bmpbuttn.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/gbsizer.h>
#include <wx/html/htmlwin.h>
#include <wx/gauge.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/notebook.h>
#include <wx/dataview.h>
#include <wx/listctrl.h>
@ -39,11 +35,12 @@ class WX_INFOBAR;
#include <wx/stattext.h>
#include <wx/checkbox.h>
#include <widgets/number_badge.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
#define ID_ERASE_DRC_MARKERS 7100
#define ID_ERASE_DRC_MARKERS 1000
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_ERC_BASE
@ -54,7 +51,6 @@ class DIALOG_ERC_BASE : public DIALOG_SHIM
protected:
WX_INFOBAR* m_infoBar;
STD_BITMAP_BUTTON* m_bMenu;
wxSimplebook* m_runningResultsBook;
wxPanel* running;
wxNotebook* m_runningNotebook;
@ -86,7 +82,6 @@ class DIALOG_ERC_BASE : public DIALOG_SHIM
// Virtual event handlers, override them in your derived class
virtual void OnCloseErcDialog( wxCloseEvent& event ) { event.Skip(); }
virtual void OnMenu( wxCommandEvent& event ) { event.Skip(); }
virtual void OnLinkClicked( wxHtmlLinkEvent& event ) { event.Skip(); }
virtual void OnERCItemDClick( wxDataViewEvent& event ) { event.Skip(); }
virtual void OnERCItemRClick( wxDataViewEvent& event ) { event.Skip(); }

View File

@ -175,28 +175,11 @@ DIALOG_FIELD_PROPERTIES::DIALOG_FIELD_PROPERTIES( SCH_BASE_FRAME* aParent, const
wxString netlist;
wxArrayString pins;
for( SCH_PIN* pin : symbol->GetGraphicalPins( 0 /* all units */, 1 /* single bodyStyle */ ) )
{
bool valid = false;
auto expanded = pin->GetStackedPinNumbers( &valid );
if( valid && !expanded.empty() )
{
for( const wxString& num : expanded )
pins.push_back( num + ' ' + pin->GetShownName() );
}
else
{
pins.push_back( pin->GetNumber() + ' ' + pin->GetShownName() );
}
}
for( SCH_PIN* pin : symbol->GetPins( 0 /* all units */, 1 /* single bodyStyle */ ) )
pins.push_back( pin->GetNumber() + ' ' + pin->GetShownName() );
if( !pins.IsEmpty() )
{
wxString dbg = wxJoin( pins, '\t' );
wxLogTrace( "FOOTPRINT_CHOOSER", wxS( "Chooser payload pins (LIB_SYMBOL): %s" ), dbg );
netlist << EscapeString( dbg, CTX_LINE );
}
netlist << EscapeString( wxJoin( pins, '\t' ), CTX_LINE );
netlist << wxS( "\r" );
@ -230,28 +213,12 @@ DIALOG_FIELD_PROPERTIES::DIALOG_FIELD_PROPERTIES( SCH_BASE_FRAME* aParent, const
if( lib_symbol )
{
for( SCH_PIN* pin : lib_symbol->GetGraphicalPins( 0 /* all units */, 1 /* single bodyStyle */ ) )
{
bool valid = false;
auto expanded = pin->GetStackedPinNumbers( &valid );
if( valid && !expanded.empty() )
{
for( const wxString& num : expanded )
pins.push_back( num + ' ' + pin->GetShownName() );
}
else
{
pins.push_back( pin->GetNumber() + ' ' + pin->GetShownName() );
}
}
for( SCH_PIN* pin : lib_symbol->GetPins( 0 /* all units */, 1 /* single bodyStyle */ ) )
pins.push_back( pin->GetNumber() + ' ' + pin->GetShownName() );
}
if( !pins.IsEmpty() )
{
wxString dbg = wxJoin( pins, '\t' );
wxLogTrace( "FOOTPRINT_CHOOSER", wxS( "Chooser payload pins (SCH_SYMBOL): %s" ), dbg );
netlist << EscapeString( dbg, CTX_LINE );
}
netlist << EscapeString( wxJoin( pins, '\t' ), CTX_LINE );
netlist << wxS( "\r" );

View File

@ -17,77 +17,70 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef DIALOG_LIB_FIELDS_H
#define DIALOG_LIB_FIELDS_H
#include <dialog_lib_fields_table_base.h>
#include <dialog_lib_fields_base.h>
#include <sch_reference_list.h>
#include <lib_fields_data_model.h>
class SYMBOL_EDIT_FRAME;
class LIB_FIELDS_EDITOR_GRID_DATA_MODEL;
class LIB_SYMBOL;
class DIALOG_LIB_FIELDS_TABLE : public DIALOG_LIB_FIELDS_TABLE_BASE
class DIALOG_LIB_FIELDS : public DIALOG_LIB_FIELDS_BASE
{
public:
enum SCOPE : int
{
SCOPE_LIBRARY = 0,
SCOPE_RELATED_SYMBOLS
};
DIALOG_LIB_FIELDS( SYMBOL_EDIT_FRAME* parent, wxString libId, const wxArrayString& aSymbolNames );
~DIALOG_LIB_FIELDS() override;
DIALOG_LIB_FIELDS_TABLE( SYMBOL_EDIT_FRAME* parent, DIALOG_LIB_FIELDS_TABLE::SCOPE aScope );
~DIALOG_LIB_FIELDS_TABLE() override;
void OnInit();
bool TransferDataToWindow() override;
protected:
void OnClose( wxCloseEvent& event ) override;
void OnColumnItemToggled( wxDataViewEvent& event ) override;
void OnFieldsCtrlSelectionChanged( wxDataViewEvent& event ) override;
void OnSizeFieldList( wxSizeEvent& event ) override;
void OnAddField( wxCommandEvent& event ) override;
void OnRenameField( wxCommandEvent& event ) override;
void OnRemoveField( wxCommandEvent& event ) override;
void OnFilterMouseMoved( wxMouseEvent& event ) override;
void OnFilterText( wxCommandEvent& event ) override;
void OnRegroupSymbols( wxCommandEvent& event ) override;
void OnTableValueChanged( wxGridEvent& event ) override;
void OnTableCellClick( wxGridEvent& event ) override;
void OnTableItemContextMenu( wxGridEvent& event ) override;
void OnTableColSize( wxGridSizeEvent& event ) override;
void OnCancel( wxCommandEvent& event ) override;
void OnOk( wxCommandEvent& event ) override;
void OnApply( wxCommandEvent& event ) override;
bool TransferDataFromWindow() override;
void ShowHideColumn( int aCol, bool aShow );
private:
void UpdateFieldList();
void AddField( const wxString& aFieldName, const wxString& aLabelValue, bool show, bool groupBy,
bool addedByUser = false, bool aIsCheckbox = false );
void AddField( const wxString& aFieldName, const wxString& aLabelValue, bool show, bool groupBy, bool addedByUser = false, bool aIsCheckbox = false );
void RemoveField( const wxString& fieldName );
void RenameField( const wxString& oldName, const wxString& newName );
void RegroupSymbols();
void OnColSort( wxGridEvent& aEvent );
void OnColMove( wxGridEvent& aEvent );
void OnColLabelChange( wxDataViewEvent& aEvent );
void SetupColumnProperties( int aCol );
void SetupAllColumnProperties();
void setScope( SCOPE aScope );
void loadSymbols( const wxArrayString& aSymbolNames );
void OnViewControlsCellChanged( wxGridEvent& aEvent ) override;
void OnSizeViewControlsGrid( wxSizeEvent& event ) override;
void OnAddField( wxCommandEvent& event ) override;
void OnRenameField( wxCommandEvent& event ) override;
void OnRemoveField( wxCommandEvent& event ) override;
void OnFilterMouseMoved( wxMouseEvent& event ) override;
void OnFilterText( wxCommandEvent& event ) override;
void OnScope( wxCommandEvent& event ) override;
void OnRegroupSymbols( wxCommandEvent& event ) override;
void OnTableValueChanged( wxGridEvent& event ) override;
void OnTableCellClick( wxGridEvent& event ) override;
void OnTableItemContextMenu( wxGridEvent& event ) override;
void OnTableColSize( wxGridSizeEvent& event ) override;
void OnSidebarToggle( wxCommandEvent& event ) override;
void OnCancel( wxCommandEvent& event ) override;
void OnOk( wxCommandEvent& event ) override;
void OnApply( wxCommandEvent& event ) override;
void OnClose( wxCloseEvent& event ) override;
private:
wxString m_libId;
SYMBOL_EDIT_FRAME* m_parent;
SCOPE m_scope;
VIEW_CONTROLS_GRID_DATA_MODEL* m_viewControlsDataModel;
int m_fieldNameColWidth;
int m_labelColWidth;
int m_showColWidth;
int m_groupByColWidth;
LIB_FIELDS_EDITOR_GRID_DATA_MODEL* m_dataModel;
std::vector<LIB_SYMBOL*> m_symbolsList;
};
#endif // DIALOG_LIB_FIELDS_H

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!
@ -8,11 +8,11 @@
#include "widgets/std_bitmap_button.h"
#include "widgets/wx_grid.h"
#include "dialog_lib_fields_table_base.h"
#include "dialog_lib_fields_base.h"
///////////////////////////////////////////////////////////////////////////
DIALOG_LIB_FIELDS_TABLE_BASE::DIALOG_LIB_FIELDS_TABLE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
DIALOG_LIB_FIELDS_BASE::DIALOG_LIB_FIELDS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
@ -29,41 +29,10 @@ DIALOG_LIB_FIELDS_TABLE_BASE::DIALOG_LIB_FIELDS_TABLE_BASE( wxWindow* parent, wx
wxBoxSizer* bLeftSizer;
bLeftSizer = new wxBoxSizer( wxVERTICAL );
m_viewControlsGrid = new WX_GRID( m_leftPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_fieldsCtrl = new wxDataViewListCtrl( m_leftPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_fieldsCtrl->SetMinSize( wxSize( -1,250 ) );
// Grid
m_viewControlsGrid->CreateGrid( 1, 4 );
m_viewControlsGrid->EnableEditing( true );
m_viewControlsGrid->EnableGridLines( false );
m_viewControlsGrid->EnableDragGridSize( false );
m_viewControlsGrid->SetMargins( 0, 0 );
// Columns
m_viewControlsGrid->SetColSize( 0, 60 );
m_viewControlsGrid->SetColSize( 1, 60 );
m_viewControlsGrid->SetColSize( 2, 46 );
m_viewControlsGrid->SetColSize( 3, 56 );
m_viewControlsGrid->EnableDragColMove( false );
m_viewControlsGrid->EnableDragColSize( false );
m_viewControlsGrid->SetColLabelValue( 0, _("Field") );
m_viewControlsGrid->SetColLabelValue( 1, _("BOM Name") );
m_viewControlsGrid->SetColLabelValue( 2, _("Include") );
m_viewControlsGrid->SetColLabelValue( 3, _("Group By") );
m_viewControlsGrid->SetColLabelSize( 24 );
m_viewControlsGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Rows
m_viewControlsGrid->EnableDragRowSize( false );
m_viewControlsGrid->SetRowLabelSize( 0 );
m_viewControlsGrid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Label Appearance
// Cell Defaults
m_viewControlsGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
m_viewControlsGrid->SetMinSize( wxSize( -1,250 ) );
bLeftSizer->Add( m_viewControlsGrid, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
bLeftSizer->Add( m_fieldsCtrl, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
wxBoxSizer* bFieldsButtons;
bFieldsButtons = new wxBoxSizer( wxHORIZONTAL );
@ -81,7 +50,7 @@ DIALOG_LIB_FIELDS_TABLE_BASE::DIALOG_LIB_FIELDS_TABLE_BASE( wxWindow* parent, wx
bFieldsButtons->Add( m_removeFieldButton, 0, wxBOTTOM|wxLEFT, 5 );
bLeftSizer->Add( bFieldsButtons, 0, wxEXPAND|wxTOP|wxBOTTOM, 2 );
bLeftSizer->Add( bFieldsButtons, 0, wxEXPAND, 5 );
m_leftPanel->SetSizer( bLeftSizer );
@ -107,15 +76,6 @@ DIALOG_LIB_FIELDS_TABLE_BASE::DIALOG_LIB_FIELDS_TABLE_BASE( wxWindow* parent, wx
m_staticline31 = new wxStaticLine( m_rightPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
bControls->Add( m_staticline31, 0, wxEXPAND | wxALL, 3 );
wxString m_choiceScopeChoices[] = { _("Whole Library"), _("Related Symbols Only") };
int m_choiceScopeNChoices = sizeof( m_choiceScopeChoices ) / sizeof( wxString );
m_choiceScope = new wxChoice( m_rightPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceScopeNChoices, m_choiceScopeChoices, 0 );
m_choiceScope->SetSelection( 0 );
bControls->Add( m_choiceScope, 0, wxALL, 5 );
m_staticline311 = new wxStaticLine( m_rightPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
bControls->Add( m_staticline311, 0, wxEXPAND | wxALL, 5 );
m_bRefresh = new STD_BITMAP_BUTTON( m_rightPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_bRefresh->SetMinSize( wxSize( 30,30 ) );
@ -152,38 +112,35 @@ DIALOG_LIB_FIELDS_TABLE_BASE::DIALOG_LIB_FIELDS_TABLE_BASE( wxWindow* parent, wx
bRightSizer->Add( m_grid, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
m_rightPanel->SetSizer( bRightSizer );
m_rightPanel->Layout();
bRightSizer->Fit( m_rightPanel );
m_splitterMainWindow->SplitVertically( m_leftPanel, m_rightPanel, -1 );
bEditSizer->Add( m_splitterMainWindow, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
bMainSizer->Add( bEditSizer, 1, wxEXPAND, 5 );
wxBoxSizer* bButtonsSizer;
bButtonsSizer = new wxBoxSizer( wxHORIZONTAL );
m_sidebarButton = new STD_BITMAP_BUTTON( m_rightPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bButtonsSizer->Add( m_sidebarButton, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
bButtonsSizer->Add( 0, 0, 9, wxEXPAND, 5 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( m_rightPanel, wxID_OK );
m_sdbSizerOK = new wxButton( this, wxID_OK );
m_sdbSizer->AddButton( m_sdbSizerOK );
m_sdbSizerApply = new wxButton( m_rightPanel, wxID_APPLY );
m_sdbSizerApply = new wxButton( this, wxID_APPLY );
m_sdbSizer->AddButton( m_sdbSizerApply );
m_sdbSizerCancel = new wxButton( m_rightPanel, wxID_CANCEL );
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
bButtonsSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
bRightSizer->Add( bButtonsSizer, 0, wxEXPAND, 5 );
m_rightPanel->SetSizer( bRightSizer );
m_rightPanel->Layout();
bRightSizer->Fit( m_rightPanel );
m_splitterMainWindow->SplitVertically( m_leftPanel, m_rightPanel, -1 );
bEditSizer->Add( m_splitterMainWindow, 1, wxEXPAND|wxALL, 5 );
bMainSizer->Add( bEditSizer, 1, wxEXPAND, 5 );
bMainSizer->Add( bButtonsSizer, 0, wxEXPAND, 5 );
this->SetSizer( bMainSizer );
@ -193,56 +150,54 @@ DIALOG_LIB_FIELDS_TABLE_BASE::DIALOG_LIB_FIELDS_TABLE_BASE( wxWindow* parent, wx
this->Centre( wxBOTH );
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnClose ) );
m_viewControlsGrid->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnViewControlsCellChanged ), NULL, this );
m_viewControlsGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnSizeViewControlsGrid ), NULL, this );
m_addFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnAddField ), NULL, this );
m_renameFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnRenameField ), NULL, this );
m_removeFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnRemoveField ), NULL, this );
m_filter->Connect( wxEVT_MOTION, wxMouseEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnFilterMouseMoved ), NULL, this );
m_filter->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnFilterText ), NULL, this );
m_choiceScope->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnScope ), NULL, this );
m_bRefresh->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnRegroupSymbols ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableValueChanged ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableCellClick ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableCellClick ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableItemContextMenu ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableCmdCellClick ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableCmdCellClick ), NULL, this );
m_grid->Connect( wxEVT_GRID_COL_SIZE, wxGridSizeEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableColSize ), NULL, this );
m_grid->Connect( wxEVT_GRID_EDITOR_SHOWN, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnEditorShown ), NULL, this );
m_grid->Connect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableSelectCell ), NULL, this );
m_sidebarButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnSidebarToggle ), NULL, this );
m_sdbSizerApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnApply ), NULL, this );
m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnCancel ), NULL, this );
m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnOk ), NULL, this );
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_LIB_FIELDS_BASE::OnClose ) );
m_fieldsCtrl->Connect( wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED, wxDataViewEventHandler( DIALOG_LIB_FIELDS_BASE::OnColumnItemToggled ), NULL, this );
m_fieldsCtrl->Connect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_LIB_FIELDS_BASE::OnFieldsCtrlSelectionChanged ), NULL, this );
m_fieldsCtrl->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_LIB_FIELDS_BASE::OnSizeFieldList ), NULL, this );
m_addFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnAddField ), NULL, this );
m_renameFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnRenameField ), NULL, this );
m_removeFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnRemoveField ), NULL, this );
m_filter->Connect( wxEVT_MOTION, wxMouseEventHandler( DIALOG_LIB_FIELDS_BASE::OnFilterMouseMoved ), NULL, this );
m_filter->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnFilterText ), NULL, this );
m_bRefresh->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnRegroupSymbols ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableValueChanged ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCellClick ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCellClick ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableItemContextMenu ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCmdCellClick ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCmdCellClick ), NULL, this );
m_grid->Connect( wxEVT_GRID_COL_SIZE, wxGridSizeEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableColSize ), NULL, this );
m_grid->Connect( wxEVT_GRID_EDITOR_SHOWN, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnEditorShown ), NULL, this );
m_grid->Connect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableSelectCell ), NULL, this );
m_sdbSizerApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnApply ), NULL, this );
m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnCancel ), NULL, this );
m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnOk ), NULL, this );
}
DIALOG_LIB_FIELDS_TABLE_BASE::~DIALOG_LIB_FIELDS_TABLE_BASE()
DIALOG_LIB_FIELDS_BASE::~DIALOG_LIB_FIELDS_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnClose ) );
m_viewControlsGrid->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnViewControlsCellChanged ), NULL, this );
m_viewControlsGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnSizeViewControlsGrid ), NULL, this );
m_addFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnAddField ), NULL, this );
m_renameFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnRenameField ), NULL, this );
m_removeFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnRemoveField ), NULL, this );
m_filter->Disconnect( wxEVT_MOTION, wxMouseEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnFilterMouseMoved ), NULL, this );
m_filter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnFilterText ), NULL, this );
m_choiceScope->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnScope ), NULL, this );
m_bRefresh->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnRegroupSymbols ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableValueChanged ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableCellClick ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableCellClick ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableItemContextMenu ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableCmdCellClick ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableCmdCellClick ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_COL_SIZE, wxGridSizeEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableColSize ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_EDITOR_SHOWN, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnEditorShown ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnTableSelectCell ), NULL, this );
m_sidebarButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnSidebarToggle ), NULL, this );
m_sdbSizerApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnApply ), NULL, this );
m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnCancel ), NULL, this );
m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_TABLE_BASE::OnOk ), NULL, this );
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_LIB_FIELDS_BASE::OnClose ) );
m_fieldsCtrl->Disconnect( wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED, wxDataViewEventHandler( DIALOG_LIB_FIELDS_BASE::OnColumnItemToggled ), NULL, this );
m_fieldsCtrl->Disconnect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_LIB_FIELDS_BASE::OnFieldsCtrlSelectionChanged ), NULL, this );
m_fieldsCtrl->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_LIB_FIELDS_BASE::OnSizeFieldList ), NULL, this );
m_addFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnAddField ), NULL, this );
m_renameFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnRenameField ), NULL, this );
m_removeFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnRemoveField ), NULL, this );
m_filter->Disconnect( wxEVT_MOTION, wxMouseEventHandler( DIALOG_LIB_FIELDS_BASE::OnFilterMouseMoved ), NULL, this );
m_filter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnFilterText ), NULL, this );
m_bRefresh->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnRegroupSymbols ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableValueChanged ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCellClick ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCellClick ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableItemContextMenu ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCmdCellClick ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCmdCellClick ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_COL_SIZE, wxGridSizeEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableColSize ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_EDITOR_SHOWN, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnEditorShown ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableSelectCell ), NULL, this );
m_sdbSizerApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnApply ), NULL, this );
m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnCancel ), NULL, this );
m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnOk ), NULL, this );
}

View File

@ -13,12 +13,12 @@
<property name="cpp_use_enum">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="file">dialog_lib_fields_table_base</property>
<property name="file">dialog_lib_fields_base</property>
<property name="first_id">1000</property>
<property name="internationalize">1</property>
<property name="lua_skip_events">1</property>
<property name="lua_ui_table">UI</property>
<property name="name">dialog_lib_fields_table_base</property>
<property name="name">dialog_lib_fields_base</property>
<property name="path">.</property>
<property name="php_disconnect_events">0</property>
<property name="php_disconnect_mode">source_name</property>
@ -48,12 +48,12 @@
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size">-1,-1</property>
<property name="name">DIALOG_LIB_FIELDS_TABLE_BASE</property>
<property name="name">DIALOG_LIB_FIELDS_BASE</property>
<property name="pos"></property>
<property name="size">-1,-1</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
<property name="title">Library Fields Table (%s)</property>
<property name="title">Library Fields Editor</property>
<property name="tooltip"></property>
<property name="two_step_creation">0</property>
<property name="window_extra_style"></property>
@ -76,7 +76,7 @@
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
<property name="proportion">1</property>
<object class="wxSplitterWindow" expanded="true">
<property name="BottomDockable">1</property>
@ -194,100 +194,40 @@
<property name="name">bLeftSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
<property name="proportion">1</property>
<object class="wxGrid" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="autosize_cols">0</property>
<property name="autosize_rows">0</property>
<property name="best_size"></property>
<object class="wxDataViewListCtrl" expanded="false">
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="cell_bg"></property>
<property name="cell_font"></property>
<property name="cell_horiz_alignment">wxALIGN_LEFT</property>
<property name="cell_text"></property>
<property name="cell_vert_alignment">wxALIGN_TOP</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="col_label_horiz_alignment">wxALIGN_CENTER</property>
<property name="col_label_size">24</property>
<property name="col_label_values">&quot;Field&quot; &quot;BOM Name&quot; &quot;Include&quot; &quot;Group By&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTER</property>
<property name="cols">4</property>
<property name="column_sizes">60,60,46,56</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="drag_col_move">0</property>
<property name="drag_col_size">0</property>
<property name="drag_grid_size">0</property>
<property name="drag_row_size">0</property>
<property name="editing">1</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="grid_line_color"></property>
<property name="grid_lines">0</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label_bg"></property>
<property name="label_font"></property>
<property name="label_text"></property>
<property name="margin_height">0</property>
<property name="margin_width">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">-1,250</property>
<property name="moveable">1</property>
<property name="name">m_viewControlsGrid</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="name">m_fieldsCtrl</property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="row_label_horiz_alignment">wxALIGN_CENTER</property>
<property name="row_label_size">0</property>
<property name="row_label_values"></property>
<property name="row_label_vert_alignment">wxALIGN_CENTER</property>
<property name="row_sizes"></property>
<property name="rows">1</property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass">WX_GRID; widgets/wx_grid.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="style"></property>
<property name="subclass"></property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnGridCellChange">OnViewControlsCellChanged</event>
<event name="OnSize">OnSizeViewControlsGrid</event>
<event name="OnDataViewListCtrlItemValueChanged">OnColumnItemToggled</event>
<event name="OnDataViewListCtrlSelectionChanged">OnFieldsCtrlSelectionChanged</event>
<event name="OnSize">OnSizeFieldList</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">2</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
@ -728,131 +668,6 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxChoice" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices">&quot;Whole Library&quot; &quot;Related Symbols Only&quot;</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_choiceScope</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="selection">0</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChoice">OnScope</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND | wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticLine" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticline311</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxLI_VERTICAL</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
@ -1028,123 +843,6 @@
<event name="OnGridSelectCell">OnTableSelectCell</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bButtonsSizer</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Remove Field...</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_sidebarButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnSidebarToggle</event>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">9</property>
<object class="spacer" expanded="false">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
<property name="proportion">0</property>
<object class="wxStdDialogButtonSizer" expanded="false">
<property name="Apply">1</property>
<property name="Cancel">1</property>
<property name="ContextHelp">0</property>
<property name="Help">0</property>
<property name="No">0</property>
<property name="OK">1</property>
<property name="Save">0</property>
<property name="Yes">0</property>
<property name="minimum_size"></property>
<property name="name">m_sdbSizer</property>
<property name="permission">protected</property>
<event name="OnApplyButtonClick">OnApply</event>
<event name="OnCancelButtonClick">OnCancel</event>
<event name="OnOKButtonClick">OnOk</event>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
@ -1152,6 +850,48 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bButtonsSizer</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">9</property>
<object class="spacer" expanded="false">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
<property name="proportion">0</property>
<object class="wxStdDialogButtonSizer" expanded="false">
<property name="Apply">1</property>
<property name="Cancel">1</property>
<property name="ContextHelp">0</property>
<property name="Help">0</property>
<property name="No">0</property>
<property name="OK">1</property>
<property name="Save">0</property>
<property name="Yes">0</property>
<property name="minimum_size"></property>
<property name="name">m_sdbSizer</property>
<property name="permission">protected</property>
<event name="OnApplyButtonClick">OnApply</event>
<event name="OnCancelButtonClick">OnCancel</event>
<event name="OnOKButtonClick">OnOk</event>
</object>
</object>
</object>
</object>
</object>
</object>
</object>

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!
@ -14,12 +14,12 @@ class STD_BITMAP_BUTTON;
class WX_GRID;
#include "dialog_shim.h"
#include <wx/dataview.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/font.h>
#include <wx/grid.h>
#include <wx/gdicmn.h>
#include <wx/bmpbuttn.h>
#include <wx/bitmap.h>
#include <wx/image.h>
@ -29,34 +29,31 @@ class WX_GRID;
#include <wx/panel.h>
#include <wx/srchctrl.h>
#include <wx/statline.h>
#include <wx/choice.h>
#include <wx/grid.h>
#include <wx/splitter.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_LIB_FIELDS_TABLE_BASE
/// Class DIALOG_LIB_FIELDS_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_LIB_FIELDS_TABLE_BASE : public DIALOG_SHIM
class DIALOG_LIB_FIELDS_BASE : public DIALOG_SHIM
{
private:
protected:
wxSplitterWindow* m_splitterMainWindow;
wxPanel* m_leftPanel;
WX_GRID* m_viewControlsGrid;
wxDataViewListCtrl* m_fieldsCtrl;
STD_BITMAP_BUTTON* m_addFieldButton;
STD_BITMAP_BUTTON* m_renameFieldButton;
STD_BITMAP_BUTTON* m_removeFieldButton;
wxPanel* m_rightPanel;
wxSearchCtrl* m_filter;
wxStaticLine* m_staticline31;
wxChoice* m_choiceScope;
wxStaticLine* m_staticline311;
STD_BITMAP_BUTTON* m_bRefresh;
WX_GRID* m_grid;
STD_BITMAP_BUTTON* m_sidebarButton;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerApply;
@ -64,14 +61,14 @@ class DIALOG_LIB_FIELDS_TABLE_BASE : public DIALOG_SHIM
// Virtual event handlers, override them in your derived class
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnViewControlsCellChanged( wxGridEvent& event ) { event.Skip(); }
virtual void OnSizeViewControlsGrid( wxSizeEvent& event ) { event.Skip(); }
virtual void OnColumnItemToggled( wxDataViewEvent& event ) { event.Skip(); }
virtual void OnFieldsCtrlSelectionChanged( wxDataViewEvent& event ) { event.Skip(); }
virtual void OnSizeFieldList( wxSizeEvent& event ) { event.Skip(); }
virtual void OnAddField( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRenameField( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemoveField( wxCommandEvent& event ) { event.Skip(); }
virtual void OnFilterMouseMoved( wxMouseEvent& event ) { event.Skip(); }
virtual void OnFilterText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnScope( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRegroupSymbols( wxCommandEvent& event ) { event.Skip(); }
virtual void OnTableValueChanged( wxGridEvent& event ) { event.Skip(); }
virtual void OnTableCellClick( wxGridEvent& event ) { event.Skip(); }
@ -80,7 +77,6 @@ class DIALOG_LIB_FIELDS_TABLE_BASE : public DIALOG_SHIM
virtual void OnTableColSize( wxGridSizeEvent& event ) { event.Skip(); }
virtual void OnEditorShown( wxGridEvent& event ) { event.Skip(); }
virtual void OnTableSelectCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnSidebarToggle( wxCommandEvent& event ) { event.Skip(); }
virtual void OnApply( wxCommandEvent& event ) { event.Skip(); }
virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOk( wxCommandEvent& event ) { event.Skip(); }
@ -88,9 +84,9 @@ class DIALOG_LIB_FIELDS_TABLE_BASE : public DIALOG_SHIM
public:
DIALOG_LIB_FIELDS_TABLE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Library Fields Table (%s)"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER );
DIALOG_LIB_FIELDS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Library Fields Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER );
~DIALOG_LIB_FIELDS_TABLE_BASE();
~DIALOG_LIB_FIELDS_BASE();
};

View File

@ -133,16 +133,21 @@ void DIALOG_SCH_FIND::onShowSearchPanel( wxHyperlinkEvent& event )
{
wxCHECK2( m_frame->GetFrameType() == FRAME_SCH, /* void */ );
m_frame->GetToolManager()->RunAction( ACTIONS::showSearch );
if( static_cast<SCH_EDIT_FRAME*>( m_frame )->IsSearchPaneShown() )
{
EndModal( wxID_CANCEL );
EndModal( wxID_CANCEL );
CallAfter(
[]()
{
if( wxWindow* frame = wxWindow::FindWindowByName( SCH_EDIT_FRAME_NAME ) )
static_cast<SCH_EDIT_FRAME*>( frame )->FocusSearch();
} );
CallAfter(
[]()
{
if( wxWindow* frame = wxWindow::FindWindowByName( SCH_EDIT_FRAME_NAME ) )
static_cast<SCH_EDIT_FRAME*>( frame )->FocusSearch();
} );
}
else
{
m_frame->GetToolManager()->RunAction( ACTIONS::showSearch );
}
}

View File

@ -149,7 +149,7 @@ DIALOG_SCH_FIND_BASE::DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id, con
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizer6->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
m_searchPanelLink = new wxHyperlinkCtrl( this, wxID_ANY, _("Show search panel"), wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE );
m_searchPanelLink = new wxHyperlinkCtrl( this, wxID_ANY, _("Show search panel"), wxT("http://www.wxformbuilder.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE );
bSizer6->Add( m_searchPanelLink, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_RIGHT, 5 );

View File

@ -1648,7 +1648,7 @@
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="url"></property>
<property name="url">http://www.wxformbuilder.org</property>
<property name="visited_color"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>

View File

@ -77,8 +77,8 @@ public:
*/
std::vector<std::pair<FIELD_T, wxString>> GetFields() const;
bool GetKeepSymbol() { return m_keepSymbol->GetValue(); }
bool GetPlaceAllUnits() { return m_useUnits->GetValue(); }
bool GetKeepSymbol() { return m_keepSymbol; }
bool GetPlaceAllUnits() { return m_useUnits; }
public:
static std::mutex g_Mutex;

File diff suppressed because it is too large Load Diff

View File

@ -22,17 +22,21 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#pragma once
#ifndef DIALOG_SYMBOL_FIELDS_TABLE_H
#define DIALOG_SYMBOL_FIELDS_TABLE_H
#include <dialog_symbol_fields_table_base.h>
#include <sch_reference_list.h>
#include <schematic.h>
#include <fields_data_model.h>
wxDECLARE_EVENT( EDA_EVT_CLOSE_DIALOG_SYMBOL_FIELDS_TABLE, wxCommandEvent );
class SCHEMATIC_SETTINGS;
struct BOM_PRESET;
struct BOM_FMT_PRESET;
class SCH_EDIT_FRAME;
class FIELDS_EDITOR_GRID_DATA_MODEL;
class JOB_EXPORT_SCH_BOM;
@ -40,21 +44,19 @@ class DIALOG_SYMBOL_FIELDS_TABLE : public DIALOG_SYMBOL_FIELDS_TABLE_BASE, publi
{
public:
DIALOG_SYMBOL_FIELDS_TABLE( SCH_EDIT_FRAME* parent, JOB_EXPORT_SCH_BOM* aJob = nullptr );
~DIALOG_SYMBOL_FIELDS_TABLE() override;
virtual ~DIALOG_SYMBOL_FIELDS_TABLE();
bool TransferDataToWindow() override;
bool TransferDataFromWindow() override;
void ShowEditTab();
void ShowExportTab();
void ShowHideColumn( int aCol, bool aShow );
private:
void SetupColumnProperties( int aCol );
void SetupAllColumnProperties();
void AddField( const wxString& displayName, const wxString& aCanonicalName, bool show,
bool groupBy, bool addedByUser = false );
void setScope( FIELDS_EDITOR_GRID_DATA_MODEL::SCOPE aScope );
/**
* Construct the rows of m_fieldsCtrl and the columns of m_dataModel from a union of all
@ -62,33 +64,33 @@ private:
*/
void LoadFieldNames();
void OnViewControlsCellChanged( wxGridEvent& aEvent ) override;
void OnSizeViewControlsGrid( wxSizeEvent& event ) override;
void OnColSort( wxGridEvent& aEvent );
void OnColMove( wxGridEvent& aEvent );
void OnColLabelChange( wxDataViewEvent& aEvent );
void OnTableRangeSelected( wxGridRangeSelectEvent& aEvent );
void OnColumnItemToggled( wxDataViewEvent& event ) override;
void OnGroupSymbolsToggled( wxCommandEvent& event ) override;
void OnExcludeDNPToggled( wxCommandEvent& event ) override;
void OnShowExcludedToggled( wxCommandEvent& event ) override;
void OnRegroupSymbols( wxCommandEvent& aEvent ) override;
void OnScopeChanged( wxCommandEvent& aEvent ) override;
void UpdateScope();
void OnTableValueChanged( wxGridEvent& event ) override;
void OnTableCellClick( wxGridEvent& event ) override;
void OnTableItemContextMenu( wxGridEvent& event ) override;
void OnTableColSize( wxGridSizeEvent& event ) override;
void OnSizeFieldList( wxSizeEvent& event ) override;
void OnAddField( wxCommandEvent& event ) override;
void OnRemoveField( wxCommandEvent& event ) override;
void OnRenameField( wxCommandEvent& event ) override;
void OnColSort( wxGridEvent& aEvent );
void OnColMove( wxGridEvent& aEvent );
void OnTableRangeSelected( wxGridRangeSelectEvent& aEvent );
void OnFilterText( wxCommandEvent& aEvent ) override;
void OnFilterMouseMoved( wxMouseEvent& event ) override;
void OnScope( wxCommandEvent& event ) override;
void OnGroupSymbolsToggled( wxCommandEvent& event ) override;
void OnRegroupSymbols( wxCommandEvent& aEvent ) override;
void OnMenu( wxCommandEvent& event ) override;
void OnTableValueChanged( wxGridEvent& event ) override;
void OnTableCellClick( wxGridEvent& event ) override;
void OnTableColSize( wxGridSizeEvent& event ) override;
void OnSidebarToggle( wxCommandEvent& event ) override;
void OnExport( wxCommandEvent& aEvent ) override;
void OnSaveAndContinue( wxCommandEvent& aEvent ) override;
void OnCancel( wxCommandEvent& aEvent ) override;
void OnOk( wxCommandEvent& aEvent ) override;
void OnClose( wxCloseEvent& aEvent ) override;
void OnOk( wxCommandEvent& aEvent ) override;
void OnFilterText( wxCommandEvent& aEvent ) override;
void OnFilterMouseMoved( wxMouseEvent& event ) override;
void OnOutputFileBrowseClicked( wxCommandEvent& event ) override;
void OnPageChanged( wxNotebookEvent& event ) override;
@ -153,7 +155,10 @@ private:
// Index in the fields list control for each MANDATORY_FIELD type
std::map<FIELD_T, int> m_mandatoryFieldListIndexes;
VIEW_CONTROLS_GRID_DATA_MODEL* m_viewControlsDataModel;
int m_fieldNameColWidth;
int m_labelColWidth;
int m_showColWidth;
int m_groupByColWidth;
SCH_REFERENCE_LIST m_symbolsList;
FIELDS_EDITOR_GRID_DATA_MODEL* m_dataModel;
@ -162,3 +167,5 @@ private:
JOB_EXPORT_SCH_BOM* m_job;
};
#endif /* DIALOG_SYMBOL_FIELDS_TABLE_H */

View File

@ -19,51 +19,22 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
wxBoxSizer* bMainSizer;
bMainSizer = new wxBoxSizer( wxVERTICAL );
m_splitterMainWindow = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH|wxSP_LIVE_UPDATE|wxSP_NO_XP_THEME );
m_splitterMainWindow->SetMinimumPaneSize( 120 );
m_nbPages = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_panelEdit = new wxPanel( m_nbPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bEditSizer;
bEditSizer = new wxBoxSizer( wxVERTICAL );
m_splitterMainWindow = new wxSplitterWindow( m_panelEdit, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH|wxSP_LIVE_UPDATE|wxSP_NO_XP_THEME );
m_splitterMainWindow->SetMinimumPaneSize( 200 );
m_leftPanel = new wxPanel( m_splitterMainWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bLeftSizer;
bLeftSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bMargins;
bMargins = new wxBoxSizer( wxVERTICAL );
m_fieldsCtrl = new wxDataViewListCtrl( m_leftPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_fieldsCtrl->SetMinSize( wxSize( -1,250 ) );
m_viewControlsGrid = new WX_GRID( m_leftPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_viewControlsGrid->CreateGrid( 1, 4 );
m_viewControlsGrid->EnableEditing( true );
m_viewControlsGrid->EnableGridLines( false );
m_viewControlsGrid->EnableDragGridSize( false );
m_viewControlsGrid->SetMargins( 0, 0 );
// Columns
m_viewControlsGrid->SetColSize( 0, 60 );
m_viewControlsGrid->SetColSize( 1, 60 );
m_viewControlsGrid->SetColSize( 2, 46 );
m_viewControlsGrid->SetColSize( 3, 56 );
m_viewControlsGrid->EnableDragColMove( false );
m_viewControlsGrid->EnableDragColSize( false );
m_viewControlsGrid->SetColLabelValue( 0, _("Field") );
m_viewControlsGrid->SetColLabelValue( 1, _("BOM Name") );
m_viewControlsGrid->SetColLabelValue( 2, _("Include") );
m_viewControlsGrid->SetColLabelValue( 3, _("Group By") );
m_viewControlsGrid->SetColLabelSize( 24 );
m_viewControlsGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Rows
m_viewControlsGrid->EnableDragRowSize( false );
m_viewControlsGrid->SetRowLabelSize( 0 );
m_viewControlsGrid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Label Appearance
// Cell Defaults
m_viewControlsGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
m_viewControlsGrid->SetMinSize( wxSize( -1,250 ) );
bMargins->Add( m_viewControlsGrid, 1, wxEXPAND|wxTOP|wxLEFT, 5 );
bLeftSizer->Add( m_fieldsCtrl, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
wxBoxSizer* bFieldsButtons;
bFieldsButtons = new wxBoxSizer( wxHORIZONTAL );
@ -87,32 +58,26 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
bFieldsButtons->Add( m_removeFieldButton, 0, wxBOTTOM|wxLEFT, 5 );
bMargins->Add( bFieldsButtons, 0, wxEXPAND|wxTOP, 5 );
bLeftSizer->Add( bFieldsButtons, 0, wxEXPAND, 5 );
wxBoxSizer* bPresets;
bPresets = new wxBoxSizer( wxVERTICAL );
m_staticline11 = new wxStaticLine( m_leftPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bPresets->Add( m_staticline11, 0, wxEXPAND|wxBOTTOM, 5 );
m_staticline1 = new wxStaticLine( m_leftPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bPresets->Add( m_staticline1, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
m_bomPresetsLabel = new wxStaticText( m_leftPanel, wxID_ANY, _("View presets:"), wxDefaultPosition, wxDefaultSize, 0 );
m_bomPresetsLabel->Wrap( -1 );
bPresets->Add( m_bomPresetsLabel, 0, 0, 5 );
bPresets->Add( 0, 2, 0, 0, 5 );
bPresets->Add( m_bomPresetsLabel, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
wxString m_cbBomPresetsChoices[] = { _("Default"), _("(unsaved)") };
int m_cbBomPresetsNChoices = sizeof( m_cbBomPresetsChoices ) / sizeof( wxString );
m_cbBomPresets = new wxChoice( m_leftPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_cbBomPresetsNChoices, m_cbBomPresetsChoices, 0 );
m_cbBomPresets->SetSelection( 0 );
bPresets->Add( m_cbBomPresets, 0, wxEXPAND|wxBOTTOM, 2 );
bPresets->Add( m_cbBomPresets, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 4 );
bMargins->Add( bPresets, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 );
bLeftSizer->Add( bMargins, 1, wxEXPAND|wxALL, 5 );
bLeftSizer->Add( bPresets, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
m_leftPanel->SetSizer( bLeftSizer );
@ -122,59 +87,50 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
wxBoxSizer* bRightSizer;
bRightSizer = new wxBoxSizer( wxVERTICAL );
m_nbPages = new wxNotebook( m_rightPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_panelEdit = new wxPanel( m_nbPages, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bEditSizer;
bEditSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bControls;
bControls = new wxBoxSizer( wxHORIZONTAL );
m_filter = new wxSearchCtrl( m_panelEdit, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_filter = new wxSearchCtrl( m_rightPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
#ifndef __WXMAC__
m_filter->ShowSearchButton( true );
#endif
m_filter->ShowCancelButton( true );
m_filter->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
m_filter->SetMinSize( wxSize( 240,-1 ) );
m_filter->SetMinSize( wxSize( 140,-1 ) );
bControls->Add( m_filter, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_staticline31 = new wxStaticLine( m_panelEdit, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
m_staticline31 = new wxStaticLine( m_rightPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
bControls->Add( m_staticline31, 0, wxEXPAND | wxALL, 3 );
wxString m_scopeChoices[] = { _("Entire Project"), _("Current Sheet Only"), _("Current Sheet and Down") };
int m_scopeNChoices = sizeof( m_scopeChoices ) / sizeof( wxString );
m_scope = new wxChoice( m_panelEdit, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_scopeNChoices, m_scopeChoices, 0 );
m_scope->SetSelection( 0 );
bControls->Add( m_scope, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_checkExcludeDNP = new wxCheckBox( m_rightPanel, wxID_ANY, _("Exclude DNP"), wxDefaultPosition, wxDefaultSize, 0 );
bControls->Add( m_checkExcludeDNP, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_staticline311 = new wxStaticLine( m_panelEdit, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
bControls->Add( m_staticline311, 0, wxEXPAND | wxALL, 5 );
m_checkShowExcluded = new wxCheckBox( m_rightPanel, wxID_ANY, _("Show 'Exclude from BOM'"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkShowExcluded->SetValue(true);
bControls->Add( m_checkShowExcluded, 0, wxALL, 5 );
m_groupSymbolsBox = new wxCheckBox( m_panelEdit, wxID_ANY, _("Group symbols"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticline32 = new wxStaticLine( m_rightPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
bControls->Add( m_staticline32, 0, wxEXPAND | wxALL, 3 );
m_groupSymbolsBox = new wxCheckBox( m_rightPanel, wxID_ANY, _("Group symbols"), wxDefaultPosition, wxDefaultSize, 0 );
m_groupSymbolsBox->SetValue(true);
m_groupSymbolsBox->SetToolTip( _("Group symbols together based on common properties") );
bControls->Add( m_groupSymbolsBox, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 8 );
bControls->Add( m_groupSymbolsBox, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_staticline3 = new wxStaticLine( m_panelEdit, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
bControls->Add( m_staticline3, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 3 );
m_staticline3 = new wxStaticLine( m_rightPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
bControls->Add( m_staticline3, 0, wxEXPAND | wxALL, 3 );
m_bRefresh = new STD_BITMAP_BUTTON( m_panelEdit, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_bRefresh = new STD_BITMAP_BUTTON( m_rightPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_bRefresh->SetMinSize( wxSize( 30,30 ) );
bControls->Add( m_bRefresh, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_bMenu = new STD_BITMAP_BUTTON( m_panelEdit, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_bMenu->SetMinSize( wxSize( 30,30 ) );
bControls->Add( m_bMenu, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
bRightSizer->Add( bControls, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
bEditSizer->Add( bControls, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
m_grid = new WX_GRID( m_panelEdit, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_grid = new WX_GRID( m_rightPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_grid->CreateGrid( 5, 5 );
@ -200,7 +156,51 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
m_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_CENTER );
m_grid->SetMinSize( wxSize( 400,200 ) );
bEditSizer->Add( m_grid, 1, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
bRightSizer->Add( m_grid, 1, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
m_staticline7 = new wxStaticLine( m_rightPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bRightSizer->Add( m_staticline7, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
wxFlexGridSizer* fgSizer1;
fgSizer1 = new wxFlexGridSizer( 0, 4, 0, 0 );
fgSizer1->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_scopeLabel = new wxStaticText( m_rightPanel, wxID_ANY, _("Scope:"), wxDefaultPosition, wxDefaultSize, 0 );
m_scopeLabel->Wrap( -1 );
fgSizer1->Add( m_scopeLabel, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_radioProject = new wxRadioButton( m_rightPanel, wxID_ANY, _("Entire project"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
fgSizer1->Add( m_radioProject, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
m_radioCurrentSheet = new wxRadioButton( m_rightPanel, wxID_ANY, _("Current sheet only"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_radioCurrentSheet, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
m_radioRecursive = new wxRadioButton( m_rightPanel, wxID_ANY, _("Recursive"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_radioRecursive, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_crossProbeLabel = new wxStaticText( m_rightPanel, wxID_ANY, _("Cross-probe action:"), wxDefaultPosition, wxDefaultSize, 0 );
m_crossProbeLabel->Wrap( -1 );
fgSizer1->Add( m_crossProbeLabel, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_radioHighlight = new wxRadioButton( m_rightPanel, wxID_ANY, _("Highlight"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
fgSizer1->Add( m_radioHighlight, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
m_radioSelect = new wxRadioButton( m_rightPanel, wxID_ANY, _("Select"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_radioSelect, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
m_radioOff = new wxRadioButton( m_rightPanel, wxID_ANY, _("None"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_radioOff, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
bRightSizer->Add( fgSizer1, 0, 0, 5 );
m_rightPanel->SetSizer( bRightSizer );
m_rightPanel->Layout();
bRightSizer->Fit( m_rightPanel );
m_splitterMainWindow->SplitVertically( m_leftPanel, m_rightPanel, -1 );
bEditSizer->Add( m_splitterMainWindow, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
m_panelEdit->SetSizer( bEditSizer );
@ -327,43 +327,31 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
gbExport->Fit( m_panelExport );
m_nbPages->AddPage( m_panelExport, _("Export"), false );
bRightSizer->Add( m_nbPages, 1, wxEXPAND|wxALL, 5 );
bMainSizer->Add( m_nbPages, 1, wxEXPAND | wxALL, 5 );
wxBoxSizer* bButtonsSizer;
bButtonsSizer = new wxBoxSizer( wxHORIZONTAL );
m_sidebarButton = new STD_BITMAP_BUTTON( m_rightPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_sidebarButton->SetToolTip( _("Add a new field") );
bButtonsSizer->Add( m_sidebarButton, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
bButtonsSizer->Add( 0, 0, 9, wxEXPAND, 5 );
m_buttonExport = new wxButton( m_rightPanel, wxID_ANY, _("Export"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonExport = new wxButton( this, wxID_ANY, _("Export"), wxDefaultPosition, wxDefaultSize, 0 );
bButtonsSizer->Add( m_buttonExport, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 10 );
m_buttonApply = new wxButton( m_rightPanel, wxID_ANY, _("Apply, Save Schematic && Continue"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonApply = new wxButton( this, wxID_ANY, _("Apply, Save Schematic && Continue"), wxDefaultPosition, wxDefaultSize, 0 );
bButtonsSizer->Add( m_buttonApply, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 10 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( m_rightPanel, wxID_OK );
m_sdbSizerOK = new wxButton( this, wxID_OK );
m_sdbSizer->AddButton( m_sdbSizerOK );
m_sdbSizerCancel = new wxButton( m_rightPanel, wxID_CANCEL );
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
bButtonsSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
bRightSizer->Add( bButtonsSizer, 0, wxEXPAND, 5 );
m_rightPanel->SetSizer( bRightSizer );
m_rightPanel->Layout();
bRightSizer->Fit( m_rightPanel );
m_splitterMainWindow->SplitVertically( m_leftPanel, m_rightPanel, -1 );
bMainSizer->Add( m_splitterMainWindow, 1, wxEXPAND, 5 );
bMainSizer->Add( bButtonsSizer, 0, wxEXPAND, 5 );
this->SetSizer( bMainSizer );
@ -374,22 +362,26 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnClose ) );
m_viewControlsGrid->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnViewControlsCellChanged ), NULL, this );
m_viewControlsGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnSizeViewControlsGrid ), NULL, this );
m_nbPages->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPageChanged ), NULL, this );
m_fieldsCtrl->Connect( wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED, wxDataViewEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnColumnItemToggled ), NULL, this );
m_fieldsCtrl->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnSizeFieldList ), NULL, this );
m_addFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnAddField ), NULL, this );
m_renameFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnRenameField ), NULL, this );
m_removeFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnRemoveField ), NULL, this );
m_nbPages->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPageChanged ), NULL, this );
m_filter->Connect( wxEVT_MOTION, wxMouseEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnFilterMouseMoved ), NULL, this );
m_filter->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnFilterText ), NULL, this );
m_scope->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnScope ), NULL, this );
m_checkExcludeDNP->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnExcludeDNPToggled ), NULL, this );
m_checkShowExcluded->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnShowExcludedToggled ), NULL, this );
m_groupSymbolsBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnGroupSymbolsToggled ), NULL, this );
m_bRefresh->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnRegroupSymbols ), NULL, this );
m_bMenu->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnMenu ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnTableValueChanged ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnTableCellClick ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnTableCellClick ), NULL, this );
m_grid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnTableItemContextMenu ), NULL, this );
m_grid->Connect( wxEVT_GRID_COL_SIZE, wxGridSizeEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnTableColSize ), NULL, this );
m_radioProject->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnScopeChanged ), NULL, this );
m_radioCurrentSheet->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnScopeChanged ), NULL, this );
m_radioRecursive->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnScopeChanged ), NULL, this );
m_textFieldDelimiter->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_textStringDelimiter->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_textRefDelimiter->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
@ -398,7 +390,6 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
m_checkKeepLineBreaks->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnOutputFileBrowseClicked ), NULL, this );
m_bRefreshPreview->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_sidebarButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnSidebarToggle ), NULL, this );
m_buttonExport->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnExport ), NULL, this );
m_buttonApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnSaveAndContinue ), NULL, this );
m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnCancel ), NULL, this );
@ -409,22 +400,26 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::~DIALOG_SYMBOL_FIELDS_TABLE_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnClose ) );
m_viewControlsGrid->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnViewControlsCellChanged ), NULL, this );
m_viewControlsGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnSizeViewControlsGrid ), NULL, this );
m_nbPages->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPageChanged ), NULL, this );
m_fieldsCtrl->Disconnect( wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED, wxDataViewEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnColumnItemToggled ), NULL, this );
m_fieldsCtrl->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnSizeFieldList ), NULL, this );
m_addFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnAddField ), NULL, this );
m_renameFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnRenameField ), NULL, this );
m_removeFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnRemoveField ), NULL, this );
m_nbPages->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPageChanged ), NULL, this );
m_filter->Disconnect( wxEVT_MOTION, wxMouseEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnFilterMouseMoved ), NULL, this );
m_filter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnFilterText ), NULL, this );
m_scope->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnScope ), NULL, this );
m_checkExcludeDNP->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnExcludeDNPToggled ), NULL, this );
m_checkShowExcluded->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnShowExcludedToggled ), NULL, this );
m_groupSymbolsBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnGroupSymbolsToggled ), NULL, this );
m_bRefresh->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnRegroupSymbols ), NULL, this );
m_bMenu->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnMenu ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnTableValueChanged ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnTableCellClick ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnTableCellClick ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnTableItemContextMenu ), NULL, this );
m_grid->Disconnect( wxEVT_GRID_COL_SIZE, wxGridSizeEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnTableColSize ), NULL, this );
m_radioProject->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnScopeChanged ), NULL, this );
m_radioCurrentSheet->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnScopeChanged ), NULL, this );
m_radioRecursive->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnScopeChanged ), NULL, this );
m_textFieldDelimiter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_textStringDelimiter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_textRefDelimiter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
@ -433,7 +428,6 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::~DIALOG_SYMBOL_FIELDS_TABLE_BASE()
m_checkKeepLineBreaks->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnOutputFileBrowseClicked ), NULL, this );
m_bRefreshPreview->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnPreviewRefresh ), NULL, this );
m_sidebarButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnSidebarToggle ), NULL, this );
m_buttonExport->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnExport ), NULL, this );
m_buttonApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnSaveAndContinue ), NULL, this );
m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_FIELDS_TABLE_BASE::OnCancel ), NULL, this );

File diff suppressed because it is too large Load Diff

View File

@ -14,12 +14,12 @@ class STD_BITMAP_BUTTON;
class WX_GRID;
#include "dialog_shim.h"
#include <wx/dataview.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/font.h>
#include <wx/grid.h>
#include <wx/gdicmn.h>
#include <wx/bmpbuttn.h>
#include <wx/bitmap.h>
#include <wx/image.h>
@ -32,10 +32,12 @@ class WX_GRID;
#include <wx/panel.h>
#include <wx/srchctrl.h>
#include <wx/checkbox.h>
#include <wx/grid.h>
#include <wx/radiobut.h>
#include <wx/splitter.h>
#include <wx/textctrl.h>
#include <wx/gbsizer.h>
#include <wx/notebook.h>
#include <wx/splitter.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
@ -48,27 +50,36 @@ class DIALOG_SYMBOL_FIELDS_TABLE_BASE : public DIALOG_SHIM
private:
protected:
wxNotebook* m_nbPages;
wxPanel* m_panelEdit;
wxSplitterWindow* m_splitterMainWindow;
wxPanel* m_leftPanel;
WX_GRID* m_viewControlsGrid;
wxDataViewListCtrl* m_fieldsCtrl;
STD_BITMAP_BUTTON* m_addFieldButton;
STD_BITMAP_BUTTON* m_renameFieldButton;
STD_BITMAP_BUTTON* m_removeFieldButton;
wxStaticLine* m_staticline11;
wxStaticLine* m_staticline1;
wxStaticText* m_bomPresetsLabel;
wxChoice* m_cbBomPresets;
wxPanel* m_rightPanel;
wxNotebook* m_nbPages;
wxPanel* m_panelEdit;
wxSearchCtrl* m_filter;
wxStaticLine* m_staticline31;
wxChoice* m_scope;
wxStaticLine* m_staticline311;
wxCheckBox* m_checkExcludeDNP;
wxCheckBox* m_checkShowExcluded;
wxStaticLine* m_staticline32;
wxCheckBox* m_groupSymbolsBox;
wxStaticLine* m_staticline3;
STD_BITMAP_BUTTON* m_bRefresh;
STD_BITMAP_BUTTON* m_bMenu;
WX_GRID* m_grid;
wxStaticLine* m_staticline7;
wxStaticText* m_scopeLabel;
wxRadioButton* m_radioProject;
wxRadioButton* m_radioCurrentSheet;
wxRadioButton* m_radioRecursive;
wxStaticText* m_crossProbeLabel;
wxRadioButton* m_radioHighlight;
wxRadioButton* m_radioSelect;
wxRadioButton* m_radioOff;
wxPanel* m_panelExport;
wxStaticText* m_labelFieldDelimiter;
wxTextCtrl* m_textFieldDelimiter;
@ -89,7 +100,6 @@ class DIALOG_SYMBOL_FIELDS_TABLE_BASE : public DIALOG_SHIM
wxStaticText* m_labelPreview;
STD_BITMAP_BUTTON* m_bRefreshPreview;
wxTextCtrl* m_textOutput;
STD_BITMAP_BUTTON* m_sidebarButton;
wxButton* m_buttonExport;
wxButton* m_buttonApply;
wxStdDialogButtonSizer* m_sdbSizer;
@ -98,24 +108,25 @@ class DIALOG_SYMBOL_FIELDS_TABLE_BASE : public DIALOG_SHIM
// Virtual event handlers, override them in your derived class
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnViewControlsCellChanged( wxGridEvent& event ) { event.Skip(); }
virtual void OnSizeViewControlsGrid( wxSizeEvent& event ) { event.Skip(); }
virtual void OnPageChanged( wxNotebookEvent& event ) { event.Skip(); }
virtual void OnColumnItemToggled( wxDataViewEvent& event ) { event.Skip(); }
virtual void OnSizeFieldList( wxSizeEvent& event ) { event.Skip(); }
virtual void OnAddField( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRenameField( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemoveField( wxCommandEvent& event ) { event.Skip(); }
virtual void OnPageChanged( wxNotebookEvent& event ) { event.Skip(); }
virtual void OnFilterMouseMoved( wxMouseEvent& event ) { event.Skip(); }
virtual void OnFilterText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnScope( wxCommandEvent& event ) { event.Skip(); }
virtual void OnExcludeDNPToggled( wxCommandEvent& event ) { event.Skip(); }
virtual void OnShowExcludedToggled( wxCommandEvent& event ) { event.Skip(); }
virtual void OnGroupSymbolsToggled( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRegroupSymbols( wxCommandEvent& event ) { event.Skip(); }
virtual void OnMenu( wxCommandEvent& event ) { event.Skip(); }
virtual void OnTableValueChanged( wxGridEvent& event ) { event.Skip(); }
virtual void OnTableCellClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnTableItemContextMenu( wxGridEvent& event ) { event.Skip(); }
virtual void OnTableColSize( wxGridSizeEvent& event ) { event.Skip(); }
virtual void OnScopeChanged( wxCommandEvent& event ) { event.Skip(); }
virtual void OnPreviewRefresh( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOutputFileBrowseClicked( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSidebarToggle( wxCommandEvent& event ) { event.Skip(); }
virtual void OnExport( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSaveAndContinue( wxCommandEvent& event ) { event.Skip(); }
virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); }

View File

@ -75,7 +75,6 @@ void PANEL_EESCHEMA_DISPLAY_OPTIONS::loadEEschemaSettings( EESCHEMA_SETTINGS* cf
m_checkCrossProbeCenter->SetValue( cfg->m_CrossProbing.center_on_items );
m_checkCrossProbeZoom->SetValue( cfg->m_CrossProbing.zoom_to_fit );
m_checkCrossProbeAutoHighlight->SetValue( cfg->m_CrossProbing.auto_highlight );
m_checkCrossProbeFlash->SetValue( cfg->m_CrossProbing.flash_selection );
}
@ -118,7 +117,6 @@ bool PANEL_EESCHEMA_DISPLAY_OPTIONS::TransferDataFromWindow()
cfg->m_CrossProbing.center_on_items = m_checkCrossProbeCenter->GetValue();
cfg->m_CrossProbing.zoom_to_fit = m_checkCrossProbeZoom->GetValue();
cfg->m_CrossProbing.auto_highlight = m_checkCrossProbeAutoHighlight->GetValue();
cfg->m_CrossProbing.flash_selection = m_checkCrossProbeFlash->GetValue();
}
m_galOptsPanel->TransferDataFromWindow();

View File

@ -62,10 +62,6 @@ PANEL_EESCHEMA_DISPLAY_OPTIONS_BASE::PANEL_EESCHEMA_DISPLAY_OPTIONS_BASE( wxWind
bCrossProbingSizer->Add( m_checkCrossProbeAutoHighlight, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_checkCrossProbeFlash = new wxCheckBox( this, wxID_ANY, _("Flash cross-probed selection"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkCrossProbeFlash->SetToolTip( _("Temporarily flash the newly cross-probed selection 3 times") );
bCrossProbingSizer->Add( m_checkCrossProbeFlash, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bSizer8->Add( bCrossProbingSizer, 0, wxEXPAND|wxTOP|wxLEFT, 5 );

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