Compare commits

...

159 Commits

Author SHA1 Message Date
Wayne Stambaugh 582732918d Tag release version 7.0.2. 2023-04-13 16:27:39 -04:00
Lucas Dumont f1f69c607e Check KiFACE return value
Avoid segfault when cancelling initial global library setup

(Cherry-picked from 3c24017aa4)
2023-04-13 14:39:49 +01:00
Jeff Young 8e82fee494 Attempt to fix gcc compile error. 2023-04-13 13:57:14 +01:00
Jeff Young a51475a094 Performance improvement for GetShownColumns.
(This needs to be fast as it's called from OnUpdateUI events.)

(cherry picked from commit 8e29a054f3)
2023-04-13 13:47:21 +01:00
Jeff Young f25e2d48bd Search in label fields.
Fixes https://gitlab.com/kicad/code/kicad/issues/14075

(cherry picked from commit a24a63e416)
2023-04-13 10:59:39 +01:00
jean-pierre charras 2bbff64a12 Fix compatibility of QA golden files with 7.0x version 2023-04-13 08:01:32 +02:00
Seth Hillbrand 70b4503187 Fix cherry-pick errors 2023-04-13 02:11:39 +02:00
Jeff Young 912bd4458f Don't trip over a uniquified-name in the schematic library-symbol cache.
Fixes https://gitlab.com/kicad/code/kicad/issues/14160
2023-04-12 18:35:27 +01:00
Ian McInerney d3f4494925 Make version info work without lsb-release installed
(Cherry-picked from 8351c8923a)
2023-04-12 16:13:51 +01:00
Ian McInerney 464467ae8b Fix nanodbc build with clang and gcc stdlib
This should really be fixed upstream somehow, but the upstream build
with clang is broken on Fedora 38 right now anyway due to header issues.

(Cherry-picked from 45b8dced92)
2023-04-12 16:10:20 +01:00
Ian McInerney 8e579ec8e0 Remove python-based board_item duplicate method
This method shadows the C++ method, and doesn't properly handle updating
the duplicated object's KIID to be unique.

Also add tests to ensure the KIIDs are unique after duplication.

Fixes https://gitlab.com/kicad/code/kicad/issues/14460

(Cherry-picked from 5d0b5e16ff)
2023-04-12 16:07:00 +01:00
Ian McInerney 4ef6cbf4fb Add hack to speed up font choice box widget creation
There are problems internal to GTK that mean creating choice boxes with
a lot of items is a very slow process. This hack works around one of
those issues to make it faster to create and display the menu in the
choice box.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/14277

(Cherry-picked from a77e94d16f)
2023-04-12 15:24:25 +01:00
Seth Hillbrand 68dfcddbe9 Allow bus elements to connect
Previously, bus elements that were not instantiated as individual nets
could not connect to each other.  This caused issues for complex
schematics where busses needed to connect to other busses with elements
that resolved to the same net names.  Functionally, this means mixing
bus elements, which we will replace with first-class elements in version
8 but currently can only be accomplished either by using bus aliases and
  this patch or by individually instantiating each bus element as a
local label

Fixes https://gitlab.com/kicad/code/kicad/issues/14300

(cherry picked from commit 16b4ec3c7e)
2023-04-12 16:10:50 +02:00
jean-pierre charras 907761f14e SCH_LABEL_BASE::SetPosition(): ensure field positions are also handled.
Fixes #14520
https://gitlab.com/kicad/code/kicad/issues/14520
2023-04-12 11:20:41 +02:00
jean-pierre charras be7917c8d8 LIB_TABLE_GRID_TRICKS, popup context menu: fix minor issues:
- add separator only if needed
- ensure selection parameters are up to date.
From master branch
2023-04-12 11:20:11 +02:00
jean-pierre charras 2e25f09ae4 French translation update 2023-04-12 09:47:43 +02:00
jean-pierre charras ea95d8604a Ensure we do not use a non existing pin in SIM_MODEL::MigrateSimModel()
From master branch
Fixes #14522
https://gitlab.com/kicad/code/kicad/issues/14522
2023-04-12 09:41:07 +02:00
Marek Roszko 35def3ab2e Prevent VIEW::UpdateItems and onShowTimer from firing repaints if GAL did not complete init
This appears to be a possible event race on startup

Fixes sentry KICAD-10A


(cherry picked from commit bfad8bb0d5)
2023-04-12 02:10:34 +00:00
Marek Roszko 5527c12a8d Fix crash due to extra right parens in pcad files
Fixes sentry KICAD-TA


(cherry picked from commit 37eaa29679)
2023-04-12 01:53:29 +00:00
Mark Roszko fb1cc72013 Don't crash on empty pcad polygons
Fixes sentry KICAD-103
2023-04-12 01:41:06 +00:00
Jeff Young 1f34883a27 Make symbol/footprint trees sensitive to language change.
(cherry picked from commit eef3492fc0)
2023-04-12 00:01:58 +01:00
jean-pierre charras 724262651f manage libraries dialog: show new state of widgets as soon as the context-menu
activate/deactivate changes their state
From master branch
Fixes #14517
https://gitlab.com/kicad/code/kicad/issues/14517
2023-04-11 18:55:51 +02:00
Alex d7b2247878 opengl_gal: Remove extra padding of bitmap textures.
Since the format has been changed to RGBA8, default (UN)PACK_ALIGNMENT = 4
works correctly, so the texture width padding to 4 is not needed anymore.

Fixes https://gitlab.com/kicad/code/kicad/issues/14432


(cherry picked from commit e91b53fc39)
2023-04-11 04:32:42 +00:00
jean-pierre charras 372e7b6312 fix 2 issues related to SCH_GLOBALLABEL items:
- Ensure the first field in m_fields has id = 0 to be seen has hypertext
(it was not the case after reading a .kicad_sch file)
- when converting this item to another label/text, remove this special Field
from the copied field list to the converted label.
From master branch.
2023-04-10 10:02:50 +02:00
Jeff Young 323a2d83fa Ease acquisition of a target item.
pickSingleItem() had a two-attempt algorithm, but the second attempt
was never made because we'd check for no hits before throwing out the
aAvoidItems.

The second attempt would fail anyway because QueryHoverItems() ignored
the aUseClearance flag when not idle, and didn't factor in the actual
clearance.

(cherry picked from commit d040690f60)
2023-04-09 23:13:44 +01:00
Jeff Young 03c3393616 Handle more pad shapes when building diffpair gateways.
Fixes https://gitlab.com/kicad/code/kicad/issues/1883

(cherry picked from commit 1d19672054)
2023-04-09 23:07:38 +01:00
Jeff Young cbff011e3c Don't delete default intersheetrefs field from global labels.
Fixes https://gitlab.com/kicad/code/kicad/issues/14493

(cherry picked from commit a226f7fc14)
2023-04-09 19:04:33 +01:00
Jeff Young 2ba6fad633 Centralize NPTH has-annulus processing.
Fixes https://gitlab.com/kicad/code/kicad/issues/13437

(cherry picked from commit 3b63d70d01)
2023-04-09 19:04:33 +01:00
Mark Roszko bc4878d71e Update ngspice to 40 in vcpkg 2023-04-09 02:16:09 +00:00
jean-pierre charras e991ae504b DIALOG_IMAGE_PROPERTIES: fix some issues:
- add missing panel_image_properties_base.fpb file
- fix not displayed image.
From master branch
2023-04-08 17:04:02 +02:00
Seth Hillbrand c18181042f Simplify test for substantial nubs
Substantial elements following a divot should be at least as far in each
cardinal direction from the origin point in order to be considered
substantial.  This catches cases where the "substantial" element is
actually a straight segment away from the divot

Fixes https://gitlab.com/kicad/code/kicad/issues/14130

(cherry picked from commit 914b5a4d21)
2023-04-07 16:41:11 -07:00
jean-pierre charras 3de80d3b20 Plot gerber: fix a too zealous plot of negative objects on the silkscreen layers,
when merging layers to silkscreen layers.
From master branch
2023-04-07 11:34:42 +02:00
Seth Hillbrand 39dcd0a352 Handle nested netclass assignments
Netclass directives should not be overriden, instead hold our error
checking for actually missing nets

Fixes https://gitlab.com/kicad/code/kicad/issues/14494

(cherry picked from commit 012737593b)
2023-04-06 17:38:42 -07:00
Jeff Young 199e31ea3f Eagle template footprints don't actually belong to board.
Set their parent to nullptr before deleting (as the board may have
already been deleted).

Likely fix for Sentry KICAD-79.

(cherry picked from commit 13e79af8a0)
2023-04-04 14:21:19 +01:00
Jeff Young dce2247925 Improve scoping control of connetion members.
(The real bug here is that CONNECTION_GRAPH::assignNetCodesToBus() was
growing the bus aliases members list because it used a non-const
reference to it as a local storage list.  The const scoping of it will
prevent this type of error in future.)

Fixes https://gitlab.com/kicad/code/kicad/issues/14269
2023-04-04 11:35:06 +01:00
Jeff Young 89e78c0276 Fix Mac crash-on-quit when timed infobar is up.
(cherry picked from commit b3e2cf218f)
2023-04-03 23:47:14 +01:00
Jeff Young 9a57c11348 Possible protection from acessing deleted window data.
(Long shot for Sentry KICAD-MM.)

(cherry picked from commit bd60f38569)
2023-04-03 23:47:09 +01:00
Jeff Young 1dbe8b2a79 Nullptr safety.
(This is a long shot for Sentry KICAD-MV, but you never know....)

(cherry picked from commit a4e8fa96d4)
2023-04-03 23:47:00 +01:00
Seth Hillbrand 29fd0caf58 Update translator contributions
Adds a number of missing contributors to our translations

(cherry picked from commit d135295ac8)
2023-04-03 13:07:33 -07:00
jean-pierre charras d30701ed59 Fix compil warnings.
(cherry picked from commit ac71227e75)
2023-04-03 10:14:14 -07:00
Seth Hillbrand e39550e77f Update to Clipper 1.2+
Updates to Clipper2 742614f, which includes bug fixes for specific KiCad
boards beyond Clipper2 itself

Fixes https://gitlab.com/kicad/code/kicad/issues/14294

(cherry picked from commit 97558b62ec)

Fixes https://gitlab.com/kicad/code/kicad/issues/14475
2023-04-03 10:06:34 -07:00
Jeff Young a21e7a5eee Don't pass a FRAME-based UNITS_PROVIDER to a modeless dialog.
(The dialog may outlive said frame.)
Should fix Sentry KICAD-3A.

(cherry picked from commit 9b4627e782)
2023-04-03 17:20:06 +01:00
Jeff Young 927b5ae707 Use enums for column ids.
(The nickname, in particular, is no longer column 1.)

Fixes https://gitlab.com/kicad/code/kicad/issues/14291
2023-04-02 15:28:11 +01:00
jean-pierre charras f59626004c PCB_TEXT::TransformTextToPolySet(): fix missing code for knockout texts.
From master branch
Fixes #14473
https://gitlab.com/kicad/code/kicad/issues/14473
2023-04-02 10:29:18 +02:00
Jeff Young 2ece2719d0 Naming conventions and nullptr usage. No functional changes. 2023-04-01 15:14:35 +01:00
Jeff Young 78ee542d8d Naming conventions. 2023-04-01 14:11:56 +01:00
Jeff Young cea9b38815 Update local coords after changing footprint item properties.
Fixes https://gitlab.com/kicad/code/kicad/issues/14348

(cherry picked from commit 0f9a4ef7b7)
2023-04-01 13:57:47 +01:00
Jeff Young cb8f6db68d Add hole clearance to moutning hole keepouts for SPECCTRA.
Fixes https://gitlab.com/kicad/code/kicad/issues/14439
2023-04-01 13:57:47 +01:00
Seth Hillbrand 85038c2b46 Prevent PCB Editor from opening multiple board_setup
ShowBoardSetup can be called multiple times from multiple locations,
resulting in duplicate board setup dialog boxes.  This is confusing and
should be prevented.  We use the established patter from the symbol
picker to ensure that only one copy of the dialog is ever opened at a
time

(cherry picked from commit 7695d510d6)
2023-03-30 15:34:42 -07:00
Roberto Fernandez Bautista 1e8055f504 CADSTAR PCB Importer: Ignore construction layers on outer surfaces
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14443

7.0 version of d5bc223ff2 (no strings)
2023-03-31 00:17:06 +02:00
jean-pierre charras a7a5f20d1c Pcbnew: fix incorrect position of cached text shapes when moving a footprint.
when moving a footprint, the position of texts living in FP_TEXT_BOX was
not updated when the text shape was cached (non Kicad fonts).
From master branch.
Fixes #14452
https://gitlab.com/kicad/code/kicad/issues/14452
2023-03-30 17:33:44 +02:00
jean-pierre charras 0d744a4e74 kicad-cli, layer names: allows using both names used in GUI and in board files
From master branch
Fixes #14455
https://gitlab.com/kicad/code/kicad/issues/14455
2023-03-30 13:50:09 +02:00
jean-pierre charras 216ec60dc1 kicad-cli, export drill files: fix duplicate options and fix some others:
- remove --separate-files duplicate option
- change --units to --excellon-units (valid only for Excellon) and default to mm
- Gerber resolution: 5 -> 6 (default must be always the higher resolution)
From Master
Fixes #14454
https://gitlab.com/kicad/code/kicad/issues/14454
2023-03-30 10:35:46 +02:00
Roberto Fernandez Bautista 3d9047bec4 Revert "CADSTAR PCB importer: Fix incorrect position of overridden pads"
This reverts commit 5cab66fb18
2023-03-29 21:53:14 +00:00
Roberto Fernandez Bautista 08d65beb26 CADSTAR PCB importer: Fix loading of rounded rectangle pads
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14445


(cherry picked from commit aaeb8ca739)
2023-03-29 20:56:14 +00:00
Roberto Fernandez Bautista 5cab66fb18 CADSTAR PCB importer: Fix incorrect position of overridden pads
(cherry picked from commit 89441d807d)
2023-03-29 20:55:50 +00:00
jean-pierre charras 9466624f9d Footprint editor: always export the currently loaded footprint.
Previously, it was not always the edited footprint, but a footprint
selected from the library tree.
It was especially annoying when the footprint was loaded from the board editor:
The footprint was not the loaded footprint, but its copy from library.
From master branch
2023-03-29 20:30:25 +02:00
jean-pierre charras 80b842a704 Footprint viewer: ensure the footprint is updated after new library selection
Previously, if the first fp of the new lib has the same name as the old
displayed fp, the old fp was not replace by the new fp.
From master branch
2023-03-29 16:59:12 +02:00
Seth Hillbrand d513a9fe5c Locked shadow needs to be in shadow color
Otherwise, text shadow is stroked by text color

(cherry picked from commit f93fde15b7)
2023-03-28 13:02:18 -07:00
jean-pierre charras c98081cb04 QA test: disable Silk clearance test in solder mask bridge QA test.
the Silk clearance test has nothing to do with a solder mask bridge QA test
From master branch
2023-03-27 12:50:14 +02:00
Jon Evans 17a1dc18be Properties: Hide Net Class from GUI
It is confusing users who want to change the netclass of a net.

(cherry picked from commit 3f42e6b702)
2023-03-26 19:50:10 -04:00
Jon Evans b22ff229db DbLib: Get rid of some GCC warnings
(cherry picked from commit c35cefe1d5)
2023-03-26 19:48:58 -04:00
Jon Evans 23b03fd6ab Properties: Rename methods to better reflect their purposes
(cherry picked from commit 65193487a6)
2023-03-26 19:48:46 -04:00
Jeff Young 97b273905a Manual cherry-pick of a214ac0310. 2023-03-26 21:06:24 +01:00
Jeff Young e759c4d27a Only report on clearances where there was one defined.
If it's 0, it's just a straight-up collision.

(cherry picked from commit 9976b9ce8c)
2023-03-26 20:59:41 +01:00
Jeff Young 76685ae2d9 Run SILK_CLEARANCE rules on mask layer when testing silk-to-mask clearance.
This allows custom rules to be authored without firing the auto-generated
rule from Board Setup > Silk Item Clearance (which should be only for silk-
to-silk clearances).

Fixes https://gitlab.com/kicad/code/kicad/issues/14417

(cherry picked from commit 0266d03f79)
2023-03-26 20:59:36 +01:00
Jeff Young 3fad3ceb35 Update allow-solder-mask-bridges when updating footprint from library.
Fixes https://gitlab.com/kicad/code/kicad/issues/14422
2023-03-26 16:25:54 +01:00
Jeff Young dede9e8549 Test silk/mask collisions on the correct layer.
Fixes https://gitlab.com/kicad/code/kicad/issues/14417
2023-03-26 16:25:54 +01:00
Roberto Fernandez Bautista 97c018118d CADSTAR Sch: TERMATTR may have more than one attribute subnode
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13526


(cherry picked from commit fc04f5135f)
2023-03-26 14:55:06 +00:00
jean-pierre charras 8b1ce36402 QA pcbnew: Add missing golden files and disable issue14294 that always fails.
It needs a Clipper2 update, not yet made in stable branch (made only in testing).
2023-03-26 15:09:35 +02:00
Jeff Young 7931f315b1 Manually cherry-pick some fixes back from master.
Fixes https://gitlab.com/kicad/code/kicad/issues/14424
2023-03-26 11:00:23 +01:00
Marek Roszko abb6404ab2 Move up a layer validity check to prevent crash
Fixes sentry crash KICAD-RF


(cherry picked from commit 604a7d69db)
2023-03-25 21:13:38 +00:00
Wayne Stambaugh c434542c65 Fix GCC compile error.
(cherry picked from commit a79108f102)
2023-03-25 17:35:39 +00:00
Marek Roszko 42b7aa6450 Use read/write locks in the settings_manager to avoid thread issues in some scenarios
Fixes sentry issue KICAD-90


(cherry picked from commit ab28650d57)
2023-03-25 17:35:31 +00:00
jean-pierre charras f2ce9cf857 Plot symbol graphic texts: fix incorrect position of texts in some rotations.
The plot code is now similar to the one for symbol fields
From master branch.
Fixes #14327
https://gitlab.com/kicad/code/kicad/issues/14327
2023-03-25 18:27:35 +01:00
jean-pierre charras 56134d0202 KICAD_CURL_EASY: fix compil warnings (avoid using deprecated functions) 2023-03-25 18:27:35 +01:00
Jeff Young f33bbe2d5d Add regression test for 14412.
(cherry picked from commit 30b3645e60)
2023-03-25 16:16:10 +00:00
Jeff Young 59a478bdc5 Allow solder mask bridges between net-tie-group pads.
Fixes https://gitlab.com/kicad/code/kicad/issues/14412

(cherry picked from commit c5e66361db)
2023-03-25 16:15:46 +00:00
Jeff Young 141b332d4f Add regression test for 13988.
(cherry picked from commit 35ca3e7264)
2023-03-25 15:37:57 +00:00
Jeff Young d4a312d6cb Move separation of model name from params earlier in the process.
We need just the model name when we look for a match in the library file.

(cherry picked from commit 60aadfee40)
2023-03-25 15:37:57 +00:00
Jeff Young 31d688b34c Add regression test for 14334.
(cherry picked from commit e65a58b823)
2023-03-25 15:37:57 +00:00
Jeff Young fbef9ea600 Keep track of single-pad-islands so we can discount spokes to them.
(cherry picked from commit d6dd58fff9)
2023-03-25 15:37:57 +00:00
Marek Roszko 0688491e1b Fix typo
(cherry picked from commit eb90448247)
2023-03-24 23:55:24 +00:00
Marek Roszko 434161687e Fix cli crash due to dialogs buried in the pcb parser...
Fixes sentry KICAD-Q2


(cherry picked from commit 8a8589b9db)
2023-03-24 23:53:15 +00:00
Seth Hillbrand 4b3709b96b Revert "Update to Clipper2 1.2+"
This reverts commit 560717de76.
2023-03-24 12:30:11 -07:00
Seth Hillbrand 1fa993303d Revert "Undefine None for X11 after Clipper2 update"
This reverts commit 4f265a52a2.
2023-03-24 12:30:11 -07:00
Seth Hillbrand 01897e7755 Revert "Fix GCC 13 build error."
This reverts commit 00d1e01e12.
2023-03-24 12:30:10 -07:00
Seth Hillbrand 7040b2178d Revert "Update for Clipper 1.2"
This reverts commit e758391a23.
2023-03-24 12:30:09 -07:00
Seth Hillbrand edf23c4c18 Revert "Clean up various simplify steps"
This reverts commit 798e13f70d.
2023-03-24 12:30:06 -07:00
Jon Evans b0b9e66fad Move to requiring explicit action to save project settings
(cherry picked from commit 610e787ada)

Fixes https://gitlab.com/kicad/code/kicad/issues/14414
2023-03-24 11:49:50 -07:00
Seth Hillbrand 89488a43b9 Pins are case-sensitive
Cleanup should remove mis-matched cases

Fixes https://gitlab.com/kicad/code/kicad/issues/14415

(cherry picked from commit 0984599624)
2023-03-24 11:35:20 -07:00
Seth Hillbrand 798e13f70d Clean up various simplify steps
Adds the option to simplify the output of Clipper ops that remove minor
detours from the output lines.  These detours are not substantive, so
removing them speeds up the rest of the system by removing unimportant
vertices.  This also prevents the introduction of inadvertant concave
points when unioning two, closely-sized rounded shapes
2023-03-24 09:42:01 -07:00
Seth Hillbrand e758391a23 Update for Clipper 1.2 2023-03-24 09:42:01 -07:00
Steven A. Falco 00d1e01e12 Fix GCC 13 build error.
See https://kicad.zulipchat.com/#narrow/stream/258851-Developer-Chat/topic/GCC.20Breakage
for more info.
2023-03-24 09:42:01 -07:00
Seth Hillbrand 4f265a52a2 Undefine None for X11 after Clipper2 update 2023-03-24 09:42:01 -07:00
Seth Hillbrand 560717de76 Update to Clipper2 1.2+
Updates to 303232e, which includes bug fixes for specific KiCad boards
beyond Clipper2 1.2 itself

Fixes https://gitlab.com/kicad/code/kicad/issues/14294
2023-03-24 09:42:01 -07:00
jean-pierre charras 0f40894317 Pcbnew, APPEARANCE_CONTROLS: do not change objects visibility, when changing
layers visibility using Preset layers widget.
Fixes #14381
https://gitlab.com/kicad/code/kicad/issues/14381
2023-03-24 15:06:06 +01:00
jean-pierre charras 3915e882a8 Gerbview: Aperture Macro: handle overwriting of variables
Gerbview did not handle redefinition of variable like $3 = $3 / 2
This redefinition is sometimes found in Gerber files.
This is a long standing issue now fixed.
From master branch
2023-03-24 12:02:49 +01:00
jean-pierre charras c5caa23a63 Manager teardrops on arcs. From master branch. 2023-03-24 11:46:11 +01:00
jean-pierre charras 36978d2ddc Gerber plotter: fix incorrect arcs in regions when using a plot offset.
The arc center in Gerber units was incorrectly calculated.
From master
Fixes #14402
https://gitlab.com/kicad/code/kicad/issues/14402
2023-03-24 11:37:26 +01:00
Marek Roszko 3f90c895b9 Prevent crash in color settings due to dropdown weirdness
Fixes sentry reported crash KICAD-R6


(cherry picked from commit c65e33ac13)
2023-03-23 23:47:13 +00:00
Jon Evans 2ada171806 Be more flexible about extracting booleans from database
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14376


(cherry picked from commit dd8b52af93)
2023-03-23 01:25:09 +00:00
Marek Roszko 5dc683c968 Fix crash editing footprint editor defaults
Missing one level of GetParent()....use a dynamic_cast to sanity check it in debug

Fixes sentry crash KICAD-R4


(cherry picked from commit d49562a7aa)
2023-03-22 22:41:57 +00:00
Jeff Young 7026cfe140 Split name from additional params only when model is a library reference.
(cherry picked from commit b8cf7cc080)
2023-03-22 14:12:42 +00:00
Jeff Young b7cd1dd764 Handle single-token flag parameters.
Also fixes a bug where all VDMOS instance parameters weren't marked as
instance parameters.

Also fixes a bug where VDMOS thermal models weren't supported (they
have two extra pins: Tj and Tcase).

(cherry picked from commit 5bda3b99f9)
2023-03-22 14:12:42 +00:00
Jeff Young 09bb8fc4f4 Don't include non-overridden parameters in Sim.Params.
Fixes https://gitlab.com/kicad/code/kicad/issues/14369

(cherry picked from commit 9dc16eb014)
2023-03-22 14:12:42 +00:00
jean-pierre charras 746ab49d36 Ensure 3D shapes are always shown in footprint settings dialog.
From master branch
Fixes #14371
https://gitlab.com/kicad/code/kicad/issues/14371
2023-03-22 08:53:42 +01:00
Jeff Young 1614dc975a Separate legacy model name from parameters.
Fixes https://gitlab.com/kicad/code/kicad/issues/13988

(cherry picked from commit 39a801423e)
2023-03-21 13:31:20 +00:00
Alex ba7598d90d Fix clashing error dialogs when can't load dynamic library.
(cherry picked from commit 672c468342)
2023-03-21 09:57:46 +00:00
Alex 92fc4872e8 GTK: Fix settings import paths showing up twice.
(cherry picked from commit b89545e484)
2023-03-21 09:57:28 +00:00
jean-pierre charras 30dbfc33a4 step exporter: fix missing initialization of a member (m_pcbBaseName)
EXPORTER_STEP: rename m_pcbName to m_pcbBaseName.
From master.
2023-03-21 09:52:41 +01:00
Mark Roszko b3de5aa08e Put the project name back into the step pcb label.
Software like Solidworks and other CAD treat STEP labels as unique entries.
When you import multi STEP files into the same project, it'll start deduplicating your design by those name.
So two completely unrelated PCBs with the same "PCB" name will result in one being replaced by another.
2023-03-21 01:18:33 +00:00
Jeff Young ba4773e448 Orthogonal dimension are always cardinal, even when their start points are not.
Fixes https://gitlab.com/kicad/code/kicad/issues/13728

(cherry picked from commit bb2a0f825a)
2023-03-20 21:32:06 +00:00
Jeff Young a713ee852c Ignore extraneous LTSpice parameters for VDMOS models.
Also adds special case handling of VDMOS syntax to allow parens (or extra
spaces, linebreaks, etc.) between "VDMOS" and "NCHAN"/"PCHAN".

Fixes https://gitlab.com/kicad/code/kicad/issues/14299
2023-03-20 16:16:13 +00:00
jean-pierre charras a65accd412 EDA_SHAPE_DESC(): catch a std::runtime_error when emitted by
template<typename T> T Get( PROPERTY_BASE* aProperty ) to avoid a crash,
and displays in Debug mode the runtime error message.
From master branch.
Fixes #14347
https://gitlab.com/kicad/code/kicad/issues/14347
2023-03-20 16:21:54 +01:00
Jeff Young 1dc9583e06 Don't attempt to load unknown plot types. 2023-03-20 10:24:22 +00:00
Jeff Young 3afe02ac1f Make sure legend reflects gain/phase for AC small signal analyses.
Fixes https://gitlab.com/kicad/code/kicad/issues/14301

(cherry picked from commit ec6d709929)
2023-03-20 10:24:22 +00:00
Jeff Young 57aa61f1ba Formatting. (No functional changes.)
(cherry picked from commit 6f44b85c13)
2023-03-20 09:59:30 +00:00
Jeff Young 121ea14fe4 Filter Selected Items... is inclusive, not exclusive.
Fixes https://gitlab.com/kicad/code/kicad/issues/14273

(cherry picked from commit 897984aa22)
2023-03-19 21:31:08 +00:00
Jeff Young 9d457dc0ab Less nagging. (If we need a field name, then create one.)
Also cleans up empty fields when exiting the dialog.
2023-03-19 19:15:28 +00:00
Jeff Young befd836ab4 Clean up items which weren't pasted from clipboard.
Fixes https://gitlab.com/kicad/code/kicad/issues/14335

(cherry picked from commit ad5d3d4eba)
2023-03-18 23:38:09 +00:00
Jeff Young 044c301d64 Remove accelerator keys from schematic find/replace dialog.
Fixes https://gitlab.com/kicad/code/kicad/issues/14304

(cherry picked from commit afe813cae5)
2023-03-18 23:38:09 +00:00
jean-pierre charras 94fd0df2e2 BOARD_NETLIST_UPDATER: add missing count of warnings
From master branch
Fixes #14290
https://gitlab.com/kicad/code/kicad/issues/14290
2023-03-18 17:57:07 +01:00
Salvador E. Tropea e5087ca3db Load the global fp-lib-table before running the Python DRC
Without this we get parity errors for all the KiCad footprints
2023-03-17 21:00:41 +00:00
jean-pierre charras 819a9da599 Pcbnew: fix crash when loading a library with a ft containing a dimension.
(crash due to the use of a null pointer during loading)

(cherry picked from commit 5735a57504)
2023-03-17 16:00:34 +00:00
Jeff Young fb02e55424 Don't pass a REPORTER when checking for overrides.
It fails the unit tests (as it generates a message whenever no override
is found).
2023-03-17 15:30:24 +00:00
Jeff Young 70e86434ef Manual cherry-pick of much of 6d296038f3 2023-03-17 14:12:58 +00:00
Jeff Young c41b1e2f06 Manual cherry-pick of bug fix part of ee1d9c561c. 2023-03-17 13:35:23 +00:00
Jeff Young 64641c28ef Handle underscore in parameter names.
Fixes https://gitlab.com/kicad/code/kicad/issues/14308

(cherry picked from commit 222cd4d009)
2023-03-16 23:51:56 +00:00
jean-pierre charras 69e9f4ada2 DIALOG_LABEL_PROPERTIES, add global label: better filtering of candidates.
The list of candidates (names) must be restricted to existing global labels
and symbols creating a global net name: power symbols having only one power
input pin (a power output does not create net name).
Fixes #14319
https://gitlab.com/kicad/code/kicad/issues/14319
2023-03-16 16:01:18 +01:00
Wayne Stambaugh d28cf632e4 Coverity fixes and code cleaning.
(cherry picked from commit a1fb8e1b1d)
2023-03-16 10:59:05 -04:00
Alex b466bfa6c8 Improve anti-overflow in SEG::intersects.
Caused issues when testing against
A=( -INT_MAX, ... ), B=( INT_MAX, ... ) segments.

Fixes https://gitlab.com/kicad/code/kicad/issues/14293


(cherry picked from commit 98e635869f)
2023-03-16 02:50:22 +00:00
Alex 1c06f4cf06 Don't create 0-length tracks when placing via in the middle of a track.
(cherry picked from commit 8fe78101db)
2023-03-16 02:49:54 +00:00
jean-pierre charras 25f40566ed Symbol editor: fix incorrect position of fields when loading a symbol from schematic.
In symbol editor, symbols are always shown not mirrored, not rotated.
So if the loaded symbol from schematic was rotated/mirrored, the position
of fields must be recalculated for the rotation 0, no mirror.
From master branch
2023-03-15 18:03:11 +01:00
Marco Ciampa e8fa2cbc4d Small fix in Italian translation 2023-03-15 13:35:38 +01:00
Marco Ciampa 779c441e0a Small fix in Italian translation 2023-03-15 13:31:29 +01:00
Marco Ciampa e33031ee7d Updated Italian translation 2023-03-15 10:18:07 +01:00
jean-pierre charras ae63313b55 PDF plotter: encode the letters ( and ) in strings with context CTX_JS_STR
They are separators and cannot be used in user strings.
Fixes #14302
https://gitlab.com/kicad/code/kicad/issues/14302
2023-03-15 09:36:01 +01:00
jean-pierre charras ae50b8d839 make QA link-able on msys2 (from master branch). 2023-03-14 18:05:18 +01:00
Jeff Young 10a27156c2 Defenses in depth for ratsnest drawing.
(cherry picked from commit e60837ec95)
2023-03-14 12:00:03 +00:00
Jeff Young 94057886a3 Support SHEET_PATH when printing.
Fixes https://gitlab.com/kicad/code/kicad/issues/14233

(cherry picked from commit dc78797274)
2023-03-14 11:56:33 +00:00
Jeff Young 2d9bcb6e4f Select correct face from a .ttc file.
Fixes https://gitlab.com/kicad/code/kicad/issues/13314

(cherry picked from commit 7b3e01ce52)
2023-03-14 11:56:33 +00:00
Jeff Young 249bcd9e1a Update dimension units when opening PCBs in CLI.
Fixes https://gitlab.com/kicad/code/kicad/issues/14170

(cherry picked from commit a0adb59437)
2023-03-14 11:56:33 +00:00
Jeff Young b2679b7648 Swap pins for undo.
Fixes https://gitlab.com/kicad/code/kicad/issues/14100

(cherry picked from commit c266913ec7)
2023-03-14 11:56:33 +00:00
Seth Hillbrand 9995b8714b Check for dirtied items in the cluster
When drawing the ratsnest, we need to be careful to avoid accessing
CONN_ITEMs that have been changed by the underlying model.  Checking for
dirty items instead of valid items will prevent us looking at data that
are out of date

Fixes https://gitlab.com/kicad/code/kicad/issues/14265

(cherry picked from commit 283770fc45)
2023-03-13 16:11:27 -07:00
jean-pierre charras 7b4dd2f7f5 DIALOG_BOARD_REANNOTATE: ensure indexes are not out of bound. 2023-03-13 20:25:54 +01:00
Seth Hillbrand cc6b01cf88 Force initialization of board units
Unitialized variables are the devil's playground

(cherry picked from commit f0892598a4)
2023-03-13 12:15:51 -07:00
Seth Hillbrand 3568ff72bf Avoid drawing null-arcs in 3d viewer
An arc with no radius or no angle is not visible and should be avoided

Fixes https://gitlab.com/kicad/code/kicad/issues/14271

(cherry picked from commit 72ebe5a429)
2023-03-13 11:48:24 -07:00
Jeff Young e20614660b Fix qa gold value.
(cherry picked from commit 6eb73133f0)
2023-03-12 21:06:28 +00:00
Jeff Young c5a69f073c Added PSPICE/LTSPICE JFET model parameters.
Fixes https://gitlab.com/kicad/code/kicad/issues/12425

(cherry picked from commit 3bc5e3dd8a)
2023-03-12 21:05:06 +00:00
Jeff Young 3025671b1a Add missing command to SPICE directives list.
Fixes https://gitlab.com/kicad/code/kicad/issues/14215

(cherry picked from commit 6d29088668)
2023-03-12 21:04:50 +00:00
Jeff Young 74da0043b4 Move automatic dimension processing inside PCB_DIMENSION_BASE.
Also move dimension precision to an enum so it can get a proper dropdown
in the properties inspector.

(cherry picked from commit 461def2719)
2023-03-12 21:04:09 +00:00
Jeff Young c0ddca12df Add Property Inspector support for dimension objects.
Includes changing the class hierarchy so that dimension objects inherit
from PCB_TEXT rather than containing a PCB_TEXT member variable.

(cherry picked from commit 23accffc6d)
2023-03-12 21:03:58 +00:00
Jeff Young bf55e610b9 Handle plotting of text on solder mask layer.
Admittedly this is an odd thing to do, but we should still be internally
consistent, and it has come up in customers' files.

Fixes https://gitlab.com/kicad/code/kicad/issues/14226
2023-03-12 21:00:19 +00:00
Mark Roszko 4e775a4090 Move vcpkg forwards for newer curl and python 3.9.16 2023-03-12 02:18:35 +00:00
Jon Evans 9f7b31b5c5 Do not try to process invalid ratsnest nodes
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14254


(cherry picked from commit 8eaa3cfac9)
2023-03-11 21:12:33 +00:00
Simon Richter 279641df73 Avoid "suggest parentheses around assignment used as truth value" 2023-03-10 23:09:41 +01:00
Wayne Stambaugh 9e1fd16329 Coverity fixes and code cleaning.
(cherry picked from commit 4e99812145)
2023-03-10 11:21:19 -05:00
Wayne Stambaugh d6ff5f0239 Begin 7.0.2 development. 2023-03-09 17:03:32 -05:00
293 changed files with 19618 additions and 9680 deletions
+1 -2
View File
@@ -342,8 +342,7 @@ private:
OBJECT_2D* createPadWithDrill( const PAD* aPad, int aInflateValue );
void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper, bool aSkipPlatedPads,
bool aSkipNonPlatedPads );
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads );
void addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId );
@@ -145,7 +145,7 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine
void BOARD_ADAPTER::addShape( const PCB_DIMENSION_BASE* aDimension, CONTAINER_2D_BASE* aContainer,
const BOARD_ITEM* aOwner )
{
addText( &aDimension->Text(), aContainer, aDimension );
addText( aDimension, aContainer, aDimension );
const int linewidth = aDimension->GetLineThickness();
@@ -275,6 +275,10 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
int arcsegcount = GetArcToSegmentCount( radius, ARC_HIGH_DEF, arc_angle );
int circlesegcount;
// Avoid arcs that cannot be drawn
if( radius < std::numeric_limits<double>::min() || arc_angle.IsZero() )
break;
// We need a circle to segment count. However, the arc angle can be small, and the
// radius very big. so we calculate a reasonable value for circlesegcount.
if( arcsegcount <= 1 ) // The arc will be approximated by a segment
@@ -488,41 +492,24 @@ OBJECT_2D* BOARD_ADAPTER::createPadWithDrill( const PAD* aPad, int aInflateValue
void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aContainer,
PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper,
bool aSkipPlatedPads, bool aSkipNonPlatedPads )
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads )
{
for( PAD* pad : aFootprint->Pads() )
{
if( !pad->IsOnLayer( aLayerId ) )
continue;
// Skip pad annulus when not connected on this layer (if removing is enabled)
if( !pad->FlashLayer( aLayerId ) && IsCopperLayer( aLayerId ) )
continue;
// NPTH pads are not drawn on layers if the shape size and pos is the same as their hole:
if( aSkipNPTHPadsWihNoCopper && ( pad->GetAttribute() == PAD_ATTRIB::NPTH ) )
if( IsCopperLayer( aLayerId ) )
{
if( pad->GetDrillSize() == pad->GetSize() && pad->GetOffset() == wxPoint( 0, 0 ) )
{
switch( pad->GetShape() )
{
case PAD_SHAPE::CIRCLE:
if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
continue;
// Skip pad annulus when there isn't one (note: this is more discerning than
// pad->IsOnLayer(), which doesn't check for NPTH pads with holes that consume
// the entire pad).
if( !pad->IsOnCopperLayer() )
continue;
break;
case PAD_SHAPE::OVAL:
if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
continue;
break;
default:
break;
}
}
// Skip pad annulus when not connected on this layer (if removing is enabled)
if( !pad->FlashLayer( aLayerId ) )
continue;
}
VECTOR2I margin( 0, 0 );
+4 -6
View File
@@ -525,9 +525,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
// ADD PADS
for( FOOTPRINT* footprint : m_board->Footprints() )
{
// Note: NPTH pads are not drawn on copper layers when the pad has the same shape
// as its hole
addPads( footprint, layerContainer, layer, true, renderPlatedPadsAsPlated, false );
addPads( footprint, layerContainer, layer, renderPlatedPadsAsPlated, false );
// Micro-wave footprints may have items on copper layers
addFootprintShapes( footprint, layerContainer, layer );
@@ -539,8 +537,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
// ADD PLATED PADS
for( FOOTPRINT* footprint : m_board->Footprints() )
{
addPads( footprint, m_platedPadsFront, F_Cu, true, false, true );
addPads( footprint, m_platedPadsBack, B_Cu, true, false, true );
addPads( footprint, m_platedPadsFront, F_Cu, false, true );
addPads( footprint, m_platedPadsBack, B_Cu, false, true );
}
m_platedPadsFront->BuildBVH();
@@ -995,7 +993,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
}
else
{
addPads( footprint, layerContainer, layer, false, false, false );
addPads( footprint, layerContainer, layer, false, false );
}
addFootprintShapes( footprint, layerContainer, layer );
@@ -912,7 +912,8 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
if( !m_boardAdapter.GetBoard() )
return;
if( !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
if( !m_boardAdapter.m_IsPreviewer
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_insert
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_virtual )
{
@@ -1202,7 +1202,8 @@ void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMa
if( !m_boardAdapter.GetBoard() )
return;
if( !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
if( !m_boardAdapter.m_IsPreviewer
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_insert
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_virtual )
{
+1 -1
View File
@@ -37,7 +37,7 @@
# KiCad.
#
# Note: This version string should follow the semantic versioning system
set( KICAD_SEMANTIC_VERSION "7.0.1" )
set( KICAD_SEMANTIC_VERSION "7.0.2" )
# Default the version to the semantic version.
# This is overridden by the git repository tag though (if using git)
+12 -4
View File
@@ -177,12 +177,20 @@ wxString GetVersionInfoData( const wxString& aTitle, bool aHtml, bool aBrief )
aMsg << eol;
aMsg << "Platform: "
wxString osDescription;
#if __LINUX__
<< wxGetLinuxDistributionInfo().Description << ", "
#else
<< wxGetOsDescription() << ", "
osDescription = wxGetLinuxDistributionInfo().Description;
#endif
// Linux uses the lsb-release program to get the description of the OS, if lsb-release
// isn't installed, then the string will be empty and we fallback to the method used on
// the other platforms (to at least get the kernel/uname info).
if( osDescription.empty() )
osDescription = wxGetOsDescription();
aMsg << "Platform: "
<< osDescription << ", "
<< GetPlatformGetBitnessName() << ", "
<< platform.GetEndiannessName() << ", "
<< platform.GetPortIdName();
+4 -21
View File
@@ -31,30 +31,13 @@
#include <dialogs/html_message_box.h>
#include <functional>
#include <unordered_map>
#include <pgm_base.h>
#include "cli/cli_names.h"
// Set of dialogs that have been chosen not to be shown again
static std::unordered_map<unsigned long, int> doNotShowAgainDlgs;
bool IsGUI()
{
if( !wxTheApp )
return false;
#if wxCHECK_VERSION( 3, 1, 6 )
return wxTheApp->IsGUI();
#else
// wxWidgets older than version 3.1.6 do not have a way to know if the app
// has a GUI or is a console application.
// So the trick is to set the App class name when starting kicad-cli, and when
// the app class name is the kicad-cli class name the app is a console app
bool run_gui = wxTheApp->GetClassName() != KICAD_CLI_APP_NAME;
return run_gui;
#endif
}
KIDIALOG::KIDIALOG( wxWindow* aParent, const wxString& aMessage, const wxString& aCaption,
long aStyle )
: wxRichMessageDialog( aParent, aMessage, aCaption, aStyle | wxCENTRE | wxSTAY_ON_TOP ),
@@ -305,7 +288,7 @@ void DisplayError( wxWindow* aParent, const wxString& aText, int aDisplayTime )
return;
}
if( !IsGUI() )
if( !Pgm().IsGUI() )
{
wxFprintf( stderr, aText );
return;
@@ -330,7 +313,7 @@ void DisplayErrorMessage( wxWindow* aParent, const wxString& aText, const wxStri
return;
}
if( !IsGUI() )
if( !Pgm().IsGUI() )
{
wxFprintf( stderr, aText );
return;
@@ -357,7 +340,7 @@ void DisplayInfoMessage( wxWindow* aParent, const wxString& aMessage, const wxSt
return;
}
if( !IsGUI() )
if( !Pgm().IsGUI() )
{
wxFprintf( stdout, "%s %s", aMessage, aExtraInfo );
return;
+52
View File
@@ -659,6 +659,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
wxEmptyString,
wxEmptyString,
wxS( "Greek (el_GR)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxS( "aris-kimi" ),
wxEmptyString,
wxEmptyString,
wxS( "Greek (el_GR)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Adolfo Jayme Barrientos" ),
wxEmptyString,
@@ -688,6 +692,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
wxEmptyString,
wxEmptyString,
wxS( "Spanish (ES)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "VicSanRoPe" ),
wxEmptyString,
wxEmptyString,
wxS( "Spanish - Latin American (ES)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Ulices Avila Hernandez" ),
wxEmptyString,
@@ -822,14 +830,46 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
wxEmptyString,
wxEmptyString,
wxS( "Korean (KO)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "김낙환" ),
wxEmptyString,
wxEmptyString,
wxS( "Korean (KO)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "이기형" ),
wxEmptyString,
wxEmptyString,
wxS( "Korean (KO)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "남우근" ),
wxEmptyString,
wxEmptyString,
wxS( "Korean (KO)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "강명구" ),
wxEmptyString,
wxEmptyString,
wxS( "Korean (KO)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "김용재" ),
wxEmptyString,
wxEmptyString,
wxS( "Korean (KO)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "서범기" ),
wxEmptyString,
wxEmptyString,
wxS( "Korean (KO)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "김세영" ),
wxEmptyString,
wxEmptyString,
wxS( "Korean (KO)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "이윤성" ),
wxEmptyString,
wxEmptyString,
wxS( "Korean (KO)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "KwonHyeokbeom" ),
wxEmptyString,
wxEmptyString,
wxS( "Korean (KO)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Minsu Kim (0xGabriel)" ),
wxEmptyString,
wxEmptyString,
wxS( "Korean (KO)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Henrik Kauhanen" ),
wxEmptyString,
@@ -860,6 +900,14 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
wxEmptyString,
wxEmptyString,
wxS( "Dutch (NL)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Tom Niesse" ),
wxEmptyString,
wxEmptyString,
wxS( "Dutch (NL)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Christiaan Nieuwlaat" ),
wxEmptyString,
wxEmptyString,
wxS( "Dutch (NL)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Jarl Gjessing" ),
wxEmptyString,
@@ -932,6 +980,10 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
wxEmptyString,
wxEmptyString,
wxS( "Portuguese (PT)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "ssantos" ),
wxEmptyString,
wxEmptyString,
wxS( "Portuguese (PT)" ) ) );
aInfo.AddTranslator( new CONTRIBUTOR( wxT( "Igor Plyatov" ),
wxEmptyString,
+4 -4
View File
@@ -223,7 +223,7 @@ bool DIALOG_PAGES_SETTINGS::TransferDataFromWindow()
m_screen->SetContentModified();
if( LocalPrjConfigChanged() )
m_parent->SaveProjectSettings();
m_parent->OnModify();
// Call the post processing (if any) after changes
m_parent->OnPageSettingsChange();
@@ -674,9 +674,9 @@ void DIALOG_PAGES_SETTINGS::UpdateDrawingSheetExample()
GRFilledRect( &memDC, VECTOR2I( 0, 0 ), m_layout_size, 0, bgColor, bgColor );
PrintDrawingSheet( &renderSettings, pageDUMMY, emptyString, emptyString, m_tb,
nullptr, m_screen->GetPageCount(), m_screen->GetPageNumber(), 1,
&Prj(), wxEmptyString, m_screen->GetVirtualPageNumber() == 1 );
PrintDrawingSheet( &renderSettings, pageDUMMY, emptyString, emptyString, emptyString,
m_tb, nullptr, m_screen->GetPageCount(), m_screen->GetPageNumber(),
1, &Prj(), wxEmptyString, m_screen->GetVirtualPageNumber() == 1 );
memDC.SelectObject( wxNullBitmap );
m_PageLayoutExampleBitmap->SetBitmap( *m_pageBitmap );
+15 -6
View File
@@ -117,8 +117,7 @@ void PANEL_COLOR_SETTINGS::OnThemeChanged( wxCommandEvent& event )
if( idx == static_cast<int>( m_cbTheme->GetCount() ) - 2 )
{
// separator; re-select active theme
m_cbTheme->SetStringSelection( m_currentSettings->GetName() );
m_cbTheme->SetStringSelection( GetSettingsDropdownName( m_currentSettings ) );
return;
}
@@ -217,10 +216,7 @@ void PANEL_COLOR_SETTINGS::createThemeList( const wxString& aCurrent )
for( COLOR_SETTINGS* settings : Pgm().GetSettingsManager().GetColorSettingsList() )
{
wxString name = settings->GetName();
if( settings->IsReadOnly() )
name += wxS( " " ) + _( "(read-only)" );
wxString name = GetSettingsDropdownName( settings );
int pos = m_cbTheme->Append( name, static_cast<void*>( settings ) );
@@ -286,6 +282,8 @@ void PANEL_COLOR_SETTINGS::ShowColorContextMenu( wxMouseEvent& aEvent, int aLaye
auto selected =
static_cast<COLOR_SETTINGS*>( m_cbTheme->GetClientData( m_cbTheme->GetSelection() ) );
wxCHECK_RET( selected, wxT( "Invalid color theme selected" ) );
COLOR4D current = m_currentSettings->GetColor( aLayer );
COLOR4D saved = selected->GetColor( aLayer );
bool readOnly = m_currentSettings->IsReadOnly();
@@ -379,3 +377,14 @@ bool PANEL_COLOR_SETTINGS::saveCurrentTheme( bool aValidate )
return true;
}
wxString PANEL_COLOR_SETTINGS::GetSettingsDropdownName(COLOR_SETTINGS* aSettings)
{
wxString name = aSettings->GetName();
if( aSettings->IsReadOnly() )
name += wxS( " " ) + _( "(read-only)" );
return name;
}
+13 -6
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2018 jean-pierre.charras
* Copyright (C) 2011-2020 Kicad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2011-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
@@ -110,12 +110,19 @@ bool PANEL_IMAGE_EDITOR::TransferDataFromWindow()
void PANEL_IMAGE_EDITOR::OnRedrawPanel( wxPaintEvent& event )
{
wxPaintDC dc( m_panelDraw );
wxSize size = m_panelDraw->GetClientSize();
dc.SetDeviceOrigin( size.x / 2, size.y / 2 );
wxSize display_size = m_panelDraw->GetClientSize();
double scale = 1.0 / m_workingImage->GetScalingFactor();
dc.SetUserScale( scale, scale );
m_workingImage->DrawBitmap( &dc, wxPoint( 0, 0 ) );
double img_scale = 1.0 / m_workingImage->GetScalingFactor();
VECTOR2I img_size_pixels = m_workingImage->GetSizePixels();
// Adjust the display scale to use the full available display area
double scale_X = (double)display_size.x/img_size_pixels.x;
double scale_Y = (double)display_size.y/img_size_pixels.y;
double display_scale = img_scale * std::min( scale_X, scale_Y );
dc.SetUserScale( display_scale, display_scale );
m_workingImage->DrawBitmap( &dc, VECTOR2I( m_workingImage->GetSize()/2 ) );
}
+1 -1
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-133-g388db8e4)
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
+368
View File
@@ -0,0 +1,368 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="16" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">panel_image_editor_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">panel_image_editor_base</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Panel" expanded="1">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">PANEL_IMAGE_EDITOR_BASE</property>
<property name="pos"></property>
<property name="size">500,300</property>
<property name="subclass">; ; forward_declare</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">wxTAB_TRAVERSAL</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerMain</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bUpperSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerLeft</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND | wxALL</property>
<property name="proportion">1</property>
<object class="wxPanel" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">256,256</property>
<property name="moveable">1</property>
<property name="name">m_panelDraw</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL|wxBORDER_SIMPLE</property>
<event name="OnPaint">OnRedrawPanel</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerRight</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Grey</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_buttonGrey</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnGreyScaleConvert</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">10</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
<property name="proportion">0</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Image Scale:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticTextScale</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="maxlength">0</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_textCtrlScale</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>
+1 -1
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-133-g388db8e4)
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
+1 -1
View File
@@ -626,7 +626,7 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
void EDA_DRAW_PANEL_GAL::onShowTimer( wxTimerEvent& aEvent )
{
if( m_gal && m_gal->IsVisible() )
if( m_gal && m_gal->IsInitialized() && m_gal->IsVisible() )
{
m_onShowTimer.Stop();
OnShow();
+5 -1
View File
@@ -219,6 +219,10 @@ void EDA_BASE_FRAME::windowClosing( wxCloseEvent& event )
if( canCloseWindow( event ) )
{
m_isClosing = true;
if( m_infoBar )
m_infoBar->Dismiss();
APP_SETTINGS_BASE* cfg = config();
if( cfg )
@@ -1230,7 +1234,7 @@ bool EDA_BASE_FRAME::IsWritable( const wxFileName& aFileName, bool aVerbose )
void EDA_BASE_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
{
if( !IsGUI() )
if( !Pgm().IsGUI() )
return;
wxCHECK_RET( aFileName.IsOk(), wxT( "Invalid file name!" ) );
+18 -9
View File
@@ -289,7 +289,7 @@ void EDA_DRAW_FRAME::ToggleUserUnits()
else
{
SetUserUnits( GetUserUnits() == EDA_UNITS::INCHES ? EDA_UNITS::MILLIMETRES
: EDA_UNITS::INCHES );
: EDA_UNITS::INCHES );
unitsChangeRefresh();
wxCommandEvent e( UNITS_CHANGED );
@@ -613,8 +613,8 @@ void EDA_DRAW_FRAME::DisplayGridMsg()
{
wxString msg;
msg.Printf( wxS( "grid %s" ), MessageTextFromValue( GetCanvas()->GetGAL()->GetGridSize().x,
false ) );
msg.Printf( _( "grid %s" ), MessageTextFromValue( GetCanvas()->GetGAL()->GetGridSize().x,
false ) );
SetStatusText( msg, 4 );
}
@@ -990,8 +990,8 @@ static const wxString productName = wxT( "KiCad E.D.A. " );
void PrintDrawingSheet( const RENDER_SETTINGS* aSettings, const PAGE_INFO& aPageInfo,
const wxString& aFullSheetName, const wxString& aFileName,
const TITLE_BLOCK& aTitleBlock,
const wxString& aSheetName, const wxString& aSheetPath,
const wxString& aFileName, const TITLE_BLOCK& aTitleBlock,
const std::map<wxString, wxString>* aProperties, int aSheetCount,
const wxString& aPageNumber, double aMils2Iu, const PROJECT* aProject,
const wxString& aSheetLayer, bool aIsFirstPage )
@@ -1003,7 +1003,8 @@ void PrintDrawingSheet( const RENDER_SETTINGS* aSettings, const PAGE_INFO& aPage
drawList.SetPageNumber( aPageNumber );
drawList.SetSheetCount( aSheetCount );
drawList.SetFileName( aFileName );
drawList.SetSheetName( aFullSheetName );
drawList.SetSheetName( aSheetName );
drawList.SetSheetPath( aSheetPath );
drawList.SetSheetLayer( aSheetLayer );
drawList.SetProject( aProject );
drawList.SetIsFirstPage( aIsFirstPage );
@@ -1033,9 +1034,10 @@ void EDA_DRAW_FRAME::PrintDrawingSheet( const RENDER_SETTINGS* aSettings, BASE_S
DC->SetAxisOrientation( true, false );
}
::PrintDrawingSheet( aSettings, GetPageSettings(), GetScreenDesc(), aFilename, GetTitleBlock(),
aProperties, aScreen->GetPageCount(), aScreen->GetPageNumber(), aMils2Iu,
&Prj(), aSheetLayer, aScreen->GetVirtualPageNumber() == 1 );
::PrintDrawingSheet( aSettings, GetPageSettings(), GetScreenDesc(), GetFullScreenDesc(),
aFilename, GetTitleBlock(), aProperties, aScreen->GetPageCount(),
aScreen->GetPageNumber(), aMils2Iu, &Prj(), aSheetLayer,
aScreen->GetVirtualPageNumber() == 1 );
if( origin.y > 0 )
{
@@ -1052,6 +1054,13 @@ wxString EDA_DRAW_FRAME::GetScreenDesc() const
}
wxString EDA_DRAW_FRAME::GetFullScreenDesc() const
{
// Virtual function. Base class implementation returns an empty string.
return wxEmptyString;
}
bool EDA_DRAW_FRAME::LibraryFileBrowser( bool doOpen, wxFileName& aFilename,
const wxString& wildcard, const wxString& ext,
bool isDirectory, bool aIsGlobal,
+1 -1
View File
@@ -394,7 +394,7 @@ static struct EDA_ITEM_DESC
propMgr.AddProperty( new PROPERTY_ENUM<EDA_ITEM, KICAD_T>( wxS( "Type" ),
NO_SETTER( EDA_ITEM, KICAD_T ), &EDA_ITEM::Type ) )
.SetIsInternal();
.SetIsHiddenFromPropertiesManager();
}
} _EDA_ITEM_DESC;
+11 -1
View File
@@ -1736,7 +1736,17 @@ static struct EDA_SHAPE_DESC
filled->SetAvailableFunc(
[=]( INSPECTABLE* aItem ) -> bool
{
SHAPE_T itemShape = aItem->Get<SHAPE_T>( shape );
SHAPE_T itemShape;
try
{
itemShape = aItem->Get<SHAPE_T>( shape );
}
catch( std::runtime_error& err )
{
wxFAIL_MSG( err.what() );
return false;
}
switch( itemShape )
{
+1 -1
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2004-2022 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2004-2023 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
+7 -3
View File
@@ -152,7 +152,7 @@ std::string FONTCONFIG::getFamilyStringByLang( FONTCONFIG_PAT& aPat, const wxStr
FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString &aFontFile,
bool aBold, bool aItalic )
int& aFaceIndex, bool aBold, bool aItalic )
{
FF_RESULT retval = FF_RESULT::FF_ERROR;
wxString qualifiedFontName = aFontName;
@@ -184,6 +184,8 @@ FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString
if( FcPatternGetString( font, FC_FILE, 0, &file ) == FcResultMatch )
{
aFontFile = wxString::FromUTF8( (char*) file );
aFaceIndex = 0;
wxString styleStr;
FcChar8* family = nullptr;
FcChar8* style = nullptr;
@@ -192,9 +194,13 @@ FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString
std::unordered_map<std::string, std::string> famStrings;
FONTCONFIG_PAT patHolder{ font };
getAllFamilyStrings( patHolder, famStrings );
if( FcPatternGetString( font, FC_FAMILY, 0, &family ) == FcResultMatch )
{
FcPatternGetInteger( font, FC_INDEX, 0, &aFaceIndex );
fontName = wxString::FromUTF8( (char*) family );
if( FcPatternGetString( font, FC_STYLE, 0, &style ) == FcResultMatch )
@@ -248,8 +254,6 @@ FONTCONFIG::FF_RESULT FONTCONFIG::FindFont( const wxString &aFontName, wxString
break;
}
}
}
}
+5 -4
View File
@@ -98,9 +98,10 @@ OUTLINE_FONT* OUTLINE_FONT::LoadFont( const wxString& aFontName, bool aBold, boo
std::unique_ptr<OUTLINE_FONT> font = std::make_unique<OUTLINE_FONT>();
wxString fontFile;
int faceIndex;
using fc = fontconfig::FONTCONFIG;
fc::FF_RESULT retval = Fontconfig()->FindFont( aFontName, fontFile, aBold, aItalic );
fc::FF_RESULT retval = Fontconfig()->FindFont( aFontName, fontFile, faceIndex, aBold, aItalic );
if( retval == fc::FF_RESULT::FF_ERROR )
return nullptr;
@@ -111,7 +112,7 @@ OUTLINE_FONT* OUTLINE_FONT::LoadFont( const wxString& aFontName, bool aBold, boo
if( retval == fc::FF_RESULT::FF_MISSING_ITAL || retval == fc::FF_RESULT::FF_MISSING_BOLD_ITAL )
font->SetFakeItal();
if( font->loadFace( fontFile ) != 0 )
if( font->loadFace( fontFile, faceIndex ) != 0 )
return nullptr;
font->m_fontName = aFontName; // Keep asked-for name, even if we substituted.
@@ -121,13 +122,13 @@ OUTLINE_FONT* OUTLINE_FONT::LoadFont( const wxString& aFontName, bool aBold, boo
}
FT_Error OUTLINE_FONT::loadFace( const wxString& aFontFileName )
FT_Error OUTLINE_FONT::loadFace( const wxString& aFontFileName, int aFaceIndex )
{
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
// TODO: check that going from wxString to char* with UTF-8
// conversion for filename makes sense on any/all platforms
FT_Error e = FT_New_Face( m_freeType, aFontFileName.mb_str( wxConvUTF8 ), 0, &m_face );
FT_Error e = FT_New_Face( m_freeType, aFontFileName.mb_str( wxConvUTF8 ), aFaceIndex, &m_face );
if( !e )
{
+3 -12
View File
@@ -169,14 +169,6 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap )
bmp.w = imgData.GetSize().x;
bmp.h = imgData.GetSize().y;
// The bitmap size needs to be a multiple of 4.
// This is easiest to achieve by ensuring that each row
// has a multiple of 4 pixels
int extra_w = bmp.w % 4;
if( extra_w )
extra_w = 4 - extra_w;
GLuint textureID;
if( m_freedTextureIds.empty() )
@@ -189,15 +181,14 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap )
m_freedTextureIds.pop_front();
}
// make_unique initializes this to 0, so extra pixels are transparent
bmp.size = ( bmp.w + extra_w ) * bmp.h * 4;
bmp.size = bmp.w * bmp.h * 4;
auto buf = std::make_unique<uint8_t[]>( bmp.size );
for( int y = 0; y < bmp.h; y++ )
{
for( int x = 0; x < bmp.w; x++ )
{
uint8_t* p = buf.get() + ( ( bmp.w + extra_w ) * y + x ) * 4;
uint8_t* p = buf.get() + ( bmp.w * y + x ) * 4;
p[0] = imgData.GetRed( x, y );
p[1] = imgData.GetGreen( x, y );
@@ -214,7 +205,7 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap )
}
glBindTexture( GL_TEXTURE_2D, textureID );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, bmp.w + extra_w, bmp.h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, bmp.w, bmp.h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
buf.get() );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+7 -2
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-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
@@ -100,12 +100,13 @@ static int xferinfo( void* aProgress, curl_off_t aDLtotal, curl_off_t aDLnow, cu
return CURLE_OK;
}
#if LIBCURL_VERSION_NUM < 0x072000 // 7.32.0
static int progressinfo( void* aProgress, double aDLtotal, double aDLnow, double aULtotal, double aULnow )
{
return xferinfo( aProgress, static_cast<curl_off_t>( aDLtotal ), static_cast<curl_off_t>( aDLnow ),
static_cast<curl_off_t>( aULtotal ), static_cast<curl_off_t>( aULnow ) );
}
#endif
KICAD_CURL_EASY::KICAD_CURL_EASY() :
@@ -126,7 +127,11 @@ KICAD_CURL_EASY::KICAD_CURL_EASY() :
curl_easy_setopt( m_CURL, CURLOPT_WRITEDATA, static_cast<void*>( &m_buffer ) );
// Only allow HTTP and HTTPS protocols
#if LIBCURL_VERSION_NUM >= 0x075500 // version 7.85.0
curl_easy_setopt(m_CURL, CURLOPT_PROTOCOLS_STR, "http,https");
#else
curl_easy_setopt( m_CURL, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS );
#endif
#ifdef _WIN32
// We need this to use the Windows Certificate store
+6 -4
View File
@@ -431,15 +431,17 @@ KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, wxTopLevelWindow
}
catch( const IO_ERROR& ioe )
{
DisplayErrorMessage( nullptr, _( "Error loading editor." ), ioe.What() );
wxLogError( ioe.What() );
wxLogError( _( "Error loading editor." ) );
}
catch( const std::exception& e)
catch( const std::exception& e )
{
DisplayErrorMessage( nullptr, _( "Error loading editor." ), e.what() );
wxLogError( e.what() );
wxLogError( _( "Error loading editor." ) );
}
catch( ... )
{
DisplayErrorMessage( nullptr, _( "Error loading editor." ) );
wxLogError( _( "Error loading editor." ) );
}
}
+16 -5
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-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 as published by the
@@ -24,12 +24,16 @@ LIB_TABLE_GRID_TRICKS::LIB_TABLE_GRID_TRICKS( WX_GRID* aGrid ) : GRID_TRICKS( aG
{
}
void LIB_TABLE_GRID_TRICKS::showPopupMenu( wxMenu& menu )
{
bool showActivate = false;
bool showDeactivate = false;
LIB_TABLE_GRID* tbl = static_cast<LIB_TABLE_GRID*>( m_grid->GetTable() );
// Ensure selection parameters are up to date
getSelectedArea();
for( int row = m_sel_row_start; row < m_sel_row_start + m_sel_row_count; ++row )
{
if( tbl->GetValueAsBool( row, 0 ) )
@@ -49,10 +53,14 @@ void LIB_TABLE_GRID_TRICKS::showPopupMenu( wxMenu& menu )
menu.Append( LIB_TABLE_GRID_TRICKS_ACTIVATE_SELECTED, _( "Activate selected" ) );
if( showDeactivate )
menu.Append( LIB_TABLE_GRID_TRICKS_DEACTIVATE_SELECTED, _( "Deactivate selected" ) );
menu.AppendSeparator();
if( showActivate || showDeactivate )
menu.AppendSeparator();
GRID_TRICKS::showPopupMenu( menu );
}
void LIB_TABLE_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
{
int menu_id = event.GetId();
@@ -61,10 +69,13 @@ void LIB_TABLE_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
{
LIB_TABLE_GRID* tbl = (LIB_TABLE_GRID*) m_grid->GetTable();
bool selected_state = menu_id == LIB_TABLE_GRID_TRICKS_ACTIVATE_SELECTED;
for( int row = m_sel_row_start; row < m_sel_row_start + m_sel_row_count; ++row )
{
tbl->SetValueAsBool( row, 0, menu_id == LIB_TABLE_GRID_TRICKS_ACTIVATE_SELECTED );
}
tbl->SetValueAsBool( row, 0, selected_state );
// Ensure the new state (on/off) of the widgets is immediately shown:
m_grid->Refresh();
}
else
{
+1 -1
View File
@@ -269,7 +269,7 @@ void LIB_TREE_MODEL_ADAPTER::recreateColumns()
for( const wxString& colName : m_shownColumns )
{
if( !m_colNameMap.count( colName ) )
doAddColumn( colName, false );
doAddColumn( colName, colName == wxT( "Description" ) );
}
}
+3 -2
View File
@@ -2,7 +2,7 @@
* This file is part of libeval, a simple math expression evaluator
*
* Copyright (C) 2017 Michael Geselbracht, mgeselbracht3@gmail.com
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-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 as published by
@@ -356,10 +356,11 @@ void COMPILER::newString( const wxString& aString )
m_parseFinished = false;
}
T_TOKEN COMPILER::getToken()
{
T_TOKEN rv;
rv.value.str = nullptr;
rv.value = defaultTokenValue;
bool done = false;
+18
View File
@@ -857,3 +857,21 @@ ENV_VAR_MAP& PGM_BASE::GetLocalEnvVariables() const
{
return GetCommonSettings()->m_Env.vars;
}
bool PGM_BASE::IsGUI()
{
if( !wxTheApp )
return false;
#if wxCHECK_VERSION( 3, 1, 6 )
return wxTheApp->IsGUI();
#else
// wxWidgets older than version 3.1.6 do not have a way to know if the app
// has a GUI or is a console application.
// So the trick is to set the App class name when starting kicad-cli, and when
// the app class name is the kicad-cli class name the app is a console app
bool run_gui = wxTheApp->GetClassName() != KICAD_CLI_APP_NAME;
return run_gui;
#endif
}
+13 -7
View File
@@ -848,11 +848,16 @@ void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion )
LineTo( start );
VECTOR2D devEnd = userToDeviceCoordinates( end );
VECTOR2D devCenter = userToDeviceCoordinates( center - start );
// devRelCenter is the position on arc center relative to the arc start, in Gerber coord.
// Warning: it is **not** userToDeviceCoordinates( center - start ) when the plotter
// has an offset.
VECTOR2D devRelCenter = userToDeviceCoordinates( center ) - userToDeviceCoordinates( start );
// We need to know if the arc is CW or CCW in device coordinates, so build this arc.
SHAPE_ARC deviceArc( userToDeviceCoordinates( start ),
userToDeviceCoordinates( aArc.GetArcMid() ), devEnd, 0 );
userToDeviceCoordinates( aArc.GetArcMid() ),
devEnd, 0 );
fprintf( m_outputFile, "G75*\n" ); // Multiquadrant (360 degrees) mode
@@ -863,7 +868,7 @@ void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion )
fprintf( m_outputFile, "X%dY%dI%dJ%dD01*\n",
KiROUND( devEnd.x ), KiROUND( devEnd.y ),
KiROUND( devCenter.x ), KiROUND( devCenter.y ) );
KiROUND( devRelCenter.x ), KiROUND( devRelCenter.y ) );
fprintf( m_outputFile, "G01*\n" ); // Back to linear interpolate (perhaps useless here).
}
@@ -884,7 +889,8 @@ void GERBER_PLOTTER::plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAn
end.x = aCenter.x + KiROUND( aRadius * aEndAngle.Cos() );
end.y = aCenter.y - KiROUND( aRadius * aEndAngle.Sin() );
VECTOR2D devEnd = userToDeviceCoordinates( end );
VECTOR2D devCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start );
// devRelCenter is the position on arc center relative to the arc start, in Gerber coord.
VECTOR2D devRelCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start );
fprintf( m_outputFile, "G75*\n" ); // Multiquadrant (360 degrees) mode
@@ -895,7 +901,7 @@ void GERBER_PLOTTER::plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAn
fprintf( m_outputFile, "X%dY%dI%dJ%dD01*\n",
KiROUND( devEnd.x ), KiROUND( devEnd.y ),
KiROUND( devCenter.x ), KiROUND( devCenter.y ) );
KiROUND( devRelCenter.x ), KiROUND( devRelCenter.y ) );
fprintf( m_outputFile, "G01*\n" ); // Back to linear interpolate (perhaps useless here).
}
@@ -1020,7 +1026,7 @@ void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, int
{
const SHAPE_ARC& arc = aPoly.Arc( arcindex );
plotArc( arc, ii > 0 );
plotArc( arc, true );
// skip points on arcs, since we plot the arc itself
while( ii+1 < aPoly.PointCount() && arcindex == aPoly.ArcIndex( ii+1 ) )
@@ -1054,7 +1060,7 @@ void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, int
{
const SHAPE_ARC& arc = aPoly.Arc( arcindex );
plotArc( arc, ii > 0 );
plotArc( arc, true );
// skip points on arcs, since we plot the arc itself
while( ii+1 < aPoly.PointCount() && arcindex == aPoly.ArcIndex( ii+1 ) )
-1
View File
@@ -47,7 +47,6 @@ struct EPART;
struct ETEXT;
typedef std::unordered_map<wxString, wxXmlNode*> NODE_MAP;
typedef std::map<wxString, FOOTPRINT*> FOOTPRINT_MAP;
typedef std::map<wxString, EINSTANCE*> EINSTANCE_MAP;
typedef std::map<wxString, std::unique_ptr<EPART>> EPART_MAP;
+2 -2
View File
@@ -633,12 +633,12 @@ bool SETTINGS_MANAGER::GetPreviousVersionPaths( std::vector<wxString>* aPaths )
wxFileName wxGtkPath;
wxGtkPath.AssignDir( wxS( "~/.config/kicad" ) );
wxGtkPath.MakeAbsolute();
base_paths.emplace_back( wxGtkPath.GetPath() );
base_paths.emplace_back( wxGtkPath );
// We also want to pick up regular flatpak if we are nightly
wxGtkPath.AssignDir( wxS( "~/.var/app/org.kicad.KiCad/config/kicad" ) );
wxGtkPath.MakeAbsolute();
base_paths.emplace_back( wxGtkPath.GetPath() );
base_paths.emplace_back( wxGtkPath );
}
#endif
+1 -1
View File
@@ -196,7 +196,7 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
}
else if( aContext == CTX_JS_STR )
{
if( c >= 0x7F || c == '\'' || c == '\\' )
if( c >= 0x7F || c == '\'' || c == '\\' || c == '(' || c == ')' )
{
unsigned int code = c;
char buffer[16];
+3 -1
View File
@@ -113,7 +113,9 @@ int COMMON_CONTROL::ShowLibraryTable( const TOOL_EVENT& aEvent )
try // Sch frame was not available, try to start it
{
KIFACE* kiface = m_frame->Kiway().KiFACE( KIWAY::FACE_SCH );
kiface->CreateKiWindow( m_frame, DIALOG_SCH_LIBRARY_TABLE, &m_frame->Kiway() );
if( kiface )
kiface->CreateKiWindow( m_frame, DIALOG_SCH_LIBRARY_TABLE, &m_frame->Kiway() );
}
catch( ... )
{
+1 -1
View File
@@ -1400,7 +1400,7 @@ void VIEW::RecacheAllItems()
void VIEW::UpdateItems()
{
if( !m_gal->IsVisible() )
if( !m_gal->IsVisible() || !m_gal->IsInitialized() )
return;
unsigned int cntGeomUpdate = 0;
+5
View File
@@ -18,6 +18,7 @@
*/
#include <widgets/font_choice.h>
#include <kiplatform/ui.h>
#include <wx/fontenum.h>
#include <font/fontconfig.h>
#include <pgm_base.h>
@@ -54,7 +55,11 @@ FONT_CHOICE::FONT_CHOICE( wxWindow* aParent, int aId, wxPoint aPosition, wxSize
menuList.Add( wxString( name ) );
menuList.Sort();
Freeze();
Append( menuList );
KIPLATFORM::UI::LargeChoiceBoxHack( this );
Thaw();
m_notFound = wxS( " " ) + _( "<not found>" );
}
+10
View File
@@ -185,6 +185,16 @@ LIB_TREE::~LIB_TREE()
}
void LIB_TREE::ShowChangedLanguage()
{
if( m_query_ctrl )
m_query_ctrl->SetDescriptiveText( _( "Filter" ) );
if( m_adapter )
m_adapter->ShowChangedLanguage();
}
LIB_ID LIB_TREE::GetSelectedLibId( int* aUnit ) const
{
wxDataViewItem sel = m_tree_ctrl->GetSelection();
+42 -33
View File
@@ -61,7 +61,8 @@ double mpWindow::zoomIncrementalFactor = 1.1;
IMPLEMENT_ABSTRACT_CLASS( mpLayer, wxObject )
mpLayer::mpLayer() : m_type( mpLAYER_UNDEF )
mpLayer::mpLayer() :
m_type( mpLAYER_UNDEF )
{
SetPen( (wxPen&) *wxBLACK_PEN );
SetFont( (wxFont&) *wxNORMAL_FONT );
@@ -197,12 +198,14 @@ wxSize mpInfoLayer::GetSize() const
}
mpInfoCoords::mpInfoCoords() : mpInfoLayer()
mpInfoCoords::mpInfoCoords() :
mpInfoLayer()
{
}
mpInfoCoords::mpInfoCoords( wxRect rect, const wxBrush* brush ) : mpInfoLayer( rect, brush )
mpInfoCoords::mpInfoCoords( wxRect rect, const wxBrush* brush ) :
mpInfoLayer( rect, brush )
{
}
@@ -273,12 +276,14 @@ void mpInfoCoords::Plot( wxDC& dc, mpWindow& w )
}
mpInfoLegend::mpInfoLegend() : mpInfoLayer()
mpInfoLegend::mpInfoLegend() :
mpInfoLayer()
{
}
mpInfoLegend::mpInfoLegend( wxRect rect, const wxBrush* brush ) : mpInfoLayer( rect, brush )
mpInfoLegend::mpInfoLegend( wxRect rect, const wxBrush* brush ) :
mpInfoLayer( rect, brush )
{
}
@@ -301,7 +306,7 @@ void mpInfoLegend::Plot( wxDC& dc, mpWindow& w )
int scrx = w.GetScrX();
int scry = w.GetScrY();
if( (m_winX != scrx) || (m_winY != scry) )
if( m_winX != scrx || m_winY != scry )
{
if( m_winX > 1 )
m_dim.x = (int) floor( (double) (m_dim.x * scrx / m_winX) );
@@ -322,26 +327,27 @@ void mpInfoLegend::Plot( wxDC& dc, mpWindow& w )
// wxBrush semiWhite(image1);
dc.SetBrush( m_brush );
dc.SetFont( m_font );
const int baseWidth = (mpLEGEND_MARGIN * 2 + mpLEGEND_LINEWIDTH);
int textX = baseWidth, textY = mpLEGEND_MARGIN;
int plotCount = 0;
int posY = 0;
int tmpX = 0, tmpY = 0;
mpLayer* ly = nullptr;
wxPen lpen;
wxString label;
const int baseWidth = mpLEGEND_MARGIN * 2 + mpLEGEND_LINEWIDTH;
int textX = baseWidth, textY = mpLEGEND_MARGIN;
int plotCount = 0;
int posY = 0;
int tmpX = 0;
int tmpY = 0;
mpLayer* layer = nullptr;
wxPen lpen;
wxString label;
for( unsigned int p = 0; p < w.CountAllLayers(); p++ )
{
ly = w.GetLayer( p );
layer = w.GetLayer( p );
if( (ly->GetLayerType() == mpLAYER_PLOT) && ( ly->IsVisible() ) )
if( layer->GetLayerType() == mpLAYER_PLOT && layer->IsVisible() )
{
label = ly->GetName();
label = layer->GetDisplayName();
dc.GetTextExtent( label, &tmpX, &tmpY );
textX =
( textX > (tmpX + baseWidth) ) ? textX : (tmpX + baseWidth + mpLEGEND_MARGIN);
textY += (tmpY);
textX = ( textX > tmpX + baseWidth ) ? textX : tmpX + baseWidth + mpLEGEND_MARGIN;
textY += tmpY;
}
}
@@ -357,25 +363,25 @@ void mpInfoLegend::Plot( wxDC& dc, mpWindow& w )
for( unsigned int p2 = 0; p2 < w.CountAllLayers(); p2++ )
{
ly = w.GetLayer( p2 );
layer = w.GetLayer( p2 );
if( (ly->GetLayerType() == mpLAYER_PLOT) && ( ly->IsVisible() ) )
if( layer->GetLayerType() == mpLAYER_PLOT && layer->IsVisible() )
{
label = ly->GetName();
lpen = ly->GetPen();
label = layer->GetDisplayName();
lpen = layer->GetPen();
dc.GetTextExtent( label, &tmpX, &tmpY );
dc.SetPen( lpen );
// textX = (textX > (tmpX + baseWidth)) ? textX : (tmpX + baseWidth);
// textY += (tmpY + mpLEGEND_MARGIN);
posY = m_dim.y + mpLEGEND_MARGIN + plotCount * tmpY + (tmpY >> 1);
dc.DrawLine( m_dim.x + mpLEGEND_MARGIN, // X start coord
posY, // Y start coord
m_dim.x + mpLEGEND_LINEWIDTH + mpLEGEND_MARGIN, // X end coord
posY );
dc.DrawLine( m_dim.x + mpLEGEND_MARGIN, // X start coord
posY, // Y start coord
m_dim.x + mpLEGEND_LINEWIDTH + mpLEGEND_MARGIN, // X end coord
posY );
// dc.DrawRectangle(m_dim.x + 5, m_dim.y + 5 + plotCount*tmpY, 5, 5);
dc.DrawText( label,
m_dim.x + baseWidth,
m_dim.y + mpLEGEND_MARGIN + plotCount * tmpY );
m_dim.x + baseWidth,
m_dim.y + mpLEGEND_MARGIN + plotCount * tmpY );
plotCount++;
}
}
@@ -1612,7 +1618,8 @@ EVT_MENU( mpID_ZOOM_OUT, mpWindow::OnZoomOut )
EVT_MENU( mpID_LOCKASPECT, mpWindow::OnLockAspect )
END_EVENT_TABLE()
mpWindow::mpWindow() : wxWindow(),
mpWindow::mpWindow() :
wxWindow(),
m_lockaspect( false ),
m_minX( 0.0 ),
m_maxX( 0.0 ),
@@ -2826,7 +2833,8 @@ void mpWindow::SetColourTheme( const wxColour& bgColour, const wxColour& drawCol
IMPLEMENT_DYNAMIC_CLASS( mpFXYVector, mpFXY )
// Constructor
mpFXYVector::mpFXYVector( const wxString& name, int flags ) : mpFXY( name, flags )
mpFXYVector::mpFXYVector( const wxString& name, int flags ) :
mpFXY( name, flags )
{
m_index = 0;
m_minX = -1;
@@ -3030,7 +3038,8 @@ void mpText::Plot( wxDC& dc, mpWindow& w )
// mpPrintout - provided by Davide Rondini
// -----------------------------------------------------------------------------
mpPrintout::mpPrintout( mpWindow* drawWindow, const wxChar* title ) : wxPrintout( title )
mpPrintout::mpPrintout( mpWindow* drawWindow, const wxChar* title ) :
wxPrintout( title )
{
drawn = false;
plotWindow = drawWindow;
+1 -1
View File
@@ -205,7 +205,7 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
// Find a set of properties that is common to all selected items
for( PROPERTY_BASE* property : commonProps )
{
if( property->IsInternal() )
if( property->IsHiddenFromPropertiesManager() )
continue;
if( propMgr.IsAvailableFor( TYPE_HASH( *firstItem ), property, firstItem ) )
+4 -11
View File
@@ -46,7 +46,6 @@ UNIT_BINDER::UNIT_BINDER( EDA_DRAW_FRAME* aParent, wxStaticText* aLabel, wxWindo
UNIT_BINDER::UNIT_BINDER( UNITS_PROVIDER* aUnitsProvider, wxWindow* aEventSource,
wxStaticText* aLabel, wxWindow* aValueCtrl, wxStaticText* aUnitLabel,
bool aAllowEval, bool aBindFocusEvent ) :
m_eventSource( aEventSource ),
m_bindFocusEvent( aBindFocusEvent ),
m_label( aLabel ),
m_valueCtrl( aValueCtrl ),
@@ -99,10 +98,10 @@ UNIT_BINDER::UNIT_BINDER( UNITS_PROVIDER* aUnitsProvider, wxWindow* aEventSource
this );
}
if( m_eventSource )
if( aEventSource )
{
m_eventSource->Connect( UNITS_CHANGED, wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
nullptr, this );
aEventSource->Connect( UNITS_CHANGED, wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
nullptr, this );
}
}
@@ -115,12 +114,6 @@ UNIT_BINDER::~UNIT_BINDER()
this );
}
if( m_eventSource )
{
m_eventSource->Disconnect( UNITS_CHANGED, wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
nullptr, this );
}
if( m_valueCtrl )
{
m_valueCtrl->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( UNIT_BINDER::onSetFocus ),
@@ -395,7 +388,7 @@ void UNIT_BINDER::SetValue( const wxString& aValue )
value += EDA_UNIT_UTILS::GetLabel( m_units, m_dataType );
}
if( textEntry )
textEntry->SetValue( value );
else if( staticText )
+24 -1
View File
@@ -273,7 +273,7 @@ void WX_GRID::DestroyTable( wxGridTableBase* aTable )
}
wxString WX_GRID::GetShownColumns()
wxString WX_GRID::GetShownColumnsAsString()
{
wxString shownColumns;
@@ -292,6 +292,17 @@ wxString WX_GRID::GetShownColumns()
}
std::bitset<64> WX_GRID::GetShownColumns()
{
std::bitset<64> shownColumns;
for( int ii = 0; ii < GetNumberCols(); ++ii )
shownColumns[ii] = IsColShown( ii );
return shownColumns;
}
void WX_GRID::ShowHideColumns( const wxString& shownColumns )
{
for( int i = 0; i < GetNumberCols(); ++i )
@@ -310,6 +321,18 @@ void WX_GRID::ShowHideColumns( const wxString& shownColumns )
}
void WX_GRID::ShowHideColumns( const std::bitset<64>& aShownColumns )
{
for( int ii = 0; ii < GetNumberCols(); ++ ii )
{
if( aShownColumns[ii] )
ShowCol( ii );
else
HideCol( ii );
}
}
void WX_GRID::DrawCornerLabel( wxDC& dc )
{
if( m_nativeColumnLabels )
+1 -1
View File
@@ -63,7 +63,7 @@ WX_INFOBAR::WX_INFOBAR( wxWindow* aParent, wxAuiManager* aMgr, wxWindowID aWinid
// Infobar is broken on Mac without the effects
SetShowHideEffects( wxSHOW_EFFECT_ROLL_TO_BOTTOM, wxSHOW_EFFECT_ROLL_TO_TOP );
SetEffectDuration( 300 );
SetEffectDuration( 200 );
#else
// Infobar freezes canvas on Windows with the effect, and GTK looks bad with it
SetShowHideEffects( wxSHOW_EFFECT_NONE, wxSHOW_EFFECT_NONE );
+108 -11
View File
@@ -195,7 +195,7 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
m_driver_connection->SetDriver( m_driver );
m_driver_connection->ClearDirty();
}
else
else if( !m_is_bus_member )
{
m_driver_connection = nullptr;
}
@@ -246,7 +246,36 @@ wxString CONNECTION_SUBGRAPH::GetNetName() const
}
std::vector<SCH_ITEM*> CONNECTION_SUBGRAPH::GetBusLabels() const
std::vector<SCH_ITEM*> CONNECTION_SUBGRAPH::GetAllBusLabels() const
{
std::vector<SCH_ITEM*> labels;
for( SCH_ITEM* item : m_drivers )
{
switch( item->Type() )
{
case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T:
{
CONNECTION_TYPE type = item->Connection( &m_sheet )->Type();
// Only consider bus vectors
if( type == CONNECTION_TYPE::BUS || type == CONNECTION_TYPE::BUS_GROUP )
labels.push_back( item );
break;
}
default:
break;
}
}
return labels;
}
std::vector<SCH_ITEM*> CONNECTION_SUBGRAPH::GetVectorBusLabels() const
{
std::vector<SCH_ITEM*> labels;
@@ -971,6 +1000,58 @@ void CONNECTION_GRAPH::collectAllDriverValues()
}
void CONNECTION_GRAPH::generateBusAliasMembers()
{
std::vector<CONNECTION_SUBGRAPH*> new_subgraphs;
SCH_CONNECTION dummy( this );
for( auto&& subgraph : m_driver_subgraphs )
{
auto vec = subgraph->GetAllBusLabels();
for( auto& item : vec )
{
SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( item );
dummy.ConfigureFromLabel( label->GetText() );
wxLogTrace( ConnTrace, wxS( "new bus label (%s)" ), label->GetText() );
for( auto& conn : dummy.Members() )
{
wxString name = conn->FullLocalName();
CONNECTION_SUBGRAPH* new_sg = new CONNECTION_SUBGRAPH( this );
SCH_CONNECTION* new_conn = new SCH_CONNECTION( this );
new_conn->SetName( name );
new_conn->SetType( CONNECTION_TYPE::NET );
int code = assignNewNetCode( *new_conn );
wxLogTrace( ConnTrace, wxS( "SG(%ld), Adding full local name (%s) with sg (%d)" ), subgraph->m_code,
name, code );
new_sg->m_driver_connection = new_conn;
new_sg->m_code = m_last_subgraph_code++;
new_sg->m_sheet = subgraph->m_sheet;
new_sg->m_is_bus_member = true;
new_sg->m_strong_driver = true;
/// Need to figure out why these sgs are not getting connected to their bus parents
NET_NAME_CODE_CACHE_KEY key = { new_sg->GetNetName(), code };
m_net_code_to_subgraphs_map[ key ].push_back( new_sg );
m_net_name_to_subgraphs_map[ name ].push_back( new_sg );
m_subgraphs.push_back( new_sg );
new_subgraphs.push_back( new_sg );
}
}
}
std::copy( new_subgraphs.begin(), new_subgraphs.end(), std::back_inserter( m_driver_subgraphs ) );
}
void CONNECTION_GRAPH::generateInvisiblePinSubGraphs()
{
// Generate subgraphs for invisible power pins. These will be merged with other subgraphs
@@ -1115,7 +1196,7 @@ void CONNECTION_GRAPH::processSubGraphs()
name = new_name;
}
else
else if( subgraph->m_driver )
{
// If there is no conflict, promote sheet pins to be strong drivers so that they
// will be considered below for propagation/merging.
@@ -1355,7 +1436,8 @@ void CONNECTION_GRAPH::processSubGraphs()
if( subgraph->m_absorbed )
continue;
subgraph->ResolveDrivers();
if( !subgraph->ResolveDrivers() )
continue;
if( subgraph->m_driver_connection->IsBus() )
assignNetCodesToBus( subgraph->m_driver_connection );
@@ -1412,6 +1494,8 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
generateInvisiblePinSubGraphs();
generateBusAliasMembers();
PROF_TIMER proc_sub_graph( "ProcessSubGraphs" );
processSubGraphs();
@@ -1610,7 +1694,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
// As a visual aid, we can check sheet pins that are driven by themselves to see
// if they should be promoted to buses
if( subgraph->m_driver->Type() == SCH_SHEET_PIN_T )
if( subgraph->m_driver && subgraph->m_driver->Type() == SCH_SHEET_PIN_T )
{
SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( subgraph->m_driver );
@@ -1689,6 +1773,8 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
const CONNECTION_SUBGRAPH* driverSubgraph = nullptr;
wxString netclass;
wxCHECK_RET( !subgraphs.empty(), wxT("Invalid empty subgraph" ) );
for( const CONNECTION_SUBGRAPH* subgraph : subgraphs )
{
for( SCH_ITEM* item : subgraph->m_items )
@@ -1699,7 +1785,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
break;
}
if( !netclass.IsEmpty() || !driverSubgraph )
if( !netclass.IsEmpty() )
{
driverSubgraph = subgraph;
break;
@@ -1709,6 +1795,9 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
if( netclass.IsEmpty() )
return;
if( !driverSubgraph )
driverSubgraph = subgraphs.front();
const wxString netname = driverSubgraph->GetNetName();
if( driverSubgraph->m_driver_connection->IsBus() )
@@ -1735,22 +1824,30 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
}
int CONNECTION_GRAPH::assignNewNetCode( SCH_CONNECTION& aConnection )
int CONNECTION_GRAPH::getOrCreateNetCode( const wxString& aNetName )
{
int code;
auto it = m_net_name_to_code_map.find( aConnection.Name() );
auto it = m_net_name_to_code_map.find( aNetName );
if( it == m_net_name_to_code_map.end() )
{
code = m_last_net_code++;
m_net_name_to_code_map[ aConnection.Name() ] = code;
m_net_name_to_code_map[ aNetName ] = code;
}
else
{
code = it->second;
}
return code;
}
int CONNECTION_GRAPH::assignNewNetCode( SCH_CONNECTION& aConnection )
{
int code = getOrCreateNetCode( aConnection.Name() );
aConnection.SetNetCode( code );
return code;
@@ -1759,7 +1856,7 @@ int CONNECTION_GRAPH::assignNewNetCode( SCH_CONNECTION& aConnection )
void CONNECTION_GRAPH::assignNetCodesToBus( SCH_CONNECTION* aConnection )
{
std::vector< std::shared_ptr<SCH_CONNECTION>>& connections_to_check( aConnection->Members() );
std::vector<std::shared_ptr<SCH_CONNECTION>> connections_to_check( aConnection->Members() );
for( unsigned i = 0; i < connections_to_check.size(); i++ )
{
@@ -2230,7 +2327,7 @@ std::vector<const CONNECTION_SUBGRAPH*> CONNECTION_GRAPH::GetBusesNeedingMigrati
if( !connection->IsBus() )
continue;
auto labels = subgraph->GetBusLabels();
auto labels = subgraph->GetVectorBusLabels();
if( labels.size() > 1 )
{
+24 -2
View File
@@ -76,6 +76,7 @@ public:
m_graph( aGraph ),
m_dirty( false ),
m_absorbed( false ),
m_is_bus_member( false ),
m_absorbed_by( nullptr ),
m_code( -1 ),
m_multiple_drivers( false ),
@@ -108,8 +109,11 @@ public:
*/
wxString GetNetName() const;
/// Returns all the bus labels attached to this subgraph (if any)
std::vector<SCH_ITEM*> GetBusLabels() const;
/// Returns all the vector-based bus labels attached to this subgraph (if any)
std::vector<SCH_ITEM*> GetVectorBusLabels() const;
/// Returns all the all bus labels attached to this subgraph (if any)
std::vector<SCH_ITEM*> GetAllBusLabels() const;
/// Returns the candidate net name for a driver
const wxString& GetNameForDriver( SCH_ITEM* aItem ) const;
@@ -160,6 +164,12 @@ public:
/// True if this subgraph has been absorbed into another. No pointers here are safe if so!
bool m_absorbed;
/**
* True if the subgraph is not actually part of a net. These are created for bus members
* to ensure that bus-to-bus connection happens but they don't have any valid data
*/
bool m_is_bus_member;
/// If this subgraph is absorbed, points to the absorbing (and valid) subgraph
CONNECTION_SUBGRAPH* m_absorbed_by;
@@ -421,6 +431,11 @@ private:
*/
void generateInvisiblePinSubGraphs();
/**
* Iterate through labels to create placeholders for bus elements
*/
void generateBusAliasMembers();
/**
* Process all subgraphs to assign netcodes and merge subgraphs based on labels
*/
@@ -433,6 +448,13 @@ private:
*/
int assignNewNetCode( SCH_CONNECTION& aConnection );
/**
*
* @param aNetName string with the netname for coding
* @return existing netcode (if it exists) or newly created one
*/
int getOrCreateNetCode( const wxString& aNetName );
/**
* Ensures all members of the bus connection have a valid net code assigned
* @param aConnection is a bus connection
+1 -1
View File
@@ -132,7 +132,7 @@ DIALOG_ANNOTATE::~DIALOG_ANNOTATE()
if( projSettings.m_AnnotateStartNum != startNum )
{
projSettings.m_AnnotateStartNum = startNum;
schFrame->SaveProjectSettings();
schFrame->OnModify();
}
}
}
+28 -13
View File
@@ -129,7 +129,7 @@ private:
void InstallPageSpiceModel();
bool TransferDataFromWindow() override;
void NetlistUpdateOpt();
bool NetlistUpdateOpt();
void updateGeneratorButtons();
@@ -254,7 +254,7 @@ DIALOG_EXPORT_NETLIST::DIALOG_EXPORT_NETLIST( SCH_EDIT_FRAME* parent ) :
SCHEMATIC_SETTINGS& settings = m_Parent->Schematic().Settings();
for( EXPORT_NETLIST_PAGE*& page : m_PanelNetType)
for( EXPORT_NETLIST_PAGE*& page : m_PanelNetType )
page = nullptr;
// Add notebook pages:
@@ -463,22 +463,35 @@ void DIALOG_EXPORT_NETLIST::OnNetlistTypeSelection( wxNotebookEvent& event )
}
void DIALOG_EXPORT_NETLIST::NetlistUpdateOpt()
bool DIALOG_EXPORT_NETLIST::NetlistUpdateOpt()
{
bool saveAllVoltages = m_PanelNetType[ PANELSPICE ]->m_SaveAllVoltages->IsChecked();
bool saveAllCurrents = m_PanelNetType[ PANELSPICE ]->m_SaveAllCurrents->IsChecked();
bool changed = false;
bool saveAllVoltages = m_PanelNetType[ PANELSPICE ]->m_SaveAllVoltages->IsChecked();
bool saveAllCurrents = m_PanelNetType[ PANELSPICE ]->m_SaveAllCurrents->IsChecked();
wxString spiceCmdString = m_PanelNetType[ PANELSPICE ]->m_CommandStringCtrl->GetValue();
bool curSheetAsRoot = m_PanelNetType[ PANELSPICE ]->m_CurSheetAsRoot->GetValue();
bool spiceModelCurSheetAsRoot = m_PanelNetType[ PANELSPICEMODEL ]->m_CurSheetAsRoot->GetValue();
SCHEMATIC_SETTINGS& settings = m_Parent->Schematic().Settings();
wxString netFormatName = m_PanelNetType[m_NoteBook->GetSelection()]->GetPageNetFmtName();
settings.m_SpiceSaveAllVoltages = saveAllVoltages;
settings.m_SpiceSaveAllCurrents = saveAllCurrents;
settings.m_SpiceCommandString = spiceCmdString;
settings.m_SpiceCurSheetAsRoot = curSheetAsRoot;
changed |= ( settings.m_SpiceSaveAllVoltages != saveAllVoltages );
changed |= ( settings.m_SpiceSaveAllCurrents != saveAllCurrents );
changed |= ( settings.m_SpiceCommandString != spiceCmdString );
changed |= ( settings.m_SpiceCurSheetAsRoot != curSheetAsRoot );
changed |= ( settings.m_SpiceModelCurSheetAsRoot != spiceModelCurSheetAsRoot );
changed |= ( settings.m_NetFormatName != netFormatName );
settings.m_SpiceSaveAllVoltages = saveAllVoltages;
settings.m_SpiceSaveAllCurrents = saveAllCurrents;
settings.m_SpiceCommandString = spiceCmdString;
settings.m_SpiceCurSheetAsRoot = curSheetAsRoot;
settings.m_SpiceModelCurSheetAsRoot = spiceModelCurSheetAsRoot;
settings.m_NetFormatName = m_PanelNetType[m_NoteBook->GetSelection()]->GetPageNetFmtName();
settings.m_NetFormatName = netFormatName;
return changed;
}
@@ -489,7 +502,8 @@ bool DIALOG_EXPORT_NETLIST::TransferDataFromWindow()
wxString fileExt;
wxString title = _( "Save Netlist File" );
NetlistUpdateOpt();
if( NetlistUpdateOpt() )
m_Parent->OnModify();
EXPORT_NETLIST_PAGE* currPage;
currPage = (EXPORT_NETLIST_PAGE*) m_NoteBook->GetCurrentPage();
@@ -621,7 +635,8 @@ bool DIALOG_EXPORT_NETLIST::FilenamePrms( NETLIST_TYPE_ID aType, wxString * aExt
void DIALOG_EXPORT_NETLIST::WriteCurrentNetlistSetup()
{
NetlistUpdateOpt();
if( NetlistUpdateOpt() )
m_Parent->OnModify();
EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
wxASSERT( cfg );
@@ -798,7 +813,7 @@ int InvokeDialogNetList( SCH_EDIT_FRAME* aCaller )
DIALOG_EXPORT_NETLIST dlg( aCaller );
int ret = dlg.ShowModal();
aCaller->SaveProjectSettings();
aCaller->SaveProjectLocalSettings();
return ret;
}
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -79,7 +79,6 @@ DIALOG_IMAGE_PROPERTIES_BASE::DIALOG_IMAGE_PROPERTIES_BASE( wxWindow* parent, wx
this->SetSizer( m_GeneralBoxSizer );
this->Layout();
m_GeneralBoxSizer->Fit( this );
this->Centre( wxBOTH );
}
@@ -36,6 +36,7 @@
<property name="center">wxBOTH</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="extra_style"></property>
@@ -47,8 +48,8 @@
<property name="minimum_size"></property>
<property name="name">DIALOG_IMAGE_PROPERTIES_BASE</property>
<property name="pos"></property>
<property name="size"></property>
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
<property name="size">363,281</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h; forward_declare</property>
<property name="title"></property>
<property name="tooltip"></property>
@@ -87,6 +88,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@@ -143,6 +145,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@@ -231,6 +234,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@@ -292,6 +296,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@@ -356,6 +361,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@@ -417,6 +423,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@@ -478,6 +485,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@@ -542,6 +550,7 @@
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -52,7 +52,7 @@ class DIALOG_IMAGE_PROPERTIES_BASE : public DIALOG_SHIM
public:
DIALOG_IMAGE_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
DIALOG_IMAGE_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 363,281 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_IMAGE_PROPERTIES_BASE();
+30 -15
View File
@@ -118,13 +118,10 @@ DIALOG_LABEL_PROPERTIES::DIALOG_LABEL_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_L
m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
// Show/hide columns according to user's preference
auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
wxASSERT( cfg );
if( cfg )
if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
{
m_shownColumns = cfg->m_Appearance.edit_label_visible_columns;
m_grid->ShowHideColumns( m_shownColumns );
m_grid->ShowHideColumns( cfg->m_Appearance.edit_label_visible_columns );
m_shownColumns = m_grid->GetShownColumns();
}
// Configure button logos
@@ -221,19 +218,19 @@ DIALOG_LABEL_PROPERTIES::DIALOG_LABEL_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_L
// Now all widgets have the size fixed, call FinishDialogSettings
finishDialogSettings();
if( cfg && cfg->m_Appearance.edit_label_width > 0 && cfg->m_Appearance.edit_label_height > 0 )
SetSize( cfg->m_Appearance.edit_label_width, cfg->m_Appearance.edit_label_height );
if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
{
if( cfg->m_Appearance.edit_label_width > 0 && cfg->m_Appearance.edit_label_height > 0 )
SetSize( cfg->m_Appearance.edit_label_width, cfg->m_Appearance.edit_label_height );
}
}
DIALOG_LABEL_PROPERTIES::~DIALOG_LABEL_PROPERTIES()
{
EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
wxASSERT( cfg );
if( cfg )
if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
{
cfg->m_Appearance.edit_label_visible_columns = m_grid->GetShownColumns();
cfg->m_Appearance.edit_label_visible_columns = m_grid->GetShownColumnsAsString();
cfg->m_Appearance.edit_label_width = GetSize().x;
cfg->m_Appearance.edit_label_height = GetSize().y;
}
@@ -286,7 +283,11 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataToWindow()
for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_LOCATE_POWER_T ) )
{
const SCH_SYMBOL* power = static_cast<const SCH_SYMBOL*>( item );
existingLabels.insert( UnescapeString( power->GetValueFieldText( false ) ) );
// Ensure the symbol has the Power (i.e. equivalent to a global label
// before adding its value in list
if( power->IsSymbolLikePowerGlobalLabel() )
existingLabels.insert( UnescapeString( power->GetValueFieldText( false ) ) );
}
}
@@ -498,6 +499,20 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataFromWindow()
else
doAutoplace = true;
for( int ii = m_fields->GetNumberRows() - 1; ii >= 0; ii-- )
{
SCH_FIELD& field = m_fields->at( ii );
const wxString& fieldName = field.GetCanonicalName();
const wxString& fieldText = field.GetText();
if( fieldName.IsEmpty() && fieldText.IsEmpty() )
m_fields->erase( m_fields->begin() + ii );
else if( fieldName == wxT( "Netclass" ) && fieldText.IsEmpty() )
m_fields->erase( m_fields->begin() + ii );
else if( fieldName.IsEmpty() )
field.SetName( _( "untitled" ) );
}
m_currentLabel->SetFields( *m_fields );
if( m_shapeSizer->AreAnyItemsShown() )
@@ -758,7 +773,7 @@ void DIALOG_LABEL_PROPERTIES::AdjustGridColumns( int aWidth )
void DIALOG_LABEL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
{
wxString shownColumns = m_grid->GetShownColumns();
std::bitset<64> shownColumns = m_grid->GetShownColumns();
if( shownColumns != m_shownColumns )
{
+1 -1
View File
@@ -71,7 +71,7 @@ private:
SCH_NETNAME_VALIDATOR m_netNameValidator;
FIELDS_GRID_TABLE<SCH_FIELD>* m_fields;
wxString m_shownColumns;
std::bitset<64> m_shownColumns;
UNIT_BINDER m_textSize;
@@ -723,10 +723,11 @@ DIALOG_LIB_EDIT_PIN_TABLE::DIALOG_LIB_EDIT_PIN_TABLE( SYMBOL_EDIT_FRAME* parent,
} ) );
// Show/hide columns according to the user's preference
SYMBOL_EDITOR_SETTINGS* cfg = parent->GetSettings();
m_columnsShown = cfg->m_PinTableVisibleColumns;
m_grid->ShowHideColumns( m_columnsShown );
if( SYMBOL_EDITOR_SETTINGS* cfg = parent->GetSettings() )
{
m_grid->ShowHideColumns( cfg->m_PinTableVisibleColumns );
m_columnsShown = m_grid->GetShownColumns();
}
// Set special attributes
wxGridCellAttr* attr;
@@ -838,8 +839,8 @@ DIALOG_LIB_EDIT_PIN_TABLE::DIALOG_LIB_EDIT_PIN_TABLE( SYMBOL_EDIT_FRAME* parent,
DIALOG_LIB_EDIT_PIN_TABLE::~DIALOG_LIB_EDIT_PIN_TABLE()
{
SYMBOL_EDITOR_SETTINGS* cfg = m_editFrame->GetSettings();
cfg->m_PinTableVisibleColumns = m_grid->GetShownColumns().ToStdString();
if( SYMBOL_EDITOR_SETTINGS* cfg = m_editFrame->GetSettings() )
cfg->m_PinTableVisibleColumns = m_grid->GetShownColumnsAsString();
// Disconnect Events
m_grid->Disconnect( wxEVT_GRID_COL_SORT,
@@ -1130,7 +1131,7 @@ void DIALOG_LIB_EDIT_PIN_TABLE::OnSize( wxSizeEvent& event )
void DIALOG_LIB_EDIT_PIN_TABLE::OnUpdateUI( wxUpdateUIEvent& event )
{
wxString columnsShown = m_grid->GetShownColumns();
std::bitset<64> columnsShown = m_grid->GetShownColumns();
if( columnsShown != m_columnsShown )
{
+1 -1
View File
@@ -84,7 +84,7 @@ protected:
SYMBOL_EDIT_FRAME* m_editFrame;
bool m_initialized = false;
int m_originalColWidths[ COL_COUNT ];
wxString m_columnsShown;
std::bitset<64> m_columnsShown;
LIB_SYMBOL* m_symbol;
LIB_PINS m_pins; // a copy of the pins owned by me
bool m_modified; ///< true when there are unsaved changes
@@ -134,8 +134,8 @@ DIALOG_LIB_SYMBOL_PROPERTIES::~DIALOG_LIB_SYMBOL_PROPERTIES()
{
m_lastOpenedPage = m_NoteBook->GetSelection( );
SYMBOL_EDITOR_SETTINGS* cfg = m_Parent->GetSettings();
cfg->m_EditSymbolVisibleColumns = m_grid->GetShownColumns();
if( SYMBOL_EDITOR_SETTINGS* cfg = m_Parent->GetSettings() )
cfg->m_EditSymbolVisibleColumns = m_grid->GetShownColumnsAsString();
// Prevents crash bug in wxGrid's d'tor
m_grid->DestroyTable( m_fields );
@@ -302,7 +302,7 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::Validate()
LIB_FIELD& field = m_fields->at( ii );
wxString fieldName = field.GetName( false );
if( fieldName.IsEmpty() )
if( fieldName.IsEmpty() && !field.GetText().IsEmpty() )
{
if( m_NoteBook->GetSelection() != 0 )
m_NoteBook->SetSelection( 0 );
@@ -393,6 +393,17 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
m_fields->at( ii ).SetId( ii );
}
for( int ii = m_fields->GetNumberRows() - 1; ii >= MANDATORY_FIELDS; ii-- )
{
LIB_FIELD& field = m_fields->at( ii );
const wxString& fieldName = field.GetCanonicalName();
if( fieldName.IsEmpty() && field.GetText().IsEmpty() )
m_fields->erase( m_fields->begin() + ii );
else if( fieldName.IsEmpty() )
field.SetName( _( "untitled" ) );
}
m_libEntry->SetFields( *m_fields );
// Update the parent for inherited symbols
@@ -841,7 +852,7 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
}
// Handle shown columns changes
wxString shownColumns = m_grid->GetShownColumns();
std::bitset<64> shownColumns = m_grid->GetShownColumns();
if( shownColumns != m_shownColumns )
{
@@ -90,7 +90,7 @@ public:
int m_delayedFocusPage;
wxString m_delayedErrorMessage;
wxString m_shownColumns;
std::bitset<64> m_shownColumns;
wxSize m_size;
private:
@@ -122,6 +122,8 @@ DIALOG_LIB_TEXT_PROPERTIES::~DIALOG_LIB_TEXT_PROPERTIES()
bool DIALOG_LIB_TEXT_PROPERTIES::TransferDataToWindow()
{
wxCHECK( m_CommonUnit, false );
LIB_SYMBOL* symbol = nullptr;
if( m_graphicText )
@@ -170,10 +172,11 @@ bool DIALOG_LIB_TEXT_PROPERTIES::TransferDataToWindow()
auto* tools = m_parent->GetToolManager()->GetTool<SYMBOL_EDITOR_DRAWING_TOOLS>();
symbol = m_parent->GetCurSymbol();
wxCHECK( cfg && symbol && tools, false );
m_textSize.SetValue( schIUScale.MilsToIU( cfg->m_Defaults.text_size ) );
m_CommonUnit->SetValue(
symbol && symbol->GetUnitCount() > 1 && !tools->GetDrawSpecificUnit() );
m_CommonUnit->SetValue( symbol->GetUnitCount() > 1 && !tools->GetDrawSpecificUnit() );
m_CommonConvert->SetValue( !tools->GetDrawSpecificConvert() );
if( tools->GetLastTextAngle().IsHorizontal() )
+2 -2
View File
@@ -84,7 +84,7 @@ void DIALOG_MIGRATE_BUSES::loadGraphData()
status.subgraph = subgraph;
status.approved = false;
std::vector<SCH_ITEM*> labels = subgraph->GetBusLabels();
std::vector<SCH_ITEM*> labels = subgraph->GetVectorBusLabels();
wxASSERT( labels.size() > 1 );
for( SCH_ITEM* label : labels )
@@ -205,7 +205,7 @@ void DIALOG_MIGRATE_BUSES::onAcceptClicked( wxCommandEvent& aEvent )
m_items[sel].approved_label = m_cb_new_name->GetStringSelection();
m_items[sel].approved = true;
std::vector<SCH_ITEM*> labels = m_items[sel].subgraph->GetBusLabels();
std::vector<SCH_ITEM*> labels = m_items[sel].subgraph->GetVectorBusLabels();
for( SCH_ITEM* label : labels )
static_cast<SCH_LABEL_BASE*>( label )->SetText( m_items[sel].approved_label );
@@ -112,17 +112,17 @@ DIALOG_SCH_FIND_BASE::DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id, con
wxBoxSizer* rightSizer;
rightSizer = new wxBoxSizer( wxVERTICAL );
m_buttonFind = new wxButton( this, wxID_FIND, _("&Find"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonFind = new wxButton( this, wxID_FIND, _("Find"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonFind->SetDefault();
rightSizer->Add( m_buttonFind, 0, wxALL|wxEXPAND, 6 );
m_buttonReplace = new wxButton( this, wxID_REPLACE, _("&Replace"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonReplace = new wxButton( this, wxID_REPLACE, _("Replace"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonReplace->Hide();
rightSizer->Add( m_buttonReplace, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 6 );
m_buttonReplaceAll = new wxButton( this, wxID_REPLACE_ALL, _("Replace &All"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonReplaceAll = new wxButton( this, wxID_REPLACE_ALL, _("Replace All"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonReplaceAll->Hide();
rightSizer->Add( m_buttonReplaceAll, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 6 );
@@ -1100,7 +1100,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_FIND</property>
<property name="label">&amp;Find</property>
<property name="label">Find</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
@@ -1174,7 +1174,7 @@
<property name="gripper">0</property>
<property name="hidden">1</property>
<property name="id">wxID_REPLACE</property>
<property name="label">&amp;Replace</property>
<property name="label">Replace</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
@@ -1249,7 +1249,7 @@
<property name="gripper">0</property>
<property name="hidden">1</property>
<property name="id">wxID_REPLACE_ALL</property>
<property name="label">Replace &amp;All</property>
<property name="label">Replace All</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
+17 -12
View File
@@ -69,13 +69,10 @@ DIALOG_SHEET_PROPERTIES::DIALOG_SHEET_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_S
m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
// Show/hide columns according to user's preference
EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
wxASSERT( cfg );
if( cfg )
if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
{
m_shownColumns = cfg->m_Appearance.edit_sheet_visible_columns;
m_grid->ShowHideColumns( m_shownColumns );
m_grid->ShowHideColumns( cfg->m_Appearance.edit_sheet_visible_columns );
m_shownColumns = m_grid->GetShownColumns();
}
if( m_frame->GetColorSettings()->GetOverrideSchItemColors() )
@@ -108,12 +105,9 @@ DIALOG_SHEET_PROPERTIES::DIALOG_SHEET_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_S
DIALOG_SHEET_PROPERTIES::~DIALOG_SHEET_PROPERTIES()
{
EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
wxASSERT( cfg );
if( cfg )
if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
{
cfg->m_Appearance.edit_sheet_visible_columns = m_grid->GetShownColumns();
cfg->m_Appearance.edit_sheet_visible_columns = m_grid->GetShownColumnsAsString();
cfg->m_Appearance.edit_sheet_width = GetSize().x;
cfg->m_Appearance.edit_sheet_height = GetSize().y;
}
@@ -368,6 +362,17 @@ bool DIALOG_SHEET_PROPERTIES::TransferDataFromWindow()
if( positioningChanged( m_fields, m_sheet->GetFields() ) )
m_sheet->ClearFieldsAutoplaced();
for( int ii = m_fields->GetNumberRows() - 1; ii >= SHEET_MANDATORY_FIELDS; ii-- )
{
SCH_FIELD& field = m_fields->at( ii );
const wxString& fieldName = field.GetCanonicalName();
if( fieldName.IsEmpty() && field.GetText().IsEmpty() )
m_fields->erase( m_fields->begin() + ii );
else if( fieldName.IsEmpty() )
field.SetName( _( "untitled" ) );
}
m_sheet->SetFields( *m_fields );
m_sheet->SetBorderWidth( m_borderWidth.GetValue() );
@@ -841,7 +846,7 @@ void DIALOG_SHEET_PROPERTIES::AdjustGridColumns()
void DIALOG_SHEET_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
{
wxString shownColumns = m_grid->GetShownColumns();
std::bitset<64> shownColumns = m_grid->GetShownColumns();
if( shownColumns != m_shownColumns )
{
+1 -1
View File
@@ -70,7 +70,7 @@ private:
wxSize m_size;
int m_delayedFocusRow;
int m_delayedFocusColumn;
wxString m_shownColumns;
std::bitset<64> m_shownColumns;
FIELDS_GRID_TABLE<SCH_FIELD>* m_fields;
UNIT_BINDER m_borderWidth;
+33 -26
View File
@@ -136,6 +136,9 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
wxString pinMap;
bool storeInValue = false;
wxString msg;
WX_STRING_REPORTER reporter( &msg );
// Infer RLC and VI models if they aren't specified
if( SIM_MODEL::InferSimModel( m_symbol, &m_fields, false, SIM_VALUE_GRAMMAR::NOTATION::SI,
&deviceType, &modelType, &modelParams, &pinMap ) )
@@ -180,7 +183,7 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
if( !loadLibrary( libraryFilename ) )
{
m_libraryPathText->ChangeValue( libraryFilename );
m_curModelType = SIM_MODEL::ReadTypeFromFields( m_fields );
m_curModelType = SIM_MODEL::ReadTypeFromFields( m_fields, &reporter );
m_libraryModelsMgr.CreateModel( nullptr, sourcePins, m_fields );
m_modelNameChoice->Append( _( "<unknown>" ) );
@@ -256,25 +259,32 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
{
// The model is sourced from the instance.
m_useInstanceModelRadioButton->SetValue( true );
m_curModelType = SIM_MODEL::ReadTypeFromFields( m_fields );
msg.clear();
m_curModelType = SIM_MODEL::ReadTypeFromFields( m_fields, &reporter );
if( reporter.HasMessage() )
DisplayErrorMessage( this, msg );
}
m_builtinModelsMgr.SetReporter( &reporter );
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
{
wxString msg;
WX_STRING_REPORTER reporter( &msg );
m_builtinModelsMgr.SetReporter( &reporter );
if( m_useInstanceModelRadioButton->GetValue() && type == m_curModelType )
m_builtinModelsMgr.CreateModel( m_fields, sourcePins, false );
else
m_builtinModelsMgr.CreateModel( type, sourcePins );
if( reporter.HasMessage() )
{
DisplayErrorMessage( this, _( "Failed to read simulation model from fields." )
+ wxT( "\n\n" ) + msg );
msg.clear();
m_builtinModelsMgr.CreateModel( m_fields, sourcePins, false );
if( reporter.HasMessage() )
{
DisplayErrorMessage( this, _( "Failed to read simulation model from fields." )
+ wxT( "\n\n" ) + msg );
}
}
else
{
m_builtinModelsMgr.CreateModel( type, sourcePins );
}
SIM_MODEL::DEVICE_T deviceTypeT = SIM_MODEL::TypeInfo( type ).deviceType;
@@ -698,7 +708,7 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::loadLibrary( const wxString& aLibraryP
std::string modelName = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::NAME_FIELD );
for( auto& [baseModelName, baseModel] : library()->GetModels() )
for( const auto& [baseModelName, baseModel] : library()->GetModels() )
{
if( baseModelName == modelName )
m_libraryModelsMgr.CreateModel( &baseModel, sourcePins, m_fields );
@@ -714,7 +724,7 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::loadLibrary( const wxString& aLibraryP
wxArrayString modelNames;
for( auto& [name, model] : library()->GetModels() )
for( const auto& [name, model] : library()->GetModels() )
modelNames.Add( name );
m_modelNameChoice->Clear();
@@ -1160,6 +1170,9 @@ void DIALOG_SIM_MODEL<T_symbol, T_field>::onDifferentialCheckbox( wxCommandEvent
if( isIbisLoaded() )
{
SIM_MODEL_KIBIS* modelkibis = dynamic_cast<SIM_MODEL_KIBIS*>( &curModel() );
wxCHECK( modelkibis, /* void */ );
bool diff = m_differentialCheckbox->GetValue() && modelkibis->CanDifferential();
modelkibis->SwitchSingleEndedDiff( diff );
}
@@ -1404,22 +1417,16 @@ void DIALOG_SIM_MODEL<T_symbol, T_field>::adjustParamGridColumns( int aWidth, bo
for( size_t ii = 0; ii < grid->GetColumnCount(); ii++ )
{
if( ii == 0 )
if( ii == PARAM_COLUMN::DESCRIPTION )
colWidths.push_back( grid->GetState()->GetColumnWidth( ii ) + margin + indent );
else if( ii == 1 )
colWidths.push_back( grid->GetState()->GetColumnWidth( ii ) + margin );
else if( ii == PARAM_COLUMN::VALUE )
colWidths.push_back( std::max( 72, grid->GetState()->GetColumnWidth( ii ) ) + margin );
else
colWidths.push_back( 50 );
colWidths.push_back( 60 + margin );
aWidth -= colWidths[ ii ];
}
// Account for scroll bars
aWidth -= ( grid->GetSize().x - grid->GetClientSize().x );
if( aWidth > 0 )
colWidths[ PARAM_COLUMN::VALUE ] += aWidth;
for( size_t ii = 0; ii < grid->GetColumnCount(); ii++ )
grid->SetColumnProportion( ii, colWidths[ ii ] );
+18 -12
View File
@@ -333,12 +333,10 @@ DIALOG_SYMBOL_PROPERTIES::DIALOG_SYMBOL_PROPERTIES( SCH_EDIT_FRAME* aParent,
m_fieldsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
// Show/hide columns according to user's preference
EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
if( cfg )
if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
{
m_shownColumns = cfg->m_Appearance.edit_symbol_visible_columns;
m_fieldsGrid->ShowHideColumns( m_shownColumns );
m_fieldsGrid->ShowHideColumns( cfg->m_Appearance.edit_symbol_visible_columns );
m_shownColumns = m_fieldsGrid->GetShownColumns();
}
if( m_part && m_part->HasConversion() )
@@ -394,11 +392,9 @@ DIALOG_SYMBOL_PROPERTIES::DIALOG_SYMBOL_PROPERTIES( SCH_EDIT_FRAME* aParent,
DIALOG_SYMBOL_PROPERTIES::~DIALOG_SYMBOL_PROPERTIES()
{
EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
if( cfg )
if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
{
cfg->m_Appearance.edit_symbol_visible_columns = m_fieldsGrid->GetShownColumns();
cfg->m_Appearance.edit_symbol_visible_columns = m_fieldsGrid->GetShownColumnsAsString();
cfg->m_Appearance.edit_symbol_width = GetSize().x;
cfg->m_Appearance.edit_symbol_height = GetSize().y;
}
@@ -769,8 +765,18 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataFromWindow()
fields.clear();
for( size_t i = 0; i < m_fields->size(); ++i )
fields.push_back( m_fields->at( i ) );
for( size_t ii = 0; ii < m_fields->size(); ++ii )
{
SCH_FIELD& field = m_fields->at( ii );
const wxString& fieldName = field.GetCanonicalName();
if( fieldName.IsEmpty() && field.GetText().IsEmpty() )
continue;
else if( fieldName.IsEmpty() )
field.SetName( _( "untitled" ) );
fields.push_back( field );
}
// Reference has a specific initialization, depending on the current active sheet
// because for a given symbol, in a complex hierarchy, there are more than one
@@ -1168,7 +1174,7 @@ void DIALOG_SYMBOL_PROPERTIES::AdjustPinsGridColumns()
void DIALOG_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
{
wxString shownColumns = m_fieldsGrid->GetShownColumns();
std::bitset<64> shownColumns = m_fieldsGrid->GetShownColumns();
if( shownColumns != m_shownColumns )
{
+7 -7
View File
@@ -102,14 +102,14 @@ private:
void AdjustGridColumns( int aWidth );
private:
SCH_SYMBOL* m_symbol;
LIB_SYMBOL* m_part;
SCH_SYMBOL* m_symbol;
LIB_SYMBOL* m_part;
wxSize m_fieldsSize;
wxSize m_lastRequestedSize;
wxSize m_pinsSize;
bool m_editorShown;
wxString m_shownColumns;
wxSize m_fieldsSize;
wxSize m_lastRequestedSize;
wxSize m_pinsSize;
bool m_editorShown;
std::bitset<64> m_shownColumns;
FIELDS_GRID_TABLE<SCH_FIELD>* m_fields;
SCH_PIN_TABLE_DATA_MODEL* m_dataModel;
+4 -4
View File
@@ -572,8 +572,8 @@ void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
if( !filePathsList.IsEmpty() )
{
m_cur_grid->MakeCellVisible( m_cur_grid->GetNumberRows() - 1, 0 );
m_cur_grid->SetGridCursor( m_cur_grid->GetNumberRows() - 1, 1 );
m_cur_grid->MakeCellVisible( m_cur_grid->GetNumberRows() - 1, COL_ENABLED );
m_cur_grid->SetGridCursor( m_cur_grid->GetNumberRows() - 1, COL_NICKNAME );
}
}
@@ -588,8 +588,8 @@ void PANEL_SYM_LIB_TABLE::appendRowHandler( wxCommandEvent& event )
int row = m_cur_grid->GetNumberRows() - 1;
// wx documentation is wrong, SetGridCursor does not make visible.
m_cur_grid->MakeCellVisible( row, 0 );
m_cur_grid->SetGridCursor( row, 1 );
m_cur_grid->MakeCellVisible( row, COL_ENABLED );
m_cur_grid->SetGridCursor( row, COL_NICKNAME );
m_cur_grid->EnableCellEditControl( true );
m_cur_grid->ShowCellEditControl();
}
+7 -7
View File
@@ -140,7 +140,7 @@ static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER
void OnKifaceEnd() override;
wxWindow* CreateKiWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway,
int aCtlBits = 0 ) override
int aCtlBits = 0 ) override
{
switch( aClassId )
{
@@ -204,9 +204,9 @@ static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER
frame = aKiway->Player( FRAME_SCH, false );
if( frame )
return new PANEL_SYM_EDITING_OPTIONS( aParent, frame, frame );
else
return new PANEL_SYM_EDITING_OPTIONS( aParent, this, nullptr );
SetUserUnits( frame->GetUserUnits() );
return new PANEL_SYM_EDITING_OPTIONS( aParent, this, frame );
}
case PANEL_SYM_COLORS:
@@ -231,9 +231,9 @@ static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER
frame = aKiway->Player( FRAME_SCH_VIEWER, false );
if( frame )
return new PANEL_EESCHEMA_EDITING_OPTIONS( aParent, frame, frame );
else
return new PANEL_EESCHEMA_EDITING_OPTIONS( aParent, this, nullptr );
SetUserUnits( frame->GetUserUnits() );
return new PANEL_EESCHEMA_EDITING_OPTIONS( aParent, this, frame );
}
case PANEL_SCH_ANNO_OPTIONS:
+12 -2
View File
@@ -39,6 +39,7 @@
#include <wildcards_and_files_ext.h>
#include <drawing_sheet/ds_data_model.h>
#include <zoom_defines.h>
#include <sim/spice_settings.h>
/// Helper for all the old plotting/printing code while it still exists
@@ -88,7 +89,8 @@ void SCH_EDIT_FRAME::ShowSchematicSetupDialog( const wxString& aInitialPage )
if( dlg.ShowQuasiModal() == wxID_OK )
{
SaveProjectSettings();
// Mark document as modified so that project settings can be saved as part of doc save
OnModify();
Kiway().CommonSettingsChanged( false, true );
@@ -119,7 +121,7 @@ int SCH_EDIT_FRAME::GetSchematicJunctionSize()
}
void SCH_EDIT_FRAME::SaveProjectSettings()
void SCH_EDIT_FRAME::saveProjectSettings()
{
wxFileName fn = Schematic().RootScreen()->GetFileName(); //ConfigFileName
@@ -130,6 +132,8 @@ void SCH_EDIT_FRAME::SaveProjectSettings()
RecordERCExclusions();
if( Kiway().Player( FRAME_SIMULATOR, false ) )
Prj().GetProjectFile().m_SchematicSettings->m_NgspiceSimulatorSettings->SaveToFile();
// Save the page layout file if doesn't exist yet (e.g. if we opened a non-kicad schematic)
@@ -158,6 +162,12 @@ void SCH_EDIT_FRAME::SaveProjectSettings()
}
void SCH_EDIT_FRAME::SaveProjectLocalSettings()
{
// No schematic local settings yet
}
void SCH_EDIT_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg )
{
// For now, axes are forced off in Eeschema even if turned on in config
+1 -1
View File
@@ -1394,7 +1394,7 @@ bool SCH_EDIT_FRAME::updateAutoSaveFile()
void SCH_EDIT_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
{
if( !IsGUI() )
if( !Pgm().IsGUI() )
return;
wxCHECK_RET( aFileName.IsOk(), wxT( "Invalid file name!" ) );
+1 -1
View File
@@ -286,7 +286,7 @@ int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags ) const
if( lhsField->GetId() == VALUE_FIELD )
{
if( ( aCompareFlags & LIB_ITEM::COMPARE_FLAGS::ERC ) == 0 || IsPower() )
if( ( aCompareFlags & LIB_ITEM::COMPARE_FLAGS::ERC ) == 0 )
retv = lhsItem->compare( *rhsItem, aCompareFlags );
}
else if( lhsField->IsMandatory() )
+15 -20
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2004-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
@@ -276,27 +276,22 @@ void LIB_TEXT::Plot( PLOTTER* plotter, bool aBackground, const VECTOR2I& offset,
BOX2I bBox = GetBoundingBox();
// convert coordinates from draw Y axis to symbol_editor Y axis
bBox.RevertYAxis();
/*
* Calculate the text justification, according to the symbol orientation/mirror. This is
* a bit complicated due to cumulative calculations:
* - numerous cases (mirrored or not, rotation)
* - the plotter's Text() function will also recalculate H and V justifications according
* to the text orientation
* - when a symbol is mirrored the text is not, and justifications become a nightmare
*
* So the easier way is to use no justifications (centered text) and use GetBoundingBox to
* know the text coordinate considered as centered.
*/
VECTOR2I txtpos = bBox.Centre();
TEXT_ATTRIBUTES attrs = GetAttributes();
if( attrs.m_Angle == ANGLE_VERTICAL )
{
switch( attrs.m_Halign )
{
case GR_TEXT_H_ALIGN_LEFT: txtpos.y = bBox.GetTop(); break;
case GR_TEXT_H_ALIGN_CENTER: txtpos.y = bBox.GetCenter().y; break;
case GR_TEXT_H_ALIGN_RIGHT: txtpos.y = bBox.GetBottom(); break;
}
}
else
{
switch( attrs.m_Halign )
{
case GR_TEXT_H_ALIGN_LEFT: txtpos.x = bBox.GetLeft(); break;
case GR_TEXT_H_ALIGN_CENTER: txtpos.x = bBox.GetCenter().x; break;
case GR_TEXT_H_ALIGN_RIGHT: txtpos.x = bBox.GetRight(); break;
}
}
attrs.m_Halign = GR_TEXT_H_ALIGN_CENTER;
attrs.m_Valign = GR_TEXT_V_ALIGN_CENTER;
// The text orientation may need to be flipped if the transformation matrix causes xy
// axes to be flipped.
@@ -83,20 +83,13 @@ namespace NETLIST_EXPORTER_SPICE_PARSER
std::string NAME_GENERATOR::Generate( const std::string& aProposedName )
{
if( !m_names.count( aProposedName ) )
return aProposedName;
std::string name = aProposedName;
int ii = 1;
for( uint64_t i = 1; i < UINT64_MAX; ++i )
{
std::string name = fmt::format( "{}#{}", aProposedName, i );
while( m_names.count( name ) )
name = fmt::format( "{}#{}", aProposedName, ii++ );
if( !m_names.count( name ) )
return name;
}
// Should never happen.
THROW_IO_ERROR( wxString::Format( _( "Failed to generate a name for '%s': exceeded UINT64_MAX" ),
aProposedName ) );
return name;
}
@@ -126,8 +119,7 @@ bool NETLIST_EXPORTER_SPICE::DoWriteNetlist( OUTPUTFORMATTER& aFormatter, unsign
// Cleanup list to avoid duplicate if the netlist exporter is run more than once.
m_rawIncludes.clear();
if( !ReadSchematicAndLibraries( aNetlistOptions, aReporter ) )
return false;
bool result = ReadSchematicAndLibraries( aNetlistOptions, aReporter );
WriteHead( aFormatter, aNetlistOptions );
@@ -142,7 +134,7 @@ bool NETLIST_EXPORTER_SPICE::DoWriteNetlist( OUTPUTFORMATTER& aFormatter, unsign
WriteTail( aFormatter, aNetlistOptions );
return true;
return result;
}
@@ -165,6 +157,8 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
std::set<std::string> refNames; // Set of reference names to check for duplication.
int ncCounter = 1;
m_libMgr.SetReporter( &aReporter );
ReadDirectives( aNetlistOptions );
m_nets.clear();
@@ -240,50 +234,19 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
wxString modelParams;
wxString pinMap;
// JEY TODO: readModel() below will also do the inference, so I don't think this
// accomplishes anything....
// Infer RLC and VI models if they aren't specified
if( SIM_MODEL::InferSimModel( *symbol, &spiceItem.fields, true,
SIM_VALUE_GRAMMAR::NOTATION::SPICE, &deviceType,
&modelType, &modelParams, &pinMap ) )
{
spiceItem.fields.emplace_back( symbol, -1, SIM_DEVICE_TYPE_FIELD );
spiceItem.fields.back().SetText( deviceType );
readRefName( sheet, *symbol, spiceItem, refNames );
readModel( sheet, *symbol, spiceItem );
readPinNumbers( *symbol, spiceItem, pins );
readPinNetNames( *symbol, spiceItem, pins, ncCounter );
if( !modelType.IsEmpty() )
{
spiceItem.fields.emplace_back( symbol, -1, SIM_TYPE_FIELD );
spiceItem.fields.back().SetText( modelType );
}
// TODO: transmission line handling?
spiceItem.fields.emplace_back( symbol, -1, SIM_PARAMS_FIELD );
spiceItem.fields.back().SetText( modelParams );
spiceItem.fields.emplace_back( symbol, -1, SIM_PINS_FIELD );
spiceItem.fields.back().SetText( pinMap );
}
try
{
readRefName( sheet, *symbol, spiceItem, refNames );
readModel( sheet, *symbol, spiceItem );
readPinNumbers( *symbol, spiceItem, pins );
readPinNetNames( *symbol, spiceItem, pins, ncCounter );
// TODO: transmission line handling?
m_items.push_back( std::move( spiceItem ) );
}
catch( const IO_ERROR& e )
{
msg.Printf( _( "Error reading simulation model from symbol '%s':\n%s" ),
symbol->GetRef( &sheet ),
e.Problem() );
aReporter.Report( msg, RPT_SEVERITY_ERROR );
}
m_items.push_back( std::move( spiceItem ) );
}
}
m_libMgr.SetReporter( nullptr );
return !aReporter.HasMessage();
}
@@ -403,6 +366,7 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions )
|| isDirective( line, wxS( ".CONTROL" ) )
|| isDirective( line, wxS( ".CSPARAM" ) )
|| isDirective( line, wxS( ".DISTO" ) )
|| isDirective( line, wxS( ".DC" ) )
|| isDirective( line, wxS( ".ELSE" ) )
|| isDirective( line, wxS( ".ELSEIF" ) )
|| isDirective( line, wxS( ".END" ) )
@@ -594,7 +558,7 @@ void NETLIST_EXPORTER_SPICE::writeInclude( OUTPUTFORMATTER& aFormatter, unsigned
void NETLIST_EXPORTER_SPICE::writeIncludes( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
{
for( auto& [path, library] : m_libMgr.GetLibraries() )
for( const auto& [path, library] : m_libMgr.GetLibraries() )
{
if( dynamic_cast<const SIM_LIBRARY_SPICE*>( &library.get() ) )
writeInclude( aFormatter, aNetlistOptions, path );
-5
View File
@@ -185,11 +185,6 @@ public:
wxString VectorPrefix() const { return m_vector_prefix; }
std::vector< std::shared_ptr< SCH_CONNECTION > >& Members()
{
return m_members;
}
const std::vector< std::shared_ptr< SCH_CONNECTION > >& Members() const
{
return m_members;
+22 -8
View File
@@ -647,6 +647,14 @@ SCHEMATIC& SCH_EDIT_FRAME::Schematic() const
wxString SCH_EDIT_FRAME::GetScreenDesc() const
{
wxString s = GetCurrentSheet().Last()->GetName();
return s;
}
wxString SCH_EDIT_FRAME::GetFullScreenDesc() const
{
wxString s = GetCurrentSheet().PathHumanReadable();
@@ -814,8 +822,6 @@ void SCH_EDIT_FRAME::doCloseWindow()
if( m_toolManager )
m_toolManager->ShutdownAllTools();
RecordERCExclusions();
// Close the find dialog and preserve its setting if it is displayed.
if( m_findReplaceDialog )
{
@@ -834,9 +840,6 @@ void SCH_EDIT_FRAME::doCloseWindow()
m_auimgr.Update();
}
if( Kiway().Player( FRAME_SIMULATOR, false ) )
Prj().GetProjectFile().m_SchematicSettings->m_NgspiceSimulatorSettings->SaveToFile();
SCH_SCREENS screens( Schematic().Root() );
wxFileName fn;
@@ -865,7 +868,7 @@ void SCH_EDIT_FRAME::doCloseWindow()
UpdateFileHistory( fileName );
// Make sure local settings are persisted
SaveProjectSettings();
SaveProjectLocalSettings();
Schematic().RootScreen()->Clear();
@@ -1823,13 +1826,19 @@ void SCH_EDIT_FRAME::UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete, bool aUpda
void SCH_EDIT_FRAME::DisplayCurrentSheet()
{
wxCHECK( m_toolManager, /* void */ );
m_toolManager->RunAction( ACTIONS::cancelInteractive, true );
m_toolManager->RunAction( EE_ACTIONS::clearSelection, true );
SCH_SCREEN* screen = GetCurrentSheet().LastScreen();
wxASSERT( screen );
wxCHECK( screen, /* void */ );
SetScreen( screen );
m_toolManager->RunAction( EE_ACTIONS::clearSelection, true );
SCH_BASE_FRAME::SetScreen( screen );
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
// update the References
GetCurrentSheet().UpdateAllScreenReferences();
@@ -1837,6 +1846,8 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet()
EE_SELECTION_TOOL* selectionTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
wxCHECK( selectionTool, /* void */ );
auto visit =
[&]( EDA_ITEM* item )
{
@@ -1881,6 +1892,9 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet()
HardRedraw(); // Ensure all items are redrawn (especially the drawing-sheet items)
SCH_EDITOR_CONTROL* editTool = m_toolManager->GetTool<SCH_EDITOR_CONTROL>();
wxCHECK( editTool, /* void */ );
TOOL_EVENT dummy;
editTool->UpdateNetHighlighting( dummy );
+4 -1
View File
@@ -114,7 +114,7 @@ public:
/**
* Save changes to the project settings to the project (.pro) file.
*/
void SaveProjectSettings() override;
void SaveProjectLocalSettings() override;
/**
* Load the KiCad project file (*.pro) settings specific to Eeschema.
@@ -164,6 +164,7 @@ public:
* Return a human-readable description of the current screen.
*/
wxString GetScreenDesc() const override;
wxString GetFullScreenDesc() const override;
/**
* Execute a remote command sent by Pcbnew via a socket connection.
@@ -835,6 +836,8 @@ protected:
void onSize( wxSizeEvent& aEvent );
void saveProjectSettings() override;
private:
// Called when resizing the Hierarchy Navigator panel
void OnResizeHierarchyNavigator( wxSizeEvent& aEvent );
+15
View File
@@ -290,6 +290,21 @@ VECTOR2I SCH_LABEL_BASE::GetSchematicTextOffset( const RENDER_SETTINGS* aSetting
return text_offset;
}
void SCH_LABEL_BASE::SetPosition( const VECTOR2I& aPosition )
{
VECTOR2I offset = aPosition - GetTextPos();
Move( offset );
}
void SCH_LABEL_BASE::Move( const VECTOR2I& aMoveVector )
{
SCH_TEXT::Move( aMoveVector );
for( SCH_FIELD& field : m_fields )
field.Offset( aMoveVector );
}
void SCH_LABEL_BASE::Rotate( const VECTOR2I& aCenter )
{
+8 -8
View File
@@ -100,6 +100,11 @@ public:
m_fields = aFields; // vector copying, length is changed possibly
}
void AddFields( const std::vector<SCH_FIELD>& aFields )
{
m_fields.insert( m_fields.end(), aFields.begin(), aFields.end() );
}
/**
* Increment the label text, if it ends with a number.
*
@@ -107,17 +112,12 @@ public:
*/
bool IncrementLabel( int aIncrement );
void Move( const VECTOR2I& aMoveVector ) override
{
SCH_TEXT::Move( aMoveVector );
for( SCH_FIELD& field : m_fields )
field.Offset( aMoveVector );
}
void Move( const VECTOR2I& aMoveVector ) override;
void Rotate( const VECTOR2I& aCenter ) override;
void Rotate90( bool aClockwise ) override;
void SetPosition( const VECTOR2I& aPosition ) override;
void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) override;
/**
+1 -1
View File
@@ -872,7 +872,7 @@ void SCH_LINE::Plot( PLOTTER* aPlotter, bool aBackground ) const
{
if( SCH_CONNECTION* connection = Connection() )
{
for( std::shared_ptr<SCH_CONNECTION>& member : connection->Members() )
for( const std::shared_ptr<SCH_CONNECTION>& member : connection->Members() )
properties.emplace_back( wxT( "!" ) + member->Name() );
}
@@ -551,14 +551,14 @@ void CADSTAR_SCH_ARCHIVE_PARSER::TERMATTR::Parse( XNODE* aNode, PARSER_CONTEXT*
TerminalID = GetXmlAttributeIDLong( aNode, 0 );
XNODE* cNode = aNode->GetChildren();
bool attrParsed = false;
for( ; cNode; cNode = cNode->GetNext() )
{
if( !attrParsed && cNode->GetName() == wxT( "ATTR" ) )
if( cNode->GetName() == wxT( "ATTR" ) )
{
Value.Parse( cNode, aContext );
attrParsed = true;
ATTRIBUTE_VALUE val;
val.Parse( cNode, aContext );
Attributes.push_back( val );
}
else
{
@@ -206,8 +206,8 @@ public:
struct TERMATTR : PARSER
{
TERMINAL_ID TerminalID;
ATTRIBUTE_VALUE Value;
TERMINAL_ID TerminalID;
std::vector<ATTRIBUTE_VALUE> Attributes;
void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override;
};
@@ -292,6 +292,55 @@ void SCH_DATABASE_PLUGIN::ensureConnection()
}
std::optional<bool> SCH_DATABASE_PLUGIN::boolFromAny( const std::any& aVal )
{
try
{
bool val = std::any_cast<bool>( aVal );
return val;
}
catch( const std::bad_any_cast& )
{
}
try
{
int val = std::any_cast<int>( aVal );
return static_cast<bool>( val );
}
catch( const std::bad_any_cast& )
{
}
try
{
wxString strval( std::any_cast<std::string>( aVal ).c_str(), wxConvUTF8 );
if( strval.IsEmpty() )
return std::nullopt;
strval.MakeLower();
for( const auto& trueVal : { wxS( "true" ), wxS( "yes" ), wxS( "y" ), wxS( "1" ) } )
{
if( strval.Matches( trueVal ) )
return true;
}
for( const auto& falseVal : { wxS( "false" ), wxS( "no" ), wxS( "n" ), wxS( "0" ) } )
{
if( strval.Matches( falseVal ) )
return false;
}
}
catch( const std::bad_any_cast& )
{
}
return std::nullopt;
}
LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
const DATABASE_LIB_TABLE& aTable,
const DATABASE_CONNECTION::ROW& aRow )
@@ -300,12 +349,15 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
if( aRow.count( aTable.symbols_col ) )
{
LIB_SYMBOL* originalSymbol = nullptr;
// TODO: Support multiple options for symbol
std::string symbolIdStr = std::any_cast<std::string>( aRow.at( aTable.symbols_col ) );
LIB_ID symbolId;
symbolId.Parse( std::any_cast<std::string>( aRow.at( aTable.symbols_col ) ) );
LIB_SYMBOL* originalSymbol = m_libTable->LoadSymbol( symbolId );
if( symbolId.IsValid() )
originalSymbol = m_libTable->LoadSymbol( symbolId );
if( originalSymbol )
{
@@ -314,6 +366,11 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
symbol = originalSymbol->Duplicate();
symbol->SetSourceLibId( symbolId );
}
else if( !symbolId.IsValid() )
{
wxLogTrace( traceDatabase, wxT( "loadSymboFromRow: source symbol id '%s' is invalid, "
"will create empty symbol" ), symbolIdStr );
}
else
{
wxLogTrace( traceDatabase, wxT( "loadSymboFromRow: source symbol '%s' not found, "
@@ -376,15 +433,33 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
if( !aTable.properties.exclude_from_board.empty()
&& aRow.count( aTable.properties.exclude_from_board ) )
{
bool exclude = std::any_cast<bool>( aRow.at( aTable.properties.exclude_from_board ) );
symbol->SetIncludeOnBoard( !exclude );
std::optional<bool> val = boolFromAny( aRow.at( aTable.properties.exclude_from_board ) );
if( val )
{
symbol->SetIncludeOnBoard( !( *val ) );
}
else
{
wxLogTrace( traceDatabase, wxT( "loadSymbolFromRow: exclude_from_board value for %s "
"could not be cast to a boolean" ), aSymbolName );
}
}
if( !aTable.properties.exclude_from_bom.empty()
&& aRow.count( aTable.properties.exclude_from_bom ) )
{
bool exclude = std::any_cast<bool>( aRow.at( aTable.properties.exclude_from_bom ) );
symbol->SetIncludeInBom( !exclude );
std::optional<bool> val = boolFromAny( aRow.at( aTable.properties.exclude_from_bom ) );
if( val )
{
symbol->SetIncludeInBom( !( *val ) );
}
else
{
wxLogTrace( traceDatabase, wxT( "loadSymbolFromRow: exclude_from_bom value for %s "
"could not be cast to a boolean" ), aSymbolName );
}
}
std::vector<LIB_FIELD*> fields;
@@ -399,7 +474,7 @@ LIB_SYMBOL* SCH_DATABASE_PLUGIN::loadSymbolFromRow( const wxString& aSymbolName,
{
if( !aRow.count( mapping.column ) )
{
wxLogTrace( traceDatabase, wxT( "loadSymboFromRow: field %s not found in result" ),
wxLogTrace( traceDatabase, wxT( "loadSymbolFromRow: field %s not found in result" ),
mapping.column );
continue;
}
@@ -103,6 +103,8 @@ private:
const DATABASE_LIB_TABLE& aTable,
const DATABASE_CONNECTION::ROW& aRow );
static std::optional<bool> boolFromAny( const std::any& aVal );
SYMBOL_LIB_TABLE* m_libTable;
std::unique_ptr<DATABASE_LIB_SETTINGS> m_settings;
@@ -61,6 +61,7 @@
#include <progress_reporter.h>
#include <sch_shape.h>
using namespace TSCHEMATIC_T;
@@ -1948,7 +1949,6 @@ SCH_FIELD* SCH_SEXPR_PARSER::parseSchField( SCH_ITEM* aParent )
std::unique_ptr<SCH_FIELD> field = std::make_unique<SCH_FIELD>( wxDefaultPosition, -1,
aParent, name );
field->SetText( value );
field->SetVisible( true );
@@ -3853,6 +3853,10 @@ SCH_TEXT* SCH_SEXPR_PARSER::parseSchText()
|| field->GetInternalName() == wxT( "Intersheetrefs" ) ) ) // Current name
{
SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( text.get() );
// Ensure the Id of this special and first field is 0, needed by
// SCH_FIELD::IsHypertext() test
field->SetId( 0 );
label->GetFields()[0] = *field;
}
else
+2 -2
View File
@@ -398,7 +398,7 @@ bool SCH_SHEET::HasPin( const wxString& aName ) const
{
for( SCH_SHEET_PIN* pin : m_pins )
{
if( pin->GetText().CmpNoCase( aName ) == 0 )
if( pin->GetText().Cmp( aName ) == 0 )
return true;
}
@@ -448,7 +448,7 @@ bool SCH_SHEET::HasUndefinedPins() const
for( SCH_ITEM* aItem : m_screen->Items().OfType( SCH_HIER_LABEL_T ) )
{
if( !pin->GetText().CmpNoCase( static_cast<SCH_HIERLABEL*>( aItem )->GetText() ) )
if( !pin->GetText().Cmp( static_cast<SCH_HIERLABEL*>( aItem )->GetText() ) )
{
HLabel = static_cast<SCH_HIERLABEL*>( aItem );
break;
+27
View File
@@ -1095,6 +1095,14 @@ void SCH_SYMBOL::SwapData( SCH_ITEM* aItem )
std::swap( m_lib_id, symbol->m_lib_id );
m_pins.swap( symbol->m_pins ); // std::vector's swap()
for( std::unique_ptr<SCH_PIN>& pin : symbol->m_pins )
pin->SetParent( symbol );
for( std::unique_ptr<SCH_PIN>& pin : m_pins )
pin->SetParent( this );
LIB_SYMBOL* libSymbol = symbol->m_part.release();
symbol->m_part = std::move( m_part );
symbol->UpdatePins();
@@ -2271,3 +2279,22 @@ bool SCH_SYMBOL::IsPointClickableAnchor( const VECTOR2I& aPos ) const
return false;
}
bool SCH_SYMBOL::IsSymbolLikePowerGlobalLabel() const
{
// return true if the symbol is equivalent to a global label:
// It is a Power symbol
// It has only one pin type Power input
if( !GetLibSymbolRef() || !GetLibSymbolRef()->IsPower() )
return false;
std::vector<LIB_PIN*> pin_list = GetAllLibPins();
if( pin_list.size() != 1 )
return false;
return pin_list[0]->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN;
}
+7
View File
@@ -755,6 +755,13 @@ public:
bool IsPointClickableAnchor( const VECTOR2I& aPos ) const override;
/**
* @return true if the symbol is equivalent to a global label:
* It is a Power symbol
* It has only one pin type Power input
*/
bool IsSymbolLikePowerGlobalLabel() const;
private:
BOX2I doGetBoundingBox( bool aIncludePins, bool aIncludeFields ) const;
+35 -49
View File
@@ -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-2021 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
@@ -60,8 +60,7 @@ SCH_FIELD_VALIDATOR::SCH_FIELD_VALIDATOR( bool aIsLibEditor, int aFieldId, wxSt
// The reference, sheetname and sheetfilename fields cannot be empty.
if( aFieldId == REFERENCE_FIELD
|| aFieldId == SHEETNAME_V
|| aFieldId == SHEETFILENAME_V
|| aFieldId == FIELD_NAME )
|| aFieldId == SHEETFILENAME_V )
{
style |= wxFILTER_EMPTY;
}
@@ -91,54 +90,12 @@ bool SCH_FIELD_VALIDATOR::Validate( wxWindow* aParent )
return false;
wxString val( text->GetValue() );
// The format of the error message for not allowed chars
wxString fieldCharError;
switch( m_fieldId )
{
case REFERENCE_FIELD:
fieldCharError = _( "The reference designator cannot contain %s character(s)." );
break;
case VALUE_FIELD:
fieldCharError = _( "The value field cannot contain %s character(s)." );
break;
case FOOTPRINT_FIELD:
fieldCharError = _( "The footprint field cannot contain %s character(s)." );
break;
case DATASHEET_FIELD:
fieldCharError = _( "The datasheet field cannot contain %s character(s)." );
break;
case SHEETNAME_V:
fieldCharError = _( "The sheet name cannot contain %s character(s)." );
break;
case SHEETFILENAME_V:
fieldCharError = _( "The sheet filename cannot contain %s character(s)." );
break;
default:
fieldCharError = _( "The field cannot contain %s character(s)." );
break;
};
wxString msg;
// We can only do some kinds of validation once the input is complete, so
// check for them here:
if( HasFlag( wxFILTER_EMPTY ) && val.empty() )
{
// Some fields cannot have an empty value, and user fields require a name:
if( m_fieldId == FIELD_NAME )
msg.Printf( _( "The name of the field cannot be empty." ) );
else // the FIELD_VALUE id or REFERENCE_FIELD or VALUE_FIELD
msg.Printf( _( "The value of the field cannot be empty." ) );
}
else if( HasFlag( wxFILTER_EXCLUDE_CHAR_LIST ) && ContainsExcludedCharacters( val ) )
msg.Printf( _( "The value of the field cannot be empty." ) );
if( HasFlag( wxFILTER_EXCLUDE_CHAR_LIST ) && ContainsExcludedCharacters( val ) )
{
wxArrayString badCharsFound;
@@ -200,7 +157,36 @@ bool SCH_FIELD_VALIDATOR::Validate( wxWindow* aParent )
badChars += badCharsFound.Item( i );
}
msg.Printf( fieldCharError, badChars );
switch( m_fieldId )
{
case REFERENCE_FIELD:
msg.Printf( _( "The reference designator cannot contain %s character(s)." ), badChars );
break;
case VALUE_FIELD:
msg.Printf( _( "The value field cannot contain %s character(s)." ), badChars );
break;
case FOOTPRINT_FIELD:
msg.Printf( _( "The footprint field cannot contain %s character(s)." ), badChars );
break;
case DATASHEET_FIELD:
msg.Printf( _( "The datasheet field cannot contain %s character(s)." ), badChars );
break;
case SHEETNAME_V:
msg.Printf( _( "The sheet name cannot contain %s character(s)." ), badChars );
break;
case SHEETFILENAME_V:
msg.Printf( _( "The sheet filename cannot contain %s character(s)." ), badChars );
break;
default:
msg.Printf( _( "The field cannot contain %s character(s)." ), badChars );
break;
};
}
else if( m_fieldId == REFERENCE_FIELD && val.Contains( wxT( "${" ) ) )
{
+2 -4
View File
@@ -113,10 +113,8 @@ void SCH_VIEW::DisplaySheet( const SCH_SCREEN *aScreen )
wxCHECK( editFrame, /* void */ );
wxString sheetName = editFrame->GetCurrentSheet().Last()->GetName();
wxString sheetPath = editFrame->GetCurrentSheet().PathHumanReadable();
m_drawingSheet->SetSheetName( TO_UTF8( sheetName ) );
m_drawingSheet->SetSheetPath( TO_UTF8( sheetPath ) );
m_drawingSheet->SetSheetName( TO_UTF8( editFrame->GetScreenDesc() ) );
m_drawingSheet->SetSheetPath( TO_UTF8( editFrame->GetFullScreenDesc() ) );
}
else
{
+13 -6
View File
@@ -33,17 +33,24 @@
SIM_PLOT_TYPE NGSPICE_CIRCUIT_MODEL::VectorToSignal( const std::string& aVector,
wxString& aSignal ) const
{
using namespace std;
static wxString BRANCH( wxS( "#branch" ) );
// See ngspice manual chapt. 31.1 "Accessing internal device parameters"
wxRegEx internalDevParameter( "^@(\\w*[\\.\\w+]*)\\[(\\w*)\\]$", wxRE_ADVANCED );
static wxRegEx internalDevParameter( wxS( "^@(\\w*[\\.\\w+]*)\\[(\\w*)\\]$" ), wxRE_ADVANCED );
wxString vector( aVector );
if( !internalDevParameter.Matches( vector ) )
{
// any text is a node name, which returns voltage
aSignal = wxT( "V(" ) + aVector + wxT( ")" );
return SPT_VOLTAGE;
if( vector.EndsWith( BRANCH ) )
{
aSignal = wxT( "I(" ) + vector.Left( vector.Length() - BRANCH.Length() ) + wxT( ")" );
return SPT_CURRENT;
}
else
{
aSignal = wxT( "V(" ) + vector + wxT( ")" );
return SPT_VOLTAGE;
}
}
else
{
+1 -1
View File
@@ -49,7 +49,7 @@ void SIM_LIBRARY_KIBIS::ReadFile( const std::string& aFilePath, REPORTER* aRepor
for( KIBIS_COMPONENT& kcomp : m_kibis.m_components )
{
m_models.push_back( SIM_MODEL::Create( SIM_MODEL::TYPE::KIBIS_DEVICE, pins, nullptr ) );
m_models.push_back( SIM_MODEL::Create( SIM_MODEL::TYPE::KIBIS_DEVICE, pins, aReporter ) );
m_modelNames.emplace_back( kcomp.m_name );
SIM_MODEL_KIBIS* libcomp = dynamic_cast<SIM_MODEL_KIBIS*>( m_models.back().get() );
+79 -42
View File
@@ -361,11 +361,13 @@ SIM_MODEL::SPICE_INFO SIM_MODEL::SpiceInfo( TYPE aType )
}
template TYPE SIM_MODEL::ReadTypeFromFields( const std::vector<SCH_FIELD>& aFields );
template TYPE SIM_MODEL::ReadTypeFromFields( const std::vector<LIB_FIELD>& aFields );
template TYPE SIM_MODEL::ReadTypeFromFields( const std::vector<SCH_FIELD>& aFields,
REPORTER* aReporter );
template TYPE SIM_MODEL::ReadTypeFromFields( const std::vector<LIB_FIELD>& aFields,
REPORTER* aReporter );
template <typename T>
TYPE SIM_MODEL::ReadTypeFromFields( const std::vector<T>& aFields )
TYPE SIM_MODEL::ReadTypeFromFields( const std::vector<T>& aFields, REPORTER* aReporter )
{
std::string deviceTypeFieldValue = GetFieldValue( &aFields, SIM_DEVICE_TYPE_FIELD );
std::string typeFieldValue = GetFieldValue( &aFields, SIM_TYPE_FIELD );
@@ -392,6 +394,17 @@ TYPE SIM_MODEL::ReadTypeFromFields( const std::vector<T>& aFields )
if( typeFromLegacyFields != TYPE::NONE )
return typeFromLegacyFields;
if( aReporter )
{
if( aFields.size() > REFERENCE_FIELD )
{
aReporter->Report( wxString::Format( _( "Error reading simulation model from symbol '%s':\n%s" ),
aFields[REFERENCE_FIELD].GetText(),
_( "Failed to read simulation model from fields." ) ),
RPT_SEVERITY_ERROR );
}
}
return TYPE::NONE;
}
@@ -506,36 +519,46 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL* aBaseModel,
const std::vector<T>& aFields,
REPORTER* aReporter )
{
TYPE type = ReadTypeFromFields( aFields );
std::unique_ptr<SIM_MODEL> model;
TYPE type;
// If the model has a specified type, it takes priority over the type of its base class.
if( type == TYPE::NONE && aBaseModel )
if( aBaseModel )
{
type = aBaseModel->GetType();
std::unique_ptr<SIM_MODEL> model;
// No REPORTER here; we're just checking to see if we have an override
if( ReadTypeFromFields( aFields, nullptr ) != TYPE::NONE )
type = ReadTypeFromFields( aFields, nullptr );
// A null base model means the model wasn't found in the library, so create a fallback
if( dynamic_cast<const SIM_MODEL_SPICE_FALLBACK*>( aBaseModel ) )
model = std::make_unique<SIM_MODEL_SPICE_FALLBACK>( type );
else if( dynamic_cast< const SIM_MODEL_RAW_SPICE*>( aBaseModel ) )
model = std::make_unique<SIM_MODEL_RAW_SPICE>();
else
model = Create( type );
if( !aBaseModel || dynamic_cast<const SIM_MODEL_SPICE_FALLBACK*>( aBaseModel ) )
model->SetBaseModel( *aBaseModel );
}
else // No base model means the model wasn't found in the library, so create a fallback
{
type = ReadTypeFromFields( aFields, aReporter );
model = std::make_unique<SIM_MODEL_SPICE_FALLBACK>( type );
else if( dynamic_cast< const SIM_MODEL_RAW_SPICE*>( aBaseModel ) )
model = std::make_unique<SIM_MODEL_RAW_SPICE>();
else
model = Create( type );
}
try
{
if( aBaseModel )
model->SetBaseModel( *aBaseModel );
model->ReadDataFields( &aFields, aPins );
}
catch( IO_ERROR& err )
{
if( aReporter )
aReporter->Report( err.What(), RPT_SEVERITY_ERROR );
else
DisplayErrorMessage( nullptr, err.What() );
{
aReporter->Report( wxString::Format( _( "Error reading simulation model from "
"symbol '%s':\n%s" ),
aFields[REFERENCE_FIELD].GetText(),
err.Problem() ),
RPT_SEVERITY_ERROR );
}
}
return model;
@@ -557,7 +580,7 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const std::vector<T>& aFields,
const std::vector<LIB_PIN*>& aPins,
bool aResolved, REPORTER* aReporter )
{
TYPE type = ReadTypeFromFields( aFields );
TYPE type = ReadTypeFromFields( aFields, aReporter );
std::unique_ptr<SIM_MODEL> model = SIM_MODEL::Create( type );
try
@@ -589,11 +612,15 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const std::vector<T>& aFields,
}
catch( const IO_ERROR& err )
{
// We own the pin syntax, so if we can't parse it then there's an error, full stop.
// We own the pin syntax, so if we can't parse it then there's an error.
if( aReporter )
aReporter->Report( err.Problem(), RPT_SEVERITY_ERROR );
else
THROW_IO_ERROR( err.Problem() );
{
aReporter->Report( wxString::Format( _( "Error reading simulation model from "
"symbol '%s':\n%s" ),
aFields[REFERENCE_FIELD].GetText(),
err.Problem() ),
RPT_SEVERITY_ERROR );
}
}
}
@@ -726,21 +753,8 @@ void SIM_MODEL::AddParam( const PARAM::INFO& aInfo )
void SIM_MODEL::SetBaseModel( const SIM_MODEL& aBaseModel )
{
auto describe =
[]( const SIM_MODEL* aModel )
{
return fmt::format( "{} ({})",
aModel->GetDeviceInfo().fieldValue,
aModel->GetTypeInfo().description );
};
if( GetType() != aBaseModel.GetType() )
{
THROW_IO_ERROR( wxString::Format( _( "Simulation model type must be the same as of its "
"base class: '%s', but is '%s'" ),
describe( &aBaseModel ),
describe( this ) ) );
}
wxASSERT_MSG( GetType() == aBaseModel.GetType(),
wxS( "Simulation model type must be the same as its base class!" ) );
m_baseModel = &aBaseModel;
}
@@ -1079,6 +1093,9 @@ bool SIM_MODEL::requiresSpiceModelLine( const SPICE_ITEM& aItem ) const
continue;
const SIM_MODEL* baseModel = dynamic_cast<const SIM_MODEL*>( m_baseModel );
wxCHECK( baseModel, false );
std::string baseValue = baseModel->m_params[ii].value;
if( param.value == baseValue )
@@ -1647,7 +1664,7 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
}
else
{
for( unsigned ii = 0; ii < pinIndexes.size(); ++ii )
for( unsigned ii = 0; ii < pinIndexes.size() && ii < sourcePins.size(); ++ii )
{
if( ii > 0 )
pinMap.Append( wxS( " " ) );
@@ -1673,6 +1690,7 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
wxString spiceDeviceType = spiceDeviceInfo.m_Text.Trim( true ).Trim( false );
wxString spiceLib = spiceLibInfo.m_Text.Trim( true ).Trim( false );
wxString spiceModel = spiceModelInfo.m_Text.Trim( true ).Trim( false );
wxString modelLineParams;
bool libraryModel = false;
bool inferredModel = false;
@@ -1685,6 +1703,10 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
SIM_LIB_MGR libMgr( aProject, &reporter );
std::vector<T_field> emptyFields;
// Pull out any following parameters from model name
spiceModel = spiceModel.BeforeFirst( ' ', &modelLineParams );
spiceModelInfo.m_Text = spiceModel;
SIM_LIBRARY::MODEL model = libMgr.CreateModel( spiceLib, spiceModel.ToStdString(),
emptyFields, sourcePins );
@@ -1734,6 +1756,7 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
if( spiceTypeInfo.m_Text == wxT( "DC" ) && tokenizer.CountTokens() == 1 )
{
wxCHECK( valueField, /* void */ );
valueField->SetText( tokenizer.GetNextToken() );
modelFromValueField = false;
}
@@ -1779,9 +1802,23 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
T_field nameField = spiceModelInfo.CreateField( &aSymbol, SIM_NAME_FIELD );
aSymbol.AddField( nameField );
// Don't write a paramsField unless we actually have overrides
if( !spiceParamsInfo.IsEmpty() )
if( !modelLineParams.IsEmpty() )
{
spiceParamsInfo = spiceModelInfo;
spiceParamsInfo.m_Pos.x += nameField.GetBoundingBox().GetWidth();
spiceParamsInfo.m_Text = modelLineParams;
BOX2I nameBBox = nameField.GetBoundingBox();
int nameWidth = nameBBox.GetWidth();
// Add space between model name and additional parameters
nameWidth += KiROUND( nameBBox.GetHeight() * 1.25 );
if( nameField.GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
spiceParamsInfo.m_Pos.x -= nameWidth;
else
spiceParamsInfo.m_Pos.x += nameWidth;
T_field paramsField = spiceParamsInfo.CreateField( &aSymbol, SIM_PARAMS_FIELD );
aSymbol.AddField( paramsField );
}
+1 -1
View File
@@ -384,7 +384,7 @@ public:
template <typename T>
static TYPE ReadTypeFromFields( const std::vector<T>& aFields );
static TYPE ReadTypeFromFields( const std::vector<T>& aFields, REPORTER* aReporter );
template <typename T>
static TYPE InferTypeFromLegacyFields( const std::vector<T>& aFields );
+14 -3
View File
@@ -55,7 +55,6 @@ std::vector<std::string> SPICE_GENERATOR_NGSPICE::CurrentNames( const SPICE_ITEM
return SPICE_GENERATOR::CurrentNames( aItem );
default:
wxFAIL_MSG( "Unhandled model device type in SIM_MODEL_NGSPICE" );
return {};
}
}
@@ -68,9 +67,10 @@ SIM_MODEL_NGSPICE::SIM_MODEL_NGSPICE( TYPE aType ) :
for( const SIM_MODEL::PARAM::INFO& paramInfo : modelInfo.instanceParams )
{
// For now, only the geometry parameters.
// For now, only the geometry and flags parameters.
if( paramInfo.category == SIM_MODEL::PARAM::CATEGORY::PRINCIPAL
|| paramInfo.category == SIM_MODEL::PARAM::CATEGORY::GEOMETRY )
|| paramInfo.category == SIM_MODEL::PARAM::CATEGORY::GEOMETRY
|| paramInfo.category == SIM_MODEL::PARAM::CATEGORY::FLAGS )
{
AddParam( paramInfo );
}
@@ -211,6 +211,17 @@ bool SIM_MODEL_NGSPICE::canSilentlyIgnoreParam( const std::string& aParamName )
}
}
if( GetType() == TYPE::NMOS_VDMOS || GetType() == TYPE::PMOS_VDMOS )
{
// Ignore the purely informative LTspice-specific parameters "Vds", "Ron" and "Qg".
if( aParamName == "vds"
|| aParamName == "ron"
|| aParamName == "qg" )
{
return true;
}
}
return false;
}
+64 -57
View File
@@ -789,8 +789,8 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "pjf", 112, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "P type JFET model" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "vt0", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::DC, "-2", "-2", "Threshold voltage" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "vto", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "-2", "-2", "n.a." );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "beta", 102, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "A/V²", SIM_MODEL::PARAM::CATEGORY::DC, "0.0001", "0.0001", "Transconductance parameter" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "lambda", 103, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "1/V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Channel length modulation param." );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "beta", 102, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "A/V²", SIM_MODEL::PARAM::CATEGORY::DC, "0.0001", "0.0001", "Transconductance" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "lambda", 103, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "1/V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Channel length modulation coefficient" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "rd", 104, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "Ω", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Drain ohmic resistance" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "gd", 301, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Drain conductance" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "rs", 105, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "Ω", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Source ohmic resistance" );
@@ -799,19 +799,26 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "cgd", 107, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "G-D junction cap" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "pb", 108, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "Gate junction potential" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "is_", 109, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::DC, "1e-14", "1e-14", "Gate junction saturation current" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "fc", 110, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0.5", "0.5", "Forward bias junction fit parm." );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "fc", 110, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0.5", "0.5", "Forward bias junction fit parameter" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "b", 114, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "Doping tail parameter" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "tnom", 113, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "°C", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "27", "27", "parameter measurement temperature" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "tcv", 115, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "0", "0", "Threshold voltage temperature coefficient" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "vtotc", 116, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "0", "0", "Threshold voltage temperature coefficient alternative" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "tnom", 113, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "°C", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "27", "27", "Measurement temperature" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "tcv", 115, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V°C", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "0", "0", "Threshold voltage temperature coefficient" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "vtotc", 116, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V/°C", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "0", "0", "Threshold voltage temperature coefficient alternate" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "bex", 117, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "0", "0", "Mobility temperature exponent" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "betatce", 118, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "%/°C", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "0", "0", "Mobility temperature exponent alternative" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "betatce", 118, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "%/°C", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "0", "0", "Mobility temperature exponent alternate" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "xti", 119, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "3", "3", "Gate junction saturation current temperature exponent" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "eg", 120, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::DC, "1.11", "1.11", "Bandgap voltage" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "kf", 121, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::NOISE, "0", "0", "Flicker Noise Coefficient" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "af", 122, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::NOISE, "1", "1", "Flicker Noise Exponent" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "nlev", 123, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::NOISE, "2", "2", "Noise equation selector" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "gdsnoi", 124, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::NOISE, "1", "1", "Channel noise coefficient" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "alpha", 401, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "1/V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Ionization coefficient" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "m_", 402, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0.5", "0.5", "Gate p-n grading coefficient" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "n", 403, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "Gate p-n emission coefficient" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "isr", 404, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Gate p-n recombination current" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "nr", 405, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "2", "2", "Gate p-n recombination current emission coefficient" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "vk", 406, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Ionization knee voltage" );
// Instance parameters
modelInfos[MODEL_TYPE::JFET].instanceParams.emplace_back( "off", 5, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_BOOL, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Device initially off", true );
modelInfos[MODEL_TYPE::JFET].instanceParams.emplace_back( "ic", 4, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT_VECTOR, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Initial VDS,VGS vector", true );
@@ -861,36 +868,36 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "hfg1", 117, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "hfg2", 118, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "mvst", 119, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "modulation index for subtreshold current" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "mxi", 120, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "saturation potential modulation parameter" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "fc", 121, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0.5", "0.5", "Forward bias junction fit parm." );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "ibd", 122, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Breakdown current of diode jnc" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "mxi", 120, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Saturation potential modulation" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "fc", 121, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0.5", "0.5", "Forward bias junction fit" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "ibd", 122, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Breakdown current of diode junction" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "is_", 123, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::DC, "1e-14", "1e-14", "Gate junction saturation current" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "kf", 124, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::NOISE, "0", "0", "Flicker Noise Coefficient" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "lambda", 125, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "1/V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Channel length modulation param." );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "lfgam", 126, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "drain feedback parameter" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "kf", 124, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::NOISE, "0", "0", "Flicker noise coefficient" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "lambda", 125, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "1/V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Channel length modulation" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "lfgam", 126, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Drain feedback coefficient" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "lfg1", 127, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "lfg2", 128, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "n", 129, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "gate junction ideality factor" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "n", 129, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "Gate junction ideality factor" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "p_", 130, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "2", "2", "Power law (triode region)" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "vbi", 131, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "Gate junction potential" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "pb", 131, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "1", "1", "n.a." );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "q", 132, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "2", "2", "Power Law (Saturated region)" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "q", 132, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "2", "2", "Power Law (saturated region)" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "rd", 133, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "ohm", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Drain ohmic resistance" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "rs", 134, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "ohm", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Source ohmic resistance" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "taud", 135, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "s", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Thermal relaxation time" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "taug", 136, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "s", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Drain feedback relaxation time" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "vbd", 137, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "Breakdown potential of diode jnc" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "ver", 139, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "version number of PS model" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "vst", 140, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Crit Poten subthreshold conductn" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "vst", 140, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Crit Poten subthreshold conduction" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "vt0", 141, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::DC, "-2", "-2", "Threshold voltage" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "vto", 141, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "-2", "-2", "n.a." );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "xc", 142, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "amount of cap. red at pinch-off" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "xi", 143, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "m/s", SIM_MODEL::PARAM::CATEGORY::DC, "1000", "1000", "velocity saturation index" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "z", 144, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "m/s", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "rate of velocity saturation" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "hfgam", 145, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "high freq drain feedback parm" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "xi", 143, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "m/s", SIM_MODEL::PARAM::CATEGORY::DC, "1000", "1000", "Velocity saturation index" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "z", 144, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "m/s", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "Rate of velocity saturation" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "hfgam", 145, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "High freq drain feedback" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "gd", 301, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Drain conductance" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "gs", 302, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Source conductance" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "tnom", 104, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "°C", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "27", "27", "parameter measurement temperature" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "tnom", 104, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "°C", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "27", "27", "Measurement temperature" );
// Instance parameters
modelInfos[MODEL_TYPE::JFET2].instanceParams.emplace_back( "off", 5, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_BOOL, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Device initially off", true );
modelInfos[MODEL_TYPE::JFET2].instanceParams.emplace_back( "ic", 4, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT_VECTOR, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Initial VDS,VGS vector", true );
@@ -1257,7 +1264,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::HFET2].instanceParams.emplace_back( "p", 8, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Power dissipated by the mesfet", true );
modelInfos[MODEL_TYPE::VDMOS] = { "VDMOS", "NCHAN", "PCHAN", { "D", "G", "S" }, "DMOS model based on Level 1 MOSFET model", {}, {} };
modelInfos[MODEL_TYPE::VDMOS] = { "VDMOS", "NCHAN", "PCHAN", { "D", "G", "S", "<TJ>", "<TCASE>" }, "DMOS model based on Level 1 MOSFET model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::VDMOS].modelParams.emplace_back( "type", 116, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_STRING, "", SIM_MODEL::PARAM::CATEGORY::DC, "vdmosn", "vdmosp", "N-channel or P-channel MOS" );
modelInfos[MODEL_TYPE::VDMOS].modelParams.emplace_back( "vto", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Threshold voltage" );
@@ -1329,42 +1336,42 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::VDMOS].modelParams.emplace_back( "rth_ext", 165, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "ohm", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "1000", "1000", "thermal resistance case to ambient, incl. heat sink" );
modelInfos[MODEL_TYPE::VDMOS].modelParams.emplace_back( "derating", 166, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "thermal derating for power" );
// Instance parameters
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "m", 9, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::GEOMETRY, "0.5", "0.5", "Multiplier" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "off", 1, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, "", SIM_MODEL::PARAM::CATEGORY::FLAGS, "", "", "Device initially off" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "icvds", 3, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Initial D-S voltage" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "icvgs", 4, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Initial G-S voltage" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "temp", 8, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "deg C", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Instance temperature" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "dtemp", 10, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "deg C", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Instance temperature difference" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "ic", 2, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_FLOAT_VECTOR, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Vector of D-S, G-S voltages" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "thermal", 11, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_BOOL, "", SIM_MODEL::PARAM::CATEGORY::FLAGS, "", "", "Thermal model switch on/off" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "id", 214, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain current" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "is", 6, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "1e-14", "1e-14", "Source current" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "ig", 5, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate current" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "vgs", 217, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Source voltage" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "vds", 218, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain-Source voltage" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cgs", 201, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "0", "0", "Gate-Source capacitance" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cgd", 202, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Drain capacitance" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cds", 203, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain-Source capacitance" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "idio", 223, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Body diode current" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "dnode", 204, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of the drain node" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "gnode", 205, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of the gate node" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "snode", 206, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of the source node" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "tempnode", 207, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of temperature node" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "tcasenode", 208, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of 2nd temperature node" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "dnodeprime", 209, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of int. drain node" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "snodeprime", 210, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of int. source node" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "von", 213, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Device on state voltage" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "rs", 224, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "ohm", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "0", "0", "Source resistance" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "sourceconductance", 211, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Conductance of source" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "rd", 225, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "0", "0", "Drain conductance" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "drainconductance", 212, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Conductance of drain" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "gm", 215, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Transconductance" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "gds", 216, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain-Source conductance" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cqgs", 220, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Capacitance due to gate-source charge storage" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cqgd", 222, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Capacitance due to gate-drain charge storage" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "qgs", 219, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Source charge storage" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "qgd", 221, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Drain charge storage" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "p", 7, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Instantaneous power" );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "m", 9, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::GEOMETRY, "0.5", "0.5", "Multiplier", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "off", 1, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, "", SIM_MODEL::PARAM::CATEGORY::FLAGS, "", "", "Device initially off", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "icvds", 3, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Initial D-S voltage", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "icvgs", 4, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Initial G-S voltage", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "temp", 8, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "deg C", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Instance temperature", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "dtemp", 10, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "deg C", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Instance temperature difference", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "ic", 2, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_FLOAT_VECTOR, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Vector of D-S, G-S voltages", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "thermal", 11, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_BOOL, "", SIM_MODEL::PARAM::CATEGORY::FLAGS, "", "", "Thermal model switch on/off", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "id", 214, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain current", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "is", 6, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "1e-14", "1e-14", "Source current", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "ig", 5, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate current", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "vgs", 217, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Source voltage", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "vds", 218, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain-Source voltage", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cgs", 201, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "0", "0", "Gate-Source capacitance", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cgd", 202, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Drain capacitance", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cds", 203, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain-Source capacitance", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "idio", 223, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Body diode current", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "dnode", 204, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of the drain node", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "gnode", 205, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of the gate node", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "snode", 206, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of the source node", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "tempnode", 207, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of temperature node", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "tcasenode", 208, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of 2nd temperature node", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "dnodeprime", 209, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of int. drain node", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "snodeprime", 210, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of int. source node", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "von", 213, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Device on state voltage", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "rs", 224, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "ohm", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "0", "0", "Source resistance", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "sourceconductance", 211, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Conductance of source", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "rd", 225, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "0", "0", "Drain conductance", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "drainconductance", 212, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Conductance of drain", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "gm", 215, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Transconductance", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "gds", 216, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain-Source conductance", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cqgs", 220, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Capacitance due to gate-source charge storage", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cqgd", 222, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Capacitance due to gate-drain charge storage", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "qgs", 219, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Source charge storage", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "qgd", 221, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Drain charge storage", true );
modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "p", 7, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Instantaneous power", true );
modelInfos[MODEL_TYPE::MOS1] = { "Mos1", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Level 1 MOSfet model with Meyer capacitance model", {}, {} };
+14 -1
View File
@@ -38,6 +38,7 @@ namespace SIM_MODEL_SERIALIZER_PARSER
template <typename Rule> struct fieldParamValuePairsSelector : std::false_type {};
template <> struct fieldParamValuePairsSelector<param> : std::true_type {};
template <> struct fieldParamValuePairsSelector<flagParam> : std::true_type {};
template <> struct fieldParamValuePairsSelector<quotedStringContent> : std::true_type {};
template <> struct fieldParamValuePairsSelector<unquotedString> : std::true_type {};
@@ -94,6 +95,9 @@ std::string SIM_MODEL_SERIALIZER::GenerateParams() const
continue;
}
if( m_model.GetBaseModel() && m_model.GetBaseModel()->GetParam( i ).value == param.value )
continue;
// If the parameter is an enum and the value is default, don't write anything.
if( param.info.enumValues.size() >= 1 && param.value == param.info.defaultValue )
continue;
@@ -235,6 +239,12 @@ bool SIM_MODEL_SERIALIZER::ParseParams( const std::string& aParams )
m_model.SetParamValue( paramName, str, SIM_VALUE_GRAMMAR::NOTATION::SI );
}
else if( node->is_type<SIM_MODEL_SERIALIZER_PARSER::flagParam>() )
{
std::string token = node->string();
m_model.SetParamValue( token, "1", SIM_VALUE_GRAMMAR::NOTATION::SI );
}
else
{
wxFAIL;
@@ -297,7 +307,10 @@ std::string SIM_MODEL_SERIALIZER::generateParamValuePair( const SIM_MODEL::PARAM
name = aParam.info.name.substr( 0, aParam.info.name.length() - 1 );
std::string value = aParam.value;
if( aParam.info.category == SIM_MODEL::PARAM::CATEGORY::FLAGS )
return value == "1" ? aParam.info.name : "";
if( value == "" || value.find( ' ' ) != std::string::npos )
value = fmt::format( "\"{}\"", value );
+12 -7
View File
@@ -54,7 +54,7 @@ namespace SIM_MODEL_SERIALIZER_GRAMMAR
opt<sep>,
tao::pegtl::eof> {};
struct param : plus<alnum> {};
struct param : identifier {};
struct unquotedString : plus<not_at<sep>, any> {};
struct quotedStringContent : star<not_at<one<'"'>>, any> {}; // TODO: Allow escaping '"'.
@@ -62,12 +62,17 @@ namespace SIM_MODEL_SERIALIZER_GRAMMAR
quotedStringContent,
one<'"'>> {};
struct fieldParamValuePair : if_must<param,
opt<sep>,
one<'='>,
opt<sep>,
sor<quotedString,
unquotedString>> {};
struct flagParam : sor<TAO_PEGTL_ISTRING( "off" ), // VDMOS
TAO_PEGTL_ISTRING( "thermal" ), // VDMOS
TAO_PEGTL_ISTRING( "xpart" )> {}; // BSIM1
struct fieldParamValuePair : sor<flagParam,
if_must<param,
opt<sep>,
one<'='>,
opt<sep>,
sor<quotedString,
unquotedString>>> {};
struct fieldParamValuePairs : list<fieldParamValuePair, sep> {};
struct fieldParamValuePairsGrammar : must<opt<sep>,
opt<fieldParamValuePairs>,
+3 -2
View File
@@ -291,7 +291,7 @@ void SIM_PLOT_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
project.m_SchematicSettings->m_NgspiceSimulatorSettings->SaveToFile();
if( m_schematicFrame )
m_schematicFrame->SaveProjectSettings();
m_schematicFrame->OnModify();
}
}
@@ -1069,7 +1069,8 @@ bool SIM_PLOT_FRAME::loadWorkbook( const wxString& aPath )
}
#endif
addPlot( name, (SIM_PLOT_TYPE) traceType );
if( traceType != SPT_UNKNOWN )
addPlot( name, (SIM_PLOT_TYPE) traceType );
}
}
+14
View File
@@ -105,6 +105,20 @@ public:
SetContinuity( true );
SetDrawOutsideMargins( false );
ShowName( false );
SetName( aName );
}
void SetName( const wxString& aName ) override
{
mpFXYVector::SetName( aName );
if( m_type & SPT_AC_MAG )
m_displayName = aName + _( " (mag)" );
else if( m_type & SPT_AC_PHASE )
m_displayName = aName + _( " (phase)" );
else
m_displayName = aName;
}
/**
+26 -6
View File
@@ -89,12 +89,24 @@ std::string SPICE_GENERATOR::ModelLine( const SPICE_ITEM& aItem ) const
if( value == "" )
continue;
result.append( fmt::format( "+{}{}={}\n",
std::string( indentLength - 1, ' ' ),
name,
value ) );
if( param.info.category == SIM_MODEL::PARAM::CATEGORY::FLAGS )
{
if( value == "1" )
result.append( fmt::format( "+{}\n", name ) );
}
else
{
result.append( fmt::format( "+{}{}={}\n",
std::string( indentLength - 1, ' ' ),
name,
value ) );
}
}
// Don't send SPICE empty models.
if( result.length() == indentLength + 1 /* line ending */ )
result.clear();
return result;
}
@@ -175,8 +187,16 @@ std::string SPICE_GENERATOR::ItemParams() const
: param.info.spiceInstanceName;
std::string value = SIM_VALUE::ToSpice( param.value );
if( value != "" )
result.append( fmt::format( " {}={}", name, value ) );
if( param.info.category == SIM_MODEL::PARAM::CATEGORY::FLAGS )
{
if( value == "1" )
result.append( fmt::format( " {}", name ) );
}
else
{
if( value != "" )
result.append( fmt::format( " {}={}", name, value ) );
}
}
return result;
+25 -5
View File
@@ -277,12 +277,32 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadTypeFromSpiceStrings( const std::string&
if( typePrefix == "" )
continue;
// Check if `aTypeString` starts with `typePrefix`.
if( boost::starts_with( boost::to_upper_copy( aTypeString ), typePrefix )
&& ( level == readLevel || ( !aSkipDefaultLevel && isDefaultLevel && aLevel == "" ) )
&& version == aVersion )
if( boost::starts_with( typePrefix, "VDMOS" ) )
{
return type;
wxString deviceType = wxString( typePrefix ).BeforeFirst( ' ' ); // VDMOS
wxString channelType = wxString( typePrefix ).AfterFirst( ' ' ); // NCHAN or PCHAN
wxStringTokenizer tokenizer( aTypeString, wxT( " \t\n\r+(" ), wxTOKEN_STRTOK );
if( tokenizer.HasMoreTokens() && tokenizer.GetNextToken().Upper() == deviceType
&& tokenizer.HasMoreTokens() && tokenizer.GetNextToken().Upper() == channelType )
{
return type;
}
}
else if( boost::starts_with( boost::to_upper_copy( aTypeString ), typePrefix ) )
{
if( version != aVersion )
continue;
if( level == readLevel )
return type;
if( aSkipDefaultLevel )
continue;
if( isDefaultLevel && aLevel == "" )
return type;
}
}

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