Compare commits
432 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2bc8c0ace5 | |||
| f439dfb6ea | |||
| 9fdc1257a1 | |||
| 95828ff2e2 | |||
| 98e55c0a04 | |||
| 2757d81231 | |||
| 985ceb365b | |||
| cdf04d5582 | |||
| a1ff9134f4 | |||
| cc0b51c81a | |||
| 4e34bdb621 | |||
| 6d96059917 | |||
| 99cfa1fad7 | |||
| b2a6f12645 | |||
| b33cf23bda | |||
| 5a36c3685e | |||
| 5991842ae4 | |||
| 6c0a30e2f3 | |||
| c0eee45876 | |||
| 6ebd970f88 | |||
| 5e3b74aee5 | |||
| 316087c468 | |||
| 1b1586696f | |||
| 339a349a58 | |||
| 1a161858fc | |||
| 12abcd6ece | |||
| 5e64fb1415 | |||
| 7616461e61 | |||
| 968406c6b5 | |||
| 5144186fca | |||
| c0fb041be6 | |||
| 45e15f2394 | |||
| f5b592e38c | |||
| 60a8eee515 | |||
| 38e09789e5 | |||
| f993e51fba | |||
| 7600f45d11 | |||
| 48d8c149a8 | |||
| 131115e19f | |||
| cd7cab9794 | |||
| 22bece0922 | |||
| 01cff24e4e | |||
| 948071183c | |||
| ee05b67599 | |||
| c07043e762 | |||
| bd9c37aa5f | |||
| 6e6a748320 | |||
| 61c0cac22d | |||
| 3c973a788d | |||
| 048436f0ef | |||
| 491e0cac6a | |||
| cf1d0a9667 | |||
| 3ae39f9614 | |||
| 45d9a58bc7 | |||
| 1a8d974520 | |||
| 8ea00c42d9 | |||
| be8750ad1c | |||
| 350d0323e1 | |||
| 2c7aee057a | |||
| fb6c89358b | |||
| d790e85fe4 | |||
| 7f08356a48 | |||
| 045633626c | |||
| 5de05312d5 | |||
| ecfd74c1be | |||
| cdeb539254 | |||
| 540c5d2b16 | |||
| 38886c998b | |||
| 46b3188737 | |||
| f663b42d77 | |||
| 9ac87132af | |||
| 8af64fb326 | |||
| be86e9f57f | |||
| 3253bd9a3d | |||
| 994dd570de | |||
| c171f5b1b0 | |||
| 36bbe733a8 | |||
| 3400b567b1 | |||
| 28d6c17e42 | |||
| 0df81f67ed | |||
| 30f08024b7 | |||
| d93364268b | |||
| 11531471c6 | |||
| 1626ba3f58 | |||
| 76479f40ef | |||
| 4c9e409df9 | |||
| b4b4f1f3ca | |||
| ed684cd92e | |||
| 3f99dae704 | |||
| 7e72a3c993 | |||
| 2960e9c1b4 | |||
| 0f5e12a535 | |||
| acf62122c8 | |||
| bf9db4d4f8 | |||
| e09212ccad | |||
| 390effe3c6 | |||
| eaafa5d8f0 | |||
| c558144c7b | |||
| b7713dbf0d | |||
| 9b21712ea0 | |||
| 6f7b0cb240 | |||
| ea1aed2fc9 | |||
| 88ad0e5a50 | |||
| 15ead17cea | |||
| 92356b4805 | |||
| cec810a452 | |||
| ec92def539 | |||
| 2dd04ea43a | |||
| d7a7ddd80e | |||
| 27676f4388 | |||
| 2f47857abc | |||
| ede21ed6ae | |||
| a09a3dfe68 | |||
| e083cbaf50 | |||
| 9d401b00d8 | |||
| 25e3b6c1bf | |||
| 2029fc4e8f | |||
| c9cc29593a | |||
| 42bd43407a | |||
| de05a513f3 | |||
| 554d82b2a4 | |||
| 3b3e86b968 | |||
| f6ca98061c | |||
| cca7f1dbda | |||
| 2cf4cb937f | |||
| c3b9c65fd6 | |||
| d9a1703bcc | |||
| a22c466639 | |||
| 9a2f83537d | |||
| f136f3d7ee | |||
| 61d4a5bfbe | |||
| 6289a82a18 | |||
| 6ca2f6a6e1 | |||
| 2ff3fac7b3 | |||
| 08452433e8 | |||
| 39b9b3e570 | |||
| b29f91cc15 | |||
| f81313068e | |||
| 882756b676 | |||
| 8c3cd200d1 | |||
| a5fd03df88 | |||
| 2d2912c23d | |||
| 3106f6c9f4 | |||
| fde2b429b9 | |||
| 0593663462 | |||
| bce8c95647 | |||
| 4d729110d5 | |||
| 6c2b9eb433 | |||
| df223cced4 | |||
| 8e331628b6 | |||
| ceaf3fc72d | |||
| b004d7a1cb | |||
| f3ff9ddd31 | |||
| e5fa18c9b1 | |||
| d52f246b2a | |||
| 3dfbe582db | |||
| 431aa88612 | |||
| 03a1a8e6d3 | |||
| 5f6de83981 | |||
| 02d38db577 | |||
| bd1698f80e | |||
| 6de30b19a0 | |||
| 00ff5baf59 | |||
| 152252c685 | |||
| 3b0466f3e8 | |||
| 2ca7a76693 | |||
| af159c9841 | |||
| de9ae28bdb | |||
| 9f151025b3 | |||
| 549dca1a05 | |||
| da520f83ee | |||
| 47547713de | |||
| 705570923e | |||
| 2827835720 | |||
| bf95906f90 | |||
| e8d2c222b6 | |||
| f891c4641b | |||
| a65fc7f82a | |||
| 5bcd0a5828 | |||
| 74d8040e8c | |||
| c5514d43c7 | |||
| 0704e37eb5 | |||
| c94de31a8c | |||
| 2793e67bab | |||
| 3213ea582d | |||
| 6003097411 | |||
| 6390633a7b | |||
| dde5f2bed1 | |||
| 7c4b8d50dd | |||
| 56f58cf53f | |||
| 914e396e2e | |||
| f6bdd40c30 | |||
| 1bf1620157 | |||
| da85a5f6bf | |||
| e2219a0c4d | |||
| de46097ce0 | |||
| ae53986487 | |||
| 3cf3a3ebe0 | |||
| a62e6b1f7f | |||
| d99ce976b9 | |||
| 161d15dcea | |||
| 81319a5fcf | |||
| 628b4ca8b8 | |||
| d8ed1fea61 | |||
| 6f474a389f | |||
| 5a1a147585 | |||
| de9ef4ce70 | |||
| 835f358816 | |||
| 61cfe53be1 | |||
| 535982f245 | |||
| 8ee73903c6 | |||
| 292492bd01 | |||
| f1029b7280 | |||
| 578c0ef0f0 | |||
| 238c8df8b5 | |||
| 95acc1bf33 | |||
| 8dbfe79536 | |||
| 8f9830eb92 | |||
| bf0b80d676 | |||
| bc8e3c22d8 | |||
| 28ddfbadbf | |||
| e834374ad2 | |||
| 981aafd5d9 | |||
| 09960caa66 | |||
| cf6fd64758 | |||
| b08dccb7b3 | |||
| d6e5c74573 | |||
| ea93502ab3 | |||
| e1f402aa3d | |||
| 08f1b666d1 | |||
| 8d62725598 | |||
| cbd8b3c59e | |||
| e9cc66cc8d | |||
| 258b702dad | |||
| 6c3e891123 | |||
| 80937ae2c0 | |||
| 2d37b86530 | |||
| 8bdcd299d7 | |||
| 22e9985f5d | |||
| 594beef22e | |||
| 03ed7a4a27 | |||
| 8cbfd8af9f | |||
| c16e86be9a | |||
| b0e2aeb972 | |||
| fc06192643 | |||
| 2faaa0a042 | |||
| 2d4bcc6557 | |||
| ba72676edb | |||
| 1a2e2bd29a | |||
| 8b690c9a3c | |||
| 6d25e57cd7 | |||
| 7dfa715a45 | |||
| e8a10939b5 | |||
| 44ec38ad2d | |||
| 9cb6df9c38 | |||
| 4a5fdd4214 | |||
| fe7ed364b6 | |||
| 43f9863182 | |||
| 4987809fe3 | |||
| 894f424d14 | |||
| e21995c401 | |||
| bb7362ceba | |||
| 334268f5e7 | |||
| 3abcdb7e63 | |||
| c45aa734b0 | |||
| a35b89258a | |||
| 408bf85cf5 | |||
| ba34cd629e | |||
| 81dba33c8f | |||
| 2b238de012 | |||
| c0ce4cb0bc | |||
| f379fa4f7f | |||
| 4e67b94b00 | |||
| bb0f3550e0 | |||
| ce1f166aa8 | |||
| 437cd8b1e5 | |||
| 3e8532264e | |||
| 9b15717349 | |||
| 73d00cc5d7 | |||
| 295aa15c3d | |||
| 50adb45c33 | |||
| a1a44db01d | |||
| b2f68854b2 | |||
| 42f844826d | |||
| 52ca321b11 | |||
| 5af5511dfe | |||
| f06f205886 | |||
| 030a562ba6 | |||
| 2393165ada | |||
| e593e0b014 | |||
| 42dae1504a | |||
| 440d324c9e | |||
| 29cadaf54e | |||
| 83eb9e03b1 | |||
| b324abefe5 | |||
| b72675ba92 | |||
| 70b69af313 | |||
| 83f135315c | |||
| c276280e5c | |||
| 07481cd4ca | |||
| 8a9ee0f9e1 | |||
| 9a823ca61b | |||
| 5afeb45a84 | |||
| 45da795668 | |||
| 87a8e69632 | |||
| d57caf2ad7 | |||
| 7f1c2461b5 | |||
| 26104c83ba | |||
| 6d14ce24aa | |||
| e760579828 | |||
| 7640246097 | |||
| e25d937fd8 | |||
| ea3f6c8406 | |||
| bf272e379f | |||
| 0acea2e386 | |||
| 83305dd407 | |||
| 1d5db513a1 | |||
| 9d0d45450b | |||
| 9bce3c243a | |||
| ace0032c82 | |||
| cd30711cf8 | |||
| a3da0b9af6 | |||
| 32a11e4df0 | |||
| 5606714952 | |||
| 9af666ba34 | |||
| 4d9802760e | |||
| c3496d61eb | |||
| 1e09f0e8b0 | |||
| c2c4609272 | |||
| 9328cf42c5 | |||
| 93f23dbdcd | |||
| 9e9b38ef6a | |||
| 5e409f0f6c | |||
| 408e7fed29 | |||
| 85ce1a2a20 | |||
| c1947c108b | |||
| d2916bf399 | |||
| 93f973d825 | |||
| 72503c47c6 | |||
| db96624990 | |||
| 962df45b65 | |||
| f92d25e00b | |||
| 64220656e9 | |||
| 39940fe5ab | |||
| 40977514ce | |||
| cfde5300d7 | |||
| 30c83ed055 | |||
| 64acd8bd47 | |||
| ca4da4706a | |||
| 1005f75cdb | |||
| f637a820b6 | |||
| 47cb817a86 | |||
| 7769069078 | |||
| 411d57396c | |||
| 5f00847a86 | |||
| 36a0c2a9cc | |||
| 4ac48ad829 | |||
| 3bca4f8835 | |||
| afc491c5a5 | |||
| f75104d456 | |||
| 1f3bb83a06 | |||
| efc75047c1 | |||
| 7b5e3feb19 | |||
| fec9331b48 | |||
| a12ae5050a | |||
| 82e8e38054 | |||
| 57de5a6b65 | |||
| 675a5a6e7b | |||
| 6c617d84ca | |||
| 7f71eef45b | |||
| b50d7adaeb | |||
| 027b745124 | |||
| c9c31fcbc2 | |||
| 45c20bec49 | |||
| fe0d09222d | |||
| 28d755ac27 | |||
| 37d9186e2d | |||
| c076239915 | |||
| ca34cea2c1 | |||
| 4c064e41f6 | |||
| 650caae323 | |||
| 06e612661c | |||
| ee4e4d0773 | |||
| 147b11abe0 | |||
| df9cf0a0c3 | |||
| b1ce6be634 | |||
| 3f448a7eaa | |||
| 5214290000 | |||
| fcd7e827e6 | |||
| 466f1283c1 | |||
| 39dd51490d | |||
| 120ceade06 | |||
| f3caac5bfd | |||
| 7bd073b5cb | |||
| af40ddd0e1 | |||
| e59d8b0a2d | |||
| 7113f1f879 | |||
| 31db2b8525 | |||
| 3363fdb248 | |||
| 983f389b24 | |||
| 8d48a56b4a | |||
| 2460276e85 | |||
| 70f2e80dd1 | |||
| 8a5233912f | |||
| c2a6906c31 | |||
| b05fd8f209 | |||
| f3a906dc86 | |||
| a5b676fa0e | |||
| 38b75db12c | |||
| fb2cf7b8be | |||
| ac28ed9888 | |||
| d9fef3da72 | |||
| 61bb793324 | |||
| ccb416eead | |||
| 6e10a496ef | |||
| e06e65cdde | |||
| 832c689345 | |||
| 0580fc6819 | |||
| 0f882d91e5 | |||
| 2fdddb970f | |||
| 0321d96b1e | |||
| ce92c676e6 | |||
| bb5fd5a2ec | |||
| 41a9293106 | |||
| 3c4f8a335f | |||
| 1a6e9538cd | |||
| 06baaa33fa | |||
| cd5b4ec8f2 | |||
| 58451335cb | |||
| e7dd9f9337 | |||
| 7bf66be2ac | |||
| 0bc97b7952 |
@@ -54,6 +54,15 @@ common/pcb_keywords.cpp
|
||||
include/pcb_lexer.h
|
||||
fp-info-cache
|
||||
|
||||
# .md generated files
|
||||
eeschema/dialogs/dialog_bom_help_md.h
|
||||
pcb_calculator/attenuators/bridget_tee_formula.h
|
||||
pcb_calculator/attenuators/pi_formula.h
|
||||
pcb_calculator/attenuators/splitter_formula.h
|
||||
pcb_calculator/attenuators/tee_formula.h
|
||||
pcb_calculator/eserie_help.h
|
||||
pcb_calculator/tracks_width_versus_current_formula.h
|
||||
|
||||
# demo project auxiliary files
|
||||
demos/**/*-bak
|
||||
demos/**/_autosave-*
|
||||
|
||||
+2
-1
@@ -40,6 +40,7 @@ include:
|
||||
- local: '/.gitlab/templates.yml'
|
||||
- local: '/.gitlab/Fedora-Linux-CI.yml'
|
||||
- local: '/.gitlab/Ubuntu-20.04-CI.yml'
|
||||
# - local: '/.gitlab/Windows-CI.yml'
|
||||
- local: '/.gitlab/Windows-CI.yml'
|
||||
- local: '/.gitlab/coverity.yml'
|
||||
- local: '/.gitlab/linux-metadata-validate.yml'
|
||||
- local: '/.gitlab/doxygen.yml'
|
||||
|
||||
+13
-2
@@ -7,16 +7,27 @@ win64_build:
|
||||
- kicad-windows-1809
|
||||
extends: .only_code
|
||||
interruptible: false
|
||||
image: registry.gitlab.com/kicad/kicad-ci/source_containers/win64:msvc1809
|
||||
image: registry.gitlab.com/kicad/kicad-ci/windows-build-image/win1809-msvc:latest
|
||||
variables:
|
||||
VCPKG_BINARY_SOURCES: 'nuget,kicad,readwrite'
|
||||
cache:
|
||||
key: win64-vcpkg-"$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- build\windows\vcpkg_installed
|
||||
- .vcpkgCache
|
||||
only:
|
||||
- branches@kicad/code/kicad
|
||||
- tags@kicad/code/kicad
|
||||
script:
|
||||
- C:\builder\build.ps1 -Env -Arch x64
|
||||
- $vcpkgCache=Join-Path -Path (Get-Location) -ChildPath ".vcpkgCache";$env:VCPKG_DEFAULT_BINARY_CACHE=$vcpkgCache;New-Item -ItemType Directory -Force -Path $vcpkgCache
|
||||
- nuget.exe sources add -Name kicad -Source "https://nuget.kicad.org:443/v3/index.json"
|
||||
- nuget.exe setapikey $env:KICAD_NUGET_KEY -Source "https://nuget.kicad.org:443/v3/index.json"
|
||||
- mkdir -p build/windows -Force
|
||||
- cd build/windows
|
||||
- cmake `
|
||||
-G "Ninja" `
|
||||
-DCMAKE_TOOLCHAIN_FILE=C:\build\vcpkg\scripts\buildsystems\vcpkg.cmake `
|
||||
-DCMAKE_TOOLCHAIN_FILE=C:\builder\vcpkg\scripts\buildsystems\vcpkg.cmake `
|
||||
-DCMAKE_BUILD_TYPE=Debug `
|
||||
-DKICAD_SCRIPTING_WXPYTHON=OFF `
|
||||
-DKICAD_USE_OCC=ON `
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
build_doxygen_docker:
|
||||
image: docker:stable
|
||||
services:
|
||||
- docker:dind
|
||||
stage: build
|
||||
tags:
|
||||
- docker
|
||||
before_script:
|
||||
- docker info
|
||||
- docker login -u gitlab-ci-token -p "$CI_BUILD_TOKEN" "$CI_REGISTRY"
|
||||
script:
|
||||
- docker build -t "${CI_REGISTRY_IMAGE}/doxygen:$CI_COMMIT_BRANCH" -f ./Documentation/doxygen.Dockerfile .
|
||||
- docker push "${CI_REGISTRY_IMAGE}/doxygen:$CI_COMMIT_BRANCH"
|
||||
only:
|
||||
refs:
|
||||
- schedules
|
||||
variables:
|
||||
- $SCHEDULED_JOB_NAME == "doxygen"
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2018-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2018-2022 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,7 +29,6 @@
|
||||
|
||||
#include <wx/datetime.h>
|
||||
#include <wx/dir.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/stdpaths.h>
|
||||
|
||||
@@ -55,6 +54,7 @@
|
||||
#include <project.h>
|
||||
#include <settings/common_settings.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <wx_filename.h>
|
||||
|
||||
|
||||
#define MASK_3D_CACHE "3D_CACHE"
|
||||
@@ -514,7 +514,7 @@ bool S3D_CACHE::Set3DConfigDir( const wxString& aConfigDir )
|
||||
|
||||
wxFileName cfgdir( ExpandEnvVarSubstitutions( aConfigDir, m_project ), wxEmptyString );
|
||||
|
||||
cfgdir.Normalize();
|
||||
cfgdir.Normalize( FN_NORMALIZE_FLAGS );
|
||||
|
||||
if( !cfgdir.DirExists() )
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020-2022 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,13 +29,13 @@
|
||||
|
||||
#include <wx/dir.h>
|
||||
#include <wx/dynlib.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <paths.h>
|
||||
#include <wx_filename.h>
|
||||
#include "3d_plugin_manager.h"
|
||||
#include "plugins/3d/3d_plugin.h"
|
||||
#include "3d_cache/sg/scenegraph.h"
|
||||
@@ -153,24 +153,14 @@ void S3D_PLUGIN_MANAGER::loadPlugins( void )
|
||||
|
||||
fn.AssignDir( PATHS::GetStockPlugins3DPath() );
|
||||
checkPluginPath( std::string( fn.GetPathWithSep().ToUTF8() ), searchpaths );
|
||||
|
||||
// check for per-user third party plugins
|
||||
// note: GetUserDataDir() gives '.pcbnew' rather than '.kicad' since it uses the exe name;
|
||||
fn.AssignDir( PATHS::GetUserPlugins3DPath() );
|
||||
checkPluginPath( fn.GetPathWithSep(), searchpaths );
|
||||
#else
|
||||
|
||||
// Search path on OS X is
|
||||
// (1) User ~/Library/Application Support/kicad/PlugIns/3d
|
||||
checkPluginPath( PATHS::GetOSXKicadUserDataDir() + wxT( "/PlugIns/3d" ), searchpaths );
|
||||
|
||||
// (2) Machine /Library/Application Support/kicad/PlugIns/3d
|
||||
// (1) Machine /Library/Application Support/kicad/PlugIns/3d
|
||||
checkPluginPath( PATHS::GetOSXKicadMachineDataDir() + wxT( "/PlugIns/3d" ), searchpaths );
|
||||
|
||||
// (3) Bundle kicad.app/Contents/PlugIns/3d
|
||||
// (2) Bundle kicad.app/Contents/PlugIns/3d
|
||||
fn.AssignDir( PATHS::GetStockPlugins3DPath() );
|
||||
checkPluginPath( fn.GetPathWithSep(), searchpaths );
|
||||
|
||||
#endif
|
||||
|
||||
std::list< wxString >::iterator sPL = searchpaths.begin();
|
||||
@@ -288,7 +278,7 @@ void S3D_PLUGIN_MANAGER::checkPluginName( const wxString& aPath,
|
||||
|
||||
wxFileName path( ExpandEnvVarSubstitutions( aPath, nullptr ) );
|
||||
|
||||
path.Normalize();
|
||||
path.Normalize( FN_NORMALIZE_FLAGS );
|
||||
|
||||
// determine if the path is already in the list
|
||||
wxString wxpath = path.GetFullPath();
|
||||
@@ -326,7 +316,7 @@ void S3D_PLUGIN_MANAGER::checkPluginPath( const wxString& aPath,
|
||||
else
|
||||
path.Assign( aPath, wxEmptyString );
|
||||
|
||||
path.Normalize();
|
||||
path.Normalize( FN_NORMALIZE_FLAGS );
|
||||
|
||||
if( !wxFileName::DirExists( path.GetFullPath() ) )
|
||||
return;
|
||||
|
||||
@@ -119,6 +119,7 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
|
||||
SetFlag( FL_ZONE, true );
|
||||
SetFlag( FL_SILKSCREEN, true );
|
||||
SetFlag( FL_SOLDERMASK, true );
|
||||
SetFlag( FL_SOLDERPASTE, true );
|
||||
SetFlag( FL_SUBTRACT_MASK_FROM_SILK, false );
|
||||
|
||||
SetFlag( FL_RENDER_OPENGL_COPPER_THICKNESS, true );
|
||||
|
||||
@@ -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-2022 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
|
||||
@@ -89,30 +89,32 @@ END_EVENT_TABLE()
|
||||
|
||||
EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList,
|
||||
BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera,
|
||||
S3D_CACHE* a3DCachePointer )
|
||||
: HIDPI_GL_CANVAS( aParent, wxID_ANY, aAttribList, wxDefaultPosition, wxDefaultSize,
|
||||
S3D_CACHE* a3DCachePointer ) :
|
||||
HIDPI_GL_CANVAS( aParent, wxID_ANY, aAttribList, wxDefaultPosition, wxDefaultSize,
|
||||
wxFULL_REPAINT_ON_RESIZE ),
|
||||
m_eventDispatcher( nullptr ),
|
||||
m_parentStatusBar( nullptr ),
|
||||
m_parentInfoBar( nullptr ),
|
||||
m_glRC( nullptr ),
|
||||
m_is_opengl_initialized( false ),
|
||||
m_is_opengl_version_supported( true ),
|
||||
m_mouse_is_moving( false ),
|
||||
m_mouse_was_moved( false ),
|
||||
m_camera_is_moving( false ),
|
||||
m_render_pivot( false ),
|
||||
m_camera_moving_speed( 1.0f ),
|
||||
m_strtime_camera_movement( 0 ),
|
||||
m_animation_enabled( true ),
|
||||
m_moving_speed_multiplier( 3 ),
|
||||
m_boardAdapter( aBoardAdapter ),
|
||||
m_camera( aCamera ),
|
||||
m_3d_render( nullptr ),
|
||||
m_opengl_supports_raytracing( true ),
|
||||
m_render_raytracing_was_requested( false ),
|
||||
m_accelerator3DShapes( nullptr ),
|
||||
m_currentRollOverItem( nullptr )
|
||||
m_eventDispatcher( nullptr ),
|
||||
m_parentStatusBar( nullptr ),
|
||||
m_parentInfoBar( nullptr ),
|
||||
m_glRC( nullptr ),
|
||||
m_is_opengl_initialized( false ),
|
||||
m_is_opengl_version_supported( true ),
|
||||
m_editing_timeout_timer( this, wxID_HIGHEST + 1 ),
|
||||
m_redraw_trigger_timer( this, wxID_HIGHEST + 2 ),
|
||||
m_mouse_is_moving( false ),
|
||||
m_mouse_was_moved( false ),
|
||||
m_camera_is_moving( false ),
|
||||
m_render_pivot( false ),
|
||||
m_camera_moving_speed( 1.0f ),
|
||||
m_strtime_camera_movement( 0 ),
|
||||
m_animation_enabled( true ),
|
||||
m_moving_speed_multiplier( 3 ),
|
||||
m_boardAdapter( aBoardAdapter ),
|
||||
m_camera( aCamera ),
|
||||
m_3d_render( nullptr ),
|
||||
m_opengl_supports_raytracing( true ),
|
||||
m_render_raytracing_was_requested( false ),
|
||||
m_accelerator3DShapes( nullptr ),
|
||||
m_currentRollOverItem( nullptr )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::EDA_3D_CANVAS" ) );
|
||||
|
||||
@@ -845,8 +847,14 @@ void EDA_3D_CANVAS::OnMiddleUp( wxMouseEvent& event )
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::OnTimerTimeout_Editing( wxTimerEvent& /* event */ )
|
||||
void EDA_3D_CANVAS::OnTimerTimeout_Editing( wxTimerEvent& aEvent )
|
||||
{
|
||||
if( aEvent.GetId() != m_editing_timeout_timer.GetId() )
|
||||
{
|
||||
aEvent.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
m_mouse_is_moving = false;
|
||||
m_mouse_was_moved = false;
|
||||
|
||||
@@ -867,8 +875,14 @@ void EDA_3D_CANVAS::restart_editingTimeOut_Timer()
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::OnTimerTimeout_Redraw( wxTimerEvent& event )
|
||||
void EDA_3D_CANVAS::OnTimerTimeout_Redraw( wxTimerEvent& aEvent )
|
||||
{
|
||||
if( aEvent.GetId() != m_redraw_trigger_timer.GetId() )
|
||||
{
|
||||
aEvent.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
Request_refresh( true );
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
* 3d models that come in the original data from the files without any transformations.
|
||||
*/
|
||||
|
||||
#include <gal/opengl/kiglew.h> // Must be included first
|
||||
#include <iostream>
|
||||
#include "3d_rendering/opengl/3d_model.h"
|
||||
#include "eda_3d_model_viewer.h"
|
||||
@@ -38,6 +39,7 @@
|
||||
#include <settings/common_settings.h>
|
||||
#include <pgm_base.h>
|
||||
#include <gal/dpi_scaling.h>
|
||||
#include <macros.h>
|
||||
|
||||
/**
|
||||
* Scale conversion from 3d model units to pcb units
|
||||
@@ -182,6 +184,20 @@ void EDA_3D_MODEL_VIEWER::Clear3DModel()
|
||||
|
||||
void EDA_3D_MODEL_VIEWER::ogl_initialize()
|
||||
{
|
||||
const GLenum err = glewInit();
|
||||
|
||||
if( GLEW_OK != err )
|
||||
{
|
||||
const wxString msgError = (const char*) glewGetErrorString( err );
|
||||
|
||||
wxLogMessage( msgError );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "EDA_3D_MODEL_VIEWER::ogl_initialize Using GLEW version %s" ),
|
||||
FROM_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
|
||||
}
|
||||
|
||||
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
|
||||
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
|
||||
glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
|
||||
|
||||
@@ -111,7 +111,7 @@ TOOL_ACTION EDA_3D_ACTIONS::resetView( "3DViewer.Control.resetView",
|
||||
|
||||
TOOL_ACTION EDA_3D_ACTIONS::flipView( "3DViewer.Control.flipView",
|
||||
AS_ACTIVE,
|
||||
0, "",
|
||||
'F', "",
|
||||
_( "Flip Board" ), _( "Flip the board view" ),
|
||||
BITMAPS::flip_board, AF_NONE, (void*) ID_VIEW3D_FLIP );
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2022 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
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <common_ogl/ogl_attr_list.h>
|
||||
#include <filename_resolver.h>
|
||||
#include <pcbnew/footprint.h>
|
||||
#include <wx_filename.h>
|
||||
|
||||
#include <wx/filedlg.h>
|
||||
|
||||
@@ -164,7 +165,7 @@ bool DIALOG_SELECT_3DMODEL::TransferDataFromWindow()
|
||||
// file selection mode: retrieve the filename and specify a
|
||||
// path relative to one of the config paths
|
||||
wxFileName fname = m_FileTree->GetFilePath();
|
||||
fname.Normalize();
|
||||
fname.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
|
||||
m_model->m_Filename = m_resolver->ShortenPath( fname.GetFullPath() );
|
||||
|
||||
return true;
|
||||
|
||||
@@ -38,8 +38,8 @@ macro( create_git_version_header _git_src_path )
|
||||
${GIT_EXECUTABLE} describe --dirty
|
||||
WORKING_DIRECTORY ${_git_src_path}
|
||||
OUTPUT_VARIABLE _git_DESCRIBE
|
||||
ERROR_VARIABLE _git_log_error
|
||||
RESULT_VARIABLE _git_log_result
|
||||
ERROR_VARIABLE _git_describe_error
|
||||
RESULT_VARIABLE _git_describe_result
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process(
|
||||
@@ -47,8 +47,8 @@ macro( create_git_version_header _git_src_path )
|
||||
${GIT_EXECUTABLE} rev-list --count --first-parent HEAD
|
||||
WORKING_DIRECTORY ${_git_src_path}
|
||||
OUTPUT_VARIABLE _git_REV_COUNT
|
||||
ERROR_VARIABLE _git_log_error
|
||||
RESULT_VARIABLE _git_log_result
|
||||
ERROR_VARIABLE _git_rev_count_error
|
||||
RESULT_VARIABLE _git_rev_count_result
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
set( ENV{LC_ALL} ${_Git_SAVED_LC_ALL} )
|
||||
@@ -56,11 +56,11 @@ macro( create_git_version_header _git_src_path )
|
||||
|
||||
# Check to make sure 'git' command did not fail. Otherwise fallback
|
||||
# to KiCadVersion.cmake as the revision level.
|
||||
if( _git_DESCRIBE )
|
||||
if( _git_describe_result EQUAL 0 )
|
||||
set( KICAD_VERSION "(${_git_DESCRIBE})" )
|
||||
endif()
|
||||
|
||||
if( _git_REV_COUNT )
|
||||
if( _git_rev_count_result EQUAL 0 )
|
||||
set( KICAD_GIT_REV "${_git_REV_COUNT}" )
|
||||
|
||||
# Sanity check
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# This program source code file is part of KICAD, a free EDA CAD application.
|
||||
#
|
||||
# Copyright (C) 2016 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
# Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
# Copyright (C) 2016-2023 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
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "6.0.6-unknown" )
|
||||
set( KICAD_SEMANTIC_VERSION "6.0.11-unknown" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
FROM registry.gitlab.com/kicad/kicad-ci/source_containers/master/ubuntu:22.04 as build-doxygen-env
|
||||
USER root
|
||||
|
||||
WORKDIR /src
|
||||
COPY . ./
|
||||
|
||||
RUN ls
|
||||
RUN mkdir build && cd build
|
||||
|
||||
WORKDIR /src/build
|
||||
|
||||
RUN cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DKICAD_USE_OCC=ON \
|
||||
-DKICAD_SCRIPTING_WXPYTHON=ON \
|
||||
-DKICAD_SPICE=ON
|
||||
RUN make doxygen-docs
|
||||
RUN make doxygen-python
|
||||
|
||||
|
||||
FROM scratch as output-image
|
||||
|
||||
COPY --from=build-doxygen-env /src/Documentation/doxygen/html /doxygen-docs_html
|
||||
COPY --from=build-doxygen-env /src/build/pcbnew/doxygen-python/html /doxygen-python_html
|
||||
@@ -0,0 +1,6 @@
|
||||
doxygen.Dockerfile.dockerignore.git
|
||||
.gitlab
|
||||
.github
|
||||
.idea
|
||||
.vs
|
||||
build
|
||||
@@ -503,21 +503,22 @@ void BITMAPCONV_INFO::createOutputData( BMP2CMP_MOD_LAYER aModLayer )
|
||||
polyset_areas.BooleanSubtract( polyset_holes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
|
||||
// Ensure there are no self intersecting polygons
|
||||
polyset_areas.NormalizeAreaOutlines();
|
||||
|
||||
// Convert polygon with holes to a unique polygon
|
||||
polyset_areas.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
|
||||
// Output current resulting polygon(s)
|
||||
for( int ii = 0; ii < polyset_areas.OutlineCount(); ii++ )
|
||||
if( polyset_areas.NormalizeAreaOutlines() )
|
||||
{
|
||||
SHAPE_LINE_CHAIN& poly = polyset_areas.Outline( ii );
|
||||
outputOnePolygon( poly, getBoardLayerName( aModLayer ));
|
||||
}
|
||||
// Convert polygon with holes to a unique polygon
|
||||
polyset_areas.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
|
||||
polyset_areas.RemoveAllContours();
|
||||
polyset_holes.RemoveAllContours();
|
||||
main_outline = true;
|
||||
// Output current resulting polygon(s)
|
||||
for( int ii = 0; ii < polyset_areas.OutlineCount(); ii++ )
|
||||
{
|
||||
SHAPE_LINE_CHAIN& poly = polyset_areas.Outline( ii );
|
||||
outputOnePolygon( poly, getBoardLayerName( aModLayer ));
|
||||
}
|
||||
|
||||
polyset_areas.RemoveAllContours();
|
||||
polyset_holes.RemoveAllContours();
|
||||
main_outline = true;
|
||||
}
|
||||
}
|
||||
|
||||
paths = paths->next;
|
||||
|
||||
@@ -82,13 +82,6 @@ static const wxChar DRCEpsilon[] = wxT( "DRCEpsilon" );
|
||||
*/
|
||||
static const wxChar HoleWallThickness[] = wxT( "HoleWallPlatingThickness" );
|
||||
|
||||
/**
|
||||
* Testing mode for new connectivity algorithm. Setting this to on will cause all modifications
|
||||
* to the netlist to be recalculated on the fly. This may be slower than the standard process
|
||||
* at the moment
|
||||
*/
|
||||
static const wxChar RealtimeConnectivity[] = wxT( "RealtimeConnectivity" );
|
||||
|
||||
/**
|
||||
* Configure the coroutine stack size in bytes. This should be allocated in multiples of
|
||||
* the system page size (n*4096 is generally safe)
|
||||
@@ -260,7 +253,6 @@ ADVANCED_CFG::ADVANCED_CFG()
|
||||
|
||||
// Init defaults - this is done in case the config doesn't exist,
|
||||
// then the values will remain as set here.
|
||||
m_RealTimeConnectivity = true;
|
||||
m_CoroutineStackSize = AC_STACK::default_stack;
|
||||
m_ShowRouterDebugGraphics = false;
|
||||
m_DrawArcAccuracy = 10.0;
|
||||
@@ -333,9 +325,6 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
|
||||
{
|
||||
std::vector<PARAM_CFG*> configParams;
|
||||
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::RealtimeConnectivity,
|
||||
&m_RealTimeConnectivity, m_RealTimeConnectivity ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::ExtraFillMargin,
|
||||
&m_ExtraClearance, m_ExtraClearance, 0.0, 1.0 ) );
|
||||
|
||||
|
||||
@@ -121,6 +121,13 @@ wxBitmap KiBitmap( const BITMAP_OPAQUE* aBitmap )
|
||||
|
||||
int KiIconScale( wxWindow* aWindow )
|
||||
{
|
||||
#if defined( __WXMSW__) && wxCHECK_VERSION( 3, 1, 6 )
|
||||
// Basically don't try and scale within kicad and let wx do its thing
|
||||
// with wx introducing bitmap bundles, it will auto scale automatically with dpi
|
||||
// the issue is, none of the scaling factors have any tie to system scaling
|
||||
// this means wx is actually going to scale again causing even more distorted icons
|
||||
return 4;
|
||||
#else
|
||||
const int vert_size = aWindow->ConvertDialogToPixels( wxSize( 0, 8 ) ).y;
|
||||
|
||||
// Autoscale won't exceed unity until the system has quite high resolution,
|
||||
@@ -131,6 +138,7 @@ int KiIconScale( wxWindow* aWindow )
|
||||
else if( vert_size > 29 ) return 7;
|
||||
else if( vert_size > 24 ) return 6;
|
||||
else return 4;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -251,6 +251,16 @@ void BITMAP_BASE::DrawBitmap( wxDC* aDC, const wxPoint& aPos )
|
||||
aDC->GetLogicalOrigin( &logicalOriginX, &logicalOriginY );
|
||||
|
||||
bool useTransform = aDC->CanUseTransformMatrix();
|
||||
|
||||
// We already have issues to draw a bitmap on the wxDC, depending on wxWidgets version.
|
||||
// Now we have an issue on wxWidgets 3.1.6 and later to fix the clipboard
|
||||
// and the bitmap position when using TransformMatrix
|
||||
// So for version >= 3.1.6 do not use it
|
||||
// Be carefull before changing the code.
|
||||
#if wxCHECK_VERSION( 3, 1, 6 )
|
||||
useTransform = false;
|
||||
#endif
|
||||
|
||||
wxAffineMatrix2D init_matrix = aDC->GetTransformMatrix();
|
||||
|
||||
wxPoint clipAreaPos;
|
||||
@@ -261,8 +271,12 @@ void BITMAP_BASE::DrawBitmap( wxDC* aDC, const wxPoint& aPos )
|
||||
matrix.Translate( pos.x, pos.y );
|
||||
matrix.Scale( GetScalingFactor(), GetScalingFactor() );
|
||||
aDC->SetTransformMatrix( matrix );
|
||||
// Needed on wx <= 3.1.5, and this is strange...
|
||||
// Nevertheless, this code has problem (the bitmap is not seen)
|
||||
// with wx version > 3.1.5
|
||||
clipAreaPos.x = pos.x;
|
||||
clipAreaPos.y = pos.y;
|
||||
|
||||
pos.x = pos.y = 0;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -136,6 +136,9 @@ void BOARD_PRINTOUT::DrawPage( const wxString& aLayerName, int aPageNum, int aPa
|
||||
|
||||
setupPainter( *painter );
|
||||
setupViewLayers( *view, m_settings.m_LayerSet );
|
||||
dstSettings->SetPrintLayers( m_settings.m_LayerSet );
|
||||
|
||||
dstSettings->SetLayerName( aLayerName );
|
||||
|
||||
wxSize sheetSizeMils = m_settings.m_pageInfo.GetSizeMils();
|
||||
VECTOR2I sheetSizeIU( milsToIU( sheetSizeMils.GetWidth() ),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -396,13 +396,18 @@ void DIALOG_COLOR_PICKER::drawRGBPalette()
|
||||
|
||||
// Use Y axis from bottom to top and origin to center
|
||||
bitmapDC.SetAxisOrientation( true, true );
|
||||
#if wxCHECK_VERSION( 3, 1, 7 )
|
||||
// For some reason, SetDeviceOrigin has changed in wxWidgets 3.1.6 or 3.1.7
|
||||
bitmapDC.SetDeviceOrigin( half_size, -half_size );
|
||||
#else
|
||||
bitmapDC.SetDeviceOrigin( half_size, half_size );
|
||||
#endif
|
||||
|
||||
// Reserve room to draw cursors inside the bitmap
|
||||
half_size -= m_cursorsSize/2;
|
||||
|
||||
// Draw the 3 RGB cursors, using white color to make them always visible:
|
||||
wxPen pen( wxColor( 255, 255, 255 ) );
|
||||
wxPen pen( wxColor( 255, 255, 255 ), 2 ); // use 2 pixels for pen size
|
||||
wxBrush brush( wxColor( 0, 0, 0 ), wxBRUSHSTYLE_TRANSPARENT );
|
||||
bitmapDC.SetPen( pen );
|
||||
bitmapDC.SetBrush( brush );
|
||||
@@ -461,7 +466,12 @@ void DIALOG_COLOR_PICKER::drawHSVPalette()
|
||||
|
||||
// Use Y axis from bottom to top and origin to center
|
||||
bitmapDC.SetAxisOrientation( true, true );
|
||||
#if wxCHECK_VERSION( 3, 1, 7 )
|
||||
// For some reason, SetDeviceOrigin has changed in wxWidgets 3.1.6 or 3.1.7
|
||||
bitmapDC.SetDeviceOrigin( half_size, -half_size );
|
||||
#else
|
||||
bitmapDC.SetDeviceOrigin( half_size, half_size );
|
||||
#endif
|
||||
|
||||
// Reserve room to draw cursors inside the bitmap
|
||||
half_size -= m_cursorsSize / 2;
|
||||
@@ -470,7 +480,7 @@ void DIALOG_COLOR_PICKER::drawHSVPalette()
|
||||
m_cursorBitmapHSV.x = cos( m_hue * M_PI / 180.0 ) * half_size * m_sat;
|
||||
m_cursorBitmapHSV.y = sin( m_hue * M_PI / 180.0 ) * half_size * m_sat;
|
||||
|
||||
wxPen pen( wxColor( 0, 0, 0 ) );
|
||||
wxPen pen( wxColor( 0, 0, 0 ), 2 ); // Use 2 pixels as pensize
|
||||
wxBrush brush( wxColor( 0, 0, 0 ), wxBRUSHSTYLE_TRANSPARENT );
|
||||
bitmapDC.SetPen( pen );
|
||||
bitmapDC.SetBrush( brush );
|
||||
|
||||
@@ -45,6 +45,8 @@ DIALOG_PASTE_SPECIAL::DIALOG_PASTE_SPECIAL( wxWindow* aParent,
|
||||
"with '%s'." ),
|
||||
aReplacement ) );
|
||||
|
||||
m_sdbSizerOK->SetFocus();
|
||||
|
||||
// Now all widgets have the size fixed, call FinishDialogSettings
|
||||
finishDialogSettings();
|
||||
}
|
||||
|
||||
@@ -40,10 +40,11 @@ static int DEFAULT_COL_WIDTHS[] = { 200, 600 };
|
||||
EDA_LIST_DIALOG::EDA_LIST_DIALOG( wxWindow* aParent, const wxString& aTitle,
|
||||
const wxArrayString& aItemHeaders,
|
||||
const std::vector<wxArrayString>& aItemList,
|
||||
const wxString& aPreselectText ) :
|
||||
const wxString& aPreselectText, bool aSortList ) :
|
||||
EDA_LIST_DIALOG_BASE( aParent, wxID_ANY, aTitle )
|
||||
{
|
||||
m_itemsList = &aItemList;
|
||||
m_sortList = aSortList;
|
||||
|
||||
m_filterBox->SetHint( _( "Filter" ) );
|
||||
|
||||
@@ -234,5 +235,6 @@ static int wxCALLBACK myCompareFunction( wxIntPtr aItem1, wxIntPtr aItem2,
|
||||
|
||||
void EDA_LIST_DIALOG::sortList()
|
||||
{
|
||||
m_listBox->SortItems( myCompareFunction, 0 );
|
||||
if( m_sortList )
|
||||
m_listBox->SortItems( myCompareFunction, 0 );
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ static void netclassToGridRow( EDA_UNITS aUnits, wxGrid* aGrid, int aRow, const
|
||||
SET_MILS_CELL( GRID_WIREWIDTH, nc->GetWireWidth() );
|
||||
SET_MILS_CELL( GRID_BUSWIDTH, nc->GetBusWidth() );
|
||||
|
||||
wxString colorAsString = nc->GetSchematicColor().ToWxString( wxC2S_CSS_SYNTAX );
|
||||
wxString colorAsString = nc->GetSchematicColor().ToCSSString();
|
||||
aGrid->SetCellValue( aRow, GRID_SCHEMATIC_COLOR, colorAsString );
|
||||
|
||||
int lineStyleIdx = std::max( 0, nc->GetLineStyle() );
|
||||
|
||||
@@ -174,6 +174,11 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::DoRePaint()
|
||||
{
|
||||
if( !m_refreshMutex.try_lock() )
|
||||
return;
|
||||
|
||||
std::lock_guard<std::mutex> lock( m_refreshMutex, std::adopt_lock );
|
||||
|
||||
// Repaint the canvas, and fix scrollbar cursors
|
||||
// Usually called by a OnPaint event, but because it does not use a wxPaintDC,
|
||||
// it can be called outside a wxPaintEvent.
|
||||
|
||||
@@ -83,6 +83,7 @@ void DS_PROXY_VIEW_ITEM::buildDrawList( VIEW* aView, DS_DRAW_ITEM_LIST* aDrawLis
|
||||
aDrawList->SetSheetCount( m_sheetCount );
|
||||
aDrawList->SetFileName( fileName );
|
||||
aDrawList->SetSheetName( sheetName );
|
||||
aDrawList->SetSheetLayer( settings->GetLayerName() );
|
||||
aDrawList->SetProject( m_project );
|
||||
|
||||
aDrawList->BuildDrawItemsList( *m_pageInfo, *m_titleBlock );
|
||||
|
||||
+17
-17
@@ -969,22 +969,27 @@ bool EDA_DRAW_FRAME::LibraryFileBrowser( bool doOpen, wxFileName& aFilename,
|
||||
wxString prompt = doOpen ? _( "Select Library" ) : _( "New Library" );
|
||||
aFilename.SetExt( ext );
|
||||
|
||||
wxString dir;
|
||||
wxString projectDir = Prj().IsNullProject() ? aFilename.GetPath() : Prj().GetProjectPath();
|
||||
wxString defaultDir;
|
||||
|
||||
if( GetMruPath().IsEmpty() )
|
||||
dir = aGlobalPath;
|
||||
if( aIsGlobal )
|
||||
{
|
||||
if( !GetMruPath().IsEmpty() && !GetMruPath().StartsWith( projectDir ) )
|
||||
defaultDir = GetMruPath();
|
||||
else
|
||||
defaultDir = aGlobalPath;
|
||||
}
|
||||
else
|
||||
dir = GetMruPath();
|
||||
|
||||
{
|
||||
if( !GetMruPath().IsEmpty() && GetMruPath().StartsWith( projectDir ) )
|
||||
defaultDir = GetMruPath();
|
||||
else
|
||||
defaultDir = projectDir;
|
||||
}
|
||||
|
||||
if( isDirectory && doOpen )
|
||||
{
|
||||
if( !aIsGlobal && GetMruPath().IsEmpty() )
|
||||
{
|
||||
dir = Prj().GetProjectPath();
|
||||
}
|
||||
|
||||
wxDirDialog dlg( this, prompt, dir, wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );
|
||||
wxDirDialog dlg( this, prompt, defaultDir, wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );
|
||||
|
||||
if( dlg.ShowModal() == wxID_CANCEL )
|
||||
return false;
|
||||
@@ -998,12 +1003,7 @@ bool EDA_DRAW_FRAME::LibraryFileBrowser( bool doOpen, wxFileName& aFilename,
|
||||
if( aFilename.GetName().empty() )
|
||||
aFilename.SetName( wxT( "Library" ) );
|
||||
|
||||
if( !aIsGlobal && GetMruPath().IsEmpty() )
|
||||
{
|
||||
dir = Prj().IsNullProject() ? aFilename.GetFullPath() : Prj().GetProjectPath();
|
||||
}
|
||||
|
||||
wxFileDialog dlg( this, prompt, dir, aFilename.GetFullName(),
|
||||
wxFileDialog dlg( this, prompt, defaultDir, aFilename.GetFullName(),
|
||||
wildcard, doOpen ? wxFD_OPEN | wxFD_FILE_MUST_EXIST
|
||||
: wxFD_SAVE | wxFD_CHANGE_DIR | wxFD_OVERWRITE_PROMPT );
|
||||
|
||||
|
||||
@@ -365,7 +365,7 @@ void EDA_SHAPE::flip( const wxPoint& aCentre, bool aFlipLeftRight )
|
||||
|
||||
void EDA_SHAPE::RebuildBezierToSegmentsPointsList( int aMinSegLen )
|
||||
{
|
||||
// Has meaning only for S_CURVE DRAW_SEGMENT shape
|
||||
// Has meaning only for SHAPE_T::BEZIER
|
||||
if( m_shape != SHAPE_T::BEZIER )
|
||||
{
|
||||
m_bezierPoints.clear();
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
|
||||
#include <wx/filename.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <pgm_base.h>
|
||||
@@ -34,6 +33,7 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "filename_resolver.h"
|
||||
#include <wx_filename.h>
|
||||
|
||||
// configuration file version
|
||||
#define CFGFILE_VERSION 1
|
||||
@@ -66,7 +66,7 @@ bool FILENAME_RESOLVER::Set3DConfigDir( const wxString& aConfigDir )
|
||||
|
||||
wxFileName cfgdir( ExpandEnvVarSubstitutions( aConfigDir, m_project ), wxEmptyString );
|
||||
|
||||
cfgdir.Normalize();
|
||||
cfgdir.Normalize( FN_NORMALIZE_FLAGS );
|
||||
|
||||
if( !cfgdir.DirExists() )
|
||||
return false;
|
||||
@@ -87,7 +87,7 @@ bool FILENAME_RESOLVER::SetProject( PROJECT* aProject, bool* flgChanged )
|
||||
|
||||
wxFileName projdir( ExpandEnvVarSubstitutions( aProject->GetProjectPath(), aProject ), wxEmptyString );
|
||||
|
||||
projdir.Normalize();
|
||||
projdir.Normalize( FN_NORMALIZE_FLAGS );
|
||||
|
||||
if( !projdir.DirExists() )
|
||||
return false;
|
||||
@@ -189,7 +189,7 @@ bool FILENAME_RESOLVER::createPathList()
|
||||
else
|
||||
{
|
||||
fndummy.Assign( pathVal, wxEmptyString );
|
||||
fndummy.Normalize();
|
||||
fndummy.Normalize( FN_NORMALIZE_FLAGS );
|
||||
lpath.m_Pathexp = fndummy.GetFullPath();
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName )
|
||||
// working directory (which is not necessarily the current project directory)
|
||||
if( tmpFN.FileExists() )
|
||||
{
|
||||
tmpFN.Normalize();
|
||||
tmpFN.Normalize( FN_NORMALIZE_FLAGS );
|
||||
tname = tmpFN.GetFullPath();
|
||||
|
||||
// special case: if a path begins with ${ENV_VAR} but is not in the resolver's path list
|
||||
@@ -316,7 +316,7 @@ wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName )
|
||||
if( wxFileName::FileExists( fullPath ) )
|
||||
{
|
||||
tmpFN.Assign( fullPath );
|
||||
tmpFN.Normalize();
|
||||
tmpFN.Normalize( FN_NORMALIZE_FLAGS );
|
||||
tname = tmpFN.GetFullPath();
|
||||
return tname;
|
||||
}
|
||||
@@ -333,7 +333,7 @@ wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName )
|
||||
fullPath = ExpandEnvVarSubstitutions( fullPath, m_project );
|
||||
fpath.Assign( fullPath );
|
||||
|
||||
if( fpath.Normalize() && fpath.FileExists() )
|
||||
if( fpath.Normalize( FN_NORMALIZE_FLAGS ) && fpath.FileExists() )
|
||||
{
|
||||
tname = fpath.GetFullPath();
|
||||
return tname;
|
||||
@@ -381,7 +381,7 @@ wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName )
|
||||
|
||||
wxFileName tmp( fullPath );
|
||||
|
||||
if( tmp.Normalize() )
|
||||
if( tmp.Normalize( FN_NORMALIZE_FLAGS ) )
|
||||
tname = tmp.GetFullPath();
|
||||
|
||||
return tname;
|
||||
@@ -422,7 +422,7 @@ bool FILENAME_RESOLVER::addPath( const SEARCH_PATH& aPath )
|
||||
|
||||
wxFileName path( ExpandEnvVarSubstitutions( tpath.m_Pathvar, m_project ), wxEmptyString );
|
||||
|
||||
path.Normalize();
|
||||
path.Normalize( FN_NORMALIZE_FLAGS );
|
||||
|
||||
if( !path.DirExists() )
|
||||
{
|
||||
@@ -496,7 +496,11 @@ bool FILENAME_RESOLVER::readPathList()
|
||||
}
|
||||
|
||||
wxFileName cfgpath( m_configDir, RESOLVER_CONFIG );
|
||||
cfgpath.Normalize();
|
||||
|
||||
// This should be the same as wxWidgets 3.0 wxPATH_NORM_ALL which is deprecated in 3.1.
|
||||
// There are known issues with environment variable expansion so maybe we should be using
|
||||
// our own ExpandEnvVarSubstitutions() here instead.
|
||||
cfgpath.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
|
||||
wxString cfgname = cfgpath.GetFullPath();
|
||||
|
||||
size_t nitems = m_paths.size();
|
||||
@@ -716,7 +720,7 @@ void FILENAME_RESOLVER::checkEnvVarPath( const wxString& aPath )
|
||||
wxFileName tmpFN( ExpandEnvVarSubstitutions( lpath.m_Alias, m_project ), wxEmptyString );
|
||||
|
||||
wxUniChar psep = tmpFN.GetPathSeparator();
|
||||
tmpFN.Normalize();
|
||||
tmpFN.Normalize( FN_NORMALIZE_FLAGS );
|
||||
|
||||
if( !tmpFN.DirExists() )
|
||||
return;
|
||||
|
||||
+27
-4
@@ -144,10 +144,33 @@ bool COLOR4D::SetFromWxString( const wxString& aColorString )
|
||||
}
|
||||
|
||||
|
||||
wxString COLOR4D::ToWxString( long flags ) const
|
||||
wxString COLOR4D::ToCSSString() const
|
||||
{
|
||||
wxColour c = ToColour();
|
||||
return c.GetAsString( flags );
|
||||
wxString str;
|
||||
|
||||
const int red = c.Red();
|
||||
const int green = c.Green();
|
||||
const int blue = c.Blue();
|
||||
const int alpha = c.Alpha();
|
||||
|
||||
if ( alpha == wxALPHA_OPAQUE )
|
||||
{
|
||||
str.Printf( wxT( "rgb(%d, %d, %d)" ), red, green, blue );
|
||||
}
|
||||
else // use rgba() form
|
||||
{
|
||||
wxString alpha_str = wxString::FromCDouble( alpha / 255.0, 3 );
|
||||
|
||||
// The wxC2S_CSS_SYNTAX is particularly sensitive to ','s (as it uses them for value
|
||||
// delimiters), and wxWidgets is known to be buggy in this respect when dealing with
|
||||
// Serbian and Russian locales (at least), so we enforce an extra level of safety.
|
||||
alpha_str.Replace( wxT( "," ), wxT( "." ) );
|
||||
|
||||
str.Printf( wxT( "rgba(%d, %d, %d, %s)" ), red, green, blue, alpha_str );
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@@ -271,13 +294,13 @@ const bool operator<( const COLOR4D& lhs, const COLOR4D& rhs )
|
||||
|
||||
std::ostream &operator<<( std::ostream &aStream, COLOR4D const &aColor )
|
||||
{
|
||||
return aStream << aColor.ToWxString( wxC2S_CSS_SYNTAX );
|
||||
return aStream << aColor.ToCSSString();
|
||||
}
|
||||
|
||||
|
||||
void to_json( nlohmann::json& aJson, const COLOR4D& aColor )
|
||||
{
|
||||
aJson = nlohmann::json( aColor.ToWxString( wxC2S_CSS_SYNTAX ).ToStdString() );
|
||||
aJson = nlohmann::json( aColor.ToCSSString().ToStdString() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
+6
-8
@@ -41,14 +41,11 @@
|
||||
static std::mutex rng_mutex;
|
||||
|
||||
// Static rng and generators are used because the overhead of constant seeding is expensive
|
||||
// We break out the rng separately from the generator because we want to control seeding in cases like unit tests
|
||||
#if BOOST_VERSION >= 106700
|
||||
static boost::uuids::detail::random_provider seeder; // required to ensure the rng has a random initial seed
|
||||
#else
|
||||
static boost::uuids::detail::seed_rng seeder; // required to ensure the rng has a random initial seed
|
||||
#endif
|
||||
static boost::mt19937 rng( seeder );
|
||||
static boost::uuids::basic_random_generator<boost::mt19937> randomGenerator( rng );
|
||||
// We rely on the default non-arg constructor of basic_random_generator to provide a random seed.
|
||||
// We use a separate rng object for cases where we want to control the basic_random_generator
|
||||
// initial seed by calling SeedGenerator from unit tests and other special cases.
|
||||
static boost::mt19937 rng;
|
||||
static boost::uuids::basic_random_generator<boost::mt19937> randomGenerator;
|
||||
|
||||
// These don't have the same performance penalty, but we might as well be consistent
|
||||
static boost::uuids::string_generator stringGenerator;
|
||||
@@ -279,6 +276,7 @@ void KIID::CreateNilUuids( bool aNil )
|
||||
void KIID::SeedGenerator( unsigned int aSeed )
|
||||
{
|
||||
rng.seed( aSeed );
|
||||
randomGenerator = boost::uuids::basic_random_generator<boost::mt19937>( rng );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -465,7 +465,10 @@ bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce )
|
||||
return true;
|
||||
|
||||
if( frame->NonUserClose( doForce ) )
|
||||
{
|
||||
m_playerFrameId[aFrameType] = wxID_NONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
+14
-1
@@ -31,6 +31,7 @@
|
||||
#include <typeinfo>
|
||||
#include <wx/utils.h>
|
||||
#include <wx/evtloop.h>
|
||||
#include <wx/socket.h>
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE( KIWAY_PLAYER, EDA_BASE_FRAME )
|
||||
@@ -65,7 +66,19 @@ KIWAY_PLAYER::KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& a
|
||||
}
|
||||
|
||||
|
||||
KIWAY_PLAYER::~KIWAY_PLAYER() throw() {}
|
||||
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
|
||||
if( m_socketServer )
|
||||
{
|
||||
// ensure any event handling stops
|
||||
m_socketServer->Notify( false );
|
||||
|
||||
delete m_socketServer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent )
|
||||
|
||||
@@ -77,7 +77,7 @@ NUMERIC_EVALUATOR::~NUMERIC_EVALUATOR()
|
||||
|
||||
void NUMERIC_EVALUATOR::Clear()
|
||||
{
|
||||
free( m_token.token );
|
||||
delete[] m_token.token;
|
||||
m_token.token = nullptr;
|
||||
m_token.input = nullptr;
|
||||
m_parseError = true;
|
||||
@@ -103,7 +103,7 @@ void NUMERIC_EVALUATOR::parseSetResult( double val )
|
||||
{
|
||||
// Naively printing this with %g produces "nan" on some platforms
|
||||
// and "-nan(ind)" on others (e.g. MSVC). So force a "standard" string.
|
||||
snprintf( m_token.token, m_token.OutLen, "%s", "NaN" );
|
||||
snprintf( m_token.token, m_token.outputLen, "%s", "NaN" );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -111,7 +111,7 @@ void NUMERIC_EVALUATOR::parseSetResult( double val )
|
||||
// Warning: DO NOT use a format like %f or %g, because they can create issues.
|
||||
// especially %g can generate an exponent, incompatible with UNIT_BINDER
|
||||
// Use the optimized Double2Str
|
||||
snprintf( m_token.token, m_token.OutLen, "%s", Double2Str( val ).c_str() );
|
||||
snprintf( m_token.token, m_token.outputLen, "%s", Double2Str( val ).c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,12 +159,12 @@ void NUMERIC_EVALUATOR::newString( const wxString& aString )
|
||||
Clear();
|
||||
|
||||
m_originalText = aString;
|
||||
|
||||
m_token.token = reinterpret_cast<decltype( m_token.token )>( malloc( TokenStat::OutLen + 1 ) );
|
||||
strcpy( m_token.token, "0" );
|
||||
m_token.inputLen = aString.length();
|
||||
m_token.outputLen = std::max<std::size_t>( 64, m_token.inputLen + 1 );
|
||||
m_token.pos = 0;
|
||||
m_token.input = aString.mb_str();
|
||||
m_token.token = new char[m_token.outputLen]();
|
||||
m_token.token[0] = '0';
|
||||
|
||||
m_parseFinished = false;
|
||||
}
|
||||
|
||||
@@ -249,6 +249,7 @@ COMPILER::~COMPILER()
|
||||
if( m_tree )
|
||||
{
|
||||
freeTree( m_tree );
|
||||
m_tree = nullptr;
|
||||
}
|
||||
|
||||
// Allow explicit call to destructor
|
||||
@@ -693,6 +694,7 @@ void COMPILER::freeTree( LIBEVAL::TREE_NODE *tree )
|
||||
freeTree( tree->leaf[1] );
|
||||
|
||||
delete tree->uop;
|
||||
tree->uop = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -1006,10 +1008,13 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Printf( _( "Missing units for '%s'| (%s)" ),
|
||||
*node->value.str,
|
||||
m_unitResolver->GetSupportedUnitsMessage() );
|
||||
reportError( CST_CODEGEN, msg, node->srcPos );
|
||||
if( !m_unitResolver->GetSupportedUnitsMessage().empty() )
|
||||
{
|
||||
msg.Printf( _( "Missing units for '%s'| (%s)" ),
|
||||
*node->value.str,
|
||||
m_unitResolver->GetSupportedUnitsMessage() );
|
||||
reportError( CST_CODEGEN, msg, node->srcPos );
|
||||
}
|
||||
|
||||
value = DoubleValueFromString( EDA_UNITS::UNSCALED, *node->value.str );
|
||||
}
|
||||
@@ -1038,7 +1043,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
reportError( CST_CODEGEN, msg, node->srcPos - (int) node->value.str->length() );
|
||||
}
|
||||
|
||||
node->SetUop( TR_UOP_PUSH_VALUE, std::move( vref ) );
|
||||
node->SetUop( TR_UOP_PUSH_VAR, std::move( vref ) );
|
||||
node->isTerminal = true;
|
||||
break;
|
||||
}
|
||||
@@ -1090,10 +1095,12 @@ void UOP::Exec( CONTEXT* ctx )
|
||||
{
|
||||
case TR_UOP_PUSH_VAR:
|
||||
{
|
||||
VALUE* value = ctx->AllocValue();
|
||||
VALUE* value = nullptr;
|
||||
|
||||
if( m_ref )
|
||||
value->Set( m_ref->GetValue( ctx ) );
|
||||
value = ctx->StoreValue( m_ref->GetValue( ctx ) );
|
||||
else
|
||||
value = ctx->AllocValue();
|
||||
|
||||
ctx->Push( value );
|
||||
}
|
||||
@@ -1162,10 +1169,20 @@ void UOP::Exec( CONTEXT* ctx )
|
||||
result = arg1Value > arg2Value ? 1 : 0;
|
||||
break;
|
||||
case TR_OP_EQUAL:
|
||||
result = arg1 && arg2 && arg1->EqualTo( ctx, arg2 ) ? 1 : 0;
|
||||
if( !arg1 || !arg2 )
|
||||
result = arg1 == arg2 ? 1 : 0;
|
||||
else if( arg2->GetType() == VT_UNDEFINED )
|
||||
result = arg2->EqualTo( ctx, arg1 ) ? 1 : 0;
|
||||
else
|
||||
result = arg1->EqualTo( ctx, arg2 ) ? 1 : 0;
|
||||
break;
|
||||
case TR_OP_NOT_EQUAL:
|
||||
result = arg1 && arg2 && arg1->NotEqualTo( ctx, arg2 ) ? 1 : 0;
|
||||
if( !arg1 || !arg2 )
|
||||
result = arg1 != arg2 ? 1 : 0;
|
||||
else if( arg2->GetType() == VT_UNDEFINED )
|
||||
result = arg2->NotEqualTo( ctx, arg1 ) ? 1 : 0;
|
||||
else
|
||||
result = arg1->NotEqualTo( ctx, arg2 ) ? 1 : 0;
|
||||
break;
|
||||
case TR_OP_BOOL_AND:
|
||||
result = arg1Value != 0.0 && arg2Value != 0.0 ? 1 : 0;
|
||||
|
||||
@@ -8635,7 +8635,7 @@ const char* const newstroke_font[] =
|
||||
"F^K[KFYFY[K[",
|
||||
"F^K[KFYFY[K[",
|
||||
"F^K[KFYFY[K[",
|
||||
/* // Letterlike Symbols (2100-214F) */
|
||||
/* // Letterlike Symbols (2100-2125) */
|
||||
"F^K[KFYFY[K[", /* U+2100 */
|
||||
"F^K[KFYFY[K[",
|
||||
"F^K[KFYFY[K[",
|
||||
@@ -8674,7 +8674,8 @@ const char* const newstroke_font[] =
|
||||
"F^K[KFYFY[K[",
|
||||
"F^K[KFYFY[K[",
|
||||
"F^K[KFYFY[K[",
|
||||
"F^K[KFYFY[K[",
|
||||
"F^J[O[OWMVKTJQJLKIMGPFTFWGYIZLZQYTWVUWU[Z[",
|
||||
/* // Letterlike Symbols (2127-214F) */
|
||||
"F^K[KFYFY[K[",
|
||||
"F^K[KFYFY[K[",
|
||||
"F^K[KFYFY[K[",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <macros.h>
|
||||
#include <trigo.h>
|
||||
|
||||
#include <basic_gal.h>
|
||||
#include <plotters/plotters_pslike.h>
|
||||
|
||||
|
||||
@@ -837,6 +838,7 @@ void PDF_PLOTTER::Text( const wxPoint& aPos,
|
||||
// be pixel-accurate, but it doesn't matter for searching.
|
||||
int render_mode = 3; // invisible
|
||||
|
||||
wxPoint pos( aPos );
|
||||
const char *fontname = aItalic ? ( aBold ? "/KicadFontBI" : "/KicadFontI" )
|
||||
: ( aBold ? "/KicadFontB" : "/KicadFont" );
|
||||
|
||||
@@ -844,28 +846,64 @@ void PDF_PLOTTER::Text( const wxPoint& aPos,
|
||||
double ctm_a, ctm_b, ctm_c, ctm_d, ctm_e, ctm_f;
|
||||
double wideningFactor, heightFactor;
|
||||
|
||||
computeTextParameters( aPos, aText, aOrient, aSize, m_plotMirror, aH_justify,
|
||||
aV_justify, aWidth, aItalic, aBold,
|
||||
&wideningFactor, &ctm_a, &ctm_b, &ctm_c,
|
||||
&ctm_d, &ctm_e, &ctm_f, &heightFactor );
|
||||
|
||||
SetColor( aColor );
|
||||
SetCurrentLineWidth( aWidth, aData );
|
||||
|
||||
/* We use the full CTM instead of the text matrix because the same
|
||||
coordinate system will be used for the overlining. Also the %f
|
||||
for the trig part of the matrix to avoid %g going in exponential
|
||||
format (which is not supported) */
|
||||
fprintf( workFile, "q %f %f %f %f %g %g cm BT %s %g Tf %d Tr %g Tz ",
|
||||
ctm_a, ctm_b, ctm_c, ctm_d, ctm_e, ctm_f,
|
||||
fontname, heightFactor, render_mode, wideningFactor * 100 );
|
||||
const auto& font = basic_gal.GetStrokeFont();
|
||||
VECTOR2D fontSize( aSize.x, aSize.y );
|
||||
double penWidth( aWidth );
|
||||
VECTOR2D extents = font.ComputeStringBoundaryLimits( aText, fontSize, penWidth );
|
||||
|
||||
// The text must be escaped correctly
|
||||
std:: string txt_pdf = encodeStringForPlotter( aText );
|
||||
fprintf( workFile, "%s Tj ET\n", txt_pdf.c_str() );
|
||||
wxPoint box_x( KiROUND( extents.x ), 0 );
|
||||
wxPoint box_y( 0, KiROUND( extents.y ) );
|
||||
|
||||
// Restore the CTM
|
||||
fputs( "Q\n", workFile );
|
||||
RotatePoint( &box_x, aOrient );
|
||||
RotatePoint( &box_y, aOrient );
|
||||
|
||||
if( aH_justify == GR_TEXT_HJUSTIFY_CENTER )
|
||||
pos -= box_x / 2;
|
||||
else if( aH_justify == GR_TEXT_HJUSTIFY_RIGHT )
|
||||
pos -= box_x;
|
||||
|
||||
if( aV_justify == GR_TEXT_VJUSTIFY_CENTER )
|
||||
pos += box_y / 2;
|
||||
else if( aV_justify == GR_TEXT_VJUSTIFY_TOP )
|
||||
pos += box_y;
|
||||
|
||||
wxStringTokenizer str_tok( aText, " ", wxTOKEN_RET_DELIMS );
|
||||
|
||||
while( str_tok.HasMoreTokens() )
|
||||
{
|
||||
wxString word = str_tok.GetNextToken();
|
||||
|
||||
computeTextParameters( pos, word, aOrient, aSize, m_plotMirror, GR_TEXT_HJUSTIFY_LEFT,
|
||||
GR_TEXT_VJUSTIFY_BOTTOM, aWidth, aItalic, aBold, &wideningFactor, &ctm_a,
|
||||
&ctm_b, &ctm_c, &ctm_d, &ctm_e, &ctm_f, &heightFactor );
|
||||
|
||||
// Extract the changed width and rotate by the orientation to get the offset for the
|
||||
// next word
|
||||
extents = font.ComputeStringBoundaryLimits( word, fontSize, penWidth );
|
||||
wxPoint bbox( KiROUND( extents.x ), 0 );
|
||||
RotatePoint( &bbox, aOrient );
|
||||
pos += bbox;
|
||||
|
||||
// Don't try to output a blank string
|
||||
if( word.Trim( false ).Trim( true ).empty() )
|
||||
continue;
|
||||
|
||||
/* We use the full CTM instead of the text matrix because the same
|
||||
coordinate system will be used for the overlining. Also the %f
|
||||
for the trig part of the matrix to avoid %g going in exponential
|
||||
format (which is not supported) */
|
||||
fprintf( workFile, "q %f %f %f %f %g %g cm BT %s %g Tf %d Tr %g Tz ",
|
||||
ctm_a, ctm_b, ctm_c, ctm_d, ctm_e, ctm_f,
|
||||
fontname, heightFactor, render_mode, wideningFactor * 100 );
|
||||
|
||||
std::string txt_pdf = encodeStringForPlotter( word );
|
||||
fprintf( workFile, "%s Tj ET\n", txt_pdf.c_str() );
|
||||
// Restore the CTM
|
||||
fputs( "Q\n", workFile );
|
||||
}
|
||||
|
||||
// Plot the stroked text (if requested)
|
||||
PLOTTER::Text( aPos, aColor, aText, aOrient, aSize, aH_justify, aV_justify, aWidth,
|
||||
|
||||
@@ -84,6 +84,7 @@ void PlotDrawingSheet( PLOTTER* plotter, const PROJECT* aProject, const TITLE_BL
|
||||
drawList.SetSheetCount( aSheetCount );
|
||||
drawList.SetFileName( fn.GetFullName() ); // Print only the short filename
|
||||
drawList.SetSheetName( aSheetDesc );
|
||||
drawList.SetSheetLayer( plotter->RenderSettings()->GetLayerName() );
|
||||
drawList.SetProject( aProject );
|
||||
drawList.SetIsFirstPage( aIsFirstPage );
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2014-2022 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
|
||||
@@ -273,7 +273,7 @@ const wxString PROJECT::AbsolutePath( const wxString& aFileName ) const
|
||||
if( !fn.IsAbsolute() )
|
||||
{
|
||||
wxString pro_dir = wxPathOnly( GetProjectFullName() );
|
||||
fn.Normalize( wxPATH_NORM_ALL, pro_dir );
|
||||
fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS, pro_dir );
|
||||
}
|
||||
|
||||
return fn.GetFullPath();
|
||||
|
||||
+1
-1
@@ -466,7 +466,7 @@ void RC_TREE_MODEL::DeleteCurrentItem( bool aDeep )
|
||||
|
||||
void RC_TREE_MODEL::DeleteItems( bool aCurrentOnly, bool aIncludeExclusions, bool aDeep )
|
||||
{
|
||||
RC_TREE_NODE* current_node = ToNode( m_view->GetCurrentItem() );
|
||||
RC_TREE_NODE* current_node = m_view ? ToNode( m_view->GetCurrentItem() ) : nullptr;
|
||||
const std::shared_ptr<RC_ITEM> current_item = current_node ? current_node->m_RcItem : nullptr;
|
||||
|
||||
/// Keep a vector of elements to free after wxWidgets is definitely done accessing them
|
||||
|
||||
+21
-15
@@ -79,18 +79,23 @@ void SCINTILLA_TRICKS::onThemeChanged( wxSysColourChangedEvent &aEvent )
|
||||
|
||||
void SCINTILLA_TRICKS::setupStyles()
|
||||
{
|
||||
wxTextCtrl dummy( m_te->GetParent(), wxID_ANY );
|
||||
wxColour foreground = dummy.GetForegroundColour();
|
||||
wxColour background = dummy.GetBackgroundColour();
|
||||
wxColour highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
|
||||
wxColour highlightText = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHTTEXT );
|
||||
wxTextCtrl dummy( m_te->GetParent(), wxID_ANY );
|
||||
wxColour foreground = dummy.GetForegroundColour();
|
||||
wxColour background = dummy.GetBackgroundColour();
|
||||
KIGFX::COLOR4D highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
|
||||
KIGFX::COLOR4D highlightText = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHTTEXT );
|
||||
|
||||
m_te->StyleSetForeground( wxSTC_STYLE_DEFAULT, foreground );
|
||||
m_te->StyleSetBackground( wxSTC_STYLE_DEFAULT, background );
|
||||
m_te->StyleClearAll();
|
||||
|
||||
m_te->SetSelForeground( true, highlightText );
|
||||
m_te->SetSelBackground( true, highlight );
|
||||
// Scintilla doesn't handle alpha channel, which at least OSX uses in some highlight colours,
|
||||
// such as "graphite".
|
||||
highlight = highlight.Mix( background, highlight.a ).WithAlpha( 1.0 );
|
||||
highlightText = highlightText.Mix( background, highlightText.a ).WithAlpha( 1.0 );
|
||||
|
||||
m_te->SetSelForeground( true, highlightText.ToColour() );
|
||||
m_te->SetSelBackground( true, highlight.ToColour() );
|
||||
m_te->SetCaretForeground( foreground );
|
||||
|
||||
if( !m_singleLine )
|
||||
@@ -105,14 +110,13 @@ void SCINTILLA_TRICKS::setupStyles()
|
||||
m_te->SetTabWidth( 4 );
|
||||
}
|
||||
|
||||
// Set up the brace highlighting
|
||||
unsigned char r = highlight.Red();
|
||||
unsigned char g = highlight.Green();
|
||||
unsigned char b = highlight.Blue();
|
||||
wxColour::MakeGrey( &r, &g, &b );
|
||||
highlight.Set( r, g, b );
|
||||
m_te->StyleSetForeground( wxSTC_STYLE_BRACELIGHT, highlightText );
|
||||
m_te->StyleSetBackground( wxSTC_STYLE_BRACELIGHT, highlight );
|
||||
// Set up the brace highlighting. Scintilla doesn't handle alpha, so we construct our own
|
||||
// 20% wash by blending with the background.
|
||||
KIGFX::COLOR4D braceText = foreground;
|
||||
KIGFX::COLOR4D braceHighlight = braceText.Mix( background, 0.2 );
|
||||
|
||||
m_te->StyleSetForeground( wxSTC_STYLE_BRACELIGHT, highlightText.ToColour() );
|
||||
m_te->StyleSetBackground( wxSTC_STYLE_BRACELIGHT, braceHighlight.ToColour() );
|
||||
m_te->StyleSetForeground( wxSTC_STYLE_BRACEBAD, *wxRED );
|
||||
}
|
||||
|
||||
@@ -228,7 +232,9 @@ void SCINTILLA_TRICKS::onCharHook( wxKeyEvent& aEvent )
|
||||
str = data.GetText();
|
||||
|
||||
ConvertSmartQuotesAndDashes( &str );
|
||||
m_te->BeginUndoAction();
|
||||
m_te->AddText( str );
|
||||
m_te->EndUndoAction();
|
||||
}
|
||||
|
||||
wxTheClipboard->Close();
|
||||
|
||||
@@ -230,7 +230,7 @@ COLOR_SETTINGS::COLOR_SETTINGS( const wxString& aFilename, bool aAbsolutePath )
|
||||
// Fix LAYER_VIA_HOLES color - before version 2, this setting had no effect
|
||||
nlohmann::json::json_pointer ptr( "/board/via_hole");
|
||||
|
||||
( *m_internals )[ptr] = COLOR4D( 0.5, 0.4, 0, 0.8 ).ToWxString( wxC2S_CSS_SYNTAX );
|
||||
( *m_internals )[ptr] = COLOR4D( 0.5, 0.4, 0, 0.8 ).ToCSSString();
|
||||
|
||||
return true;
|
||||
} );
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <settings/json_settings_internals.h>
|
||||
#include <settings/nested_settings.h>
|
||||
#include <locale_io.h>
|
||||
|
||||
NESTED_SETTINGS::NESTED_SETTINGS( const std::string& aName, int aVersion, JSON_SETTINGS* aParent,
|
||||
const std::string& aPath ) :
|
||||
@@ -116,6 +117,8 @@ bool NESTED_SETTINGS::SaveToFile( const wxString& aDirectory, bool aForce )
|
||||
if( !m_parent )
|
||||
return false;
|
||||
|
||||
LOCALE_IO dummy;
|
||||
|
||||
try
|
||||
{
|
||||
bool modified = Store();
|
||||
|
||||
+2
-15
@@ -145,13 +145,6 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
|
||||
wxString converted;
|
||||
std::vector<bool> braceStack; // true == formatting construct
|
||||
|
||||
auto hasFormattingPrefix =
|
||||
[&]()
|
||||
{
|
||||
static wxString prefixes = wxT( "~_^" );
|
||||
return !converted.IsEmpty() && prefixes.Find( converted.Last() ) >= 0;
|
||||
};
|
||||
|
||||
converted.reserve( aSource.length() );
|
||||
|
||||
for( wxUniChar c: aSource )
|
||||
@@ -167,9 +160,7 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
|
||||
}
|
||||
else if( aContext == CTX_LIBID )
|
||||
{
|
||||
if( c == '{' && !hasFormattingPrefix() )
|
||||
converted += wxT( "{brace}" );
|
||||
else if( c == '/' )
|
||||
if( c == '/' )
|
||||
converted += wxT( "{slash}" );
|
||||
else if( c == '\\' )
|
||||
converted += wxT( "{backslash}" );
|
||||
@@ -202,9 +193,7 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
|
||||
}
|
||||
else if( aContext == CTX_FILENAME )
|
||||
{
|
||||
if( c == '{' )
|
||||
converted += wxT( "{brace}" );
|
||||
else if( c == '/' )
|
||||
if( c == '/' )
|
||||
converted += wxT( "{slash}" );
|
||||
else if( c == '\\' )
|
||||
converted += wxT( "{backslash}" );
|
||||
@@ -229,8 +218,6 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
|
||||
{
|
||||
if( c == ' ' )
|
||||
converted += wxT( "{space}" );
|
||||
else if( c == '{' )
|
||||
converted += wxT( "{brace}" );
|
||||
else
|
||||
converted += c;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.TXT for contributors.
|
||||
* Copyright (C) 2015-2022 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,18 +35,9 @@ using namespace TFIELD_T;
|
||||
#define FOOTPRINT_CANONICAL "Footprint"
|
||||
#define DATASHEET_CANONICAL "Datasheet"
|
||||
|
||||
static std::mutex s_defaultFieldMutex;
|
||||
|
||||
const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx, bool aTranslate )
|
||||
const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx, bool aTranslateForHI )
|
||||
{
|
||||
static void* locale = nullptr;
|
||||
static wxString referenceDefault;
|
||||
static wxString valueDefault;
|
||||
static wxString footprintDefault;
|
||||
static wxString datasheetDefault;
|
||||
static wxString fieldDefault;
|
||||
|
||||
if( !aTranslate )
|
||||
if( !aTranslateForHI )
|
||||
{
|
||||
switch( aFieldNdx )
|
||||
{
|
||||
@@ -54,42 +45,20 @@ const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx, bool aTra
|
||||
case VALUE_FIELD: return VALUE_CANONICAL; // The symbol value
|
||||
case FOOTPRINT_FIELD: return FOOTPRINT_CANONICAL; // The footprint for use with Pcbnew
|
||||
case DATASHEET_FIELD: return DATASHEET_CANONICAL; // Link to a datasheet for symbol
|
||||
default: return wxString::Format( wxT( "Field%d" ), aFieldNdx );
|
||||
}
|
||||
}
|
||||
|
||||
// Mutex protection is needed so that multiple loader threads don't write to the static
|
||||
// variables at once
|
||||
std::lock_guard<std::mutex> lock( s_defaultFieldMutex );
|
||||
|
||||
// Fetching translations can take a surprising amount of time when loading libraries,
|
||||
// so only do it when necessary.
|
||||
if( Pgm().GetLocale() != locale )
|
||||
{
|
||||
referenceDefault = _( REFERENCE_CANONICAL );
|
||||
valueDefault = _( VALUE_CANONICAL );
|
||||
footprintDefault = _( FOOTPRINT_CANONICAL );
|
||||
datasheetDefault = _( DATASHEET_CANONICAL );
|
||||
fieldDefault = _( "Field%d" );
|
||||
locale = Pgm().GetLocale();
|
||||
}
|
||||
|
||||
// Fixed values for the mandatory fields
|
||||
switch( aFieldNdx )
|
||||
{
|
||||
case REFERENCE_FIELD: return referenceDefault; // The symbol reference, R1, C1, etc.
|
||||
case VALUE_FIELD: return valueDefault; // The symbol value
|
||||
case FOOTPRINT_FIELD: return footprintDefault; // The footprint for use with Pcbnew
|
||||
case DATASHEET_FIELD: return datasheetDefault; // Link to a datasheet for symbol
|
||||
default: return wxString::Format( fieldDefault, aFieldNdx );
|
||||
case REFERENCE_FIELD: return _( REFERENCE_CANONICAL ); // The symbol reference, R1, C1, etc.
|
||||
case VALUE_FIELD: return _( VALUE_CANONICAL ); // The symbol value
|
||||
case FOOTPRINT_FIELD: return _( FOOTPRINT_CANONICAL ); // The footprint for use with Pcbnew
|
||||
case DATASHEET_FIELD: return _( DATASHEET_CANONICAL ); // Link to a datasheet for symbol
|
||||
default: return wxString::Format( _( "Field%d" ), aFieldNdx );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#undef REFERENCE_CANONICAL
|
||||
#undef VALUE_CANONICAL
|
||||
#undef FOOTPRINT_CANONICAL
|
||||
#undef DATASHEET_CANONICAL
|
||||
|
||||
|
||||
void TEMPLATE_FIELDNAME::Format( OUTPUTFORMATTER* out, int nestLevel ) const
|
||||
{
|
||||
|
||||
@@ -91,6 +91,7 @@ void TITLE_BLOCK::GetContextualTextVars( wxArrayString* aVars )
|
||||
bool TITLE_BLOCK::TextVarResolver( wxString* aToken, const PROJECT* aProject ) const
|
||||
{
|
||||
bool tokenUpdated = false;
|
||||
wxString originalToken = *aToken;
|
||||
|
||||
if( aToken->IsSameAs( wxT( "ISSUE_DATE" ) ) )
|
||||
{
|
||||
@@ -146,7 +147,12 @@ bool TITLE_BLOCK::TextVarResolver( wxString* aToken, const PROJECT* aProject ) c
|
||||
|
||||
if( tokenUpdated )
|
||||
{
|
||||
*aToken = ExpandTextVars( *aToken, aProject );
|
||||
*aToken = ExpandTextVars( *aToken, aProject );
|
||||
|
||||
// This is the default fallback, so don't claim we resolved it
|
||||
if( *aToken == wxT( "${" ) + originalToken + wxT( "}" ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -242,6 +242,13 @@ bool TOOL_EVENT::IsMoveTool() const
|
||||
}
|
||||
|
||||
|
||||
bool TOOL_EVENT::IsEditorTool() const
|
||||
{
|
||||
return ( m_commandStr
|
||||
&& m_commandStr.value().find( "InteractiveEdit" ) != GetCommandStr()->npos );
|
||||
}
|
||||
|
||||
|
||||
bool TOOL_EVENT::IsSimulator() const
|
||||
{
|
||||
return( m_commandStr.is_initialized()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020-2022 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
|
||||
@@ -117,8 +117,11 @@ bool TOOLS_HOLDER::IsCurrentTool( const TOOL_ACTION& aAction ) const
|
||||
|
||||
void TOOLS_HOLDER::ShowChangedLanguage()
|
||||
{
|
||||
if( !GetToolManager() )
|
||||
return;
|
||||
|
||||
std::string actionName = CurrentToolName();
|
||||
TOOL_ACTION* action = m_toolManager->GetActionManager()->FindAction( actionName );
|
||||
TOOL_ACTION* action = GetToolManager()->GetActionManager()->FindAction( actionName );
|
||||
|
||||
if( action )
|
||||
DisplayToolMsg( action->GetLabel() );
|
||||
|
||||
@@ -39,6 +39,7 @@ const wxChar* const kicadTraceCoroutineStack = wxT( "KICAD_COROUTINE_STACK" );
|
||||
const wxChar* const traceSchLibMem = wxT( "KICAD_SCH_LIB_MEM" );
|
||||
const wxChar* const traceFindItem = wxT( "KICAD_FIND_ITEM" );
|
||||
const wxChar* const traceSchLegacyPlugin = wxT( "KICAD_SCH_LEGACY_PLUGIN" );
|
||||
const wxChar* const traceSchPlugin = wxT( "KICAD_SCH_PLUGIN" );
|
||||
const wxChar* const traceGedaPcbPlugin = wxT( "KICAD_GEDA_PLUGIN" );
|
||||
const wxChar* const traceKicadPcbPlugin = wxT( "KICAD_PCB_PLUGIN" );
|
||||
const wxChar* const tracePrinting = wxT( "KICAD_PRINT" );
|
||||
|
||||
@@ -148,7 +148,7 @@ void VIEW_GROUP::ViewDraw( int aLayer, VIEW* aView ) const
|
||||
{
|
||||
int layer = layers[i];
|
||||
|
||||
if( IsZoneLayer( layer ) )
|
||||
if( IsZoneFillLayer( layer ) )
|
||||
layer = layer - LAYER_ZONE_START;
|
||||
|
||||
bool draw = aView->IsLayerVisible( layer );
|
||||
|
||||
@@ -248,7 +248,7 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
|
||||
{
|
||||
if( !justWarped )
|
||||
{
|
||||
m_parentPanel->WarpPointer( x + warpX, y + warpY );
|
||||
KIPLATFORM::UI::WarpPointer( m_parentPanel, x + warpX, y + warpY );
|
||||
m_dragStartPoint += VECTOR2D( warpX, warpY );
|
||||
justWarped = true;
|
||||
}
|
||||
@@ -288,7 +288,7 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
|
||||
{
|
||||
if( !justWarped )
|
||||
{
|
||||
m_parentPanel->WarpPointer( x, y + warpY );
|
||||
KIPLATFORM::UI::WarpPointer( m_parentPanel, x, y + warpY );
|
||||
m_dragStartPoint += VECTOR2D( 0, warpY );
|
||||
justWarped = true;
|
||||
}
|
||||
@@ -353,7 +353,7 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent )
|
||||
|
||||
// Refresh the zoom level and mouse position on message panel
|
||||
// (mouse position has not changed, only the zoom level has changed):
|
||||
refreshMouse();
|
||||
refreshMouse( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -371,7 +371,7 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent )
|
||||
VECTOR2D delta( scrollX, scrollY );
|
||||
|
||||
m_view->SetCenter( m_view->GetCenter() + delta );
|
||||
refreshMouse();
|
||||
refreshMouse( true );
|
||||
}
|
||||
|
||||
// Do not skip this event, otherwise wxWidgets will fire
|
||||
@@ -507,6 +507,18 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef __WXMSW__
|
||||
// Hackfix: It's possible for the mouse to leave the canvas
|
||||
// without triggering any leave events on windows
|
||||
// Use a MSW only wx function
|
||||
if( !m_parentPanel->IsMouseInWindow() )
|
||||
{
|
||||
m_panTimer.Stop();
|
||||
m_state = IDLE;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( !m_parentPanel->HasFocus() )
|
||||
break;
|
||||
|
||||
@@ -533,7 +545,7 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
|
||||
dir = m_view->ToWorld( dir, false );
|
||||
m_view->SetCenter( m_view->GetCenter() + dir );
|
||||
|
||||
refreshMouse();
|
||||
refreshMouse( true );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -741,20 +753,22 @@ void WX_VIEW_CONTROLS::WarpCursor( const VECTOR2D& aPosition, bool aWorldCoordin
|
||||
if( aWarpView )
|
||||
{
|
||||
m_view->SetCenter( clampedPosition );
|
||||
m_parentPanel->WarpPointer( screenSize.x / 2, screenSize.y / 2 );
|
||||
KIPLATFORM::UI::WarpPointer( m_parentPanel, screenSize.x / 2, screenSize.y / 2 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_parentPanel->WarpPointer( screenPos.x, screenPos.y );
|
||||
KIPLATFORM::UI::WarpPointer( m_parentPanel, screenPos.x, screenPos.y );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_parentPanel->WarpPointer( aPosition.x, aPosition.y );
|
||||
KIPLATFORM::UI::WarpPointer( m_parentPanel, aPosition.x, aPosition.y );
|
||||
}
|
||||
|
||||
refreshMouse();
|
||||
// If we are not refreshing because of mouse movement, don't set the modifiers
|
||||
// because we are refreshing for keyboard movement, which uses the same modifiers for other actions
|
||||
refreshMouse( m_updateCursor );
|
||||
}
|
||||
|
||||
|
||||
@@ -766,7 +780,7 @@ void WX_VIEW_CONTROLS::CenterOnCursor() const
|
||||
if( GetMousePosition( false ) != screenCenter )
|
||||
{
|
||||
m_view->SetCenter( GetCursorPosition() );
|
||||
m_parentPanel->WarpPointer( KiROUND( screenSize.x / 2 ), KiROUND( screenSize.y / 2 ) );
|
||||
KIPLATFORM::UI::WarpPointer( m_parentPanel, KiROUND( screenSize.x / 2 ), KiROUND( screenSize.y / 2 ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -877,12 +891,12 @@ void WX_VIEW_CONTROLS::handleCursorCapture( int x, int y )
|
||||
}
|
||||
|
||||
if( warp )
|
||||
m_parentPanel->WarpPointer( x, y );
|
||||
KIPLATFORM::UI::WarpPointer( m_parentPanel, x, y );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WX_VIEW_CONTROLS::refreshMouse()
|
||||
void WX_VIEW_CONTROLS::refreshMouse( bool aSetModifiers )
|
||||
{
|
||||
// Notify tools that the cursor position has changed in the world coordinates
|
||||
wxMouseEvent moveEvent( EVT_REFRESH_MOUSE );
|
||||
@@ -890,10 +904,13 @@ void WX_VIEW_CONTROLS::refreshMouse()
|
||||
moveEvent.SetX( msp.x );
|
||||
moveEvent.SetY( msp.y );
|
||||
|
||||
// Set the modifiers state
|
||||
moveEvent.SetControlDown( wxGetKeyState( WXK_CONTROL ) );
|
||||
moveEvent.SetShiftDown( wxGetKeyState( WXK_SHIFT ) );
|
||||
moveEvent.SetAltDown( wxGetKeyState( WXK_ALT ) );
|
||||
if( aSetModifiers )
|
||||
{
|
||||
// Set the modifiers state
|
||||
moveEvent.SetControlDown( wxGetKeyState( WXK_CONTROL ) );
|
||||
moveEvent.SetShiftDown( wxGetKeyState( WXK_SHIFT ) );
|
||||
moveEvent.SetAltDown( wxGetKeyState( WXK_ALT ) );
|
||||
}
|
||||
|
||||
m_cursorPos = GetClampedCoords( m_view->ToWorld( VECTOR2D( msp.x, msp.y ) ) );
|
||||
wxPostEvent( m_parentPanel, moveEvent );
|
||||
@@ -942,7 +959,7 @@ void WX_VIEW_CONTROLS::UpdateScrollbars()
|
||||
// Trigger a mouse refresh to get the canvas update in GTK (re-draws the scrollbars).
|
||||
// Note that this causes an infinite loop on OSX and Windows (in certain cases) as it
|
||||
// generates a paint event.
|
||||
refreshMouse();
|
||||
refreshMouse( false );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ BITMAP_TOGGLE::BITMAP_TOGGLE( wxWindow *aParent, wxWindowID aId, const wxBitmap&
|
||||
|
||||
const wxBitmap& bitmap = aChecked ? m_checked_bitmap : m_unchecked_bitmap;
|
||||
|
||||
m_bitmap = new wxStaticBitmap( this, aId, bitmap, wxDefaultPosition, bitmap.GetSize() );
|
||||
m_bitmap = new wxStaticBitmap( this, aId, bitmap, wxDefaultPosition );
|
||||
|
||||
sizer->Add( m_bitmap, 0, 0 );
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ void GRID_CELL_COLOR_SELECTOR::Create( wxWindow* aParent, wxWindowID aId,
|
||||
|
||||
wxString GRID_CELL_COLOR_SELECTOR::GetValue() const
|
||||
{
|
||||
return m_value.ToWxString( wxC2S_CSS_SYNTAX );
|
||||
return m_value.ToCSSString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -237,7 +237,9 @@ bool PAGED_DIALOG::TransferDataToWindow()
|
||||
}
|
||||
}
|
||||
|
||||
m_treebook->SetSelection( (unsigned) std::max( 0, lastPageIndex ) );
|
||||
lastPageIndex = std::max( 0, lastPageIndex );
|
||||
m_treebook->ChangeSelection( lastPageIndex );
|
||||
UpdateResetButton( lastPageIndex );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -360,18 +362,17 @@ void PAGED_DIALOG::OnUpdateUI( wxUpdateUIEvent& event )
|
||||
}
|
||||
|
||||
|
||||
void PAGED_DIALOG::OnPageChange( wxBookCtrlEvent& event )
|
||||
void PAGED_DIALOG::UpdateResetButton( int aPage )
|
||||
{
|
||||
size_t page = event.GetSelection();
|
||||
|
||||
// Enable the reset button only if the page is re-settable
|
||||
if( m_resetButton )
|
||||
{
|
||||
if( auto panel = dynamic_cast<RESETTABLE_PANEL*>( m_treebook->GetPage( page ) ) )
|
||||
if( auto panel = dynamic_cast<RESETTABLE_PANEL*>( m_treebook->GetPage( aPage ) ) )
|
||||
{
|
||||
m_resetButton->SetLabel( wxString::Format( _( "Reset %s to Defaults" ),
|
||||
m_treebook->GetPageText( page ) ) );
|
||||
m_resetButton->SetToolTip( panel->GetResetTooltip() );
|
||||
m_treebook->GetPageText( aPage ) ) );
|
||||
m_resetButton->SetToolTip( panel->GetHelpTextAtPoint( wxPoint( -INT_MAX, INT_MAX ),
|
||||
wxHelpEvent::Origin_Unknown ) );
|
||||
m_resetButton->Enable( true );
|
||||
}
|
||||
else
|
||||
@@ -382,20 +383,27 @@ void PAGED_DIALOG::OnPageChange( wxBookCtrlEvent& event )
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Work around an OSX bug where the wxGrid children don't get placed correctly until
|
||||
// the first resize event
|
||||
#ifdef __WXMAC__
|
||||
if( page + 1 <= m_macHack.size() && m_macHack[ page ] )
|
||||
|
||||
void PAGED_DIALOG::OnPageChange( wxBookCtrlEvent& event )
|
||||
{
|
||||
int page = event.GetSelection();
|
||||
|
||||
// Use the first sub-page when a tree level node is selected.
|
||||
if( m_treebook->GetCurrentPage()->GetChildren().IsEmpty() )
|
||||
{
|
||||
wxSize pageSize = m_treebook->GetPage( page )->GetSize();
|
||||
pageSize.x -= 5;
|
||||
pageSize.y += 2;
|
||||
unsigned next = page + 1;
|
||||
|
||||
m_treebook->GetPage( page )->SetSize( pageSize );
|
||||
m_macHack[ page ] = false;
|
||||
if( next < m_treebook->GetPageCount() )
|
||||
m_treebook->ChangeSelection( next );
|
||||
}
|
||||
#endif
|
||||
|
||||
UpdateResetButton( page );
|
||||
|
||||
wxSizeEvent evt( wxDefaultSize );
|
||||
|
||||
wxQueueEvent( m_treebook, evt.Clone() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
+80
-12
@@ -60,8 +60,9 @@
|
||||
#define CVPCB_MAINFRAME_NAME wxT( "CvpcbFrame" )
|
||||
|
||||
CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||
KIWAY_PLAYER( aKiway, aParent, FRAME_CVPCB, _( "Assign Footprints" ), wxDefaultPosition,
|
||||
wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, CVPCB_MAINFRAME_NAME )
|
||||
KIWAY_PLAYER( aKiway, aParent, FRAME_CVPCB, _( "Assign Footprints" ), wxDefaultPosition,
|
||||
wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, CVPCB_MAINFRAME_NAME ),
|
||||
m_viewerPendingUpdate( false )
|
||||
{
|
||||
m_symbolsListBox = nullptr;
|
||||
m_footprintListBox = nullptr;
|
||||
@@ -209,12 +210,17 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||
// Start the main processing loop
|
||||
m_toolManager->InvokeTool( "cvpcb.Control" );
|
||||
|
||||
m_filterTimer->StartOnce( 100 );
|
||||
|
||||
KIPLATFORM::APP::SetShutdownBlockReason( this, _( "Symbol to footprint changes are unsaved" ) );
|
||||
}
|
||||
|
||||
|
||||
CVPCB_MAINFRAME::~CVPCB_MAINFRAME()
|
||||
{
|
||||
// Stop the timer during destruction early to avoid potential race conditions (that do happen)
|
||||
m_filterTimer->Stop();
|
||||
|
||||
// Shutdown all running tools
|
||||
if( m_toolManager )
|
||||
m_toolManager->ShutdownAllTools();
|
||||
@@ -370,6 +376,9 @@ void CVPCB_MAINFRAME::setupEventHandlers()
|
||||
// Attach the events to the tool dispatcher
|
||||
Bind( wxEVT_CHAR, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
|
||||
Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
|
||||
|
||||
m_filterTimer = new wxTimer( this );
|
||||
Bind( wxEVT_TIMER, &CVPCB_MAINFRAME::onTextFilterChangedTimer, this, m_filterTimer->GetId() );
|
||||
}
|
||||
|
||||
|
||||
@@ -420,11 +429,37 @@ void CVPCB_MAINFRAME::OnEnterFilteringText( wxCommandEvent& aEvent )
|
||||
// If the option FOOTPRINTS_LISTBOX::FILTERING_BY_TEXT_PATTERN is set, update the list
|
||||
// of available footprints which match the filter
|
||||
|
||||
m_filterTimer->StartOnce( 200 );
|
||||
}
|
||||
|
||||
|
||||
void CVPCB_MAINFRAME::onTextFilterChangedTimer( wxTimerEvent& aEvent )
|
||||
{
|
||||
// GTK loses the search-control's focus on a Refresh event, so we record the focus and
|
||||
// insertion point here and then restore them at the end.
|
||||
bool searchCtrlHasFocus = m_tcFilterString->HasFocus();
|
||||
long pos = m_tcFilterString->GetInsertionPoint();
|
||||
wxListEvent l_event;
|
||||
OnSelectComponent( l_event );
|
||||
m_tcFilterString->SetFocus();
|
||||
m_tcFilterString->SetInsertionPoint( pos );
|
||||
|
||||
COMPONENT* symbol = GetSelectedComponent();
|
||||
wxString libraryName = m_librariesListBox->GetSelectedLibrary();
|
||||
|
||||
m_footprintListBox->SetFootprints( *m_FootprintsList, libraryName, symbol,
|
||||
m_tcFilterString->GetValue(), m_filteringOptions );
|
||||
|
||||
if( symbol && symbol->GetFPID().IsValid() )
|
||||
m_footprintListBox->SetSelectedFootprint( symbol->GetFPID() );
|
||||
else if( m_footprintListBox->GetSelection() >= 0 )
|
||||
m_footprintListBox->SetSelection( m_footprintListBox->GetSelection(), false );
|
||||
|
||||
RefreshFootprintViewer();
|
||||
|
||||
DisplayStatus();
|
||||
|
||||
if( searchCtrlHasFocus )
|
||||
{
|
||||
m_tcFilterString->SetFocus();
|
||||
m_tcFilterString->SetInsertionPoint( pos );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -433,22 +468,58 @@ void CVPCB_MAINFRAME::OnSelectComponent( wxListEvent& event )
|
||||
if( m_skipComponentSelect )
|
||||
return;
|
||||
|
||||
wxString libraryName;
|
||||
COMPONENT* symbol = GetSelectedComponent();
|
||||
libraryName = m_librariesListBox->GetSelectedLibrary();
|
||||
wxString libraryName = m_librariesListBox->GetSelectedLibrary();
|
||||
|
||||
m_footprintListBox->SetFootprints( *m_FootprintsList, libraryName, symbol,
|
||||
m_tcFilterString->GetValue(), m_filteringOptions );
|
||||
|
||||
if( symbol && symbol->GetFPID().IsValid() )
|
||||
m_footprintListBox->SetSelectedFootprint( symbol->GetFPID() );
|
||||
else
|
||||
else if( m_footprintListBox->GetSelection() >= 0 )
|
||||
m_footprintListBox->SetSelection( m_footprintListBox->GetSelection(), false );
|
||||
|
||||
RefreshFootprintViewer();
|
||||
|
||||
refreshAfterSymbolSearch( symbol );
|
||||
}
|
||||
|
||||
|
||||
void CVPCB_MAINFRAME::RefreshFootprintViewer()
|
||||
{
|
||||
if( GetFootprintViewerFrame() && !m_viewerPendingUpdate )
|
||||
{
|
||||
Bind( wxEVT_IDLE, &CVPCB_MAINFRAME::updateFootprintViewerOnIdle, this );
|
||||
m_viewerPendingUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVPCB_MAINFRAME::updateFootprintViewerOnIdle( wxIdleEvent& aEvent )
|
||||
{
|
||||
Unbind( wxEVT_IDLE, &CVPCB_MAINFRAME::updateFootprintViewerOnIdle, this );
|
||||
m_viewerPendingUpdate = false;
|
||||
|
||||
// On some plateforms (OSX) the focus is lost when the viewers (fp and 3D viewers)
|
||||
// are opened and refreshed when a new footprint is selected.
|
||||
// If the listbox has the focus before selecting a new footprint, it will be forced
|
||||
// after selection.
|
||||
bool footprintListHasFocus = m_footprintListBox->HasFocus();
|
||||
bool symbolListHasFocus = m_symbolsListBox->HasFocus();
|
||||
|
||||
// If the footprint view window is displayed, update the footprint.
|
||||
if( GetFootprintViewerFrame() )
|
||||
GetToolManager()->RunAction( CVPCB_ACTIONS::showFootprintViewer, true );
|
||||
|
||||
DisplayStatus();
|
||||
|
||||
if( footprintListHasFocus )
|
||||
m_footprintListBox->SetFocus();
|
||||
else if( symbolListHasFocus )
|
||||
m_symbolsListBox->SetFocus();
|
||||
}
|
||||
|
||||
|
||||
void CVPCB_MAINFRAME::LoadSettings( APP_SETTINGS_BASE* aCfg )
|
||||
{
|
||||
EDA_BASE_FRAME::LoadSettings( aCfg );
|
||||
@@ -652,9 +723,6 @@ void CVPCB_MAINFRAME::refreshAfterSymbolSearch( COMPONENT* aSymbol )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( GetFootprintViewerFrame() )
|
||||
m_toolManager->RunAction( CVPCB_ACTIONS::showFootprintViewer, true );
|
||||
}
|
||||
|
||||
SendMessageToEESCHEMA();
|
||||
|
||||
+14
-3
@@ -330,6 +330,8 @@ public:
|
||||
*/
|
||||
wxString GetSelectedFootprint();
|
||||
|
||||
void RefreshFootprintViewer();
|
||||
|
||||
void SetStatusText( const wxString& aText, int aNumber = 0 ) override;
|
||||
|
||||
protected:
|
||||
@@ -351,6 +353,12 @@ private:
|
||||
*/
|
||||
void setupEventHandlers();
|
||||
|
||||
void onTextFilterChanged( wxCommandEvent& event );
|
||||
|
||||
void updateFootprintViewerOnIdle( wxIdleEvent& aEvent );
|
||||
|
||||
void onTextFilterChangedTimer( wxTimerEvent& aEvent );
|
||||
|
||||
/**
|
||||
* Read the .equ files and populate the list of equivalents.
|
||||
*
|
||||
@@ -398,9 +406,12 @@ private:
|
||||
ACTION_MENU* m_footprintContextMenu;
|
||||
ACTION_MENU* m_symbolsContextMenu;
|
||||
|
||||
// Undo/Redo item lists
|
||||
CVPCB_UNDO_REDO_LIST m_undoList;
|
||||
CVPCB_UNDO_REDO_LIST m_redoList;
|
||||
CVPCB_UNDO_REDO_LIST m_undoList;
|
||||
CVPCB_UNDO_REDO_LIST m_redoList;
|
||||
|
||||
wxTimer* m_filterTimer;
|
||||
bool m_viewerPendingUpdate;
|
||||
|
||||
};
|
||||
|
||||
#endif //#ifndef _CVPCB_MAINFRAME_H_
|
||||
|
||||
@@ -62,13 +62,15 @@ BEGIN_EVENT_TABLE( DISPLAY_FOOTPRINTS_FRAME, PCB_BASE_FRAME )
|
||||
EVT_CLOSE( DISPLAY_FOOTPRINTS_FRAME::OnCloseWindow )
|
||||
EVT_CHOICE( ID_ON_ZOOM_SELECT, DISPLAY_FOOTPRINTS_FRAME::OnSelectZoom )
|
||||
EVT_CHOICE( ID_ON_GRID_SELECT, DISPLAY_FOOTPRINTS_FRAME::OnSelectGrid )
|
||||
EVT_MENU( ID_GRID_SETTINGS, DISPLAY_FOOTPRINTS_FRAME::OnGridSettings )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||
PCB_BASE_FRAME( aKiway, aParent, FRAME_CVPCB_DISPLAY, _( "Footprint Viewer" ),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
KICAD_DEFAULT_DRAWFRAME_STYLE, FOOTPRINTVIEWER_FRAME_NAME )
|
||||
PCB_BASE_FRAME( aKiway, aParent, FRAME_CVPCB_DISPLAY, _( "Footprint Viewer" ),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
KICAD_DEFAULT_DRAWFRAME_STYLE, FOOTPRINTVIEWER_FRAME_NAME ),
|
||||
m_currentComp( nullptr )
|
||||
{
|
||||
// Give an icon
|
||||
wxIcon icon;
|
||||
@@ -451,21 +453,20 @@ FOOTPRINT* DISPLAY_FOOTPRINTS_FRAME::GetFootprint( const wxString& aFootprintNam
|
||||
void DISPLAY_FOOTPRINTS_FRAME::InitDisplay()
|
||||
{
|
||||
CVPCB_MAINFRAME* parentframe = (CVPCB_MAINFRAME *) GetParent();
|
||||
COMPONENT* comp = parentframe->GetSelectedComponent();
|
||||
FOOTPRINT* footprint = nullptr;
|
||||
const FOOTPRINT_INFO* fpInfo = nullptr;
|
||||
|
||||
GetBoard()->DeleteAllFootprints();
|
||||
GetCanvas()->GetView()->Clear();
|
||||
|
||||
wxString footprintName = parentframe->GetSelectedFootprint();
|
||||
|
||||
if( footprintName.IsEmpty() )
|
||||
{
|
||||
COMPONENT* comp = parentframe->GetSelectedComponent();
|
||||
if( footprintName.IsEmpty() && comp )
|
||||
footprintName = comp->GetFPID().Format();
|
||||
|
||||
if( comp )
|
||||
footprintName = comp->GetFPID().GetUniStringLibId();
|
||||
}
|
||||
if( m_currentFootprint == footprintName && m_currentComp == comp )
|
||||
return;
|
||||
|
||||
GetBoard()->DeleteAllFootprints();
|
||||
GetCanvas()->GetView()->Clear();
|
||||
|
||||
INFOBAR_REPORTER infoReporter( m_infoBar );
|
||||
m_infoBar->Dismiss();
|
||||
@@ -480,7 +481,11 @@ void DISPLAY_FOOTPRINTS_FRAME::InitDisplay()
|
||||
}
|
||||
|
||||
if( footprint )
|
||||
{
|
||||
GetBoard()->Add( footprint );
|
||||
m_currentFootprint = footprintName;
|
||||
m_currentComp = comp;
|
||||
}
|
||||
|
||||
if( fpInfo )
|
||||
SetStatusText( wxString::Format( _( "Lib: %s" ), fpInfo->GetLibNickname() ), 0 );
|
||||
|
||||
@@ -114,6 +114,10 @@ public:
|
||||
|
||||
protected:
|
||||
void setupUIConditions() override;
|
||||
|
||||
private:
|
||||
wxString m_currentFootprint;
|
||||
COMPONENT* m_currentComp;
|
||||
};
|
||||
|
||||
#endif // DISPLAY_FOOTPRINTS_FRAME_H
|
||||
|
||||
@@ -99,15 +99,15 @@ wxString FOOTPRINTS_LISTBOX::OnGetItemText( long item, long column ) const
|
||||
}
|
||||
|
||||
|
||||
void FOOTPRINTS_LISTBOX::SetSelection( int index, bool State )
|
||||
void FOOTPRINTS_LISTBOX::SetSelection( int aIndex, bool aState )
|
||||
{
|
||||
if( index >= GetCount() )
|
||||
index = GetCount() - 1;
|
||||
if( aIndex >= GetCount() )
|
||||
aIndex = GetCount() - 1;
|
||||
|
||||
if( (index >= 0) && (GetCount() > 0) )
|
||||
if(( aIndex >= 0) && ( GetCount() > 0) )
|
||||
{
|
||||
Select( index, State );
|
||||
EnsureVisible( index );
|
||||
Select( aIndex, aState );
|
||||
EnsureVisible( aIndex );
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
@@ -156,7 +156,7 @@ void FOOTPRINTS_LISTBOX::SetFootprints( FOOTPRINT_LIST& aList, const wxString& a
|
||||
if( GetSelection() >= 0 && GetSelection() < (int)m_footprintList.GetCount() )
|
||||
oldSelection = m_footprintList[ GetSelection() ];
|
||||
|
||||
for( auto& i: filter )
|
||||
for( const FOOTPRINT_INFO& i : filter )
|
||||
{
|
||||
msg.Printf( wxT( "%3d %s:%s" ),
|
||||
int( newList.GetCount() + 1 ),
|
||||
@@ -199,23 +199,7 @@ END_EVENT_TABLE()
|
||||
|
||||
void FOOTPRINTS_LISTBOX::OnLeftClick( wxListEvent& event )
|
||||
{
|
||||
if( m_footprintList.IsEmpty() )
|
||||
return;
|
||||
|
||||
// On some plateforms (OSX) the focus is lost when the viewers (fp and 3D viewers)
|
||||
// are opened and refreshed when a new footprint is selected.
|
||||
// If the listbox has the focus before selecting a new footprint, it will be forced
|
||||
// after selection.
|
||||
bool hasFocus = HasFocus();
|
||||
|
||||
// If the footprint view window is displayed, update the footprint.
|
||||
if( GetParent()->GetFootprintViewerFrame() )
|
||||
GetParent()->GetToolManager()->RunAction( CVPCB_ACTIONS::showFootprintViewer, true );
|
||||
|
||||
GetParent()->DisplayStatus();
|
||||
|
||||
if( hasFocus )
|
||||
SetFocus();
|
||||
GetParent()->RefreshFootprintViewer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ public:
|
||||
~FOOTPRINTS_LISTBOX();
|
||||
|
||||
int GetCount();
|
||||
void SetSelection( int index, bool State = true );
|
||||
void SetSelection( int aIndex, bool aState = true );
|
||||
void SetSelectedFootprint( const LIB_ID& aFPID );
|
||||
void SetString( unsigned linecount, const wxString& text );
|
||||
void AppendLine( const wxString& text );
|
||||
|
||||
@@ -161,8 +161,8 @@ int CVPCB_CONTROL::ShowFootprintViewer( const TOOL_EVENT& aEvent )
|
||||
|
||||
if( !fpframe )
|
||||
{
|
||||
fpframe = (DISPLAY_FOOTPRINTS_FRAME*) m_frame->Kiway().Player(
|
||||
FRAME_CVPCB_DISPLAY, true, m_frame );
|
||||
fpframe = (DISPLAY_FOOTPRINTS_FRAME*) m_frame->Kiway().Player( FRAME_CVPCB_DISPLAY, true,
|
||||
m_frame );
|
||||
fpframe->Show( true );
|
||||
}
|
||||
else
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2004-2022 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
|
||||
@@ -182,10 +182,6 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope,
|
||||
// Store previous annotations for building info messages
|
||||
mapExistingAnnotation( previousAnnotation );
|
||||
|
||||
// If it is an annotation for all the symbols, reset previous annotation.
|
||||
if( aResetAnnotation )
|
||||
DeleteAnnotation( aAnnotateScope, &appendUndo );
|
||||
|
||||
// Set sheet number and number of sheets.
|
||||
SetSheetNumberAndCount();
|
||||
|
||||
@@ -205,6 +201,12 @@ void SCH_EDIT_FRAME::AnnotateSymbols( ANNOTATE_SCOPE_T aAnnotateScope,
|
||||
break;
|
||||
}
|
||||
|
||||
// Remove annotation only updates the "new" flag to indicate to the algorithm
|
||||
// that these references must be reannotated, but keeps the original reference
|
||||
// so that we can reannotate multi-unit symbols together.
|
||||
if( aResetAnnotation )
|
||||
references.RemoveAnnotation();
|
||||
|
||||
// Build additional list of references to be used during reannotation
|
||||
// to avoid duplicate designators (no additional references when annotating
|
||||
// the full schematic)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1992-2018 jean-pierre Charras <jp.charras at wanadoo.fr>
|
||||
* Copyright (C) 1992-2011 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2022 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 <sch_reference_list.h>
|
||||
#include <core/kicad_algo.h>
|
||||
|
||||
#include <wx/regex.h>
|
||||
#include <algorithm>
|
||||
@@ -48,7 +49,7 @@ void SCH_REFERENCE_LIST::RemoveItem( unsigned int aIndex )
|
||||
}
|
||||
|
||||
|
||||
bool SCH_REFERENCE_LIST::Contains( const SCH_REFERENCE& aItem )
|
||||
bool SCH_REFERENCE_LIST::Contains( const SCH_REFERENCE& aItem ) const
|
||||
{
|
||||
for( unsigned ii = 0; ii < GetCount(); ii++ )
|
||||
{
|
||||
@@ -154,14 +155,14 @@ bool SCH_REFERENCE_LIST::sortByTimeStamp( const SCH_REFERENCE& item1,
|
||||
}
|
||||
|
||||
|
||||
int SCH_REFERENCE_LIST::FindUnit( size_t aIndex, int aUnit ) const
|
||||
int SCH_REFERENCE_LIST::FindUnit( size_t aIndex, int aUnit, bool aIncludeNew ) const
|
||||
{
|
||||
int NumRef = flatList[aIndex].m_numRef;
|
||||
|
||||
for( size_t ii = 0; ii < flatList.size(); ii++ )
|
||||
{
|
||||
if( ( aIndex == ii )
|
||||
|| ( flatList[ii].m_isNew )
|
||||
|| ( flatList[ii].m_isNew && !aIncludeNew )
|
||||
|| ( flatList[ii].m_numRef != NumRef )
|
||||
|| ( flatList[aIndex].CompareRef( flatList[ii] ) != 0 ) )
|
||||
continue;
|
||||
@@ -210,34 +211,98 @@ void SCH_REFERENCE_LIST::GetRefsInUse( int aIndex, std::vector< int >& aIdList,
|
||||
aIdList.push_back( ref.m_numRef );
|
||||
}
|
||||
|
||||
sort( aIdList.begin(), aIdList.end() );
|
||||
std::sort( aIdList.begin(), aIdList.end() );
|
||||
|
||||
// Ensure each reference number appears only once. If there are symbols with
|
||||
// multiple parts per package the same number will be stored for each part.
|
||||
std::vector< int >::iterator it = unique( aIdList.begin(), aIdList.end() );
|
||||
|
||||
// Using the C++ unique algorithm only moves the duplicate entries to the end of
|
||||
// of the array. This removes the duplicate entries from the array.
|
||||
aIdList.resize( it - aIdList.begin() );
|
||||
alg::remove_duplicates( aIdList );
|
||||
}
|
||||
|
||||
|
||||
int SCH_REFERENCE_LIST::GetLastReference( int aIndex, int aMinValue ) const
|
||||
std::vector<int> SCH_REFERENCE_LIST::GetUnitsMatchingRef( const SCH_REFERENCE& aRef ) const
|
||||
{
|
||||
int lastNumber = aMinValue;
|
||||
std::vector<int> unitsList;
|
||||
|
||||
// Always add this reference to the list
|
||||
unitsList.push_back( aRef.m_unit );
|
||||
|
||||
for( SCH_REFERENCE ref : flatList )
|
||||
{
|
||||
if( ref.CompareValue( aRef ) != 0 )
|
||||
continue;
|
||||
|
||||
if( ref.CompareLibName( aRef ) != 0 )
|
||||
continue;
|
||||
|
||||
// Split if needed before comparing ref and number
|
||||
if( ref.IsSplitNeeded() )
|
||||
ref.Split();
|
||||
|
||||
if( ref.CompareRef( aRef ) != 0 )
|
||||
continue;
|
||||
|
||||
if( ref.m_numRef != aRef.m_numRef )
|
||||
continue;
|
||||
|
||||
unitsList.push_back( ref.m_unit );
|
||||
}
|
||||
|
||||
std::sort( unitsList.begin(), unitsList.end() );
|
||||
|
||||
// Ensure each reference number appears only once. If there are symbols with
|
||||
// multiple parts per package the same number will be stored for each part.
|
||||
alg::remove_duplicates( unitsList );
|
||||
|
||||
return unitsList;
|
||||
}
|
||||
|
||||
|
||||
int SCH_REFERENCE_LIST::FindFirstUnusedReference( const SCH_REFERENCE& aRef, int aMinValue,
|
||||
const std::vector<int>& aRequiredUnits ) const
|
||||
{
|
||||
// Create a map of references indexed by reference number, only including those with the same
|
||||
// reference prefix as aRef
|
||||
std::map<int, std::vector<SCH_REFERENCE>> refNumberMap;
|
||||
|
||||
for( const SCH_REFERENCE& ref : flatList )
|
||||
{
|
||||
// search only for the current reference prefix:
|
||||
if( flatList[aIndex].CompareRef( ref ) != 0 )
|
||||
if( ref.CompareRef( aRef ) != 0 )
|
||||
continue;
|
||||
|
||||
// update max value for the current reference prefix
|
||||
if( lastNumber < ref.m_numRef )
|
||||
lastNumber = ref.m_numRef;
|
||||
if( ref.m_isNew )
|
||||
continue; // It will be reannotated
|
||||
|
||||
refNumberMap[ref.m_numRef].push_back( ref );
|
||||
}
|
||||
|
||||
return lastNumber;
|
||||
// Start at the given minimum value
|
||||
int minFreeNumber = aMinValue;
|
||||
|
||||
for( ; refNumberMap[minFreeNumber].size() > 0; ++minFreeNumber )
|
||||
{
|
||||
auto isNumberInUse = [&]() -> bool
|
||||
{
|
||||
for( const int& unit : aRequiredUnits )
|
||||
{
|
||||
for( const SCH_REFERENCE& ref : refNumberMap[minFreeNumber] )
|
||||
{
|
||||
if( ref.CompareLibName( aRef ) || ref.CompareValue( aRef )
|
||||
|| ref.GetUnit() == unit )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
if( !isNumberInUse() )
|
||||
return minFreeNumber;
|
||||
}
|
||||
|
||||
return minFreeNumber;
|
||||
}
|
||||
|
||||
|
||||
@@ -261,7 +326,7 @@ std::vector<SYMBOL_INSTANCE_REFERENCE> SCH_REFERENCE_LIST::GetSymbolInstances()
|
||||
}
|
||||
|
||||
|
||||
int SCH_REFERENCE_LIST::CreateFirstFreeRefId( std::vector<int>& aIdList, int aFirstValue )
|
||||
int SCH_REFERENCE_LIST::createFirstFreeRefId( std::vector<int>& aIdList, int aFirstValue )
|
||||
{
|
||||
int expectedId = aFirstValue;
|
||||
|
||||
@@ -327,9 +392,9 @@ void SCH_REFERENCE_LIST::ReannotateDuplicates( const SCH_REFERENCE_LIST& aAdditi
|
||||
if( refstr[refstr.Len() - 1] == '?' )
|
||||
continue;
|
||||
|
||||
lockedSymbols[refstr].AddItem( ref );
|
||||
|
||||
ref.m_isNew = true; // We want to reannotate all references
|
||||
|
||||
lockedSymbols[refstr].AddItem( ref );
|
||||
}
|
||||
|
||||
Annotate( false, 0, 0, lockedSymbols, aAdditionalReferences, true );
|
||||
@@ -372,7 +437,6 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
|
||||
}
|
||||
|
||||
int LastReferenceNumber = 0;
|
||||
int NumberOfUnits, Unit;
|
||||
|
||||
/* calculate index of the first symbol with the same reference prefix
|
||||
* than the current symbol. All symbols having the same reference
|
||||
@@ -390,10 +454,6 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
|
||||
else
|
||||
minRefId = aStartNumber + 1;
|
||||
|
||||
// This is the list of all Id already in use for a given reference prefix.
|
||||
// Will be refilled for each new reference prefix.
|
||||
std::vector<int>idList;
|
||||
GetRefsInUse( first, idList, minRefId );
|
||||
|
||||
for( unsigned ii = 0; ii < flatList.size(); ii++ )
|
||||
{
|
||||
@@ -435,23 +495,20 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
|
||||
minRefId = ref_unit.m_sheetNum * aSheetIntervalId + 1;
|
||||
else
|
||||
minRefId = aStartNumber + 1;
|
||||
|
||||
GetRefsInUse( first, idList, minRefId );
|
||||
}
|
||||
|
||||
// Find references greater than current reference (unless not annotated)
|
||||
if( aStartAtCurrent && ref_unit.m_numRef > 0 )
|
||||
{
|
||||
minRefId = ref_unit.m_numRef;
|
||||
GetRefsInUse( first, idList, minRefId );
|
||||
}
|
||||
|
||||
// Annotation of one part per package symbols (trivial case).
|
||||
if( ref_unit.GetLibPart()->GetUnitCount() <= 1 )
|
||||
{
|
||||
if( ref_unit.m_isNew )
|
||||
{
|
||||
LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
|
||||
std::vector<int> idList;
|
||||
GetRefsInUse( first, idList, minRefId );
|
||||
LastReferenceNumber = createFirstFreeRefId( idList, minRefId );
|
||||
ref_unit.m_numRef = LastReferenceNumber;
|
||||
}
|
||||
|
||||
@@ -460,48 +517,46 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
|
||||
continue;
|
||||
}
|
||||
|
||||
// Annotation of multi-unit parts ( n units per part ) (complex case)
|
||||
NumberOfUnits = ref_unit.GetLibPart()->GetUnitCount();
|
||||
|
||||
if( ref_unit.m_isNew )
|
||||
{
|
||||
LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
|
||||
ref_unit.m_numRef = LastReferenceNumber;
|
||||
|
||||
ref_unit.m_flag = 1;
|
||||
}
|
||||
|
||||
// If this symbol is in aLockedUnitMap, copy the annotation to all
|
||||
// symbols that are not it
|
||||
if( lockedList != nullptr )
|
||||
{
|
||||
unsigned n_refs = lockedList->GetCount();
|
||||
std::vector<int> units = lockedList->GetUnitsMatchingRef( ref_unit );
|
||||
|
||||
for( unsigned thisRefI = 0; thisRefI < n_refs; ++thisRefI )
|
||||
if( ref_unit.m_isNew )
|
||||
{
|
||||
SCH_REFERENCE &thisRef = (*lockedList)[thisRefI];
|
||||
LastReferenceNumber = FindFirstUnusedReference( ref_unit, minRefId, units );
|
||||
ref_unit.m_numRef = LastReferenceNumber;
|
||||
ref_unit.m_isNew = false;
|
||||
ref_unit.m_flag = 1;
|
||||
}
|
||||
|
||||
if( thisRef.IsSameInstance( ref_unit ) )
|
||||
for( unsigned lockedRefI = 0; lockedRefI < n_refs; ++lockedRefI )
|
||||
{
|
||||
SCH_REFERENCE& lockedRef = ( *lockedList )[lockedRefI];
|
||||
|
||||
if( lockedRef.IsSameInstance( ref_unit ) )
|
||||
{
|
||||
// This is the symbol we're currently annotating. Hold the unit!
|
||||
ref_unit.m_unit = thisRef.m_unit;
|
||||
ref_unit.m_unit = lockedRef.m_unit;
|
||||
// lock this new full reference
|
||||
inUseRefs.insert( buildFullReference( ref_unit ) );
|
||||
}
|
||||
|
||||
if( thisRef.CompareValue( ref_unit ) != 0 )
|
||||
if( lockedRef.CompareValue( ref_unit ) != 0 )
|
||||
continue;
|
||||
|
||||
if( thisRef.CompareLibName( ref_unit ) != 0 )
|
||||
if( lockedRef.CompareLibName( ref_unit ) != 0 )
|
||||
continue;
|
||||
|
||||
// Find the matching symbol
|
||||
for( unsigned jj = ii + 1; jj < flatList.size(); jj++ )
|
||||
{
|
||||
if( ! thisRef.IsSameInstance( flatList[jj] ) )
|
||||
if( !lockedRef.IsSameInstance( flatList[jj] ) )
|
||||
continue;
|
||||
|
||||
wxString ref_candidate = buildFullReference( ref_unit, thisRef.m_unit );
|
||||
wxString ref_candidate = buildFullReference( ref_unit, lockedRef.m_unit );
|
||||
|
||||
// propagate the new reference and unit selection to the "old" symbol,
|
||||
// if this new full reference is not already used (can happens when initial
|
||||
@@ -518,56 +573,16 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if( ref_unit.m_isNew )
|
||||
{
|
||||
/* search for others units of this symbol.
|
||||
* we search for others parts that have the same value and the same
|
||||
* reference prefix (ref without ref number)
|
||||
*/
|
||||
for( Unit = 1; Unit <= NumberOfUnits; Unit++ )
|
||||
{
|
||||
if( ref_unit.m_unit == Unit )
|
||||
continue;
|
||||
|
||||
int found = FindUnit( ii, Unit );
|
||||
|
||||
if( found >= 0 )
|
||||
continue; // this unit exists for this reference (unit already annotated)
|
||||
|
||||
// Search a symbol to annotate ( same prefix, same value, not annotated)
|
||||
for( unsigned jj = ii + 1; jj < flatList.size(); jj++ )
|
||||
{
|
||||
auto& cmp_unit = flatList[jj];
|
||||
|
||||
if( cmp_unit.m_flag ) // already tested
|
||||
continue;
|
||||
|
||||
if( cmp_unit.CompareRef( ref_unit ) != 0 )
|
||||
continue;
|
||||
|
||||
if( cmp_unit.CompareValue( ref_unit ) != 0 )
|
||||
continue;
|
||||
|
||||
if( cmp_unit.CompareLibName( ref_unit ) != 0 )
|
||||
continue;
|
||||
|
||||
if( aUseSheetNum &&
|
||||
cmp_unit.GetSheetPath().Cmp( ref_unit.GetSheetPath() ) != 0 )
|
||||
continue;
|
||||
|
||||
if( !cmp_unit.m_isNew )
|
||||
continue;
|
||||
|
||||
// Symbol without reference number found, annotate it if possible.
|
||||
if( cmp_unit.m_unit == Unit )
|
||||
{
|
||||
cmp_unit.m_numRef = ref_unit.m_numRef;
|
||||
cmp_unit.m_flag = 1;
|
||||
cmp_unit.m_isNew = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Reference belonging to multi-unit symbol that has not yet been annotated. We don't
|
||||
// know what group this might belong to, so just find the first unused reference for
|
||||
// this specific unit. The other units will be annotated in the following passes.
|
||||
std::vector<int> units = { ref_unit.GetUnit() };
|
||||
LastReferenceNumber = FindFirstUnusedReference( ref_unit, minRefId, units );
|
||||
ref_unit.m_numRef = LastReferenceNumber;
|
||||
ref_unit.m_isNew = false;
|
||||
ref_unit.m_flag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -824,6 +839,16 @@ void SCH_REFERENCE::Split()
|
||||
}
|
||||
|
||||
|
||||
bool SCH_REFERENCE::IsSplitNeeded()
|
||||
{
|
||||
std::string refText = GetRefStr();
|
||||
|
||||
int ll = refText.length() - 1;
|
||||
|
||||
return ( refText[ll] == '?' ) || isdigit( refText[ll] );
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_REFERENCE_LIST::Shorthand( std::vector<SCH_REFERENCE> aList )
|
||||
{
|
||||
wxString retVal;
|
||||
|
||||
+182
-139
@@ -410,9 +410,6 @@ CONNECTION_SUBGRAPH::PRIORITY CONNECTION_SUBGRAPH::GetDriverPriority( SCH_ITEM*
|
||||
}
|
||||
|
||||
|
||||
bool CONNECTION_GRAPH::m_allowRealTime = true;
|
||||
|
||||
|
||||
void CONNECTION_GRAPH::Reset()
|
||||
{
|
||||
for( auto& subgraph : m_subgraphs )
|
||||
@@ -481,17 +478,6 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
|
||||
|
||||
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
|
||||
recalc_time.Show();
|
||||
|
||||
#ifndef DEBUG
|
||||
// Pressure relief valve for release builds
|
||||
const double max_recalc_time_msecs = 250.;
|
||||
|
||||
if( m_allowRealTime && ADVANCED_CFG::GetCfg().m_RealTimeConnectivity &&
|
||||
recalc_time.msecs() > max_recalc_time_msecs )
|
||||
{
|
||||
m_allowRealTime = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -2205,6 +2191,31 @@ CONNECTION_SUBGRAPH* CONNECTION_GRAPH::FindSubgraphByName( const wxString& aNetN
|
||||
}
|
||||
|
||||
|
||||
wxString CONNECTION_GRAPH::GetResolvedSubgraphName( const CONNECTION_SUBGRAPH* aSubGraph ) const
|
||||
{
|
||||
wxString retval = aSubGraph->GetNetName();
|
||||
bool found = false;
|
||||
|
||||
// This is a hacky way to find the true subgraph net name (why do we not store it?)
|
||||
// TODO: Remove once the actual netname of the subgraph is stored with the subgraph
|
||||
|
||||
for( auto it = m_net_name_to_subgraphs_map.begin(); it != m_net_name_to_subgraphs_map.end() && !found; ++it )
|
||||
{
|
||||
for( CONNECTION_SUBGRAPH* graph : it->second )
|
||||
{
|
||||
if( graph == aSubGraph )
|
||||
{
|
||||
retval = it->first;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
CONNECTION_SUBGRAPH* CONNECTION_GRAPH::FindFirstSubgraphByName( const wxString& aNetName )
|
||||
{
|
||||
auto it = m_net_name_to_subgraphs_map.find( aNetName );
|
||||
@@ -2372,7 +2383,9 @@ bool CONNECTION_GRAPH::ercCheckMultipleDrivers( const CONNECTION_SUBGRAPH* aSubg
|
||||
|
||||
if( driver->Type() == SCH_GLOBAL_LABEL_T
|
||||
|| driver->Type() == SCH_HIER_LABEL_T
|
||||
|| driver->Type() == SCH_LABEL_T )
|
||||
|| driver->Type() == SCH_LABEL_T
|
||||
|| ( driver->Type() == SCH_PIN_T
|
||||
&& static_cast<SCH_PIN*>( driver )->IsPowerConnection() ) )
|
||||
{
|
||||
wxString primaryName = aSubgraph->GetNameForDriver( aSubgraph->m_driver );
|
||||
wxString secondaryName = aSubgraph->GetNameForDriver( driver );
|
||||
@@ -2628,68 +2641,96 @@ bool CONNECTION_GRAPH::ercCheckBusToBusEntryConflicts( const CONNECTION_SUBGRAPH
|
||||
bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph )
|
||||
{
|
||||
ERC_SETTINGS& settings = m_schematic->ErcSettings();
|
||||
wxString msg;
|
||||
const SCH_SHEET_PATH& sheet = aSubgraph->m_sheet;
|
||||
SCH_SCREEN* screen = sheet.LastScreen();
|
||||
bool ok = true;
|
||||
SCH_PIN* pin = nullptr;
|
||||
|
||||
if( aSubgraph->m_no_connect != nullptr )
|
||||
std::set<SCH_PIN*> unique_pins;
|
||||
std::set<SCH_TEXT*> unique_labels;
|
||||
|
||||
wxString netName = GetResolvedSubgraphName( aSubgraph );
|
||||
|
||||
auto process_subgraph = [&]( const CONNECTION_SUBGRAPH* aProcessGraph )
|
||||
{
|
||||
bool has_invalid_items = false;
|
||||
bool has_other_items = false;
|
||||
SCH_PIN* pin = nullptr;
|
||||
std::vector<SCH_ITEM*> invalid_items;
|
||||
wxPoint noConnectPos = aSubgraph->m_no_connect->GetPosition();
|
||||
double minDist = 0;
|
||||
// Any subgraph that contains a no-connect should not
|
||||
// more than one pin (which would indicate it is connected
|
||||
|
||||
// Any subgraph that contains both a pin and a no-connect should not
|
||||
// contain any other driving items.
|
||||
|
||||
for( SCH_ITEM* item : aSubgraph->m_items )
|
||||
for( SCH_ITEM* item : aProcessGraph->m_items )
|
||||
{
|
||||
switch( item->Type() )
|
||||
{
|
||||
case SCH_PIN_T:
|
||||
{
|
||||
SCH_PIN* candidate = static_cast<SCH_PIN*>( item );
|
||||
double dist = VECTOR2I( candidate->GetTransformedPosition() - noConnectPos )
|
||||
.SquaredEuclideanNorm();
|
||||
SCH_PIN* test_pin = static_cast<SCH_PIN*>( item );
|
||||
|
||||
if( !pin || dist < minDist )
|
||||
// Only link NC to pin on the current subgraph being checked
|
||||
if( aProcessGraph == aSubgraph )
|
||||
pin = test_pin;
|
||||
|
||||
if( std::none_of( unique_pins.begin(), unique_pins.end(),
|
||||
[test_pin]( SCH_PIN* aPin )
|
||||
{
|
||||
return test_pin->IsStacked( aPin );
|
||||
}
|
||||
) )
|
||||
{
|
||||
pin = candidate;
|
||||
minDist = dist;
|
||||
unique_pins.insert( test_pin );
|
||||
}
|
||||
|
||||
has_invalid_items |= has_other_items;
|
||||
has_other_items = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SCH_LINE_T:
|
||||
case SCH_JUNCTION_T:
|
||||
case SCH_NO_CONNECT_T:
|
||||
break;
|
||||
|
||||
case SCH_LABEL_T:
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
case SCH_HIER_LABEL_T:
|
||||
unique_labels.insert( static_cast<SCH_TEXT*>( item ) );
|
||||
KI_FALLTHROUGH;
|
||||
default:
|
||||
has_invalid_items = true;
|
||||
has_other_items = true;
|
||||
invalid_items.push_back( item );
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if( pin && has_invalid_items && settings.IsTestEnabled( ERCE_NOCONNECT_CONNECTED ) )
|
||||
auto it = m_net_name_to_subgraphs_map.find( netName );
|
||||
|
||||
if( it != m_net_name_to_subgraphs_map.end() )
|
||||
{
|
||||
for( const CONNECTION_SUBGRAPH* subgraph : it->second )
|
||||
{
|
||||
process_subgraph( subgraph );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
process_subgraph( aSubgraph );
|
||||
}
|
||||
|
||||
if( aSubgraph->m_no_connect != nullptr )
|
||||
{
|
||||
if( unique_pins.size() > 1 && settings.IsTestEnabled( ERCE_NOCONNECT_CONNECTED ) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_NOCONNECT_CONNECTED );
|
||||
ercItem->SetItems( pin );
|
||||
wxPoint pos;
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, pin->GetTransformedPosition() );
|
||||
if( pin )
|
||||
{
|
||||
ercItem->SetItems( pin, aSubgraph->m_no_connect );
|
||||
pos = pin->GetTransformedPosition();
|
||||
}
|
||||
else
|
||||
{
|
||||
ercItem->SetItems( aSubgraph->m_no_connect );
|
||||
pos = aSubgraph->m_no_connect->GetPosition();
|
||||
}
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
|
||||
screen->Append( marker );
|
||||
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if( !has_other_items && settings.IsTestEnabled( ERCE_NOCONNECT_NOT_CONNECTED ) )
|
||||
if( unique_pins.empty() && unique_labels.empty() && settings.IsTestEnabled( ERCE_NOCONNECT_NOT_CONNECTED ) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_NOCONNECT_NOT_CONNECTED );
|
||||
ercItem->SetItems( aSubgraph->m_no_connect );
|
||||
@@ -2717,12 +2758,11 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph
|
||||
// Stacked pins do not count as other connections but non-stacked pins do
|
||||
if( !has_other_connections && !pins.empty() )
|
||||
{
|
||||
SCH_PIN* pin = static_cast<SCH_PIN*>( item );
|
||||
SCH_PIN* test_pin = static_cast<SCH_PIN*>( item );
|
||||
|
||||
for( SCH_PIN* other_pin : pins )
|
||||
{
|
||||
if( other_pin->GetParent() != pin->GetParent()
|
||||
|| other_pin->GetPosition() != pin->GetPosition() )
|
||||
if( !test_pin->IsStacked( other_pin ) )
|
||||
{
|
||||
has_other_connections = true;
|
||||
break;
|
||||
@@ -2744,7 +2784,17 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph
|
||||
}
|
||||
|
||||
// For many checks, we can just use the first pin
|
||||
SCH_PIN* pin = pins.empty() ? nullptr : pins[0];
|
||||
pin = pins.empty() ? nullptr : pins[0];
|
||||
|
||||
// But if there is a power pin, it might be connected elsewhere
|
||||
for( SCH_PIN* test_pin : pins )
|
||||
{
|
||||
if( test_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
|
||||
{
|
||||
pin = test_pin;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if invisible power input pins connect to anything else via net name,
|
||||
// but not for power symbols as the ones in the standard library all have invisible pins
|
||||
@@ -2852,13 +2902,11 @@ bool CONNECTION_GRAPH::ercCheckFloatingWires( const CONNECTION_SUBGRAPH* aSubgra
|
||||
bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph )
|
||||
{
|
||||
// Label connection rules:
|
||||
// Any label without a no-connect needs to have at least 2 pins, otherwise it is invalid
|
||||
// Local labels are flagged if they don't connect to any pins and don't have a no-connect
|
||||
// Global labels are flagged if they appear only once, don't connect to any local labels,
|
||||
// and don't have a no-connect marker
|
||||
|
||||
// So, if there is a no-connect, we will never generate a warning here
|
||||
if( aSubgraph->m_no_connect )
|
||||
return true;
|
||||
|
||||
if( !aSubgraph->m_driver_connection )
|
||||
return true;
|
||||
@@ -2868,30 +2916,36 @@ bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph )
|
||||
if( aSubgraph->m_driver_connection->IsBus() )
|
||||
return true;
|
||||
|
||||
ERC_SETTINGS& settings = m_schematic->ErcSettings();
|
||||
bool ok = true;
|
||||
SCH_TEXT* text = nullptr;
|
||||
bool hasOtherConnections = false;
|
||||
int pinCount = 0;
|
||||
ERC_SETTINGS& settings = m_schematic->ErcSettings();
|
||||
bool ok = true;
|
||||
int pinCount = 0;
|
||||
bool has_nc = !!aSubgraph->m_no_connect;
|
||||
|
||||
std::map<KICAD_T, std::vector<SCH_TEXT*>> label_map;
|
||||
|
||||
|
||||
auto hasPins =
|
||||
[]( const CONNECTION_SUBGRAPH* aLocSubgraph )
|
||||
[]( const CONNECTION_SUBGRAPH* aLocSubgraph ) -> int
|
||||
{
|
||||
for( const SCH_ITEM* item : aLocSubgraph->m_items )
|
||||
{
|
||||
switch( item->Type() )
|
||||
{
|
||||
case SCH_PIN_T:
|
||||
case SCH_SHEET_PIN_T:
|
||||
return true;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return
|
||||
std::count_if( aLocSubgraph->m_items.begin(), aLocSubgraph->m_items.end(), []( const SCH_ITEM* item )
|
||||
{ return item->Type() == SCH_PIN_T; } );
|
||||
};
|
||||
|
||||
auto reportError = [&]( SCH_TEXT* aText, int errCode )
|
||||
{
|
||||
if( settings.IsTestEnabled( errCode ) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( errCode );
|
||||
ercItem->SetItems( aText );
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, aText->GetPosition() );
|
||||
aSubgraph->m_sheet.LastScreen()->Append( marker );
|
||||
}
|
||||
};
|
||||
|
||||
pinCount = hasPins( aSubgraph );
|
||||
|
||||
for( SCH_ITEM* item : aSubgraph->m_items )
|
||||
{
|
||||
switch( item->Type() )
|
||||
@@ -2900,105 +2954,94 @@ bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph )
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
case SCH_HIER_LABEL_T:
|
||||
{
|
||||
text = static_cast<SCH_TEXT*>( item );
|
||||
SCH_TEXT* text = static_cast<SCH_TEXT*>( item );
|
||||
|
||||
label_map[item->Type()].push_back( text );
|
||||
|
||||
// Below, we'll create an ERC if the whole subgraph is unconnected. But, additionally,
|
||||
// we want to error if an individual label in the subgraph is floating, even if it's
|
||||
// connected to other valid things by way of another label on the same sheet.
|
||||
|
||||
if( text->IsDangling() && settings.IsTestEnabled( ERCE_LABEL_NOT_CONNECTED ) )
|
||||
if( text->IsDangling() )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LABEL_NOT_CONNECTED );
|
||||
ercItem->SetItems( text );
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, text->GetPosition() );
|
||||
aSubgraph->m_sheet.LastScreen()->Append( marker );
|
||||
ok = false;
|
||||
reportError( text, ERCE_LABEL_NOT_CONNECTED );
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SCH_PIN_T:
|
||||
case SCH_SHEET_PIN_T:
|
||||
hasOtherConnections = true;
|
||||
pinCount++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !text )
|
||||
if( label_map.empty() )
|
||||
return true;
|
||||
|
||||
bool isGlobal = text->Type() == SCH_GLOBAL_LABEL_T;
|
||||
int errCode = isGlobal ? ERCE_GLOBLABEL : ERCE_LABEL_NOT_CONNECTED;
|
||||
wxString netName = GetResolvedSubgraphName( aSubgraph );
|
||||
|
||||
wxCHECK_MSG( m_schematic, true, wxT( "Null m_schematic in CONNECTION_GRAPH::ercCheckLabels" ) );
|
||||
wxCHECK_MSG( m_schematic, true, "Null m_schematic in CONNECTION_GRAPH::ercCheckLabels" );
|
||||
|
||||
wxString name = EscapeString( text->GetShownText(), CTX_NETNAME );
|
||||
// Labels that have multiple pins connected are not dangling (may be used for naming segments)
|
||||
// so leave them without errors here
|
||||
if( pinCount > 1 )
|
||||
return true;
|
||||
|
||||
if( isGlobal )
|
||||
for( auto label_el : label_map )
|
||||
{
|
||||
// This will be set to true if the global is connected to a pin above, but we want to
|
||||
// reset this to false so that globals get flagged if they only have a single instance
|
||||
// connected to a single pin
|
||||
hasOtherConnections = ( pinCount > 1 );
|
||||
KICAD_T type = label_el.first;
|
||||
std::vector<SCH_TEXT*>& label_vec = label_el.second;
|
||||
|
||||
auto it = m_net_name_to_subgraphs_map.find( name );
|
||||
|
||||
if( it != m_net_name_to_subgraphs_map.end() )
|
||||
switch( type )
|
||||
{
|
||||
if( it->second.size() > 1 || aSubgraph->m_multiple_drivers )
|
||||
hasOtherConnections = true;
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
if( !settings.IsTestEnabled( ERCE_GLOBLABEL ) )
|
||||
continue;
|
||||
|
||||
break;
|
||||
default:
|
||||
if( !settings.IsTestEnabled( ERCE_LABEL_NOT_CONNECTED ) )
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( text->Type() == SCH_HIER_LABEL_T )
|
||||
{
|
||||
// For a hier label, check if the parent pin is connected
|
||||
if( aSubgraph->m_hier_parent
|
||||
&& ( aSubgraph->m_hier_parent->m_strong_driver
|
||||
|| aSubgraph->m_hier_parent->m_drivers.size() > 1) )
|
||||
{
|
||||
// For now, a simple check: if there is more than one driver, the parent is probably
|
||||
// connected elsewhere (because at least one driver will be the hier pin itself)
|
||||
hasOtherConnections = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto pair = std::make_pair( aSubgraph->m_sheet, name );
|
||||
auto it = m_local_label_cache.find( pair );
|
||||
|
||||
if( it != m_local_label_cache.end() && it->second.size() > 1 )
|
||||
for( SCH_TEXT* text : label_vec )
|
||||
{
|
||||
for( const CONNECTION_SUBGRAPH* neighbor : it->second )
|
||||
int allPins = pinCount;
|
||||
|
||||
auto net_it = m_net_name_to_subgraphs_map.find( netName );
|
||||
|
||||
if( net_it != m_net_name_to_subgraphs_map.end() )
|
||||
{
|
||||
if( neighbor == aSubgraph )
|
||||
continue;
|
||||
|
||||
if( hasPins( neighbor ) )
|
||||
for( const CONNECTION_SUBGRAPH* neighbor : net_it->second )
|
||||
{
|
||||
hasOtherConnections = true;
|
||||
break;
|
||||
if( neighbor == aSubgraph )
|
||||
continue;
|
||||
|
||||
if( neighbor->m_no_connect )
|
||||
has_nc = true;
|
||||
|
||||
allPins += hasPins( neighbor );
|
||||
}
|
||||
}
|
||||
|
||||
if( allPins == 1 && !has_nc )
|
||||
{
|
||||
reportError( text,
|
||||
type == SCH_GLOBAL_LABEL_T ? ERCE_GLOBLABEL : ERCE_LABEL_NOT_CONNECTED );
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if( allPins == 0 )
|
||||
{
|
||||
reportError( text,
|
||||
type == SCH_GLOBAL_LABEL_T ? ERCE_GLOBLABEL : ERCE_LABEL_NOT_CONNECTED );
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !hasOtherConnections && settings.IsTestEnabled( errCode ) )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( errCode );
|
||||
ercItem->SetItems( text );
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, text->GetPosition() );
|
||||
aSubgraph->m_sheet.LastScreen()->Append( marker );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
@@ -324,6 +324,13 @@ public:
|
||||
|
||||
CONNECTION_SUBGRAPH* GetSubgraphForItem( SCH_ITEM* aItem );
|
||||
|
||||
/**
|
||||
* Returns the fully-resolved netname for a given subgraph
|
||||
* @param aSubGraph Reference to the subgraph
|
||||
* @return Netname string usable with m_net_name_to_subgraphs_map
|
||||
*/
|
||||
wxString GetResolvedSubgraphName( const CONNECTION_SUBGRAPH* aSubGraph ) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Updates the graphical connectivity between items (i.e. where they touch)
|
||||
@@ -530,10 +537,6 @@ private:
|
||||
*/
|
||||
int ercCheckHierSheets();
|
||||
|
||||
public:
|
||||
// TODO(JE) Remove this when pressure valve is removed
|
||||
static bool m_allowRealTime;
|
||||
|
||||
private:
|
||||
// All the sheets in the schematic (as long as we don't have partial updates)
|
||||
SCH_SHEET_LIST m_sheetList;
|
||||
|
||||
@@ -578,11 +578,6 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
||||
NETLIST_EXPORTER_KICAD exporter( &Schematic() );
|
||||
STRING_FORMATTER formatter;
|
||||
|
||||
// TODO remove once real-time connectivity is a given
|
||||
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
|
||||
// Ensure the netlist data is up to date:
|
||||
RecalculateConnections( NO_CLEANUP );
|
||||
|
||||
exporter.Format( &formatter, GNL_ALL | GNL_OPT_KICAD );
|
||||
|
||||
payload = formatter.GetString();
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
// Do not edit this file, it is autogenerated by CMake from the .md file
|
||||
_HKI( "# 1 - Full documentation\n"
|
||||
"\n"
|
||||
"The Eeschema documentation (*eeschema.html*) describes this intermediate netlist and gives examples(chapter ***creating customized netlists and bom files***).\n"
|
||||
"\n"
|
||||
"# 2 - The intermediate Netlist File\n"
|
||||
"\n"
|
||||
"BOM files (and netlist files) can be created from an *Intermediate netlist file* created by Eeschema.\n"
|
||||
"\n"
|
||||
"This file uses XML syntax and is called the intermediate netlist. The intermediate netlist includes a large amount of data about your board and because of this, it can be used with post-processing to create a BOM or other reports.\n"
|
||||
"\n"
|
||||
"Depending on the output (BOM or netlist), different subsets of the complete Intermediate Netlist file will be used in the post-processing.\n"
|
||||
"\n"
|
||||
"# 3 - Conversion to a new format\n"
|
||||
"\n"
|
||||
"By applying a post-processing filter to the Intermediate netlist file you can generate foreign netlist files as well as BOM files. Because this conversion is a text to text transformation, this post-processing filter can be written using *Python*, *XSLT*, or any other tool capable of taking XML as input.\n"
|
||||
"\n"
|
||||
"XSLT itself is a XML language suitable for XML transformations. There is a free program called `xsltproc` that you can download and install. The `xsltproc` program can be used to read the Intermediate XML netlist input file, apply a style-sheet to transform the input, and save the results in an output file. Use of `xsltproc` requires a style-sheet file using XSLT conventions. The full conversion process is handled by Eeschema, after it is configured once to run `xsltproc` in a specific way.\n"
|
||||
"\n"
|
||||
"A Python script is somewhat more easy to create.\n"
|
||||
"\n"
|
||||
"# 4 - Initialization of the dialog window\n"
|
||||
"\n"
|
||||
"You should add a new plugin (a script) in the plugin list by clicking on the Add Plugin button.\n"
|
||||
"\n"
|
||||
"## 4.1 - Plugin Configuration Parameters\n"
|
||||
"\n"
|
||||
"The Eeschema plug-in configuration dialog requires the following information:\n"
|
||||
"\n"
|
||||
" * The title: for instance, the name of the netlist format.\n"
|
||||
" * The command line to launch the converter (usually a script).\n"
|
||||
"\n"
|
||||
"***Note (Windows only):***\n"
|
||||
"*By default, the command line runs with hidden console window and output is redirected to \"Plugin info\" field. To show the window of the running command, set the checkbox \"Show console window\".*\n"
|
||||
"\n"
|
||||
"Once you click on the generate button the following will happen:\n"
|
||||
"\n"
|
||||
"1. Eeschema creates an intermediate netlist file \\*.xml, for instance `test.xml`.\n"
|
||||
"2. Eeschema runs the script from the command line to create the final output file.\n"
|
||||
"\n"
|
||||
"## 4.2 - Generate netlist files with the command line\n"
|
||||
"\n"
|
||||
"Assuming we are using the program `xsltproc.exe` to apply the sheet style to the intermediate file, `xsltproc.exe` is executed with the following command.\n"
|
||||
"\n"
|
||||
"```\n"
|
||||
"xsltproc.exe -o <output filename> <style-sheet filename> <input XML file to convert>\n"
|
||||
"```\n"
|
||||
"\n"
|
||||
"On Windows the command line is the following.\n"
|
||||
"\n"
|
||||
"```\n"
|
||||
"f:/kicad/bin/xsltproc.exe -o \"%O\" f:/kicad/bin/plugins/myconverter.xsl \"%I\"\n"
|
||||
"```\n"
|
||||
"\n"
|
||||
"On Linux the command becomes as following.\n"
|
||||
"\n"
|
||||
"```\n"
|
||||
"xsltproc -o \"%O\" /usr/local/kicad/bin/plugins/myconverter .xsl \"%I\"\n"
|
||||
"```\n"
|
||||
"where `myconverter.xsl` is the style-sheet that you are applying.\n"
|
||||
"\n"
|
||||
"Do not forget the double quotes around the file names, this allows them to have spaces after the substitution by Eeschema.\n"
|
||||
"\n"
|
||||
"If a Python script is used, the command line is something like (depending on the Python script):\n"
|
||||
"\n"
|
||||
"```\n"
|
||||
"python f:/kicad/bin/plugins/bom-in-python/myconverter.py \"%I\" \"%O\"\n"
|
||||
"```\n"
|
||||
"\n"
|
||||
"or\n"
|
||||
"\n"
|
||||
"```\n"
|
||||
"python /usr/local/kicad/bin/plugins/bom-in-python/myconverter .xsl \"%I\" \"%O\"\n"
|
||||
"```\n"
|
||||
"\n"
|
||||
"The command line format accepts parameters for filenames. The supported formatting parameters are:\n"
|
||||
"\n"
|
||||
" * `%B`: base filename of selected output file, minus path and extension.\n"
|
||||
" * `%P`: project directory, without name and without trailing '/'.\n"
|
||||
" * `%I`: complete filename and path of the temporary input file\n"
|
||||
"(the intermediate net file).\n"
|
||||
" * `%O`: complete filename and path (but without extension) of the user\n"
|
||||
"chosen output file.\n"
|
||||
"\n"
|
||||
"`%I` will be replaced by the actual intermediate file name (usually the full root sheet filename with extension \".xml\").\n"
|
||||
"`%O` will be replaced by the actual output file name (the full root sheet filename minus extension).\n"
|
||||
"`%B` will be replaced by the actual output short file name (the short root sheet filename minus extension).\n"
|
||||
"`%P` will be replaced by the actual current project path.\n"
|
||||
"\n"
|
||||
"## 4.3 - Command line format:\n"
|
||||
"\n"
|
||||
"### 4.3.1 - Remark:\n"
|
||||
"\n"
|
||||
"Most of time, the created file must have an extension, depending on its type.\n"
|
||||
"Therefore you have to add to the option ***%O*** the right file extension.\n"
|
||||
"\n"
|
||||
"For instance:\n"
|
||||
"\n"
|
||||
" * **%O.csv** to create a .csv file (comma separated value file).\n"
|
||||
" * **%O.htm** to create a .html file.\n"
|
||||
" * **%O.bom** to create a .bom file.\n"
|
||||
"\n"
|
||||
"### 4.3.2 Example for xsltproc:\n"
|
||||
"\n"
|
||||
"The command line format for xsltproc is the following:\n"
|
||||
"\n"
|
||||
"```\n"
|
||||
"<path of xsltproc> xsltproc <xsltproc parameters>\n"
|
||||
"```\n"
|
||||
"\n"
|
||||
"On Windows:\n"
|
||||
"```\n"
|
||||
"f:/kicad/bin/xsltproc.exe -o \"%O.bom\" f:/kicad/bin/plugins/netlist_form_pads-pcb.xsl \"%I\"\n"
|
||||
"```\n"
|
||||
"\n"
|
||||
"On Linux:\n"
|
||||
"```\n"
|
||||
"xsltproc -o \"%O.bom\" /usr/local/kicad/bin/plugins/netlist_form_pads-pcb.xsl \"%I\"\n"
|
||||
"```\n"
|
||||
"\n"
|
||||
"The above examples assume `xsltproc` is installed on your PC under Windows and xsl files located in `<path_to_kicad>/kicad/bin/plugins/`.\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"### 4.3.3 Example for Python scripts:\n"
|
||||
"\n"
|
||||
"Assuming python is installed on your PC, and python scripts are located in\n"
|
||||
"\n"
|
||||
" `<path_to_kicad>/kicad/bin/plugins/bom-in-python/`,\n"
|
||||
"\n"
|
||||
"the command line format for python is something like:\n"
|
||||
"\n"
|
||||
"```\n"
|
||||
"python <script file name> <input filename> <output filename>\n"
|
||||
"```\n"
|
||||
"\n"
|
||||
"On Windows:\n"
|
||||
"```\n"
|
||||
"python.exe f:/kicad/bin/plugins/bom-in-python/my_python_script.py \"%I\" \"%O.html\"\n"
|
||||
"```\n"
|
||||
"\n"
|
||||
"On Linux:\n"
|
||||
"```\n"
|
||||
"python /usr/local/kicad/bin/plugins/bom-in-python/my_python_script.py \"%I\" \"%O.csv\"\n"
|
||||
"```\n"
|
||||
"" );
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020-2021 CERN
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* @author Wayne Stambaugh <stambaughw@gmail.com>
|
||||
*
|
||||
@@ -25,14 +25,12 @@
|
||||
#include <bitmaps.h>
|
||||
#include <string_utils.h> // WildCompareString
|
||||
#include <kiway.h>
|
||||
#include <lib_id.h>
|
||||
#include <refdes_utils.h>
|
||||
#include <core/kicad_algo.h>
|
||||
#include <dialog_change_symbols.h>
|
||||
#include <sch_symbol.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <sch_screen.h>
|
||||
#include <sch_sheet_path.h>
|
||||
#include <schematic.h>
|
||||
#include <template_fieldnames.h>
|
||||
#include <wx_html_report_panel.h>
|
||||
@@ -100,7 +98,7 @@ DIALOG_CHANGE_SYMBOLS::DIALOG_CHANGE_SYMBOLS( SCH_EDIT_FRAME* aParent, SCH_SYMBO
|
||||
|
||||
for( int i = 0; i < MANDATORY_FIELDS; ++i )
|
||||
{
|
||||
m_fieldsBox->Append( TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) );
|
||||
m_fieldsBox->Append( TEMPLATE_FIELDNAME::GetDefaultFieldName( i, DO_TRANSLATE ) );
|
||||
|
||||
if( i == REFERENCE_FIELD )
|
||||
m_fieldsBox->Check( i, g_selectRefDes );
|
||||
@@ -399,7 +397,9 @@ void DIALOG_CHANGE_SYMBOLS::onOkButtonClicked( wxCommandEvent& aEvent )
|
||||
m_updateFields.insert( dummy_field.GetCanonicalName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_updateFields.insert( m_fieldsBox->GetString( i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,15 +451,16 @@ bool DIALOG_CHANGE_SYMBOLS::isMatch( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aInsta
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
|
||||
int DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
|
||||
{
|
||||
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
|
||||
|
||||
wxCHECK( frame, false );
|
||||
|
||||
LIB_ID newId;
|
||||
bool appendToUndo = false;
|
||||
bool changed = false;
|
||||
wxString msg;
|
||||
int matchesProcessed = 0;
|
||||
SCH_SYMBOL* symbol = nullptr;
|
||||
SCH_SHEET_LIST hierarchy = frame->Schematic().GetSheets();
|
||||
|
||||
if( m_mode == MODE::CHANGE )
|
||||
@@ -470,70 +471,258 @@ bool DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO> symbols;
|
||||
|
||||
for( SCH_SHEET_PATH& instance : hierarchy )
|
||||
{
|
||||
SCH_SCREEN* screen = instance.LastScreen();
|
||||
|
||||
wxCHECK2( screen, continue );
|
||||
|
||||
std::vector<SCH_SYMBOL*> symbols;
|
||||
|
||||
// Fetch all the symbols that meet the change criteria.
|
||||
for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
|
||||
symbols.push_back( static_cast<SCH_SYMBOL*>( item ) );
|
||||
|
||||
for( SCH_SYMBOL* symbol : symbols )
|
||||
{
|
||||
symbol = static_cast<SCH_SYMBOL*>( item );
|
||||
|
||||
wxCHECK2( symbol, continue );
|
||||
|
||||
if( !isMatch( symbol, &instance ) )
|
||||
continue;
|
||||
|
||||
if( m_mode == MODE::UPDATE )
|
||||
newId = symbol->GetLibId();
|
||||
|
||||
auto it = symbols.find( symbol );
|
||||
|
||||
if( it == symbols.end() )
|
||||
{
|
||||
if( processSymbol( symbol, &instance, symbol->GetLibId(), appendToUndo ) )
|
||||
changed = true;
|
||||
SYMBOL_CHANGE_INFO info;
|
||||
|
||||
info.m_Instances.emplace_back( instance );
|
||||
info.m_LibId = newId;
|
||||
symbols.insert( { symbol, info } );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( processSymbol( symbol, &instance, newId, appendToUndo ) )
|
||||
changed = true;
|
||||
it->second.m_Instances.emplace_back( instance );
|
||||
}
|
||||
|
||||
if( changed )
|
||||
appendToUndo = true;
|
||||
}
|
||||
}
|
||||
|
||||
matchesProcessed += processSymbols( symbols );
|
||||
|
||||
frame->GetCurrentSheet().UpdateAllScreenReferences();
|
||||
|
||||
return changed;
|
||||
return matchesProcessed;
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_PATH* aInstance,
|
||||
const LIB_ID& aNewId, bool aAppendToUndo )
|
||||
int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
|
||||
SYMBOL_CHANGE_INFO>& aSymbols )
|
||||
{
|
||||
wxCHECK( aSymbol, false );
|
||||
wxCHECK( aNewId.IsValid(), false );
|
||||
wxCHECK( !aSymbols.empty(), 0 );
|
||||
|
||||
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
|
||||
SCH_SCREEN* screen = aInstance->LastScreen();
|
||||
int matchesProcessed = 0;
|
||||
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
|
||||
SCH_SCREEN* screen = nullptr;
|
||||
SCH_SYMBOL* symbol = nullptr;
|
||||
LIB_SYMBOL* libSymbol = nullptr;
|
||||
std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO> symbols = aSymbols;
|
||||
|
||||
wxCHECK( frame, false );
|
||||
wxCHECK( frame, 0 );
|
||||
|
||||
LIB_ID oldId = aSymbol->GetLibId();
|
||||
wxString msg;
|
||||
wxString references;
|
||||
|
||||
for( SYMBOL_INSTANCE_REFERENCE instance : aSymbol->GetInstanceReferences() )
|
||||
auto it = symbols.begin();
|
||||
|
||||
// Remove all symbols that don't have a valid library symbol link or enough units to
|
||||
// satify the library symbol update.
|
||||
while( it != symbols.end() )
|
||||
{
|
||||
symbol = it->first;
|
||||
|
||||
wxCHECK2( symbol && it->second.m_LibId.IsValid(), continue );
|
||||
|
||||
libSymbol = frame->GetLibSymbol( it->second.m_LibId );
|
||||
|
||||
if( !libSymbol )
|
||||
{
|
||||
msg = getSymbolReferences( *symbol, it->second.m_LibId );
|
||||
msg << wxT( ": " ) << _( "*** symbol not found ***" );
|
||||
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
|
||||
it = symbols.erase( it );
|
||||
continue;
|
||||
}
|
||||
|
||||
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
|
||||
|
||||
if( flattenedSymbol->GetUnitCount() < symbol->GetUnit() )
|
||||
{
|
||||
msg = getSymbolReferences( *symbol, it->second.m_LibId );
|
||||
msg << wxT( ": " ) << _( "*** new symbol has too few units ***" );
|
||||
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
|
||||
it = symbols.erase( it );
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
// Removing the symbol needs to be done before the LIB_SYMBOL is changed to prevent stale
|
||||
// library symbols in the schematic file.
|
||||
for( auto& pair : symbols )
|
||||
{
|
||||
symbol = pair.first;
|
||||
|
||||
wxCHECK( symbol && !pair.second.m_Instances.empty(), 0 );
|
||||
|
||||
screen = pair.second.m_Instances[0].LastScreen();
|
||||
|
||||
wxCHECK( screen, 0 );
|
||||
|
||||
screen->Remove( symbol );
|
||||
frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, true );
|
||||
}
|
||||
|
||||
for( auto& pair : symbols )
|
||||
{
|
||||
symbol = pair.first;
|
||||
|
||||
if( pair.second.m_LibId != symbol->GetLibId() )
|
||||
symbol->SetLibId( pair.second.m_LibId );
|
||||
|
||||
libSymbol = frame->GetLibSymbol( pair.second.m_LibId );
|
||||
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
|
||||
|
||||
symbol->SetLibSymbol( flattenedSymbol.release() );
|
||||
|
||||
if( m_resetAttributes->GetValue() )
|
||||
{
|
||||
symbol->SetIncludeInBom( libSymbol->GetIncludeInBom() );
|
||||
symbol->SetIncludeOnBoard( libSymbol->GetIncludeOnBoard() );
|
||||
}
|
||||
|
||||
bool removeExtras = m_removeExtraBox->GetValue();
|
||||
bool resetVis = m_resetFieldVisibilities->GetValue();
|
||||
bool resetEffects = m_resetFieldEffects->GetValue();
|
||||
bool resetPositions = m_resetFieldPositions->GetValue();
|
||||
|
||||
for( unsigned i = 0; i < symbol->GetFields().size(); ++i )
|
||||
{
|
||||
SCH_FIELD& field = symbol->GetFields()[i];
|
||||
LIB_FIELD* libField = nullptr;
|
||||
|
||||
// Mandatory fields always exist in m_updateFields, but these names can be translated.
|
||||
// so use GetCanonicalName().
|
||||
if( !alg::contains( m_updateFields, field.GetCanonicalName() ) )
|
||||
continue;
|
||||
|
||||
if( i < MANDATORY_FIELDS )
|
||||
libField = libSymbol->GetFieldById( (int) i );
|
||||
else
|
||||
libField = libSymbol->FindField( field.GetName() );
|
||||
|
||||
if( libField )
|
||||
{
|
||||
bool resetText = libField->GetText().IsEmpty() ? m_resetEmptyFields->GetValue()
|
||||
: m_resetFieldText->GetValue();
|
||||
|
||||
if( resetText )
|
||||
{
|
||||
for( const SCH_SHEET_PATH& instance : pair.second.m_Instances )
|
||||
{
|
||||
if( i == REFERENCE_FIELD )
|
||||
symbol->SetRef( &instance,
|
||||
UTIL::GetRefDesUnannotated( libField->GetText() ) );
|
||||
else if( i == VALUE_FIELD )
|
||||
symbol->SetValue( &instance, UnescapeString( libField->GetText() ) );
|
||||
else if( i == FOOTPRINT_FIELD )
|
||||
symbol->SetFootprint( &instance, libField->GetText() );
|
||||
else
|
||||
field.SetText( libField->GetText() );
|
||||
}
|
||||
}
|
||||
|
||||
if( resetVis )
|
||||
field.SetVisible( libField->IsVisible() );
|
||||
|
||||
if( resetEffects )
|
||||
{
|
||||
// Careful: the visible bit and position are also in Effects
|
||||
bool visible = field.IsVisible();
|
||||
wxPoint pos = field.GetPosition();
|
||||
|
||||
field.SetEffects( *libField );
|
||||
|
||||
field.SetVisible( visible );
|
||||
field.SetPosition( pos );
|
||||
}
|
||||
|
||||
if( resetPositions )
|
||||
field.SetTextPos( symbol->GetPosition() + libField->GetTextPos() );
|
||||
}
|
||||
else if( i >= MANDATORY_FIELDS && removeExtras )
|
||||
{
|
||||
symbol->RemoveField( field.GetName() );
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<LIB_FIELD*> libFields;
|
||||
libSymbol->GetFields( libFields );
|
||||
|
||||
for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
|
||||
{
|
||||
const LIB_FIELD& libField = *libFields[i];
|
||||
|
||||
if( !alg::contains( m_updateFields, libField.GetCanonicalName() ) )
|
||||
continue;
|
||||
|
||||
if( !symbol->FindField( libField.GetName(), false ) )
|
||||
{
|
||||
wxString fieldName = libField.GetCanonicalName();
|
||||
SCH_FIELD newField( wxPoint( 0, 0 ), symbol->GetFieldCount(), symbol,
|
||||
fieldName );
|
||||
SCH_FIELD* schField = symbol->AddField( newField );
|
||||
|
||||
schField->SetEffects( libField );
|
||||
schField->SetText( libField.GetText() );
|
||||
schField->SetTextPos( symbol->GetPosition() + libField.GetTextPos() );
|
||||
}
|
||||
}
|
||||
|
||||
symbol->SetSchSymbolLibraryName( wxEmptyString );
|
||||
screen = pair.second.m_Instances[0].LastScreen();
|
||||
screen->Append( symbol );
|
||||
frame->GetCanvas()->GetView()->Update( symbol );
|
||||
|
||||
msg = getSymbolReferences( *symbol, pair.second.m_LibId );
|
||||
msg += wxS( ": OK" );
|
||||
m_messagePanel->Report( msg, RPT_SEVERITY_ACTION );
|
||||
matchesProcessed +=1;
|
||||
}
|
||||
|
||||
return matchesProcessed;
|
||||
}
|
||||
|
||||
|
||||
wxString DIALOG_CHANGE_SYMBOLS::getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId )
|
||||
{
|
||||
wxString msg;
|
||||
wxString references;
|
||||
LIB_ID oldId = aSymbol.GetLibId();
|
||||
|
||||
for( const SYMBOL_INSTANCE_REFERENCE& instance : aSymbol.GetInstanceReferences() )
|
||||
{
|
||||
if( references.IsEmpty() )
|
||||
references = instance.m_Reference;
|
||||
else
|
||||
references += wxT( " " ) + instance.m_Reference;
|
||||
}
|
||||
|
||||
if( m_mode == MODE::UPDATE )
|
||||
{
|
||||
if( aSymbol->GetInstanceReferences().size() == 1 )
|
||||
if( aSymbol.GetInstanceReferences().size() == 1 )
|
||||
{
|
||||
msg.Printf( _( "Update symbol %s from '%s' to '%s'" ),
|
||||
references,
|
||||
@@ -550,7 +739,7 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aSymbol->GetInstanceReferences().size() == 1 )
|
||||
if( aSymbol.GetInstanceReferences().size() == 1 )
|
||||
{
|
||||
msg.Printf( _( "Change symbol %s from '%s' to '%s'" ),
|
||||
references,
|
||||
@@ -566,132 +755,5 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_
|
||||
}
|
||||
}
|
||||
|
||||
LIB_SYMBOL* libSymbol = frame->GetLibSymbol( aNewId );
|
||||
|
||||
if( !libSymbol )
|
||||
{
|
||||
msg << wxT( ": " ) << _( "*** symbol not found ***" );
|
||||
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
|
||||
|
||||
if( flattenedSymbol->GetUnitCount() < aSymbol->GetUnit() )
|
||||
{
|
||||
msg << wxT( ": " ) << _( "*** new symbol has too few units ***" );
|
||||
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Removing the symbol needs to be done before the LIB_SYMBOL is changed to prevent stale
|
||||
// library symbols in the schematic file.
|
||||
screen->Remove( aSymbol );
|
||||
frame->SaveCopyInUndoList( screen, aSymbol, UNDO_REDO::CHANGED, aAppendToUndo );
|
||||
|
||||
if( aNewId != aSymbol->GetLibId() )
|
||||
aSymbol->SetLibId( aNewId );
|
||||
|
||||
aSymbol->SetLibSymbol( flattenedSymbol.release() );
|
||||
|
||||
if( m_resetAttributes->GetValue() )
|
||||
{
|
||||
aSymbol->SetIncludeInBom( libSymbol->GetIncludeInBom() );
|
||||
aSymbol->SetIncludeOnBoard( libSymbol->GetIncludeOnBoard() );
|
||||
}
|
||||
|
||||
bool removeExtras = m_removeExtraBox->GetValue();
|
||||
bool resetVis = m_resetFieldVisibilities->GetValue();
|
||||
bool resetEffects = m_resetFieldEffects->GetValue();
|
||||
bool resetPositions = m_resetFieldPositions->GetValue();
|
||||
|
||||
for( unsigned i = 0; i < aSymbol->GetFields().size(); ++i )
|
||||
{
|
||||
SCH_FIELD& field = aSymbol->GetFields()[i];
|
||||
LIB_FIELD* libField = nullptr;
|
||||
|
||||
// Mandatory fields always exist in m_updateFields, but these names can be translated.
|
||||
// so use GetCanonicalName().
|
||||
if( !alg::contains( m_updateFields, field.GetCanonicalName() ) )
|
||||
continue;
|
||||
|
||||
if( i < MANDATORY_FIELDS )
|
||||
libField = libSymbol->GetFieldById( (int) i );
|
||||
else
|
||||
libField = libSymbol->FindField( field.GetName() );
|
||||
|
||||
if( libField )
|
||||
{
|
||||
bool resetText = libField->GetText().IsEmpty() ? m_resetEmptyFields->GetValue()
|
||||
: m_resetFieldText->GetValue();
|
||||
|
||||
if( resetText )
|
||||
{
|
||||
if( i == REFERENCE_FIELD )
|
||||
aSymbol->SetRef( aInstance, UTIL::GetRefDesUnannotated( libField->GetText() ) );
|
||||
else if( i == VALUE_FIELD )
|
||||
aSymbol->SetValue( aInstance, UnescapeString( libField->GetText() ) );
|
||||
else if( i == FOOTPRINT_FIELD )
|
||||
aSymbol->SetFootprint( aInstance, libField->GetText() );
|
||||
else
|
||||
field.SetText( libField->GetText() );
|
||||
}
|
||||
|
||||
if( resetVis )
|
||||
field.SetVisible( libField->IsVisible() );
|
||||
|
||||
if( resetEffects )
|
||||
{
|
||||
// Careful: the visible bit and position are also in Effects
|
||||
bool visible = field.IsVisible();
|
||||
wxPoint pos = field.GetPosition();
|
||||
|
||||
field.SetEffects( *libField );
|
||||
|
||||
field.SetVisible( visible );
|
||||
field.SetPosition( pos );
|
||||
}
|
||||
|
||||
if( resetPositions )
|
||||
field.SetTextPos( aSymbol->GetPosition() + libField->GetTextPos() );
|
||||
}
|
||||
else if( i >= MANDATORY_FIELDS && removeExtras )
|
||||
{
|
||||
aSymbol->RemoveField( field.GetName() );
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<LIB_FIELD*> libFields;
|
||||
libSymbol->GetFields( libFields );
|
||||
|
||||
for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
|
||||
{
|
||||
const LIB_FIELD& libField = *libFields[i];
|
||||
|
||||
if( !alg::contains( m_updateFields, libField.GetCanonicalName() ) )
|
||||
continue;
|
||||
|
||||
if( !aSymbol->FindField( libField.GetName(), false ) )
|
||||
{
|
||||
wxString fieldName = libField.GetCanonicalName();
|
||||
SCH_FIELD newField( wxPoint( 0, 0), aSymbol->GetFieldCount(), aSymbol, fieldName );
|
||||
SCH_FIELD* schField = aSymbol->AddField( newField );
|
||||
|
||||
schField->SetEffects( libField );
|
||||
schField->SetText( libField.GetText() );
|
||||
schField->SetTextPos( aSymbol->GetPosition() + libField.GetTextPos() );
|
||||
}
|
||||
}
|
||||
|
||||
aSymbol->SetSchSymbolLibraryName( wxEmptyString );
|
||||
screen->Append( aSymbol );
|
||||
frame->GetCanvas()->GetView()->Update( aSymbol );
|
||||
|
||||
msg += wxT( ": OK" );
|
||||
m_messagePanel->Report( msg, RPT_SEVERITY_ACTION );
|
||||
|
||||
return true;
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 CERN
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* @author Wayne Stambaugh <stambaughw@gmail.com>
|
||||
*
|
||||
@@ -25,11 +25,21 @@
|
||||
|
||||
#include <dialog_change_symbols_base.h>
|
||||
|
||||
class LIB_ID;
|
||||
#include <lib_id.h>
|
||||
#include <sch_sheet_path.h>
|
||||
|
||||
|
||||
class SCH_SYMBOL;
|
||||
class SCH_EDIT_FRAME;
|
||||
class SCH_SCREEN;
|
||||
class SCH_SHEET_PATH;
|
||||
|
||||
|
||||
struct SYMBOL_CHANGE_INFO
|
||||
{
|
||||
std::vector<SCH_SHEET_PATH> m_Instances;
|
||||
LIB_ID m_LibId;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Dialog to update or change schematic library symbols.
|
||||
@@ -73,9 +83,9 @@ private:
|
||||
void updateFieldsList();
|
||||
|
||||
bool isMatch( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aInstance );
|
||||
bool processMatchingSymbols();
|
||||
bool processSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_PATH* aInstance,
|
||||
const LIB_ID& aNewId, bool aAppendToUndo );
|
||||
int processMatchingSymbols();
|
||||
int processSymbols( const std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO>& aSymbols );
|
||||
wxString getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId );
|
||||
|
||||
SCH_SYMBOL* m_symbol;
|
||||
MODE m_mode;
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
#include <string_utils.h>
|
||||
#include <kiplatform/ui.h>
|
||||
|
||||
static SCHEMATIC* g_lastERCSchematic = nullptr;
|
||||
static bool g_lastERCRun = false;
|
||||
|
||||
|
||||
DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
|
||||
DIALOG_ERC_BASE( parent ),
|
||||
PROGRESS_REPORTER_BASE( 1 ),
|
||||
@@ -57,6 +61,8 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
|
||||
m_ercRun( false ),
|
||||
m_severities( RPT_SEVERITY_ERROR | RPT_SEVERITY_WARNING )
|
||||
{
|
||||
m_currentSchematic = &parent->Schematic();
|
||||
|
||||
SetName( DIALOG_ERC_WINDOW_NAME ); // Set a window name to be able to find it
|
||||
|
||||
EESCHEMA_SETTINGS* settings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
|
||||
@@ -70,8 +76,9 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
|
||||
|
||||
m_markerTreeModel->SetSeverities( m_severities );
|
||||
m_markerTreeModel->SetProvider( m_markerProvider );
|
||||
syncCheckboxes();
|
||||
updateDisplayedCounts();
|
||||
|
||||
if( m_currentSchematic == g_lastERCSchematic )
|
||||
m_ercRun = g_lastERCRun;
|
||||
|
||||
// We use a sdbSizer to get platform-dependent ordering of the action buttons, but
|
||||
// that requires us to correct the button labels here.
|
||||
@@ -81,12 +88,24 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
|
||||
|
||||
m_sdbSizer1OK->SetDefault();
|
||||
|
||||
m_violationsTitleTemplate = m_notebook->GetPageText( 1 );
|
||||
|
||||
// Hack to keep from changing translated string in 6.0.x
|
||||
m_violationsTitleTemplate.Append( wxT( " (%s)" ) );
|
||||
|
||||
m_errorsBadge->SetMaximumNumber( 999 );
|
||||
m_warningsBadge->SetMaximumNumber( 999 );
|
||||
m_exclusionsBadge->SetMaximumNumber( 999 );
|
||||
|
||||
UpdateAnnotationWarning();
|
||||
|
||||
Layout();
|
||||
|
||||
SetFocus();
|
||||
|
||||
syncCheckboxes();
|
||||
updateDisplayedCounts();
|
||||
|
||||
// Now all widgets have the size fixed, call FinishDialogSettings
|
||||
finishDialogSettings();
|
||||
}
|
||||
@@ -94,6 +113,9 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
|
||||
|
||||
DIALOG_ERC::~DIALOG_ERC()
|
||||
{
|
||||
g_lastERCSchematic = m_currentSchematic;
|
||||
g_lastERCRun = m_ercRun;
|
||||
|
||||
EESCHEMA_SETTINGS* settings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
|
||||
wxASSERT( settings );
|
||||
|
||||
@@ -176,18 +198,41 @@ void DIALOG_ERC::updateDisplayedCounts()
|
||||
int numWarnings = 0;
|
||||
int numExcluded = 0;
|
||||
|
||||
int numMarkers = 0;
|
||||
|
||||
if( m_markerProvider )
|
||||
{
|
||||
numMarkers += m_markerProvider->GetCount();
|
||||
numErrors += m_markerProvider->GetCount( RPT_SEVERITY_ERROR );
|
||||
numWarnings += m_markerProvider->GetCount( RPT_SEVERITY_WARNING );
|
||||
numExcluded += m_markerProvider->GetCount( RPT_SEVERITY_EXCLUSION );
|
||||
}
|
||||
|
||||
if( !m_ercRun )
|
||||
bool markersOverflowed = false;
|
||||
|
||||
// We don't currently have a limit on ERC violations, so the above is always false.
|
||||
|
||||
wxString num;
|
||||
wxString msg;
|
||||
|
||||
if( m_ercRun )
|
||||
{
|
||||
numErrors = -1;
|
||||
numWarnings = -1;
|
||||
num.Printf( markersOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numMarkers );
|
||||
msg.Printf( m_violationsTitleTemplate, num );
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = m_violationsTitleTemplate;
|
||||
msg.Replace( wxT( "(%s)" ), wxEmptyString );
|
||||
}
|
||||
|
||||
m_notebook->SetPageText( 1, msg );
|
||||
|
||||
if( !m_ercRun && numErrors == 0 )
|
||||
numErrors = -1;
|
||||
|
||||
if( !m_ercRun && numWarnings == 0 )
|
||||
numWarnings = -1;
|
||||
|
||||
m_errorsBadge->UpdateNumber( numErrors, RPT_SEVERITY_ERROR );
|
||||
m_warningsBadge->UpdateNumber( numWarnings, RPT_SEVERITY_WARNING );
|
||||
@@ -221,9 +266,9 @@ void DIALOG_ERC::OnEraseDrcMarkersClick( wxCommandEvent& event )
|
||||
|
||||
deleteAllMarkers( includeExclusions );
|
||||
|
||||
m_ercRun = false;
|
||||
// redraw the schematic
|
||||
redrawDrawPanel();
|
||||
updateDisplayedCounts();
|
||||
m_parent->GetCanvas()->Refresh();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -91,6 +91,9 @@ private:
|
||||
|
||||
private:
|
||||
SCH_EDIT_FRAME* m_parent;
|
||||
SCHEMATIC* m_currentSchematic;
|
||||
|
||||
wxString m_violationsTitleTemplate;
|
||||
|
||||
RC_ITEMS_PROVIDER* m_markerProvider;
|
||||
RC_TREE_MODEL* m_markerTreeModel;
|
||||
|
||||
@@ -309,7 +309,7 @@
|
||||
</object>
|
||||
<object class="notebookpage" expanded="1">
|
||||
<property name="bitmap"></property>
|
||||
<property name="label">Violations</property>
|
||||
<property name="label">Violations (%d)</property>
|
||||
<property name="select">0</property>
|
||||
<object class="wxPanel" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
|
||||
@@ -53,8 +53,6 @@ DIALOG_FIELD_PROPERTIES::DIALOG_FIELD_PROPERTIES( SCH_BASE_FRAME* aParent, const
|
||||
{
|
||||
wxASSERT( aTextItem );
|
||||
|
||||
SetTitle( aTitle );
|
||||
|
||||
m_note->SetFont( KIUI::GetInfoFont( this ).Italic() );
|
||||
m_note->Show( false );
|
||||
|
||||
@@ -348,7 +346,14 @@ DIALOG_SCH_FIELD_PROPERTIES::DIALOG_SCH_FIELD_PROPERTIES( SCH_BASE_FRAME* aParen
|
||||
|
||||
m_isPower = false;
|
||||
|
||||
m_textLabel->SetLabel( m_field->GetName() + wxT( ":" ) );
|
||||
wxString translated_fieldname;
|
||||
|
||||
if( m_field->GetId() < MANDATORY_FIELDS )
|
||||
translated_fieldname = TEMPLATE_FIELDNAME::GetDefaultFieldName( m_field->GetId(), DO_TRANSLATE );
|
||||
else
|
||||
translated_fieldname = m_field->GetName();
|
||||
|
||||
m_textLabel->SetLabel( translated_fieldname + ":" );
|
||||
|
||||
m_position = m_field->GetPosition();
|
||||
|
||||
|
||||
@@ -109,10 +109,6 @@ DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS( SCH_
|
||||
m_parent = parent;
|
||||
m_appendUndo = false;
|
||||
|
||||
// TODO(JE) remove once real-time connectivity is a given
|
||||
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
|
||||
m_parent->RecalculateConnections( NO_CLEANUP );
|
||||
|
||||
m_lineStyle->Append( DEFAULT_STYLE );
|
||||
m_lineStyle->Append( INDETERMINATE_ACTION );
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ public:
|
||||
val = StringFromValue( aUserUnits, pin->GetPosition().x, true );
|
||||
break;
|
||||
case COL_POSY:
|
||||
val = StringFromValue( aUserUnits, pin->GetPosition().y, true );
|
||||
val = StringFromValue( aUserUnits, -pin->GetPosition().y, true );
|
||||
break;
|
||||
case COL_VISIBLE:
|
||||
val = StringFromBool( pin->IsVisible() );
|
||||
@@ -216,7 +216,7 @@ public:
|
||||
|
||||
case COL_POSY:
|
||||
pin->SetPosition( wxPoint( pin->GetPosition().x,
|
||||
ValueFromString( m_frame->GetUserUnits(), aValue ) ) );
|
||||
-ValueFromString( m_frame->GetUserUnits(), aValue ) ) );
|
||||
break;
|
||||
|
||||
case COL_VISIBLE:
|
||||
@@ -556,7 +556,9 @@ DIALOG_LIB_EDIT_PIN_TABLE::~DIALOG_LIB_EDIT_PIN_TABLE()
|
||||
bool DIALOG_LIB_EDIT_PIN_TABLE::TransferDataToWindow()
|
||||
{
|
||||
// Make a copy of the pins for editing
|
||||
for( LIB_PIN* pin = m_part->GetNextPin( nullptr ); pin; pin = m_part->GetNextPin( pin ) )
|
||||
std::vector<LIB_PIN*> pins = m_part->GetAllLibPins();
|
||||
|
||||
for( LIB_PIN* pin : pins )
|
||||
m_pins.push_back( new LIB_PIN( *pin ) );
|
||||
|
||||
m_dataModel->RebuildRows( m_pins, m_cbGroup->GetValue() );
|
||||
@@ -573,7 +575,9 @@ bool DIALOG_LIB_EDIT_PIN_TABLE::TransferDataFromWindow()
|
||||
return false;
|
||||
|
||||
// Delete the part's pins
|
||||
while( LIB_PIN* pin = m_part->GetNextPin( nullptr ) )
|
||||
std::vector<LIB_PIN*> pins = m_part->GetAllLibPins();
|
||||
|
||||
for( LIB_PIN* pin : pins )
|
||||
m_part->RemoveDrawItem( pin );
|
||||
|
||||
// Transfer our pins to the part
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <dialog_lib_text_properties.h>
|
||||
#include <symbol_editor/symbol_editor_settings.h>
|
||||
#include <tools/symbol_editor_drawing_tools.h>
|
||||
|
||||
#include "confirm.h"
|
||||
|
||||
DIALOG_LIB_TEXT_PROPERTIES::DIALOG_LIB_TEXT_PROPERTIES( SYMBOL_EDIT_FRAME* aParent,
|
||||
LIB_TEXT* aText ) :
|
||||
@@ -116,9 +116,15 @@ bool DIALOG_LIB_TEXT_PROPERTIES::TransferDataFromWindow()
|
||||
if( m_graphicText )
|
||||
{
|
||||
if( m_TextCtrl->GetValue().IsEmpty() )
|
||||
m_graphicText->SetText( wxT( "[null]" ) );
|
||||
{
|
||||
// Other text items do not have defined extents, and so will disappear if empty
|
||||
DisplayError( this, _( "Value may not be empty." ) );
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_graphicText->SetText( m_TextCtrl->GetValue() );
|
||||
}
|
||||
|
||||
m_graphicText->SetPosition( wxPoint( m_posX.GetValue(), m_posY.GetValue() ) );
|
||||
|
||||
|
||||
@@ -83,8 +83,8 @@ public:
|
||||
* @param title is the title of the notebook page.
|
||||
* @param id_NetType is the netlist ID type.
|
||||
*/
|
||||
NETLIST_PAGE_DIALOG( wxNotebook* parent, const wxString& title,
|
||||
NETLIST_TYPE_ID id_NetType );
|
||||
NETLIST_PAGE_DIALOG( wxNotebook* aParent, const wxString& aTitle,
|
||||
NETLIST_TYPE_ID aIdNetType, bool aCustom );
|
||||
~NETLIST_PAGE_DIALOG() { };
|
||||
|
||||
/**
|
||||
@@ -102,8 +102,12 @@ public:
|
||||
wxBoxSizer* m_RightOptionsBoxSizer;
|
||||
wxBoxSizer* m_LowBoxSizer;
|
||||
|
||||
bool IsCustom() const { return m_custom; }
|
||||
|
||||
private:
|
||||
wxString m_pageNetFmtName;
|
||||
|
||||
bool m_custom;
|
||||
};
|
||||
|
||||
|
||||
@@ -125,6 +129,8 @@ private:
|
||||
bool TransferDataFromWindow() override;
|
||||
void NetlistUpdateOpt();
|
||||
|
||||
void updateGeneratorButtons();
|
||||
|
||||
// Called when changing the notebook page (and therefore the current netlist format)
|
||||
void OnNetlistTypeSelection( wxNotebookEvent& event ) override;
|
||||
|
||||
@@ -206,17 +212,18 @@ BEGIN_EVENT_TABLE( NETLIST_DIALOG, NETLIST_DIALOG_BASE )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
NETLIST_PAGE_DIALOG::NETLIST_PAGE_DIALOG( wxNotebook* parent, const wxString& title,
|
||||
NETLIST_TYPE_ID id_NetType ) :
|
||||
wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL )
|
||||
NETLIST_PAGE_DIALOG::NETLIST_PAGE_DIALOG( wxNotebook* aParent, const wxString& aTitle,
|
||||
NETLIST_TYPE_ID aIdNetType, bool aCustom ) :
|
||||
wxPanel( aParent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL )
|
||||
{
|
||||
m_IdNetType = id_NetType;
|
||||
m_pageNetFmtName = title;
|
||||
m_IdNetType = aIdNetType;
|
||||
m_pageNetFmtName = aTitle;
|
||||
m_CommandStringCtrl = nullptr;
|
||||
m_TitleStringCtrl = nullptr;
|
||||
m_AdjustPassiveValues = nullptr;
|
||||
m_custom = aCustom;
|
||||
|
||||
parent->AddPage( this, title, false );
|
||||
aParent->AddPage( this, aTitle, false );
|
||||
|
||||
wxBoxSizer* MainBoxSizer = new wxBoxSizer( wxVERTICAL );
|
||||
SetSizer( MainBoxSizer );
|
||||
@@ -245,14 +252,14 @@ NETLIST_DIALOG::NETLIST_DIALOG( SCH_EDIT_FRAME* parent ) :
|
||||
page = nullptr;
|
||||
|
||||
// Add notebook pages:
|
||||
m_PanelNetType[PANELPCBNEW] = new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "KiCad" ),
|
||||
NET_TYPE_PCBNEW );
|
||||
m_PanelNetType[PANELPCBNEW] =
|
||||
new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "KiCad" ), NET_TYPE_PCBNEW, false );
|
||||
|
||||
m_PanelNetType[PANELORCADPCB2] = new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "OrcadPCB2" ),
|
||||
NET_TYPE_ORCADPCB2 );
|
||||
m_PanelNetType[PANELORCADPCB2] =
|
||||
new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "OrcadPCB2" ), NET_TYPE_ORCADPCB2, false );
|
||||
|
||||
m_PanelNetType[PANELCADSTAR] = new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "CadStar" ),
|
||||
NET_TYPE_CADSTAR );
|
||||
m_PanelNetType[PANELCADSTAR] =
|
||||
new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "CadStar" ), NET_TYPE_CADSTAR, false );
|
||||
|
||||
InstallPageSpice();
|
||||
InstallCustomPages();
|
||||
@@ -275,6 +282,8 @@ NETLIST_DIALOG::NETLIST_DIALOG( SCH_EDIT_FRAME* parent ) :
|
||||
|
||||
// Now all widgets have the size fixed, call FinishDialogSettings
|
||||
finishDialogSettings();
|
||||
|
||||
updateGeneratorButtons();
|
||||
}
|
||||
|
||||
|
||||
@@ -320,7 +329,7 @@ void NETLIST_DIALOG::OnRunSpiceButtUI( wxUpdateUIEvent& aEvent )
|
||||
void NETLIST_DIALOG::InstallPageSpice()
|
||||
{
|
||||
NETLIST_PAGE_DIALOG* page = m_PanelNetType[PANELSPICE] =
|
||||
new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "Spice" ), NET_TYPE_SPICE );
|
||||
new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "Spice" ), NET_TYPE_SPICE, false );
|
||||
|
||||
SCHEMATIC_SETTINGS& settings = m_Parent->Schematic().Settings();
|
||||
|
||||
@@ -385,7 +394,7 @@ NETLIST_PAGE_DIALOG* NETLIST_DIALOG::AddOneCustomPage( const wxString& aTitle,
|
||||
const wxString& aCommandString,
|
||||
NETLIST_TYPE_ID aNetTypeId )
|
||||
{
|
||||
NETLIST_PAGE_DIALOG* currPage = new NETLIST_PAGE_DIALOG( m_NoteBook, aTitle, aNetTypeId );
|
||||
NETLIST_PAGE_DIALOG* currPage = new NETLIST_PAGE_DIALOG( m_NoteBook, aTitle, aNetTypeId, true );
|
||||
|
||||
currPage->m_LowBoxSizer->Add( new wxStaticText( currPage, -1, _( "Title:" ) ), 0,
|
||||
wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
|
||||
@@ -413,12 +422,7 @@ NETLIST_PAGE_DIALOG* NETLIST_DIALOG::AddOneCustomPage( const wxString& aTitle,
|
||||
|
||||
void NETLIST_DIALOG::OnNetlistTypeSelection( wxNotebookEvent& event )
|
||||
{
|
||||
NETLIST_PAGE_DIALOG* currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
|
||||
|
||||
if( currPage == nullptr )
|
||||
return;
|
||||
|
||||
m_buttonDelGenerator->Enable( currPage->m_IdNetType >= NET_TYPE_CUSTOM1 );
|
||||
updateGeneratorButtons();
|
||||
}
|
||||
|
||||
|
||||
@@ -588,6 +592,9 @@ void NETLIST_DIALOG::OnDelGenerator( wxCommandEvent& event )
|
||||
{
|
||||
NETLIST_PAGE_DIALOG* currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
|
||||
|
||||
if( !currPage->IsCustom() )
|
||||
return;
|
||||
|
||||
currPage->m_CommandStringCtrl->SetValue( wxEmptyString );
|
||||
currPage->m_TitleStringCtrl->SetValue( wxEmptyString );
|
||||
|
||||
@@ -712,6 +719,17 @@ void NETLIST_DIALOG_ADD_GENERATOR::OnBrowseGenerators( wxCommandEvent& event )
|
||||
}
|
||||
|
||||
|
||||
void NETLIST_DIALOG::updateGeneratorButtons()
|
||||
{
|
||||
NETLIST_PAGE_DIALOG* currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
|
||||
|
||||
if( currPage == nullptr )
|
||||
return;
|
||||
|
||||
m_buttonDelGenerator->Enable( currPage->IsCustom() );
|
||||
}
|
||||
|
||||
|
||||
int InvokeDialogNetList( SCH_EDIT_FRAME* aCaller )
|
||||
{
|
||||
NETLIST_DIALOG dlg( aCaller );
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 1992-2018 Jean-Pierre Charras jp.charras at wanadoo.fr
|
||||
* Copyright (C) 1992-2010 Lorenzo Marcantonio
|
||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2022 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
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <trace_helpers.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <drawing_sheet/ds_painter.h>
|
||||
#include <wx_filename.h>
|
||||
|
||||
#include <sch_edit_frame.h>
|
||||
#include <sch_painter.h>
|
||||
@@ -1283,7 +1284,7 @@ wxString DIALOG_PLOT_SCHEMATIC::getOutputPath()
|
||||
fn.SetName( wxEmptyString );
|
||||
fn.SetExt( wxEmptyString );
|
||||
|
||||
if( fn.Normalize() )
|
||||
if( fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ) )
|
||||
{
|
||||
path = fn.GetPath();
|
||||
}
|
||||
@@ -1318,7 +1319,7 @@ wxString DIALOG_PLOT_SCHEMATIC::getOutputPath()
|
||||
// Build the absolute path of current output directory and the project path.
|
||||
fn.SetPath( Prj().GetProjectPath() + path );
|
||||
|
||||
if( fn.Normalize() )
|
||||
if( fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ) )
|
||||
{
|
||||
path = fn.GetPath();
|
||||
}
|
||||
|
||||
@@ -409,6 +409,11 @@ bool SCH_PRINTOUT::OnBeginDocument( int startPage, int endPage )
|
||||
*/
|
||||
void SCH_PRINTOUT::PrintPage( SCH_SCREEN* aScreen )
|
||||
{
|
||||
// Warning:
|
||||
// When printing many pages, changes in the current wxDC will affect all next printings
|
||||
// because all prints are using the same wxPrinterDC after creation
|
||||
// So be careful and reinit parameters, especially when using offsets.
|
||||
|
||||
wxPoint tmp_startvisu;
|
||||
wxSize pageSizeIU; // Page size in internal units
|
||||
wxPoint old_org;
|
||||
@@ -439,16 +444,31 @@ void SCH_PRINTOUT::PrintPage( SCH_SCREEN* aScreen )
|
||||
int xoffset = ( fitRect.width - pageSizeIU.x ) / 2;
|
||||
int yoffset = ( fitRect.height - pageSizeIU.y ) / 2;
|
||||
|
||||
// Using a wxAffineMatrix2D has a big advantage: it handles different pages orientations
|
||||
//(PORTRAIT/LANDSCAPE), but the affine matrix is not always supported
|
||||
if( dc->CanUseTransformMatrix() )
|
||||
{
|
||||
wxAffineMatrix2D matrix = dc->GetTransformMatrix();
|
||||
wxAffineMatrix2D matrix; // starts from a unity matrix (the current wxDC default)
|
||||
|
||||
// Check for portrait/landscape mismatch:
|
||||
if( ( fitRect.width > fitRect.height ) != ( pageSizeIU.x > pageSizeIU.y ) )
|
||||
{
|
||||
// Rotate the coordinates, and keep the draw coordinates inside the page
|
||||
matrix.Rotate( M_PI_2 );
|
||||
xoffset = ( fitRect.height - pageSizeIU.x ) / 2;
|
||||
yoffset = ( fitRect.width - pageSizeIU.y ) / 2;
|
||||
matrix.Translate( 0, -pageSizeIU.y );
|
||||
|
||||
// Recalculate the offsets and page sizes according to the page rotation
|
||||
std::swap( pageSizeIU.x, pageSizeIU.y );
|
||||
FitThisSizeToPaper( pageSizeIU );
|
||||
fitRect = GetLogicalPaperRect();
|
||||
|
||||
xoffset = ( fitRect.width - pageSizeIU.x ) / 2;
|
||||
yoffset = ( fitRect.height - pageSizeIU.y ) / 2;
|
||||
|
||||
// All the coordinates will be rotated 90 deg when printing,
|
||||
// so the X,Y offset vector must be rotated -90 deg before printing
|
||||
std::swap( xoffset, yoffset );
|
||||
yoffset = -yoffset;
|
||||
}
|
||||
|
||||
matrix.Translate( xoffset, yoffset );
|
||||
@@ -456,12 +476,8 @@ void SCH_PRINTOUT::PrintPage( SCH_SCREEN* aScreen )
|
||||
}
|
||||
else
|
||||
{
|
||||
// wxWidgets appears to have a bug when OffsetLogicalOrigin()'s yoffset changes from
|
||||
// page to page.
|
||||
// NB: this is a workaround, not a fix. The Y centering will be off, but this is less
|
||||
// annoying than a blank page. See https://bugs.launchpad.net/kicad/+bug/1464773.
|
||||
yoffset = 0;
|
||||
|
||||
SetLogicalOrigin( 0, 0 ); // Reset all offset settings made previously.
|
||||
// When printing previous pages (all prints are using the same wxDC)
|
||||
OffsetLogicalOrigin( xoffset, yoffset );
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <wx/tooltip.h>
|
||||
#include <confirm.h>
|
||||
#include <validators.h>
|
||||
#include <wx_filename.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <widgets/tab_traversal.h>
|
||||
#include <sch_edit_frame.h>
|
||||
@@ -425,7 +426,8 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
|
||||
// SCH_SCREEN file names are always absolute.
|
||||
wxFileName currentScreenFileName = currentScreen->GetFileName();
|
||||
|
||||
if( !screenFileName.Normalize( wxPATH_NORM_ALL, currentScreenFileName.GetPath() ) )
|
||||
if( !screenFileName.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS,
|
||||
currentScreenFileName.GetPath() ) )
|
||||
{
|
||||
msg = wxString::Format( _( "Cannot normalize new sheet schematic file path:\n"
|
||||
"'%s'\n"
|
||||
|
||||
@@ -233,6 +233,10 @@ public:
|
||||
if( aCol == QUANTITY_COLUMN )
|
||||
return _( "Qty" );
|
||||
else if( aCol < MANDATORY_FIELDS )
|
||||
// FIX ME: the column label should be displayed translated.
|
||||
// but when translated, and the DATASHEET column is shown, a new field
|
||||
// with the translated DATASHEET field name is added when saving fields
|
||||
// return TEMPLATE_FIELDNAME::GetDefaultFieldName( aCol, DO_TRANSLATE );
|
||||
return TEMPLATE_FIELDNAME::GetDefaultFieldName( aCol );
|
||||
else
|
||||
return m_fieldNames[ aCol ];
|
||||
@@ -615,19 +619,21 @@ public:
|
||||
const wxString& srcValue = srcData.second;
|
||||
SCH_FIELD* destField = symbol.FindField( srcName );
|
||||
|
||||
if( !destField && !srcValue.IsEmpty() )
|
||||
// Add a not existing field if it has a value for this symbol
|
||||
bool createField = !destField && !srcValue.IsEmpty();
|
||||
|
||||
if( createField )
|
||||
{
|
||||
const wxPoint symbolPos = symbol.GetPosition();
|
||||
destField = symbol.AddField( SCH_FIELD( symbolPos, -1, &symbol, srcName ) );
|
||||
}
|
||||
|
||||
if( !destField )
|
||||
continue;
|
||||
|
||||
if( destField->GetId() == REFERENCE_FIELD )
|
||||
{
|
||||
symbol.RemoveField( srcName );
|
||||
}
|
||||
else if( destField->GetId() == REFERENCE_FIELD )
|
||||
{
|
||||
// Reference is not editable
|
||||
// Reference is not editable from this dialog
|
||||
}
|
||||
else if( destField->GetId() == VALUE_FIELD )
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Oliver Walters
|
||||
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2022 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
|
||||
@@ -74,6 +74,8 @@ private:
|
||||
|
||||
SCH_REFERENCE_LIST m_symbolsList;
|
||||
FIELDS_EDITOR_GRID_DATA_MODEL* m_dataModel;
|
||||
static int m_newFieldsOption; // Store the option choice for new fields
|
||||
// during a session:
|
||||
};
|
||||
|
||||
#endif /* DIALOG_SYMBOL_FIELDS_TABLE_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -32,7 +32,7 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
|
||||
m_groupSymbolsBox->SetValue(true);
|
||||
m_groupSymbolsBox->SetToolTip( _("Group symbols together based on common properties") );
|
||||
|
||||
bGroupSizer->Add( m_groupSymbolsBox, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
bGroupSizer->Add( m_groupSymbolsBox, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
|
||||
bGroupSizer->Add( 0, 0, 1, wxEXPAND|wxRIGHT|wxLEFT, 10 );
|
||||
@@ -103,7 +103,7 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
|
||||
bButtonsSizer->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
m_buttonApply = new wxButton( this, wxID_ANY, _("Apply, Save Schematic && Continue"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bButtonsSizer->Add( m_buttonApply, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
|
||||
bButtonsSizer->Add( m_buttonApply, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
|
||||
|
||||
m_sdbSizer = new wxStdDialogButtonSizer();
|
||||
m_sdbSizerOK = new wxButton( this, wxID_OK );
|
||||
@@ -112,10 +112,10 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
|
||||
m_sdbSizer->AddButton( m_sdbSizerCancel );
|
||||
m_sdbSizer->Realize();
|
||||
|
||||
bButtonsSizer->Add( m_sdbSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT, 5 );
|
||||
bButtonsSizer->Add( m_sdbSizer, 0, wxEXPAND|wxLEFT, 5 );
|
||||
|
||||
|
||||
bMainSizer->Add( bButtonsSizer, 0, wxEXPAND, 5 );
|
||||
bMainSizer->Add( bButtonsSizer, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 );
|
||||
|
||||
|
||||
this->SetSizer( bMainSizer );
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxRIGHT</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
@@ -603,7 +603,7 @@
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND|wxTOP</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
@@ -622,7 +622,7 @@
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
@@ -696,7 +696,7 @@
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT</property>
|
||||
<property name="flag">wxEXPAND|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStdDialogButtonSizer" expanded="1">
|
||||
<property name="Apply">0</property>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2004-2022 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
|
||||
@@ -89,6 +89,14 @@ public:
|
||||
|
||||
void BuildAttrs()
|
||||
{
|
||||
for( wxGridCellAttr* attr : m_nameAttrs )
|
||||
attr->DecRef();
|
||||
|
||||
m_nameAttrs.clear();
|
||||
|
||||
if( m_readOnlyAttr )
|
||||
m_readOnlyAttr->DecRef();
|
||||
|
||||
m_readOnlyAttr = new wxGridCellAttr;
|
||||
m_readOnlyAttr->SetReadOnly( true );
|
||||
|
||||
@@ -117,11 +125,17 @@ public:
|
||||
m_nameAttrs.push_back( attr );
|
||||
}
|
||||
|
||||
if( m_typeAttr )
|
||||
m_typeAttr->DecRef();
|
||||
|
||||
m_typeAttr = new wxGridCellAttr;
|
||||
m_typeAttr->SetRenderer( new GRID_CELL_ICON_TEXT_RENDERER( PinTypeIcons(),
|
||||
PinTypeNames() ) );
|
||||
m_typeAttr->SetReadOnly( true );
|
||||
|
||||
if( m_shapeAttr )
|
||||
m_shapeAttr->DecRef();
|
||||
|
||||
m_shapeAttr = new wxGridCellAttr;
|
||||
m_shapeAttr->SetRenderer( new GRID_CELL_ICON_TEXT_RENDERER( PinShapeIcons(),
|
||||
PinShapeNames() ) );
|
||||
@@ -744,8 +758,14 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataFromWindow()
|
||||
}
|
||||
else
|
||||
{
|
||||
SCH_FIELD* newField = otherUnit->AddField( m_fields->at( ii ) );
|
||||
const_cast<KIID&>( newField->m_Uuid ) = KIID();
|
||||
SCH_FIELD newField( m_fields->at( ii ) );
|
||||
const_cast<KIID&>( newField.m_Uuid ) = KIID();
|
||||
|
||||
newField.Offset( -m_symbol->GetPosition() );
|
||||
newField.Offset( otherUnit->GetPosition() );
|
||||
|
||||
newField.SetParent( otherUnit );
|
||||
otherUnit->AddField( newField );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -847,7 +867,7 @@ void DIALOG_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
|
||||
SCHEMATIC_SETTINGS& settings = m_symbol->Schematic()->Settings();
|
||||
int fieldID = m_fields->size();
|
||||
SCH_FIELD newField( wxPoint( 0, 0 ), fieldID, m_symbol,
|
||||
TEMPLATE_FIELDNAME::GetDefaultFieldName( fieldID ) );
|
||||
TEMPLATE_FIELDNAME::GetDefaultFieldName( fieldID, DO_TRANSLATE ) );
|
||||
|
||||
newField.SetTextAngle( m_fields->at( REFERENCE_FIELD ).GetTextAngle() );
|
||||
newField.SetTextSize( wxSize( settings.m_DefaultTextSize, settings.m_DefaultTextSize ) );
|
||||
@@ -1024,6 +1044,7 @@ void DIALOG_SYMBOL_PROPERTIES::OnPinTableColSort( wxGridEvent& aEvent )
|
||||
ascending = true;
|
||||
|
||||
m_dataModel->SortRows( sortCol, ascending );
|
||||
m_dataModel->BuildAttrs();
|
||||
}
|
||||
|
||||
|
||||
@@ -1139,3 +1160,16 @@ void DIALOG_SYMBOL_PROPERTIES::OnChoice( wxCommandEvent& event )
|
||||
{
|
||||
OnModify();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SYMBOL_PROPERTIES::onUpdateEditSymbol( wxUpdateUIEvent& event )
|
||||
{
|
||||
event.Enable( m_symbol && m_symbol->GetLibSymbolRef() );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SYMBOL_PROPERTIES::onUpdateEditLibrarySymbol( wxUpdateUIEvent& event )
|
||||
{
|
||||
event.Enable( m_symbol && m_symbol->GetLibSymbolRef() );
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2022 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
|
||||
@@ -88,6 +88,9 @@ private:
|
||||
void OnUpdateSymbol( wxCommandEvent& ) override;
|
||||
void OnExchangeSymbol( wxCommandEvent& ) override;
|
||||
|
||||
virtual void onUpdateEditSymbol( wxUpdateUIEvent& event ) override;
|
||||
virtual void onUpdateEditLibrarySymbol( wxUpdateUIEvent& event ) override;
|
||||
|
||||
void AdjustGridColumns( int aWidth );
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -49,7 +49,6 @@ DIALOG_SYMBOL_PROPERTIES_BASE::DIALOG_SYMBOL_PROPERTIES_BASE( wxWindow* parent,
|
||||
m_fieldsGrid->SetColSize( 10, 84 );
|
||||
m_fieldsGrid->EnableDragColMove( false );
|
||||
m_fieldsGrid->EnableDragColSize( true );
|
||||
m_fieldsGrid->SetColLabelSize( 22 );
|
||||
m_fieldsGrid->SetColLabelValue( 0, _("Name") );
|
||||
m_fieldsGrid->SetColLabelValue( 1, _("Value") );
|
||||
m_fieldsGrid->SetColLabelValue( 2, _("Show") );
|
||||
@@ -61,6 +60,7 @@ DIALOG_SYMBOL_PROPERTIES_BASE::DIALOG_SYMBOL_PROPERTIES_BASE( wxWindow* parent,
|
||||
m_fieldsGrid->SetColLabelValue( 8, _("Orientation") );
|
||||
m_fieldsGrid->SetColLabelValue( 9, _("X Position") );
|
||||
m_fieldsGrid->SetColLabelValue( 10, _("Y Position") );
|
||||
m_fieldsGrid->SetColLabelSize( 22 );
|
||||
m_fieldsGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
|
||||
|
||||
// Rows
|
||||
@@ -260,12 +260,12 @@ DIALOG_SYMBOL_PROPERTIES_BASE::DIALOG_SYMBOL_PROPERTIES_BASE( wxWindow* parent,
|
||||
m_pinGrid->SetColSize( 4, 140 );
|
||||
m_pinGrid->EnableDragColMove( false );
|
||||
m_pinGrid->EnableDragColSize( true );
|
||||
m_pinGrid->SetColLabelSize( 24 );
|
||||
m_pinGrid->SetColLabelValue( 0, _("Pin Number") );
|
||||
m_pinGrid->SetColLabelValue( 1, _("Base Pin Name") );
|
||||
m_pinGrid->SetColLabelValue( 2, _("Alternate Assignment") );
|
||||
m_pinGrid->SetColLabelValue( 3, _("Electrical Type") );
|
||||
m_pinGrid->SetColLabelValue( 4, _("Graphic Style") );
|
||||
m_pinGrid->SetColLabelSize( 24 );
|
||||
m_pinGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
|
||||
|
||||
// Rows
|
||||
@@ -353,7 +353,9 @@ DIALOG_SYMBOL_PROPERTIES_BASE::DIALOG_SYMBOL_PROPERTIES_BASE( wxWindow* parent,
|
||||
m_updateSymbolBtn->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnUpdateSymbol ), NULL, this );
|
||||
m_changeSymbolBtn->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnExchangeSymbol ), NULL, this );
|
||||
m_editSchematicSymbolBtn->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnEditSymbol ), NULL, this );
|
||||
m_editSchematicSymbolBtn->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::onUpdateEditSymbol ), NULL, this );
|
||||
m_editLibrarySymbolBtn->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnEditLibrarySymbol ), NULL, this );
|
||||
m_editLibrarySymbolBtn->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::onUpdateEditLibrarySymbol ), NULL, this );
|
||||
m_pinGrid->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnPinTableCellEdited ), NULL, this );
|
||||
m_spiceFieldsButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnEditSpiceModel ), NULL, this );
|
||||
m_stdDialogButtonSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnCancelButtonClick ), NULL, this );
|
||||
@@ -381,7 +383,9 @@ DIALOG_SYMBOL_PROPERTIES_BASE::~DIALOG_SYMBOL_PROPERTIES_BASE()
|
||||
m_updateSymbolBtn->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnUpdateSymbol ), NULL, this );
|
||||
m_changeSymbolBtn->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnExchangeSymbol ), NULL, this );
|
||||
m_editSchematicSymbolBtn->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnEditSymbol ), NULL, this );
|
||||
m_editSchematicSymbolBtn->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::onUpdateEditSymbol ), NULL, this );
|
||||
m_editLibrarySymbolBtn->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnEditLibrarySymbol ), NULL, this );
|
||||
m_editLibrarySymbolBtn->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::onUpdateEditLibrarySymbol ), NULL, this );
|
||||
m_pinGrid->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnPinTableCellEdited ), NULL, this );
|
||||
m_spiceFieldsButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnEditSpiceModel ), NULL, this );
|
||||
m_stdDialogButtonSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES_BASE::OnCancelButtonClick ), NULL, this );
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<wxFormBuilder_Project>
|
||||
<FileVersion major="1" minor="15" />
|
||||
<FileVersion major="1" minor="16" />
|
||||
<object class="Project" expanded="1">
|
||||
<property name="class_decoration">; </property>
|
||||
<property name="code_generation">C++</property>
|
||||
@@ -14,6 +14,7 @@
|
||||
<property name="file">dialog_symbol_properties_base</property>
|
||||
<property name="first_id">1000</property>
|
||||
<property name="help_provider">none</property>
|
||||
<property name="image_path_wrapper_function_name"></property>
|
||||
<property name="indent_with_spaces"></property>
|
||||
<property name="internationalize">1</property>
|
||||
<property name="name">dialog_edit_component_in_schematic_base</property>
|
||||
@@ -25,6 +26,7 @@
|
||||
<property name="skip_php_events">1</property>
|
||||
<property name="skip_python_events">1</property>
|
||||
<property name="ui_table">UI</property>
|
||||
<property name="use_array_enum">0</property>
|
||||
<property name="use_enum">0</property>
|
||||
<property name="use_microsoft_bom">0</property>
|
||||
<object class="Dialog" expanded="1">
|
||||
@@ -50,6 +52,7 @@
|
||||
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
|
||||
<property name="title">Symbol Properties</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="two_step_creation">0</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
@@ -301,6 +304,7 @@
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
@@ -374,6 +378,7 @@
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
@@ -447,6 +452,7 @@
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
@@ -530,6 +536,7 @@
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
@@ -1429,6 +1436,7 @@
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
@@ -1502,6 +1510,7 @@
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
@@ -1575,6 +1584,7 @@
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
@@ -1633,6 +1643,7 @@
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick">OnEditSymbol</event>
|
||||
<event name="OnUpdateUI">onUpdateEditSymbol</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
@@ -1658,6 +1669,7 @@
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
@@ -1716,6 +1728,7 @@
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick">OnEditLibrarySymbol</event>
|
||||
<event name="OnUpdateUI">onUpdateEditLibrarySymbol</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
@@ -2058,6 +2071,7 @@
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -77,7 +77,7 @@ class DIALOG_SYMBOL_PROPERTIES_BASE : public DIALOG_SHIM
|
||||
wxButton* m_stdDialogButtonSizerOK;
|
||||
wxButton* m_stdDialogButtonSizerCancel;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void OnInitDlg( wxInitDialogEvent& event ) { event.Skip(); }
|
||||
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnGridEditorShown( wxGridEvent& event ) { event.Skip(); }
|
||||
@@ -91,7 +91,9 @@ class DIALOG_SYMBOL_PROPERTIES_BASE : public DIALOG_SHIM
|
||||
virtual void OnUpdateSymbol( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnExchangeSymbol( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnEditSymbol( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onUpdateEditSymbol( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnEditLibrarySymbol( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onUpdateEditLibrarySymbol( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnPinTableCellEdited( wxGridEvent& event ) { event.Skip(); }
|
||||
virtual void OnEditSpiceModel( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnCancelButtonClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
@@ -100,6 +102,7 @@ class DIALOG_SYMBOL_PROPERTIES_BASE : public DIALOG_SHIM
|
||||
public:
|
||||
|
||||
DIALOG_SYMBOL_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Symbol Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU );
|
||||
|
||||
~DIALOG_SYMBOL_PROPERTIES_BASE();
|
||||
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <confirm.h>
|
||||
#include <reporter.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <wx_filename.h>
|
||||
#include <wx_html_report_panel.h>
|
||||
|
||||
#include <symbol_library.h>
|
||||
@@ -201,7 +202,7 @@ void DIALOG_SYMBOL_REMAP::createProjectSymbolLibTable( REPORTER& aReporter )
|
||||
wxFileName tmpFn = fullFileName;
|
||||
|
||||
// Don't add symbol libraries that do not exist.
|
||||
if( tmpFn.Normalize() && tmpFn.FileExists() )
|
||||
if( tmpFn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ) && tmpFn.FileExists() )
|
||||
{
|
||||
msg.Printf( _( "Adding library '%s', file '%s' to project symbol library table." ),
|
||||
libName,
|
||||
|
||||
@@ -47,7 +47,7 @@ DIALOG_UPDATE_SYMBOL_FIELDS::DIALOG_UPDATE_SYMBOL_FIELDS( SYMBOL_EDIT_FRAME* aPa
|
||||
|
||||
for( int i = 0; i < MANDATORY_FIELDS; ++i )
|
||||
{
|
||||
m_fieldsBox->Append( TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) );
|
||||
m_fieldsBox->Append( TEMPLATE_FIELDNAME::GetDefaultFieldName( i, DO_TRANSLATE ) );
|
||||
m_fieldsBox->Check( i, true );
|
||||
}
|
||||
|
||||
|
||||
+17
-1
@@ -321,7 +321,20 @@ void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aProje
|
||||
ext == KiCadSchematicFileExtension + BackupFileSuffix )
|
||||
{
|
||||
if( destFile.GetName() == aProjectName )
|
||||
{
|
||||
destFile.SetName( aNewProjectName );
|
||||
}
|
||||
else if( destFile.GetName() == aNewProjectName )
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
if( !aErrors.empty() )
|
||||
aErrors += "\n";
|
||||
|
||||
msg.Printf( _( "Cannot copy file '%s'." ), destFile.GetFullPath() );
|
||||
aErrors += msg;
|
||||
return;
|
||||
}
|
||||
|
||||
// Sheet paths when auto-generated are relative to the root, so those will stay
|
||||
// pointing to whatever they were pointing at.
|
||||
@@ -343,7 +356,10 @@ void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aProje
|
||||
ext == KiCadSymbolLibFileExtension )
|
||||
{
|
||||
if( destFile.GetName() == aProjectName + wxT( "-cache" ) )
|
||||
destFile.SetName( aNewProjectName + wxT( "-cache" ) );
|
||||
destFile.SetName( aNewProjectName + wxT( "-cache" ) );
|
||||
|
||||
if( destFile.GetName() == aProjectName + wxT( "-rescue" ) )
|
||||
destFile.SetName( aNewProjectName + wxT( "-rescue" ) );
|
||||
|
||||
KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
|
||||
}
|
||||
|
||||
@@ -389,7 +389,7 @@ wxString FIELDS_GRID_TABLE<T>::GetValue( int aRow, int aCol )
|
||||
if( aRow < m_mandatoryFieldCount )
|
||||
{
|
||||
if( m_parentType == SCH_SYMBOL_T )
|
||||
return TEMPLATE_FIELDNAME::GetDefaultFieldName( aRow );
|
||||
return TEMPLATE_FIELDNAME::GetDefaultFieldName( aRow, DO_TRANSLATE );
|
||||
else if( m_parentType == SCH_SHEET_T )
|
||||
return SCH_SHEET::GetDefaultFieldName( aRow );
|
||||
}
|
||||
|
||||
+14
-9
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2013 CERN (www.cern.ch)
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023 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
|
||||
@@ -489,7 +489,6 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
{
|
||||
DIALOG_MIGRATE_BUSES dlg( this );
|
||||
dlg.ShowQuasiModal();
|
||||
RecalculateConnections( NO_CLEANUP );
|
||||
OnModify();
|
||||
}
|
||||
|
||||
@@ -516,6 +515,8 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
SyncView();
|
||||
GetScreen()->ClearDrawingState();
|
||||
|
||||
TestDanglingEnds();
|
||||
|
||||
UpdateHierarchyNavigator();
|
||||
UpdateTitle();
|
||||
|
||||
@@ -624,7 +625,8 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
|
||||
allWildcards += "*." + formatWildcardExt( plugin->GetFileExtension() ) + ";";
|
||||
}
|
||||
|
||||
fileFilters = _( "All supported formats|" ) + allWildcards + "|" + fileFilters;
|
||||
fileFilters = _( "All supported formats" ) + wxS( "|" ) + allWildcards + wxS( "|" ) +
|
||||
fileFilters;
|
||||
|
||||
wxFileDialog dlg( this, _( "Import Schematic" ), path, wxEmptyString, fileFilters,
|
||||
wxFD_OPEN | wxFD_FILE_MUST_EXIST ); // TODO
|
||||
@@ -1419,12 +1421,17 @@ void SCH_EDIT_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
|
||||
" Auto save file: '%s'" ),
|
||||
recoveredFn.GetFullPath(), backupFn.GetFullPath(), fn );
|
||||
|
||||
// Attempt to back up the last schematic file before overwriting it with the auto
|
||||
// save file.
|
||||
if( !wxCopyFile( recoveredFn.GetFullPath(), backupFn.GetFullPath() ) )
|
||||
if( !wxFileExists( fn ) )
|
||||
{
|
||||
unrecoveredFiles.Add( recoveredFn.GetFullPath() );
|
||||
}
|
||||
// Attempt to back up the last schematic file before overwriting it with the auto
|
||||
// save file.
|
||||
else if( !wxCopyFile( recoveredFn.GetFullPath(), backupFn.GetFullPath() ) )
|
||||
{
|
||||
unrecoveredFiles.Add( recoveredFn.GetFullPath() );
|
||||
}
|
||||
// Attempt to replace last saved file with auto save file
|
||||
else if( !wxRenameFile( fn, recoveredFn.GetFullPath() ) )
|
||||
{
|
||||
unrecoveredFiles.Add( recoveredFn.GetFullPath() );
|
||||
@@ -1452,10 +1459,8 @@ void SCH_EDIT_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
|
||||
{
|
||||
wxLogTrace( traceAutoSave, wxT( "Removing auto save file " ) + fn );
|
||||
|
||||
if( !wxRemoveFile( fn ) )
|
||||
{
|
||||
if( wxFileExists( fn ) && !wxRemoveFile( fn ) )
|
||||
unremovedFiles.Add( fn );
|
||||
}
|
||||
}
|
||||
|
||||
if( !unremovedFiles.IsEmpty() )
|
||||
|
||||
@@ -403,10 +403,11 @@ wxString LIB_FIELD::GetCanonicalName() const
|
||||
{
|
||||
switch( m_id )
|
||||
{
|
||||
case REFERENCE_FIELD: return wxT( "Reference" );
|
||||
case VALUE_FIELD: return wxT( "Value" );
|
||||
case FOOTPRINT_FIELD: return wxT( "Footprint" );
|
||||
case DATASHEET_FIELD: return wxT( "Datasheet" );
|
||||
case REFERENCE_FIELD:
|
||||
case VALUE_FIELD:
|
||||
case FOOTPRINT_FIELD:
|
||||
case DATASHEET_FIELD:
|
||||
return TEMPLATE_FIELDNAME::GetDefaultFieldName( m_id );
|
||||
}
|
||||
|
||||
return m_name;
|
||||
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
void Init( int aId );
|
||||
|
||||
/**
|
||||
* Return the field name.
|
||||
* Return the field name (not translated).
|
||||
*
|
||||
* The first four field IDs are reserved and therefore always return their respective
|
||||
* names.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2015 Jean-Pierre Charras, jaen-pierre.charras at wanadoo.fr
|
||||
* Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2004-2021 KiCad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see change_log.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
|
||||
@@ -49,7 +49,7 @@ void LIB_ITEM::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_IT
|
||||
if( m_unit == 0 )
|
||||
msg = _( "All" );
|
||||
else
|
||||
msg.Printf( wxT( "%d" ), m_unit );
|
||||
msg = LIB_SYMBOL::SubReference( m_unit, false );
|
||||
|
||||
aList.emplace_back( _( "Unit" ), msg );
|
||||
|
||||
|
||||
@@ -886,7 +886,7 @@ int LIB_PIN::compare( const LIB_ITEM& aOther, int aCompareFlags ) const
|
||||
if( !( aCompareFlags & COMPARE_FLAGS::UNIT ) && m_number != tmp->m_number )
|
||||
return m_number.Cmp( tmp->m_number );
|
||||
|
||||
int result = m_name.CmpNoCase( tmp->m_name );
|
||||
int result = m_name.Cmp( tmp->m_name );
|
||||
|
||||
if( result )
|
||||
return result;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user