Compare commits
397 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 761bfcd291 | |||
| 7663928a66 | |||
| dd3c846f4a | |||
| 6877bc32bc | |||
| 64564825c7 | |||
| b1ec1011b6 | |||
| 80539790c3 | |||
| 981772887a | |||
| 896b80652f | |||
| 968cf4267a | |||
| f3567cda99 | |||
| df372baff8 | |||
| dec96e6a77 | |||
| 8a1de8c6f8 | |||
| 255975f5fd | |||
| aa608ca147 | |||
| 682b74f7d2 | |||
| d662b2c34b | |||
| 7740c66479 | |||
| 4d4f6a810c | |||
| d74dca3a7a | |||
| 6513ca9168 | |||
| 6782bb73bd | |||
| 9c35689b04 | |||
| 8aff7cad17 | |||
| c2c6cad525 | |||
| 9b17ec5d2d | |||
| e971f90adc | |||
| 06c61a4831 | |||
| 7977f0f745 | |||
| 38a2b8eba7 | |||
| 951f0065ed | |||
| 22c06c7ed8 | |||
| 4f086271aa | |||
| 297999cb43 | |||
| 91aec9ac7f | |||
| 9105b380c3 | |||
| a285f86240 | |||
| b2f8a43c24 | |||
| 8383165269 | |||
| bc8af77aba | |||
| 7d0e1670ee | |||
| 877f7daa2b | |||
| 4c563e5ef3 | |||
| d6d6075a60 | |||
| 49c528f3ef | |||
| ae1bccfb85 | |||
| c2c13a5226 | |||
| 5b2e0d113a | |||
| 7ee8f786f2 | |||
| bd14224b42 | |||
| ccfec170b0 | |||
| 9852b535e7 | |||
| 758ac90069 | |||
| 697ff382f8 | |||
| 6b6aa84158 | |||
| a0d219c2d1 | |||
| 8af1af7f76 | |||
| 991d5812e2 | |||
| b019ce4515 | |||
| 168a1b3e75 | |||
| e8a6e579e4 | |||
| f2b1422ed5 | |||
| 63f4d45665 | |||
| 96ab1e47c9 | |||
| 4d69d966ee | |||
| e9294bee9e | |||
| d2b052b12c | |||
| 34f0a97cca | |||
| ad5ca38cc2 | |||
| 58bd7f3b24 | |||
| 5b2b4832d4 | |||
| a3618cbfeb | |||
| 8c6edc0414 | |||
| 1308fd7c4a | |||
| b241e09914 | |||
| 0a29c0dea3 | |||
| 8832b22952 | |||
| 33b93a3824 | |||
| b589da63d8 | |||
| 48077d77c4 | |||
| a605c4b6ff | |||
| 092ce30b40 | |||
| 28eb6dab97 | |||
| fb82130530 | |||
| a3d218ffbc | |||
| 471f72a340 | |||
| 2abbc601a0 | |||
| 522f1c7bea | |||
| 828f32649f | |||
| b39b54a92e | |||
| 6a55a47276 | |||
| 648d463b32 | |||
| 489f345fb2 | |||
| e308d65108 | |||
| ee0be76fb4 | |||
| 813fce2d2d | |||
| e0a27b430a | |||
| 73b2180c06 | |||
| b3f53ac862 | |||
| 9b49fc5a0d | |||
| 03c71b22d5 | |||
| 7d79bebcc6 | |||
| 5c2300022b | |||
| 91b042990f | |||
| 265e2d61be | |||
| df3924421d | |||
| 4ee2a007eb | |||
| b19a47fa2a | |||
| 7f3ca3b889 | |||
| a3d64d604c | |||
| 006f0a95c1 | |||
| 6afd865259 | |||
| d319cd4b89 | |||
| 566fefafc5 | |||
| 66bd0f850a | |||
| 491bb6e57a | |||
| 4fe74a9870 | |||
| 8f03f7c367 | |||
| 7f690d596b | |||
| be4c2715ab | |||
| 02f8260e18 | |||
| a8871fdda4 | |||
| d552ce00aa | |||
| 37dd7c6df9 | |||
| a5cbcd4abe | |||
| 4ede6f61b2 | |||
| 994c1c971a | |||
| ebdfeb4c0a | |||
| e1ffd956e6 | |||
| 3f4dc01d97 | |||
| be192d5df0 | |||
| efc35dec74 | |||
| 096566e857 | |||
| 944ee4af7d | |||
| 245894e8eb | |||
| 74abb40e84 | |||
| 1eb2983efe | |||
| 63b3e0cc4f | |||
| a8b127019c | |||
| 4d0ca33b47 | |||
| e2c53df13b | |||
| 03dd6c7a8e | |||
| bdd5a752dc | |||
| 8dbdc3717c | |||
| f60b76696a | |||
| 695505fc71 | |||
| b34dbf58c5 | |||
| 1fb19c0d81 | |||
| d6162196ec | |||
| 3ea314cb9f | |||
| 9d51fabe9b | |||
| c6b483acb9 | |||
| 96370f6665 | |||
| ad7bd9b5f8 | |||
| 2a1ef2d09d | |||
| 9f9fa0dd8d | |||
| 6ecfa65c4c | |||
| 831d438852 | |||
| a9b5b1728a | |||
| d304a30155 | |||
| 02ca96df48 | |||
| 5ca3414707 | |||
| 76a68b1f8d | |||
| 41ebd3c560 | |||
| fbc75656f4 | |||
| b882defb28 | |||
| 7d7decafd4 | |||
| 8705bea9ab | |||
| 64da49f22e | |||
| 0c9554a325 | |||
| dc24d13fef | |||
| 78cbb8e994 | |||
| ddd0ccbefd | |||
| f5797d367f | |||
| 89dff6411b | |||
| 093da7f73a | |||
| 2215e8906f | |||
| d34df3e951 | |||
| 044a2305e3 | |||
| 05264424b3 | |||
| 3e59c40283 | |||
| 2a99464fc1 | |||
| 412da66cf6 | |||
| c6215b08ed | |||
| 769060c584 | |||
| 0b48a66cb0 | |||
| 836b3219c1 | |||
| 2c0010fbcb | |||
| c1ed2506f9 | |||
| 299495a0aa | |||
| 6f3b6e3ad8 | |||
| cb9d78b46c | |||
| 46b3dcba4f | |||
| 06150388d8 | |||
| b07de4f6af | |||
| 6dd5422137 | |||
| 546ca18662 | |||
| de0f6ecf68 | |||
| 995c1a179e | |||
| bee4856a7f | |||
| 9721559005 | |||
| 7a1ab44207 | |||
| d269513857 | |||
| b4928f20a6 | |||
| 05d2893ac1 | |||
| 7ea205222d | |||
| e853b593b1 | |||
| c2a41bad09 | |||
| 1a13bed1c1 | |||
| 7b9c775cbd | |||
| e9bf1daa5f | |||
| d6727934a5 | |||
| a8df90762d | |||
| 7b4bb28307 | |||
| ee8744770f | |||
| ace480d3f6 | |||
| 154795d32a | |||
| ce20c6ec77 | |||
| 6380f29214 | |||
| 1aaf767c5d | |||
| bd4ffa493f | |||
| cf26b12478 | |||
| cdb26a9c97 | |||
| b5687b87bd | |||
| e581ba4c7b | |||
| a2064f85b1 | |||
| 2dbe4485cc | |||
| 6b7b6fa3e3 | |||
| be71f776ce | |||
| 51ba4763f0 | |||
| f9a9db6503 | |||
| 8d001a8031 | |||
| 88115e1dd2 | |||
| e914c0c1a0 | |||
| a1cd73e730 | |||
| cecc1a2ff1 | |||
| dc08cf3252 | |||
| e20a11cbb3 | |||
| c27ca33a2e | |||
| 1073ca0760 | |||
| 4440fe0935 | |||
| d1cd859765 | |||
| 36119b869c | |||
| 3e5ceaa319 | |||
| 78cd01038f | |||
| 7b4952df11 | |||
| 73acc80c1d | |||
| 8b41207351 | |||
| 5dbc1c7b18 | |||
| 5780a15468 | |||
| 15f6d5ad73 | |||
| 421bc27181 | |||
| afe41498c4 | |||
| 92c40f2761 | |||
| bb82d99a76 | |||
| 1d0e118294 | |||
| d40b12301d | |||
| 138d22b26f | |||
| 9c69ea9df3 | |||
| 3395738e55 | |||
| 6afc2e727b | |||
| f10864b3a7 | |||
| 892602c070 | |||
| d8f2a455e0 | |||
| 561b2d490d | |||
| 1869da0e7d | |||
| be2f317f6d | |||
| c248993a84 | |||
| 0a227ea916 | |||
| f75e6dae84 | |||
| 160a493885 | |||
| 625d241adf | |||
| 1264230973 | |||
| 6dfd417767 | |||
| 585f11a01d | |||
| d6a121d617 | |||
| dfd8aa402d | |||
| 5b1c84b5dd | |||
| 11586863cf | |||
| d52e50a97a | |||
| fee0028ee9 | |||
| a762311733 | |||
| e0581370e1 | |||
| 2cd0139cbf | |||
| 28cd2a203e | |||
| 33715143e3 | |||
| ba6fd2716e | |||
| 882ff06e24 | |||
| f52a51dce3 | |||
| a96e16b766 | |||
| 81e51b00ca | |||
| c01681a32e | |||
| eeb9133588 | |||
| d45769e508 | |||
| a499bc9f66 | |||
| 341f102d79 | |||
| 3e50a03ce7 | |||
| 1defa3872e | |||
| e66d25b6e8 | |||
| 76f38600af | |||
| 44b0ef64e8 | |||
| c3e7509823 | |||
| 3622a296be | |||
| 0b48913876 | |||
| 9000cfb9cd | |||
| c748645334 | |||
| 79443b7e59 | |||
| 02925fdecc | |||
| ef1e054bb6 | |||
| bb13ab2963 | |||
| 9c7fb0697c | |||
| c92b11900b | |||
| cde18d7ae7 | |||
| 1a932cb13b | |||
| cc75d8c0af | |||
| cb93d2940c | |||
| 88e0d373d1 | |||
| c2d59c6103 | |||
| f8f48f922e | |||
| eb7e781bec | |||
| 378300c733 | |||
| ddd7c35586 | |||
| 6482a322da | |||
| dc6d421fa2 | |||
| 7b19fb0c8d | |||
| f6480d67eb | |||
| 35c788a332 | |||
| a0cba3a9af | |||
| af6835e766 | |||
| 1f88d33c81 | |||
| 6aee6f857e | |||
| 6d69fee097 | |||
| c7dd993439 | |||
| 7e5dd02ef1 | |||
| ca16ff05df | |||
| b8fa10ab2b | |||
| 09736ebf2c | |||
| 897b9fe6a1 | |||
| 48f14d6dea | |||
| 1ef916086d | |||
| 0b44ba61d8 | |||
| 3c99a3797e | |||
| 76c98859bf | |||
| 57c8fbc9fe | |||
| bbac5430cf | |||
| 279ef4210d | |||
| 2ef18ad4ca | |||
| 1a76fce255 | |||
| ee75a50d84 | |||
| 99d8d0bc63 | |||
| f859fe37ca | |||
| 451cb7a194 | |||
| 17175fe71e | |||
| f8b02f99dd | |||
| 69fb86322c | |||
| 4d683232b7 | |||
| cb7e0e4383 | |||
| 90b62762d3 | |||
| 787a9ae4e4 | |||
| 83be5ba63d | |||
| e1cad6189e | |||
| f29fc2a025 | |||
| 43d4c8d801 | |||
| c179f4d4f1 | |||
| ac8b3989be | |||
| 9a7b1a20dc | |||
| cff58bae7f | |||
| 2ee2d7d5d9 | |||
| 743759578d | |||
| 9f1d1fc45e | |||
| b4ea25dccb | |||
| f15551a6b5 | |||
| 5c0a654e1e | |||
| edace908fb | |||
| ff966eaf62 | |||
| a39b9b8890 | |||
| 9f39420808 | |||
| 67b5e86cc4 | |||
| baaa8b6537 | |||
| 4f776050e6 | |||
| fa490644dd | |||
| 0363806e7e | |||
| c0a608bfdd | |||
| fe26628113 | |||
| c7ead70e0f | |||
| 31177be88f | |||
| 48fd6bab7b | |||
| 9fd2b32665 | |||
| 1ba05d4c9c | |||
| bae3ccdfb5 | |||
| dd2f15c96d | |||
| 7e04a1b8d3 | |||
| aea70a14ff | |||
| 8edfc23679 | |||
| 87f3d45109 | |||
| 2ca07b47af |
+1
-1
@@ -6,7 +6,7 @@ build_doxygen_docker:
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_JOB_NAME == "doxygen"
|
||||
tags:
|
||||
- docker
|
||||
- gitlab-org-docker
|
||||
before_script:
|
||||
- docker info
|
||||
- docker login -u gitlab-ci-token -p "$CI_JOB_TOKEN" "$CI_REGISTRY"
|
||||
|
||||
+1
-19
@@ -15,25 +15,7 @@ macos_build:
|
||||
- cd build/macos
|
||||
- cmake
|
||||
-G Ninja
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DDEFAULT_INSTALL_PATH=/Library/Application\ Support /kicad
|
||||
-DOCC_INCLUDE_DIR=/opt/homebrew/Cellar/opencascade/7.7.2_2/include/opencascade
|
||||
-DOCC_LIBRARY_DIR=/opt/homebrew/Cellar/opencascade/7.7.2_2/Lib
|
||||
-DCMAKE_INSTALL_PREFIX=/Users/ci/kicad-mac-builder/build/kicad-dest
|
||||
-DCMAKE_C_COMPILER=/usr/bin/clang
|
||||
-DCMAKE_CXX_COMPILER=/usr/bin/clang++
|
||||
-DwxWidgets_CONFIG_EXECUTABLE=/Users/ci/kicad-mac-builder/build/wxwidgets-dest/bin/wx-config
|
||||
-DKICAD_BUILD_I18N=ON
|
||||
-DKICAD_SCRIPTING_WXPYTHON=ON
|
||||
-DKICAD_BUILD_PNS_DEBUG_TOOL=ON
|
||||
-DPYTHON_EXECUTABLE=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework/Versions/Current/bin/python3
|
||||
-DPYTHON_INCLUDE_DIR=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework/Versions/Current/include/python3.9/
|
||||
-DPYTHON_LIBRARY=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework/Versions/Current/lib/libpython3.9.dylib
|
||||
-DPYTHON_SITE_PACKAGE_PATH=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework/Versions/Current/lib/python3.9/site-packages
|
||||
-DPYTHON_FRAMEWORK=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework
|
||||
-DNGSPICE_INCLUDE_DIR=/Users/ci/kicad-mac-builder/build/ngspice-dest/include
|
||||
-DNGSPICE_LIBRARY=/Users/ci/kicad-mac-builder/build/ngspice-dest/lib/libngspice.dylib
|
||||
-DKICAD_USE_3DCONNEXION=ON
|
||||
-DCMAKE_TOOLCHAIN_FILE=/Users/ci/kicad-mac-builder/toolchain/kicad-mac-builder.cmake
|
||||
../../
|
||||
- cmake --build . 2>&1 | tee compilation_log.txt
|
||||
- cd ../../
|
||||
|
||||
@@ -708,6 +708,8 @@ void BOARD_ADAPTER::SetLayerColors( const std::map<int, COLOR4D>& aColors )
|
||||
|
||||
for( const auto& [ layer, color ] : aColors )
|
||||
settings->SetColor( layer, color );
|
||||
|
||||
Pgm().GetSettingsManager().SaveColorSettings( settings, "3d_viewer" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <3d_rendering/opengl/render_3d_opengl.h>
|
||||
#include <3d_viewer_id.h>
|
||||
#include <advanced_config.h>
|
||||
#include <build_version.h>
|
||||
#include <board.h>
|
||||
#include <reporter.h>
|
||||
#include <gal/opengl/gl_context_mgr.h>
|
||||
@@ -229,6 +230,9 @@ bool EDA_3D_CANVAS::initializeOpenGL()
|
||||
From_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
|
||||
}
|
||||
|
||||
SetOpenGLInfo( (const char*) glGetString( GL_VENDOR ), (const char*) glGetString( GL_RENDERER ),
|
||||
(const char*) glGetString( GL_VERSION ) );
|
||||
|
||||
wxString version = From_UTF8( (char *) glGetString( GL_VERSION ) );
|
||||
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::%s OpenGL version string %s." ),
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2024 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
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "../3d_cache/3d_cache.h"
|
||||
#include <wx/dcclient.h>
|
||||
#include <base_units.h>
|
||||
#include <build_version.h>
|
||||
#include <gal/opengl/gl_context_mgr.h>
|
||||
#include <settings/common_settings.h>
|
||||
#include <pgm_base.h>
|
||||
@@ -102,11 +103,6 @@ EDA_3D_MODEL_VIEWER::EDA_3D_MODEL_VIEWER( wxWindow* aParent, const int* aAttribL
|
||||
m_BiuTo3dUnits = 1.0;
|
||||
|
||||
m_glRC = nullptr;
|
||||
|
||||
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
|
||||
|
||||
const DPI_SCALING_COMMON dpi{ settings, this };
|
||||
SetScaleFactor( dpi.GetScaleFactor() );
|
||||
}
|
||||
|
||||
|
||||
@@ -200,6 +196,9 @@ void EDA_3D_MODEL_VIEWER::ogl_initialize()
|
||||
From_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
|
||||
}
|
||||
|
||||
SetOpenGLInfo( (const char*) glGetString( GL_VENDOR ), (const char*) glGetString( GL_RENDERER ),
|
||||
(const char*) glGetString( GL_VERSION ) );
|
||||
|
||||
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
|
||||
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
|
||||
glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
|
||||
|
||||
@@ -812,9 +812,6 @@ void EDA_3D_VIEWER_FRAME::loadCommonSettings()
|
||||
|
||||
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
|
||||
|
||||
const DPI_SCALING_COMMON dpi{ settings, this };
|
||||
m_canvas->SetScaleFactor( dpi.GetScaleFactor() );
|
||||
|
||||
// TODO(JE) use all control options
|
||||
m_boardAdapter.m_MousewheelPanning = settings->m_Input.scroll_modifier_zoom != 0;
|
||||
}
|
||||
|
||||
@@ -210,9 +210,6 @@ void PANEL_PREVIEW_3D_MODEL::loadSettings()
|
||||
|
||||
COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
|
||||
|
||||
const DPI_SCALING_COMMON dpi{ settings, this };
|
||||
m_previewPane->SetScaleFactor( dpi.GetScaleFactor() );
|
||||
|
||||
// TODO(JE) use all control options
|
||||
m_boardAdapter.m_MousewheelPanning = settings->m_Input.scroll_modifier_zoom != 0;
|
||||
|
||||
@@ -444,10 +441,15 @@ void PANEL_PREVIEW_3D_MODEL::doIncrementScale( wxSpinEvent& event, double aSign
|
||||
else if( spinCtrl == m_spinZscale )
|
||||
textCtrl = zscale;
|
||||
|
||||
double step = SCALE_INCREMENT;
|
||||
|
||||
if( wxGetMouseState().ShiftDown( ) )
|
||||
step = SCALE_INCREMENT_FINE;
|
||||
|
||||
double curr_value = EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::UNSCALED,
|
||||
textCtrl->GetValue() );
|
||||
|
||||
curr_value += ( SCALE_INCREMENT * aSign );
|
||||
curr_value += ( step * aSign );
|
||||
curr_value = std::max( 1/MAX_SCALE, curr_value );
|
||||
curr_value = std::min( curr_value, MAX_SCALE );
|
||||
|
||||
@@ -465,10 +467,15 @@ void PANEL_PREVIEW_3D_MODEL::doIncrementRotation( wxSpinEvent& aEvent, double aS
|
||||
else if( spinCtrl == m_spinZrot )
|
||||
textCtrl = zrot;
|
||||
|
||||
double step = ROTATION_INCREMENT;
|
||||
|
||||
if( wxGetMouseState().ShiftDown( ) )
|
||||
step = ROTATION_INCREMENT_FINE;
|
||||
|
||||
double curr_value = EDA_UNIT_UTILS::UI::DoubleValueFromString( unityScale, EDA_UNITS::DEGREES,
|
||||
textCtrl->GetValue() );
|
||||
|
||||
curr_value += ( ROTATION_INCREMENT * aSign );
|
||||
curr_value += ( step * aSign );
|
||||
curr_value = std::max( -MAX_ROTATION, curr_value );
|
||||
curr_value = std::min( curr_value, MAX_ROTATION );
|
||||
|
||||
@@ -488,16 +495,22 @@ void PANEL_PREVIEW_3D_MODEL::doIncrementOffset( wxSpinEvent& event, double aSign
|
||||
textCtrl = zoff;
|
||||
|
||||
double step_mm = OFFSET_INCREMENT_MM;
|
||||
double curr_value_mm =
|
||||
EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, m_userUnits,
|
||||
textCtrl->GetValue() )
|
||||
/ pcbIUScale.IU_PER_MM;
|
||||
|
||||
if( wxGetMouseState().ShiftDown( ) )
|
||||
step_mm = OFFSET_INCREMENT_MM_FINE;
|
||||
|
||||
if( m_userUnits == EDA_UNITS::MILS || m_userUnits == EDA_UNITS::INCHES )
|
||||
{
|
||||
step_mm = 25.4*OFFSET_INCREMENT_MIL/1000;
|
||||
|
||||
if( wxGetMouseState().ShiftDown( ) )
|
||||
step_mm = 25.4*OFFSET_INCREMENT_MIL_FINE/1000;;
|
||||
}
|
||||
|
||||
double curr_value_mm = EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, m_userUnits,
|
||||
textCtrl->GetValue() )
|
||||
/ pcbIUScale.IU_PER_MM;
|
||||
|
||||
curr_value_mm += ( step_mm * aSign );
|
||||
curr_value_mm = std::max( -MAX_OFFSET, curr_value_mm );
|
||||
curr_value_mm = std::min( curr_value_mm, MAX_OFFSET );
|
||||
@@ -533,10 +546,10 @@ void PANEL_PREVIEW_3D_MODEL::onMouseWheelRot( wxMouseEvent& event )
|
||||
{
|
||||
wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
|
||||
|
||||
double step = ROTATION_INCREMENT_WHEEL;
|
||||
double step = ROTATION_INCREMENT;
|
||||
|
||||
if( event.ShiftDown( ) )
|
||||
step = ROTATION_INCREMENT_WHEEL_FINE;
|
||||
step = ROTATION_INCREMENT_FINE;
|
||||
|
||||
if( event.GetWheelRotation() >= 0 )
|
||||
step = -step;
|
||||
|
||||
@@ -43,9 +43,8 @@
|
||||
#define SCALE_INCREMENT_FINE 0.02
|
||||
#define SCALE_INCREMENT 0.1
|
||||
|
||||
#define ROTATION_INCREMENT 90 // in degrees, for spin button command
|
||||
#define ROTATION_INCREMENT_WHEEL 90 // in degrees, for mouse wheel command
|
||||
#define ROTATION_INCREMENT_WHEEL_FINE 1 // in degrees, for mouse wheel command
|
||||
#define ROTATION_INCREMENT 90 // in degrees
|
||||
#define ROTATION_INCREMENT_FINE 1 // in degrees
|
||||
|
||||
#define OFFSET_INCREMENT_MM 0.5
|
||||
#define OFFSET_INCREMENT_MM_FINE 0.1
|
||||
|
||||
@@ -138,7 +138,7 @@ void IMAGE_SIZE::SetUnit( EDA_UNITS aUnit )
|
||||
}
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE( BITMAP2CMP_FRAME, EDA_BASE_FRAME )
|
||||
BEGIN_EVENT_TABLE( BITMAP2CMP_FRAME, KIWAY_PLAYER )
|
||||
EVT_MENU( wxID_CLOSE, BITMAP2CMP_FRAME::OnExit )
|
||||
EVT_MENU( wxID_EXIT, BITMAP2CMP_FRAME::OnExit )
|
||||
|
||||
@@ -193,6 +193,7 @@ BITMAP2CMP_FRAME::BITMAP2CMP_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||
m_toolManager->InitTools();
|
||||
|
||||
ReCreateMenuBar();
|
||||
setupUIConditions();
|
||||
|
||||
GetSizer()->SetSizeHints( this );
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ unset(_Python_NAMES)
|
||||
|
||||
set(_PYTHON1_VERSIONS 1.6 1.5)
|
||||
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
|
||||
set(_PYTHON3_VERSIONS 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
set(_PYTHON3_VERSIONS 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
|
||||
# Disabling the "search every possible place" code for now
|
||||
# see https://gitlab.com/kicad/code/kicad/-/issues/8553
|
||||
|
||||
@@ -44,7 +44,7 @@ cmake_find_frameworks(Python)
|
||||
|
||||
set(_PYTHON1_VERSIONS 1.6 1.5)
|
||||
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
|
||||
set(_PYTHON3_VERSIONS 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
set(_PYTHON3_VERSIONS 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
|
||||
if(PythonLibs_FIND_VERSION)
|
||||
if(PythonLibs_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "8.0.2" )
|
||||
set( KICAD_SEMANTIC_VERSION "8.0.4" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -51,6 +51,19 @@ extern std::string GetCurlLibVersion();
|
||||
#include <kicad_build_version.h>
|
||||
#undef INCLUDE_KICAD_VERSION
|
||||
|
||||
// Remember OpenGL info
|
||||
static wxString s_glVendor;
|
||||
static wxString s_glRenderer;
|
||||
static wxString s_glVersion;
|
||||
|
||||
void SetOpenGLInfo( const char* aVendor, const char* aRenderer, const char* aVersion )
|
||||
{
|
||||
s_glVendor = wxString::FromUTF8( aVendor );
|
||||
s_glRenderer = wxString::FromUTF8( aRenderer );
|
||||
s_glVersion = wxString::FromUTF8( aVersion );
|
||||
}
|
||||
|
||||
|
||||
wxString GetPlatformGetBitnessName()
|
||||
{
|
||||
wxPlatformInfo platform;
|
||||
@@ -200,6 +213,12 @@ wxString GetVersionInfoData( const wxString& aTitle, bool aHtml, bool aBrief )
|
||||
<< ", " << wxGetenv( "XDG_SESSION_TYPE" );
|
||||
#endif
|
||||
|
||||
if( !s_glVendor.empty() || !s_glRenderer.empty() || !s_glVersion.empty() )
|
||||
{
|
||||
aMsg << eol;
|
||||
aMsg << "OpenGL: " << s_glVendor << ", " << s_glRenderer << ", " << s_glVersion;
|
||||
}
|
||||
|
||||
aMsg << eol << eol;
|
||||
|
||||
if( !aBrief )
|
||||
|
||||
@@ -347,6 +347,24 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectOne: table `%s` not in row cache; will SelectAll" ),
|
||||
tableName, aWhere.second );
|
||||
|
||||
selectAllAndCache( tableName, aWhere.first );
|
||||
|
||||
if( m_cache->Get( tableName, cacheEntry ) )
|
||||
{
|
||||
if( cacheEntry.count( aWhere.second ) )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectOne: `%s` with parameter `%s` - cache hit" ),
|
||||
tableName, aWhere.second );
|
||||
aResult = cacheEntry.at( aWhere.second );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_columnCache.count( tableName ) )
|
||||
{
|
||||
@@ -372,15 +390,14 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
columnsFor( tableName ),
|
||||
m_quoteChar, tableName, m_quoteChar,
|
||||
m_quoteChar, columnName, m_quoteChar );
|
||||
|
||||
nanodbc::statement statement( *m_conn );
|
||||
nanodbc::string query = fromUTF8( queryStr );
|
||||
|
||||
PROF_TIMER timer;
|
||||
nanodbc::statement statement;
|
||||
|
||||
try
|
||||
{
|
||||
statement.prepare( query );
|
||||
statement.prepare( *m_conn, query );
|
||||
statement.bind( 0, aWhere.second.c_str() );
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
@@ -474,44 +491,14 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
}
|
||||
|
||||
|
||||
bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::string& aKey,
|
||||
std::vector<ROW>& aResults )
|
||||
bool DATABASE_CONNECTION::selectAllAndCache( const std::string& aTable, const std::string& aKey )
|
||||
{
|
||||
if( !m_conn )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "Called SelectAll without valid connection!" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
auto tableMapIter = m_tables.find( aTable );
|
||||
|
||||
if( tableMapIter == m_tables.end() )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll: requested table %s not found in cache" ),
|
||||
aTable );
|
||||
return false;
|
||||
}
|
||||
|
||||
DB_CACHE_TYPE::CACHE_VALUE cacheEntry;
|
||||
|
||||
if( m_cache->Get( aTable, cacheEntry ) )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` - cache hit" ), aTable );
|
||||
|
||||
aResults.reserve( cacheEntry.size() );
|
||||
|
||||
for( auto &[ key, row ] : cacheEntry )
|
||||
aResults.emplace_back( row );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nanodbc::statement statement( *m_conn );
|
||||
|
||||
nanodbc::string query = fromUTF8( fmt::format( "SELECT {} FROM {}{}{}", columnsFor( aTable ),
|
||||
m_quoteChar, aTable, m_quoteChar ) );
|
||||
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s`" ), toUTF8( query ) );
|
||||
wxLogTrace( traceDatabase, wxT( "selectAllAndCache: `%s`" ), toUTF8( query ) );
|
||||
|
||||
PROF_TIMER timer;
|
||||
|
||||
@@ -522,7 +509,8 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
|
||||
catch( nanodbc::database_error& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while preparing query for SelectAll: %s" ),
|
||||
wxLogTrace( traceDatabase,
|
||||
wxT( "Exception while preparing query for selectAllAndCache: %s" ),
|
||||
m_lastError );
|
||||
|
||||
// Exception may be due to a connection error; nanodbc won't auto-reconnect
|
||||
@@ -540,7 +528,8 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
|
||||
catch( nanodbc::database_error& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while executing query for SelectAll: %s" ),
|
||||
wxLogTrace( traceDatabase,
|
||||
wxT( "Exception while executing query for selectAllAndCache: %s" ),
|
||||
m_lastError );
|
||||
|
||||
// Exception may be due to a connection error; nanodbc won't auto-reconnect
|
||||
@@ -551,15 +540,17 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
|
||||
|
||||
timer.Stop();
|
||||
|
||||
DB_CACHE_TYPE::CACHE_VALUE cacheEntry;
|
||||
|
||||
auto handleException =
|
||||
[&]( std::runtime_error& aException, const std::string& aExtraContext = "" )
|
||||
{
|
||||
m_lastError = aException.what();
|
||||
std::string extra = aExtraContext.empty() ? "" : ": " + aExtraContext;
|
||||
wxLogTrace( traceDatabase,
|
||||
wxT( "Exception while parsing result %d from SelectAll: %s%s" ),
|
||||
aResults.size(), m_lastError, extra );
|
||||
};
|
||||
{
|
||||
m_lastError = aException.what();
|
||||
std::string extra = aExtraContext.empty() ? "" : ": " + aExtraContext;
|
||||
wxLogTrace( traceDatabase,
|
||||
wxT( "Exception while parsing result %d from selectAllAndCache: %s%s" ),
|
||||
cacheEntry.size(), m_lastError, extra );
|
||||
};
|
||||
|
||||
while( results.next() )
|
||||
{
|
||||
@@ -636,20 +627,64 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
|
||||
}
|
||||
}
|
||||
|
||||
aResults.emplace_back( std::move( result ) );
|
||||
wxASSERT( result.count( aKey ) );
|
||||
std::string keyStr = std::any_cast<std::string>( result.at( aKey ) );
|
||||
cacheEntry[keyStr] = result;
|
||||
}
|
||||
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll from %s completed in %0.1f ms" ), aTable,
|
||||
wxLogTrace( traceDatabase, wxT( "selectAllAndCache from %s completed in %0.1f ms" ), aTable,
|
||||
timer.msecs() );
|
||||
|
||||
for( const ROW& row : aResults )
|
||||
m_cache->Put( aTable, cacheEntry );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::string& aKey,
|
||||
std::vector<ROW>& aResults )
|
||||
{
|
||||
if( !m_conn )
|
||||
{
|
||||
wxASSERT( row.count( aKey ) );
|
||||
std::string keyStr = std::any_cast<std::string>( row.at( aKey ) );
|
||||
cacheEntry[keyStr] = row;
|
||||
wxLogTrace( traceDatabase, wxT( "Called SelectAll without valid connection!" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cache->Put( aTable, cacheEntry );
|
||||
auto tableMapIter = m_tables.find( aTable );
|
||||
|
||||
if( tableMapIter == m_tables.end() )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll: requested table %s not found in cache" ),
|
||||
aTable );
|
||||
return false;
|
||||
}
|
||||
|
||||
DB_CACHE_TYPE::CACHE_VALUE cacheEntry;
|
||||
|
||||
if( !m_cache->Get( aTable, cacheEntry ) )
|
||||
{
|
||||
if( !selectAllAndCache( aTable, aKey ) )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` cache fill failed" ), aTable );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now it should be filled
|
||||
m_cache->Get( aTable, cacheEntry );
|
||||
}
|
||||
|
||||
if( !m_cache->Get( aTable, cacheEntry ) )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` failed to get results from cache!" ),
|
||||
aTable );
|
||||
return false;
|
||||
}
|
||||
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` - returning cached results" ), aTable );
|
||||
|
||||
aResults.reserve( cacheEntry.size() );
|
||||
|
||||
for( auto &[ key, row ] : cacheEntry )
|
||||
aResults.emplace_back( row );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,9 @@ void DIALOG_EDIT_LIBRARY_TABLES::InstallPanel( wxPanel* aPanel )
|
||||
auto mainSizer = new wxBoxSizer( wxVERTICAL );
|
||||
SetSizer( mainSizer );
|
||||
|
||||
m_infoBar = new WX_INFOBAR( this );
|
||||
mainSizer->Add( m_infoBar, 0, wxEXPAND, 0 );
|
||||
|
||||
mainSizer->Add( m_contentPanel, 1, wxEXPAND|wxLEFT|wxTOP|wxRIGHT, 5 );
|
||||
m_contentPanel->SetMinSize( FromDIP( wxSize( 1000, 600 ) ) );
|
||||
|
||||
|
||||
@@ -442,14 +442,11 @@ bool PANEL_SETUP_NETCLASSES::TransferDataFromWindow()
|
||||
wxString netclass = m_assignmentGrid->GetCellValue( row, 1 );
|
||||
|
||||
m_netSettings->m_NetClassPatternAssignments.push_back(
|
||||
{
|
||||
std::make_unique<EDA_COMBINED_MATCHER>( pattern, CTX_NETCLASS ),
|
||||
netclass
|
||||
} );
|
||||
|
||||
m_netSettings->m_NetClassPatternAssignmentCache.clear();
|
||||
{ std::make_unique<EDA_COMBINED_MATCHER>( pattern, CTX_NETCLASS ), netclass } );
|
||||
}
|
||||
|
||||
m_netSettings->m_NetClassPatternAssignmentCache.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -648,8 +648,21 @@ void EDA_DRAW_PANEL_GAL::onShowTimer( wxTimerEvent& aEvent )
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::SetCurrentCursor( KICURSOR aCursor )
|
||||
{
|
||||
if( m_gal )
|
||||
m_gal->SetNativeCursorStyle( aCursor );
|
||||
if( !m_gal )
|
||||
return;
|
||||
|
||||
DPI_SCALING_COMMON dpi( nullptr, m_parent );
|
||||
|
||||
bool hidpi = false;
|
||||
|
||||
// Cursor scaling factor cannot be set for a wxCursor on GTK and OSX (at least before wx 3.3),
|
||||
// resulting in 4x rendered size on 2x window scale.
|
||||
// MSW renders the bitmap as-is, without scaling, so this works here.
|
||||
#ifdef __WXMSW__
|
||||
hidpi = dpi.GetContentScaleFactor() >= 2.0;
|
||||
#endif
|
||||
|
||||
m_gal->SetNativeCursorStyle( aCursor, hidpi );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -681,6 +681,35 @@ void DS_DATA_ITEM_TEXT::SetConstrainedTextSize()
|
||||
|
||||
if( m_ConstrainedTextSize.y == 0 )
|
||||
m_ConstrainedTextSize.y = DS_DATA_MODEL::GetTheInstance().m_DefaultTextSize.y;
|
||||
|
||||
if( m_BoundingBoxSize.x > 0 || m_BoundingBoxSize.y > 0 )
|
||||
{
|
||||
// to know the X and Y size of the line, we should use EDA_TEXT::GetTextBox()
|
||||
// but this function uses integers
|
||||
// So, to avoid truncations with our unit in mm, use microns.
|
||||
VECTOR2I size_micron;
|
||||
#define FSCALE 1000.0
|
||||
int linewidth = 0;
|
||||
size_micron.x = KiROUND( m_ConstrainedTextSize.x * FSCALE );
|
||||
size_micron.y = KiROUND( m_ConstrainedTextSize.y * FSCALE );
|
||||
DS_DRAW_ITEM_TEXT dummy( unityScale, this, 0, m_FullText, VECTOR2I( 0, 0 ), size_micron,
|
||||
linewidth, m_Font, m_Italic, m_Bold, m_TextColor );
|
||||
dummy.SetMultilineAllowed( true );
|
||||
dummy.SetHorizJustify( m_Hjustify ) ;
|
||||
dummy.SetVertJustify( m_Vjustify );
|
||||
dummy.SetTextAngle( EDA_ANGLE( m_Orient, DEGREES_T ) );
|
||||
|
||||
BOX2I rect = dummy.GetTextBox();
|
||||
VECTOR2D size;
|
||||
size.x = KiROUND( (int) rect.GetWidth() / FSCALE );
|
||||
size.y = KiROUND( (int) rect.GetHeight() / FSCALE );
|
||||
|
||||
if( m_BoundingBoxSize.x > 0 && size.x > m_BoundingBoxSize.x )
|
||||
m_ConstrainedTextSize.x *= m_BoundingBoxSize.x / size.x;
|
||||
|
||||
if( m_BoundingBoxSize.y > 0 && size.y > m_BoundingBoxSize.y )
|
||||
m_ConstrainedTextSize.y *= m_BoundingBoxSize.y / size.y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1991,13 +1991,13 @@ static struct EDA_SHAPE_DESC
|
||||
.SetAvailableFunc( isNotPolygonOrCircle );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Center X" ),
|
||||
&EDA_SHAPE::SetStartX, &EDA_SHAPE::GetStartX, PROPERTY_DISPLAY::PT_COORD,
|
||||
&EDA_SHAPE::SetCenterX, &EDA_SHAPE::GetStartX, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_X_COORD ),
|
||||
shapeProps )
|
||||
.SetAvailableFunc( isCircle );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Center Y" ),
|
||||
&EDA_SHAPE::SetStartY, &EDA_SHAPE::GetStartY, PROPERTY_DISPLAY::PT_COORD,
|
||||
&EDA_SHAPE::SetCenterY, &EDA_SHAPE::GetStartY, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_Y_COORD ),
|
||||
shapeProps )
|
||||
.SetAvailableFunc( isCircle );
|
||||
|
||||
+5
-1
@@ -528,10 +528,13 @@ EDA_TEXT::GetRenderCache( const KIFONT::FONT* aFont, const wxString& forResolved
|
||||
}
|
||||
|
||||
|
||||
void EDA_TEXT::SetupRenderCache( const wxString& aResolvedText, const EDA_ANGLE& aAngle )
|
||||
void EDA_TEXT::SetupRenderCache( const wxString& aResolvedText, const KIFONT::FONT* aFont,
|
||||
const EDA_ANGLE& aAngle, const VECTOR2I& aOffset )
|
||||
{
|
||||
m_render_cache_text = aResolvedText;
|
||||
m_render_cache_font = aFont;
|
||||
m_render_cache_angle = aAngle;
|
||||
m_render_cache_offset = aOffset;
|
||||
m_render_cache.clear();
|
||||
}
|
||||
|
||||
@@ -539,6 +542,7 @@ void EDA_TEXT::SetupRenderCache( const wxString& aResolvedText, const EDA_ANGLE&
|
||||
void EDA_TEXT::AddRenderCacheGlyph( const SHAPE_POLY_SET& aPoly )
|
||||
{
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( aPoly ) );
|
||||
static_cast<KIFONT::OUTLINE_GLYPH*>( m_render_cache.back().get() )->CacheTriangulation();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <string_utils.h>
|
||||
#include <macros.h>
|
||||
#include <cstdint>
|
||||
#include <reporter.h>
|
||||
|
||||
#ifdef __WIN32__
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
@@ -37,6 +38,8 @@ using namespace fontconfig;
|
||||
static FONTCONFIG* g_config = nullptr;
|
||||
static bool g_fcInitSuccess = false;
|
||||
|
||||
REPORTER* FONTCONFIG::s_reporter = nullptr;
|
||||
|
||||
/**
|
||||
* A simple wrapper to avoid exporing fontconfig in the header
|
||||
*/
|
||||
@@ -57,6 +60,12 @@ FONTCONFIG::FONTCONFIG()
|
||||
};
|
||||
|
||||
|
||||
void fontconfig::FONTCONFIG::SetReporter( REPORTER* aReporter )
|
||||
{
|
||||
s_reporter = aReporter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is simply a wrapper to call FcInit() with SEH for Windows
|
||||
* SEH on Windows can only be used in functions without objects that might be unwinded
|
||||
@@ -317,12 +326,15 @@ FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString
|
||||
|
||||
if( retval == FF_RESULT::FF_ERROR )
|
||||
{
|
||||
wxLogWarning( _( "Error loading font '%s'." ), qualifiedFontName );
|
||||
if( s_reporter )
|
||||
s_reporter->Report( wxString::Format( _( "Error loading font '%s'." ), qualifiedFontName ) );
|
||||
}
|
||||
else if( retval == FF_RESULT::FF_SUBSTITUTE )
|
||||
{
|
||||
fontName.Replace( ':', ' ' );
|
||||
wxLogWarning( _( "Font '%s' not found; substituting '%s'." ), qualifiedFontName, fontName );
|
||||
|
||||
if( s_reporter )
|
||||
s_reporter->Report( wxString::Format( _( "Font '%s' not found; substituting '%s'." ), qualifiedFontName, fontName ) );
|
||||
}
|
||||
|
||||
FcPatternDestroy( pat );
|
||||
|
||||
@@ -259,6 +259,7 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_pt
|
||||
struct GLYPH_CACHE_KEY {
|
||||
FT_Face face;
|
||||
hb_codepoint_t codepoint;
|
||||
double scaler;
|
||||
bool fakeItalic;
|
||||
bool fakeBold;
|
||||
bool mirror;
|
||||
@@ -266,7 +267,7 @@ struct GLYPH_CACHE_KEY {
|
||||
|
||||
bool operator==(const GLYPH_CACHE_KEY& rhs ) const
|
||||
{
|
||||
return face == rhs.face && codepoint == rhs.codepoint
|
||||
return face == rhs.face && codepoint == rhs.codepoint && scaler == rhs.scaler
|
||||
&& fakeItalic == rhs.fakeItalic && fakeBold == rhs.fakeBold
|
||||
&& mirror == rhs.mirror && angle == rhs.angle;
|
||||
}
|
||||
@@ -280,6 +281,7 @@ namespace std
|
||||
std::size_t operator()( const GLYPH_CACHE_KEY& k ) const
|
||||
{
|
||||
return hash<const void*>()( k.face ) ^ hash<unsigned>()( k.codepoint )
|
||||
^ hash<double>()( k.scaler )
|
||||
^ hash<int>()( k.fakeItalic ) ^ hash<int>()( k.fakeBold )
|
||||
^ hash<int>()( k.mirror ) ^ hash<int>()( k.angle.AsTenthsOfADegree() );
|
||||
}
|
||||
@@ -339,7 +341,7 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
GLYPH_CACHE_KEY key = { face, glyphInfo[i].codepoint, m_fakeItal, m_fakeBold,
|
||||
GLYPH_CACHE_KEY key = { face, glyphInfo[i].codepoint, scaler, m_fakeItal, m_fakeBold,
|
||||
aMirror, aAngle };
|
||||
GLYPH_DATA& glyphData = s_glyphCache[ key ];
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ static double roundp( double x )
|
||||
|
||||
const VECTOR2D CAIRO_GAL_BASE::roundp( const VECTOR2D& v )
|
||||
{
|
||||
if( m_lineWidthIsOdd && m_isStrokeEnabled )
|
||||
if( m_lineWidthIsOdd )
|
||||
return VECTOR2D( ::roundp( v.x ), ::roundp( v.y ) );
|
||||
else
|
||||
return VECTOR2D( floor( v.x + 0.5 ), floor( v.y + 0.5 ) );
|
||||
@@ -352,13 +352,18 @@ void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
|
||||
double r = xform( aRadius );
|
||||
|
||||
// N.B. This is backwards. We set this because we want to adjust the center
|
||||
// point that changes both endpoints. In the worst case, this is twice as far.
|
||||
// We cannot adjust radius or center based on the other because this causes the
|
||||
// whole arc to change position/size
|
||||
m_lineWidthIsOdd = !( static_cast<int>( aRadius ) % 2 );
|
||||
// Adjust center and radius slightly to better match the rounding of endpoints.
|
||||
VECTOR2D mid = roundp( xform( aCenterPoint ) );
|
||||
|
||||
auto mid = roundp( xform( aCenterPoint ) );
|
||||
VECTOR2D startPointS = VECTOR2D( r, 0.0 );
|
||||
VECTOR2D endPointS = VECTOR2D( r, 0.0 );
|
||||
RotatePoint( startPointS, -EDA_ANGLE( startAngle, RADIANS_T ) );
|
||||
RotatePoint( endPointS, -EDA_ANGLE( endAngle, RADIANS_T ) );
|
||||
|
||||
VECTOR2D refStart = roundp( xform( aCenterPoint ) + startPointS );
|
||||
VECTOR2D refEnd = roundp( xform( aCenterPoint ) + endPointS );
|
||||
|
||||
r = ( ( refStart - mid ).EuclideanNorm() + ( refEnd - mid ).EuclideanNorm() ) / 2.0;
|
||||
|
||||
cairo_set_line_width( m_currentContext, m_lineWidthInPixels );
|
||||
cairo_new_sub_path( m_currentContext );
|
||||
@@ -403,13 +408,7 @@ void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadiu
|
||||
|
||||
double r = xform( aRadius );
|
||||
|
||||
// N.B. This is backwards. We set this because we want to adjust the center
|
||||
// point that changes both endpoints. In the worst case, this is twice as far.
|
||||
// We cannot adjust radius or center based on the other because this causes the
|
||||
// whole arc to change position/size
|
||||
m_lineWidthIsOdd = !( static_cast<int>( aRadius ) % 2 );
|
||||
|
||||
VECTOR2D mid = roundp( xform( aCenterPoint ) );
|
||||
VECTOR2D mid = xform( aCenterPoint );
|
||||
double width = xform( aWidth / 2.0 );
|
||||
VECTOR2D startPointS = VECTOR2D( r, 0.0 );
|
||||
VECTOR2D endPointS = VECTOR2D( r, 0.0 );
|
||||
@@ -1672,13 +1671,16 @@ bool CAIRO_GAL::updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions )
|
||||
}
|
||||
|
||||
|
||||
bool CAIRO_GAL::SetNativeCursorStyle( KICURSOR aCursor )
|
||||
bool CAIRO_GAL::SetNativeCursorStyle( KICURSOR aCursor, bool aHiDPI )
|
||||
{
|
||||
// Store the current cursor type and get the wxCursor for it
|
||||
if( !GAL::SetNativeCursorStyle( aCursor ) )
|
||||
if( !GAL::SetNativeCursorStyle( aCursor, aHiDPI ) )
|
||||
return false;
|
||||
|
||||
m_currentwxCursor = CURSOR_STORE::GetCursor( m_currentNativeCursor );
|
||||
if( aHiDPI )
|
||||
m_currentwxCursor = CURSOR_STORE::GetHiDPICursor( m_currentNativeCursor );
|
||||
else
|
||||
m_currentwxCursor = CURSOR_STORE::GetCursor( m_currentNativeCursor );
|
||||
|
||||
// Update the cursor in the wx control
|
||||
wxWindow::SetCursor( m_currentwxCursor );
|
||||
|
||||
+259
-51
@@ -44,85 +44,76 @@
|
||||
#include <cursors/cursor-subtract.xpm>
|
||||
#include <cursors/cursor-text.xpm>
|
||||
#include <cursors/cursor-xor.xpm>
|
||||
#include <cursors/cursor-zoom.xpm>
|
||||
#include <cursors/cursor-zoom-in.xpm>
|
||||
#include <cursors/cursor-zoom-out.xpm>
|
||||
#include <cursors/cursor_tune.xpm>
|
||||
#include <cursors/voltage_probe.xpm>
|
||||
#include <cursors/current_probe.xpm>
|
||||
|
||||
// HiDPI cursor files
|
||||
#include <cursors/cursor-add64.xpm>
|
||||
#include <cursors/cursor-component64.xpm>
|
||||
#include <cursors/cursor-eraser64.xpm>
|
||||
#include <cursors/cursor-label-global64.xpm>
|
||||
#include <cursors/cursor-label-hier64.xpm>
|
||||
#include <cursors/cursor-label-net64.xpm>
|
||||
#include <cursors/cursor-line-bus64.xpm>
|
||||
#include <cursors/cursor-line-graphic64.xpm>
|
||||
#include <cursors/cursor-line-wire64.xpm>
|
||||
#include <cursors/cursor-line-wire-add64.xpm>
|
||||
#include <cursors/cursor-measure64.xpm>
|
||||
#include <cursors/cursor-pencil64.xpm>
|
||||
#include <cursors/cursor-select-lasso64.xpm>
|
||||
#include <cursors/cursor-select-window64.xpm>
|
||||
#include <cursors/cursor-subtract64.xpm>
|
||||
#include <cursors/cursor-text64.xpm>
|
||||
#include <cursors/cursor-xor64.xpm>
|
||||
#include <cursors/cursor-zoom-in64.xpm>
|
||||
#include <cursors/cursor-zoom-out64.xpm>
|
||||
#include <cursors/cursor_tune64.xpm>
|
||||
#include <cursors/voltage_probe64.xpm>
|
||||
#include <cursors/current_probe64.xpm>
|
||||
|
||||
|
||||
// Under MSW, the standard cursor is white on black. Elsewhere it is black on white
|
||||
#ifdef __WINDOWS__
|
||||
#include <cursors/cursor-place.xpm>
|
||||
#include <cursors/cursor-place64.xpm>
|
||||
#include <cursors/cursor-select-m.xpm>
|
||||
#include <cursors/cursor-select-m64.xpm>
|
||||
#else
|
||||
#include <cursors/cursor-place-black.xpm>
|
||||
#include <cursors/cursor-place-black64.xpm>
|
||||
#include <cursors/cursor-select-m-black.xpm>
|
||||
#include <cursors/cursor-select-m-black64.xpm>
|
||||
#endif
|
||||
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/debug.h>
|
||||
|
||||
|
||||
static const unsigned char voltage_probe[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
|
||||
0x00, 0x30, 0x06, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x0e, 0x08, 0x00, 0x80, 0x07, 0x08, 0x00,
|
||||
0xc0, 0x07, 0x18, 0x00, 0xe0, 0x07, 0x30, 0x00, 0xf0, 0x03, 0x60, 0x00, 0xf8, 0x01, 0x00, 0x00,
|
||||
0xfc, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0xc0,
|
||||
0x0f, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
static const unsigned char current_probe[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00,
|
||||
0x00, 0x30, 0x0c, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x00, 0x0f, 0x08, 0x00, 0x80, 0x0f, 0x18, 0x00,
|
||||
0xc0, 0x0f, 0x30, 0x80, 0xe1, 0x07, 0x60, 0x80, 0xf1, 0x03, 0x00, 0x80, 0xf9, 0x01, 0x00, 0x80,
|
||||
0xfd, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0xc0,
|
||||
0x0f, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xc6, 0x01, 0x00, 0x00, 0x83,
|
||||
0x01, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xfc,
|
||||
0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00 };
|
||||
|
||||
static const unsigned char cursor_tune[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xc0, 0x0f, 0x00,
|
||||
0x00, 0xe0, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00,
|
||||
0x00, 0xfe, 0x03, 0x00, 0x00, 0xff, 0x01, 0x00, 0x80, 0xff, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00,
|
||||
0xe0, 0x3f, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
|
||||
0xfc, 0x03, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x50,
|
||||
0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a,
|
||||
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 };
|
||||
|
||||
static const unsigned char cursor_tune_mask[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xc0, 0x0f,
|
||||
0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xfc, 0x07,
|
||||
0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xff, 0x01, 0x00, 0x80, 0xff, 0x00, 0x00, 0xc0, 0x7f, 0x00,
|
||||
0x00, 0xe0, 0x3f, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00,
|
||||
0x00, 0xfc, 0x03, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00,
|
||||
0x00, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x70, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
|
||||
0x0e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 };
|
||||
|
||||
|
||||
static const std::vector<CURSOR_STORE::CURSOR_DEF> standard_cursors = {
|
||||
{
|
||||
KICURSOR::VOLTAGE_PROBE,
|
||||
voltage_probe,
|
||||
voltage_probe,
|
||||
nullptr,
|
||||
nullptr,
|
||||
voltage_probe_xpm,
|
||||
{ 32, 32 },
|
||||
{ 1, 31 },
|
||||
},
|
||||
{
|
||||
KICURSOR::CURRENT_PROBE,
|
||||
current_probe,
|
||||
current_probe,
|
||||
nullptr,
|
||||
nullptr,
|
||||
current_probe_xpm,
|
||||
{ 32, 32 },
|
||||
{ 4, 27 },
|
||||
},
|
||||
{
|
||||
KICURSOR::TUNE,
|
||||
cursor_tune,
|
||||
cursor_tune_mask,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_tune_xpm,
|
||||
{ 32, 32 },
|
||||
{ 1, 30 },
|
||||
},
|
||||
@@ -198,7 +189,7 @@ static const std::vector<CURSOR_STORE::CURSOR_DEF> standard_cursors = {
|
||||
KICURSOR::ZOOM_IN,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_zoom_xpm,
|
||||
cursor_zoom_in_xpm,
|
||||
{ 32, 32 },
|
||||
{ 6, 6 },
|
||||
},
|
||||
@@ -305,6 +296,209 @@ static const std::vector<CURSOR_STORE::CURSOR_DEF> standard_cursors = {
|
||||
};
|
||||
|
||||
|
||||
static const std::vector<CURSOR_STORE::CURSOR_DEF> hidpi_cursors = {
|
||||
{
|
||||
KICURSOR::VOLTAGE_PROBE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
voltage_probe64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 1, 62 },
|
||||
},
|
||||
{
|
||||
KICURSOR::CURRENT_PROBE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
current_probe64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 8, 54 },
|
||||
},
|
||||
{
|
||||
KICURSOR::TUNE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_tune64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 2, 60 },
|
||||
},
|
||||
{
|
||||
KICURSOR::PENCIL,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_pencil64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 8, 54 },
|
||||
},
|
||||
{
|
||||
KICURSOR::MOVING,
|
||||
nullptr,
|
||||
nullptr,
|
||||
#ifdef __WINDOWS__
|
||||
cursor_select_m64_xpm,
|
||||
#else
|
||||
cursor_select_m_black64_xpm,
|
||||
#endif
|
||||
{ 64, 64 },
|
||||
{ 2, 2 },
|
||||
},
|
||||
{
|
||||
KICURSOR::REMOVE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_eraser64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 8, 8 },
|
||||
},
|
||||
{
|
||||
KICURSOR::TEXT,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_text64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::MEASURE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_measure64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 8, 8 },
|
||||
},
|
||||
{
|
||||
KICURSOR::ADD,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_add64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::SUBTRACT,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_subtract64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::XOR,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_xor64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::ZOOM_IN,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_zoom_in64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 12, 12 },
|
||||
},
|
||||
{
|
||||
KICURSOR::ZOOM_OUT,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_zoom_out64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 12, 12 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LABEL_NET,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_label_net64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LABEL_GLOBAL,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_label_global64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::COMPONENT,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_component64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::SELECT_LASSO,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_select_lasso64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::SELECT_WINDOW,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_select_window64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 20 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LINE_BUS,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_line_bus64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 10, 52 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LINE_WIRE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_line_wire64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 10, 52 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LINE_WIRE_ADD,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_line_wire_add64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 10, 52 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LINE_GRAPHIC,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_line_graphic64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 10, 52 },
|
||||
},
|
||||
{
|
||||
KICURSOR::LABEL_HIER,
|
||||
nullptr,
|
||||
nullptr,
|
||||
cursor_label_hier64_xpm,
|
||||
{ 64, 64 },
|
||||
{ 14, 14 },
|
||||
},
|
||||
{
|
||||
KICURSOR::PLACE,
|
||||
nullptr,
|
||||
nullptr,
|
||||
#ifdef __WINDOWS__
|
||||
cursor_place64_xpm,
|
||||
#else
|
||||
cursor_place_black64_xpm,
|
||||
#endif
|
||||
{ 64, 64 },
|
||||
{ 2, 2 },
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct a cursor for the given definition.
|
||||
*
|
||||
@@ -393,8 +587,8 @@ const wxCursor& CURSOR_STORE::Get( KICURSOR aIdKey ) const
|
||||
|
||||
const wxCursor CURSOR_STORE::GetCursor( KICURSOR aCursorType )
|
||||
{
|
||||
wxStockCursor stock =
|
||||
GetStockCursor( aCursorType );
|
||||
wxStockCursor stock = GetStockCursor( aCursorType );
|
||||
|
||||
if( stock != wxCURSOR_MAX )
|
||||
{
|
||||
return wxCursor( stock );
|
||||
@@ -405,6 +599,20 @@ const wxCursor CURSOR_STORE::GetCursor( KICURSOR aCursorType )
|
||||
}
|
||||
|
||||
|
||||
const wxCursor CURSOR_STORE::GetHiDPICursor( KICURSOR aCursorType )
|
||||
{
|
||||
wxStockCursor stock = GetStockCursor( aCursorType );
|
||||
|
||||
if( stock != wxCURSOR_MAX )
|
||||
{
|
||||
return wxCursor( stock );
|
||||
}
|
||||
|
||||
static CURSOR_STORE store( hidpi_cursors );
|
||||
return store.Get( aCursorType );
|
||||
}
|
||||
|
||||
|
||||
wxStockCursor CURSOR_STORE::GetStockCursor( KICURSOR aCursorType )
|
||||
{
|
||||
wxStockCursor stockCursor;
|
||||
|
||||
@@ -81,7 +81,7 @@ GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) :
|
||||
SetCursorEnabled( false );
|
||||
|
||||
// Initialize the native widget to an arrow cursor
|
||||
SetNativeCursorStyle( KICURSOR::ARROW );
|
||||
SetNativeCursorStyle( KICURSOR::ARROW, false );
|
||||
|
||||
// Initialize text properties
|
||||
ResetTextAttributes();
|
||||
@@ -277,7 +277,7 @@ void GAL::BitmapText( const wxString& aText, const VECTOR2I& aPosition, const ED
|
||||
}
|
||||
|
||||
|
||||
bool GAL::SetNativeCursorStyle( KICURSOR aCursor )
|
||||
bool GAL::SetNativeCursorStyle( KICURSOR aCursor, bool aHiDPI )
|
||||
{
|
||||
if( m_currentNativeCursor == aCursor )
|
||||
return false;
|
||||
|
||||
@@ -34,8 +34,7 @@ HIDPI_GL_CANVAS::HIDPI_GL_CANVAS( const KIGFX::VC_SETTINGS& aSettings, wxWindow*
|
||||
const wxPoint& aPos, const wxSize& aSize, long aStyle,
|
||||
const wxString& aName, const wxPalette& aPalette ) :
|
||||
wxGLCanvas( aParent, aId, aAttribList, aPos, aSize, aStyle, aName, aPalette ),
|
||||
m_settings( aSettings ),
|
||||
m_scale_factor( DPI_SCALING::GetDefaultScaleFactor() )
|
||||
m_settings( aSettings )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -64,13 +63,7 @@ wxPoint HIDPI_GL_CANVAS::GetNativePosition( const wxPoint& aPoint ) const
|
||||
}
|
||||
|
||||
|
||||
void HIDPI_GL_CANVAS::SetScaleFactor( double aNewScaleFactor )
|
||||
{
|
||||
m_scale_factor = aNewScaleFactor;
|
||||
}
|
||||
|
||||
|
||||
double HIDPI_GL_CANVAS::GetScaleFactor() const
|
||||
{
|
||||
return m_scale_factor;
|
||||
return GetContentScaleFactor();
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2012-2024 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2013-2017 CERN
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
@@ -33,6 +33,7 @@
|
||||
#endif
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <build_version.h>
|
||||
#include <gal/opengl/opengl_gal.h>
|
||||
#include <gal/opengl/utils.h>
|
||||
#include <gal/definitions.h>
|
||||
@@ -254,7 +255,8 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap )
|
||||
bmp.accessTime = currentTime;
|
||||
|
||||
#ifndef DISABLE_BITMAP_CACHE
|
||||
if( m_cacheLru.size() + 1 > m_cacheMaxElements || m_cacheSize + bmp.size > m_cacheMaxSize )
|
||||
if( ( m_cacheLru.size() + 1 > m_cacheMaxElements || m_cacheSize + bmp.size > m_cacheMaxSize )
|
||||
&& !m_cacheLru.empty() )
|
||||
{
|
||||
KIID toRemove( 0 );
|
||||
auto toRemoveLru = m_cacheLru.end();
|
||||
@@ -506,13 +508,6 @@ bool OPENGL_GAL::updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions )
|
||||
refresh = true;
|
||||
}
|
||||
|
||||
if( m_options.m_scaleFactor != GetScaleFactor() )
|
||||
{
|
||||
SetScaleFactor( m_options.m_scaleFactor );
|
||||
m_gridLineWidth = m_options.m_scaleFactor * ( m_options.m_gridLineWidth + 0.25 );
|
||||
refresh = true;
|
||||
}
|
||||
|
||||
if( super::updatedGalDisplayOptions( aOptions ) || refresh )
|
||||
{
|
||||
Refresh();
|
||||
@@ -2133,13 +2128,16 @@ void OPENGL_GAL::EndDiffLayer()
|
||||
}
|
||||
|
||||
|
||||
bool OPENGL_GAL::SetNativeCursorStyle( KICURSOR aCursor )
|
||||
bool OPENGL_GAL::SetNativeCursorStyle( KICURSOR aCursor, bool aHiDPI )
|
||||
{
|
||||
// Store the current cursor type and get the wxCursor for it
|
||||
if( !GAL::SetNativeCursorStyle( aCursor ) )
|
||||
if( !GAL::SetNativeCursorStyle( aCursor, aHiDPI ) )
|
||||
return false;
|
||||
|
||||
m_currentwxCursor = CURSOR_STORE::GetCursor( m_currentNativeCursor );
|
||||
if( aHiDPI )
|
||||
m_currentwxCursor = CURSOR_STORE::GetHiDPICursor( m_currentNativeCursor );
|
||||
else
|
||||
m_currentwxCursor = CURSOR_STORE::GetCursor( m_currentNativeCursor );
|
||||
|
||||
// Update the cursor in the wx control
|
||||
HIDPI_GL_CANVAS::SetCursor( m_currentwxCursor );
|
||||
@@ -2678,6 +2676,9 @@ void OPENGL_GAL::init()
|
||||
|
||||
#endif // KICAD_USE_EGL
|
||||
|
||||
SetOpenGLInfo( (const char*) glGetString( GL_VENDOR ), (const char*) glGetString( GL_RENDERER ),
|
||||
(const char*) glGetString( GL_VERSION ) );
|
||||
|
||||
if( GLEW_OK != err )
|
||||
throw std::runtime_error( (const char*) glewGetErrorString( err ) );
|
||||
|
||||
|
||||
@@ -642,10 +642,6 @@ void DXF_IMPORT_PLUGIN::addEllipse( const DL_EllipseData& aData )
|
||||
if( startAngle > endAngle )
|
||||
endAngle += ANGLE_360;
|
||||
|
||||
// Angles are relative to major axis
|
||||
startAngle -= EDA_ANGLE( major );
|
||||
endAngle -= EDA_ANGLE( major );
|
||||
|
||||
if( aData.ratio == 1.0 )
|
||||
{
|
||||
double radius = major.EuclideanNorm();
|
||||
@@ -658,6 +654,10 @@ void DXF_IMPORT_PLUGIN::addEllipse( const DL_EllipseData& aData )
|
||||
}
|
||||
else
|
||||
{
|
||||
// Angles are relative to major axis
|
||||
startAngle -= EDA_ANGLE( major );
|
||||
endAngle -= EDA_ANGLE( major );
|
||||
|
||||
DL_ArcData arc( aData.cx, aData.cy, aData.cz, radius, startAngle.AsDegrees(),
|
||||
endAngle.AsDegrees() );
|
||||
addArc( arc );
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 Alex Shvartzkop <dudesuchamazing@gmail.com>
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2023-2024 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
|
||||
@@ -246,7 +246,7 @@ EASYEDA_PARSER_BASE::ParseLineChains( const wxString& data, int aArcMinSegLen, b
|
||||
arc.ConstructFromStartEndCenter( RelPos( start ), RelPos( end ), RelPos( arcCenter ),
|
||||
!cw );
|
||||
|
||||
chain.Append( arc );
|
||||
chain.Append( arc, aArcMinSegLen );
|
||||
|
||||
prevPt = end;
|
||||
}
|
||||
|
||||
+14
-1
@@ -57,7 +57,6 @@ KIWAY_PLAYER::KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType
|
||||
|
||||
KIWAY_PLAYER::~KIWAY_PLAYER() throw()
|
||||
{
|
||||
|
||||
// socket server must be destructed before we complete
|
||||
// destructing the frame or else we could crash
|
||||
// as the socket server holds a reference to this frame
|
||||
@@ -69,6 +68,20 @@ KIWAY_PLAYER::~KIWAY_PLAYER() throw()
|
||||
delete m_socketServer;
|
||||
m_socketServer = nullptr;
|
||||
}
|
||||
|
||||
// remove active sockets as well
|
||||
for( wxSocketBase* socket : m_sockets )
|
||||
{
|
||||
if( !socket )
|
||||
continue;
|
||||
|
||||
// ensure any event handling stops
|
||||
socket->Notify( false );
|
||||
|
||||
delete socket;
|
||||
}
|
||||
|
||||
m_sockets.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <wx/debug.h>
|
||||
#include <wx/filename.h>
|
||||
#include <set>
|
||||
#include <common.h>
|
||||
@@ -198,7 +199,16 @@ LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName, bool aCheckIfEnabl
|
||||
|
||||
do
|
||||
{
|
||||
std::shared_lock<std::shared_mutex> lock( cur->m_mutex );
|
||||
try
|
||||
{
|
||||
std::shared_lock<std::shared_mutex> lock( cur->m_mutex );
|
||||
}
|
||||
catch( std::system_error& e )
|
||||
{
|
||||
wxASSERT_MSG( false, wxString::Format( wxS( "Failed to lock lib table mutex: %s" ),
|
||||
e.what() ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( cur->m_rowsMap.count( aNickName ) )
|
||||
row = &*cur->m_rowsMap.at( aNickName );
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
#include "lib_table_grid.h"
|
||||
|
||||
|
||||
LIB_TABLE_GRID_TRICKS::LIB_TABLE_GRID_TRICKS( WX_GRID* aGrid ) : GRID_TRICKS( aGrid )
|
||||
LIB_TABLE_GRID_TRICKS::LIB_TABLE_GRID_TRICKS( WX_GRID* aGrid ) :
|
||||
GRID_TRICKS( aGrid )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -65,11 +66,14 @@ void LIB_TABLE_GRID_TRICKS::showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
|
||||
if( showDeactivate )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_DEACTIVATE_SELECTED, _( "Deactivate selected" ) );
|
||||
|
||||
if( showSetVisible )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_SET_VISIBLE, _( "Set visible flag" ) );
|
||||
if( supportsVisibilityColumn() )
|
||||
{
|
||||
if( showSetVisible )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_SET_VISIBLE, _( "Set visible flag" ) );
|
||||
|
||||
if( showUnsetVisible )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_UNSET_VISIBLE, _( "Unset visible flag" ) );
|
||||
if( showUnsetVisible )
|
||||
menu.Append( LIB_TABLE_GRID_TRICKS_UNSET_VISIBLE, _( "Unset visible flag" ) );
|
||||
}
|
||||
|
||||
bool showSettings = false;
|
||||
|
||||
|
||||
@@ -416,7 +416,7 @@ wxDataViewColumn* LIB_TREE_MODEL_ADAPTER::doAddColumn( const wxString& aHeader,
|
||||
|
||||
wxDataViewColumn* col = new wxDataViewColumn(
|
||||
translatedHeader, new LIB_TREE_RENDERER(), index, m_colWidths[aHeader], wxALIGN_NOT,
|
||||
wxDATAVIEW_CELL_INERT | wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE );
|
||||
wxDATAVIEW_CELL_INERT | static_cast<int>( wxDATAVIEW_COL_RESIZABLE ) );
|
||||
m_widget->AppendColumn( col );
|
||||
|
||||
col->SetMinWidth( headerMinWidth.x );
|
||||
|
||||
+4
-5
@@ -153,6 +153,9 @@ PGM_BASE::~PGM_BASE()
|
||||
}
|
||||
|
||||
delete[] m_argvUtf8;
|
||||
|
||||
delete m_locale;
|
||||
m_locale = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -164,10 +167,6 @@ void PGM_BASE::Destroy()
|
||||
sentry_close();
|
||||
#endif
|
||||
|
||||
// unlike a normal destructor, this is designed to be called more than once safely:
|
||||
delete m_locale;
|
||||
m_locale = nullptr;
|
||||
|
||||
m_pgm_checker.reset();
|
||||
}
|
||||
|
||||
@@ -990,7 +989,7 @@ void PGM_BASE::HandleAssert( const wxString& aFile, int aLine, const wxString& a
|
||||
{
|
||||
static std::set<SENTRY_ASSERT_CACHE_KEY> assertCache;
|
||||
|
||||
SENTRY_ASSERT_CACHE_KEY key = { aFile, aLine, aFunc, aCond, aMsg };
|
||||
SENTRY_ASSERT_CACHE_KEY key = { aFile, aLine, aFunc, aCond };
|
||||
|
||||
if( assertCache.find( key ) == assertCache.end() )
|
||||
{
|
||||
|
||||
@@ -851,7 +851,7 @@ void SVG_PLOTTER::Text( const VECTOR2I& aPos,
|
||||
|
||||
fprintf( m_outputFile,
|
||||
"textLength=\"%.*f\" font-size=\"%.*f\" lengthAdjust=\"spacingAndGlyphs\"\n"
|
||||
"text-anchor=\"%s\" opacity=\"0\">%s</text>\n",
|
||||
"text-anchor=\"%s\" opacity=\"0\" stroke-opacity=\"0\">%s</text>\n",
|
||||
m_precision, sz_dev.x, m_precision, sz_dev.y, hjust, TO_UTF8( XmlEsc( aText ) ) );
|
||||
|
||||
if( !aOrient.IsZero() )
|
||||
|
||||
@@ -160,6 +160,9 @@ APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaV
|
||||
m_params.emplace_back( new PARAM<int>( "system.last_imperial_units",
|
||||
&m_System.last_imperial_units, static_cast<int>( EDA_UNITS::MILS ) ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "system.show_import_issues",
|
||||
&m_System.show_import_issues, true ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<wxString>( "appearance.color_theme",
|
||||
&m_ColorTheme, COLOR_SETTINGS::COLOR_BUILTIN_DEFAULT ) );
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ const wxString COLOR_SETTINGS::COLOR_BUILTIN_CLASSIC = "_builtin_classic";
|
||||
|
||||
|
||||
COLOR_SETTINGS::COLOR_SETTINGS( const wxString& aFilename, bool aAbsolutePath ) :
|
||||
JSON_SETTINGS( std::move( aFilename ), SETTINGS_LOC::COLORS, colorsSchemaVersion ),
|
||||
JSON_SETTINGS( aFilename, SETTINGS_LOC::COLORS, colorsSchemaVersion ),
|
||||
m_overrideSchItemColors( false )
|
||||
{
|
||||
if( aAbsolutePath )
|
||||
|
||||
@@ -591,7 +591,7 @@ wxString RemoveHTMLTags( const wxString& aInput )
|
||||
|
||||
wxString LinkifyHTML( wxString aStr )
|
||||
{
|
||||
wxRegEx regex( wxS( "\\b(https?|ftp|file)://([-\\w+&@#/%?=~|!:,.;]*[^.<>\\s\u00b6])" ),
|
||||
wxRegEx regex( wxS( "\\b(https?|ftp|file)://([-\\w+&@#/%?=~|!:,.;]*[^.,:;<>\\s\u00b6])" ),
|
||||
wxRE_ICASE );
|
||||
|
||||
regex.ReplaceAll( &aStr, "<a href=\"\\0\">\\0</a>" );
|
||||
@@ -907,11 +907,12 @@ bool ApplyModifier( double& value, const wxString& aString )
|
||||
}
|
||||
|
||||
if( units.length()
|
||||
&& !units.CmpNoCase( wxT( "F" ) )
|
||||
&& !units.CmpNoCase( wxT( "hz" ) )
|
||||
&& !units.CmpNoCase( wxT( "W" ) )
|
||||
&& !units.CmpNoCase( wxT( "V" ) )
|
||||
&& !units.CmpNoCase( wxT( "H" ) ) )
|
||||
&& !units.IsSameAs( wxT( "F" ), false )
|
||||
&& !units.IsSameAs( wxT( "hz" ), false )
|
||||
&& !units.IsSameAs( wxT( "W" ), false )
|
||||
&& !units.IsSameAs( wxT( "V" ), false )
|
||||
&& !units.IsSameAs( wxT( "A" ), false )
|
||||
&& !units.IsSameAs( wxT( "H" ), false ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ VECTOR2I SELECTION::GetCenter() const
|
||||
}
|
||||
|
||||
|
||||
BOX2I SELECTION::GetBoundingBox() const
|
||||
BOX2I SELECTION::GetBoundingBox( bool aOnlyVisible ) const
|
||||
{
|
||||
BOX2I bbox;
|
||||
|
||||
|
||||
@@ -455,8 +455,11 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
|
||||
|
||||
if( isMouseClick( type ) )
|
||||
{
|
||||
if( m_toolMgr->GetToolHolder() && m_toolMgr->GetToolHolder()->GetToolCanvas() )
|
||||
if( m_toolMgr->GetToolHolder() && m_toolMgr->GetToolHolder()->GetToolCanvas() &&
|
||||
!m_toolMgr->GetToolHolder()->GetToolCanvas()->HasFocus() )
|
||||
{
|
||||
m_toolMgr->GetToolHolder()->GetToolCanvas()->SetFocus();
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse handling
|
||||
|
||||
@@ -362,7 +362,11 @@ bool TOOL_MANAGER::doRunAction( const TOOL_ACTION& aAction, bool aNow, const std
|
||||
|
||||
while( synchronousControl == STS_RUNNING )
|
||||
{
|
||||
wxYield();
|
||||
wxYield(); // Needed to honor mouse (and other) events during editing
|
||||
wxMilliSleep( 1 ); // Needed to avoid 100% use of one cpu core.
|
||||
// The sleeping time must be must be small to avoid
|
||||
// noticeable lag in mouse and editing events
|
||||
// (1 to 5 ms is a good value)
|
||||
}
|
||||
|
||||
retVal = synchronousControl != STS_CANCELLED;
|
||||
|
||||
+25
-25
@@ -399,35 +399,19 @@ void VIEW::SetRequired( int aLayerId, int aRequiredId, bool aRequired )
|
||||
}
|
||||
|
||||
|
||||
// stupid C++... python lambda would do this in one line
|
||||
template <class CONTAINER>
|
||||
struct QUERY_VISITOR
|
||||
{
|
||||
typedef typename CONTAINER::value_type item_type;
|
||||
|
||||
QUERY_VISITOR( CONTAINER& aCont, int aLayer ) :
|
||||
m_cont( aCont ), m_layer( aLayer )
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()( VIEW_ITEM* aItem )
|
||||
{
|
||||
if( aItem->viewPrivData()->GetFlags() & VISIBLE )
|
||||
m_cont.push_back( VIEW::LAYER_ITEM_PAIR( aItem, m_layer ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CONTAINER& m_cont;
|
||||
int m_layer;
|
||||
};
|
||||
|
||||
|
||||
int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const
|
||||
{
|
||||
if( m_orderedLayers.empty() )
|
||||
return 0;
|
||||
|
||||
int layer = UNDEFINED_LAYER;
|
||||
auto visitor =
|
||||
[&]( VIEW_ITEM* item ) -> bool
|
||||
{
|
||||
aResult.push_back( VIEW::LAYER_ITEM_PAIR( item, layer ) );
|
||||
return true;
|
||||
};
|
||||
|
||||
std::vector<VIEW_LAYER*>::const_reverse_iterator i;
|
||||
|
||||
// execute queries in reverse direction, so that items that are on the top of
|
||||
@@ -438,7 +422,7 @@ int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) con
|
||||
if( ( *i )->displayOnly || !( *i )->visible )
|
||||
continue;
|
||||
|
||||
QUERY_VISITOR<std::vector<LAYER_ITEM_PAIR> > visitor( aResult, ( *i )->id );
|
||||
layer = ( *i )->id;
|
||||
( *i )->items->Query( aRect, visitor );
|
||||
}
|
||||
|
||||
@@ -446,6 +430,22 @@ int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) con
|
||||
}
|
||||
|
||||
|
||||
void VIEW::Query( const BOX2I& aRect, const std::function<bool( VIEW_ITEM* )>& aFunc ) const
|
||||
{
|
||||
if( m_orderedLayers.empty() )
|
||||
return;
|
||||
|
||||
for( const auto& i : m_orderedLayers )
|
||||
{
|
||||
// ignore layers that do not contain actual items (i.e. the selection box, menus, floats)
|
||||
if( i->displayOnly || !i->visible )
|
||||
continue;
|
||||
|
||||
i->items->Query( aRect, aFunc );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const
|
||||
{
|
||||
const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
#include <wx/log.h>
|
||||
|
||||
#ifdef __WXMSW__
|
||||
#define USE_MOUSE_CAPTURE
|
||||
#define USE_MOUSE_CAPTURE
|
||||
#endif
|
||||
|
||||
using namespace KIGFX;
|
||||
@@ -694,7 +694,11 @@ void WX_VIEW_CONTROLS::CaptureCursor( bool aEnabled )
|
||||
// Note: for some reason, m_parentPanel->HasCapture() can be false even if CaptureMouse()
|
||||
// was called (i.e. mouse was captured, so when need to test m_MouseCapturedLost to be
|
||||
// sure a wxEVT_MOUSE_CAPTURE_LOST event was fired before. Otherwise wxMSW complains
|
||||
if( aEnabled && !m_parentPanel->HasCapture() && m_parentPanel->m_MouseCapturedLost )
|
||||
// The IsModalDialogFocused is checked because it's possible to start a capture
|
||||
// due to event ordering while a modal dialog was just opened, the mouse capture steels focus
|
||||
// from the modal and causes odd behavior
|
||||
if( aEnabled && !m_parentPanel->HasCapture() && m_parentPanel->m_MouseCapturedLost
|
||||
&& !KIUI::IsModalDialogFocused() )
|
||||
{
|
||||
m_parentPanel->CaptureMouse();
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 CERN
|
||||
* Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2018-2024 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
|
||||
@@ -213,13 +213,15 @@ protected:
|
||||
if( rawValue.IsEmpty() )
|
||||
rawValue = m_preselect;
|
||||
|
||||
wxString symbolId = escapeLibId( rawValue );
|
||||
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_SYMBOL_CHOOSER, true, m_dlg );
|
||||
wxString symbolId = escapeLibId( rawValue );
|
||||
|
||||
if( frame->ShowModal( &symbolId, m_dlg ) )
|
||||
SetValue( UnescapeString( symbolId ) );
|
||||
if( KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_SYMBOL_CHOOSER, true, m_dlg ) )
|
||||
{
|
||||
if( frame->ShowModal( &symbolId, m_dlg ) )
|
||||
SetValue( UnescapeString( symbolId ) );
|
||||
|
||||
frame->Destroy();
|
||||
frame->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
DIALOG_SHIM* m_dlg;
|
||||
@@ -247,6 +249,7 @@ public:
|
||||
m_preselect( aPreselect ),
|
||||
m_symbolNetlist( aSymbolNetlist.ToStdString() )
|
||||
{
|
||||
m_buttonFpChooserLock = false;
|
||||
SetButtonBitmaps( KiBitmap( BITMAPS::small_library ) );
|
||||
|
||||
// win32 fix, avoids drawing the "native dropdown caret"
|
||||
@@ -261,30 +264,45 @@ protected:
|
||||
|
||||
void OnButtonClick() override
|
||||
{
|
||||
if( m_buttonFpChooserLock ) // The button to show the FP chooser is clicked, but
|
||||
// a previous click is currently in progress.
|
||||
return;
|
||||
|
||||
// Disable the button until we have finished processing it. Normally this is not an issue
|
||||
// but if the footprint chooser is loading for the first time, it can be slow enough that
|
||||
// multiple clicks will cause multiple instances of the footprint loader process to start
|
||||
m_buttonFpChooserLock = true;
|
||||
|
||||
// pick a footprint using the footprint picker.
|
||||
wxString fpid = GetValue();
|
||||
|
||||
if( fpid.IsEmpty() )
|
||||
fpid = m_preselect;
|
||||
|
||||
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg );
|
||||
|
||||
if( !m_symbolNetlist.empty() )
|
||||
if( KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg ) )
|
||||
{
|
||||
KIWAY_EXPRESS event( FRAME_FOOTPRINT_CHOOSER, MAIL_SYMBOL_NETLIST, m_symbolNetlist );
|
||||
frame->KiwayMailIn( event );
|
||||
if( !m_symbolNetlist.empty() )
|
||||
{
|
||||
KIWAY_EXPRESS event( FRAME_FOOTPRINT_CHOOSER, MAIL_SYMBOL_NETLIST, m_symbolNetlist );
|
||||
frame->KiwayMailIn( event );
|
||||
}
|
||||
|
||||
if( frame->ShowModal( &fpid, m_dlg ) )
|
||||
SetValue( fpid );
|
||||
|
||||
frame->Destroy();
|
||||
}
|
||||
|
||||
if( frame->ShowModal( &fpid, m_dlg ) )
|
||||
SetValue( fpid );
|
||||
|
||||
frame->Destroy();
|
||||
m_buttonFpChooserLock = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
DIALOG_SHIM* m_dlg;
|
||||
wxString m_preselect;
|
||||
|
||||
// Lock flag to lock the button to show the FP chooser
|
||||
// true when the button is busy, waiting all footprints loaded to
|
||||
// avoid running more than once the FP chooser
|
||||
bool m_buttonFpChooserLock;
|
||||
/*
|
||||
* Symbol netlist format:
|
||||
* pinNumber pinName <tab> pinNumber pinName...
|
||||
|
||||
@@ -725,18 +725,6 @@ void LIB_TREE::onIdle( wxIdleEvent& aEvent )
|
||||
|
||||
if( m_previewItem.IsOk() )
|
||||
{
|
||||
// Scroll checker
|
||||
if( m_tree_ctrl->GetItemRect( m_previewItem ) != m_previewItemRect )
|
||||
{
|
||||
hidePreview();
|
||||
|
||||
m_hoverPos = clientPos;
|
||||
m_hoverItem = item;
|
||||
m_hoverItemRect = m_tree_ctrl->GetItemRect( m_hoverItem );
|
||||
m_hoverTimer.StartOnce( HOVER_TIMER_MILLIS );
|
||||
return;
|
||||
}
|
||||
|
||||
if( item != m_previewItem )
|
||||
{
|
||||
#ifdef __WXGTK__
|
||||
|
||||
@@ -518,8 +518,10 @@ void mpFXY::Plot( wxDC& dc, mpWindow& w )
|
||||
ys.insert( w.y2p( py ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
else for( int sweep = 0; sweep < GetSweepCount(); ++sweep )
|
||||
{
|
||||
SetSweepWindow( sweep );
|
||||
|
||||
int count = 0;
|
||||
int x0 = 0; // X position of merged current vertical line
|
||||
int ymin0 = 0; // y min coord of merged current vertical line
|
||||
@@ -2456,18 +2458,20 @@ double mpScaleXLog::TransformFromPlot( double xplot ) const
|
||||
void mpFXYVector::Rewind()
|
||||
{
|
||||
m_index = 0;
|
||||
m_sweepWindow = std::numeric_limits<size_t>::max();
|
||||
}
|
||||
|
||||
|
||||
size_t mpFXYVector::GetCount() const
|
||||
void mpFXYVector::SetSweepWindow( int aSweepIdx )
|
||||
{
|
||||
return m_xs.size();
|
||||
m_index = aSweepIdx * m_sweepSize;
|
||||
m_sweepWindow = ( aSweepIdx + 1 ) * m_sweepSize;
|
||||
}
|
||||
|
||||
|
||||
bool mpFXYVector::GetNextXY( double& x, double& y )
|
||||
{
|
||||
if( m_index >= m_xs.size() )
|
||||
if( m_index >= m_xs.size() || m_index >= m_sweepWindow )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -2475,7 +2479,7 @@ bool mpFXYVector::GetNextXY( double& x, double& y )
|
||||
{
|
||||
x = m_xs[m_index];
|
||||
y = m_ys[m_index++];
|
||||
return m_index <= m_xs.size();
|
||||
return m_index <= m_xs.size() && m_index <= m_sweepWindow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -406,14 +406,19 @@ void PROPERTIES_PANEL::onShow( wxShowEvent& aEvent )
|
||||
{
|
||||
if( aEvent.IsShown() )
|
||||
UpdateData();
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void PROPERTIES_PANEL::onCharHook( wxKeyEvent& aEvent )
|
||||
{
|
||||
if( aEvent.GetKeyCode() == WXK_TAB && !aEvent.ShiftDown() )
|
||||
if( aEvent.GetKeyCode() == WXK_TAB && !aEvent.ShiftDown() && m_grid->IsAnyModified() )
|
||||
{
|
||||
m_grid->CommitChangesFromEditor();
|
||||
|
||||
// Pass the tab key on so the default property grid tab behavior is honored.
|
||||
aEvent.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,8 +87,8 @@ protected:
|
||||
virtual wxPGProperty* createPGProperty( const PROPERTY_BASE* aProperty ) const = 0;
|
||||
|
||||
// Event handlers
|
||||
virtual void valueChanging( wxPropertyGridEvent& aEvent ) {}
|
||||
virtual void valueChanged( wxPropertyGridEvent& aEvent ) {}
|
||||
virtual void valueChanging( wxPropertyGridEvent& aEvent ) { aEvent.Skip(); }
|
||||
virtual void valueChanged( wxPropertyGridEvent& aEvent ) { aEvent.Skip(); }
|
||||
void onCharHook( wxKeyEvent& aEvent );
|
||||
void onShow( wxShowEvent& aEvent );
|
||||
|
||||
|
||||
@@ -991,8 +991,19 @@ void CVPCB_MAINFRAME::BuildLibrariesList()
|
||||
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
||||
PROJECT_FILE& project = Kiway().Prj().GetProjectFile();
|
||||
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
|
||||
std::set<wxString> pinnedMatches;
|
||||
std::set<wxString> otherMatches;
|
||||
|
||||
// Use same sorting algorithm as LIB_TREE_NODE::AssignIntrinsicRanks
|
||||
struct library_sort
|
||||
{
|
||||
bool operator()( const wxString& lhs, const wxString& rhs ) const
|
||||
{
|
||||
return StrNumCmp( lhs, rhs, true ) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
std::set<wxString, library_sort> pinnedMatches;
|
||||
std::set<wxString, library_sort> otherMatches;
|
||||
|
||||
m_librariesListBox->ClearList();
|
||||
|
||||
auto process =
|
||||
|
||||
@@ -176,11 +176,11 @@ int CVPCB_CONTROL::ShowFootprintViewer( const TOOL_EVENT& aEvent )
|
||||
|
||||
fpframe = (DISPLAY_FOOTPRINTS_FRAME*) m_frame->Kiway().Player( FRAME_CVPCB_DISPLAY, true,
|
||||
m_frame );
|
||||
|
||||
// If Kiway() cannot create the eeschema frame, it shows a error message, and
|
||||
// frame is null
|
||||
if( !fpframe )
|
||||
{
|
||||
wxMessageBox( _( "Unable to create the footprint viewer frame" ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
fpframe->Show( true );
|
||||
}
|
||||
|
||||
@@ -397,6 +397,7 @@ set( EESCHEMA_SRCS
|
||||
symbol_tree_model_adapter.cpp
|
||||
symbol_tree_synchronizing_adapter.cpp
|
||||
symbol_viewer_frame.cpp
|
||||
symb_transforms_utils.cpp
|
||||
toolbars_sch_editor.cpp
|
||||
toolbars_symbol_viewer.cpp
|
||||
|
||||
|
||||
@@ -720,6 +720,20 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
|
||||
item->GetTypeDesc() );
|
||||
items.push_back( item );
|
||||
dirty_items.insert( item );
|
||||
|
||||
// Add any symbol dirty pins to the dirty_items list
|
||||
if( item->Type() == SCH_SYMBOL_T )
|
||||
{
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
|
||||
|
||||
for( SCH_PIN* pin : symbol->GetPins( &sheet ) )
|
||||
{
|
||||
if( pin->IsConnectivityDirty() )
|
||||
{
|
||||
dirty_items.insert( pin );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the symbol isn't dirty, look at the pins
|
||||
// TODO: remove symbols from connectivity graph and only use pins
|
||||
@@ -736,6 +750,19 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( item->Type() == SCH_SHEET_T )
|
||||
{
|
||||
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
|
||||
|
||||
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
|
||||
{
|
||||
if( pin->IsConnectivityDirty() )
|
||||
{
|
||||
items.push_back( pin );
|
||||
dirty_items.insert( pin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the hierarchy info stored in the SCH_SCREEN (such as symbol units) reflects
|
||||
// the current SCH_SHEET_PATH
|
||||
@@ -890,6 +917,9 @@ std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> CONNECTION_GRAPH::ExtractAffected
|
||||
|
||||
removeSubgraphs( subgraphs );
|
||||
|
||||
for( const auto& [path, item] : retvals )
|
||||
alg::delete_matching( m_items, item );
|
||||
|
||||
return retvals;
|
||||
}
|
||||
|
||||
@@ -2304,6 +2334,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
|
||||
std::shared_ptr<NET_SETTINGS>& netSettings = m_schematic->Prj().GetProjectFile().m_NetSettings;
|
||||
std::map<wxString, wxString> oldAssignments = netSettings->m_NetClassLabelAssignments;
|
||||
std::set<wxString> affectedNetclassNetAssignments;
|
||||
|
||||
netSettings->m_NetClassLabelAssignments.clear();
|
||||
|
||||
@@ -2345,9 +2376,6 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
}
|
||||
}
|
||||
|
||||
if( netclass.IsEmpty() )
|
||||
return;
|
||||
|
||||
if( !driverSubgraph )
|
||||
driverSubgraph = subgraphs.front();
|
||||
|
||||
@@ -2357,7 +2385,10 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
{
|
||||
for( const auto& member : driverSubgraph->m_driver_connection->Members() )
|
||||
{
|
||||
netSettings->m_NetClassLabelAssignments[ member->Name() ] = netclass;
|
||||
if( netclass.IsEmpty() )
|
||||
netSettings->m_NetClassLabelAssignments.erase( member->Name() );
|
||||
else
|
||||
netSettings->m_NetClassLabelAssignments[member->Name()] = netclass;
|
||||
|
||||
auto ii = m_net_name_to_subgraphs_map.find( member->Name() );
|
||||
|
||||
@@ -2366,10 +2397,24 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
}
|
||||
}
|
||||
|
||||
netSettings->m_NetClassLabelAssignments[ netname ] = netclass;
|
||||
if( netclass.IsEmpty() )
|
||||
netSettings->m_NetClassLabelAssignments.erase( netname );
|
||||
else
|
||||
netSettings->m_NetClassLabelAssignments[netname] = netclass;
|
||||
|
||||
if( oldAssignments[ netname ] != netclass )
|
||||
if( oldAssignments.count( netname ) )
|
||||
{
|
||||
if( oldAssignments[netname] != netclass )
|
||||
{
|
||||
affectedNetclassNetAssignments.insert( netname );
|
||||
dirtySubgraphs( subgraphs );
|
||||
}
|
||||
}
|
||||
else if( !netclass.IsEmpty() )
|
||||
{
|
||||
affectedNetclassNetAssignments.insert( netname );
|
||||
dirtySubgraphs( subgraphs );
|
||||
}
|
||||
};
|
||||
|
||||
for( const auto& [ netname, subgraphs ] : m_net_name_to_subgraphs_map )
|
||||
@@ -2379,8 +2424,11 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
{
|
||||
for( auto& [ netname, netclass ] : oldAssignments )
|
||||
{
|
||||
if( netSettings->m_NetClassLabelAssignments.count( netname ) )
|
||||
if( netSettings->m_NetClassLabelAssignments.count( netname )
|
||||
|| affectedNetclassNetAssignments.count( netname ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
netSettings->m_NetClassLabelAssignments[ netname ] = netclass;
|
||||
}
|
||||
@@ -2988,7 +3036,7 @@ CONNECTION_SUBGRAPH* CONNECTION_GRAPH::FindFirstSubgraphByName( const wxString&
|
||||
}
|
||||
|
||||
|
||||
CONNECTION_SUBGRAPH* CONNECTION_GRAPH::GetSubgraphForItem( SCH_ITEM* aItem )
|
||||
CONNECTION_SUBGRAPH* CONNECTION_GRAPH::GetSubgraphForItem( SCH_ITEM* aItem ) const
|
||||
{
|
||||
auto it = m_item_to_subgraph_map.find( aItem );
|
||||
CONNECTION_SUBGRAPH* ret = it != m_item_to_subgraph_map.end() ? it->second : nullptr;
|
||||
|
||||
@@ -428,7 +428,7 @@ public:
|
||||
*/
|
||||
CONNECTION_SUBGRAPH* FindFirstSubgraphByName( const wxString& aNetName );
|
||||
|
||||
CONNECTION_SUBGRAPH* GetSubgraphForItem( SCH_ITEM* aItem );
|
||||
CONNECTION_SUBGRAPH* GetSubgraphForItem( SCH_ITEM* aItem ) const;
|
||||
|
||||
const std::vector<CONNECTION_SUBGRAPH*> GetAllSubgraphs( const wxString& aNetName ) const;
|
||||
|
||||
|
||||
@@ -907,7 +907,7 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
||||
KIID uuid( payload );
|
||||
SCH_SHEET_PATH path;
|
||||
|
||||
if( SCH_ITEM* item = m_schematic->GetSheets().GetItem( uuid, &path ) )
|
||||
if( SCH_ITEM* item = m_schematic->GetItem( uuid, &path ) )
|
||||
{
|
||||
if( item->Type() == SCH_SHEET_T )
|
||||
payload = static_cast<SCH_SHEET*>( item )->GetShownName( false );
|
||||
|
||||
@@ -248,15 +248,16 @@ void DIALOG_CHANGE_SYMBOLS::launchMatchIdSymbolBrowser( wxCommandEvent& aEvent )
|
||||
{
|
||||
wxString newName = getLibIdValue( m_specifiedId );
|
||||
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SYMBOL_CHOOSER, true, this );
|
||||
|
||||
if( frame->ShowModal( &newName, this ) )
|
||||
if( KIWAY_PLAYER* frame = Kiway().Player( FRAME_SYMBOL_CHOOSER, true, this ) )
|
||||
{
|
||||
m_specifiedId->SetValue( UnescapeString( newName ) );
|
||||
updateFieldsList();
|
||||
}
|
||||
if( frame->ShowModal( &newName, this ) )
|
||||
{
|
||||
m_specifiedId->SetValue( UnescapeString( newName ) );
|
||||
updateFieldsList();
|
||||
}
|
||||
|
||||
frame->Destroy();
|
||||
frame->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -264,15 +265,16 @@ void DIALOG_CHANGE_SYMBOLS::launchNewIdSymbolBrowser( wxCommandEvent& aEvent )
|
||||
{
|
||||
wxString newName = getLibIdValue( m_newId );
|
||||
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SYMBOL_CHOOSER, true, this );
|
||||
|
||||
if( frame->ShowModal( &newName, this ) )
|
||||
if( KIWAY_PLAYER* frame = Kiway().Player( FRAME_SYMBOL_CHOOSER, true, this ) )
|
||||
{
|
||||
m_newId->SetValue( UnescapeString( newName ) );
|
||||
updateFieldsList();
|
||||
}
|
||||
if( frame->ShowModal( &newName, this ) )
|
||||
{
|
||||
m_newId->SetValue( UnescapeString( newName ) );
|
||||
updateFieldsList();
|
||||
}
|
||||
|
||||
frame->Destroy();
|
||||
frame->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
|
||||
m_currentSchematic = &parent->Schematic();
|
||||
|
||||
SetName( DIALOG_ERC_WINDOW_NAME ); // Set a window name to be able to find it
|
||||
KIPLATFORM::UI::SetFloatLevel( this );
|
||||
|
||||
EESCHEMA_SETTINGS* settings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
|
||||
m_severities = settings->m_Appearance.erc_severities;
|
||||
@@ -466,6 +467,8 @@ void DIALOG_ERC::OnRunERCClick( wxCommandEvent& event )
|
||||
m_ercRun = true;
|
||||
redrawDrawPanel();
|
||||
updateDisplayedCounts();
|
||||
// set float level again, it can be lost due to window events during test run
|
||||
KIPLATFORM::UI::SetFloatLevel( this );
|
||||
}
|
||||
|
||||
|
||||
@@ -510,7 +513,7 @@ void DIALOG_ERC::OnERCItemSelected( wxDataViewEvent& aEvent )
|
||||
{
|
||||
const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
|
||||
SCH_SHEET_PATH sheet;
|
||||
SCH_ITEM* item = m_parent->Schematic().GetSheets().GetItem( itemID, &sheet );
|
||||
SCH_ITEM* item = m_parent->Schematic().GetItem( itemID, &sheet );
|
||||
|
||||
if( m_centerMarkerOnIdle )
|
||||
{
|
||||
|
||||
@@ -677,7 +677,7 @@ void DIALOG_SCH_FIELD_PROPERTIES::UpdateField( SCH_COMMIT* aCommit, SCH_FIELD* a
|
||||
int unit = symbol->GetUnit();
|
||||
LIB_ID libId = symbol->GetLibId();
|
||||
|
||||
for( SCH_SHEET_PATH& sheet : editFrame->Schematic().GetSheets() )
|
||||
for( SCH_SHEET_PATH& sheet : editFrame->Schematic().GetUnorderedSheets() )
|
||||
{
|
||||
SCH_SCREEN* screen = sheet.LastScreen();
|
||||
std::vector<SCH_SYMBOL*> otherUnits;
|
||||
|
||||
@@ -501,7 +501,7 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
|
||||
|
||||
if( m_sheet->GetScreen() == nullptr ) // New just created sheet.
|
||||
{
|
||||
if( !m_frame->AllowCaseSensitiveFileNameClashes( newAbsoluteFilename ) )
|
||||
if( !m_frame->AllowCaseSensitiveFileNameClashes( m_sheet->GetFileName(), newAbsoluteFilename ) )
|
||||
return false;
|
||||
|
||||
if( useScreen || loadFromFile ) // Load from existing file.
|
||||
@@ -526,7 +526,7 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
|
||||
{
|
||||
isExistingSheet = true;
|
||||
|
||||
if( !m_frame->AllowCaseSensitiveFileNameClashes( newAbsoluteFilename ) )
|
||||
if( !m_frame->AllowCaseSensitiveFileNameClashes( m_sheet->GetFileName(), newAbsoluteFilename ) )
|
||||
return false;
|
||||
|
||||
// We are always using here a case insensitive comparison to avoid issues
|
||||
@@ -640,7 +640,7 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
|
||||
|
||||
SCH_SHEET_LIST sheetHierarchy( m_sheet ); // The hierarchy of the loaded file.
|
||||
|
||||
sheetHierarchy.AddNewSymbolInstances( currentSheet );
|
||||
sheetHierarchy.AddNewSymbolInstances( currentSheet, m_frame->Prj().GetProjectName() );
|
||||
sheetHierarchy.AddNewSheetInstances( currentSheet,
|
||||
fullHierarchy.GetLastVirtualPageNumber() );
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ DIALOG_SIM_FORMAT_VALUE::DIALOG_SIM_FORMAT_VALUE( wxWindow* aParent, SPICE_VALUE
|
||||
m_units = aFormat->Range.Right( 2 );
|
||||
SetTitle( wxString::Format( GetTitle(), _( "Frequency" ) ) );
|
||||
}
|
||||
else if( aFormat->Range.EndsWith( wxS( "dBV" ) ) )
|
||||
else if( aFormat->Range.EndsWith( wxS( "dB" ) ) )
|
||||
{
|
||||
m_units = aFormat->Range.Right( 3 );
|
||||
SetTitle( wxString::Format( GetTitle(), _( "Gain" ) ) );
|
||||
|
||||
@@ -109,14 +109,15 @@ protected:
|
||||
if( event.GetId() == MYID_SELECT_FOOTPRINT )
|
||||
{
|
||||
// pick a footprint using the footprint picker.
|
||||
wxString fpid = m_grid->GetCellValue( m_grid->GetGridCursorRow(),
|
||||
FOOTPRINT_FIELD );
|
||||
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg );
|
||||
wxString fpid = m_grid->GetCellValue( m_grid->GetGridCursorRow(), FOOTPRINT_FIELD );
|
||||
|
||||
if( frame->ShowModal( &fpid, m_dlg ) )
|
||||
m_grid->SetCellValue( m_grid->GetGridCursorRow(), FOOTPRINT_FIELD, fpid );
|
||||
if( KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg ) )
|
||||
{
|
||||
if( frame->ShowModal( &fpid, m_dlg ) )
|
||||
m_grid->SetCellValue( m_grid->GetGridCursorRow(), FOOTPRINT_FIELD, fpid );
|
||||
|
||||
frame->Destroy();
|
||||
frame->Destroy();
|
||||
}
|
||||
}
|
||||
else if (event.GetId() == MYID_SHOW_DATASHEET )
|
||||
{
|
||||
@@ -305,7 +306,7 @@ DIALOG_SYMBOL_FIELDS_TABLE::DIALOG_SYMBOL_FIELDS_TABLE( SCH_EDIT_FRAME* parent )
|
||||
case SCOPE::SCOPE_SHEET_RECURSIVE: m_radioRecursive->SetValue( true ); break;
|
||||
}
|
||||
|
||||
m_outputFileName->SetValue( cfg->m_FieldEditorPanel.export_filename );
|
||||
m_outputFileName->SetValue( m_schSettings.m_BomExportFileName );
|
||||
|
||||
Center();
|
||||
|
||||
@@ -1338,12 +1339,13 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnClose( wxCloseEvent& aEvent )
|
||||
|
||||
// Save all our settings since we're really closing
|
||||
savePresetsToSchematic();
|
||||
m_schSettings.m_BomExportFileName = m_outputFileName->GetValue();
|
||||
|
||||
EESCHEMA_SETTINGS* cfg = m_parent->eeconfig();
|
||||
|
||||
cfg->m_FieldEditorPanel.width = GetSize().x;
|
||||
cfg->m_FieldEditorPanel.height = GetSize().y;
|
||||
cfg->m_FieldEditorPanel.page = m_nbPages->GetSelection();
|
||||
cfg->m_FieldEditorPanel.export_filename = m_outputFileName->GetValue();
|
||||
|
||||
if( m_radioHighlight->GetValue() )
|
||||
cfg->m_FieldEditorPanel.selection_mode = 0;
|
||||
|
||||
@@ -792,7 +792,7 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataFromWindow()
|
||||
int unit = m_symbol->GetUnit();
|
||||
LIB_ID libId = m_symbol->GetLibId();
|
||||
|
||||
for( SCH_SHEET_PATH& sheet : GetParent()->Schematic().GetSheets() )
|
||||
for( SCH_SHEET_PATH& sheet : GetParent()->Schematic().GetUnorderedSheets() )
|
||||
{
|
||||
SCH_SCREEN* screen = sheet.LastScreen();
|
||||
std::vector<SCH_SYMBOL*> otherUnits;
|
||||
|
||||
@@ -150,7 +150,7 @@ DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_ITE
|
||||
|
||||
m_separator5->SetIsSeparator();
|
||||
|
||||
SCH_SHEET_LIST sheetList = m_frame->Schematic().GetSheets();
|
||||
SCH_SHEET_LIST sheetList = m_frame->Schematic().GetUnorderedSheets();
|
||||
sheetList.SortByPageNumbers( false );
|
||||
|
||||
for( const SCH_SHEET_PATH& sheet : sheetList )
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2024 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
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <../sim/simulator_frame.h>
|
||||
#include <dialog_user_defined_signals.h>
|
||||
#include <string_utils.h>
|
||||
#include <validators.h>
|
||||
|
||||
|
||||
DIALOG_USER_DEFINED_SIGNALS::DIALOG_USER_DEFINED_SIGNALS( SIMULATOR_FRAME* aParent,
|
||||
@@ -86,12 +87,19 @@ void DIALOG_USER_DEFINED_SIGNALS::addGridRow( const wxString& aText, int aId )
|
||||
m_grid->SetCellValue( row, 1, wxString::Format( wxS( "%d" ), aId ) );
|
||||
|
||||
wxGridCellAttr* attr = new wxGridCellAttr;
|
||||
#if defined( __WXMSW__ )
|
||||
// For some obscure reason, a GRID_CELL_STC_EDITOR does not work on MSW:
|
||||
// It has a strange behavior when entering data, making it unusable.
|
||||
// (see https://gitlab.com/kicad/code/kicad/-/issues/15837)
|
||||
// So use a GRID_CELL_TEXT_EDITOR.
|
||||
attr->SetEditor( new GRID_CELL_TEXT_EDITOR() );
|
||||
#else
|
||||
attr->SetEditor( new GRID_CELL_STC_EDITOR( true,
|
||||
[this]( wxStyledTextEvent& aEvent, SCINTILLA_TRICKS* aScintillaTricks )
|
||||
{
|
||||
onScintillaCharAdded( aEvent, aScintillaTricks );
|
||||
} ) );
|
||||
|
||||
#endif
|
||||
m_grid->SetAttr( row, 0, attr );
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,11 @@ PANEL_EESCHEMA_COLOR_SETTINGS::~PANEL_EESCHEMA_COLOR_SETTINGS()
|
||||
delete m_currentSettings;
|
||||
|
||||
for( EDA_ITEM* item : m_previewItems )
|
||||
{
|
||||
// Avoid referencing items after they are deleted (we don't control order)
|
||||
item->SetParent( nullptr );
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -226,6 +226,11 @@ protected:
|
||||
m_grid->AutoSizeColumns( false );
|
||||
}
|
||||
}
|
||||
|
||||
bool supportsVisibilityColumn() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@ void SCH_EDIT_FRAME::ShowSchematicSetupDialog( const wxString& aInitialPage )
|
||||
|
||||
Prj().IncrementTextVarsTicker();
|
||||
Prj().IncrementNetclassesTicker();
|
||||
Pgm().GetSettingsManager().SaveProject();
|
||||
|
||||
GetRenderSettings()->SetDefaultPenWidth( Schematic().Settings().m_DefaultLineWidth );
|
||||
GetRenderSettings()->m_LabelSizeRatio = Schematic().Settings().m_LabelSizeRatio;
|
||||
|
||||
@@ -740,7 +740,7 @@ int EESCHEMA_JOBS_HANDLER::doSymExportSvg( JOB_SYM_EXPORT_SVG* aSvgJob,
|
||||
}
|
||||
|
||||
// Get the symbol bounding box to fit the plot page to it
|
||||
BOX2I symbolBB = symbol->Flatten()->GetUnitBoundingBox( unit, bodyStyle, false );
|
||||
BOX2I symbolBB = symbol->Flatten()->GetUnitBoundingBox( unit, bodyStyle, !aSvgJob->m_includeHiddenFields );
|
||||
PAGE_INFO pageInfo( PAGE_INFO::Custom );
|
||||
pageInfo.SetHeightMils( schIUScale.IUToMils( symbolBB.GetHeight() * 1.2 ) );
|
||||
pageInfo.SetWidthMils( schIUScale.IUToMils( symbolBB.GetWidth() * 1.2 ) );
|
||||
@@ -750,7 +750,7 @@ int EESCHEMA_JOBS_HANDLER::doSymExportSvg( JOB_SYM_EXPORT_SVG* aSvgJob,
|
||||
plotter->SetPageSettings( pageInfo );
|
||||
plotter->SetColorMode( !aSvgJob->m_blackAndWhite );
|
||||
|
||||
VECTOR2I plot_offset;
|
||||
VECTOR2I plot_offset = symbolBB.GetCenter();
|
||||
const double scale = 1.0;
|
||||
|
||||
// Currently, plot units are in decimal
|
||||
|
||||
+65
-76
@@ -131,12 +131,9 @@ const std::set<ELECTRICAL_PINTYPE> DrivenPinTypes =
|
||||
|
||||
int ERC_TESTER::TestDuplicateSheetNames( bool aCreateMarker )
|
||||
{
|
||||
SCH_SCREEN* screen;
|
||||
int err_count = 0;
|
||||
int err_count = 0;
|
||||
|
||||
SCH_SCREENS screenList( m_schematic->Root() );
|
||||
|
||||
for( screen = screenList.GetFirst(); screen != nullptr; screen = screenList.GetNext() )
|
||||
for( SCH_SCREEN* screen = m_screens.GetFirst(); screen; screen = m_screens.GetNext() )
|
||||
{
|
||||
std::vector<SCH_SHEET*> list;
|
||||
|
||||
@@ -197,7 +194,7 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
|
||||
wsItems.BuildDrawItemsList( aDrawingSheet->GetPageInfo(), aDrawingSheet->GetTitleBlock() );
|
||||
}
|
||||
|
||||
for( SCH_SHEET_PATH& sheet : m_schematic->GetSheets() )
|
||||
for( const SCH_SHEET_PATH& sheet : m_sheetList )
|
||||
{
|
||||
SCH_SCREEN* screen = sheet.LastScreen();
|
||||
|
||||
@@ -300,13 +297,11 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
|
||||
|
||||
int ERC_TESTER::TestConflictingBusAliases()
|
||||
{
|
||||
wxString msg;
|
||||
int err_count = 0;
|
||||
wxString msg;
|
||||
int err_count = 0;
|
||||
std::vector<std::shared_ptr<BUS_ALIAS>> aliases;
|
||||
|
||||
SCH_SCREENS screens( m_schematic->Root() );
|
||||
std::vector< std::shared_ptr<BUS_ALIAS> > aliases;
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
|
||||
for( SCH_SCREEN* screen = m_screens.GetFirst(); screen; screen = m_screens.GetNext() )
|
||||
{
|
||||
const auto& screen_aliases = screen->GetBusAliases();
|
||||
|
||||
@@ -347,13 +342,9 @@ int ERC_TESTER::TestConflictingBusAliases()
|
||||
|
||||
int ERC_TESTER::TestMultiunitFootprints()
|
||||
{
|
||||
SCH_SHEET_LIST sheets = m_schematic->GetSheets();
|
||||
|
||||
int errors = 0;
|
||||
SCH_MULTI_UNIT_REFERENCE_MAP refMap;
|
||||
sheets.GetMultiUnitSymbols( refMap, true );
|
||||
|
||||
for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
|
||||
for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : m_refMap )
|
||||
{
|
||||
SCH_REFERENCE_LIST& refList = symbol.second;
|
||||
|
||||
@@ -412,14 +403,9 @@ int ERC_TESTER::TestMultiunitFootprints()
|
||||
|
||||
int ERC_TESTER::TestMissingUnits()
|
||||
{
|
||||
ERC_SETTINGS& settings = m_schematic->ErcSettings();
|
||||
SCH_SHEET_LIST sheets = m_schematic->GetSheets();
|
||||
|
||||
int errors = 0;
|
||||
SCH_MULTI_UNIT_REFERENCE_MAP refMap;
|
||||
sheets.GetMultiUnitSymbols( refMap, true );
|
||||
|
||||
for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
|
||||
for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : m_refMap )
|
||||
{
|
||||
SCH_REFERENCE_LIST& refList = symbol.second;
|
||||
|
||||
@@ -437,38 +423,38 @@ int ERC_TESTER::TestMissingUnits()
|
||||
std::set<int> instance_units;
|
||||
std::set<int> missing_units;
|
||||
|
||||
auto report_missing = [&]( std::set<int>& aMissingUnits, wxString aErrorMsg,
|
||||
int aErrorCode )
|
||||
{
|
||||
wxString msg;
|
||||
wxString missing_pin_units = wxS( "[ " );
|
||||
int ii = 0;
|
||||
|
||||
for( int missing_unit : aMissingUnits )
|
||||
{
|
||||
if( ii++ == 3 )
|
||||
auto report_missing =
|
||||
[&]( std::set<int>& aMissingUnits, wxString aErrorMsg, int aErrorCode )
|
||||
{
|
||||
missing_pin_units += wxS( "....." );
|
||||
break;
|
||||
}
|
||||
wxString msg;
|
||||
wxString missing_pin_units = wxS( "[ " );
|
||||
int ii = 0;
|
||||
|
||||
missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit ) + ", " ;
|
||||
}
|
||||
for( int missing_unit : aMissingUnits )
|
||||
{
|
||||
if( ii++ == 3 )
|
||||
{
|
||||
missing_pin_units += wxS( "....." );
|
||||
break;
|
||||
}
|
||||
|
||||
missing_pin_units.Truncate( missing_pin_units.length() - 2 );
|
||||
missing_pin_units += wxS( " ]" );
|
||||
missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit ) + ", " ;
|
||||
}
|
||||
|
||||
msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
|
||||
missing_pin_units.Truncate( missing_pin_units.length() - 2 );
|
||||
missing_pin_units += wxS( " ]" );
|
||||
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aErrorCode );
|
||||
ercItem->SetErrorMessage( msg );
|
||||
ercItem->SetItems( unit );
|
||||
msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, unit->GetPosition() );
|
||||
base_ref.GetSheetPath().LastScreen()->Append( marker );
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aErrorCode );
|
||||
ercItem->SetErrorMessage( msg );
|
||||
ercItem->SetItems( unit );
|
||||
|
||||
++errors;
|
||||
};
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, unit->GetPosition() );
|
||||
base_ref.GetSheetPath().LastScreen()->Append( marker );
|
||||
|
||||
++errors;
|
||||
};
|
||||
|
||||
for( int ii = 1; ii <= libSymbol->GetUnitCount(); ++ii )
|
||||
lib_units.insert( lib_units.end(), ii );
|
||||
@@ -480,7 +466,7 @@ int ERC_TESTER::TestMissingUnits()
|
||||
instance_units.begin(), instance_units.end(),
|
||||
std::inserter( missing_units, missing_units.begin() ) );
|
||||
|
||||
if( !missing_units.empty() && settings.IsTestEnabled( ERCE_MISSING_UNIT ) )
|
||||
if( !missing_units.empty() && m_settings.IsTestEnabled( ERCE_MISSING_UNIT ) )
|
||||
{
|
||||
report_missing( missing_units, _( "Symbol %s has unplaced units %s" ),
|
||||
ERCE_MISSING_UNIT );
|
||||
@@ -528,21 +514,21 @@ int ERC_TESTER::TestMissingUnits()
|
||||
}
|
||||
}
|
||||
|
||||
if( !missing_power.empty() && settings.IsTestEnabled( ERCE_MISSING_POWER_INPUT_PIN ) )
|
||||
if( !missing_power.empty() && m_settings.IsTestEnabled( ERCE_MISSING_POWER_INPUT_PIN ) )
|
||||
{
|
||||
report_missing( missing_power,
|
||||
_( "Symbol %s has input power pins in units %s that are not placed." ),
|
||||
ERCE_MISSING_POWER_INPUT_PIN );
|
||||
}
|
||||
|
||||
if( !missing_input.empty() && settings.IsTestEnabled( ERCE_MISSING_INPUT_PIN ) )
|
||||
if( !missing_input.empty() && m_settings.IsTestEnabled( ERCE_MISSING_INPUT_PIN ) )
|
||||
{
|
||||
report_missing( missing_input,
|
||||
_( "Symbol %s has input pins in units %s that are not placed." ),
|
||||
ERCE_MISSING_INPUT_PIN );
|
||||
}
|
||||
|
||||
if( !missing_bidi.empty() && settings.IsTestEnabled( ERCE_MISSING_BIDI_PIN ) )
|
||||
if( !missing_bidi.empty() && m_settings.IsTestEnabled( ERCE_MISSING_BIDI_PIN ) )
|
||||
{
|
||||
report_missing( missing_bidi,
|
||||
_( "Symbol %s has bidirectional pins in units %s that are not "
|
||||
@@ -576,7 +562,7 @@ int ERC_TESTER::TestMissingNetclasses()
|
||||
sheet.LastScreen()->Append( marker );
|
||||
};
|
||||
|
||||
for( const SCH_SHEET_PATH& sheet : m_schematic->GetSheets() )
|
||||
for( const SCH_SHEET_PATH& sheet : m_sheetList )
|
||||
{
|
||||
for( SCH_ITEM* item : sheet.LastScreen()->Items() )
|
||||
{
|
||||
@@ -612,7 +598,7 @@ int ERC_TESTER::TestNoConnectPins()
|
||||
{
|
||||
int err_count = 0;
|
||||
|
||||
for( const SCH_SHEET_PATH& sheet : m_schematic->GetSheets() )
|
||||
for( const SCH_SHEET_PATH& sheet : m_sheetList )
|
||||
{
|
||||
std::map<VECTOR2I, std::vector<SCH_ITEM*>> pinMap;
|
||||
|
||||
@@ -679,12 +665,9 @@ int ERC_TESTER::TestNoConnectPins()
|
||||
|
||||
int ERC_TESTER::TestPinToPin()
|
||||
{
|
||||
ERC_SETTINGS& settings = m_schematic->ErcSettings();
|
||||
const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
|
||||
|
||||
int errors = 0;
|
||||
|
||||
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
|
||||
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : m_nets )
|
||||
{
|
||||
std::vector<ERC_SCH_PIN_CONTEXT> pins;
|
||||
std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
|
||||
@@ -705,6 +688,21 @@ int ERC_TESTER::TestPinToPin()
|
||||
}
|
||||
}
|
||||
|
||||
std::sort( pins.begin(), pins.end(),
|
||||
[]( const ERC_SCH_PIN_CONTEXT& lhs, const ERC_SCH_PIN_CONTEXT& rhs )
|
||||
{
|
||||
int ret = StrNumCmp( lhs.Pin()->GetParentSymbol()->GetRef( &lhs.Sheet() ),
|
||||
rhs.Pin()->GetParentSymbol()->GetRef( &rhs.Sheet() ) );
|
||||
|
||||
if( ret == 0 )
|
||||
ret = StrNumCmp( lhs.Pin()->GetNumber(), rhs.Pin()->GetNumber() );
|
||||
|
||||
if( ret == 0 )
|
||||
ret = lhs < rhs; // Fallback to hash to guarantee deterministic sort
|
||||
|
||||
return ret < 0;
|
||||
} );
|
||||
|
||||
ERC_SCH_PIN_CONTEXT needsDriver;
|
||||
bool hasDriver = false;
|
||||
|
||||
@@ -765,9 +763,9 @@ int ERC_TESTER::TestPinToPin()
|
||||
else
|
||||
hasDriver |= ( DrivingPinTypes.count( testType ) != 0 );
|
||||
|
||||
PIN_ERROR erc = settings.GetPinMapValue( refType, testType );
|
||||
PIN_ERROR erc = m_settings.GetPinMapValue( refType, testType );
|
||||
|
||||
if( erc != PIN_ERROR::OK && settings.IsTestEnabled( ERCE_PIN_TO_PIN_WARNING ) )
|
||||
if( erc != PIN_ERROR::OK && m_settings.IsTestEnabled( ERCE_PIN_TO_PIN_WARNING ) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem =
|
||||
ERC_ITEM::Create( erc == PIN_ERROR::WARNING ? ERCE_PIN_TO_PIN_WARNING :
|
||||
@@ -793,7 +791,7 @@ int ERC_TESTER::TestPinToPin()
|
||||
{
|
||||
int err_code = ispowerNet ? ERCE_POWERPIN_NOT_DRIVEN : ERCE_PIN_NOT_DRIVEN;
|
||||
|
||||
if( settings.IsTestEnabled( err_code ) )
|
||||
if( m_settings.IsTestEnabled( err_code ) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( err_code );
|
||||
|
||||
@@ -815,13 +813,11 @@ int ERC_TESTER::TestPinToPin()
|
||||
|
||||
int ERC_TESTER::TestMultUnitPinConflicts()
|
||||
{
|
||||
const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
|
||||
|
||||
int errors = 0;
|
||||
|
||||
std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
|
||||
|
||||
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
|
||||
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : m_nets )
|
||||
{
|
||||
const wxString& netName = net.first.Name;
|
||||
|
||||
@@ -875,13 +871,11 @@ int ERC_TESTER::TestMultUnitPinConflicts()
|
||||
|
||||
int ERC_TESTER::TestSimilarLabels()
|
||||
{
|
||||
const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
|
||||
|
||||
int errors = 0;
|
||||
|
||||
std::unordered_map<wxString, std::pair<SCH_LABEL_BASE*, SCH_SHEET_PATH>> labelMap;
|
||||
|
||||
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
|
||||
for( const std::pair<NET_NAME_CODE_CACHE_KEY, std::vector<CONNECTION_SUBGRAPH*>> net : m_nets )
|
||||
{
|
||||
for( CONNECTION_SUBGRAPH* subgraph : net.second )
|
||||
{
|
||||
@@ -942,9 +936,7 @@ int ERC_TESTER::TestLibSymbolIssues()
|
||||
wxString msg;
|
||||
int err_count = 0;
|
||||
|
||||
SCH_SCREENS screens( m_schematic->Root() );
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
|
||||
for( SCH_SCREEN* screen = m_screens.GetFirst(); screen; screen = m_screens.GetNext() )
|
||||
{
|
||||
std::vector<SCH_MARKER*> markers;
|
||||
|
||||
@@ -1027,11 +1019,9 @@ int ERC_TESTER::TestLibSymbolIssues()
|
||||
int ERC_TESTER::TestOffGridEndpoints()
|
||||
{
|
||||
const int gridSize = m_schematic->Settings().m_ConnectionGridSize;
|
||||
int err_count = 0;
|
||||
|
||||
SCH_SCREENS screens( m_schematic->Root() );
|
||||
int err_count = 0;
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
|
||||
for( SCH_SCREEN* screen = m_screens.GetFirst(); screen; screen = m_screens.GetNext() )
|
||||
{
|
||||
std::vector<SCH_MARKER*> markers;
|
||||
|
||||
@@ -1093,11 +1083,10 @@ int ERC_TESTER::TestSimModelIssues()
|
||||
{
|
||||
wxString msg;
|
||||
WX_STRING_REPORTER reporter( &msg );
|
||||
SCH_SHEET_LIST sheets = m_schematic->GetSheets();
|
||||
int err_count = 0;
|
||||
SIM_LIB_MGR libMgr( &m_schematic->Prj() );
|
||||
|
||||
for( SCH_SHEET_PATH& sheet : sheets )
|
||||
for( SCH_SHEET_PATH& sheet : m_sheetList )
|
||||
{
|
||||
std::vector<SCH_MARKER*> markers;
|
||||
|
||||
|
||||
+14
-4
@@ -27,9 +27,10 @@
|
||||
#define ERC_H
|
||||
|
||||
#include <erc_settings.h>
|
||||
#include <sch_screen.h>
|
||||
#include <connection_graph.h>
|
||||
|
||||
|
||||
class SCH_SHEET_LIST;
|
||||
class SCHEMATIC;
|
||||
class DS_PROXY_VIEW_ITEM;
|
||||
class SCH_EDIT_FRAME;
|
||||
@@ -47,8 +48,13 @@ class ERC_TESTER
|
||||
public:
|
||||
|
||||
ERC_TESTER( SCHEMATIC* aSchematic ) :
|
||||
m_schematic( aSchematic )
|
||||
m_schematic( aSchematic ),
|
||||
m_settings( aSchematic->ErcSettings() ),
|
||||
m_sheetList( aSchematic->GetSheets() ),
|
||||
m_screens( aSchematic->Root() ),
|
||||
m_nets( aSchematic->ConnectionGraph()->GetNetMap() )
|
||||
{
|
||||
m_sheetList.GetMultiUnitSymbols( m_refMap, true );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,8 +145,12 @@ public:
|
||||
KIFACE* aCvPcb, PROJECT* aProject, PROGRESS_REPORTER* aProgressReporter );
|
||||
|
||||
private:
|
||||
|
||||
SCHEMATIC* m_schematic;
|
||||
SCHEMATIC* m_schematic;
|
||||
ERC_SETTINGS& m_settings;
|
||||
SCH_SHEET_LIST m_sheetList;
|
||||
SCH_SCREENS m_screens;
|
||||
SCH_MULTI_UNIT_REFERENCE_MAP m_refMap;
|
||||
const NET_MAP& m_nets;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -30,13 +30,13 @@
|
||||
#include <erc_sch_pin_context.h>
|
||||
|
||||
|
||||
SCH_PIN* ERC_SCH_PIN_CONTEXT::Pin()
|
||||
SCH_PIN* ERC_SCH_PIN_CONTEXT::Pin() const
|
||||
{
|
||||
return m_pin;
|
||||
}
|
||||
|
||||
|
||||
SCH_SHEET_PATH& ERC_SCH_PIN_CONTEXT::Sheet()
|
||||
const SCH_SHEET_PATH& ERC_SCH_PIN_CONTEXT::Sheet() const
|
||||
{
|
||||
return m_sheet;
|
||||
}
|
||||
|
||||
@@ -56,12 +56,12 @@ public:
|
||||
/**
|
||||
* Get the SCH_PIN for this context.
|
||||
*/
|
||||
SCH_PIN* Pin();
|
||||
SCH_PIN* Pin() const;
|
||||
|
||||
/**
|
||||
* Get the #SCH_SHEET_PATH context for the paired #SCH_PIN.
|
||||
*/
|
||||
SCH_SHEET_PATH& Sheet();
|
||||
const SCH_SHEET_PATH& Sheet() const;
|
||||
|
||||
/**
|
||||
* Test two pin contexts for equality based on the deterministic hash.
|
||||
|
||||
@@ -53,11 +53,10 @@ void FIELDS_EDITOR_GRID_DATA_MODEL::AddColumn( const wxString& aFieldName, const
|
||||
void FIELDS_EDITOR_GRID_DATA_MODEL::updateDataStoreSymbolField( const SCH_SYMBOL& aSymbol,
|
||||
const wxString& aFieldName )
|
||||
{
|
||||
if( const SCH_FIELD* field = aSymbol.GetFieldByName( aFieldName ) )
|
||||
m_dataStore[aSymbol.m_Uuid][aFieldName] = field->GetText();
|
||||
else if( isAttribute( aFieldName ) )
|
||||
if( isAttribute( aFieldName ) )
|
||||
m_dataStore[aSymbol.m_Uuid][aFieldName] = getAttributeValue( aSymbol, aFieldName );
|
||||
|
||||
else if( const SCH_FIELD* field = aSymbol.GetFieldByName( aFieldName ) )
|
||||
m_dataStore[aSymbol.m_Uuid][aFieldName] = field->GetText();
|
||||
// Handle fields with variables as names that are not present in the symbol
|
||||
// by giving them the correct value
|
||||
else if( IsTextVar( aFieldName ) )
|
||||
|
||||
@@ -946,13 +946,15 @@ void FIELDS_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
|
||||
if( event.GetId() == MYID_SELECT_FOOTPRINT )
|
||||
{
|
||||
// pick a footprint using the footprint picker.
|
||||
wxString fpid = m_grid->GetCellValue( FOOTPRINT_FIELD, FDC_VALUE );
|
||||
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg );
|
||||
wxString fpid = m_grid->GetCellValue( FOOTPRINT_FIELD, FDC_VALUE );
|
||||
|
||||
if( frame->ShowModal( &fpid, m_dlg ) )
|
||||
m_grid->SetCellValue( FOOTPRINT_FIELD, FDC_VALUE, fpid );
|
||||
if( KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg ) )
|
||||
{
|
||||
if( frame->ShowModal( &fpid, m_dlg ) )
|
||||
m_grid->SetCellValue( FOOTPRINT_FIELD, FDC_VALUE, fpid );
|
||||
|
||||
frame->Destroy();
|
||||
frame->Destroy();
|
||||
}
|
||||
}
|
||||
else if (event.GetId() == MYID_SHOW_DATASHEET )
|
||||
{
|
||||
|
||||
+22
-5
@@ -61,6 +61,7 @@
|
||||
#include <tools/sch_editor_control.h>
|
||||
#include <tools/sch_navigate_tool.h>
|
||||
#include <trace_helpers.h>
|
||||
#include <widgets/filedlg_import_non_kicad.h>
|
||||
#include <widgets/wx_infobar.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <drawing_sheet/ds_data_model.h>
|
||||
@@ -145,6 +146,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
// unload current project file before loading new
|
||||
{
|
||||
ClearUndoRedoList();
|
||||
ClearRepeatItemsList();
|
||||
SetScreen( nullptr );
|
||||
m_toolManager->GetTool<EE_INSPECTION_TOOL>()->Reset( TOOL_BASE::SUPERMODEL_RELOAD );
|
||||
CreateScreens();
|
||||
@@ -179,7 +181,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
CreateScreens();
|
||||
}
|
||||
|
||||
SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromSchPath( fullFileName );
|
||||
SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromSchPath( fullFileName, KICTL_KICAD_ONLY );
|
||||
|
||||
if( schFileType == SCH_IO_MGR::SCH_LEGACY )
|
||||
{
|
||||
@@ -229,7 +231,10 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
|
||||
if( schFileType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
|
||||
{
|
||||
msg.Printf( _( "Unsupported schematic file '%s'." ), fullFileName );
|
||||
msg.Printf( _( "'%s' is not a KiCad schematic file.\nUse File -> Import for "
|
||||
"non-KiCad schematic files." ),
|
||||
fullFileName );
|
||||
|
||||
progressReporter.Hide();
|
||||
DisplayErrorMessage( this, msg );
|
||||
}
|
||||
@@ -730,12 +735,18 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
|
||||
wxFileDialog dlg( this, _( "Import Schematic" ), path, wxEmptyString, fileFiltersStr,
|
||||
wxFD_OPEN | wxFD_FILE_MUST_EXIST ); // TODO
|
||||
|
||||
FILEDLG_IMPORT_NON_KICAD importOptions( eeconfig()->m_System.show_import_issues );
|
||||
dlg.SetCustomizeHook( importOptions );
|
||||
|
||||
if( dlg.ShowModal() == wxID_CANCEL )
|
||||
return;
|
||||
|
||||
eeconfig()->m_System.show_import_issues = importOptions.GetShowIssues();
|
||||
|
||||
// Don't leave dangling pointers to previously-opened document.
|
||||
m_toolManager->GetTool<EE_SELECTION_TOOL>()->ClearSelection();
|
||||
ClearUndoRedoList();
|
||||
ClearRepeatItemsList();
|
||||
|
||||
if( setProject )
|
||||
{
|
||||
@@ -1069,7 +1080,7 @@ bool SCH_EDIT_FRAME::SaveProject( bool aSaveAs )
|
||||
// File doesn't exist yet; true if we just imported something
|
||||
updateFileHistory = true;
|
||||
}
|
||||
else if( !Schematic().GetSheets().IsModified() )
|
||||
else if( !IsContentModified() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1383,7 +1394,11 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
|
||||
std::placeholders::_1 ) );
|
||||
}
|
||||
|
||||
pi->SetReporter( errorReporter.m_Reporter );
|
||||
if( eeconfig()->m_System.show_import_issues )
|
||||
pi->SetReporter( errorReporter.m_Reporter );
|
||||
else
|
||||
pi->SetReporter( &NULL_REPORTER::GetInstance() );
|
||||
|
||||
pi->SetProgressReporter( &progressReporter );
|
||||
|
||||
SCH_SHEET* loadedSheet =
|
||||
@@ -1452,6 +1467,7 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
|
||||
}
|
||||
|
||||
ClearUndoRedoList();
|
||||
ClearRepeatItemsList();
|
||||
|
||||
initScreenZoom();
|
||||
SetSheetNumberAndCount();
|
||||
@@ -1650,7 +1666,8 @@ void SCH_EDIT_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
|
||||
}
|
||||
// Attempt to back up the last schematic file before overwriting it with the auto
|
||||
// save file.
|
||||
else if( !wxCopyFile( recoveredFn.GetFullPath(), backupFn.GetFullPath() ) )
|
||||
else if( recoveredFn.Exists()
|
||||
&& !wxCopyFile( recoveredFn.GetFullPath(), backupFn.GetFullPath() ) )
|
||||
{
|
||||
unrecoveredFiles.Add( recoveredFn.GetFullPath() );
|
||||
}
|
||||
|
||||
@@ -664,6 +664,11 @@ static struct LIB_FIELD_DESC
|
||||
propMgr.Mask( TYPE_HASH( LIB_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Width" ) );
|
||||
propMgr.Mask( TYPE_HASH( LIB_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Height" ) );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<LIB_FIELD, int>(
|
||||
_HKI( "Text Size" ), &LIB_FIELD::SetLibTextSize,
|
||||
&LIB_FIELD::GetLibTextSize, PROPERTY_DISPLAY::PT_SIZE ),
|
||||
_HKI( "Text Properties" ) );
|
||||
|
||||
propMgr.Mask( TYPE_HASH( LIB_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Orientation" ) );
|
||||
}
|
||||
} _LIB_FIELD_DESC;
|
||||
|
||||
@@ -161,6 +161,9 @@ public:
|
||||
|
||||
wxString GetShownText( bool aAllowExtraText, int aDepth = 0 ) const override;
|
||||
|
||||
int GetLibTextSize() const { return GetTextWidth(); }
|
||||
void SetLibTextSize( int aSize ) { SetTextSize( VECTOR2I( aSize, aSize ) ); }
|
||||
|
||||
SCH_LAYER_ID GetDefaultLayer() const;
|
||||
|
||||
void BeginEdit( const VECTOR2I& aStartPoint ) override;
|
||||
|
||||
@@ -669,6 +669,7 @@ std::unique_ptr< LIB_SYMBOL > LIB_SYMBOL::Flatten() const
|
||||
retv->SetExcludedFromBoard( parent->GetExcludedFromBoard() );
|
||||
|
||||
retv->UpdateFieldOrdinals();
|
||||
retv->m_parent.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -159,6 +159,7 @@ public:
|
||||
virtual void SetName( const wxString& aName );
|
||||
wxString GetName() const override { return m_name; }
|
||||
|
||||
const LIB_ID& LibId() const { return m_libId; }
|
||||
LIB_ID& LibId() { return m_libId; }
|
||||
LIB_ID GetLibId() const override { return m_libId; }
|
||||
void SetLibId( const LIB_ID& aLibId ) { m_libId = aLibId; }
|
||||
|
||||
@@ -171,7 +171,8 @@ static wxString GetNetNavigatorItemText( const SCH_ITEM* aItem,
|
||||
|
||||
|
||||
void SCH_EDIT_FRAME::MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemId aParentId,
|
||||
const NET_NAVIGATOR_ITEM_DATA* aSelection )
|
||||
const NET_NAVIGATOR_ITEM_DATA* aSelection,
|
||||
bool aSingleSheetSchematic )
|
||||
{
|
||||
wxCHECK( !aNetName.IsEmpty(), /* void */ );
|
||||
wxCHECK( m_schematic, /* void */ );
|
||||
@@ -206,7 +207,7 @@ void SCH_EDIT_FRAME::MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemI
|
||||
m_netNavigator->SelectItem( sheetId );
|
||||
|
||||
// If there is only one sheet in the schematic, always expand the sheet tree.
|
||||
if( Schematic().GetSheets().size() == 1 )
|
||||
if( aSingleSheetSchematic )
|
||||
expandId = sheetId;
|
||||
|
||||
for( const SCH_ITEM* item : subGraph->GetItems() )
|
||||
@@ -243,6 +244,8 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect
|
||||
if( m_netNavigator->IsEmpty() && m_highlightedConn.IsEmpty() )
|
||||
return;
|
||||
|
||||
bool singleSheetSchematic = m_schematic->GetUnorderedSheets().size() == 1;
|
||||
|
||||
if( !m_netNavigator->IsEmpty() && m_highlightedConn.IsEmpty() )
|
||||
{
|
||||
m_netNavigator->DeleteAllItems();
|
||||
@@ -259,7 +262,7 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect
|
||||
|
||||
wxTreeItemId rootId = m_netNavigator->AddRoot( UnescapeString( m_highlightedConn ), 0 );
|
||||
|
||||
MakeNetNavigatorNode( m_highlightedConn, rootId, aSelection );
|
||||
MakeNetNavigatorNode( m_highlightedConn, rootId, aSelection, singleSheetSchematic );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -273,14 +276,14 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect
|
||||
m_netNavigator->DeleteAllItems();
|
||||
wxTreeItemId rootId = m_netNavigator->AddRoot( UnescapeString( m_highlightedConn ), 0 );
|
||||
|
||||
MakeNetNavigatorNode( m_highlightedConn, rootId, itemData );
|
||||
MakeNetNavigatorNode( m_highlightedConn, rootId, itemData, singleSheetSchematic );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxTreeItemId rootId = m_netNavigator->AddRoot( UnescapeString( m_highlightedConn ), 0 );
|
||||
|
||||
MakeNetNavigatorNode( m_highlightedConn, rootId, aSelection );
|
||||
MakeNetNavigatorNode( m_highlightedConn, rootId, aSelection, singleSheetSchematic );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,8 +84,7 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName,
|
||||
if( symbol->GetLibSymbolRef()
|
||||
&& symbol->GetLibSymbolRef()->GetFPFilters().GetCount() != 0 )
|
||||
{
|
||||
cmpList.push_back( SCH_REFERENCE( symbol, symbol->GetLibSymbolRef().get(),
|
||||
sheet ) );
|
||||
cmpList.push_back( SCH_REFERENCE( symbol, sheet ) );
|
||||
}
|
||||
|
||||
footprint = symbol->GetFootprintFieldText( true, &sheet, false );
|
||||
|
||||
@@ -479,7 +479,8 @@ void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSym
|
||||
|
||||
auto spiceGenerator = static_cast<const SPICE_GENERATOR_KIBIS&>( kibisModel->SpiceGenerator() );
|
||||
std::string modelData = spiceGenerator.IbisDevice(
|
||||
aItem, m_schematic->Prj(), cacheFn.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR ) );
|
||||
aItem, m_schematic->Prj(),
|
||||
cacheFn.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR ), aReporter );
|
||||
|
||||
cacheFile.Write( wxString( modelData ) );
|
||||
m_rawIncludes.insert( cacheFn.GetFullPath() );
|
||||
|
||||
+89
-82
@@ -23,7 +23,6 @@
|
||||
|
||||
#include <bitmaps.h>
|
||||
#include <cstddef>
|
||||
#include <core/arraydim.h>
|
||||
#include <magic_enum.hpp>
|
||||
#include <lib_pin.h>
|
||||
#include "pgm_base.h"
|
||||
@@ -47,56 +46,18 @@ struct pinTypeStruct
|
||||
BITMAPS bitmap;
|
||||
};
|
||||
|
||||
|
||||
std::map<ELECTRICAL_PINTYPE, struct pinTypeStruct> g_pinTypes = {
|
||||
{ ELECTRICAL_PINTYPE::PT_INPUT, { _( "Input" ), BITMAPS::pintype_input } },
|
||||
{ ELECTRICAL_PINTYPE::PT_OUTPUT, { _( "Output" ), BITMAPS::pintype_output } },
|
||||
{ ELECTRICAL_PINTYPE::PT_BIDI, { _( "Bidirectional" ), BITMAPS::pintype_bidi } },
|
||||
{ ELECTRICAL_PINTYPE::PT_TRISTATE, { _( "Tri-state" ), BITMAPS::pintype_3states } },
|
||||
{ ELECTRICAL_PINTYPE::PT_PASSIVE, { _( "Passive" ), BITMAPS::pintype_passive } },
|
||||
{ ELECTRICAL_PINTYPE::PT_NIC, { _( "Free" ), BITMAPS::pintype_nic } },
|
||||
{ ELECTRICAL_PINTYPE::PT_UNSPECIFIED, { _( "Unspecified" ), BITMAPS::pintype_notspecif } },
|
||||
{ ELECTRICAL_PINTYPE::PT_POWER_IN, { _( "Power input" ), BITMAPS::pintype_powerinput } },
|
||||
{ ELECTRICAL_PINTYPE::PT_POWER_OUT, { _( "Power output" ), BITMAPS::pintype_poweroutput } },
|
||||
{ ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR,{ _( "Open collector" ), BITMAPS::pintype_opencoll } },
|
||||
{ ELECTRICAL_PINTYPE::PT_OPENEMITTER, { _( "Open emitter" ), BITMAPS::pintype_openemit } },
|
||||
{ ELECTRICAL_PINTYPE::PT_NC, { _( "Unconnected" ), BITMAPS::pintype_noconnect } },
|
||||
};
|
||||
|
||||
|
||||
int g_pinTypesLanguage = wxLANGUAGE_UNKNOWN;
|
||||
|
||||
|
||||
struct pinShapeStruct
|
||||
{
|
||||
wxString name;
|
||||
BITMAPS bitmap;
|
||||
};
|
||||
|
||||
|
||||
// clang-format off
|
||||
const std::map<GRAPHIC_PINSHAPE, struct pinShapeStruct> pinShapes = {
|
||||
{ GRAPHIC_PINSHAPE::LINE, { _( "Line" ), BITMAPS::pinshape_normal } },
|
||||
{ GRAPHIC_PINSHAPE::INVERTED, { _( "Inverted" ), BITMAPS::pinshape_invert } },
|
||||
{ GRAPHIC_PINSHAPE::CLOCK, { _( "Clock" ), BITMAPS::pinshape_clock_normal } },
|
||||
{ GRAPHIC_PINSHAPE::INVERTED_CLOCK, { _( "Inverted clock" ), BITMAPS::pinshape_clock_invert } },
|
||||
{ GRAPHIC_PINSHAPE::INPUT_LOW, { _( "Input low" ), BITMAPS::pinshape_active_low_input } },
|
||||
{ GRAPHIC_PINSHAPE::CLOCK_LOW, { _( "Clock low" ), BITMAPS::pinshape_clock_active_low } },
|
||||
{ GRAPHIC_PINSHAPE::OUTPUT_LOW, { _( "Output low" ), BITMAPS::pinshape_active_low_output } },
|
||||
{ GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK, { _( "Falling edge clock" ), BITMAPS::pinshape_clock_fall } },
|
||||
{ GRAPHIC_PINSHAPE::NONLOGIC, { _( "NonLogic" ), BITMAPS::pinshape_nonlogic } },
|
||||
};
|
||||
// clang-format on
|
||||
static std::map<ELECTRICAL_PINTYPE, struct pinTypeStruct> g_pinElectricalTypes;
|
||||
static std::map<GRAPHIC_PINSHAPE, struct pinShapeStruct> g_pinShapes;
|
||||
static std::map<PIN_ORIENTATION, struct pinShapeStruct> g_pinOrientations;
|
||||
|
||||
|
||||
// clang-format off
|
||||
std::map<PIN_ORIENTATION, struct pinShapeStruct> pinOrientations = {
|
||||
{ PIN_ORIENTATION::PIN_RIGHT, { _( "Right" ), BITMAPS::pinorient_right } },
|
||||
{ PIN_ORIENTATION::PIN_LEFT, { _( "Left" ), BITMAPS::pinorient_left } },
|
||||
{ PIN_ORIENTATION::PIN_UP, { _( "Up" ), BITMAPS::pinorient_up } },
|
||||
{ PIN_ORIENTATION::PIN_DOWN, { _( "Down" ), BITMAPS::pinorient_down } },
|
||||
};
|
||||
// clang-format on
|
||||
static int g_language = wxLANGUAGE_UNKNOWN;
|
||||
|
||||
|
||||
PIN_ORIENTATION PinOrientationCode( size_t index )
|
||||
@@ -119,18 +80,65 @@ int PinOrientationIndex( PIN_ORIENTATION code )
|
||||
|
||||
void InitTables()
|
||||
{
|
||||
// clang-format off
|
||||
g_pinElectricalTypes = {
|
||||
{ ELECTRICAL_PINTYPE::PT_INPUT, { _( "Input" ), BITMAPS::pintype_input } },
|
||||
{ ELECTRICAL_PINTYPE::PT_OUTPUT, { _( "Output" ), BITMAPS::pintype_output } },
|
||||
{ ELECTRICAL_PINTYPE::PT_BIDI, { _( "Bidirectional" ), BITMAPS::pintype_bidi } },
|
||||
{ ELECTRICAL_PINTYPE::PT_TRISTATE, { _( "Tri-state" ), BITMAPS::pintype_3states } },
|
||||
{ ELECTRICAL_PINTYPE::PT_PASSIVE, { _( "Passive" ), BITMAPS::pintype_passive } },
|
||||
{ ELECTRICAL_PINTYPE::PT_NIC, { _( "Free" ), BITMAPS::pintype_nic } },
|
||||
{ ELECTRICAL_PINTYPE::PT_UNSPECIFIED, { _( "Unspecified" ), BITMAPS::pintype_notspecif } },
|
||||
{ ELECTRICAL_PINTYPE::PT_POWER_IN, { _( "Power input" ), BITMAPS::pintype_powerinput } },
|
||||
{ ELECTRICAL_PINTYPE::PT_POWER_OUT, { _( "Power output" ), BITMAPS::pintype_poweroutput } },
|
||||
{ ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR, { _( "Open collector" ), BITMAPS::pintype_opencoll } },
|
||||
{ ELECTRICAL_PINTYPE::PT_OPENEMITTER, { _( "Open emitter" ), BITMAPS::pintype_openemit } },
|
||||
{ ELECTRICAL_PINTYPE::PT_NC, { _( "Unconnected" ), BITMAPS::pintype_noconnect } },
|
||||
};
|
||||
|
||||
g_pinShapes = {
|
||||
{ GRAPHIC_PINSHAPE::LINE, { _( "Line" ), BITMAPS::pinshape_normal } },
|
||||
{ GRAPHIC_PINSHAPE::INVERTED, { _( "Inverted" ), BITMAPS::pinshape_invert } },
|
||||
{ GRAPHIC_PINSHAPE::CLOCK, { _( "Clock" ), BITMAPS::pinshape_clock_normal } },
|
||||
{ GRAPHIC_PINSHAPE::INVERTED_CLOCK, { _( "Inverted clock" ), BITMAPS::pinshape_clock_invert } },
|
||||
{ GRAPHIC_PINSHAPE::INPUT_LOW, { _( "Input low" ), BITMAPS::pinshape_active_low_input } },
|
||||
{ GRAPHIC_PINSHAPE::CLOCK_LOW, { _( "Clock low" ), BITMAPS::pinshape_clock_active_low } },
|
||||
{ GRAPHIC_PINSHAPE::OUTPUT_LOW, { _( "Output low" ), BITMAPS::pinshape_active_low_output } },
|
||||
{ GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK, { _( "Falling edge clock" ), BITMAPS::pinshape_clock_fall } },
|
||||
{ GRAPHIC_PINSHAPE::NONLOGIC, { _( "NonLogic" ), BITMAPS::pinshape_nonlogic } },
|
||||
};
|
||||
|
||||
g_pinOrientations = {
|
||||
{ PIN_ORIENTATION::PIN_RIGHT, { _( "Right" ), BITMAPS::pinorient_right } },
|
||||
{ PIN_ORIENTATION::PIN_LEFT, { _( "Left" ), BITMAPS::pinorient_left } },
|
||||
{ PIN_ORIENTATION::PIN_UP, { _( "Up" ), BITMAPS::pinorient_up } },
|
||||
{ PIN_ORIENTATION::PIN_DOWN, { _( "Down" ), BITMAPS::pinorient_down } },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
g_language = Pgm().GetSelectedLanguageIdentifier();
|
||||
|
||||
g_typeIcons.clear();
|
||||
g_typeNames.clear();
|
||||
|
||||
for( unsigned i = 0; i < ELECTRICAL_PINTYPES_TOTAL; ++i )
|
||||
{
|
||||
g_typeIcons.push_back( ElectricalPinTypeGetBitmap( static_cast<ELECTRICAL_PINTYPE>( i ) ) );
|
||||
g_typeNames.push_back( ElectricalPinTypeGetText( static_cast<ELECTRICAL_PINTYPE>( i ) ) );
|
||||
}
|
||||
|
||||
g_shapeIcons.clear();
|
||||
g_shapeNames.clear();
|
||||
|
||||
for( unsigned i = 0; i < GRAPHIC_PINSHAPES_TOTAL; ++i )
|
||||
{
|
||||
g_shapeIcons.push_back( PinShapeGetBitmap( static_cast<GRAPHIC_PINSHAPE>( i ) ) );
|
||||
g_shapeNames.push_back( PinShapeGetText( static_cast<GRAPHIC_PINSHAPE>( i ) ) );
|
||||
}
|
||||
|
||||
g_orientationIcons.clear();
|
||||
g_orientationNames.clear();
|
||||
|
||||
for( PIN_ORIENTATION orientation : magic_enum::enum_values<PIN_ORIENTATION>() )
|
||||
{
|
||||
g_orientationIcons.push_back( PinOrientationGetBitmap( orientation ) );
|
||||
@@ -141,7 +149,7 @@ void InitTables()
|
||||
|
||||
const wxArrayString& PinTypeNames()
|
||||
{
|
||||
if( g_typeNames.empty() )
|
||||
if( g_typeNames.empty() || g_language != Pgm().GetSelectedLanguageIdentifier() )
|
||||
InitTables();
|
||||
|
||||
return g_typeNames;
|
||||
@@ -159,7 +167,7 @@ const std::vector<BITMAPS>& PinTypeIcons()
|
||||
|
||||
const wxArrayString& PinShapeNames()
|
||||
{
|
||||
if( g_shapeNames.empty() )
|
||||
if( g_shapeNames.empty() || g_language != Pgm().GetSelectedLanguageIdentifier() )
|
||||
InitTables();
|
||||
|
||||
return g_shapeNames;
|
||||
@@ -177,7 +185,7 @@ const std::vector<BITMAPS>& PinShapeIcons()
|
||||
|
||||
const wxArrayString& PinOrientationNames()
|
||||
{
|
||||
if( g_orientationNames.empty() )
|
||||
if( g_orientationNames.empty() || g_language != Pgm().GetSelectedLanguageIdentifier() )
|
||||
InitTables();
|
||||
|
||||
return g_orientationNames;
|
||||
@@ -195,78 +203,77 @@ const std::vector<BITMAPS>& PinOrientationIcons()
|
||||
|
||||
wxString ElectricalPinTypeGetText( ELECTRICAL_PINTYPE aType )
|
||||
{
|
||||
if( g_pinTypesLanguage != Pgm().GetSelectedLanguageIdentifier() )
|
||||
{
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_INPUT].name = _( "Input" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_OUTPUT].name = _( "Output" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_BIDI].name = _( "Bidirectional" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_TRISTATE].name = _( "Tri-state" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_PASSIVE].name = _( "Passive" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_NIC].name = _( "Free" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_UNSPECIFIED].name = _( "Unspecified" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_POWER_IN].name = _( "Power input" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_POWER_OUT].name = _( "Power output" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR].name = _( "Open collector" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_OPENEMITTER].name = _( "Open emitter" );
|
||||
g_pinTypes[ELECTRICAL_PINTYPE::PT_NC].name = _( "Unconnected" );
|
||||
if( g_pinElectricalTypes.empty() || g_language != Pgm().GetSelectedLanguageIdentifier() )
|
||||
InitTables();
|
||||
|
||||
g_pinTypesLanguage = Pgm().GetSelectedLanguageIdentifier();
|
||||
}
|
||||
auto it = g_pinElectricalTypes.find( aType );
|
||||
|
||||
auto findIt = g_pinTypes.find( aType );
|
||||
wxCHECK_MSG( it != g_pinElectricalTypes.end(), wxT( "???" ), wxT( "Pin type not found!" ) );
|
||||
|
||||
wxCHECK_MSG( findIt != g_pinTypes.end(), wxT( "???" ), wxT( "Pin type not found!" ) );
|
||||
|
||||
return findIt->second.name;
|
||||
return it->second.name;
|
||||
}
|
||||
|
||||
|
||||
BITMAPS ElectricalPinTypeGetBitmap( ELECTRICAL_PINTYPE aType )
|
||||
{
|
||||
auto findIt = g_pinTypes.find( aType );
|
||||
if( g_pinElectricalTypes.empty() )
|
||||
InitTables();
|
||||
|
||||
wxCHECK_MSG( findIt != g_pinTypes.end(), BITMAPS::INVALID_BITMAP, wxT( "Pin type not found!" ) );
|
||||
auto it = g_pinElectricalTypes.find( aType );
|
||||
|
||||
return findIt->second.bitmap;
|
||||
wxCHECK_MSG( it != g_pinElectricalTypes.end(), BITMAPS::INVALID_BITMAP, wxT( "Pin type not found!" ) );
|
||||
|
||||
return it->second.bitmap;
|
||||
}
|
||||
|
||||
|
||||
wxString PinShapeGetText( GRAPHIC_PINSHAPE aShape )
|
||||
{
|
||||
auto findIt = pinShapes.find( aShape );
|
||||
if( g_pinShapes.empty() || g_language != Pgm().GetSelectedLanguageIdentifier() )
|
||||
InitTables();
|
||||
|
||||
wxCHECK_MSG( findIt != pinShapes.end(), wxT( "?" ), wxT( "Pin type not found!" ) );
|
||||
auto it = g_pinShapes.find( aShape );
|
||||
|
||||
return findIt->second.name;
|
||||
wxCHECK_MSG( it != g_pinShapes.end(), wxT( "?" ), wxT( "Pin type not found!" ) );
|
||||
|
||||
return it->second.name;
|
||||
}
|
||||
|
||||
|
||||
BITMAPS PinShapeGetBitmap( GRAPHIC_PINSHAPE aShape )
|
||||
{
|
||||
auto findIt = pinShapes.find( aShape );
|
||||
if( g_pinShapes.empty() )
|
||||
InitTables();
|
||||
|
||||
wxCHECK_MSG( findIt != pinShapes.end(), BITMAPS::INVALID_BITMAP, wxT( "Pin type not found!" ) );
|
||||
auto it = g_pinShapes.find( aShape );
|
||||
|
||||
return findIt->second.bitmap;
|
||||
wxCHECK_MSG( it != g_pinShapes.end(), BITMAPS::INVALID_BITMAP, wxT( "Pin type not found!" ) );
|
||||
|
||||
return it->second.bitmap;
|
||||
}
|
||||
|
||||
|
||||
wxString PinOrientationName( PIN_ORIENTATION aOrientation )
|
||||
{
|
||||
auto findIt = pinOrientations.find( aOrientation );
|
||||
if( g_pinOrientations.empty() || g_language != Pgm().GetSelectedLanguageIdentifier() )
|
||||
InitTables();
|
||||
|
||||
wxCHECK_MSG( findIt != pinOrientations.end(), wxT( "?" ), wxT( "Pin orientation not found!" ) );
|
||||
auto it = g_pinOrientations.find( aOrientation );
|
||||
|
||||
return findIt->second.name;
|
||||
wxCHECK_MSG( it != g_pinOrientations.end(), wxT( "?" ), wxT( "Pin orientation not found!" ) );
|
||||
|
||||
return it->second.name;
|
||||
}
|
||||
|
||||
|
||||
BITMAPS PinOrientationGetBitmap( PIN_ORIENTATION aOrientation )
|
||||
{
|
||||
auto findIt = pinOrientations.find( aOrientation );
|
||||
if( g_pinOrientations.empty() )
|
||||
InitTables();
|
||||
|
||||
wxCHECK_MSG( findIt != pinOrientations.end(), BITMAPS::INVALID_BITMAP,
|
||||
wxT( "Pin orientation not found!" ) );
|
||||
auto it = g_pinOrientations.find( aOrientation );
|
||||
|
||||
return findIt->second.bitmap;
|
||||
wxCHECK_MSG( it != g_pinOrientations.end(), BITMAPS::INVALID_BITMAP, wxT( "Pin orientation not found!" ) );
|
||||
|
||||
return it->second.bitmap;
|
||||
}
|
||||
|
||||
+12
-1
@@ -209,9 +209,20 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
|
||||
schematic = schItem->Schematic();
|
||||
|
||||
if( schItem->IsSelected() )
|
||||
{
|
||||
selectedModified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
schItem->RunOnChildren(
|
||||
[&selectedModified]( SCH_ITEM* aChild )
|
||||
{
|
||||
if( aChild->IsSelected() )
|
||||
selectedModified = true;
|
||||
} );
|
||||
}
|
||||
|
||||
auto updateConnectivityFlag = [&, this]()
|
||||
auto updateConnectivityFlag = [&]()
|
||||
{
|
||||
if( schItem->IsConnectable() )
|
||||
{
|
||||
|
||||
+12
-10
@@ -404,6 +404,11 @@ SCH_EDIT_FRAME::~SCH_EDIT_FRAME()
|
||||
if( m_schematic )
|
||||
m_schematic->RemoveAllListeners();
|
||||
|
||||
// Delete all items not in draw list before deleting schematic
|
||||
// to avoid dangling pointers stored in these items
|
||||
ClearUndoRedoList();
|
||||
ClearRepeatItemsList();
|
||||
|
||||
delete m_schematic;
|
||||
m_schematic = nullptr;
|
||||
|
||||
@@ -774,7 +779,7 @@ void SCH_EDIT_FRAME::AddCopyForRepeatItem( const SCH_ITEM* aItem )
|
||||
|
||||
EDA_ITEM* SCH_EDIT_FRAME::GetItem( const KIID& aId ) const
|
||||
{
|
||||
return Schematic().GetSheets().GetItem( aId );
|
||||
return Schematic().GetItem( aId );
|
||||
}
|
||||
|
||||
|
||||
@@ -894,7 +899,7 @@ bool SCH_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
|
||||
|
||||
// Shutdown blocks must be determined and vetoed as early as possible
|
||||
if( KIPLATFORM::APP::SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION
|
||||
&& Schematic().GetSheets().IsModified() )
|
||||
&& IsContentModified() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -942,9 +947,7 @@ bool SCH_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
|
||||
if( !Schematic().IsValid() )
|
||||
return false;
|
||||
|
||||
SCH_SHEET_LIST sheetlist = Schematic().GetSheets();
|
||||
|
||||
if( sheetlist.IsModified() )
|
||||
if( IsContentModified() )
|
||||
{
|
||||
wxFileName fileName = Schematic().RootScreen()->GetFileName();
|
||||
wxString msg = _( "Save changes to '%s' before closing?" );
|
||||
@@ -965,7 +968,7 @@ bool SCH_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
|
||||
|
||||
void SCH_EDIT_FRAME::doCloseWindow()
|
||||
{
|
||||
SCH_SHEET_LIST sheetlist = Schematic().GetSheets();
|
||||
SCH_SHEET_LIST sheetlist = Schematic().GetUnorderedSheets();
|
||||
|
||||
// Shutdown all running tools
|
||||
if( m_toolManager )
|
||||
@@ -1057,7 +1060,7 @@ void SCH_EDIT_FRAME::doCloseWindow()
|
||||
// Make sure local settings are persisted
|
||||
SaveProjectLocalSettings();
|
||||
|
||||
Schematic().RootScreen()->Clear();
|
||||
Schematic().RootScreen()->Clear( true );
|
||||
|
||||
// all sub sheets are deleted, only the main sheet is usable
|
||||
GetCurrentSheet().clear();
|
||||
@@ -2037,7 +2040,7 @@ const BOX2I SCH_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const
|
||||
|
||||
bool SCH_EDIT_FRAME::IsContentModified() const
|
||||
{
|
||||
return Schematic().GetSheets().IsModified();
|
||||
return Schematic().GetUnorderedSheets().IsModified();
|
||||
}
|
||||
|
||||
|
||||
@@ -2052,9 +2055,8 @@ void SCH_EDIT_FRAME::FocusOnItem( SCH_ITEM* aItem )
|
||||
{
|
||||
static KIID lastBrightenedItemID( niluuid );
|
||||
|
||||
SCH_SHEET_LIST sheetList = Schematic().GetSheets();
|
||||
SCH_SHEET_PATH dummy;
|
||||
SCH_ITEM* lastItem = sheetList.GetItem( lastBrightenedItemID, &dummy );
|
||||
SCH_ITEM* lastItem = Schematic().GetItem( lastBrightenedItemID, &dummy );
|
||||
|
||||
if( lastItem && lastItem != aItem )
|
||||
{
|
||||
|
||||
@@ -545,7 +545,7 @@ public:
|
||||
* @param aSchematicFileName is the absolute path and file name of the file to test.
|
||||
* @return true if the user accepts the potential file name clash risk.
|
||||
*/
|
||||
bool AllowCaseSensitiveFileNameClashes( const wxString& aSchematicFileName );
|
||||
bool AllowCaseSensitiveFileNameClashes( const wxString& aOldName, const wxString& aSchematicFileName );
|
||||
|
||||
/**
|
||||
* Edit an existing sheet or add a new sheet to the schematic.
|
||||
@@ -710,6 +710,15 @@ public:
|
||||
return m_items_to_repeat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the list of items which are to be repeated with the insert key.
|
||||
* These objects are owned by this container.
|
||||
*/
|
||||
void ClearRepeatItemsList()
|
||||
{
|
||||
m_items_to_repeat.clear();
|
||||
}
|
||||
|
||||
EDA_ITEM* GetItem( const KIID& aId ) const override;
|
||||
|
||||
/**
|
||||
@@ -866,7 +875,8 @@ public:
|
||||
void RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelection = nullptr );
|
||||
|
||||
void MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemId aParentId,
|
||||
const NET_NAVIGATOR_ITEM_DATA* aSelection = nullptr );
|
||||
const NET_NAVIGATOR_ITEM_DATA* aSelection,
|
||||
bool aSingleSheetSchematic );
|
||||
|
||||
void SelectNetNavigatorItem( const NET_NAVIGATOR_ITEM_DATA* aSelection = nullptr );
|
||||
|
||||
|
||||
+36
-5
@@ -195,15 +195,30 @@ wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraT
|
||||
return symbol->ResolveTextVar( aPath, token, aDepth + 1 );
|
||||
};
|
||||
|
||||
std::function<bool( wxString* )> schematicResolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
if( SCHEMATIC* schematic = Schematic() )
|
||||
return schematic->ResolveTextVar( aPath, token, aDepth + 1 );
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
std::function<bool( wxString* )> sheetResolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
|
||||
|
||||
SCHEMATIC* schematic = Schematic();
|
||||
SCH_SHEET_PATH path = *aPath;
|
||||
path.push_back( sheet );
|
||||
|
||||
return sheet->ResolveTextVar( &path, token, aDepth + 1 );
|
||||
bool retval = sheet->ResolveTextVar( &path, token, aDepth + 1 );
|
||||
|
||||
if( schematic )
|
||||
retval |= schematic->ResolveTextVar( &path, token, aDepth + 1 );
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
std::function<bool( wxString* )> labelResolver =
|
||||
@@ -222,7 +237,8 @@ wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraT
|
||||
{
|
||||
text = wxS( "" );
|
||||
}
|
||||
else if( HasTextVars() )
|
||||
|
||||
for( int ii = 0; ii < 10 && text.Contains( wxT( "${" ) ); ++ii )
|
||||
{
|
||||
if( aDepth < 10 )
|
||||
{
|
||||
@@ -233,7 +249,10 @@ wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraT
|
||||
else if( m_parent && m_parent->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
|
||||
text = ExpandTextVars( text, &labelResolver );
|
||||
else if( Schematic() )
|
||||
{
|
||||
text = ExpandTextVars( text, &Schematic()->Prj() );
|
||||
text = ExpandTextVars( text, &schematicResolver );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -740,11 +759,10 @@ void SCH_FIELD::OnScintillaCharAdded( SCINTILLA_TRICKS* aScintillaTricks,
|
||||
}
|
||||
else
|
||||
{
|
||||
SCH_SHEET_LIST sheets = schematic->GetSheets();
|
||||
SCH_REFERENCE_LIST refs;
|
||||
SCH_SYMBOL* refSymbol = nullptr;
|
||||
|
||||
sheets.GetSymbols( refs );
|
||||
schematic->GetUnorderedSheets().GetSymbols( refs );
|
||||
|
||||
for( size_t jj = 0; jj < refs.GetCount(); jj++ )
|
||||
{
|
||||
@@ -998,7 +1016,11 @@ void SCH_FIELD::SetText( const wxString& aText )
|
||||
if( m_isNamedVariable )
|
||||
return;
|
||||
|
||||
EDA_TEXT::SetText( aText );
|
||||
// Mandatory fields should not have leading or trailing whitespace.
|
||||
if( IsMandatory() )
|
||||
EDA_TEXT::SetText( aText.Strip( wxString::both ) );
|
||||
else
|
||||
EDA_TEXT::SetText( aText );
|
||||
}
|
||||
|
||||
|
||||
@@ -1291,6 +1313,15 @@ VECTOR2I SCH_FIELD::GetParentPosition() const
|
||||
}
|
||||
|
||||
|
||||
bool SCH_FIELD::IsMandatory() const
|
||||
{
|
||||
if( m_parent && m_parent->Type() == SCH_SHEET_T )
|
||||
return m_id >= 0 && m_id < SHEET_MANDATORY_FIELDS;
|
||||
else
|
||||
return m_id >= 0 && m_id < MANDATORY_FIELDS;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_FIELD::operator <( const SCH_ITEM& aItem ) const
|
||||
{
|
||||
if( Type() != aItem.Type() )
|
||||
|
||||
@@ -209,6 +209,8 @@ public:
|
||||
*/
|
||||
void ImportValues( const LIB_FIELD& aSource );
|
||||
|
||||
bool IsMandatory() const;
|
||||
|
||||
int GetPenWidth() const override;
|
||||
|
||||
void ClearCaches() override;
|
||||
|
||||
@@ -460,7 +460,8 @@ ASCH_ROUND_RECTANGLE::ASCH_ROUND_RECTANGLE( const std::map<wxString, wxString>&
|
||||
|
||||
ASCH_ARC::ASCH_ARC( const std::map<wxString, wxString>& aProps ) :
|
||||
ASCH_OWNER_INTERFACE( aProps ),
|
||||
ASCH_BORDER_INTERFACE( aProps )
|
||||
ASCH_BORDER_INTERFACE( aProps ),
|
||||
ASCH_FILL_INTERFACE( aProps )
|
||||
{
|
||||
m_IsElliptical = ReadRecord( aProps ) == ALTIUM_SCH_RECORD::ELLIPTICAL_ARC;
|
||||
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::ARC || m_IsElliptical );
|
||||
@@ -478,6 +479,11 @@ ASCH_ARC::ASCH_ARC( const std::map<wxString, wxString>& aProps ) :
|
||||
}
|
||||
|
||||
|
||||
ASCH_PIECHART::ASCH_PIECHART( const std::map<wxString, wxString>& aProps ) :
|
||||
ASCH_ARC( aProps )
|
||||
{}
|
||||
|
||||
|
||||
ASCH_ELLIPSE::ASCH_ELLIPSE( const std::map<wxString, wxString>& aProps ) :
|
||||
ASCH_OWNER_INTERFACE( aProps ),
|
||||
ASCH_FILL_INTERFACE( aProps ),
|
||||
|
||||
@@ -482,7 +482,7 @@ struct ASCH_ROUND_RECTANGLE : ASCH_OWNER_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BO
|
||||
};
|
||||
|
||||
|
||||
struct ASCH_ARC : ASCH_OWNER_INTERFACE, ASCH_BORDER_INTERFACE
|
||||
struct ASCH_ARC : ASCH_OWNER_INTERFACE, ASCH_BORDER_INTERFACE, ASCH_FILL_INTERFACE
|
||||
{
|
||||
bool m_IsElliptical;
|
||||
VECTOR2I m_Center;
|
||||
@@ -495,6 +495,12 @@ struct ASCH_ARC : ASCH_OWNER_INTERFACE, ASCH_BORDER_INTERFACE
|
||||
};
|
||||
|
||||
|
||||
struct ASCH_PIECHART : ASCH_ARC
|
||||
{
|
||||
explicit ASCH_PIECHART( const std::map<wxString, wxString>& aProps );
|
||||
};
|
||||
|
||||
|
||||
struct ASCH_ELLIPSE : ASCH_OWNER_INTERFACE, ASCH_FILL_INTERFACE, ASCH_BORDER_INTERFACE
|
||||
{
|
||||
VECTOR2I Center;
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
|
||||
#include <bezier_curves.h>
|
||||
#include <compoundfilereader.h>
|
||||
#include <font/fontconfig.h>
|
||||
#include <geometry/ellipse.h>
|
||||
#include <string_utils.h>
|
||||
#include <sch_edit_frame.h>
|
||||
@@ -325,6 +326,9 @@ SCH_SHEET* SCH_IO_ALTIUM::LoadSchematicFile( const wxString& aFileName, SCHEMATI
|
||||
fileName.SetExt( FILEEXT::KiCadSchematicFileExtension );
|
||||
m_schematic = aSchematic;
|
||||
|
||||
// Show the font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( &WXLOG_REPORTER::GetInstance() );
|
||||
|
||||
// Delete on exception, if I own m_rootSheet, according to aAppendToMe
|
||||
std::unique_ptr<SCH_SHEET> deleter( aAppendToMe ? nullptr : m_rootSheet );
|
||||
|
||||
@@ -892,9 +896,9 @@ void SCH_IO_ALTIUM::ParseRecord( int index, std::map<wxString, wxString>& proper
|
||||
ParseEllipse( properties );
|
||||
break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::PIECHART:
|
||||
m_reporter->Report( _( "Record 'PIECHART' not handled." ), RPT_SEVERITY_INFO );
|
||||
break;
|
||||
case ALTIUM_SCH_RECORD::PIECHART:
|
||||
ParsePieChart( properties );
|
||||
break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::ROUND_RECTANGLE:
|
||||
ParseRoundRectangle( properties );
|
||||
@@ -2152,7 +2156,9 @@ void SCH_IO_ALTIUM::ParseArc( const std::map<wxString, wxString>& aProperties,
|
||||
|
||||
circle->SetPosition( elem.m_Center + m_sheetOffset );
|
||||
circle->SetEnd( circle->GetPosition() + VECTOR2I( arc_radius, 0 ) );
|
||||
circle->SetStroke( STROKE_PARAMS( elem.LineWidth, LINE_STYLE::SOLID ) );
|
||||
|
||||
SetSchShapeLine( elem, circle );
|
||||
SetSchShapeFillAndColor( elem, circle );
|
||||
|
||||
currentScreen->Append( circle );
|
||||
}
|
||||
@@ -2168,7 +2174,8 @@ void SCH_IO_ALTIUM::ParseArc( const std::map<wxString, wxString>& aProperties,
|
||||
arc->SetStart( elem.m_Center + startOffset + m_sheetOffset );
|
||||
arc->SetArcAngleAndEnd( includedAngle.Normalize(), true );
|
||||
|
||||
arc->SetStroke( STROKE_PARAMS( elem.LineWidth, LINE_STYLE::SOLID ) );
|
||||
SetSchShapeLine( elem, arc );
|
||||
SetSchShapeFillAndColor( elem, arc );
|
||||
|
||||
currentScreen->Append( arc );
|
||||
}
|
||||
@@ -2214,6 +2221,7 @@ void SCH_IO_ALTIUM::ParseArc( const std::map<wxString, wxString>& aProperties,
|
||||
|
||||
circle->SetEnd( circle->GetPosition() + VECTOR2I( arc_radius, 0 ) );
|
||||
SetLibShapeLine( elem, circle, ALTIUM_SCH_RECORD::ARC );
|
||||
SetLibShapeFillAndColor( elem, circle, ALTIUM_SCH_RECORD::ARC, elem.Color );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2241,6 +2249,7 @@ void SCH_IO_ALTIUM::ParseArc( const std::map<wxString, wxString>& aProperties,
|
||||
arc->SetArcAngleAndEnd( includedAngle.Normalize(), true );
|
||||
|
||||
SetLibShapeLine( elem, arc, ALTIUM_SCH_RECORD::ARC );
|
||||
SetLibShapeFillAndColor( elem, arc, ALTIUM_SCH_RECORD::ARC, elem.Color );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2341,6 +2350,92 @@ void SCH_IO_ALTIUM::ParseEllipticalArc( const std::map<wxString, wxString>& aPro
|
||||
}
|
||||
|
||||
|
||||
void SCH_IO_ALTIUM::ParsePieChart( const std::map<wxString, wxString>& aProperties,
|
||||
std::vector<LIB_SYMBOL*>& aSymbol )
|
||||
{
|
||||
ParseArc( aProperties, aSymbol );
|
||||
|
||||
ASCH_PIECHART elem( aProperties );
|
||||
|
||||
int arc_radius = elem.m_Radius;
|
||||
VECTOR2I center = elem.m_Center;
|
||||
EDA_ANGLE startAngle( elem.m_EndAngle, DEGREES_T );
|
||||
EDA_ANGLE endAngle( elem.m_StartAngle, DEGREES_T );
|
||||
VECTOR2I startOffset( KiROUND( arc_radius * startAngle.Cos() ),
|
||||
-KiROUND( arc_radius * startAngle.Sin() ) );
|
||||
VECTOR2I endOffset( KiROUND( arc_radius * endAngle.Cos() ),
|
||||
-KiROUND( arc_radius * endAngle.Sin() ) );
|
||||
|
||||
if( aSymbol.empty() && ShouldPutItemOnSheet( elem.ownerindex ) )
|
||||
{
|
||||
SCH_SCREEN* screen = getCurrentScreen();
|
||||
wxCHECK( screen, /* void */ );
|
||||
|
||||
// close polygon
|
||||
SCH_LINE* line = new SCH_LINE( center + m_sheetOffset, SCH_LAYER_ID::LAYER_NOTES );
|
||||
line->SetEndPoint( center + startOffset + m_sheetOffset );
|
||||
line->SetStroke( STROKE_PARAMS( elem.LineWidth, LINE_STYLE::SOLID ) );
|
||||
|
||||
line->SetFlags( IS_NEW );
|
||||
screen->Append( line );
|
||||
|
||||
line = new SCH_LINE( center + m_sheetOffset, SCH_LAYER_ID::LAYER_NOTES );
|
||||
line->SetEndPoint( center + endOffset + m_sheetOffset );
|
||||
line->SetStroke( STROKE_PARAMS( elem.LineWidth, LINE_STYLE::SOLID ) );
|
||||
|
||||
line->SetFlags( IS_NEW );
|
||||
screen->Append( line );
|
||||
}
|
||||
else
|
||||
{
|
||||
LIB_SYMBOL* symbol = (int) aSymbol.size() <= elem.ownerpartdisplaymode
|
||||
? nullptr
|
||||
: aSymbol[elem.ownerpartdisplaymode];
|
||||
SCH_SYMBOL* schsym = nullptr;
|
||||
|
||||
if( !symbol )
|
||||
{
|
||||
const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex );
|
||||
|
||||
if( libSymbolIt == m_libSymbols.end() )
|
||||
{
|
||||
// TODO: e.g. can depend on Template (RECORD=39
|
||||
m_reporter->Report( wxString::Format( wxT( "Piechart's owner (%d) not found." ),
|
||||
elem.ownerindex ),
|
||||
RPT_SEVERITY_DEBUG );
|
||||
return;
|
||||
}
|
||||
|
||||
symbol = libSymbolIt->second;
|
||||
schsym = m_symbols.at( libSymbolIt->first );
|
||||
}
|
||||
|
||||
if( aSymbol.empty() && !IsComponentPartVisible( elem ) )
|
||||
return;
|
||||
|
||||
LIB_SHAPE* line = new LIB_SHAPE( symbol, SHAPE_T::POLY );
|
||||
symbol->AddDrawItem( line, false );
|
||||
|
||||
line->SetUnit( std::max( 0, elem.ownerpartid ) );
|
||||
|
||||
if( !schsym )
|
||||
{
|
||||
line->AddPoint( center + startOffset );
|
||||
line->AddPoint( center );
|
||||
line->AddPoint( center + endOffset );
|
||||
}
|
||||
else
|
||||
{
|
||||
line->AddPoint( GetRelativePosition( center + startOffset + m_sheetOffset, schsym ) );
|
||||
line->AddPoint( GetRelativePosition( center + m_sheetOffset, schsym ) );
|
||||
line->AddPoint( GetRelativePosition( center + endOffset + m_sheetOffset, schsym ) );
|
||||
}
|
||||
|
||||
SetLibShapeLine( elem, line, ALTIUM_SCH_RECORD::LINE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_IO_ALTIUM::ParseEllipse( const std::map<wxString, wxString>& aProperties,
|
||||
std::vector<LIB_SYMBOL*>& aSymbol )
|
||||
{
|
||||
@@ -3193,8 +3288,8 @@ void SCH_IO_ALTIUM::ParsePowerPort( const std::map<wxString, wxString>& aPropert
|
||||
{
|
||||
libSymbol = powerSymbolIt->second; // cache hit
|
||||
}
|
||||
else if( LIB_SYMBOL* alreadyLoaded =
|
||||
m_pi->LoadSymbol( getLibFileName().GetFullPath(), elem.text, m_properties.get() ) )
|
||||
else if( LIB_SYMBOL* alreadyLoaded = m_pi->LoadSymbol( getLibFileName().GetFullPath(), symName,
|
||||
m_properties.get() ) )
|
||||
{
|
||||
libSymbol = alreadyLoaded;
|
||||
}
|
||||
@@ -4210,6 +4305,8 @@ std::map<wxString,LIB_SYMBOL*> SCH_IO_ALTIUM::ParseLibFile( const ALTIUM_COMPOUN
|
||||
|
||||
case ALTIUM_SCH_RECORD::ELLIPSE: ParseEllipse( properties, symbols ); break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::PIECHART: ParsePieChart( properties, symbols ); break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::ROUND_RECTANGLE: ParseRoundRectangle( properties, symbols ); break;
|
||||
|
||||
case ALTIUM_SCH_RECORD::ELLIPTICAL_ARC: ParseEllipticalArc( properties, symbols ); break;
|
||||
@@ -4292,6 +4389,9 @@ long long SCH_IO_ALTIUM::getLibraryTimestamp( const wxString& aLibraryPath ) con
|
||||
void SCH_IO_ALTIUM::ensureLoadedLibrary( const wxString& aLibraryPath,
|
||||
const STRING_UTF8_MAP* aProperties )
|
||||
{
|
||||
// Suppress font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( nullptr );
|
||||
|
||||
if( m_libCache.count( aLibraryPath ) )
|
||||
{
|
||||
wxCHECK( m_timestamps.count( aLibraryPath ), /*void*/ );
|
||||
@@ -4396,20 +4496,40 @@ void SCH_IO_ALTIUM::ParseLibHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile,
|
||||
}
|
||||
|
||||
|
||||
void SCH_IO_ALTIUM::EnumerateSymbolLib( wxArrayString& aSymbolNameList,
|
||||
const wxString& aLibraryPath,
|
||||
const STRING_UTF8_MAP* aProperties )
|
||||
void SCH_IO_ALTIUM::doEnumerateSymbolLib( const wxString& aLibraryPath,
|
||||
const STRING_UTF8_MAP* aProperties,
|
||||
std::function<void(const wxString&, LIB_SYMBOL*)> aInserter )
|
||||
{
|
||||
ensureLoadedLibrary( aLibraryPath, aProperties );
|
||||
|
||||
bool powerSymbolsOnly = ( aProperties &&
|
||||
aProperties->find( SYMBOL_LIB_TABLE::PropPowerSymsOnly )
|
||||
!= aProperties->end() );
|
||||
|
||||
auto it = m_libCache.find( aLibraryPath );
|
||||
|
||||
if( it != m_libCache.end() )
|
||||
{
|
||||
for( auto& [libnameStr, libSymbol] : it->second )
|
||||
aSymbolNameList.Add( libnameStr );
|
||||
}
|
||||
{
|
||||
if( powerSymbolsOnly && !libSymbol->IsPower() )
|
||||
continue;
|
||||
|
||||
aInserter( libnameStr, libSymbol );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_IO_ALTIUM::EnumerateSymbolLib( wxArrayString& aSymbolNameList,
|
||||
const wxString& aLibraryPath,
|
||||
const STRING_UTF8_MAP* aProperties )
|
||||
{
|
||||
doEnumerateSymbolLib( aLibraryPath, aProperties,
|
||||
[&]( const wxString& aStr, LIB_SYMBOL* )
|
||||
{
|
||||
aSymbolNameList.Add( aStr );
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
@@ -4417,17 +4537,14 @@ void SCH_IO_ALTIUM::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
|
||||
const wxString& aLibraryPath,
|
||||
const STRING_UTF8_MAP* aProperties )
|
||||
{
|
||||
ensureLoadedLibrary( aLibraryPath, aProperties );
|
||||
|
||||
auto it = m_libCache.find( aLibraryPath );
|
||||
|
||||
if( it != m_libCache.end() )
|
||||
{
|
||||
for( auto& [libnameStr, libSymbol] : it->second )
|
||||
aSymbolList.push_back( libSymbol );
|
||||
}
|
||||
doEnumerateSymbolLib( aLibraryPath, aProperties,
|
||||
[&]( const wxString&, LIB_SYMBOL* aSymbol )
|
||||
{
|
||||
aSymbolList.emplace_back( aSymbol );
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
LIB_SYMBOL* SCH_IO_ALTIUM::LoadSymbol( const wxString& aLibraryPath,
|
||||
const wxString& aAliasName,
|
||||
const STRING_UTF8_MAP* aProperties )
|
||||
|
||||
@@ -152,6 +152,7 @@ private:
|
||||
void ParseHarnessType( const std::map<wxString, wxString>& aProperties );
|
||||
void ParseHarnessPort( const ASCH_PORT& aElem );
|
||||
void ParseHyperlink( const std::map<wxString, wxString>& aProperties, std::vector<LIB_SYMBOL*>& aSymbol = nullsym);
|
||||
void ParsePieChart( const std::map<wxString, wxString>& aProperties, std::vector<LIB_SYMBOL*>& aSymbol = nullsym);
|
||||
void ParseRectangle( const std::map<wxString, wxString>& aProperties, std::vector<LIB_SYMBOL*>& aSymbol = nullsym);
|
||||
void ParseSheetSymbol( int aIndex, const std::map<wxString, wxString>& aProperties );
|
||||
void ParseSheetEntry( const std::map<wxString, wxString>& aProperties );
|
||||
@@ -178,6 +179,9 @@ private:
|
||||
std::map<wxString,LIB_SYMBOL*> ParseLibFile( const ALTIUM_COMPOUND_FILE& aAltiumSchFile );
|
||||
std::vector<LIB_SYMBOL*> ParseLibComponent( const std::map<wxString, wxString>& aProperties );
|
||||
|
||||
void doEnumerateSymbolLib( const wxString& aLibraryPath, const STRING_UTF8_MAP* aProperties,
|
||||
std::function<void(const wxString&, LIB_SYMBOL*)> aInserter );
|
||||
|
||||
private:
|
||||
SCH_SHEET* m_rootSheet; // The root sheet of the schematic being loaded..
|
||||
SCH_SHEET_PATH m_sheetPath;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <sch_io/cadstar/sch_io_cadstar_archive.h>
|
||||
#include <io/cadstar/cadstar_parts_lib_parser.h>
|
||||
|
||||
#include <font/fontconfig.h>
|
||||
#include <lib_symbol.h>
|
||||
#include <progress_reporter.h>
|
||||
#include <project_sch.h>
|
||||
@@ -68,6 +69,9 @@ SCH_SHEET* SCH_IO_CADSTAR_ARCHIVE::LoadSchematicFile( const wxString& aFi
|
||||
{
|
||||
wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
|
||||
|
||||
// Show the font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( &WXLOG_REPORTER::GetInstance() );
|
||||
|
||||
SCH_SHEET* rootSheet = nullptr;
|
||||
|
||||
|
||||
@@ -251,6 +255,9 @@ void SCH_IO_CADSTAR_ARCHIVE::ensureLoadedLibrary( const wxString& aLibraryPath,
|
||||
wxFileName csafn;
|
||||
wxString fplibname = "cadstarpcblib";
|
||||
|
||||
// Suppress font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( nullptr );
|
||||
|
||||
if( aProperties && aProperties->count( "csa" ) )
|
||||
{
|
||||
csafn = wxFileName( aProperties->at( "csa" ) );
|
||||
|
||||
@@ -39,19 +39,21 @@
|
||||
#include <symbol_library.h>
|
||||
#include <io/eagle/eagle_parser.h>
|
||||
#include <string_utils.h>
|
||||
#include <font/fontconfig.h>
|
||||
#include <gr_text.h>
|
||||
#include <lib_shape.h>
|
||||
#include <lib_id.h>
|
||||
#include <lib_pin.h>
|
||||
#include <lib_text.h>
|
||||
#include <progress_reporter.h>
|
||||
#include <project.h>
|
||||
#include <project/net_settings.h>
|
||||
#include <project_sch.h>
|
||||
#include <sch_bus_entry.h>
|
||||
#include <sch_symbol.h>
|
||||
#include <project/net_settings.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <sch_junction.h>
|
||||
#include <sch_io/kicad_legacy/sch_io_kicad_legacy.h>
|
||||
#include <sch_junction.h>
|
||||
#include <sch_label.h>
|
||||
#include <sch_marker.h>
|
||||
#include <sch_screen.h>
|
||||
#include <sch_shape.h>
|
||||
@@ -59,9 +61,9 @@
|
||||
#include <sch_sheet_path.h>
|
||||
#include <sch_label.h>
|
||||
#include <schematic.h>
|
||||
#include <string_utils.h>
|
||||
#include <symbol_lib_table.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <progress_reporter.h>
|
||||
|
||||
|
||||
// Eagle schematic axes are aligned with x increasing left to right and Y increasing bottom to top
|
||||
@@ -408,6 +410,9 @@ SCH_SHEET* SCH_IO_EAGLE::LoadSchematicFile( const wxString& aFileName, SCHEMATIC
|
||||
wxASSERT( !aFileName || aSchematic != nullptr );
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
||||
// Show the font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( &WXLOG_REPORTER::GetInstance() );
|
||||
|
||||
m_filename = aFileName;
|
||||
m_schematic = aSchematic;
|
||||
|
||||
@@ -582,6 +587,9 @@ long long SCH_IO_EAGLE::getLibraryTimestamp( const wxString& aLibraryPath ) cons
|
||||
|
||||
void SCH_IO_EAGLE::ensureLoadedLibrary( const wxString& aLibraryPath )
|
||||
{
|
||||
// Suppress font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( nullptr );
|
||||
|
||||
if( m_eagleLibs.find( m_libName ) != m_eagleLibs.end() )
|
||||
{
|
||||
wxCHECK( m_timestamps.count( m_libName ), /*void*/ );
|
||||
@@ -973,7 +981,7 @@ void SCH_IO_EAGLE::loadSheet( wxXmlNode* aSheetNode, int aSheetIndex )
|
||||
ReplaceIllegalFileNameChars( &filename );
|
||||
replace( filename.begin(), filename.end(), ' ', '_' );
|
||||
|
||||
wxFileName fn( m_filename );
|
||||
wxFileName fn( m_schematic->Prj().GetProjectPath() );
|
||||
fn.SetName( filename );
|
||||
fn.SetExt( FILEEXT::KiCadSchematicFileExtension );
|
||||
|
||||
@@ -1839,9 +1847,10 @@ void SCH_IO_EAGLE::loadInstance( wxXmlNode* aInstanceNode )
|
||||
|
||||
SCH_FIELD* valueField = symbol->GetField( VALUE_FIELD );
|
||||
bool userValue = m_userValue.at( libIdSymbolName );
|
||||
|
||||
valueField->SetVisible( part->GetFieldById( VALUE_FIELD )->IsVisible() );
|
||||
|
||||
if( userValue && epart->value )
|
||||
if( epart->value )
|
||||
{
|
||||
valueField->SetText( *epart->value );
|
||||
}
|
||||
@@ -1953,11 +1962,8 @@ void SCH_IO_EAGLE::loadInstance( wxXmlNode* aInstanceNode )
|
||||
// Use the instance attribute to determine the reference and value field visibility.
|
||||
if( einstance.smashed && einstance.smashed.Get() )
|
||||
{
|
||||
if( !valueAttributeFound )
|
||||
symbol->GetField( VALUE_FIELD )->SetVisible( false );
|
||||
|
||||
if( !nameAttributeFound )
|
||||
symbol->GetField( REFERENCE_FIELD )->SetVisible( false );
|
||||
symbol->GetField( VALUE_FIELD )->SetVisible( valueAttributeFound );
|
||||
symbol->GetField( REFERENCE_FIELD )->SetVisible( nameAttributeFound );
|
||||
}
|
||||
|
||||
symbol->AddHierarchicalReference( m_sheetPath.Path(), reference, unit );
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 Alex Shvartzkop <dudesuchamazing@gmail.com>
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2023-2024 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
|
||||
@@ -43,12 +43,27 @@
|
||||
#include <wx/base64.h>
|
||||
#include <wx/url.h>
|
||||
#include <wx/mstream.h>
|
||||
#include <core/map_helpers.h>
|
||||
#include <gfx_import_utils.h>
|
||||
#include <import_gfx/svg_import_plugin.h>
|
||||
#include <import_gfx/graphics_importer_lib_symbol.h>
|
||||
#include <import_gfx/graphics_importer_sch.h>
|
||||
|
||||
|
||||
// clang-format off
|
||||
static const std::vector<wxString> c_attributesWhitelist = { "Datasheet",
|
||||
"Manufacturer Part",
|
||||
"Manufacturer",
|
||||
"BOM_Manufacturer Part",
|
||||
"BOM_Manufacturer",
|
||||
"Supplier Part",
|
||||
"Supplier",
|
||||
"BOM_Supplier Part",
|
||||
"BOM_Supplier",
|
||||
"LCSC Part Name" };
|
||||
// clang-format on
|
||||
|
||||
|
||||
SCH_EASYEDA_PARSER::SCH_EASYEDA_PARSER( SCHEMATIC* aSchematic,
|
||||
PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
@@ -561,97 +576,61 @@ void SCH_EASYEDA_PARSER::ParseSymbolShapes( LIB_SYMBOL* aSymbol
|
||||
wxString fillColor = arr[6].Lower();
|
||||
//bool locked = arr[8] != wxS( "0" );
|
||||
|
||||
VECTOR2D start, end;
|
||||
VECTOR2D rad( 10, 10 );
|
||||
bool isFar = false;
|
||||
bool cw = false;
|
||||
std::vector<SHAPE_LINE_CHAIN> chains =
|
||||
ParseLineChains( data, schIUScale.MilsToIU( 10 ), false );
|
||||
|
||||
size_t pos = 0;
|
||||
auto readNumber = [&]( wxString& aOut )
|
||||
auto transform = []( VECTOR2I aVec )
|
||||
{
|
||||
wxUniChar ch = data[pos];
|
||||
|
||||
while( ch == ' ' || ch == ',' )
|
||||
ch = data[++pos];
|
||||
|
||||
while( isdigit( ch ) || ch == '.' || ch == '-' )
|
||||
{
|
||||
aOut += ch;
|
||||
pos++;
|
||||
|
||||
if( pos == data.size() )
|
||||
break;
|
||||
|
||||
ch = data[pos];
|
||||
}
|
||||
return VECTOR2I( aVec.x, -aVec.y );
|
||||
};
|
||||
|
||||
do
|
||||
for( const SHAPE_LINE_CHAIN& chain : chains )
|
||||
{
|
||||
wxUniChar sym = data[pos++];
|
||||
|
||||
if( sym == 'M' )
|
||||
for( int i = 0; i <= chain.PointCount() && i != -1; i = chain.NextShape( i ) )
|
||||
{
|
||||
wxString xStr, yStr;
|
||||
readNumber( xStr );
|
||||
readNumber( yStr );
|
||||
if( chain.IsArcStart( i ) )
|
||||
{
|
||||
SHAPE_ARC arc = chain.Arc( chain.ArcIndex( i ) );
|
||||
|
||||
start = VECTOR2D( Convert( xStr ), Convert( yStr ) );
|
||||
std::unique_ptr<LIB_SHAPE> shape =
|
||||
std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::ARC );
|
||||
|
||||
shape->SetArcGeometry( transform( arc.GetP0() ),
|
||||
transform( arc.GetArcMid() ),
|
||||
transform( arc.GetP1() ) );
|
||||
|
||||
shape->SetUnit( 0 );
|
||||
shape->SetStroke( STROKE_PARAMS( ScaleSize( lineWidth ), strokeStyle ) );
|
||||
|
||||
if( fillColor != wxS( "none" ) )
|
||||
{
|
||||
shape->SetFilled( true );
|
||||
|
||||
if( fillColor == strokeColor )
|
||||
shape->SetFillMode( FILL_T::FILLED_SHAPE );
|
||||
else
|
||||
shape->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
|
||||
}
|
||||
|
||||
aSymbol->AddDrawItem( shape.release() );
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG seg = chain.CSegment( i );
|
||||
|
||||
std::unique_ptr<LIB_SHAPE> shape =
|
||||
std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::POLY );
|
||||
|
||||
shape->AddPoint( transform( seg.A ) );
|
||||
shape->AddPoint( transform( seg.B ) );
|
||||
|
||||
shape->SetUnit( 0 );
|
||||
shape->SetStroke( STROKE_PARAMS( ScaleSize( lineWidth ), strokeStyle ) );
|
||||
|
||||
aSymbol->AddDrawItem( shape.release() );
|
||||
}
|
||||
}
|
||||
else if( sym == 'A' )
|
||||
{
|
||||
wxString radX, radY, unknown, farFlag, cwFlag, endX, endY;
|
||||
readNumber( radX );
|
||||
readNumber( radY );
|
||||
readNumber( unknown );
|
||||
readNumber( farFlag );
|
||||
readNumber( cwFlag );
|
||||
readNumber( endX );
|
||||
readNumber( endY );
|
||||
|
||||
isFar = farFlag == wxS( "1" );
|
||||
cw = cwFlag == wxS( "1" );
|
||||
rad = VECTOR2D( Convert( radX ), Convert( radY ) );
|
||||
end = VECTOR2D( Convert( endX ), Convert( endY ) );
|
||||
}
|
||||
} while( pos < data.size() );
|
||||
|
||||
VECTOR2D delta = end - start;
|
||||
|
||||
double avgRad = ( rad.x + rad.y ) / 2;
|
||||
double d = delta.EuclideanNorm();
|
||||
double h = sqrt( std::max( 0.0, avgRad * avgRad - d * d / 4 ) );
|
||||
|
||||
//( !far && cw ) => h
|
||||
//( far && cw ) => -h
|
||||
//( !far && !cw ) => -h
|
||||
//( far && !cw ) => h
|
||||
VECTOR2D arcCenter =
|
||||
start + delta / 2 + delta.Perpendicular().Resize( ( isFar ^ cw ) ? h : -h );
|
||||
|
||||
if( cw )
|
||||
std::swap( start, end );
|
||||
|
||||
std::unique_ptr<LIB_SHAPE> shape = std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::ARC );
|
||||
|
||||
shape->SetStart( RelPosSym( start ) );
|
||||
shape->SetEnd( RelPosSym( end ) );
|
||||
shape->SetCenter( RelPosSym( arcCenter ) );
|
||||
|
||||
shape->SetUnit( 0 );
|
||||
shape->SetStroke( STROKE_PARAMS( ScaleSize( lineWidth ), strokeStyle ) );
|
||||
|
||||
if( fillColor != wxS( "none" ) )
|
||||
{
|
||||
shape->SetFilled( true );
|
||||
|
||||
if( fillColor == strokeColor )
|
||||
shape->SetFillMode( FILL_T::FILLED_SHAPE );
|
||||
else
|
||||
shape->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
|
||||
}
|
||||
|
||||
aSymbol->AddDrawItem( shape.release() );
|
||||
}
|
||||
else if( elType == wxS( "R" ) )
|
||||
{
|
||||
@@ -962,22 +941,20 @@ LIB_SYMBOL* SCH_EASYEDA_PARSER::ParseSymbol( const VECTOR2D& aOrigi
|
||||
|
||||
m_relOrigin = aOrigin;
|
||||
|
||||
wxString symbolName = wxS( "Unknown" );
|
||||
std::optional<wxString> valOpt;
|
||||
wxString symbolName = wxS( "Unknown" );
|
||||
|
||||
if( aParams.find( wxS( "name" ) ) != aParams.end() )
|
||||
symbolName = aParams.at( wxS( "name" ) );
|
||||
else if( aParams.find( wxS( "spiceSymbolName" ) ) != aParams.end() )
|
||||
symbolName = aParams.at( wxS( "spiceSymbolName" ) );
|
||||
if( valOpt = get_opt( aParams, wxS( "name" ) ) )
|
||||
symbolName = *valOpt;
|
||||
else if( valOpt = get_opt( aParams, wxS( "spiceSymbolName" ) ) )
|
||||
symbolName = *valOpt;
|
||||
|
||||
wxString symbolPrefix;
|
||||
|
||||
if( aParams.find( wxS( "pre" ) ) != aParams.end() )
|
||||
symbolPrefix = aParams.at( wxS( "pre" ) );
|
||||
else if( aParams.find( wxS( "spicePre" ) ) != aParams.end() )
|
||||
symbolPrefix = aParams.at( wxS( "spicePre" ) );
|
||||
|
||||
if( !symbolPrefix.EndsWith( wxS( "?" ) ) )
|
||||
symbolPrefix += wxS( "?" );
|
||||
if( valOpt = get_opt( aParams, wxS( "pre" ) ) )
|
||||
symbolPrefix = *valOpt;
|
||||
else if( valOpt = get_opt( aParams, wxS( "spicePre" ) ) )
|
||||
symbolPrefix = *valOpt;
|
||||
|
||||
LIB_ID libId = EasyEdaToKiCadLibID( wxEmptyString, symbolName );
|
||||
|
||||
@@ -987,6 +964,31 @@ LIB_SYMBOL* SCH_EASYEDA_PARSER::ParseSymbol( const VECTOR2D& aOrigi
|
||||
ksymbol->GetReferenceField().SetText( symbolPrefix );
|
||||
ksymbol->GetValueField().SetText( symbolName );
|
||||
|
||||
for( wxString attrName : c_attributesWhitelist )
|
||||
{
|
||||
wxString srcName = attrName;
|
||||
|
||||
if( srcName == wxS( "Datasheet" ) )
|
||||
srcName = wxS( "link" );
|
||||
|
||||
if( valOpt = get_opt( aParams, srcName ) )
|
||||
{
|
||||
if( valOpt->empty() )
|
||||
continue;
|
||||
|
||||
LIB_FIELD* fd = ksymbol->FindField( attrName, true );
|
||||
|
||||
if( !fd )
|
||||
{
|
||||
fd = new LIB_FIELD( ksymbol->GetNextAvailableFieldId(), attrName );
|
||||
ksymbol->AddField( fd );
|
||||
}
|
||||
|
||||
fd->SetText( *valOpt );
|
||||
fd->SetVisible( false );
|
||||
}
|
||||
}
|
||||
|
||||
ParseSymbolShapes( ksymbol.get(), aParams, aShapes );
|
||||
|
||||
return ksymbol.release();
|
||||
|
||||
@@ -25,14 +25,14 @@
|
||||
#include "sch_easyeda_parser.h"
|
||||
#include "sch_io_easyeda.h"
|
||||
|
||||
#include <schematic.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_screen.h>
|
||||
#include <font/fontconfig.h>
|
||||
#include <kiplatform/environment.h>
|
||||
#include <project_sch.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <sch_screen.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <schematic.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/stdstream.h>
|
||||
#include <wx/zipstrm.h>
|
||||
@@ -225,7 +225,19 @@ LIB_SYMBOL* loadSymbol( const wxString& aLibraryPath, nlohmann::json aFileData,
|
||||
{
|
||||
parts.RemoveAt( 0 );
|
||||
|
||||
return parser.ParseSymbol( origin, paramMap, parts );
|
||||
LIB_SYMBOL* ksymbol = parser.ParseSymbol( origin, paramMap, parts );
|
||||
|
||||
// Clear reference numbers
|
||||
LIB_FIELD& refField = ksymbol->GetReferenceField();
|
||||
wxString origRef = refField.GetText();
|
||||
wxString reference;
|
||||
|
||||
for( size_t i = 0; i < origRef.size() && !wxIsdigit( origRef[i] ); i++ )
|
||||
reference << origRef[i];
|
||||
|
||||
refField.SetText( reference );
|
||||
|
||||
return ksymbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -261,7 +273,19 @@ LIB_SYMBOL* loadSymbol( const wxString& aLibraryPath, nlohmann::json aFileData,
|
||||
|
||||
VECTOR2D origin( topDoc.head.x, topDoc.head.y );
|
||||
|
||||
return parser.ParseSymbol( origin, *c_para, topDoc.shape );
|
||||
LIB_SYMBOL* ksymbol = parser.ParseSymbol( origin, *c_para, topDoc.shape );
|
||||
|
||||
// Clear reference numbers
|
||||
LIB_FIELD& refField = ksymbol->GetReferenceField();
|
||||
wxString origRef = refField.GetText();
|
||||
wxString reference;
|
||||
|
||||
for( size_t i = 0; i < origRef.size() && !wxIsdigit( origRef[i] ); i++ )
|
||||
reference << origRef[i];
|
||||
|
||||
refField.SetText( reference );
|
||||
|
||||
return ksymbol;
|
||||
}
|
||||
}
|
||||
catch( nlohmann::json::exception& e )
|
||||
@@ -285,6 +309,9 @@ void SCH_IO_EASYEDA::EnumerateSymbolLib( wxArrayString& aSymbolNameList,
|
||||
{
|
||||
std::map<wxString, int> namesCounter;
|
||||
|
||||
// Suppress font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( nullptr );
|
||||
|
||||
try
|
||||
{
|
||||
wxFFileInputStream in( aLibraryPath );
|
||||
@@ -588,6 +615,9 @@ SCH_SHEET* SCH_IO_EASYEDA::LoadSchematicFile( const wxString& aFileName, SCHEMAT
|
||||
{
|
||||
wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
|
||||
|
||||
// Show the font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( &WXLOG_REPORTER::GetInstance() );
|
||||
|
||||
SCH_SHEET* rootSheet = nullptr;
|
||||
|
||||
if( aAppendToMe )
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 Alex Shvartzkop <dudesuchamazing@gmail.com>
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2023-2024 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
|
||||
@@ -52,6 +52,21 @@
|
||||
#include <import_gfx/graphics_importer_sch.h>
|
||||
|
||||
|
||||
// clang-format off
|
||||
static const std::vector<wxString> c_attributesWhitelist = { "Value",
|
||||
"Datasheet",
|
||||
"Manufacturer Part",
|
||||
"Manufacturer",
|
||||
"BOM_Manufacturer Part",
|
||||
"BOM_Manufacturer",
|
||||
"Supplier Part",
|
||||
"Supplier",
|
||||
"BOM_Supplier Part",
|
||||
"BOM_Supplier",
|
||||
"LCSC Part Name" };
|
||||
// clang-format on
|
||||
|
||||
|
||||
SCH_EASYEDAPRO_PARSER::SCH_EASYEDAPRO_PARSER( SCHEMATIC* aSchematic,
|
||||
PROGRESS_REPORTER* aProgressReporter )
|
||||
{
|
||||
@@ -383,7 +398,9 @@ void SCH_EASYEDAPRO_PARSER::ApplyAttrToField( const std::map<wxString, nlohmann:
|
||||
}
|
||||
|
||||
|
||||
EASYEDAPRO::SYM_INFO SCH_EASYEDAPRO_PARSER::ParseSymbol( const std::vector<nlohmann::json>& aLines )
|
||||
EASYEDAPRO::SYM_INFO
|
||||
SCH_EASYEDAPRO_PARSER::ParseSymbol( const std::vector<nlohmann::json>& aLines,
|
||||
const std::map<wxString, wxString>& aDeviceAttributes )
|
||||
{
|
||||
EASYEDAPRO::SYM_INFO symInfo;
|
||||
|
||||
@@ -686,11 +703,35 @@ EASYEDAPRO::SYM_INFO SCH_EASYEDAPRO_PARSER::ParseSymbol( const std::vector<nlohm
|
||||
{
|
||||
wxString symbolPrefix = designatorAttr->value;
|
||||
|
||||
if( !symbolPrefix.EndsWith( wxS( "?" ) ) )
|
||||
symbolPrefix += wxS( "?" );
|
||||
if( symbolPrefix.EndsWith( wxS( "?" ) ) )
|
||||
symbolPrefix.RemoveLast();
|
||||
|
||||
ksymbol->GetReferenceField().SetText( symbolPrefix );
|
||||
}
|
||||
|
||||
for( const wxString& attrName : c_attributesWhitelist )
|
||||
{
|
||||
if( auto valOpt = get_opt( aDeviceAttributes, attrName ) )
|
||||
{
|
||||
if( valOpt->empty() )
|
||||
continue;
|
||||
|
||||
LIB_FIELD* fd = ksymbol->FindField( attrName, true );
|
||||
|
||||
if( !fd )
|
||||
{
|
||||
fd = new LIB_FIELD( ksymbol->GetNextAvailableFieldId(), attrName );
|
||||
ksymbol->AddField( fd );
|
||||
}
|
||||
|
||||
wxString value = *valOpt;
|
||||
|
||||
value.Replace( wxS( "\u2103" ), wxS( "\u00B0C" ), true ); // ℃ -> °C
|
||||
|
||||
fd->SetText( value );
|
||||
fd->SetVisible( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( auto& [unitId, parentedLines] : unitParentedLines )
|
||||
@@ -1107,7 +1148,7 @@ void SCH_EASYEDAPRO_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aR
|
||||
if( !deviceAttr )
|
||||
continue;
|
||||
|
||||
nlohmann::json compAttrs =
|
||||
std::map<wxString, wxString> compAttrs =
|
||||
aProject.at( "devices" ).at( deviceAttr->value ).at( "attributes" );
|
||||
|
||||
wxString symbolId;
|
||||
@@ -1115,7 +1156,7 @@ void SCH_EASYEDAPRO_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aR
|
||||
if( symbolAttr && !symbolAttr->value.IsEmpty() )
|
||||
symbolId = symbolAttr->value;
|
||||
else
|
||||
symbolId = compAttrs.at( "Symbol" ).get<wxString>();
|
||||
symbolId = compAttrs.at( "Symbol" );
|
||||
|
||||
auto it = aSymbolMap.find( symbolId );
|
||||
if( it == aSymbolMap.end() )
|
||||
@@ -1217,6 +1258,30 @@ void SCH_EASYEDAPRO_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aR
|
||||
}
|
||||
else
|
||||
{
|
||||
for( const wxString& attrKey : c_attributesWhitelist )
|
||||
{
|
||||
if( auto valOpt = get_opt( compAttrs, attrKey ) )
|
||||
{
|
||||
if( valOpt->empty() )
|
||||
continue;
|
||||
|
||||
SCH_FIELD* text = schSym->FindField( attrKey, true );
|
||||
|
||||
if( !text )
|
||||
{
|
||||
text = schSym->AddField(
|
||||
SCH_FIELD( schSym.get(), schSym->GetFieldCount(), attrKey ) );
|
||||
}
|
||||
|
||||
wxString value = *valOpt;
|
||||
|
||||
value.Replace( wxS( "\u2103" ), wxS( "\u00B0C" ), true ); // ℃ -> °C
|
||||
|
||||
text->SetText( value );
|
||||
text->SetVisible( false );
|
||||
}
|
||||
}
|
||||
|
||||
auto nameAttr = get_opt( attributes, "Name" );
|
||||
auto valueAttr = get_opt( attributes, "Value" );
|
||||
|
||||
@@ -1265,15 +1330,18 @@ void SCH_EASYEDAPRO_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aR
|
||||
if( attr.value.IsEmpty() )
|
||||
continue;
|
||||
|
||||
SCH_FIELD* text =
|
||||
new SCH_FIELD( schSym.get(), schSym->GetFieldCount(), attrKey );
|
||||
SCH_FIELD* text = schSym->FindField( attrKey, true );
|
||||
|
||||
if( !text )
|
||||
{
|
||||
text = schSym->AddField(
|
||||
SCH_FIELD( schSym.get(), schSym->GetFieldCount(), attrKey ) );
|
||||
}
|
||||
|
||||
text->SetPosition( schSym->GetPosition() );
|
||||
|
||||
ApplyAttrToField( fontStyles, text, attr, false, true, compAttrs,
|
||||
schSym.get() );
|
||||
|
||||
schSym->AddField( *text );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 Alex Shvartzkop <dudesuchamazing@gmail.com>
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2023-2024 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
|
||||
@@ -101,7 +101,8 @@ public:
|
||||
|
||||
double SizeToKi( wxString units );
|
||||
|
||||
EASYEDAPRO::SYM_INFO ParseSymbol( const std::vector<nlohmann::json>& aLines );
|
||||
EASYEDAPRO::SYM_INFO ParseSymbol( const std::vector<nlohmann::json>& aLines,
|
||||
const std::map<wxString, wxString>& aDeviceAttributes );
|
||||
|
||||
void ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aRootSheet,
|
||||
const nlohmann::json& aProject,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 Alex Shvartzkop <dudesuchamazing@gmail.com>
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "sch_easyedapro_parser.h"
|
||||
#include "sch_io_easyedapro.h"
|
||||
|
||||
#include <font/fontconfig.h>
|
||||
#include <schematic.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_screen.h>
|
||||
@@ -156,7 +157,11 @@ static LIB_SYMBOL* loadSymbol( nlohmann::json project, const wxString& aLibraryP
|
||||
return nullptr;
|
||||
|
||||
wxString prjSymUuid = prjSymIt->first;
|
||||
wxString fpTitle;
|
||||
|
||||
wxString description;
|
||||
wxString customTags;
|
||||
std::map<wxString, wxString> deviceAttributes;
|
||||
wxString fpTitle;
|
||||
|
||||
for( auto& [key, device] : prjDevices )
|
||||
{
|
||||
@@ -164,6 +169,12 @@ static LIB_SYMBOL* loadSymbol( nlohmann::json project, const wxString& aLibraryP
|
||||
|
||||
if( val && *val == prjSymUuid )
|
||||
{
|
||||
description = device.description;
|
||||
deviceAttributes = device.attributes;
|
||||
|
||||
if( device.custom_tags.is_string() )
|
||||
customTags = device.custom_tags.get<wxString>();
|
||||
|
||||
if( auto fpUuid = get_opt( device.attributes, "Footprint" ) )
|
||||
{
|
||||
if( auto prjFp = get_opt( prjFootprints, *fpUuid ) )
|
||||
@@ -192,7 +203,7 @@ static LIB_SYMBOL* loadSymbol( nlohmann::json project, const wxString& aLibraryP
|
||||
lines.emplace_back( js );
|
||||
}
|
||||
|
||||
EASYEDAPRO::SYM_INFO symInfo = parser.ParseSymbol( lines );
|
||||
EASYEDAPRO::SYM_INFO symInfo = parser.ParseSymbol( lines, deviceAttributes );
|
||||
|
||||
if( !symInfo.libSymbol )
|
||||
EASY_IT_CONTINUE;
|
||||
@@ -202,6 +213,15 @@ static LIB_SYMBOL* loadSymbol( nlohmann::json project, const wxString& aLibraryP
|
||||
symInfo.libSymbol->SetName( aAliasName );
|
||||
symInfo.libSymbol->GetFootprintField().SetText( symLibName + wxS( ":" ) + fpTitle );
|
||||
|
||||
wxString keywords = customTags;
|
||||
keywords.Replace( wxS( ":" ), wxS( " " ), true );
|
||||
|
||||
symInfo.libSymbol->SetKeyWords( keywords );
|
||||
|
||||
description.Replace( wxS( "\u2103" ), wxS( "\u00B0C" ), true ); // ℃ -> °C
|
||||
|
||||
symInfo.libSymbol->SetDescription( description );
|
||||
|
||||
symbol = symInfo.libSymbol.release();
|
||||
|
||||
EASY_IT_BREAK;
|
||||
@@ -314,13 +334,10 @@ void SCH_IO_EASYEDAPRO::LoadAllDataFromProject( const wxString& aProjectPath )
|
||||
|
||||
if( name.EndsWith( wxS( ".esym" ) ) )
|
||||
{
|
||||
EASYEDAPRO::PRJ_SYMBOL symData = prjSymbols.at( baseName );
|
||||
EASYEDAPRO::SYM_INFO symInfo = parser.ParseSymbol( lines );
|
||||
|
||||
if( !symInfo.libSymbol )
|
||||
EASY_IT_CONTINUE;
|
||||
|
||||
wxString fpTitle;
|
||||
wxString description;
|
||||
wxString customTags;
|
||||
std::map<wxString, wxString> deviceAttributes;
|
||||
wxString fpTitle;
|
||||
|
||||
for( auto& [key, device] : prjDevices )
|
||||
{
|
||||
@@ -328,6 +345,12 @@ void SCH_IO_EASYEDAPRO::LoadAllDataFromProject( const wxString& aProjectPath )
|
||||
|
||||
if( val && *val == baseName )
|
||||
{
|
||||
description = device.description;
|
||||
deviceAttributes = device.attributes;
|
||||
|
||||
if( device.custom_tags.is_string() )
|
||||
customTags = device.custom_tags.get<wxString>();
|
||||
|
||||
if( auto fpUuid = get_opt( device.attributes, "Footprint" ) )
|
||||
{
|
||||
if( auto prjFp = get_opt( prjFootprints, *fpUuid ) )
|
||||
@@ -339,11 +362,26 @@ void SCH_IO_EASYEDAPRO::LoadAllDataFromProject( const wxString& aProjectPath )
|
||||
}
|
||||
}
|
||||
|
||||
EASYEDAPRO::PRJ_SYMBOL symData = prjSymbols.at( baseName );
|
||||
EASYEDAPRO::SYM_INFO symInfo = parser.ParseSymbol( lines, deviceAttributes );
|
||||
|
||||
if( !symInfo.libSymbol )
|
||||
EASY_IT_CONTINUE;
|
||||
|
||||
LIB_ID libID = EASYEDAPRO::ToKiCadLibID( symLibName, symData.title );
|
||||
symInfo.libSymbol->SetLibId( libID );
|
||||
symInfo.libSymbol->SetName( symData.title );
|
||||
symInfo.libSymbol->GetFootprintField().SetText( symLibName + wxS( ":" ) + fpTitle );
|
||||
|
||||
wxString keywords = customTags;
|
||||
keywords.Replace( wxS( ":" ), wxS( " " ), true );
|
||||
|
||||
symInfo.libSymbol->SetKeyWords( keywords );
|
||||
|
||||
description.Replace( wxS( "\u2103" ), wxS( "\u00B0C" ), true ); // ℃ -> °C
|
||||
|
||||
symInfo.libSymbol->SetDescription( description );
|
||||
|
||||
m_projectData->m_Symbols.emplace( baseName, std::move( symInfo ) );
|
||||
}
|
||||
else if( name.EndsWith( wxS( ".eblob" ) ) )
|
||||
@@ -386,6 +424,9 @@ SCH_SHEET* SCH_IO_EASYEDAPRO::LoadSchematicFile( const wxString& aFileName,
|
||||
{
|
||||
wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
|
||||
|
||||
// Show the font substitution warnings
|
||||
fontconfig::FONTCONFIG::SetReporter( &WXLOG_REPORTER::GetInstance() );
|
||||
|
||||
SCH_SHEET* rootSheet = nullptr;
|
||||
|
||||
if( aAppendToMe )
|
||||
|
||||
@@ -539,7 +539,9 @@ void SCH_IO_KICAD_LEGACY_LIB_CACHE::loadField( std::unique_ptr<LIB_SYMBOL>& aSym
|
||||
|
||||
LIB_FIELD* field;
|
||||
|
||||
if( id >= 0 && id < MANDATORY_FIELDS )
|
||||
// Description was not mandatory until v8.0, so any fields with an index
|
||||
// past this point should be user fields
|
||||
if( id >= 0 && id < DESCRIPTION_FIELD )
|
||||
{
|
||||
field = aSymbol->GetFieldById( id );
|
||||
|
||||
@@ -550,6 +552,7 @@ void SCH_IO_KICAD_LEGACY_LIB_CACHE::loadField( std::unique_ptr<LIB_SYMBOL>& aSym
|
||||
}
|
||||
else
|
||||
{
|
||||
id = aSymbol->GetNextAvailableFieldId();
|
||||
field = new LIB_FIELD( aSymbol.get(), id );
|
||||
aSymbol->AddDrawItem( field, false );
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user